aboutsummaryrefslogtreecommitdiff
path: root/linuxthreads/FAQ.html
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-03-11 12:42:25 +0000
committerUlrich Drepper <drepper@redhat.com>1998-03-11 12:42:25 +0000
commit5afdca0087dad2994ad4fcdfe7f489f4dbcab7b3 (patch)
treec9c82db2ff92537b921361a02a284b0e18a594b8 /linuxthreads/FAQ.html
parent3d76e7784700c20fc222920b2a22baba006daa15 (diff)
downloadglibc-5afdca0087dad2994ad4fcdfe7f489f4dbcab7b3.tar.xz
glibc-5afdca0087dad2994ad4fcdfe7f489f4dbcab7b3.zip
LinuxThreads library.
1998-03-11 00:42 Wolfram Gloger <wmglo@dent.med.uni-muenchen.de> * 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 <drepper@cygnus.com> * 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 <signal.h>. * 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 <drepper@cygnus.com> * 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 <pb@nexus.co.uk> * sysdeps/arm/pt-machine.h: New file; add ARM support. * sysdeps/arm/Implies: likewise. * README: Document it. 1997-12-13 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * signals.c: Remove unneeded initializer for sigwaited, saving a 1997-04-11 01:18 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * semaphore.c (sem_init): Set sem_spinlock only if available. 1997-12-04 01:48 Ulrich Drepper <drepper@cygnus.com> * 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 <drepper@cygnus.com> * pthread.c (__pthread_reset_main_thread): Close pipe only if still open. 1997-10-29 05:38 Ulrich Drepper <drepper@cygnus.com> * wrapsyscall.c: Add socket functions which are also cancelation points. 1997-10-19 21:40 Wolfram Gloger <wg@wolfram.dent.med.uni-muenchen.de> * 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 <drepper@cygnus.com> * semaphore.h: Add __BEGIN_DECLS/__END_DECLS. Reported by Ralf Corsepius <corsepiu@faw.uni-ulm.de>. 1997-08-29 03:05 Ulrich Drepper <drepper@cygnus.com> * 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 <rth@cygnus.com> 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 <drepper@cygnus.com> * 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 <richard@gnu.ai.mit.edu> Initial sparc64-linux support: * linuxthreads/sysdeps/sparc64/Implies: New file. * linuxthreads/sysdeps/sparc64/pt-machine.h: Likewise. 1997-06-29 00:48 Ulrich Drepper <drepper@cygnus.com> * semaphore.c: Include spinlock.h at correct place. Patch by HJ Lu. 1997-06-13 10:06 Richard Henderson <rth@tamu.edu> 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: <foo.h> -> <bits/foo.h>. * semaphore.h: Likewise. * Makefile: (headers): foo.h -> bits/foo.h. * sysdeps/pthread/Makefile: Likewise. 1997-04-11 01:18 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * 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 <drepper@cygnus.com> 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 <drepper@cygnus.com> * restart.h (suspend): Clear p_signal before suspending. (suspend_with_cancellation): Likewise. Patch by Xavier Leroy <Xavier.Leroy@inria.fr>. * 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 <miguel@nuclecu.unam.mx> * sysdeps/sparc/pt-machine (RELEASE): Fix. 1997-03-01 07:55 Geoff Keating <geoffk@ozemail.com.au> * sysdeps/powerpc/Implies: Added. * sysdeps/powerpc/pt-machine.h: Added. * sysdeps/powerpc/semaphorebits.h: Added. 1997-01-22 01:22 Ulrich Drepper <drepper@cygnus.com> * linuxtheads/pthread.c (__pthread_initial_thread): Correct initializer. (__pthread_manager_thread): Likewise. Reported by Andreas Jaeger. 1997-01-18 22:15 Richard Henderson <rth@tamu.edu> 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.
Diffstat (limited to 'linuxthreads/FAQ.html')
-rw-r--r--linuxthreads/FAQ.html986
1 files changed, 986 insertions, 0 deletions
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 @@
+<HTML>
+<HEAD>
+<TITLE>LinuxThreads Frequently Asked Questions</TITLE>
+</HEAD>
+<BODY>
+<H1 ALIGN=center>LinuxThreads Frequently Asked Questions <BR>
+ (with answers)</H1>
+
+<HR><P>
+
+<A HREF="#A">A. The big picture</A><BR>
+<A HREF="#B">B. Getting more information</A><BR>
+<A HREF="#C">C. Issues related to the C library</A><BR>
+<A HREF="#D">D. Problems, weird behaviors, potential bugs</A><BR>
+<A HREF="#E">E. Missing functions, wrong types, etc</A><BR>
+<A HREF="#F">F. C++ issues</A><BR>
+<A HREF="#G">G. Debugging LinuxThreads programs</A><BR>
+<A HREF="#H">H. Compiling multithreaded code; errno madness</A><BR>
+<A HREF="#I">I. X-Windows and other libraries</A><BR>
+<A HREF="#J">J. Signals and threads</A><BR>
+<A HREF="#K">K. Internals of LinuxThreads</A><P>
+
+<HR>
+<P>
+
+<H2><A NAME="A">A. The big picture</A></H2>
+
+<H4><A NAME="A.1">A.1: What is LinuxThreads?</A></H4>
+
+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 <A HREF="B">B</A>).
+<P>
+
+<H4><A NAME="A.2">A.2: What are threads?</A></H4>
+
+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.<P>
+
+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.<P>
+
+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.<P>
+
+<H4><A NAME="A.3">A.3: What is POSIX 1003.1c?</A></H4>
+
+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.<P>
+
+<H4><A NAME="A.4">A.4: What is the status of LinuxThreads?</A></H4>
+
+In short, it's not completely finished (hence the version numbers in
+0.<I>x</I>), 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 <A HREF="#J">J</A>). 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.<P>
+
+<H4><A NAME="A.5">A.5: How stable is LinuxThreads?</A></H4>
+
+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 <A
+HREF="#C">C</A>). <P>
+
+<HR>
+<P>
+
+<H2><A NAME="B">B. Getting more information</A></H2>
+
+<H4><A NAME="B.1">B.1: What are good books and other sources of
+information on POSIX threads?</A></H4>
+
+The FAQ for comp.programming.threads lists several books:
+<A HREF="http://www.serpentine.com/~bos/threads-faq/">http://www.serpentine.com/~bos/threads-faq/</A>.<P>
+
+There are also some online tutorials. Follow the links from the
+LinuxThreads web page:
+<A HREF="http://pauillac.inria.fr/~xleroy/linuxthreads">http://pauillac.inria.fr/~xleroy/linuxthreads</A>.<P>
+
+<H4><A NAME="B.2">B.2: I'd like to be informed of future developments on
+LinuxThreads. Is there a mailing list for this purpose?</A></H4>
+
+I post LinuxThreads-related announcements on the newsgroup
+<A HREF="news:comp.os.linux.announce">comp.os.linux.announce</A>,
+and also on the mailing list
+<code>linux-threads@magenet.com</code>.
+You can subscribe to the latter by writing
+<A HREF="mailto:majordomo@magenet.com">majordomo@magenet.com</A>.<P>
+
+<H4><A NAME="B.3">B.3: What are good places for discussing
+LinuxThreads?</A></H4>
+
+For questions about programming with POSIX threads in general, use
+the newsgroup
+<A HREF="news:comp.programming.threads">comp.programming.threads</A>.
+Be sure you read the
+<A HREF="http://www.serpentine.com/~bos/threads-faq/">FAQ</A>
+for this group before you post.<P>
+
+For Linux-specific questions, use
+<A
+HREF="news:comp.os.linux.development.apps">comp.os.linux.development.apps</A>
+and <A
+HREF="news:comp.os.linux.development.kernel">comp.os.linux.development.kernel</A>.
+The latter is especially appropriate for questions relative to the
+interface between the kernel and LinuxThreads.<P>
+
+Very specific LinuxThreads questions, and in particular everything
+that looks like a potential bug in LinuxThreads, should be mailed
+directly to me (<code>Xavier.Leroy@inria.fr</code>). Before mailing
+me, make sure that your question is not answered in this FAQ.<P>
+
+<H4><A NAME="B.4">B.4: I'd like to read the POSIX 1003.1c standard. Is
+it available online?</A></H4>
+
+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.<P>
+
+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, <CITE>Programming
+with POSIX threads</CITE> (Addison-Wesley). Butenhof was part of the
+POSIX committee and also designed the Digital Unix implementations of
+POSIX threads, and it shows.<P>
+
+Another good source of information is the X/Open Group Single Unix
+specification which is available both
+<A HREF="http://www.rdg.opengroup.org/onlinepubs/7908799/index.html">on-line</A>
+and as a
+<A HREF="http://www.UNIX-systems.org/gosolo2/">book and CD/ROM</A>.
+That specification includes pretty much all the POSIX standards,
+including 1003.1c, with some extensions and clarifications.<P>
+
+<HR>
+<P>
+
+<H2><A NAME="C">C. Issues related to the C library</A></H2>
+
+<H4><A NAME="C.1">C.1: Which version of the C library should I use
+with LinuxThreads?</A></H4>
+
+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.
+<P>
+
+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.
+<P>
+
+<H4><A NAME="C.2">C.2: What about glibc 2, a.k.a. libc 6?</A></H4>
+
+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.
+
+<H4><A NAME="C.3">C.3: So, should I switch to glibc 2, or stay with a
+recent libc 5?</A></H4>
+
+Depends how you plan to do it. Switching an already installed
+system from libc 5 to glibc 2 is not completely straightforward.
+See the <A HREF="http://sunsite.unc.edu/LDP/HOWTO/Glibc2-HOWTO.html">Glibc2
+HOWTO</A> 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.
+<P>
+
+<H4><A NAME="C.4">C.4: Where can I find glibc 2 and the version of
+LinuxThreads that goes with it?</A></H4>
+
+On <code>prep.ai.mit.edu</code> and its many, many mirrors around the world.
+See <A
+HREF="http://www.gnu.org/order/ftp.html">http://www.gnu.org/order/ftp.html</A>
+for a list of mirrors.<P>
+
+<HR>
+<P>
+
+<H2><A NAME="D">D. Problems, weird behaviors, potential bugs</A></H2>
+
+<H4><A NAME="D.1">D.1: When I compile LinuxThreads, I run into problems in
+file <code>libc_r/dirent.c</code></A></H4>
+
+You probably mean:
+<PRE>
+ libc_r/dirent.c:94: structure has no member named `dd_lock'
+</PRE>
+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 (<code>/usr/include/*</code>). Make sure
+you're using a supported version of the C library. (See section <A
+HREF="#B">B</A>).<P>
+
+<H4><A NAME="D.2">D.2: When I compile LinuxThreads, I run into problems with
+<CODE>/usr/include/sched.h</CODE>: there are several occurrences of
+<CODE>_p</CODE> that the C compiler does not understand</A></H4>
+
+Yes, <CODE>/usr/include/sched.h</CODE> that comes with libc 5.3.12 is broken.
+Replace it with the <code>sched.h</code> file contained in the
+LinuxThreads distribution. But really you should not be using libc
+5.3.12 with LinuxThreads! (See question <A HREF="#C.1">C.1</A>.)<P>
+
+<H4><A NAME="D.3">D.3: My program does <CODE>fdopen()</CODE> on a file
+descriptor opened on a pipe. When I link it with LinuxThreads,
+<CODE>fdopen()</CODE> always returns NULL!</A></H4>
+
+You're using one of the buggy versions of libc (5.3.12, 5.4.7., etc).
+See question <A HREF="#C.1">C.1</A> above.<P>
+
+<H4><A NAME="D.4">D.4: My program crashes the first time it calls
+<CODE>pthread_create()</CODE> !</A></H4>
+
+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.<P>
+
+<H4><A NAME="D.5">D.5: When I'm running a program that creates N
+threads, <code>top</code> or <code>ps</code>
+display N+2 processes that are running my program. What do all these
+processes correspond to?</A></H4>
+
+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 <CODE>pthread_create</CODE>. 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.
+
+<H4><A NAME="D.6">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?</A></H4>
+
+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.<P>
+
+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 <code>SCHED_RR</code> and <code>SCHED_FIFO</code>, which have
+precisely defined scheduling behaviors. <P>
+
+<H4><A NAME="D.7">D.7: I have a simple test program with two threads
+that do nothing but <CODE>printf()</CODE> in tight loops, and from the
+printout it seems that only one thread is running, the other doesn't
+print anything!</A></H4>
+
+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 <A HREF="#D.6">D.6</A> above: <CODE>printf()</CODE> performs
+locking on <CODE>stdout</CODE>, and thus your two threads contend very
+heavily for the mutex associated with <CODE>stdout</CODE>. But if you
+do some real work between two calls to <CODE>printf()</CODE>, you'll
+see that scheduling becomes much smoother. <P>
+
+<H4><A NAME="D.8">D.8: I've looked at <code>&lt;pthread.h&gt;</code>
+and there seems to be a gross error in the <code>pthread_cleanup_push</code>
+macro: it opens a block with <code>{</code> but does not close it!
+Surely you forgot a <code>}</code> at the end of the macro, right?
+</A></H4>
+
+Nope. That's the way it should be. The closing brace is provided by
+the <code>pthread_cleanup_pop</code> macro. The POSIX standard
+requires <code>pthread_cleanup_push</code> and
+<code>pthread_cleanup_pop</code> to be used in matching pairs, at the
+same level of brace nesting. This allows
+<code>pthread_cleanup_push</code> to open a block in order to
+stack-allocate some data structure, and
+<code>pthread_cleanup_pop</code> to close that block. It's ugly, but
+it's the standard way of implementing cleanup handlers.<P>
+
+<HR>
+<P>
+
+<H2><A NAME="E">E. Missing functions, wrong types, etc</A></H2>
+
+<H4><A NAME="E.1">E.1: Where is <CODE>pthread_yield()</CODE> ? How
+comes LinuxThreads does not implement it?</A></H4>
+
+Because it's not part of the (final) POSIX 1003.1c standard.
+Several drafts of the standard contained <CODE>pthread_yield()</CODE>,
+but then the POSIX guys discovered it was redundant with
+<CODE>sched_yield()</CODE> and dropped it. So, just use
+<CODE>sched_yield()</CODE> instead.
+
+<H4><A NAME="E.2">E.2: I've found some type errors in
+<code>&lt;pthread.h&gt;</code>.
+For instance, the second argument to <CODE>pthread_create()</CODE>
+should be a <CODE>pthread_attr_t</CODE>, not a
+<CODE>pthread_attr_t *</CODE>. Also, didn't you forget to declare
+<CODE>pthread_attr_default</CODE>?</A></H4>
+
+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.<P>
+
+<H4><A NAME="E.3">E.3: I'm porting an application from Solaris and I
+have to rename all thread functions from <code>thr_blah</code> to
+<CODE>pthread_blah</CODE>. This is very annoying. Why did you change
+all the function names?</A></H4>
+
+POSIX did it. The <code>thr_*</code> functions correspond to Solaris
+threads, an older thread interface that you'll find only under
+Solaris. The <CODE>pthread_*</CODE> 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
+other platforms.<P>
+
+<H4><A NAME="E.4">E.4: How can I suspend and resume a thread from
+another thread? Solaris has the <CODE>thr_suspend()</CODE> and
+<CODE>thr_resume()</CODE> functions to do that; why don't you?</A></H4>
+
+The POSIX standard provides <B>no</B> mechanism by which a thread A can
+suspend the execution of another thread B, without cooperation from B.
+The only way to implement a suspend/restart mechanism is to have B
+check periodically some global variable for a suspend request
+and then suspend itself on a condition variable, which another thread
+can signal later to restart B.<P>
+
+Notice that <CODE>thr_suspend()</CODE> is inherently dangerous and
+prone to race conditions. For one thing, there is no control on where
+the target thread stops: it can very well be stopped in the middle of
+a critical section, while holding mutexes. Also, there is no
+guarantee on when the target thread will actually stop. For these
+reasons, you'd be much better off using mutexes and conditions
+instead. The only situations that really require the ability to