Back to index

glibc  2.9
createthread.c
Go to the documentation of this file.
00001 /* Copyright (C) 2002-2007, 2008 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <sched.h>
00021 #include <setjmp.h>
00022 #include <signal.h>
00023 #include <stdlib.h>
00024 #include <atomic.h>
00025 #include <ldsodefs.h>
00026 #include <tls.h>
00027 
00028 #include "kernel-features.h"
00029 
00030 
00031 #define CLONE_SIGNAL        (CLONE_SIGHAND | CLONE_THREAD)
00032 
00033 /* Unless otherwise specified, the thread "register" is going to be
00034    initialized with a pointer to the TCB.  */
00035 #ifndef TLS_VALUE
00036 # define TLS_VALUE pd
00037 #endif
00038 
00039 #ifndef ARCH_CLONE
00040 # define ARCH_CLONE __clone
00041 #endif
00042 
00043 
00044 #ifndef TLS_MULTIPLE_THREADS_IN_TCB
00045 /* Pointer to the corresponding variable in libc.  */
00046 int *__libc_multiple_threads_ptr attribute_hidden;
00047 #endif
00048 
00049 
00050 static int
00051 do_clone (struct pthread *pd, const struct pthread_attr *attr,
00052          int clone_flags, int (*fct) (void *), STACK_VARIABLES_PARMS,
00053          int stopped)
00054 {
00055 #ifdef PREPARE_CREATE
00056   PREPARE_CREATE;
00057 #endif
00058 
00059   if (__builtin_expect (stopped != 0, 0))
00060     /* We make sure the thread does not run far by forcing it to get a
00061        lock.  We lock it here too so that the new thread cannot continue
00062        until we tell it to.  */
00063     lll_lock (pd->lock, LLL_PRIVATE);
00064 
00065   /* One more thread.  We cannot have the thread do this itself, since it
00066      might exist but not have been scheduled yet by the time we've returned
00067      and need to check the value to behave correctly.  We must do it before
00068      creating the thread, in case it does get scheduled first and then
00069      might mistakenly think it was the only thread.  In the failure case,
00070      we momentarily store a false value; this doesn't matter because there
00071      is no kosher thing a signal handler interrupting us right here can do
00072      that cares whether the thread count is correct.  */
00073   atomic_increment (&__nptl_nthreads);
00074 
00075   if (ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags,
00076                 pd, &pd->tid, TLS_VALUE, &pd->tid) == -1)
00077     {
00078       atomic_decrement (&__nptl_nthreads); /* Oops, we lied for a second.  */
00079 
00080       /* Failed.  If the thread is detached, remove the TCB here since
00081         the caller cannot do this.  The caller remembered the thread
00082         as detached and cannot reverify that it is not since it must
00083         not access the thread descriptor again.  */
00084       if (IS_DETACHED (pd))
00085        __deallocate_stack (pd);
00086 
00087       /* We have to translate error codes.  */
00088       return errno == ENOMEM ? EAGAIN : errno;
00089     }
00090 
00091   /* Now we have the possibility to set scheduling parameters etc.  */
00092   if (__builtin_expect (stopped != 0, 0))
00093     {
00094       INTERNAL_SYSCALL_DECL (err);
00095       int res = 0;
00096 
00097       /* Set the affinity mask if necessary.  */
00098       if (attr->cpuset != NULL)
00099        {
00100          res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
00101                               attr->cpusetsize, attr->cpuset);
00102 
00103          if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
00104            {
00105              /* The operation failed.  We have to kill the thread.  First
00106                send it the cancellation signal.  */
00107              INTERNAL_SYSCALL_DECL (err2);
00108            err_out:
00109 #if __ASSUME_TGKILL
00110              (void) INTERNAL_SYSCALL (tgkill, err2, 3,
00111                                    THREAD_GETMEM (THREAD_SELF, pid),
00112                                    pd->tid, SIGCANCEL);
00113 #else
00114              (void) INTERNAL_SYSCALL (tkill, err2, 2, pd->tid, SIGCANCEL);
00115 #endif
00116 
00117              return (INTERNAL_SYSCALL_ERROR_P (res, err)
00118                     ? INTERNAL_SYSCALL_ERRNO (res, err)
00119                     : 0);
00120            }
00121        }
00122 
00123       /* Set the scheduling parameters.  */
00124       if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)
00125        {
00126          res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid,
00127                               pd->schedpolicy, &pd->schedparam);
00128 
00129          if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
00130            goto err_out;
00131        }
00132     }
00133 
00134   /* We now have for sure more than one thread.  The main thread might
00135      not yet have the flag set.  No need to set the global variable
00136      again if this is what we use.  */
00137   THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
00138 
00139   return 0;
00140 }
00141 
00142 
00143 static int
00144 create_thread (struct pthread *pd, const struct pthread_attr *attr,
00145               STACK_VARIABLES_PARMS)
00146 {
00147 #ifdef TLS_TCB_AT_TP
00148   assert (pd->header.tcb != NULL);
00149 #endif
00150 
00151   /* We rely heavily on various flags the CLONE function understands:
00152 
00153      CLONE_VM, CLONE_FS, CLONE_FILES
00154        These flags select semantics with shared address space and
00155        file descriptors according to what POSIX requires.
00156 
00157      CLONE_SIGNAL
00158        This flag selects the POSIX signal semantics.
00159 
00160      CLONE_SETTLS
00161        The sixth parameter to CLONE determines the TLS area for the
00162        new thread.
00163 
00164      CLONE_PARENT_SETTID
00165        The kernels writes the thread ID of the newly created thread
00166        into the location pointed to by the fifth parameters to CLONE.
00167 
00168        Note that it would be semantically equivalent to use
00169        CLONE_CHILD_SETTID but it is be more expensive in the kernel.
00170 
00171      CLONE_CHILD_CLEARTID
00172        The kernels clears the thread ID of a thread that has called
00173        sys_exit() in the location pointed to by the seventh parameter
00174        to CLONE.
00175 
00176      CLONE_DETACHED
00177        No signal is generated if the thread exists and it is
00178        automatically reaped.
00179 
00180      The termination signal is chosen to be zero which means no signal
00181      is sent.  */
00182   int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL
00183                    | CLONE_SETTLS | CLONE_PARENT_SETTID
00184                    | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM
00185 #if __ASSUME_NO_CLONE_DETACHED == 0
00186                    | CLONE_DETACHED
00187 #endif
00188                    | 0);
00189 
00190   if (__builtin_expect (THREAD_GETMEM (THREAD_SELF, report_events), 0))
00191     {
00192       /* The parent thread is supposed to report events.  Check whether
00193         the TD_CREATE event is needed, too.  */
00194       const int _idx = __td_eventword (TD_CREATE);
00195       const uint32_t _mask = __td_eventmask (TD_CREATE);
00196 
00197       if ((_mask & (__nptl_threads_events.event_bits[_idx]
00198                   | pd->eventbuf.eventmask.event_bits[_idx])) != 0)
00199        {
00200          /* We always must have the thread start stopped.  */
00201          pd->stopped_start = true;
00202 
00203          /* Create the thread.  We always create the thread stopped
00204             so that it does not get far before we tell the debugger.  */
00205          int res = do_clone (pd, attr, clone_flags, start_thread,
00206                            STACK_VARIABLES_ARGS, 1);
00207          if (res == 0)
00208            {
00209              /* Now fill in the information about the new thread in
00210                the newly created thread's data structure.  We cannot let
00211                the new thread do this since we don't know whether it was
00212                already scheduled when we send the event.  */
00213              pd->eventbuf.eventnum = TD_CREATE;
00214              pd->eventbuf.eventdata = pd;
00215 
00216              /* Enqueue the descriptor.  */
00217              do
00218               pd->nextevent = __nptl_last_event;
00219              while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event,
00220                                                     pd, pd->nextevent)
00221                    != 0);
00222 
00223              /* Now call the function which signals the event.  */
00224              __nptl_create_event ();
00225 
00226              /* And finally restart the new thread.  */
00227              lll_unlock (pd->lock, LLL_PRIVATE);
00228            }
00229 
00230          return res;
00231        }
00232     }
00233 
00234 #ifdef NEED_DL_SYSINFO
00235   assert (THREAD_SELF_SYSINFO == THREAD_SYSINFO (pd));
00236 #endif
00237 
00238   /* Determine whether the newly created threads has to be started
00239      stopped since we have to set the scheduling parameters or set the
00240      affinity.  */
00241   bool stopped = false;
00242   if (attr != NULL && (attr->cpuset != NULL
00243                      || (attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0))
00244     stopped = true;
00245   pd->stopped_start = stopped;
00246   pd->parent_cancelhandling = THREAD_GETMEM (THREAD_SELF, cancelhandling);
00247 
00248   /* Actually create the thread.  */
00249   int res = do_clone (pd, attr, clone_flags, start_thread,
00250                     STACK_VARIABLES_ARGS, stopped);
00251 
00252   if (res == 0 && stopped)
00253     /* And finally restart the new thread.  */
00254     lll_unlock (pd->lock, LLL_PRIVATE);
00255 
00256   return res;
00257 }