From 5afdca0087dad2994ad4fcdfe7f489f4dbcab7b3 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 11 Mar 1998 12:42:25 +0000 Subject: LinuxThreads library. 1998-03-11 00:42 Wolfram Gloger * linuxthreads/manager.c: Enable resetting of the thread scheduling policy to SCHED_OTHER when the parent thread has a different one. 1998-02-01 13:51 Ulrich Drepper * sysdeps/unix/sysv/linux/bits/posix_opt.h: Define _POSIX_ASYNCHRONOUS_IO. * sysdeps/pthread/pthread.h: Define bits for Unix98 variants of mutexes. * mutex.c: Implement new mutex types. * internals.h: Include . * libpthread.map: Add __erno_location and __h_errno_location. * errno.c: Return pointer to variable actually in use. This might not be the one in the thread structure. * internals.h (struct _pthread_descr_struct): Add new fields p_errnop and p_h_errnop. * manager.c (__pthread_manager): Set p_errnop and p_h_errnop member of manager thread structure. (pthread_handle_create): Set p_errnop and p_h_errnop members for new thread. * pthread.c: Adapt initializer for thread structures. (__pthread_initial_thread): Set p_errnop and p_h_errnop member. (__pthread_reset_main_thread): Reset p_errnop and p_h_errnop of current thread to global variables. 1998-01-31 17:27 Ulrich Drepper * rwlock.c: New file. * Makefile (libpthread-routines): Add rwlock. * sysdeps/pthread/pthread.h: Define data structures and declare functions. * libpthread.map: Add new functions. 1997-12-18 13:50 Philip Blundell * sysdeps/arm/pt-machine.h: New file; add ARM support. * sysdeps/arm/Implies: likewise. * README: Document it. 1997-12-13 Andreas Schwab * signals.c: Remove unneeded initializer for sigwaited, saving a 1997-04-11 01:18 Andreas Schwab * semaphore.c (sem_init): Set sem_spinlock only if available. 1997-12-04 01:48 Ulrich Drepper * mutex.c: Implement PTHREAD_MUTEX_CHECKERROR. * sysdeps/pthread/pthread.h: Define PTHREAD_MUTEX_CHECKERROR. * Makefile: Update from LinuxThreads 0.7. * internals.h. Likewise. * manager.c: Likewise. * mutex.c: Likewise. * pthread.c: Likewise. * signals.c: Likewise. * specific.c: Likewise. * Examples/ex3.c: Likewise. 1997-11-20 18:13 Ulrich Drepper * pthread.c (__pthread_reset_main_thread): Close pipe only if still open. 1997-10-29 05:38 Ulrich Drepper * wrapsyscall.c: Add socket functions which are also cancelation points. 1997-10-19 21:40 Wolfram Gloger * specific.c (__libc_internal_tsd_set, __libc_internal_tsd_get): New functions for fast thread specific data within libc. * internals.h: Add new array p_libc_specific to struct _pthread_descr_struct. * sysdeps/pthread/bits/libc-lock.h: Declare new functions. 1997-10-13 05:39 Ulrich Drepper * semaphore.h: Add __BEGIN_DECLS/__END_DECLS. Reported by Ralf Corsepius . 1997-08-29 03:05 Ulrich Drepper * internals.h (struct _pthread_descr_struct): Add definitions for two-level specific key handling. * manager.c (pthread_handle_create): Initialize specific memory array. * specific.c: Implement two-level key handling. * weaks.c: Don't provide dummy key handling. * sysdeps/pthread/bits/libc-lock.h: Typedef __libc_lock_t (no #define). Add definition of __libc_key_t. * sysdeps/unix/sysv/linux/bits/local_lim.h: Define PTHREAD_KEYS_MAX as 1024. Add definition of _POSIX_THREAD_DESTRUCTOR_ITERATIONS and PTHREAD_DESTRUCTOR_ITERATIONS. * manager.c (pthread_handle_create): Compare mmap result with MAP_FAILED. * ptfork.c: Rename to __pthread_atfork and make old name a weak alias. * sysdeps/pthread/bits/pthread.h: Add prototype for __pthread_atfork. 1997-08-22 19:04 Richard Henderson sysdeps/sparc -> sysdeps/sparc/sparc32 sysdeps/sparc64 -> sysdeps/sparc/sparc64 * internals.h: Change definition of THREAD_SELF to be an expression, not a statement that did a return. * sysdeps/alpha/pt-machine.h (THREAD_SELF): Update accordingly. * sysdeps/sparc/sparc32/pt-machine.h (THREAD_SELF, INIT_THREAD_SELF): Follow Solaris and use a "system reserved" register (%g6) to hold the thread descriptor. * sysdeps/sparc/sparc64/pt-machine.h: Likewise. 1997-08-03 00:09 Ulrich Drepper * mutex.c: Correct pthread_once. Patch by Xavier Leroy. * sysdeps/pthread/pthread.h: Add prototype for __pthread_once. * sysdeps/pthread/bits/pthread.h: Add macros for __libc_once. * semaphore.c: Include spinlock.h only when needed. * specific.c (__pthread_setsepcific, __pthread_getspecific): Reject keys for entries not in use. * weaks.c: Implement key handling functions for real. 1997-06-29 01:04 Richard Henderson Initial sparc64-linux support: * linuxthreads/sysdeps/sparc64/Implies: New file. * linuxthreads/sysdeps/sparc64/pt-machine.h: Likewise. 1997-06-29 00:48 Ulrich Drepper * semaphore.c: Include spinlock.h at correct place. Patch by HJ Lu. 1997-06-13 10:06 Richard Henderson The Great Bit File Move: * sysdeps/alpha/semaphorebits.h: -> .../bits/semaphore.h. * sysdeps/powerpc/semaphorebits.h: Likewise. * sysdeps/pthread/cmpxchg/semaphorebits.h: Likewise. * sysdeps/pthread/no-cmpxchg/semaphorebits.h: Likewise. * sysdeps/pthread/libc-lock.h: -> bits/ * sysdeps/pthread/stdio-lock.h: Likewise. * sysdeps/unix/sysv/linux/local_lim.h: Likewise. * sysdeps/unix/sysv/linux/posix_opt.h: Likewise. * semaphore.h: Likewise. * sysdeps/pthread/pthread.h: Likewise. * lockfile.c: -> . * semaphore.h: Likewise. * Makefile: (headers): foo.h -> bits/foo.h. * sysdeps/pthread/Makefile: Likewise. 1997-04-11 01:18 Andreas Schwab * semaphore.c (sem_init): Set sem_spinlock only if available. * sysdeps/m68k/pt-machine.h (testandset, __compare_and_swap): Fix asm constraints. 1997-04-09 03:00 Ulrich Drepper Update from LinuxThreads 0.6. * attr.c (pthread_attr_getdetachstate): Use __sched_get_priority_max and __sched_get_priority_min instead of names without `__'. * manager.c: Rewrite large parts to implement opaque pthread_t. * cancel.c: Adapt for opaque pthread_t type. * condvar.c: Likewise. * errno.c: Likewise. * join.c: Likewise. * mutex.c: Likewise. * pthread.c: Likewise. * signals.c: Likewise. * specific.c: Likewise. * restart.h: Likewise. * queue.h: Likewise. * Examples/ex3.c: Likewise. * Examples/ex4.c: Likewise. * sysdeps/pthread/pthread.h: Likewise. * pthread.c: Accumulate time for all threads in thread manager. * semaphore.c: Implement fallback implementation for architectures sometimes missing compare-exchange operations. * cancel.c (pthread_cancel): Validate handle argument. * join.c (pthread_join): Likewise. (pthread_detach): Likewise. * signals.c (pthread_kill): Likewise. * spinlock.h (acquire): Use __sched_yield not sched_yield. * queue.h (enqueue): Enqueue thread according to priority. * internals.c (struct pthread_start_args): New struct for passing args to cloning function. (struct _pthread): Rename to _pthread_descr_struct and adapt for opaque pthread_t. * Examples/Makefile (clean): Pass -f option to rm. * sysdeps/i386/pt-machine.h: Add check for compare-exchange instruction and define TEST_FOR_COMPARE_AND_SWAP. * sysdeps/i386/i486/pt-machine.h: Removed. * sysdeps/unix/sysv/linux/local_lim.h (PTHREAD_THREADS_MAX): Increase to 1024. 1997-04-04 16:38 Ulrich Drepper * restart.h (suspend): Clear p_signal before suspending. (suspend_with_cancellation): Likewise. Patch by Xavier Leroy . * weaks.c: Make __pthread_key_create return 1. * sysdeps/pthread/libc-lock.h: Define __libc_key_create, __libc_getspecific, __libc_setspecific, and __libc_key_t. * sysdeps/pthread/stdio-lock.h: Don't care for implementation not using libio. 1997-03-19 15:13 Miguel de Icaza * sysdeps/sparc/pt-machine (RELEASE): Fix. 1997-03-01 07:55 Geoff Keating * sysdeps/powerpc/Implies: Added. * sysdeps/powerpc/pt-machine.h: Added. * sysdeps/powerpc/semaphorebits.h: Added. 1997-01-22 01:22 Ulrich Drepper * linuxtheads/pthread.c (__pthread_initial_thread): Correct initializer. (__pthread_manager_thread): Likewise. Reported by Andreas Jaeger. 1997-01-18 22:15 Richard Henderson Since sigset_t no longer fits in a register, we can't pass in the thread's initial mask so easily. Take this opportunity to simplify the clone implementation by only accepting a single void* argument. * linuxthreads/manager.c (__pthread_manager): Put thread vitals in the thread struct instead of as arguments through clone. (pthread_start_thread): Look for them there. * linuxthreads/internals.h (struct _pthread): Add p_initial_fn, p_initial_fn_arg, p_initial_mask. Fix __pthread_manager proto. * linuxthreads/pthread.c (pthread_initialize_manager): Revise clone invocation. --- linuxthreads/Banner | 1 + linuxthreads/ChangeLog | 271 ++++++ linuxthreads/Changes | 73 ++ linuxthreads/Examples/Makefile | 15 + linuxthreads/Examples/ex1.c | 36 + linuxthreads/Examples/ex2.c | 116 +++ linuxthreads/Examples/ex3.c | 144 +++ linuxthreads/Examples/ex4.c | 107 +++ linuxthreads/Examples/ex5.c | 102 +++ linuxthreads/FAQ.html | 986 +++++++++++++++++++++ linuxthreads/LICENSE | 501 +++++++++++ linuxthreads/Makefile | 44 + linuxthreads/README | 163 ++++ linuxthreads/README.Xfree3.2 | 352 ++++++++ linuxthreads/attr.c | 117 +++ linuxthreads/cancel.c | 131 +++ linuxthreads/condvar.c | 207 +++++ linuxthreads/configure | 5 + linuxthreads/errno.c | 32 + linuxthreads/internals.h | 280 ++++++ linuxthreads/join.c | 145 +++ linuxthreads/libpthread.map | 62 ++ linuxthreads/lockfile.c | 87 ++ linuxthreads/man/Makefile | 31 + linuxthreads/man/pthread_atfork.man | 58 ++ linuxthreads/man/pthread_attr_init.man | 221 +++++ linuxthreads/man/pthread_cancel.man | 155 ++++ linuxthreads/man/pthread_cleanup_push.man | 194 ++++ linuxthreads/man/pthread_cond_init.man | 235 +++++ linuxthreads/man/pthread_condattr_init.man | 39 + linuxthreads/man/pthread_create.man | 46 + linuxthreads/man/pthread_detach.man | 44 + linuxthreads/man/pthread_equal.man | 23 + linuxthreads/man/pthread_exit.man | 32 + linuxthreads/man/pthread_join.man | 70 ++ linuxthreads/man/pthread_key_create.man | 151 ++++ linuxthreads/man/pthread_kill_other_threads_np.man | 40 + linuxthreads/man/pthread_mutex_init.man | 213 +++++ linuxthreads/man/pthread_mutexattr_init.man | 84 ++ linuxthreads/man/pthread_once.man | 34 + linuxthreads/man/pthread_self.man | 23 + linuxthreads/man/pthread_setschedparam.man | 79 ++ linuxthreads/man/pthread_sigmask.man | 123 +++ linuxthreads/man/sem_init.man | 132 +++ linuxthreads/man/troffprepro | 68 ++ linuxthreads/manager.c | 400 +++++++++ linuxthreads/mutex.c | 234 +++++ linuxthreads/ptfork.c | 97 ++ linuxthreads/pthread.c | 445 ++++++++++ linuxthreads/queue.h | 62 ++ linuxthreads/restart.h | 57 ++ linuxthreads/rwlock.c | 276 ++++++ linuxthreads/semaphore.c | 236 +++++ linuxthreads/semaphore.h | 38 + linuxthreads/shlib-versions | 2 + linuxthreads/signals.c | 148 ++++ linuxthreads/specific.c | 174 ++++ linuxthreads/spinlock.h | 30 + linuxthreads/sysdeps/alpha/bits/semaphore.h | 31 + linuxthreads/sysdeps/alpha/pt-machine.h | 102 +++ linuxthreads/sysdeps/arm/Implies | 1 + linuxthreads/sysdeps/arm/pt-machine.h | 44 + linuxthreads/sysdeps/i386/Implies | 1 + linuxthreads/sysdeps/i386/pt-machine.h | 93 ++ linuxthreads/sysdeps/m68k/Implies | 1 + linuxthreads/sysdeps/m68k/pt-machine.h | 58 ++ linuxthreads/sysdeps/mips/Implies | 1 + linuxthreads/sysdeps/mips/pt-machine.h | 84 ++ linuxthreads/sysdeps/powerpc/Implies | 1 + linuxthreads/sysdeps/powerpc/bits/semaphore.h | 32 + linuxthreads/sysdeps/powerpc/pt-machine.h | 84 ++ linuxthreads/sysdeps/pthread/Makefile | 3 + linuxthreads/sysdeps/pthread/bits/libc-lock.h | 208 +++++ linuxthreads/sysdeps/pthread/bits/stdio-lock.h | 35 + .../sysdeps/pthread/cmpxchg/bits/semaphore.h | 26 + .../sysdeps/pthread/no-cmpxchg/bits/semaphore.h | 27 + linuxthreads/sysdeps/pthread/pthread.h | 578 ++++++++++++ linuxthreads/sysdeps/sparc/sparc32/Implies | 1 + linuxthreads/sysdeps/sparc/sparc32/pt-machine.h | 55 ++ linuxthreads/sysdeps/sparc/sparc64/Implies | 1 + linuxthreads/sysdeps/sparc/sparc64/pt-machine.h | 67 ++ linuxthreads/sysdeps/unix/sysv/linux/Implies | 1 + .../sysdeps/unix/sysv/linux/bits/local_lim.h | 40 + .../sysdeps/unix/sysv/linux/bits/posix_opt.h | 94 ++ linuxthreads/sysdeps/unix/sysv/linux/configure | 3 + linuxthreads/weaks.c | 87 ++ linuxthreads/wrapsyscall.c | 183 ++++ 87 files changed, 10213 insertions(+) create mode 100644 linuxthreads/Banner create mode 100644 linuxthreads/ChangeLog create mode 100644 linuxthreads/Changes create mode 100644 linuxthreads/Examples/Makefile create mode 100644 linuxthreads/Examples/ex1.c create mode 100644 linuxthreads/Examples/ex2.c create mode 100644 linuxthreads/Examples/ex3.c create mode 100644 linuxthreads/Examples/ex4.c create mode 100644 linuxthreads/Examples/ex5.c create mode 100644 linuxthreads/FAQ.html create mode 100644 linuxthreads/LICENSE create mode 100644 linuxthreads/Makefile create mode 100644 linuxthreads/README create mode 100644 linuxthreads/README.Xfree3.2 create mode 100644 linuxthreads/attr.c create mode 100644 linuxthreads/cancel.c create mode 100644 linuxthreads/condvar.c create mode 100755 linuxthreads/configure create mode 100644 linuxthreads/errno.c create mode 100644 linuxthreads/internals.h create mode 100644 linuxthreads/join.c create mode 100644 linuxthreads/libpthread.map create mode 100644 linuxthreads/lockfile.c create mode 100644 linuxthreads/man/Makefile create mode 100644 linuxthreads/man/pthread_atfork.man create mode 100644 linuxthreads/man/pthread_attr_init.man create mode 100644 linuxthreads/man/pthread_cancel.man create mode 100644 linuxthreads/man/pthread_cleanup_push.man create mode 100644 linuxthreads/man/pthread_cond_init.man create mode 100644 linuxthreads/man/pthread_condattr_init.man create mode 100644 linuxthreads/man/pthread_create.man create mode 100644 linuxthreads/man/pthread_detach.man create mode 100644 linuxthreads/man/pthread_equal.man create mode 100644 linuxthreads/man/pthread_exit.man create mode 100644 linuxthreads/man/pthread_join.man create mode 100644 linuxthreads/man/pthread_key_create.man create mode 100644 linuxthreads/man/pthread_kill_other_threads_np.man create mode 100644 linuxthreads/man/pthread_mutex_init.man create mode 100644 linuxthreads/man/pthread_mutexattr_init.man create mode 100644 linuxthreads/man/pthread_once.man create mode 100644 linuxthreads/man/pthread_self.man create mode 100644 linuxthreads/man/pthread_setschedparam.man create mode 100644 linuxthreads/man/pthread_sigmask.man create mode 100644 linuxthreads/man/sem_init.man create mode 100755 linuxthreads/man/troffprepro create mode 100644 linuxthreads/manager.c create mode 100644 linuxthreads/mutex.c create mode 100644 linuxthreads/ptfork.c create mode 100644 linuxthreads/pthread.c create mode 100644 linuxthreads/queue.h create mode 100644 linuxthreads/restart.h create mode 100644 linuxthreads/rwlock.c create mode 100644 linuxthreads/semaphore.c create mode 100644 linuxthreads/semaphore.h create mode 100644 linuxthreads/shlib-versions create mode 100644 linuxthreads/signals.c create mode 100644 linuxthreads/specific.c create mode 100644 linuxthreads/spinlock.h create mode 100644 linuxthreads/sysdeps/alpha/bits/semaphore.h create mode 100644 linuxthreads/sysdeps/alpha/pt-machine.h create mode 100644 linuxthreads/sysdeps/arm/Implies create mode 100644 linuxthreads/sysdeps/arm/pt-machine.h create mode 100644 linuxthreads/sysdeps/i386/Implies create mode 100644 linuxthreads/sysdeps/i386/pt-machine.h create mode 100644 linuxthreads/sysdeps/m68k/Implies create mode 100644 linuxthreads/sysdeps/m68k/pt-machine.h create mode 100644 linuxthreads/sysdeps/mips/Implies create mode 100644 linuxthreads/sysdeps/mips/pt-machine.h create mode 100644 linuxthreads/sysdeps/powerpc/Implies create mode 100644 linuxthreads/sysdeps/powerpc/bits/semaphore.h create mode 100644 linuxthreads/sysdeps/powerpc/pt-machine.h create mode 100644 linuxthreads/sysdeps/pthread/Makefile create mode 100644 linuxthreads/sysdeps/pthread/bits/libc-lock.h create mode 100644 linuxthreads/sysdeps/pthread/bits/stdio-lock.h create mode 100644 linuxthreads/sysdeps/pthread/cmpxchg/bits/semaphore.h create mode 100644 linuxthreads/sysdeps/pthread/no-cmpxchg/bits/semaphore.h create mode 100644 linuxthreads/sysdeps/pthread/pthread.h create mode 100644 linuxthreads/sysdeps/sparc/sparc32/Implies create mode 100644 linuxthreads/sysdeps/sparc/sparc32/pt-machine.h create mode 100644 linuxthreads/sysdeps/sparc/sparc64/Implies create mode 100644 linuxthreads/sysdeps/sparc/sparc64/pt-machine.h create mode 100644 linuxthreads/sysdeps/unix/sysv/linux/Implies create mode 100644 linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h create mode 100644 linuxthreads/sysdeps/unix/sysv/linux/bits/posix_opt.h create mode 100644 linuxthreads/sysdeps/unix/sysv/linux/configure create mode 100644 linuxthreads/weaks.c create mode 100644 linuxthreads/wrapsyscall.c (limited to 'linuxthreads') diff --git a/linuxthreads/Banner b/linuxthreads/Banner new file mode 100644 index 0000000000..c1a3821f13 --- /dev/null +++ b/linuxthreads/Banner @@ -0,0 +1 @@ +linuxthreads-0.7 by Xavier Leroy diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog new file mode 100644 index 0000000000..696d15178d --- /dev/null +++ b/linuxthreads/ChangeLog @@ -0,0 +1,271 @@ +1998-03-11 00:42 Wolfram Gloger + + * linuxthreads/manager.c: Enable resetting of the thread + scheduling policy to SCHED_OTHER when the parent thread + has a different one. + +1998-02-01 13:51 Ulrich Drepper + + * sysdeps/unix/sysv/linux/bits/posix_opt.h: Define + _POSIX_ASYNCHRONOUS_IO. + + * sysdeps/pthread/pthread.h: Define bits for Unix98 variants of + mutexes. + * mutex.c: Implement new mutex types. + + * internals.h: Include . + + * libpthread.map: Add __erno_location and __h_errno_location. + + * errno.c: Return pointer to variable actually in use. This might + not be the one in the thread structure. + * internals.h (struct _pthread_descr_struct): Add new fields p_errnop + and p_h_errnop. + * manager.c (__pthread_manager): Set p_errnop and p_h_errnop member + of manager thread structure. + (pthread_handle_create): Set p_errnop and p_h_errnop members for new + thread. + * pthread.c: Adapt initializer for thread structures. + (__pthread_initial_thread): Set p_errnop and p_h_errnop member. + (__pthread_reset_main_thread): Reset p_errnop and p_h_errnop of + current thread to global variables. + +1998-01-31 17:27 Ulrich Drepper + + * rwlock.c: New file. + * Makefile (libpthread-routines): Add rwlock. + * sysdeps/pthread/pthread.h: Define data structures and declare + functions. + * libpthread.map: Add new functions. + +1997-12-18 13:50 Philip Blundell + + * sysdeps/arm/pt-machine.h: New file; add ARM support. + * sysdeps/arm/Implies: likewise. + * README: Document it. + +1997-12-13 Andreas Schwab + + * signals.c: Remove unneeded initializer for sigwaited, saving a + warning. + +1997-04-11 01:18 Andreas Schwab + + * semaphore.c (sem_init): Set sem_spinlock only if available. + +1997-12-04 01:48 Ulrich Drepper + + * mutex.c: Implement PTHREAD_MUTEX_CHECKERROR. + * sysdeps/pthread/pthread.h: Define PTHREAD_MUTEX_CHECKERROR. + + * Makefile: Update from LinuxThreads 0.7. + * internals.h. Likewise. + * manager.c: Likewise. + * mutex.c: Likewise. + * pthread.c: Likewise. + * signals.c: Likewise. + * specific.c: Likewise. + * Examples/ex3.c: Likewise. + +1997-11-20 18:13 Ulrich Drepper + + * pthread.c (__pthread_reset_main_thread): Close pipe only if still + open. + +1997-10-29 05:38 Ulrich Drepper + + * wrapsyscall.c: Add socket functions which are also cancelation + points. + +1997-10-19 21:40 Wolfram Gloger + + * specific.c (__libc_internal_tsd_set, __libc_internal_tsd_get): + New functions for fast thread specific data within libc. + + * internals.h: Add new array p_libc_specific to struct + _pthread_descr_struct. + + * sysdeps/pthread/bits/libc-lock.h: Declare new functions. + +1997-10-13 05:39 Ulrich Drepper + + * semaphore.h: Add __BEGIN_DECLS/__END_DECLS. + Reported by Ralf Corsepius . + +1997-08-29 03:05 Ulrich Drepper + + * internals.h (struct _pthread_descr_struct): Add definitions for + two-level specific key handling. + * manager.c (pthread_handle_create): Initialize specific memory array. + * specific.c: Implement two-level key handling. + * weaks.c: Don't provide dummy key handling. + * sysdeps/pthread/bits/libc-lock.h: Typedef __libc_lock_t (no #define). + Add definition of __libc_key_t. + * sysdeps/unix/sysv/linux/bits/local_lim.h: Define PTHREAD_KEYS_MAX + as 1024. + Add definition of _POSIX_THREAD_DESTRUCTOR_ITERATIONS and + PTHREAD_DESTRUCTOR_ITERATIONS. + + * manager.c (pthread_handle_create): Compare mmap result with + MAP_FAILED. + + * ptfork.c: Rename to __pthread_atfork and make old name a weak alias. + * sysdeps/pthread/bits/pthread.h: Add prototype for __pthread_atfork. + +1997-08-22 19:04 Richard Henderson + + sysdeps/sparc -> sysdeps/sparc/sparc32 + sysdeps/sparc64 -> sysdeps/sparc/sparc64 + + * internals.h: Change definition of THREAD_SELF to be an expression, + not a statement that did a return. + * sysdeps/alpha/pt-machine.h (THREAD_SELF): Update accordingly. + * sysdeps/sparc/sparc32/pt-machine.h (THREAD_SELF, INIT_THREAD_SELF): + Follow Solaris and use a "system reserved" register (%g6) to hold + the thread descriptor. + * sysdeps/sparc/sparc64/pt-machine.h: Likewise. + +1997-08-03 00:09 Ulrich Drepper + + * mutex.c: Correct pthread_once. Patch by Xavier Leroy. + * sysdeps/pthread/pthread.h: Add prototype for __pthread_once. + * sysdeps/pthread/bits/pthread.h: Add macros for __libc_once. + + * semaphore.c: Include spinlock.h only when needed. + + * specific.c (__pthread_setsepcific, __pthread_getspecific): Reject + keys for entries not in use. + + * weaks.c: Implement key handling functions for real. + +1997-06-29 01:04 Richard Henderson + + Initial sparc64-linux support: + * linuxthreads/sysdeps/sparc64/Implies: New file. + * linuxthreads/sysdeps/sparc64/pt-machine.h: Likewise. + +1997-06-29 00:48 Ulrich Drepper + + * semaphore.c: Include spinlock.h at correct place. + Patch by HJ Lu. + +1997-06-13 10:06 Richard Henderson + + The Great Bit File Move: + * sysdeps/alpha/semaphorebits.h: -> .../bits/semaphore.h. + * sysdeps/powerpc/semaphorebits.h: Likewise. + * sysdeps/pthread/cmpxchg/semaphorebits.h: Likewise. + * sysdeps/pthread/no-cmpxchg/semaphorebits.h: Likewise. + * sysdeps/pthread/libc-lock.h: -> bits/ + * sysdeps/pthread/stdio-lock.h: Likewise. + * sysdeps/unix/sysv/linux/local_lim.h: Likewise. + * sysdeps/unix/sysv/linux/posix_opt.h: Likewise. + * semaphore.h: Likewise. + * sysdeps/pthread/pthread.h: Likewise. + + * lockfile.c: -> . + * semaphore.h: Likewise. + + * Makefile: (headers): foo.h -> bits/foo.h. + * sysdeps/pthread/Makefile: Likewise. + +1997-04-11 01:18 Andreas Schwab + + * semaphore.c (sem_init): Set sem_spinlock only if available. + + * sysdeps/m68k/pt-machine.h (testandset, __compare_and_swap): Fix + asm constraints. + +1997-04-09 03:00 Ulrich Drepper + + Update from LinuxThreads 0.6. + + * attr.c (pthread_attr_getdetachstate): Use __sched_get_priority_max + and __sched_get_priority_min instead of names without `__'. + + * manager.c: Rewrite large parts to implement opaque pthread_t. + + * cancel.c: Adapt for opaque pthread_t type. + * condvar.c: Likewise. + * errno.c: Likewise. + * join.c: Likewise. + * mutex.c: Likewise. + * pthread.c: Likewise. + * signals.c: Likewise. + * specific.c: Likewise. + * restart.h: Likewise. + * queue.h: Likewise. + * Examples/ex3.c: Likewise. + * Examples/ex4.c: Likewise. + * sysdeps/pthread/pthread.h: Likewise. + + * pthread.c: Accumulate time for all threads in thread manager. + + * semaphore.c: Implement fallback implementation for architectures + sometimes missing compare-exchange operations. + + * cancel.c (pthread_cancel): Validate handle argument. + * join.c (pthread_join): Likewise. + (pthread_detach): Likewise. + * signals.c (pthread_kill): Likewise. + + * spinlock.h (acquire): Use __sched_yield not sched_yield. + + * queue.h (enqueue): Enqueue thread according to priority. + + * internals.c (struct pthread_start_args): New struct for passing + args to cloning function. + (struct _pthread): Rename to _pthread_descr_struct and adapt for + opaque pthread_t. + + * Examples/Makefile (clean): Pass -f option to rm. + + * sysdeps/i386/pt-machine.h: Add check for compare-exchange instruction + and define TEST_FOR_COMPARE_AND_SWAP. + * sysdeps/i386/i486/pt-machine.h: Removed. + + * sysdeps/unix/sysv/linux/local_lim.h (PTHREAD_THREADS_MAX): Increase + to 1024. + +1997-04-04 16:38 Ulrich Drepper + + * restart.h (suspend): Clear p_signal before suspending. + (suspend_with_cancellation): Likewise. + Patch by Xavier Leroy . + + * weaks.c: Make __pthread_key_create return 1. + * sysdeps/pthread/libc-lock.h: Define __libc_key_create, + __libc_getspecific, __libc_setspecific, and __libc_key_t. + * sysdeps/pthread/stdio-lock.h: Don't care for implementation not + using libio. + +1997-03-19 15:13 Miguel de Icaza + + * sysdeps/sparc/pt-machine (RELEASE): Fix. + +1997-03-01 07:55 Geoff Keating + + * sysdeps/powerpc/Implies: Added. + * sysdeps/powerpc/pt-machine.h: Added. + * sysdeps/powerpc/semaphorebits.h: Added. + +1997-01-22 01:22 Ulrich Drepper + + * linuxtheads/pthread.c (__pthread_initial_thread): Correct + initializer. + (__pthread_manager_thread): Likewise. + Reported by Andreas Jaeger. + +1997-01-18 22:15 Richard Henderson + + Since sigset_t no longer fits in a register, we can't pass in the + thread's initial mask so easily. Take this opportunity to simplify + the clone implementation by only accepting a single void* argument. + + * linuxthreads/manager.c (__pthread_manager): Put thread vitals + in the thread struct instead of as arguments through clone. + (pthread_start_thread): Look for them there. + * linuxthreads/internals.h (struct _pthread): Add p_initial_fn, + p_initial_fn_arg, p_initial_mask. Fix __pthread_manager proto. + * linuxthreads/pthread.c (pthread_initialize_manager): Revise + clone invocation. diff --git a/linuxthreads/Changes b/linuxthreads/Changes new file mode 100644 index 0000000000..8ec26c9a67 --- /dev/null +++ b/linuxthreads/Changes @@ -0,0 +1,73 @@ +Release 0.7: +- Destructors for thread-specific data now conform to the POSIX semantics + (call destructors again if non-NULL TSD remains after a round of + destruction). +- Implemented thread-specific data as a sparse array, allows more TSD keys + and smaller thread descriptors (Ulrich Drepper). +- Added "error checking" mutexes. +- Protect against multiple sigwait() on the same signals. +- Simplified implementation of semaphores when compare_and_swap is + not available. +- Fixed bug in fork() where stdin was closed if fork() was called before + the first pthread_create(). +- Fixed bug in the gethostby*_r functions (bad result if null bytes + in addresses). +- Typos in manual pages corrected. +- First cut at a PowerPC port (not working yet, runs into problems + with gcc and with the C library). + +Release 0.6: +- Validation of thread identifiers: no more crashes when operating on + a thread that has exited (based on Pavel Krauz's ideas). +- Added fallback implementation of semaphores for the 386 and the + Sparc. +- Fixed a bug in signal handling causing false restarts of suspended + threads. +- Fixed a bug in realtime scheduling causing all threads to have + default scheduling on Ix86 with libc5. +- With realtime scheduling, unlocking a mutex now restarts the + highest priority thread waiting on the mutex, not the + first-suspended thread (Richard Neitzel). +- Timing a process now returns cumulative times for all threads, not + just times for the initial thread (suggested by Wolfram Gloger). +- Cleaned up name space (internal defs prefixed by __, weak aliases + for non-portable extensions). +- MIPS port (contributed by Ralf Baechle). + +Release 0.5: +- Signal-safe semaphores a la POSIX 1003.1b added. +- Locking bug in pthread_mutex_trylock over recursive mutexes fixed. +- Race conditions in thread cancellation fixed. +- Sparc port (contributed by Miguel de Icaza). +- Support for getpwnam_r and getpwuid_r. +- Added pthread_kill_other_threads_np to be used in conjunction with + exec*(). + +Release 0.4: +- Manual pages for all functions. +- Synchronization bug causing accumulation of zombie processes fixed. +- Race condition in pthread_cond_timedwait fixed. +- Recursive mutexes are back by popular demand. +- Partial support for realtime scheduling (initiated by Richard Neitzel). +- pthread.h cleaned up a lot: now C++ compatible, added missing "const" + qualifiers, added short documentation, put to GNU libc standards + for name space pollution (Ulrich Drepper). +- Motorola 68k port (contributed by Andreas Schwab). +- Interaction with fork(2) cleaned up a lot. + +Release 0.3: +- Thread creation and reclaimation now performed by a centralized + "thread manager" thread. +- Removed recursive mutexes to make regular mutexes more efficient. +- Now available as a shared library (contributed by Richard Henderson). +- Alpha port (contributed by Richard Henderson). +- Fixed many small discrepancies with Posix 1003.1c. +- Put under the LGPL instead of the GPL. + +Release 0.2: +- Reentrant libc functions (adapted from libc 5.3.9 by Peeter Joot) +- pthread_cond_wait did not reacquire the mutex correctly on return +- More efficient pthread_cond_broadcast + +Release 0.1: +- First public release diff --git a/linuxthreads/Examples/Makefile b/linuxthreads/Examples/Makefile new file mode 100644 index 0000000000..c68b3676a4 --- /dev/null +++ b/linuxthreads/Examples/Makefile @@ -0,0 +1,15 @@ +CC=gcc +CFLAGS=-g -O -Wall -I.. -D_REENTRANT +LIBPTHREAD=../libpthread.a + +PROGS=ex1 ex2 ex3 ex4 ex5 proxy + +all: $(PROGS) + +.c: + $(CC) $(CFLAGS) -o $* $*.c $(LIBPTHREAD) + +$(PROGS): + +clean: + rm -f $(PROGS) diff --git a/linuxthreads/Examples/ex1.c b/linuxthreads/Examples/ex1.c new file mode 100644 index 0000000000..c399fab894 --- /dev/null +++ b/linuxthreads/Examples/ex1.c @@ -0,0 +1,36 @@ +/* Creates two threads, one printing 10000 "a"s, the other printing + 10000 "b"s. + Illustrates: thread creation, thread joining. */ + +#include +#include +#include +#include "pthread.h" + +void * process(void * arg) +{ + int i; + fprintf(stderr, "Starting process %s\n", (char *) arg); + for (i = 0; i < 10000; i++) { + write(1, (char *) arg, 1); + } + return NULL; +} + +int main() +{ + int retcode; + pthread_t th_a, th_b; + void * retval; + + retcode = pthread_create(&th_a, NULL, process, "a"); + if (retcode != 0) fprintf(stderr, "create a failed %d\n", retcode); + retcode = pthread_create(&th_b, NULL, process, "b"); + if (retcode != 0) fprintf(stderr, "create b failed %d\n", retcode); + retcode = pthread_join(th_a, &retval); + if (retcode != 0) fprintf(stderr, "join a failed %d\n", retcode); + retcode = pthread_join(th_b, &retval); + if (retcode != 0) fprintf(stderr, "join b failed %d\n", retcode); + return 0; +} + diff --git a/linuxthreads/Examples/ex2.c b/linuxthreads/Examples/ex2.c new file mode 100644 index 0000000000..3f7f115fda --- /dev/null +++ b/linuxthreads/Examples/ex2.c @@ -0,0 +1,116 @@ +/* The classic producer-consumer example. + Illustrates mutexes and conditions. + All integers between 0 and 9999 should be printed exactly twice, + once to the right of the arrow and once to the left. */ + +#include +#include "pthread.h" + +#define BUFFER_SIZE 16 + +/* Circular buffer of integers. */ + +struct prodcons { + int buffer[BUFFER_SIZE]; /* the actual data */ + pthread_mutex_t lock; /* mutex ensuring exclusive access to buffer */ + int readpos, writepos; /* positions for reading and writing */ + pthread_cond_t notempty; /* signaled when buffer is not empty */ + pthread_cond_t notfull; /* signaled when buffer is not full */ +}; + +/* Initialize a buffer */ + +void init(struct prodcons * b) +{ + pthread_mutex_init(&b->lock, NULL); + pthread_cond_init(&b->notempty, NULL); + pthread_cond_init(&b->notfull, NULL); + b->readpos = 0; + b->writepos = 0; +} + +/* Store an integer in the buffer */ + +void put(struct prodcons * b, int data) +{ + pthread_mutex_lock(&b->lock); + /* Wait until buffer is not full */ + while ((b->writepos + 1) % BUFFER_SIZE == b->readpos) { + pthread_cond_wait(&b->notfull, &b->lock); + /* pthread_cond_wait reacquired b->lock before returning */ + } + /* Write the data and advance write pointer */ + b->buffer[b->writepos] = data; + b->writepos++; + if (b->writepos >= BUFFER_SIZE) b->writepos = 0; + /* Signal that the buffer is now not empty */ + pthread_cond_signal(&b->notempty); + pthread_mutex_unlock(&b->lock); +} + +/* Read and remove an integer from the buffer */ + +int get(struct prodcons * b) +{ + int data; + pthread_mutex_lock(&b->lock); + /* Wait until buffer is not empty */ + while (b->writepos == b->readpos) { + pthread_cond_wait(&b->notempty, &b->lock); + } + /* Read the data and advance read pointer */ + data = b->buffer[b->readpos]; + b->readpos++; + if (b->readpos >= BUFFER_SIZE) b->readpos = 0; + /* Signal that the buffer is now not full */ + pthread_cond_signal(&b->notfull); + pthread_mutex_unlock(&b->lock); + return data; +} + +/* A test program: one thread inserts integers from 1 to 10000, + the other reads them and prints them. */ + +#define OVER (-1) + +struct prodcons buffer; + +void * producer(void * data) +{ + int n; + for (n = 0; n < 10000; n++) { + printf("%d --->\n", n); + put(&buffer, n); + } + put(&buffer, OVER); + return NULL; +} + +void * consumer(void * data) +{ + int d; + while (1) { + d = get(&buffer); + if (d == OVER) break; + printf("---> %d\n", d); + } + return NULL; +} + +int main() +{ + pthread_t th_a, th_b; + void * retval; + + init(&buffer); + /* Create the threads */ + pthread_create(&th_a, NULL, producer, 0); + pthread_create(&th_b, NULL, consumer, 0); + /* Wait until producer and consumer finish. */ + pthread_join(th_a, &retval); + pthread_join(th_b, &retval); + return 0; +} + + + diff --git a/linuxthreads/Examples/ex3.c b/linuxthreads/Examples/ex3.c new file mode 100644 index 0000000000..002bc9042a --- /dev/null +++ b/linuxthreads/Examples/ex3.c @@ -0,0 +1,144 @@ +/* Multi-thread searching. + Illustrates: thread cancellation, cleanup handlers. */ + +#include +#include +#include +#include +#include + +/* Defines the number of searching threads */ +#define NUM_THREADS 5 + +/* Function prototypes */ +void *search(void *); +void print_it(void *); + +/* Global variables */ +pthread_t threads[NUM_THREADS]; +pthread_mutex_t lock; +int tries; + +int main(argc, argv) + int argc; + char ** argv; +{ + int i; + int pid; + + /* create a number to search for */ + pid = getpid(); + printf("Searching for the number = %d...\n", pid); + + /* Initialize the mutex lock */ + pthread_mutex_init(&lock, NULL); + + /* Create the searching threads */ + for (i=0; i +#include +#include +#include +#include + +/* This is a typical example of a library function that uses + static variables to accumulate results between calls. + Here, it just returns the concatenation of all string arguments + that were given to it. */ + +#if 0 + +char * str_accumulate(char * s) +{ + static char accu[1024] = { 0 }; + strcat(accu, s); + return accu; +} + +#endif + +/* Of course, this cannot be used in a multi-threaded program + because all threads store "accu" at the same location. + So, we'll use thread-specific data to have a different "accu" + for each thread. */ + +/* Key identifying the thread-specific data */ +static pthread_key_t str_key; +/* "Once" variable ensuring that the key for str_alloc will be allocated + exactly once. */ +static pthread_once_t str_alloc_key_once = PTHREAD_ONCE_INIT; + +/* Forward functions */ +static void str_alloc_key(void); +static void str_alloc_destroy_accu(void * accu); + +/* Thread-safe version of str_accumulate */ + +char * str_accumulate(char * s) +{ + char * accu; + + /* Make sure the key is allocated */ + pthread_once(&str_alloc_key_once, str_alloc_key); + /* Get the thread-specific data associated with the key */ + accu = (char *) pthread_getspecific(str_key); + /* It's initially NULL, meaning that we must allocate the buffer first. */ + if (accu == NULL) { + accu = malloc(1024); + if (accu == NULL) return NULL; + accu[0] = 0; + /* Store the buffer pointer in the thread-specific data. */ + pthread_setspecific(str_key, (void *) accu); + printf("Thread %lx: allocating buffer at %p\n", pthread_self(), accu); + } + /* Now we can use accu just as in the non thread-safe code. */ + strcat(accu, s); + return accu; +} + +/* Function to allocate the key for str_alloc thread-specific data. */ + +static void str_alloc_key(void) +{ + pthread_key_create(&str_key, str_alloc_destroy_accu); + printf("Thread %lx: allocated key %d\n", pthread_self(), str_key); +} + +/* Function to free the buffer when the thread exits. */ +/* Called only when the thread-specific data is not NULL. */ + +static void str_alloc_destroy_accu(void * accu) +{ + printf("Thread %lx: freeing buffer at %p\n", pthread_self(), accu); + free(accu); +} + +/* Test program */ + +void * process(void * arg) +{ + char * res; + res = str_accumulate("Result of "); + res = str_accumulate((char *) arg); + res = str_accumulate(" thread"); + printf("Thread %lx: \"%s\"\n", pthread_self(), res); + return NULL; +} + +int main(int argc, char ** argv) +{ + char * res; + pthread_t th1, th2; + + res = str_accumulate("Result of "); + pthread_create(&th1, NULL, process, "first"); + pthread_create(&th2, NULL, process, "second"); + res = str_accumulate("initial thread"); + printf("Thread %lx: \"%s\"\n", pthread_self(), res); + pthread_join(th1, NULL); + pthread_join(th2, NULL); + pthread_exit(NULL); +} diff --git a/linuxthreads/Examples/ex5.c b/linuxthreads/Examples/ex5.c new file mode 100644 index 0000000000..366668eb8c --- /dev/null +++ b/linuxthreads/Examples/ex5.c @@ -0,0 +1,102 @@ +/* The classic producer-consumer example, implemented with semaphores. + All integers between 0 and 9999 should be printed exactly twice, + once to the right of the arrow and once to the left. */ + +#include +#include "pthread.h" +#include "semaphore.h" + +#define BUFFER_SIZE 16 + +/* Circular buffer of integers. */ + +struct prodcons { + int buffer[BUFFER_SIZE]; /* the actual data */ + int readpos, writepos; /* positions for reading and writing */ + sem_t sem_read; /* number of elements available for reading */ + sem_t sem_write; /* number of locations available for writing */ +}; + +/* Initialize a buffer */ + +void init(struct prodcons * b) +{ + sem_init(&b->sem_write, 0, BUFFER_SIZE - 1); + sem_init(&b->sem_read, 0, 0); + b->readpos = 0; + b->writepos = 0; +} + +/* Store an integer in the buffer */ + +void put(struct prodcons * b, int data) +{ + /* Wait until buffer is not full */ + sem_wait(&b->sem_write); + /* Write the data and advance write pointer */ + b->buffer[b->writepos] = data; + b->writepos++; + if (b->writepos >= BUFFER_SIZE) b->writepos = 0; + /* Signal that the buffer contains one more element for reading */ + sem_post(&b->sem_read); +} + +/* Read and remove an integer from the buffer */ + +int get(struct prodcons * b) +{ + int data; + /* Wait until buffer is not empty */ + sem_wait(&b->sem_read); + /* Read the data and advance read pointer */ + data = b->buffer[b->readpos]; + b->readpos++; + if (b->readpos >= BUFFER_SIZE) b->readpos = 0; + /* Signal that the buffer has now one more location for writing */ + sem_post(&b->sem_write); + return data; +} + +/* A test program: one thread inserts integers from 1 to 10000, + the other reads them and prints them. */ + +#define OVER (-1) + +struct prodcons buffer; + +void * producer(void * data) +{ + int n; + for (n = 0; n < 10000; n++) { + printf("%d --->\n", n); + put(&buffer, n); + } + put(&buffer, OVER); + return NULL; +} + +void * consumer(void * data) +{ + int d; + while (1) { + d = get(&buffer); + if (d == OVER) break; + printf("---> %d\n", d); + } + return NULL; +} + +int main() +{ + pthread_t th_a, th_b; + void * retval; + + init(&buffer); + /* Create the threads */ + pthread_create(&th_a, NULL, producer, 0); + pthread_create(&th_b, NULL, consumer, 0); + /* Wait until producer and consumer finish. */ + pthread_join(th_a, &retval); + pthread_join(th_b, &retval); + return 0; +} diff --git a/linuxthreads/FAQ.html b/linuxthreads/FAQ.html new file mode 100644 index 0000000000..45d2387db2 --- /dev/null +++ b/linuxthreads/FAQ.html @@ -0,0 +1,986 @@ + + +LinuxThreads Frequently Asked Questions + + +

LinuxThreads Frequently Asked Questions
+ (with answers)

+ +

+ +A. The big picture
+B. Getting more information
+C. Issues related to the C library
+D. Problems, weird behaviors, potential bugs
+E. Missing functions, wrong types, etc
+F. C++ issues
+G. Debugging LinuxThreads programs
+H. Compiling multithreaded code; errno madness
+I. X-Windows and other libraries
+J. Signals and threads
+K. Internals of LinuxThreads

+ +


+

+ +

A. The big picture

+ +

A.1: What is LinuxThreads?

+ +LinuxThreads is a Linux library for multi-threaded programming. +It implements the Posix 1003.1c API (Application Programming +Interface) for threads. It runs on any Linux system with kernel 2.0.0 +or more recent, and a suitable C library (see section B). +

+ +

A.2: What are threads?

+ +A thread is a sequential flow of control through a program. +Multi-threaded programming is, thus, a form of parallel programming +where several threads of control are executing concurrently in the +program. All threads execute in the same memory space, and can +therefore work concurrently on shared data.

+ +Multi-threaded programming differs from Unix-style multi-processing in +that all threads share the same memory space (and a few other system +resources, such as file descriptors), instead of running in their own +memory space as is the case with Unix processes.

+ +Threads are useful for two reasons. First, they allow a program to +exploit multi-processor machines: the threads can run in parallel on +several processors, allowing a single program to divide its work +between several processors, thus running faster than a single-threaded +program, which runs on only one processor at a time. Second, some +programs are best expressed as several threads of control that +communicate together, rather than as one big monolithic sequential +program. Examples include server programs, overlapping asynchronous +I/O, and graphical user interfaces.

+ +

A.3: What is POSIX 1003.1c?

+ +It's an API for multi-threaded programming standardized by IEEE as +part of the POSIX standards. Most Unix vendors have endorsed the +POSIX 1003.1c standard. Implementations of the 1003.1c API are +already available under Sun Solaris 2.5, Digital Unix 4.0, +Silicon Graphics IRIX 6, and should soon be available from other +vendors such as IBM and HP. More generally, the 1003.1c API is +replacing relatively quickly the proprietary threads library that were +developed previously under Unix, such as Mach cthreads, Solaris +threads, and IRIX sprocs. Thus, multithreaded programs using the +1003.1c API are likely to run unchanged on a wide variety of Unix +platforms.

+ +

A.4: What is the status of LinuxThreads?

+ +In short, it's not completely finished (hence the version numbers in +0.x), but what is done is pretty mature. +LinuxThreads implements almost all of Posix 1003.1c, as well as a few +extensions. The only part of LinuxThreads that does not conform yet +to Posix is signal handling (see section J). Apart +from the signal stuff, all the Posix 1003.1c base functionality is +provided and conforms to the standard (to the best of my knowledge). +The signal stuff is hard to get right, at least without special kernel +support, and while I'm definitely looking at ways to implement the +Posix behavior for signals, this might take a long time before it's +completed.

+ +

A.5: How stable is LinuxThreads?

+ +The basic functionality (thread creation and termination, mutexes, +conditions, semaphores) is very stable. Several industrial-strength +programs, such as the AOL multithreaded Web server, use LinuxThreads +and seem quite happy about it. There are some rough edges in +the LinuxThreads / C library interface, at least with libc 5, but most +of these rough edges are fixed in glibc 2, which should soon become +the standard C library for Linux distributions (see section C).

+ +


+

+ +

B. Getting more information

+ +

B.1: What are good books and other sources of +information on POSIX threads?

+ +The FAQ for comp.programming.threads lists several books: +http://www.serpentine.com/~bos/threads-faq/.

+ +There are also some online tutorials. Follow the links from the +LinuxThreads web page: +http://pauillac.inria.fr/~xleroy/linuxthreads.

+ +

B.2: I'd like to be informed of future developments on +LinuxThreads. Is there a mailing list for this purpose?

+ +I post LinuxThreads-related announcements on the newsgroup +comp.os.linux.announce, +and also on the mailing list +linux-threads@magenet.com. +You can subscribe to the latter by writing +majordomo@magenet.com.

+ +

B.3: What are good places for discussing +LinuxThreads?

+ +For questions about programming with POSIX threads in general, use +the newsgroup +comp.programming.threads. +Be sure you read the +FAQ +for this group before you post.

+ +For Linux-specific questions, use +comp.os.linux.development.apps +and comp.os.linux.development.kernel. +The latter is especially appropriate for questions relative to the +interface between the kernel and LinuxThreads.

+ +Very specific LinuxThreads questions, and in particular everything +that looks like a potential bug in LinuxThreads, should be mailed +directly to me (Xavier.Leroy@inria.fr). Before mailing +me, make sure that your question is not answered in this FAQ.

+ +

B.4: I'd like to read the POSIX 1003.1c standard. Is +it available online?

+ +Unfortunately, no. POSIX standards are copyrighted by IEEE, and +IEEE does not distribute them freely. You can buy paper copies from +IEEE, but the price is fairly high ($120 or so). If you disagree with +this policy and you're an IEEE member, be sure to let them know.

+ +On the other hand, you probably don't want to read the standard. It's +very hard to read, written in standard-ese, and targeted to +implementors who already know threads inside-out. A good book on +POSIX threads provides the same information in a much more readable form. +I can personally recommend Dave Butenhof's book, Programming +with POSIX threads (Addison-Wesley). Butenhof was part of the +POSIX committee and also designed the Digital Unix implementations of +POSIX threads, and it shows.

+ +Another good source of information is the X/Open Group Single Unix +specification which is available both +on-line +and as a +book and CD/ROM. +That specification includes pretty much all the POSIX standards, +including 1003.1c, with some extensions and clarifications.

+ +


+

+ +

C. Issues related to the C library

+ +

C.1: Which version of the C library should I use +with LinuxThreads?

+ +Most current Linux distributions come with libc version 5, maintained +by H.J.Lu. For LinuxThreads to work properly, you must use either +libc 5.2.18 or libc 5.4.12 or later. Avoid 5.3.12 and 5.4.7: these +have problems with the per-thread errno variable. +

+ +Unfortunately, many popular Linux distributions (e.g. RedHat 4.2) come +with libc 5.3.12 preinstalled -- the one that does not work with +LinuxThreads. Fortunately, you can often find pre-packaged binaries +of more recent versions of libc for these distributions. In the case +of RedHat 4, there is a RPM package for libc-5.4 in the "contrib" +area of RedHat FTP sites. +

+ +

C.2: What about glibc 2, a.k.a. libc 6?

+ +It's the next generation libc for Linux, developed by Ulrich +Drepper and other FSF collaborators. glibc 2 offers much better +support for threads than libc 5. Indeed, thread support was +planned from the very early stages of glibc 2, while it's a +last-minute addition to libc 5. glibc 2 actually comes with a +specially adapted version of LinuxThreads, which you can drop in the +glibc 2 sources as an add-on package. + +

C.3: So, should I switch to glibc 2, or stay with a +recent libc 5?

+ +Depends how you plan to do it. Switching an already installed +system from libc 5 to glibc 2 is not completely straightforward. +See the Glibc2 +HOWTO for more information. +But (re-)installing a Linux distribution based on glibc 2 is easy. +One such distribution available now is RedHat 5.0. Debian and other +Linux distributors will also provide glibc 2-based distributions in the +near future. +

+ +

C.4: Where can I find glibc 2 and the version of +LinuxThreads that goes with it?

+ +On prep.ai.mit.edu and its many, many mirrors around the world. +See http://www.gnu.org/order/ftp.html +for a list of mirrors.

+ +


+

+ +

D. Problems, weird behaviors, potential bugs

+ +

D.1: When I compile LinuxThreads, I run into problems in +file libc_r/dirent.c

+ +You probably mean: +
 
+        libc_r/dirent.c:94: structure has no member named `dd_lock'
+
+I haven't actually seen this problem, but several users reported it. +My understanding is that something is wrong in the include files of +your Linux installation (/usr/include/*). Make sure +you're using a supported version of the C library. (See section B).

+ +

D.2: When I compile LinuxThreads, I run into problems with +/usr/include/sched.h: there are several occurrences of +_p that the C compiler does not understand

+ +Yes, /usr/include/sched.h that comes with libc 5.3.12 is broken. +Replace it with the sched.h file contained in the +LinuxThreads distribution. But really you should not be using libc +5.3.12 with LinuxThreads! (See question C.1.)

+ +

D.3: My program does fdopen() on a file +descriptor opened on a pipe. When I link it with LinuxThreads, +fdopen() always returns NULL!

+ +You're using one of the buggy versions of libc (5.3.12, 5.4.7., etc). +See question C.1 above.

+ +

D.4: My program crashes the first time it calls +pthread_create() !

+ +You wouldn't be using glibc 2.0, by any chance? That's a known bug +with glibc 2.0. Please upgrade to 2.0.1 or later.

+ +

D.5: When I'm running a program that creates N +threads, top or ps +display N+2 processes that are running my program. What do all these +processes correspond to?

+ +Due to the general "one process per thread" model, there's one process +for the initial thread and N processes for the threads it created +using pthread_create. That leaves one process +unaccounted for. That extra process corresponds to the "thread +manager" thread, a thread created internally by LinuxThreads to handle +thread creation and thread termination. This extra thread is asleep +most of the time. + +

D.6: Scheduling seems to be very unfair when there +is strong contention on a mutex: instead of giving the mutex to each +thread in turn, it seems that it's almost always the same thread that +gets the mutex. Isn't this completely broken behavior?

+ +What happens is the following: when a thread unlocks a mutex, all +other threads that were waiting on the mutex are sent a signal which +makes them runnable. However, the kernel scheduler may or may not +restart them immediately. If the thread that unlocked the mutex +tries to lock it again immediately afterwards, it is likely that it +will succeed, because the threads haven't yet restarted. This results +in an apparently very unfair behavior, when the same thread repeatedly +locks and unlocks the mutex, while other threads can't lock the mutex.

+ +This is perfectly acceptable behavior with respect to the POSIX +standard: for the default scheduling policy, POSIX makes no guarantees +of fairness, such as "the thread waiting for the mutex for the longest +time always acquires it first". This allows implementations of +mutexes to remain simple and efficient. Properly written +multithreaded code avoids that kind of heavy contention on mutexes, +and does not run into fairness problems. If you need scheduling +guarantees, you should consider using the real-time scheduling +policies SCHED_RR and SCHED_FIFO, which have +precisely defined scheduling behaviors.

+ +

D.7: I have a simple test program with two threads +that do nothing but printf() in tight loops, and from the +printout it seems that only one thread is running, the other doesn't +print anything!

+ +If you wait long enough, you should see the second thread kick in. +But still, you're right, one thread prevents the other one from +running for long periods of time. The reason is explained in +question D.6 above: printf() performs +locking on stdout, and thus your two threads contend very +heavily for the mutex associated with stdout. But if you +do some real work between two calls to printf(), you'll +see that scheduling becomes much smoother.

+ +

D.8: I've looked at <pthread.h> +and there seems to be a gross error in the pthread_cleanup_push +macro: it opens a block with { but does not close it! +Surely you forgot a } at the end of the macro, right? +

+ +Nope. That's the way it should be. The closing brace is provided by +the pthread_cleanup_pop macro. The POSIX standard +requires pthread_cleanup_push and +pthread_cleanup_pop to be used in matching pairs, at the +same level of brace nesting. This allows +pthread_cleanup_push to open a block in order to +stack-allocate some data structure, and +pthread_cleanup_pop to close that block. It's ugly, but +it's the standard way of implementing cleanup handlers.

+ +


+

+ +

E. Missing functions, wrong types, etc

+ +

E.1: Where is pthread_yield() ? How +comes LinuxThreads does not implement it?

+ +Because it's not part of the (final) POSIX 1003.1c standard. +Several drafts of the standard contained pthread_yield(), +but then the POSIX guys discovered it was redundant with +sched_yield() and dropped it. So, just use +sched_yield() instead. + +

E.2: I've found some type errors in +<pthread.h>. +For instance, the second argument to pthread_create() +should be a pthread_attr_t, not a +pthread_attr_t *. Also, didn't you forget to declare +pthread_attr_default?

+ +No, I didn't. What you're describing is draft 4 of the POSIX +standard, which is used in OSF DCE threads. LinuxThreads conforms to the +final standard. Even though the functions have the same names as in +draft 4 and DCE, their calling conventions are slightly different. In +particular, attributes are passed by reference, not by value, and +default attributes are denoted by the NULL pointer. Since draft 4/DCE +will eventually disappear, you'd better port your program to use the +standard interface.

+ +

E.3: I'm porting an application from Solaris and I +have to rename all thread functions from thr_blah to +pthread_blah. This is very annoying. Why did you change +all the function names?

+ +POSIX did it. The thr_* functions correspond to Solaris +threads, an older thread interface that you'll find only under +Solaris. The pthread_* functions correspond to POSIX +threads, an international standard available for many, many platforms. +Even Solaris 2.5 and later support the POSIX threads interface. So, +do yourself a favor and rewrite your code to use POSIX threads: this +way, it will run unchanged under Linux, Solaris, and quite a lot of