summaryrefslogtreecommitdiff
path: root/libpthread
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2005-12-27 09:53:03 +0000
committerMike Frysinger <vapier@gentoo.org>2005-12-27 09:53:03 +0000
commit0644d70924f95944ad8ce1b411e2a4634057cc90 (patch)
tree6208dbcd4364fd143773f910124773be07deca58 /libpthread
parent9acaf58149a23501ae138efce10f8944a20e214d (diff)
cut pointless files
Diffstat (limited to 'libpthread')
-rw-r--r--libpthread/linuxthreads.old/Changes85
-rw-r--r--libpthread/linuxthreads.old/FAQ.html1039
-rw-r--r--libpthread/linuxthreads.old/LICENSE501
-rw-r--r--libpthread/linuxthreads.old/README166
-rw-r--r--libpthread/linuxthreads.old/pthread.c-OLDEXAMPLE121
5 files changed, 0 insertions, 1912 deletions
diff --git a/libpthread/linuxthreads.old/Changes b/libpthread/linuxthreads.old/Changes
deleted file mode 100644
index b213f36c5..000000000
--- a/libpthread/linuxthreads.old/Changes
+++ /dev/null
@@ -1,85 +0,0 @@
-Release 0.9:
-- more ports (SH, IA-64, s390)
-- many bug fixes
-- timed sync object wait functions
-- barrier implementation
-- spinlocks implementation
-- thread register on x86
-- variable stack size and position on some platforms
-
-Release 0.8:
-(ehmm, forgot to update, don't know anymore)
-
-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/libpthread/linuxthreads.old/FAQ.html b/libpthread/linuxthreads.old/FAQ.html
deleted file mode 100644
index 21be33ec4..000000000
--- a/libpthread/linuxthreads.old/FAQ.html
+++ /dev/null
@@ -1,1039 +0,0 @@
-<HTML>
-<HEAD>
-<TITLE>LinuxThreads Frequently Asked Questions</TITLE>
-</HEAD>
-<BODY>
-<H1 ALIGN=center>LinuxThreads Frequently Asked Questions <BR>
- (with answers)</H1>
-<H2 ALIGN=center>[For LinuxThreads version 0.8]</H2>
-
-<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="C">C</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>
-
-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,
-as well as a number of optional extensions, are provided and conform
-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 used to be some rough edges in
-the LinuxThreads / C library interface with libc 5, but glibc 2
-fixes all of those problems and is now the standard C library on major
-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>
-
-<H4><A NAME="B.4">B.4: How should I report a possible bug in
-LinuxThreads?</A></H4>
-
-If you're using glibc 2, the best way by far is to use the
-<code>glibcbug</code> script to mail a bug report to the glibc
-maintainers. <P>
-
-If you're using an older libc, or don't have the <code>glibcbug</code>
-script on your machine, then e-mail me directly
-(<code>Xavier.Leroy@inria.fr</code>). <P>
-
-In both cases, before sending the bug report, make sure that it is not
-addressed already in this FAQ. Also, try to send a short program that
-reproduces the weird behavior you observed. <P>
-
-<H4><A NAME="B.5">B.5: 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>
-
-The best choice by far is glibc 2, a.k.a. libc 6. It offers very good
-support for multi-threading, and LinuxThreads has been closely
-integrated with glibc 2. The glibc 2 distribution contains the
-sources of a specially adapted version of LinuxThreads.<P>
-
-glibc 2 comes preinstalled as the default C library on several Linux
-distributions, such as RedHat 5 and up, and Debian 2.
-Those distributions include the version of LinuxThreads matching
-glibc 2.<P>
-
-<H4><A NAME="C.2">C.2: My system has libc 5 preinstalled, not glibc
-2. Can I still use LinuxThreads?</H4>
-
-Yes, but you're likely to run into some problems, as libc 5 only
-offers minimal support for threads and contains some bugs that affect
-multithreaded programs. <P>
-
-The versions of libc 5 that work best with LinuxThreads are
-libc 5.2.18 on the one hand, and libc 5.4.12 or later on the other hand.
-Avoid 5.3.12 and 5.4.7: these have problems with the per-thread errno
-variable. <P>
-
-<H4><A NAME="C.3">C.3: So, should I switch to glibc 2, or stay with a
-recent libc 5?</A></H4>
-
-I'd recommend you switch to glibc 2. Even for single-threaded
-programs, glibc 2 is more solid and more standard-conformant than libc
-5. And the shortcomings of libc 5 almost preclude any serious
-multi-threaded programming.<P>
-
-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. Much easier is (re-)installing a
-Linux distribution based on glibc 2, such as RedHat 6.<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>
-
-<H4><A NAME="C.5">C.5: Where can I find libc 5 and the version of
-LinuxThreads that goes with it?</A></H4>
-
-For libc 5, see <A HREF="ftp://sunsite.unc.edu/pub/Linux/devel/GCC/"><code>ftp://sunsite.unc.edu/pub/Linux/devel/GCC/</code></A>.<P>
-
-For the libc 5 version of LinuxThreads, see
-<A HREF="ftp://ftp.inria.fr/INRIA/Projects/cristal/Xavier.Leroy/linuxthreads/">ftp://ftp.inria.fr/INRIA/Projects/cristal/Xavier.Leroy/linuxthreads/</A>.<P>
-
-<H4><A NAME="C.6">C.6: How can I recompile the glibc 2 version of the
-LinuxThreads sources?</A></H4>
-
-You must transfer the whole glibc sources, then drop the LinuxThreads
-sources in the <code>linuxthreads/</code> subdirectory, then recompile
-glibc as a whole. There are now too many inter-dependencies between
-LinuxThreads and glibc 2 to allow separate re-compilation of LinuxThreads.
-<P>
-
-<H4><A NAME="C.7">C.7: What is the correspondence between LinuxThreads
-version numbers, libc version numbers, and RedHat version
-numbers?</A></H4>
-
-Here is a summary. (Information on Linux distributions other than
-RedHat are welcome.)<P>
-
-<TABLE>
-<TR><TD>LinuxThreads </TD> <TD>C library</TD> <TD>RedHat</TD></TR>
-<TR><TD>0.7, 0.71 (for libc 5)</TD> <TD>libc 5.x</TD> <TD>RH 4.2</TD></TR>
-<TR><TD>0.7, 0.71 (for glibc 2)</TD> <TD>glibc 2.0.x</TD> <TD>RH 5.x</TD></TR>
-<TR><TD>0.8</TD> <TD>glibc 2.1.1</TD> <TD>RH 6.0</TD></TR>
-<TR><TD>0.8</TD> <TD>glibc 2.1.2</TD> <TD>not yet released</TD></TR>
-</TABLE>
-<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 libc 5 library. (See question <A
-HREF="#C.2">C.2</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.2">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 creates a lot of threads, and after
-a while <CODE>pthread_create()</CODE> no longer returns!</A></H4>
-
-This is known bug in the version of LinuxThreads that comes with glibc
-2.1.1. An upgrade to 2.1.2 is recommended. <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>
-
-That behavior has mostly disappeared in recent releases of
-LinuxThreads (version 0.8 and up). It was fairly common in older
-releases, though.
-
-What happens in LinuxThreads 0.7 and before 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>
-
-In LinuxThreads 0.8 and up, <code>pthread_unlock</code> restarts only
-one waiting thread, and pre-assign the mutex to that thread. Hence,
-if the thread that unlocked the mutex tries to lock it again
-immediately, it will block until other waiting threads have had a
-chance to lock and unlock the mutex. This results in much fairer
-scheduling.<P>
-
-Notice however that even the old "unfair" behavior is perfectly
-acceptable 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". 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>
-
-Again, this behavior is characteristic of old releases of LinuxThreads
-(0.7 and before); more recent versions (0.8 and up) should not exhibit
-this behavior.<P>
-
-The reason for this behavior 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>
-
-<H4><A NAME="D.9">D.9: I tried to use real-time threads and my program
-loops like crazy and freezes the whole machine!</A></H4>
-
-Versions of LinuxThreads prior to 0.8 are susceptible to ``livelocks''
-(one thread loops, consuming 100% of the CPU time) in conjunction with
-real-time scheduling. Since real-time threads and processes have
-higher priority than normal Linux processes, all other processes on
-the machine, including the shell, the X server, etc, cannot run and
-the machine appears frozen.<P>
-
-The problem is fixed in LinuxThreads 0.8.<P>
-
-<H4><A NAME="D.10">D.10: My application needs to create thousands of
-threads, or maybe even more. Can I do this with
-LinuxThreads?</A></H4>
-
-No. You're going to run into several hard limits:
-<UL>
-<LI>Each thread, from the kernel's standpoint, is one process. Stock
-Linux kernels are limited to at most 512 processes for the super-user,
-and half this number for regular users. This can be changed by
-changing <code>NR_TASKS</code> in <code>include/linux/tasks.h</code>
-and recompiling the kernel. On the x86 processors at least,
-architectural constraints seem to limit <code>NR_TASKS</code> to 4090
-at most.
-<LI>LinuxThreads contains a table of all active threads. This table
-has room for 1024 threads at most. To increase this limit, you must
-change <code>PTHREAD_THREADS_MAX</code> in the LinuxThreads sources
-and recompile.
-<LI>By default, each thread reserves 2M of virtual memory space for
-its stack. This space is just reserved; actual memory is allocated
-for the stack on demand. But still, on a 32-bit processor, the total
-virtual memory space available for the stacks is on the order of 1G,
-meaning that more than 500 threads will have a hard time fitting in.
-You can overcome this limitation by moving to a 64-bit platform, or by
-allocating smaller stacks yourself using the <code>setstackaddr</code>
-attribute.
-<LI>Finally, the Linux kernel contains many algorithms that run in
-time proportional to the number of process table entries. Increasing
-this number drastically will slow down the kernel operations
-noticeably.
-</UL>
-(Other POSIX threads libraries have similar limitations, by the way.)
-For all those reasons, you'd better restructure your application so
-that it doesn't need more than, say, 100 threads. For instance,
-in the case of a multithreaded server, instead of creating a new
-thread for each connection, maintain a fixed-size pool of worker
-threads that pick incoming connection requests from a queue.<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
-suspend a thread are debuggers and some kind of garbage collectors.<P>
-
-If you really must suspend a thread in LinuxThreads, you can send it a
-<CODE>SIGSTOP</CODE> signal with <CODE>pthread_kill</CODE>. Send
-<CODE>SIGCONT</CODE> for restarting it.
-Beware, this is specific to LinuxThreads and entirely non-portable.
-Indeed, a truly conforming POSIX threads implementation will stop all
-threads when one thread receives the <CODE>SIGSTOP</CODE> signal!
-One day, LinuxThreads will implement that behavior, and the
-non-portable hack with <CODE>SIGSTOP</CODE> won't work anymore.<P>
-
-<H4><A NAME="E.5">E.5: Does LinuxThreads implement
-<CODE>pthread_attr_setstacksize()</CODE> and
-<CODE>pthread_attr_setstackaddr()</CODE>?</A></H4>
-
-These optional functions are provided in recent versions of
-LinuxThreads (0.8 and up). Earlier releases did not provide these
-optional components of the POSIX standard.<P>
-
-Even if <CODE>pthread_attr_setstacksize()</CODE> and
-<CODE>pthread_attr_setstackaddr()</CODE> are now provided, we still
-recommend that you do not use them unless you really have strong
-reasons for doing so. The default stack allocation strategy for
-LinuxThreads is nearly optimal: stacks start small (4k) and
-automatically grow on demand to a fairly large limit (2M).
-Moreover, there is no portable way to estimate the stack requirements
-of a thread, so setting the stack size yourself makes your program
-less reliable and non-portable.<P>
-
-<H4><A NAME="E.6">E.6: LinuxThreads does not support the
-<CODE>PTHREAD_SCOPE_PROCESS</CODE> value of the "contentionscope"
-attribute. Why? </A></H4>
-
-With a "one-to-one" model, as in LinuxThreads (one kernel execution
-context per thread), there is only one scheduler for all processes and
-all threads on the system. So, there is no way to obtain the behavior of
-<CODE>PTHREAD_SCOPE_PROCESS</CODE>.
-
-<H4><A NAME="E.7">E.7: LinuxThreads does not implement process-shared
-mutexes, conditions, and semaphores. Why?</A></H4>
-
-This is another optional component of the POSIX standard. Portable
-applications should test <CODE>_POSIX_THREAD_PROCESS_SHARED</CODE>
-before using this facility.
-<P>
-The goal of this extension is to allow different processes (with
-different address spaces) to synchronize through mutexes, conditions
-or semaphores allocated in shared memory (either SVR4 shared memory
-segments or <CODE>mmap()</CODE>ed files).
-<P>
-The reason why this does not work in LinuxThreads is that mutexes,
-conditions, and semaphores are not self-contained: their waiting
-queues contain pointers to linked lists of thread descriptors, and
-these pointers are meaningful only in one address space.
-<P>
-Matt Messier and I spent a significant amount of time trying to design a
-suitable mechanism for sharing waiting queues between processes. We
-came up with several solutions that combined two of the following
-three desirable features, but none that combines all three:
-<UL>
-<LI>allow sharing between processes having different UIDs
-<LI>supports cancellation
-<LI>supports <CODE>pthread_cond_timedwait</CODE>
-</UL>
-We concluded that kernel support is required to share mutexes,
-conditions and semaphores between processes. That's one place where
-Linus Torvalds's intuition that "all we need in the kernel is
-<CODE>clone()</CODE>" fails.
-<P>
-Until suitable kernel support is available, you'd better use
-traditional interprocess communications to synchronize different
-processes: System V semaphores and message queues, or pipes, or sockets.
-<P>
-
-<HR>
-<P>
-
-<H2><A NAME="F">F. C++ issues</A></H2>
-
-<H4><A NAME="F.1">F.1: Are there C++ wrappers for LinuxThreads?</A></H4>
-
-Douglas Schmidt's ACE library contains, among a lot of other
-things, C++ wrappers for LinuxThreads and quite a number of other
-thread libraries. Check out
-<A HREF="http://www.cs.wustl.edu/~schmidt/ACE.html">http://www.cs.wustl.edu/~schmidt/ACE.html</A><P>
-
-<H4><A NAME="F.2">F.2: I'm trying to use LinuxThreads from a C++
-program, and the compiler complains about the third argument to
-<CODE>pthread_create()</CODE> !</A></H4>
-
-You're probably trying to pass a class member function or some
-other C++ thing as third argument to <CODE>pthread_create()</CODE>.
-Recall that <CODE>pthread_create()</CODE> is a C function, and it must
-be passed a C function as third argument.<P>
-
-<H4><A NAME="F.3">F.3: I'm trying to use LinuxThreads in conjunction
-with libg++, and I'm having all sorts of trouble.</A></H4>
-
->From what I understand, thread support in libg++ is completely broken,
-especially with respect to locking of iostreams. H.J.Lu wrote:
-<BLOCKQUOTE>
-If you want to use thread, I can only suggest egcs and glibc. You
-can find egcs at
-<A HREF="http://www.cygnus.com/egcs">http://www.cygnus.com/egcs</A>.
-egcs has libsdtc++, which is MT safe under glibc 2. If you really
-want to use the libg++, I have a libg++ add-on for egcs.
-</BLOCKQUOTE>
-<HR>
-<P>
-
-<H2><A NAME="G">G. Debugging LinuxThreads programs</A></H2>
-
-<H4><A NAME="G.1">G.1: Can I debug LinuxThreads program using gdb?</A></H4>
-
-Yes, but not with the stock gdb 4.17. You need a specially patched
-version of gdb 4.17 developed by Eric Paire and colleages at The Open
-Group, Grenoble. The patches against gdb 4.17 are available at
-<A HREF="http://www.gr.opengroup.org/java/jdk/linux/debug.htm"><code>http://www.gr.opengroup.org/java/jdk/linux/debug.htm</code></A>.
-Precompiled binaries of the patched gdb are available in RedHat's RPM
-format at <A
-HREF="http://odin.appliedtheory.com/"><code>http://odin.appliedtheory.com/</code></A>.<P>
-
-Some Linux distributions provide an already-patched version of gdb;
-others don't. For instance, the gdb in RedHat 5.2 is thread-aware,
-but apparently not the one in RedHat 6.0. Just ask (politely) the
-makers of your Linux distributions to please make sure that they apply
-the correct patches to gdb.<P>
-
-<H4><A NAME="G.2">G.2: Does it work with post-mortem debugging?</A></H4>
-
-Not very well. Generally, the core file does not correspond to the
-thread that crashed. The reason is that the kernel will not dump core
-for a process that shares its memory with other processes, such as the
-other threads of your program. So, the thread that crashes silently
-disappears without generating a core file. Then, all other threads of
-your program die on the same signal that killed the crashing thread.
-(This is required behavior according to the POSIX standard.) The last
-one that dies is no longer sharing its memory with anyone else, so the
-kernel generates a core file for that thread. Unfortunately, that's
-not the thread you are interested in.
-
-<H4><A NAME="G.3">G.3: Any other ways to debug multithreaded programs, then?</A></H4>
-
-Assertions and <CODE>printf()</CODE> are your best friends. Try to debug
-sequential parts in a single-threaded program first. Then, put
-<CODE>printf()</CODE> statements all over the place to get execution traces.
-Also, check invariants often with the <CODE>assert()</CODE> macro. In truth,
-there is no other effective way (save for a full formal proof of your
-program) to track down concurrency bugs. Debuggers are not really
-effective for subtle concurrency problems, because they disrupt
-program execution too much.<P>
-
-<HR>
-<P>
-
-<H2><A NAME="H">H. Compiling multithreaded code; errno madness</A></H2>
-
-<H4><A NAME="H.1">H.1: You say all multithreaded code must be compiled
-with <CODE>_REENTRANT</CODE> defined. What difference does it make?</A></H4>
-
-It affects include files in three ways:
-<UL>
-<LI> The include files define prototypes for the reentrant variants of
-some of the standard library functions,
-e.g. <CODE>gethostbyname_r()</CODE> as a reentrant equivalent to
-<CODE>gethostbyname()</CODE>.<P>
-
-<LI> If <CODE>_REENTRANT</CODE> is defined, some
-<code>&lt;stdio.h&gt;</code> functions are no longer defined as macros,
-e.g. <CODE>getc()</CODE> and <CODE>putc()</CODE>. In a multithreaded
-program, stdio functions require additional locking, which the macros
-don't perform, so we must call functions instead.<P>
-
-<LI> More importantly, <code>&lt;errno.h&gt;</code> redefines errno when
-<CODE>_REENTRANT</CODE> is
-defined, so that errno refers to the thread-specific errno location
-rather than the global errno variable. This is achieved by the
-following <code>#define</code> in <code>&lt;errno.h&gt;</code>:
-<PRE>
- #define errno (*(__errno_location()))
-</PRE>
-which causes each reference to errno to call the
-<CODE>__errno_location()</CODE> function for obtaining the location
-where error codes are stored. libc provides a default definition of
-<CODE>__errno_location()</CODE> that always returns
-<code>&errno</code> (the address of the global errno variable). Thus,
-for programs not linked with LinuxThreads, defining
-<CODE>_REENTRANT</CODE> makes no difference w.r.t. errno processing.
-But LinuxThreads redefines <CODE>__errno_location()</CODE> to return a
-location in the thread descriptor reserved for holding the current
-value of errno for the calling thread. Thus, each thread operates on
-a different errno location.
-</UL>
-<P>
-
-<H4><A NAME="H.2">H.2: Why is it so important that each thread has its
-own errno variable? </A></H4>
-
-If all threads were to store error codes in the same, global errno
-variable, then the value of errno after a system call or library
-function returns would be unpredictable: between the time a system
-call stores its error code in the global errno and your code inspects
-errno to see which error occurred, another thread might have stored
-another error code in the same errno location. <P>
-
-<H4><A NAME="H.3">H.3: What happens if I link LinuxThreads with code
-not compiled with <CODE>-D_REENTRANT</CODE>?</A></H4>
-
-Lots of trouble. If the code uses <CODE>getc()</CODE> or
-<CODE>putc()</CODE>, it will perform I/O without proper interlocking
-of the stdio buffers; this can cause lost output, duplicate output, or
-just crash other stdio functions. If the code consults errno, it will
-get back the wrong error code. The following code fragment is a
-typical example:
-<PRE>
- do {
- r = read(fd, buf, n);
- if (r == -1) {
- if (errno == EINTR) /* an error we can handle */
- continue;
- else { /* other errors are fatal */
- perror("read failed");
- exit(100);
- }
- }
- } while (...);
-</PRE>
-Assume this code is not compiled with <CODE>-D_REENTRANT</CODE>, and
-linked with LinuxThreads. At run-time, <CODE>read()</CODE> is
-interrupted. Since the C library was compiled with
-<CODE>-D_REENTRANT</CODE>, <CODE>read()</CODE> stores its error code
-in the location pointed to by <CODE>__errno_location()</CODE>, which
-is the thread-local errno variable. Then, the code above sees that
-<CODE>read()</CODE> returns -1 and looks up errno. Since
-<CODE>_REENTRANT</CODE> is not defined, the reference to errno
-accesses the global errno variable, which is most likely 0. Hence the
-code concludes that it cannot handle the error and stops.<P>
-
-<H4><A NAME="H.4">H.4: With LinuxThreads, I can no longer use the signals
-<code>SIGUSR1</code> and <code>SIGUSR2</code> in my programs! Why? </A></H4>
-
-The short answer is: because the Linux kernel you're using does not
-support realtime signals. <P>
-
-LinuxThreads needs two signals for its internal operation.
-One is used to suspend and restart threads blocked on mutex, condition
-or semaphore operations. The other is used for thread
-cancellation.<P>
-
-On ``old'' kernels (2.0 and early 2.1 kernels), there are only 32
-signals available and the kernel reserves all of them but two:
-<code>SIGUSR1</code> and <code>SIGUSR2</code>. So, LinuxThreads has
-no choice but use those two signals.<P>
-
-On recent kernels (2.2 and up), more than 32 signals are provided in
-the form of realtime signals. When run on one of those kernels,
-LinuxThreads uses two reserved realtime signals for its internal
-operation, thus leaving <code>SIGUSR1</code> and <code>SIGUSR2</code>
-free for user code. (This works only with glibc, not with libc 5.) <P>
-
-<H4><A NAME="H.5">H.5: Is the stack of one thread visible from the
-other threads? Can I pass a pointer into my stack to other threads?
-</A></H4>
-
-Yes, you can -- if you're very careful. The stacks are indeed visible
-from all threads in the system. Some non-POSIX thread libraries seem
-to map the stacks for all threads at the same virtual addresses and
-change the memory mapping when they switch from one thread to
-another. But this is not the case for LinuxThreads, as it would make
-context switching between threads more expensive, and at any rate
-might not conform to the POSIX standard.<P>
-
-So, you can take the address of an "auto" variable and pass it to
-other threads via shared data structures. However, you need to make
-absolutely sure that the function doing this will not return as long
-as other threads need to access this address. It's the usual mistake
-of returning the address of an "auto" variable, only made much worse
-because of concurrency. It's much, much safer to systematically
-heap-allocate all shared data structures. <P>
-
-<HR>
-<P>
-
-<H2><A NAME="I">I. X-Windows and other libraries</A></H2>
-
-<H4><A NAME="I.1">I.1: My program uses both Xlib and LinuxThreads.
-It stops very early with an "Xlib: unknown 0 error" message. What
-does this mean? </A></H4>
-
-That's a prime example of the errno problem described in question <A
-HREF="#H.2">H.2</A>. The binaries for Xlib you're using have not been
-compiled with <CODE>-D_REENTRANT</CODE>. It happens Xlib contains a
-piece of code very much like the one in question <A
-HREF="#H.2">H.2</A>. So, your Xlib fetches the error code from the
-wrong errno location and concludes that an error it cannot handle
-occurred.<P>
-
-<H4><A NAME="I.2">I.2: So, what can I do to build a multithreaded X
-Windows client? </A></H4>
-
-The best solution is to use X libraries that have been compiled with
-multithreading options set. Linux distributions that come with glibc
-2 as the main C library generally provide thread-safe X libraries.
-At least, that seems to be the case for RedHat 5 and later.<P>
-
-You can try to recompile yourself the X libraries with multithreading
-options set. They contain optional support for multithreading; it's
-just that the binaries provided by your Linux distribution were built
-without this support. See the file <code>README.Xfree3.3</code> in
-the LinuxThreads distribution for patches and info on how to compile
-thread-safe X libraries from the Xfree3.3 distribution. The Xfree3.3
-sources are readily available in most Linux distributions, e.g. as a
-source RPM for RedHat. Be warned, however, that X Windows is a huge
-system, and recompiling even just the libraries takes a lot of time
-and disk space.<P>
-
-Another, less involving solution is to call X functions only from the
-main thread of your program. Even if all threads have their own errno
-location, the main thread uses the global errno variable for its errno
-location. Thus, code not compiled with <code>-D_REENTRANT</code>
-still "sees" the right error values if it executes in the main thread
-only. <P>
-
-<H4><A NAME="I.2">This is a lot of work. Don't you have precompiled
-thread-safe X libraries that you could distribute?</A></H4>
-
-No, I don't. Sorry. But consider installing a Linux distribution
-that comes with thread-safe X libraries, such as RedHat 6.<P>
-
-<H4><A NAME="I.3">I.3: Can I use library FOO in a multithreaded
-program?</A></H4>
-
-Most libraries cannot be used "as is" in a multithreaded program.
-For one thing, they are not necessarily thread-safe: calling
-simultaneously two functions of the library from two threads might not
-work, due to internal use of global variables and the like. Second,
-the libraries must have been compiled with <CODE>-D_REENTRANT</CODE> to avoid
-the errno problems explained in question <A HREF="#H.2">H.2</A>.
-<P>
-
-<H4><A NAME="I.4">I.4: What if I make sure that only one thread calls
-functions in these libraries?</A></H4>
-
-This avoids problems with the library not being thread-safe. But
-you're still vulnerable to errno problems. At the very least, a
-recompile of the library with <CODE>-D_REENTRANT</CODE> is needed.
-<P>
-
-<H4><A NAME="I.5">I.5: What if I make sure that only the main thread
-calls functions in these libraries?</A></H4>
-
-That might actually work. As explained in question <A HREF="#I.1">I.1</A>,
-the main thread uses the global errno variable, and can therefore
-execute code not compiled with <CODE>-D_REENTRANT</CODE>.<P>
-
-<H4><A NAME="I.6">I.6: SVGAlib doesn't work with LinuxThreads. Why?
-</A></H4>
-
-Because both LinuxThreads and SVGAlib use the signals
-<code>SIGUSR1</code> and <code>SIGUSR2</code>. See question <A
-HREF="#H.4">H.4</A>.
-<P>
-
-
-<HR>
-<P>
-
-<H2><A NAME="J">J. Signals and threads</A></H2>
-
-<H4><A NAME="J.1">J.1: When it comes to signals, what is shared
-between threads and what isn't?</A></H4>
-
-Signal handlers are shared between all threads: when a thread calls
-<CODE>sigaction()</CODE>, it sets how the signal is handled not only
-for itself, but for all other threads in the program as well.<P>
-
-On the other hand, signal masks are per-thread: each thread chooses
-which signals it blocks independently of others. At thread creation
-time, the newly created thread inherits the signal mask of the thread
-calling <CODE>pthread_create()</CODE>. But afterwards, the new thread
-can modify its signal mask independently of its creator thread.<P>
-
-<H4><A NAME="J.2">J.2: When I send a <CODE>SIGKILL</CODE> to a
-particular thread using <CODE>pthread_kill</CODE>, all my threads are
-killed!</A></H4>
-
-That's how it should be. The POSIX standard mandates that all threads
-should terminate when the process (i.e. the collection of all threads
-running the program) receives a signal whose effect is to
-terminate the process (such as <CODE>SIGKILL</CODE> or <CODE>SIGINT</CODE>
-when no handler is installed on that signal). This behavior makes a
-lot of sense: when you type "ctrl-C" at the keyboard, or when a thread
-crashes on a division by zero or a segmentation fault, you really want
-all threads to stop immediately, not just the one that caused the
-segmentation violation or that got the <CODE>SIGINT</CODE> signal.
-(This assumes default behavior for those signals; see question
-<A HREF="#J.3">J.3</A> if you install handlers for those signals.)<P>
-
-If you're trying to terminate a thread without bringing the whole
-process down, use <code>pthread_cancel()</code>.<P>
-
-<H4><A NAME="J.3">J.3: I've installed a handler on a signal. Which
-thread executes the handler when the signal is received?</A></H4>
-
-If the signal is generated by a thread during its execution (e.g. a
-thread executes a division by zero and thus generates a
-<CODE>SIGFPE</CODE> signal), then the handler is executed by that
-thread. This also applies to signals generated by
-<CODE>raise()</CODE>.<P>
-
-If the signal is sent to a particular thread using
-<CODE>pthread_kill()</CODE>, then that thread executes the handler.<P>
-
-If the signal is sent via <CODE>kill()</CODE> or the tty interface
-(e.g. by pressing ctrl-C), then the POSIX specs say that the handler
-is executed by any thread in the process that does not currently block
-the signal. In other terms, POSIX considers that the signal is sent
-to the process (the collection of all threads) as a whole, and any
-thread that is not blocking this signal can then handle it.<P>
-
-The latter case is where LinuxThreads departs from the POSIX specs.
-In LinuxThreads, there is no real notion of ``the process as a whole'':
-in the kernel, each thread is really a distinct process with a
-distinct PID, and signals sent to the PID of a thread can only be
-handled by that thread. As long as no thread is blocking the signal,
-the behavior conforms to the standard: one (unspecified) thread of the
-program handles the signal. But if the thread to which PID the signal
-is sent blocks the signal, and some other thread does not block the
-signal, then LinuxThreads will simply queue in
-that thread and execute the handler only when that thread unblocks
-the signal, instead of executing the handler immediately in the other
-thread that does not block the signal.<P>
-
-This is to be viewed as a LinuxThreads bug, but I currently don't see
-any way to implement the POSIX behavior without kernel support.<P>
-
-<H4><A NAME="J.3">J.3: How shall I go about mixing signals and threads
-in my program? </A></H4>
-
-The less you mix them, the better. Notice that all
-<CODE>pthread_*</CODE> functions are not async-signal safe, meaning
-that you should not call them from signal handlers. This
-recommendation is not to be taken lightly: your program can deadlock
-if you call a <CODE>pthread_*</CODE> function from a signal handler!
-<P>
-
-The only sensible things you can do from a signal handler is set a
-global flag, or call <CODE>sem_post</CODE> on a semaphore, to record
-the delivery of the signal. The remainder of the program can then
-either poll the global flag, or use <CODE>sem_wait()</CODE> and
-<CODE>sem_trywait()</CODE> on the semaphore.<P>
-
-Another option is to do nothing in the signal handler, and dedicate
-one thread (preferably the initial thread) to wait synchronously for
-signals, using <CODE>sigwait()</CODE>, and send messages to the other
-threads accordingly.
-
-<H4><A NAME="J.4">J.4: When one thread is blocked in
-<CODE>sigwait()</CODE>, other threads no longer receive the signals
-<CODE>sigwait()</CODE> is waiting for! What happens? </A></H4>
-
-It's an unfortunate consequence of how LinuxThreads implements
-<CODE>sigwait()</CODE>. Basically, it installs signal handlers on all
-signals waited for, in order to record which signal was received.
-Since signal handlers are shared with the other threads, this
-temporarily deactivates any signal handlers you might have previously
-installed on these signals.<P>
-
-Though surprising, this behavior actually seems to conform to the
-POSIX standard. According to POSIX, <CODE>sigwait()</CODE> is
-guaranteed to work as expected only if all other threads in the
-program block the signals waited for (otherwise, the signals could be
-delivered to other threads than the one doing <CODE>sigwait()</CODE>,
-which would make <CODE>sigwait()</CODE> useless). In this particular
-case, the problem described in this question does not appear.<P>
-
-One day, <CODE>sigwait()</CODE> will be implemented in the kernel,
-along with others POSIX 1003.1b extensions, and <CODE>sigwait()</CODE>
-will have a more natural behavior (as well as better performances).<P>
-
-<HR>
-<P>
-
-<H2><A NAME="K">K. Internals of LinuxThreads</A></H2>
-
-<H4><A NAME="K.1">K.1: What is the implementation model for
-LinuxThreads?</A></H4>
-
-LinuxThreads follows the so-called "one-to-one" model: each thread is
-actually a separate process in the kernel. The kernel scheduler takes
-care of scheduling the threads, just like it schedules regular
-processes. The threads are created with the Linux
-<code>clone()</code> system call, which is a generalization of
-<code>fork()</code> allowing the new process to share the memory
-space, file descriptors, and signal handlers of the parent.<P>
-
-Advantages of the "one-to-one" model include:
-<UL>
-<LI> minimal overhead on CPU-intensive multiprocessing (with
-about one thread per processor);
-<LI> minimal overhead on I/O operations;
-<LI> a simple and robust implementation (the kernel scheduler does
-most of the hard work for us).
-</UL>
-The main disadvantage is more expensive context switches on mutex and
-condition operations, which must go through the kernel. This is
-mitigated by the fact that context switches in the Linux kernel are
-pretty efficient.<P>
-
-<H4><A NAME="K.2">K.2: Have you considered other implementation
-models?</A></H4>
-
-There are basically two other models. The "many-to-one" model
-relies on a user-level scheduler that context-switches between the
-threads entirely in user code; viewed from the kernel, there is only
-one process running. This model is completely out of the question for
-me, since it does not take advantage of multiprocessors, and require
-unholy magic to handle blocking I/O operations properly. There are
-several user-level thread libraries available for Linux, but I found
-all of them deficient in functionality, performance, and/or robustness.
-<P>
-
-The "many-to-many" model combines both kernel-level and user-level
-scheduling: several kernel-level threads run concurrently, each
-executing a user-level scheduler that selects between user threads.
-Most commercial Unix systems (Solaris, Digital Unix, IRIX) implement
-POSIX threads this way. This model combines the advantages of both
-the "many-to-one" and the "one-to-one" model, and is attractive
-because it avoids the worst-case behaviors of both models --
-especially on kernels where context switches are expensive, such as
-Digital Unix. Unfortunately, it is pretty complex to implement, and
-requires kernel support which Linux does not provide. Linus Torvalds
-and other Linux kernel developers have always been pushing the
-"one-to-one" model in the name of overall simplicity, and are doing a
-pretty good job of making kernel-level context switches between
-threads efficient. LinuxThreads is just following the general
-direction they set.<P>
-
-<HR>
-<ADDRESS>Xavier.Leroy@inria.fr</ADDRESS>
-</BODY>
-</HTML>
diff --git a/libpthread/linuxthreads.old/LICENSE b/libpthread/linuxthreads.old/LICENSE
deleted file mode 100644
index 7bcca6050..000000000
--- a/libpthread/linuxthreads.old/LICENSE
+++ /dev/null
@@ -1,501 +0,0 @@
-GNU LIBRARY GENERAL PUBLIC LICENSE
-**********************************
-
- Version 2, June 1991
-
- Copyright (C) 1991 Free Software Foundation, Inc.
- 59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA
-
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- [This is the first released version of the library GPL. It is
- numbered 2 because it goes with version 2 of the ordinary GPL.]
-
-Preamble
-========
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Library General Public License, applies to some
-specially designated Free Software Foundation software, and to any
-other libraries whose authors decide to use it. You can use it for
-your libraries, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it in
-new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the library, or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link a program with the library, you must provide
-complete object files to the recipients so that they can relink them
-with the library, after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- Our method of protecting your rights has two steps: (1) copyright
-the library, and (2) offer you this license which gives you legal
-permission to copy, distribute and/or modify the library.
-
- Also, for each distributor's protection, we want to make certain
-that everyone understands that there is no warranty for this free
-library. If the library is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original
-version, so that any problems introduced by others will not reflect on
-the original authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that companies distributing free
-software will individually obtain patent licenses, thus in effect
-transforming the program into proprietary software. To prevent this,
-we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License, which was designed for utility
-programs. This license, the GNU Library General Public License,
-applies to certain designated libraries. This license is quite
-different from the ordinary one; be sure to read it in full, and don't
-assume that anything in it is the same as in the ordinary license.
-
- The reason we have a separate public license for some libraries is
-that they blur the distinction we usually make between modifying or
-adding to a program and simply using it. Linking a program with a
-library, without changing the library, is in some sense simply using
-the library, and is analogous to running a utility program or
-application program. However, in a textual and legal sense, the linked
-executable is a combined work, a derivative of the original library,
-and the ordinary General Public License treats it as such.
-
- Because of this blurred distinction, using the ordinary General
-Public License for libraries did not effectively promote software
-sharing, because most developers did not use the libraries. We
-concluded that weaker conditions might promote sharing better.
-
- However, unrestricted linking of non-free programs would deprive the
-users of those programs of all benefit from the free status of the
-libraries themselves. This Library General Public License is intended
-to permit developers of non-free programs to use free libraries, while
-preserving your freedom as a user of such programs to change the free
-libraries that are incorporated in them. (We have not seen how to
-achieve this as regards changes in header files, but we have achieved
-it as regards changes in the actual functions of the Library.) The
-hope is that this will lead to faster development of free libraries.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, while the latter only
-works together with the library.
-
- Note that it is possible for a library to be covered by the ordinary
-General Public License rather than by this special one.
-
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library which
- contains a notice placed by the copyright holder or other
- authorized party saying it may be distributed under the terms of
- this Library General Public License (also called "this License").
- Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
- prepared so as to be conveniently linked with application programs
- (which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
- which has been distributed under these terms. A "work based on the
- Library" means either the Library or any derivative work under
- copyright law: that is to say, a work containing the Library or a
- portion of it, either verbatim or with modifications and/or
- translated straightforwardly into another language. (Hereinafter,
- translation is included without limitation in the term
- "modification".)
-
- "Source code" for a work means the preferred form of the work for
- making modifications to it. For a library, complete source code
- means all the source code for all modules it contains, plus any
- associated interface definition files, plus the scripts used to
- control compilation and installation of the library.
-
- Activities other than copying, distribution and modification are
- not covered by this License; they are outside its scope. The act
- of running a program using the Library is not restricted, and
- output from such a program is covered only if its contents
- constitute a work based on the Library (independent of the use of
- the Library in a tool for writing it). Whether that is true
- depends on what the Library does and what the program that uses
- the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
- complete source code as you receive it, in any medium, provided
- that you conspicuously and appropriately publish on each copy an
- appropriate copyright notice and disclaimer of warranty; keep
- intact all the notices that refer to this License and to the
- absence of any warranty; and distribute a copy of this License
- along with the Library.
-
- You may charge a fee for the physical act of transferring a copy,
- and you may at your option offer warranty protection in exchange
- for a fee.
-
- 2. You may modify your copy or copies of the Library or any portion
- of it, thus forming a work based on the Library, and copy and
- distribute such modifications or work under the terms of Section 1
- above, provided that you also meet all of these conditions:
-
- a. The modified work must itself be a software library.
-
- b. You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c. You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d. If a facility in the modified Library refers to a function or
- a table of data to be supplied by an application program that
- uses the facility, other than as an argument passed when the
- facility is invoked, then you must make a good faith effort
- to ensure that, in the event an application does not supply
- such function or table, the facility still operates, and
- performs whatever part of its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots
- has a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function
- must be optional: if the application does not supply it, the
- square root function must still compute square roots.)
-
- These requirements apply to the modified work as a whole. If
- identifiable sections of that work are not derived from the
- Library, and can be reasonably considered independent and separate
- works in themselves, then this License, and its terms, do not
- apply to those sections when you distribute them as separate
- works. But when you distribute the same sections as part of a
- whole which is a work based on the Library, the distribution of
- the whole must be on the terms of this License, whose permissions
- for other licensees extend to the entire whole, and thus to each
- and every part regardless of who wrote it.
-
- Thus, it is not the intent of this section to claim rights or
- contest your rights to work written entirely by you; rather, the
- intent is to exercise the right to control the distribution of
- derivative or collective works based on the Library.
-
- In addition, mere aggregation of another work not based on the
- Library with the Library (or with a work based on the Library) on
- a volume of a storage or distribution medium does not bring the
- other work under the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
- License instead of this License to a given copy of the Library.
- To do this, you must alter all the notices that refer to this
- License, so that they refer to the ordinary GNU General Public
- License, version 2, instead of to this License. (If a newer
- version than version 2 of the ordinary GNU General Public License
- has appeared, then you can specify that version instead if you
- wish.) Do not make any other change in these notices.
-
- Once this change is made in a given copy, it is irreversible for
- that copy, so the ordinary GNU General Public License applies to
- all subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
- the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
- derivative of it, under Section 2) in object code or executable
- form under the terms of Sections 1 and 2 above provided that you
- accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software
- interchange.
-
- If distribution of object code is made by offering access to copy
- from a designated place, then offering equivalent access to copy
- the source code from the same place satisfies the requirement to
- distribute the source code, even though third parties are not
- compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
- Library, but is designed to work with the Library by being
- compiled or linked with it, is called a "work that uses the
- Library". Such a work, in isolation, is not a derivative work of
- the Library, and therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
- creates an executable that is a derivative of the Library (because
- it contains portions of the Library), rather than a "work that
- uses the library". The executable is therefore covered by this
- License. Section 6 states terms for distribution of such
- executables.
-
- When a "work that uses the Library" uses material from a header
- file that is part of the Library, the object code for the work may
- be a derivative work of the Library even though the source code is
- not. Whether this is true is especially significant if the work
- can be linked without the Library, or if the work is itself a
- library. The threshold for this to be true is not precisely
- defined by law.
-
- If such an object file uses only numerical parameters, data
- structure layouts and accessors, and small macros and small inline
- functions (ten lines or less in length), then the use of the object
- file is unrestricted, regardless of whether it is legally a
- derivative work. (Executables containing this object code plus
- portions of the Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
- distribute the object code for the work under the terms of Section
- 6. Any executables containing that work also fall under Section 6,
- whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also compile or
- link a "work that uses the Library" with the Library to produce a
- work containing portions of the Library, and distribute that work
- under terms of your choice, provided that the terms permit
- modification of the work for the customer's own use and reverse
- engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
- Library is used in it and that the Library and its use are covered
- by this License. You must supply a copy of this License. If the
- work during execution displays copyright notices, you must include
- the copyright notice for the Library among them, as well as a
- reference directing the user to the copy of this License. Also,
- you must do one of these things:
-
- a. Accompany the work with the complete corresponding
- machine-readable source code for the Library including
- whatever changes were used in the work (which must be
- distributed under Sections 1 and 2 above); and, if the work
- is an executable linked with the Library, with the complete
- machine-readable "work that uses the Library", as object code
- and/or source code, so that the user can modify the Library
- and then relink to produce a modified executable containing
- the modified Library. (It is understood that the user who
- changes the contents of definitions files in the Library will
- not necessarily be able to recompile the application to use
- the modified definitions.)
-
- b. Accompany the work with a written offer, valid for at least
- three years, to give the same user the materials specified in
- Subsection 6a, above, for a charge no more than the cost of
- performing this distribution.
-
- c. If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the
- above specified materials from the same place.
-
- d. Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
- Library" must include any data and utility programs needed for
- reproducing the executable from it. However, as a special
- exception, the source code distributed need not include anything
- that is normally distributed (in either source or binary form)
- with the major components (compiler, kernel, and so on) of the
- operating system on which the executable runs, unless that
- component itself accompanies the executable.
-
- It may happen that this requirement contradicts the license
- restrictions of other proprietary libraries that do not normally
- accompany the operating system. Such a contradiction means you
- cannot use both them and the Library together in an executable
- that you distribute.
-
- 7. You may place library facilities that are a work based on the
- Library side-by-side in a single library together with other
- library facilities not covered by this License, and distribute
- such a combined library, provided that the separate distribution
- of the work based on the Library and of the other library
- facilities is otherwise permitted, and provided that you do these
- two things:
-
- a. Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b. Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same
- work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute the
- Library except as expressly provided under this License. Any
- attempt otherwise to copy, modify, sublicense, link with, or
- distribute the Library is void, and will automatically terminate
- your rights under this License. However, parties who have
- received copies, or rights, from you under this License will not
- have their licenses terminated so long as such parties remain in
- full compliance.
-
- 9. You are not required to accept this License, since you have not
- signed it. However, nothing else grants you permission to modify
- or distribute the Library or its derivative works. These actions
- are prohibited by law if you do not accept this License.
- Therefore, by modifying or distributing the Library (or any work
- based on the Library), you indicate your acceptance of this
- License to do so, and all its terms and conditions for copying,
- distributing or modifying the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
- Library), the recipient automatically receives a license from the
- original licensor to copy, distribute, link with or modify the
- Library subject to these terms and conditions. You may not impose
- any further restrictions on the recipients' exercise of the rights
- granted herein. You are not responsible for enforcing compliance
- by third parties to this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
- infringement or for any other reason (not limited to patent
- issues), conditions are imposed on you (whether by court order,
- agreement or otherwise) that contradict the conditions of this
- License, they do not excuse you from the conditions of this
- License. If you cannot distribute so as to satisfy simultaneously
- your obligations under this License and any other pertinent
- obligations, then as a consequence you may not distribute the
- Library at all. For example, if a patent license would not permit
- royalty-free redistribution of the Library by all those who
- receive copies directly or indirectly through you, then the only
- way you could satisfy both it and this License would be to refrain
- entirely from distribution of the Library.
-
- If any portion of this section is held invalid or unenforceable
- under any particular circumstance, the balance of the section is
- intended to apply, and the section as a whole is intended to apply
- in other circumstances.
-
- It is not the purpose of this section to induce you to infringe any
- patents or other property right claims or to contest validity of
- any such claims; this section has the sole purpose of protecting
- the integrity of the free software distribution system which is
- implemented by public license practices. Many people have made
- generous contributions to the wide range of software distributed
- through that system in reliance on consistent application of that
- system; it is up to the author/donor to decide if he or she is
- willing to distribute software through any other system and a
- licensee cannot impose that choice.
-
- This section is intended to make thoroughly clear what is believed
- to be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
- certain countries either by patents or by copyrighted interfaces,
- the original copyright holder who places the Library under this
- License may add an explicit geographical distribution limitation
- excluding those countries, so that distribution is permitted only
- in or among countries not thus excluded. In such case, this
- License incorporates the limitation as if written in the body of
- this License.
-
- 13. The Free Software Foundation may publish revised and/or new
- versions of the Library General Public License from time to time.
- Such new versions will be similar in spirit to the present version,
- but may differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
- Library specifies a version number of this License which applies
- to it and "any later version", you have the option of following
- the terms and conditions either of that version or of any later
- version published by the Free Software Foundation. If the Library
- does not specify a license version number, you may choose any
- version ever published by the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
- programs whose distribution conditions are incompatible with these,
- write to the author to ask for permission. For software which is
- copyrighted by the Free Software Foundation, write to the Free
- Software Foundation; we sometimes make exceptions for this. Our
- decision will be guided by the two goals of preserving the free
- status of all derivatives of our free software and of promoting
- the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
- WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE
- LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
- HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT
- WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
- NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
- QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE
- LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
- SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
- WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
- MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE
- LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
- INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
- INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF
- DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
- OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY
- OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
-How to Apply These Terms to Your New Libraries
-==============================================
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of
-the ordinary General Public License).
-
- To apply these terms, attach the following notices to the library.
-It is safest to attach them to the start of each source file to most
-effectively convey the exclusion of warranty; and each file should have
-at least the "copyright" line and a pointer to where the full notice is
-found.
-
- ONE LINE TO GIVE THE LIBRARY'S NAME AND AN IDEA OF WHAT IT DOES.
- Copyright (C) YEAR NAME OF AUTHOR
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published
- by the Free Software Foundation; either version 2 of the License, or (at
- your option) any later version.
-
- This library is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
- Also add information on how to contact you by electronic and paper
-mail.
-
- You should also get your employer (if you work as a programmer) or
-your school, if any, to sign a "copyright disclaimer" for the library,
-if necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the library
- `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- SIGNATURE OF TY COON, 1 April 1990
- Ty Coon, President of Vice
-
- That's all there is to it!
-
diff --git a/libpthread/linuxthreads.old/README b/libpthread/linuxthreads.old/README
deleted file mode 100644
index 955bd59e7..000000000
--- a/libpthread/linuxthreads.old/README
+++ /dev/null
@@ -1,166 +0,0 @@
- Linuxthreads - POSIX 1003.1c kernel threads for Linux
-
- Copyright 1996, 1997 Xavier Leroy (Xavier.Leroy@inria.fr)
-
-
-DESCRIPTION:
-
-This is release 0.7 (late beta) of LinuxThreads, a BiCapitalized
-implementation of the Posix 1003.1c "pthread" interface for Linux.
-
-LinuxThreads provides kernel-level threads: each thread is a separate
-Unix process, sharing its address space with the other threads through
-the new system call clone(). Scheduling between threads is handled by
-the kernel scheduler, just like scheduling between Unix processes.
-
-
-REQUIREMENTS:
-
-- Linux version 2.0 and up (requires the new clone() system call
- and the new realtime scheduler).
-
-- For Intel platforms: libc 5.2.18 or later is required.
- 5.2.18 or 5.4.12 or later are recommended;
- 5.3.12 and 5.4.7 have problems (see the FAQ.html file for more info).
-
-- Also supports glibc 2 (a.k.a. libc 6), which actually comes with
- a specially-adapted version of this library.
-
-- Currently supports Intel, Alpha, Sparc, Motorola 68k, ARM and MIPS
- platforms.
-
-- Multiprocessors are supported.
-
-
-INSTALLATION:
-
-- Edit the Makefile, set the variables in the "Configuration" section.
-
-- Do "make".
-
-- Do "make install".
-
-
-USING LINUXTHREADS:
-
- gcc -D_REENTRANT ... -lpthread
-
-A complete set of manual pages is included. Also see the subdirectory
-Examples/ for some sample programs.
-
-
-STATUS:
-
-- All functions in the Posix 1003.1c base interface implemented.
- Also supports priority scheduling.
-
-- For users of libc 5 (H.J.Lu's libc), a number of C library functions
- are reimplemented or wrapped to make them thread-safe, including:
- * malloc functions
- * stdio functions (define _REENTRANT before including <stdio.h>)
- * per-thread errno variable (define _REENTRANT before including <errno.h>)
- * directory reading functions (opendir(), etc)
- * sleep()
- * gmtime(), localtime()
-
- New library functions provided:
- * flockfile(), funlockfile(), ftrylockfile()
- * reentrant versions of network database functions (gethostbyname_r(), etc)
- and password functions (getpwnam_r(), etc).
-
-- libc 6 (glibc 2) provides much better thread support than libc 5,
- and comes with a specially-adapted version of LinuxThreads.
- For serious multithreaded programming, you should consider switching
- to glibc 2. It is available from ftp.gnu.org:/pub/gnu and its mirrors.
-
-
-WARNING:
-
-Many existing libraries are not compatible with LinuxThreads,
-either because they are not inherently thread-safe, or because they
-have not been compiled with the -D_REENTRANT. For more info, see the
-FAQ.html file in this directory.
-
-A prime example of the latter is Xlib. If you link it with
-LinuxThreads, you'll probably get an "unknown 0 error" very
-early. This is just a consequence of the Xlib binaries using the
-global variable "errno" to fetch error codes, while LinuxThreads and
-the C library use the per-thread "errno" location.
-
-See the file README.Xfree3.3 for info on how to compile the Xfree 3.3
-libraries to make them compatible with LinuxThreads.
-
-
-KNOWN BUGS AND LIMITATIONS:
-
-- Threads share pretty much everything they should share according
- to the standard: memory space, file descriptors, signal handlers,
- current working directory, etc. One thing that they do not share
- is their pid's and parent pid's. According to the standard, they
- should have the same, but that's one thing we cannot achieve
- in this implementation (until the CLONE_PID flag to clone() becomes
- usable).
-
-- The current implementation uses the two signals SIGUSR1 and SIGUSR2,
- so user-level code cannot employ them. Ideally, there should be two
- signals reserved for this library. One signal is used for restarting
- threads blocked on mutexes or conditions; the other is for thread
- cancellation.
-
- *** This is not anymore true when the application runs on a kernel
- newer than approximately 2.1.60.
-
-- The stacks for the threads are allocated high in the memory space,
- below the stack of the initial process, and spaced 2M apart.
- Stacks are allocated with the "grow on demand" flag, so they don't
- use much virtual space initially (4k, currently), but can grow
- up to 2M if needed.
-
- Reserving such a large address space for each thread means that,
- on a 32-bit architecture, no more than about 1000 threads can
- coexist (assuming a 2Gb address space for user processes),
- but this is reasonable, since each thread uses up one entry in the
- kernel's process table, which is usually limited to 512 processes.
-
- Another potential problem of the "grow on demand" scheme is that
- nothing prevents the user from mmap'ing something in the 2M address
- window reserved for a thread stack, possibly causing later extensions of
- that stack to fail. Mapping at fixed addresses should be avoided
- when using this library.
-
-- Signal handling does not fully conform to the Posix standard,
- due to the fact that threads are here distinct processes that can be
- sent signals individually, so there's no notion of sending a signal
- to "the" process (the collection of all threads).
- More precisely, here is a summary of the standard requirements
- and how they are met by the implementation:
-
- 1- Synchronous signals (generated by the thread execution, e.g. SIGFPE)
- are delivered to the thread that raised them.
- (OK.)
-
- 2- A fatal asynchronous signal terminates all threads in the process.
- (OK. The thread manager notices when a thread dies on a signal
- and kills all other threads with the same signal.)
-
- 3- An asynchronous signal will be delivered to one of the threads
- of the program which does not block the signal (it is unspecified
- which).
- (No, the signal is delivered to the thread it's been sent to,
- based on the pid of the thread. If that thread is currently
- blocking the signal, the signal remains pending.)
-
- 4- The signal will be delivered to at most one thread.
- (OK, except for signals generated from the terminal or sent to
- the process group, which will be delivered to all threads.)
-
-- The current implementation of the MIPS support assumes a MIPS ISA II
- processor or better. These processors support atomic operations by
- ll/sc instructions. Older R2000/R3000 series processors are not
- supported yet; support for these will have higher overhead.
-
-- The current implementation of the ARM support assumes that the SWP
- (atomic swap register with memory) instruction is available. This is
- the case for all processors except for the ARM1 and ARM2. On StrongARM,
- the SWP instruction does not bypass the cache, so multi-processor support
- will be more troublesome.
diff --git a/libpthread/linuxthreads.old/pthread.c-OLDEXAMPLE b/libpthread/linuxthreads.old/pthread.c-OLDEXAMPLE
deleted file mode 100644
index 88b163087..000000000
--- a/libpthread/linuxthreads.old/pthread.c-OLDEXAMPLE
+++ /dev/null
@@ -1,121 +0,0 @@
-/* vi: set sw=4 ts=4: */
-/*
- * A _very_ simple clone based pthread-like implementation
- *
- * Copyright (C) 2001,2002 by Erik Andersen <andersee@debian.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <stdlib.h>
-#include <sched.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-#include <pthread.h>
-
-#define STACKSIZE 8096
-
-#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
-#define CLONE_VM 0x00000100 /* set if VM shared between processes */
-#define CLONE_FS 0x00000200 /* set if fs info shared between proces ses */
-#define CLONE_FILES 0x00000400 /* set if open files shared between pro cesses */
-#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
-
-
-
-/* Lame home-grown clone based threading */
-int pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutex_attr)
-{
- mutex->__m_lock.__spinlock = 1;
- return 0;
-}
-
-int pthread_mutex_lock (pthread_mutex_t *mutex)
-{
- while (mutex->__m_lock.__spinlock == 0) {
- usleep(10000);
- }
- --(mutex->__m_lock.__spinlock);
- return 0;
-}
-
-int pthread_mutex_unlock (pthread_mutex_t *mutex)
-{
- ++(mutex->__m_lock.__spinlock);
- return 0;
-}
-
-int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
-{
- ++(mutex->__m_lock.__spinlock);
- while (cond->__c_lock.__spinlock == 0) {
- usleep(10000);
- }
- --(cond->__c_lock.__spinlock);
- return 0;
-}
-
-int pthread_cond_signal(pthread_cond_t *cond)
-{
- ++(cond->__c_lock.__spinlock);
- return 0;
-}
-
-int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr)
-{
- cond->__c_lock.__spinlock = 1;
- return 0;
-}
-
-int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void* (*fn)(void *), void *data)
-{
- long retval;
- void **newstack;
- int (*clonefunc)(void *) = (int (*)(void *))(fn);
-
- newstack = (void **) malloc(STACKSIZE);
- if (!newstack)
- return -1;
- newstack = (void **) (STACKSIZE + (char *) newstack);
- *--newstack = data;
- retval = clone(clonefunc, newstack,
- CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD, data);
- if (retval < 0) {
- errno = -retval;
- *thread = 0;
- retval = -1;
- } else {
- *thread = retval;
- retval = 0;
- }
- return retval;
-}
-
-int pthread_join (pthread_t thread, void **thread_return)
-{
- int retval;
- /* Fixme -- wait for thread and get its return value */
- retval = EXIT_SUCCESS;
- if (thread_return)
- (int)*thread_return = retval;
- _exit(retval);
-}
-link_warning(pthread_join, "pthread_join is a stub and does not behave properly");
-
-void pthread_exit (void *retval)
-{
- _exit(*(int *)retval);
-}