return do_clone (pd, attr, clone_flags, start_thread, STACK_VARIABLES_ARGS);
int res = do_clone (pd, attr, clone_flags, start_thread, STACK_VARIABLES_ARGS);  #ifndef __ASSUME_CLONE_STOPPED if (res == 0 && (clone_flags & CLONE_STOPPED)) {  lll_unlock (pd->lock); } #endif  return res;
create_thread (struct pthread *pd, const struct pthread_attr *attr,	       STACK_VARIABLES_PARMS){#ifdef TLS_TCB_AT_TP  assert (pd->header.tcb != NULL);#endif  /* We rely heavily on various flags the CLONE function understands:     CLONE_VM, CLONE_FS, CLONE_FILES	These flags select semantics with shared address space and	file descriptors according to what POSIX requires.     CLONE_SIGNAL	This flag selects the POSIX signal semantics.     CLONE_SETTLS	The sixth parameter to CLONE determines the TLS area for the	new thread.     CLONE_PARENT_SETTID	The kernels writes the thread ID of the newly created thread	into the location pointed to by the fifth parameters to CLONE.	Note that it would be semantically equivalent to use	CLONE_CHILD_SETTID but it is be more expensive in the kernel.     CLONE_CHILD_CLEARTID	The kernels clears the thread ID of a thread that has called	sys_exit() in the location pointed to by the seventh parameter	to CLONE.     CLONE_DETACHED	No signal is generated if the thread exists and it is	automatically reaped.     The termination signal is chosen to be zero which means no signal     is sent.  */  int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL		     | CLONE_SETTLS | CLONE_PARENT_SETTID		     | CLONE_CHILD_CLEARTID | CLONE_DETACHED | CLONE_SYSVSEM		     | 0);  /* If the newly created threads has to be started stopped since we     have to set the scheduling parameters or set the affinity we set     the CLONE_STOPPED flag.  */  if (attr != NULL && (attr->cpuset != NULL		       || (attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0))    clone_flags |= CLONE_STOPPED;  if (__builtin_expect (THREAD_GETMEM (THREAD_SELF, report_events), 0))    {      /* The parent thread is supposed to report events.  Check whether	 the TD_CREATE event is needed, too.  */      const int _idx = __td_eventword (TD_CREATE);      const uint32_t _mask = __td_eventmask (TD_CREATE);      if ((_mask & (__nptl_threads_events.event_bits[_idx]		    | pd->eventbuf.eventmask.event_bits[_idx])) != 0)	{	  /* We have to report the new thread.  Make sure the thread	     does not run far by forcing it to get a lock.  We lock it	     here too so that the new thread cannot continue until we	     tell it to.  */	  lll_lock (pd->lock);	  /* Create the thread.  */	  int res = do_clone (pd, attr, clone_flags, start_thread_debug,			      STACK_VARIABLES_ARGS);	  if (res == 0)	    {	      /* Now fill in the information about the new thread in		 the newly created thread's data structure.  We cannot let		 the new thread do this since we don't know whether it was		 already scheduled when we send the event.  */	      pd->eventbuf.eventnum = TD_CREATE;	      pd->eventbuf.eventdata = pd;	      /* Enqueue the descriptor.  */	      do		pd->nextevent = __nptl_last_event;	      while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event,							   pd, pd->nextevent)		     != 0);	      /* Now call the function which signals the event.  */	      __nptl_create_event ();	      /* And finally restart the new thread.  */	      lll_unlock (pd->lock);	    }	  return res;	}    }#ifdef NEED_DL_SYSINFO  assert (THREAD_GETMEM (THREAD_SELF, header.sysinfo) == pd->header.sysinfo);#endif  /* Actually create the thread.  */  return do_clone (pd, attr, clone_flags, start_thread, STACK_VARIABLES_ARGS);}