LIBPTHREAD development step

Corey Minyard minyard@acm.org
Thu Sep 5 13:29:00 GMT 2002


Just a note before you try to use this.  This patch will not work 
correctly, it perhaps fixes one problem, but it causes many others.  For 
instance, with CLONE_THREAD, all the signals sent to any member of the 
process (and not caused by the thread itself) will be delivered to the 
first thread in the process.  This will break a large number of 
programs, including all JVM implementations.  So you have a lot more 
complex things to do to make this work.

I have a threads library at http://ssthreads.sf.net that is a drop-in 
replacement for Linuxthreads but behaves much closer to POSIX, and uses 
CLONE_THREAD.  Perhaps you can use that until Ulrich and company come 
out with their new threads work.

-Corey

Anton Lavrentiev wrote:

>Andreas Jaeger wrote:
>  
>
>>Anton Lavrentiev <lavr@ncbi.nlm.nih.gov> writes:
>>
>>    
>>
>>>Dear GLIBC Streering Committee:
>>>
>>>As of v2.2.5 of GLIBC there is still a missing feature in LIBPTHREAD
>>>about threads being created as independent processes and not sharing
>>>the same PID. "Known-Bugs" of LIBPTHREAD lists this feature to
>>>be missing until CLONE_PID will be implemented in the kernel.
>>>It is in fact implemented since kernel 2.4, and was around for
>>>quite a long, but it is called differently, CLONE_THREAD.
>>>It employs same TGID (thread group ID) task identifier, returned
>>>as process ID (via getpid()) for all threads in the program.
>>>
>>>Below please find patch files to apply to GLIBC 2.2.5 to take
>>>advantage of this Linux kernel feature.
>>>
>>>Patch for glibc-2.2.5/sysdeps/unix/sysv/linux/bits/sched.h
>>>Patch for glibc-2.2.5/linuxthreads/pthread.c
>>>Patch for glibc-2.2.5/linuxthreads/manager.c
>>>      
>>>
>>Please send those patches to libc-alpha@sources.redhat.com.
>>
>>Note that for glibc 2.2 we only accept bug fixes, these kind of
>>patches are more appropriate for the glibc 2.3 branch but Ulrich is
>>also working on similar issues, so your patch might conflict with his
>>work.
>>
>>Thanks,
>>Andreas
>>--
>> Andreas Jaeger
>>  SuSE Labs aj@suse.de
>>   private aj@arthur.inka.de
>>    http://www.suse.de/~aj
>>
>>------------------------------------------------------------------------
>>
>>*** glibc-2.2.5/sysdeps/unix/sysv/linux/bits/sched.h	Fri Aug 30 15:19:28 2002
>>--- glibc-2.2.5/sysdeps/unix/sysv/linux/bits/sched.h.orig	Fri Aug 30 16:07:21 2002
>>***************
>>*** 41,48 ****
>>  # define CLONE_PTRACE  0x00002000 /* Set if tracing continues on the child.  */
>>  # define CLONE_VFORK   0x00004000 /* Set if the parent wants the child to
>>  				     wake it up on mm_release.  */
>>- #define CLONE_PARENT    0x00008000      /* set if we want to have the same parent as the cloner */
>>- #define CLONE_THREAD    0x00010000      /* Same thread group? */
>>  #endif
>>  
>>  /* The official definition.  */
>>--- 41,46 ----
>>    
>>
>>------------------------------------------------------------------------
>>
>>*** glibc-2.2.5/linuxthreads/pthread.c	Fri Aug 30 15:14:30 2002
>>--- glibc-2.2.5/linuxthreads/pthread.c.orig	Fri Nov 30 16:16:35 2001
>>***************
>>*** 35,46 ****
>>  #include <resolv.h>
>>  #undef _res
>>  
>>- #ifdef CLONE_THREAD
>>- #define CLONE_FLAGS (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD)
>>- #else
>>- #define CLONE_FLAGS (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)
>>- #endif
>>- 
>>  extern struct __res_state _res;
>>  
>>  /* Sanity check.  */
>>--- 35,40 ----
>>*************** int __pthread_initialize_manager(void)
>>*** 564,578 ****
>>  	  pid = __clone2(__pthread_manager_event,
>>  			 (void **) __pthread_manager_thread_bos,
>>  			 THREAD_MANAGER_STACK_SIZE,
>>! 			 CLONE_FLAGS, (void *)(long)manager_pipe[0]);
>>  #elif _STACK_GROWS_UP
>>  	  pid = __clone(__pthread_manager_event,
>>  			(void **) __pthread_manager_thread_bos,
>>! 			CLONE_FLAGS, (void *)(long)manager_pipe[0]);
>>  #else
>>  	  pid = __clone(__pthread_manager_event,
>>  			(void **) __pthread_manager_thread_tos,
>>! 			CLONE_FLAGS, (void *)(long)manager_pipe[0]);
>>  #endif
>>  
>>  	  if (pid != -1)
>>--- 558,575 ----
>>  	  pid = __clone2(__pthread_manager_event,
>>  			 (void **) __pthread_manager_thread_bos,
>>  			 THREAD_MANAGER_STACK_SIZE,
>>! 			 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
>>! 			 (void *)(long)manager_pipe[0]);
>>  #elif _STACK_GROWS_UP
>>  	  pid = __clone(__pthread_manager_event,
>>  			(void **) __pthread_manager_thread_bos,
>>! 			CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
>>! 			(void *)(long)manager_pipe[0]);
>>  #else
>>  	  pid = __clone(__pthread_manager_event,
>>  			(void **) __pthread_manager_thread_tos,
>>! 			CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
>>! 			(void *)(long)manager_pipe[0]);
>>  #endif
>>  
>>  	  if (pid != -1)
>>*************** int __pthread_initialize_manager(void)
>>*** 602,614 ****
>>  #ifdef NEED_SEPARATE_REGISTER_STACK
>>        pid = __clone2(__pthread_manager, (void **) __pthread_manager_thread_bos,
>>  		     THREAD_MANAGER_STACK_SIZE,
>>! 		     CLONE_FLAGS, (void *)(long)manager_pipe[0]);
>>  #elif _STACK_GROWS_UP
>>        pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_bos,
>>! 		    CLONE_FLAGS, (void *)(long)manager_pipe[0]);
>>  #else
>>        pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
>>! 		    CLONE_FLAGS, (void *)(long)manager_pipe[0]);
>>  #endif
>>      }
>>    if (__builtin_expect (pid, 0) == -1) {
>>--- 599,614 ----
>>  #ifdef NEED_SEPARATE_REGISTER_STACK
>>        pid = __clone2(__pthread_manager, (void **) __pthread_manager_thread_bos,
>>  		     THREAD_MANAGER_STACK_SIZE,
>>! 		     CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
>>! 		     (void *)(long)manager_pipe[0]);
>>  #elif _STACK_GROWS_UP
>>        pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_bos,
>>! 		    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
>>! 		    (void *)(long)manager_pipe[0]);
>>  #else
>>        pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
>>! 		    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
>>! 		    (void *)(long)manager_pipe[0]);
>>  #endif
>>      }
>>    if (__builtin_expect (pid, 0) == -1) {
>>    
>>
>>------------------------------------------------------------------------
>>
>>*** glibc-2.2.5/linuxthreads/manager.c	Fri Aug 30 11:10:39 2002
>>--- glibc-2.2.5/linuxthreads/manager.c.orig	Thu Nov 29 02:45:19 2001
>>***************
>>*** 33,46 ****
>>  #include "restart.h"
>>  #include "semaphore.h"
>>  
>>- 
>>- #ifdef CLONE_THREAD
>>- #define CLONE_FLAGS (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD)
>>- #else
>>- #define CLONE_FLAGS (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)
>>- #endif
>>- 
>>- 
>>  /* Array of active threads. Entry 0 is reserved for the initial thread. */
>>  struct pthread_handle_struct __pthread_handles[PTHREAD_THREADS_MAX] =
>>  { { __LOCK_INITIALIZER, &__pthread_initial_thread, 0},
>>--- 33,38 ----
>>*************** static int pthread_handle_create(pthread
>>*** 642,654 ****
>>  	  pid = __clone2(pthread_start_thread_event,
>>    		 (void **)new_thread_bottom,
>>  			 (char *)new_thread - new_thread_bottom,
>>! 			 CLONE_FLAGS | __pthread_sig_cancel, new_thread);
>>  #elif _STACK_GROWS_UP
>>  	  pid = __clone(pthread_start_thread_event, (void **) new_thread_bottom,
>>! 			CLONE_FLAGS | __pthread_sig_cancel, new_thread);
>>  #else
>>  	  pid = __clone(pthread_start_thread_event, (void **) new_thread,
>>! 			CLONE_FLAGS | __pthread_sig_cancel, new_thread);
>>  #endif
>>  	  if (pid != -1)
>>  	    {
>>--- 634,649 ----
>>  	  pid = __clone2(pthread_start_thread_event,
>>    		 (void **)new_thread_bottom,
>>  			 (char *)new_thread - new_thread_bottom,
>>! 			 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
>>! 			 __pthread_sig_cancel, new_thread);
>>  #elif _STACK_GROWS_UP
>>  	  pid = __clone(pthread_start_thread_event, (void **) new_thread_bottom,
>>! 			CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
>>! 			__pthread_sig_cancel, new_thread);
>>  #else
>>  	  pid = __clone(pthread_start_thread_event, (void **) new_thread,
>>! 			CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
>>! 			__pthread_sig_cancel, new_thread);
>>  #endif
>>  	  if (pid != -1)
>>  	    {
>>*************** static int pthread_handle_create(pthread
>>*** 679,691 ****
>>        pid = __clone2(pthread_start_thread,
>>  		     (void **)new_thread_bottom,
>>                       (char *)new_thread - new_thread_bottom,
>>!                      CLONE_FLAGS | __pthread_sig_cancel, new_thread);
>>  #elif _STACK_GROWS_UP
>>        pid = __clone(pthread_start_thread, (void **) new_thread_bottom,
>>! 		    CLONE_FLAGS |  __pthread_sig_cancel, new_thread);
>>  #else
>>        pid = __clone(pthread_start_thread, (void **) new_thread,
>>! 		    CLONE_FLAGS | __pthread_sig_cancel, new_thread);
>>  #endif /* !NEED_SEPARATE_REGISTER_STACK */
>>      }
>>    /* Check if cloning succeeded */
>>--- 674,689 ----
>>        pid = __clone2(pthread_start_thread,
>>  		     (void **)new_thread_bottom,
>>                       (char *)new_thread - new_thread_bottom,
>>! 		     CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
>>! 		     __pthread_sig_cancel, new_thread);
>>  #elif _STACK_GROWS_UP
>>        pid = __clone(pthread_start_thread, (void **) new_thread_bottom,
>>! 		    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
>>! 		    __pthread_sig_cancel, new_thread);
>>  #else
>>        pid = __clone(pthread_start_thread, (void **) new_thread,
>>! 		    CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
>>! 		    __pthread_sig_cancel, new_thread);
>>  #endif /* !NEED_SEPARATE_REGISTER_STACK */
>>      }
>>    /* Check if cloning succeeded */
>>    
>>





More information about the Libc-alpha mailing list