From a311086d622d3c778e1da57cfae167c0ab1c0fb4 Mon Sep 17 00:00:00 2001
From: rpj <rpj>
Date: Sun, 1 Jul 2001 13:23:10 +0000
Subject: 2001-06-25  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>

        * create.c (pthread_create): Add priority inheritance
        attributes.
        * mutex.c (pthread_mutex_lock): Remove some overhead for
        PTHREAD_MUTEX_NORMAL mutex types. Specifically, avoid
        calling pthread_self() and pthread_equal() to check/set
        the mutex owner. Introduce a new pseudo owner for this
        type. Test results suggest increases in speed of up to
        90% for non-blocking locks.
        This is the default type of mutex used internally by other
        synchronising objects, ie. condition variables and
        read-write locks. The test rwlock7.c shows about a
        30-35% speed increase over snapshot 2001-06-06. The
        price of this is that the application developer
        must ensure correct behaviour, or explicitly set the
        mutex to a safer type such as PTHREAD_MUTEX_ERRORCHECK.
        For example, PTHREAD_MUTEX_NORMAL (or PTHREAD_MUTEX_DEFAULT)
        type mutexes will not return an error if a thread which is not
        the owner calls pthread_mutex_unlock. The call will succeed
        in unlocking the mutex if it is currently locked, but a
        subsequent unlock by the true owner will then fail with EPERM.
        This is however consistent with some other implementations.
        (pthread_mutex_unlock): Likewise.
        (pthread_mutex_trylock): Likewise.
        (pthread_mutex_destroy): Likewise.
        * attr.c (pthread_attr_init): PTHREAD_EXPLICIT_SCHED is the
        default inheritance attribute; THREAD_PRIORITY_NORMAL is
        the default priority for new threads.
        * sched.c (pthread_attr_setschedpolicy): Added routine.
        (pthread_attr_getschedpolicy): Added routine.
        (pthread_attr_setinheritsched): Added routine.
        (pthread_attr_getinheritsched): Added routine.
        * pthread.h (sched_rr_set_interval): Added as a macro;
        returns -1 with errno set to ENOSYS.

2001-06-23  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>

        *sched.c (pthread_attr_setschedparam): Add priority range
        check.
        (sched_setscheduler): New function; checks for a valid
        pid and policy; checks for permission to set information
        in the target process; expects pid to be a Win32 process ID,
        not a process handle; the only scheduler policy allowed is
        SCHED_OTHER.
        (sched_getscheduler): Likewise, but checks for permission
        to query.
        * pthread.h (SCHED_*): Moved to sched.h as defined in the
        POSIX standard.
        * sched.h (SCHED_*): Moved from pthread.h.
        (pid_t): Defined if necessary.
        (sched_setscheduler): Defined.
        (sched_getscheduler): Defined.
        * pthread.def (sched_setscheduler): Exported.
        (sched_getscheduler): Likewise.

2001-06-23  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>

        Contributed by -  Ralf Brese <Ralf.Brese@pdb4.siemens.de>

        * create.c (pthread_create): Set thread priority from
        thread attributes.
---
 ANNOUNCE           |  238 +-
 CONTRIBUTORS       |    2 +
 ChangeLog          | 6347 ++++++++++++++++++++++++++--------------------------
 Nmakefile          |    2 +-
 Nmakefile.tests    |   16 +-
 attr.c             |   10 +-
 create.c           |   80 +-
 implement.h        |   13 +-
 mutex.c            |   27 +-
 pthread.def        |   15 +-
 pthread.h          |   98 +-
 sched.c            |  410 +++-
 sched.h            |   48 +
 tests/ChangeLog    | 1017 ++++-----
 tests/GNUmakefile  |   10 +-
 tests/Makefile     |    9 +-
 tests/benchtest1.c |  117 +
 tests/benchtest2.c |  183 ++
 tests/cancel5.c    |  354 +--
 tests/exception1.c |  462 ++--
 tests/inherit1.c   |   99 +
 tests/mutex3.c     |    3 +-
 tests/mutex4.c     |   65 +-
 tests/mutex5.c     |   18 +-
 tests/priority1.c  |   78 +
 tests/priority2.c  |   80 +
 26 files changed, 5521 insertions(+), 4280 deletions(-)
 create mode 100644 tests/benchtest1.c
 create mode 100644 tests/benchtest2.c
 create mode 100644 tests/inherit1.c
 create mode 100644 tests/priority1.c
 create mode 100644 tests/priority2.c

diff --git a/ANNOUNCE b/ANNOUNCE
index b9b4970..689b16d 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,4 +1,4 @@
-                 PTHREADS-WIN32 SNAPSHOT 2001-06-06
+                 PTHREADS-WIN32 SNAPSHOT 2001-??-??
                  ----------------------------------
        Web Site: http://sources.redhat.com/pthreads-win32/
       FTP Site: ftp://sources.redhat.com/pub/pthreads-win32
@@ -28,83 +28,148 @@ Change Summary (since the last snapshot)
 
 (See the ChangeLog file for details.)
 
-New:
--	Async cancellation should now work for Windows running
-	on the following processors: IX86, MIPS, ALPHA, PPC.
-	- contributors name misplaced (please contact me if it's you)
- 
--       New functions (no-ops) for source code compatibility:
-                pthread_getconcurrency()
-                  	Returns the value previously set by
-			pthread_setconcurrency(), or 0 (zero)
-			if no value was previously set.
-			The implementation does not currently use
-			this value.
-                pthread_setconcurrency()
-                        Accepts any value >= 0 but does not
-                        have any effect; returns '0', or
-                        EINVAL if the value is < 0
-                pthread_attr_getscope()
-                pthread_attr_setscope()
-                        Currently only return ENOSYS
-
--       The following mutex types and related functions are now
-        supported:
-
-                pthread_mutexattr_gettype()
-                pthread_mutexattr_settype()
-                pthread_mutexattr_setkind_np()
-                pthread_mutexattr_getkind_np()
-                PTHREAD_MUTEX_DEFAULT
-                PTHREAD_MUTEX_NORMAL or PTHREAD_MUTEX_FAST_NP
-                PTHREAD_MUTEX_ERRORCHECK or PTHREAD_MUTEX_ERRORCHECK_NP
-                PTHREAD_MUTEX_RECURSIVE or PTHREAD_MUTEX_RECURSIVE_NP
-
-	The *_NP versions are for Linux portability.
-
-        In this implementation PTHREAD_MUTEX_DEFAULT is
-        mapped to PTHREAD_MUTEX_NORMAL for compatibility
-        with major Unix vendors. This is also the default
-	if no type is specified.
-
-	Please note that the default behaviour in previous
-	versions of the library was equivalent to
-	PTHREAD_MUTEX_RECURSIVE. This will be a problem
-	for some applications unless they are updated to
-	explicitly set the type of any mutexes that are, or
-	could be, locked recursively.
-
-        PTHREAD_MUTEX_NORMAL will cause thread deadlock
-        if the owner of a mutex tries to relock it without
-        first unlocking it. It has slightly less overhead
-	that other types.
-        - Thomas Pfaff <tpfaff@gmx.net>
-
--       Pthreads-win32 mutexes are now based on Win32
-        critical sections for all Windows versions. The
-	implementation no longer depends on
-	TryEnterCriticalSection.
-        - Thomas Pfaff <tpfaff@gmx.net>
-
--	New implementation of condition variables which attempts to
-	correct problems of spurious wakeups, unfairness, and
-	broadcast deadlock. See README.CV for details of the
-	discussion.
-	  - Alexander Terekhov <TEREKHOV@de.ibm.com>
-	  - Louis Thomas <lthomas@arbitrade.com>
-
-Bugs fixed:
--       Pthread_mutex_trylock() now properly returns EBUSY
-        even when the current thread owns the mutex.
-        Consequently, pthread_mutex_destroy() will no longer
-        destroy a locked mutex (it will return EBUSY).
-        - Thomas Pfaff <tpfaff@gmx.net>
-
--	Errno warnings and building with /MD;
-	calling conventions (stdcall v cdecl);
-	thread termination problems;
-	- Milan Gardian <Milan.Gardian@LEIBINGER.com>
+-----------------------
+Additions to Scheduling
+-----------------------
+New routines:
+	pthread_attr_setinheritsched()
+	pthread_attr_getinheritsched()
+	pthread_attr_setschedpolicy()
+	pthread_attr_getschedpolicy()
+	sched_setscheduler()
+	sched_getscheduler()
+	sched_rr_get_interval()
+Now defined:
+	_POSIX_THREAD_PRIORITY_SCHEDULING
+
+These routines complete the set required for defining
+_POSIX_THREAD_PRIORITY_SCHEDULING.
+
+
+sched_setscheduler
+sched_getscheduler
+------------------
+These routines will require patching to work with UWIN
+or any other system that provides it's own pid_t.
+Pthread.h conditionally defines pid_t as a DWORD, which
+is the type returned by GetCurrentProcessId().
+
+The only supported policy is SCHED_OTHER, however, in
+order to provide semantic compatibility these routines
+verify the following:
+- that the process identified by pid exists;
+- that permission is granted to set or query the policy;
+The appropriate error is returned if either of these fail.
+On success, both routines return SCHED_OTHER.
+
+
+sched_rr_get_interval
+---------------------
+Always returns -1 and sets errno to ENOTSUP.
+
+
+pthread_attr_setschedpolicy
+pthread_attr_getschedpolicy
+---------------------------
+The only valid supported policy is SCHED_OTHER.
+Attempting to set other policies results in an ENOTSUP
+error.
+
+
+pthread_attr_setinheritsched
+pthread_attr_getinheritsched
+----------------------------
+The two possible values that can be set are
+PTHREAD_INHERIT_SCHED and PTHREAD_EXPLICIT_SCHED.
+
+Neither the POSIX standard nor the Single Unix Spec
+specifies which should be the default value.
+Consequently, implementations use different defaults,
+eg (from a scan of the web):
+
+PTHREAD_INHERIT_SCHED default:
+	HP, MKS Toolkit, QNX, AIX (?)
+
+PTHREAD_EXPLICIT_SCHED default:
+	IBM OS/400, Linux, Sun
+
+All Win32 threads are created with THREAD_PRIORITY_NORMAL.
+They do not inherit the priority of the parent thread or the
+process. This behaviour is equivalent to the following
+Pthreads defaults:
+
+	Inheritance:	PTHREAD_EXPLICIT_SCHED
+	Priority:	THREAD_PRIORITY_NORMAL
+
+These are also the defaults in pthreads-win32, and now
+reinforced by changes to the library which now actually
+use these values and routines. This choice maintains the
+notion that, from the Pthread point-of-view, Win32
+threads (those not created via pthread_create()) are
+treated as detached POSIX threads with default attribute
+values.
+
+
+------------------
+Changes to Mutexes
+------------------
+Snapshot-2001-06-06 included Thomas Pfaff's enhancements
+to the mutex routines to improve speed. The improvements
+are most apparent on Win9x class systems where pthreads-win32
+previously used Win32 mutexes rather than critical
+sections as the underlying mechanism. The enhancements
+also resulted in speed improvements in other primitives
+which use mutexes internally, such as condition variables
+and read-write locks. Thomas also added mutex
+types to the library as described in the Single Unix
+Specification documentation, and as provided with
+the majority of major Unix and Linux Pthreads
+implementations.
+
+Changes have been made to further improve the speed of the
+default PTHREAD_MUTEX_NORMAL type (and therefore also
+PTHREAD_MUTEX_DEFAULT which is equivalent in pthreads-win32).
+
+Specifically, the library no longer sets or checks the real
+mutex owner when locking, unlocking, trylocking, or
+destroying PTHREAD_MUTEX_NORMAL mutexes. This saves
+significant overhead and results in measured speed increases
+of around 90 percent for non-blocking lock operations, and a
+slight improvement for blocking lock operations. Since the
+type of mutex used internally is PTHREAD_MUTEX_DEFAULT, this
+also results in additional speed improvements to CVs and R/W
+lock operations. Subjective observation shows an
+improvement of approximately 30-35% in R/W locks
+(from tests/rwlock7.c). This is compared to the
+already improved snapshot-2001-06-06.
+
+The price paid for this improvement is that some checking
+for errors is not done for these mutex types. The onus
+is placed on the developer to check application code
+for logical errors, or use a safer mutex type such as
+PTHREAD_MUTEX_ERRORCHECK. For example, it is now
+possible for a non-owner thread to unlock or destroy
+a mutex of these types. However, because the owner
+is not simply left as NULL but set to a special anonymous
+owner value when locked and then reset to NULL when
+unlocked or destroyed, an error will ultimately eventuate
+when the owner thread subsequently attempts to unlock or
+destroy the mutex.
+
+These mutex changes appear to be consistent with both
+the behaviour exhibited by other implementations and their
+documentation, including the Open Group documentation.
+
+
+-------
+Bug fix
+-------
+Pthread_create now sets the priority of the new thread
+from the value set in the thread attribute. 
+- from Ralf.Brese@pdb4.siemens.de.
+
 
+---------------------------
 Known bugs in this snapshot
 ---------------------------
 
@@ -173,24 +238,22 @@ reliably.
 Level of standards conformance
 ------------------------------
 
-The following POSIX 1003.1c 1995 options are defined:
+The following POSIX 1003.1c 1995 and POSIX 1003.1b options are defined:
 
       _POSIX_THREADS
       _POSIX_THREAD_SAFE_FUNCTIONS
       _POSIX_THREAD_ATTR_STACKSIZE
+      _POSIX_THREAD_PRIORITY_SCHEDULING
+      _POSIX_SEMAPHORES
 
 
 The following POSIX 1003.1c 1995 options are not defined:
 
       _POSIX_THREAD_ATTR_STACKADDR
-      _POSIX_THREAD_PRIORITY_SCHEDULING
       _POSIX_THREAD_PRIO_INHERIT
       _POSIX_THREAD_PRIO_PROTECT
       _POSIX_THREAD_PROCESS_SHARED
 
-The following POSIX 1003.1b option is defined:
-
-      _POSIX_SEMAPHORES
 
 The following functions are implemented:
 
@@ -291,6 +354,10 @@ The following functions are implemented:
       ---------------------------
       pthread_attr_getschedparam  
       pthread_attr_setschedparam  
+      pthread_attr_getinheritsched
+      pthread_attr_setinheritsched
+      pthread_attr_getschedpolicy (only supports SCHED_OTHER)
+      pthread_attr_setschedpolicy (only supports SCHED_OTHER)
       pthread_getschedparam
       pthread_setschedparam
       pthread_getconcurrency
@@ -299,6 +366,9 @@ The following functions are implemented:
       pthread_attr_setscope  (returns an error ENOSYS)
       sched_get_priority_max (POSIX 1b)
       sched_get_priority_min (POSIX 1b)
+      sched_rr_set_interval  (POSIX 1b  - returns an error ENOSYS)
+      sched_setscheduler     (POSIX 1b  - only supports SCHED_OTHER)
+      sched_getscheduler     (POSIX 1b  - only supports SCHED_OTHER)
       sched_yield            (POSIX 1b)
 
       ---------------------------
@@ -344,10 +414,6 @@ The following functions are not implemented:
       ---------------------------
       RealTime Scheduling
       ---------------------------
-      pthread_attr_getinheritsched
-      pthread_attr_getschedpolicy
-      pthread_attr_setinheritsched
-      pthread_attr_setschedpolicy
       pthread_mutex_getprioceiling
       pthread_mutex_setprioceiling
       pthread_mutex_attr_getprioceiling
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 74fe21b..91cdb73 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -32,3 +32,5 @@ Thomas Pfaff            tpfaff@gmx.net
 Franco Bez              franco.bez@gmx.de
 Alexander Terekhov      TEREKHOV@de.ibm.com
 Louis Thomas		lthomas@arbitrade.com
+David Korn		dgk@research.att.com
+
diff --git a/ChangeLog b/ChangeLog
index 4bd5a44..70b1755 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3142 +1,3205 @@
-2001-06-18  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	* Made organisational-only changes to UWIN additions.
-	* dll.c (dllMain): Moved UWIN process attach code
-	to pthread_win32_process_attach_np(); moved
-	instance of pthread_count to global.c.
-	* global.c (pthread_count): Moved from dll.c.
-	* nonportable.c (pthread_win32_process_attach_np):
-	Moved _UWIN code to here from dll.c.
-	* implement.h (pthread_count): Define extern int.
-	* create.c (pthread_count): Remove extern int.
-	* private.c (pthread_count): Likewise.
-	* exit.c (pthread_count): Likewise.
-
-2001-06-18  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	Contributed by -  David Korn <dgk@research.att.com>
-
-	* dll.c: Added changes necessary to work with UWIN.
-	* create.c: Likewise.
-	* pthread.h: Likewise.
-	* misc.c: Likewise.
-	* exit.c: Likewise.
-	* private.c: Likewise.
-	* implement.h: Likewise.
-	There is some room at the start of struct pthread_t_
-	to implement the signal semantics in UWIN's posix.dll
-	although this is not yet complete.
-	* Nmakefile: Compatible with UWIN's Nmake utility.
-	* Nmakefile.tests: Likewise - for running the tests.
-
-2001-06-08  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	* semaphore.h (sem_t): Fixed for compile and test.
-	* implement.h (sem_t_): Likewise.
-	* semaphore.c: Likewise.
-	* private.c (ptw32_sem_timedwait): Updated to use new
-	opaque sem_t.
-
-2001-06-06  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	* semaphore.h (sem_t): Is now an opaque pointer;
-	moved actual definition to implement.h.
-	* implement.h (sem_t_): Move here from semaphore.h;
-	was the definition of sem_t.
-	* semaphore.c: Wherever necessary, changed use of sem
-	from that of a pointer to a pointer-pointer; added
-	extra checks for a valid sem_t; NULL sem_t when
-	it is destroyed; added extra checks when creating
-	and destroying sem_t elements in the NEED_SEM
-	code branches; changed from using a pthread_mutex_t
-	((*sem)->mutex) to CRITICAL_SECTION ((*sem)->sem_lock_cs)
-	in NEED_SEM branches for access serialisation.
-
-2001-06-06  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	* mutex.c (pthread_mutexattr_init): Remove 
-	ptw32_mutex_default_kind.
-	
-2001-06-05  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	* nonportable.c (pthread_mutex_setdefaultkind_np):
-	Remove - should not have been included in the first place.
-	(pthread_mutex_getdefaultkind_np): Likewise.
-	* global.c (ptw32_mutex_default_kind): Likewise.
-	* mutex.c (pthread_mutex_init): Remove use of
-	ptw32_mutex_default_kind.
-	* pthread.h (pthread_mutex_setdefaultkind_np): Likewise.
-	(pthread_mutex_getdefaultkind_np): Likewise.
-	* pthread.def (pthread_mutexattr_setkind_np): Added.
-	(pthread_mutexattr_getkind_np): Likewise.
-
-	* README: Many changes that should have gone in before
-	the last snapshot.
-	* README.NONPORTABLE: New - referred to by ANNOUNCE
-	but never created; documents the non-portable routines
-	included in the library - moved from README with new
-	routines added.
-	* ANNOUNCE (pthread_mutexattr_setkind_np): Added to
-	compliance list.
-	(pthread_mutexattr_getkind_np): Likewise.
-
-2001-06-04  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	* condvar.c: Add original description of the algorithm as
-	developed by Terekhov and Thomas, plus reference to
-	README.CV.
-
-2001-06-03  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	Contributed by  - Alexander Terekhov <TEREKHOV@de.ibm.com>
-	                - Louis Thomas <lthomas@arbitrade.com>
-
-	* condvar.c (pthread_cond_init): Completely revamped.
-	(pthread_cond_destroy): Likewise.
-	(ptw32_cond_wait_cleanup): Likewise.
-	(ptw32_cond_timedwait): Likewise.
-	(ptw32_cond_unblock): New general signaling routine.
-	(pthread_cond_signal): Now calls ptw32_cond_unblock.
-	(pthread_cond_broadcast): Likewise.
-	* implement.h (pthread_cond_t_): Revamped.
-	* README.CV: New; explanation of the above changes.
-
-2001-05-30  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	* pthread.h (rand_r): Fake using _seed argument to quell
-	compiler warning (compiler should optimise this away later).
-
-	* GNUmakefile (OPT): Leave symbolic information out of the library
-	and increase optimisation level - for smaller faster prebuilt
-	dlls.
-	
-2001-05-29  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	Contributed by  - Milan Gardian <Milan.Gardian@LEIBINGER.com>
-
-	* Makefile: fix typo.
-	* pthreads.h: Fix problems with stdcall/cdecl conventions, in particular
-	remove the need for PT_STDCALL everywhere; remove warning supression.
-	* (errno): Fix the longstanding "inconsistent dll linkage" problem
-	with errno; now also works with /MD debugging libs - 
-	warnings emerged when compiling pthreads library with /MD (or /MDd)
-	compiler switch, instead of /MT (or /MTd) (i.e. when compiling pthreads
-	using Multithreaded DLL CRT instead of Multithreaded statically linked
-	CRT).
-	* create.c (pthread_create): Likewise; fix typo.
-	* private.c (ptw32_threadStart): Eliminate use of terminate() which doesn't
-	throw exceptions.
-	* Remove unnecessary #includes from a number of modules -
-	[I had to #include malloc.h in implement.h for gcc - rpj].
-
-2001-05-29  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	Contributed by 	- Thomas Pfaff <tpfaff@gmx.net>
-
-	* pthread.h (PTHREAD_MUTEX_DEFAULT): New; equivalent to
-	PTHREAD_MUTEX_DEFAULT_NP.
-	* (PTHREAD_MUTEX_NORMAL): Similarly.
-	* (PTHREAD_MUTEX_ERRORCHECK): Similarly.
-	* (PTHREAD_MUTEX_RECURSIVE): Similarly.
-	* (pthread_mutex_setdefaultkind_np): New; Linux compatibility stub
-	for pthread_mutexattr_settype.
-	* (pthread_mutexattr_getkind_np): New; Linux compatibility stub
-	for pthread_mutexattr_gettype.
-	* mutex.c (pthread_mutexattr_settype): New; allow
-	the following types of mutex:
-	  PTHREAD_MUTEX_DEFAULT_NP
-	  PTHREAD_MUTEX_NORMAL_NP
-	  PTHREAD_MUTEX_ERRORCHECK_NP
-	  PTHREAD_MUTEX_RECURSIVE_NP
-	* Note that PTHREAD_MUTEX_DEFAULT is equivalent to
-	PTHREAD_MUTEX_NORMAL - ie. mutexes should no longer
-	be recursive by default, and a thread will deadlock if it
-	tries to relock a mutex it already owns. This is inline with
-	other pthreads implementations.
-	* (pthread_mutex_lock): Process the lock request
-	according to the mutex type.
-	* (pthread_mutex_init): Eliminate use of Win32 mutexes as the
-	basis of POSIX mutexes - instead, a combination of one critical section
-	and one semaphore are used in conjunction with Win32 Interlocked* routines.
-	* (pthread_mutex_destroy): Likewise.
-	* (pthread_mutex_lock): Likewise.
-	* (pthread_mutex_trylock): Likewise.
-	* (pthread_mutex_unlock): Likewise.
-	* Use longjmp/setjmp to implement cancelation when building the library
-	using a C compiler which doesn't support exceptions, e.g. gcc -x c (note
-	that gcc -x c++ uses exceptions).
-	* Also fixed some of the same typos and eliminated PT_STDCALL as
-	Milan Gardian's patches above.
-
-2001-02-07  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	Contributed by  - Alexander Terekhov <TEREKHOV@de.ibm.com>
-	
-	* rwlock.c: Revamped.
-	* implement.h (pthread_rwlock_t_): Redefined.
-	This implementation does not have reader/writer starvation problem.
-	Rwlock attempts to behave more like a normal mutex with
-	races and scheduling policy determining who is more important;
-	It also supports recursive locking,
-	has less synchronization overhead (no broadcasts at all,
-	readers are not blocked on any condition variable) and seem to
-	be faster than the current implementation [W98 appears to be
-	approximately 15 percent faster at least - on top of speed increase
-	from Thomas Pfaff's changes to mutex.c - rpj].
-
-2000-12-29  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* Makefile: Back-out "for" loops which don't work.
-
-	* GNUmakefile: Remove the fake.a target; add the "realclean"
-	target; don't remove built libs under the "clean" target.
-
-	* config.h: Add a guard against multiple inclusion.
-
-	* semaphore.h: Add some defines from config.h to make
-	semaphore.h independent of config.h when building apps.
-
-	* pthread.h (_errno): Back-out previous fix until we know how to
-	fix it properly.
-
-	* implement.h (lockCount): Add missing element to pthread_mutex_t_.
-
-	* sync.c (pthread_join): Spelling fix in comment.
-
-	* private.c (ptw32_threadStart): Reset original termination
-	function (C++).
-	(ptw32_threadStart): Cleanup detached threads early in case
-	the library is statically linked.
-	(ptw32_callUserDestroyRoutines): Remove [SEH] __try block from
-	destructor call so that unhandled exceptions will be passed through
-	to the 	system; call terminate() from [C++] try block for the same
-	reason.
-
-	* tsd.c (pthread_getspecific): Add comment.
-
-	* mutex.c (pthread_mutex_init): Initialise new elements in
-	pthread_mutex_t.
-	(pthread_mutex_unlock): Invert "pthread_equal()" test.
-
-2000-12-28  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* semaphore.c (mode_t): Use ifndef HAVE_MODE_T to include definition.
-
-	* config.h.in (HAVE_MODE_T): Added.
-	(_UWIN): Start adding defines for the UWIN package.
-
-	* private.c (ptw32_threadStart): Unhandled exceptions are
-	now passed through to the system to deal with. This is consistent
-	with normal Windows behaviour. C++ applications may use
-	set_terminate() to override the default behaviour which is
-	to call ptw32_terminate(). Ptw32_terminate() cleans up some
-	POSIX thread stuff before calling the system default function
-	which calls abort(). The users termination function should conform
-	to standard C++ semantics which is to not return. It should
-	exit the thread (call pthread_exit()) or exit the application.
-	* private.c (ptw32_terminate): Added as the default set_terminate()
-	function. It calls the system default function after cleaning up
-	some POSIX thread stuff.
-
-	* implement.h (ptw32_try_enter_critical_section): Move
-	declaration.
-	* global.c (ptw32_try_enter_critical_section): Moved
-	from dll.c.
-	* dll.c: Move process and thread attach/detach code into
-	functions in nonportable.c.
-	* nonportable.c (pthread_win32_process_attach_np): Process
-	attach code from dll.c is now available to static linked
-	applications.
-	* nonportable.c (pthread_win32_process_detach_np): Likewise.
-	* nonportable.c (pthread_win32_thread_attach_np): Likewise.
-	* nonportable.c (pthread_win32_thread_detach_np): Likewise.
-
-	* pthread.h: Add new non-portable prototypes for static
-	linked applications.
-
-	* GNUmakefile (OPT): Increase optimisation flag and remove
-	debug info flag.
-
-	* pthread.def: Add new non-portable exports for static
-	linked applications.
-
-2000-12-11  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* FAQ: Update Answer 6 re getting a fully working
-	Mingw32 built library.
-
-2000-10-10  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
- 
-        * misc.c (pthread_self): Restore Win32 "last error"
-        cleared by TlsGetValue() call in
-        pthread_getspecific()
-        - "Steven Reddie" <smr@essemer.com.au>
- 
-2000-09-20  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
- 
-        * mutex.c (pthread_mutex_lock): Record the owner
-        of the mutex. This requires also keeping count of
-        recursive locks ourselves rather than leaving it
-        to Win32 since we need to know when to NULL the
-        thread owner when the mutex is unlocked.
-        (pthread_mutex_trylock): Likewise.
-        (pthread_mutex_unlock): Check that the calling
-        thread owns the mutex, decrement the recursive
-        lock count, and NULL the owner if zero. Return
-        EPERM if the mutex is owned by another thread.
-        * implement.h (pthread_mutex_t_): Add ownerThread
-        and lockCount members.
-        - reported by Arthur Kantor <akantor@bexusa.com>
-
-2000-09-13  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	* mutex.c (pthread_mutex_init): Call
-	TryEnterCriticalSection through the pointer
-	rather than directly so that the dll can load
-	on Windows versions that can't resolve the
-	function, eg. Windows 95
-	- "Jef Gearhart" <jgearhart@tpssys.com>
-
-2000-09-09  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* pthread.h (ctime_r): Fix arg.
-
-2000-09-08  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* GNUmakefile(_WIN32_WINNT=0x400): Define in CFLAGS;
-	doesn't seem to be needed though.
-
-	* cancel.c (pthread_cancel): Must get "self" through
-	calling pthread_self() which will ensure a POSIX thread
-	struct is built for non-POSIX threads; return an error
-	if this fails
-	- Ollie Leahy <ollie@mpt.ie>
-	(pthread_setcancelstate): Likewise.
-	(pthread_setcanceltype): Likewise.
-	* misc.c (ptw32_cancelable_wait): Likewise.
-
-	* private.c (ptw32_tkAssocCreate): Remove unused #if 0
-	wrapped code.
-
-	* pthread.h (ptw32_get_exception_services_code):
-	Needed to be forward declared unconditionally.
-
-2000-09-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* cancel.c (pthread_cancel): If called from the main
-	thread "self" would be NULL; get "self" via pthread_self()
-	instead of directly from TLS so that an implicit
-	pthread object is created.
-
-	* misc.c (pthread_equal): Strengthen test for NULLs.
-
-2000-09-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* condvar.c (ptw32_cond_wait_cleanup): Ensure that all
-	waking threads check if they are the last, and notify
-	the broadcaster if so - even if an error occurs in the
-	waiter.
-
-	* semaphore.c (_decrease_semaphore): Should be
-	a call to ptw32_decrease_semaphore.
-	(_increase_semaphore): Should be a call to
-	ptw32_increase_semaphore.
-
-	* misc.c (ptw32_cancelable_wait): Renamed from
-	CancelableWait.
-	* rwlock.c (_rwlock_check*): Renamed to
-	ptw32_rwlock_check*.
-	* mutex.c (_mutex_check*): Renamed to ptw32_mutex_check*.
-	* condvar.c (cond_timed*): Renamed to ptw32_cond_timed*.
-	(_cond_check*): Renamed to ptw32_cond_check*.
-	(cond_wait_cleanup*): Rename to ptw32_cond_wait_cleanup*.
-	(ptw32_cond_timedwait): Add comments.
-
-2000-08-22  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	* private.c (ptw32_throw): Fix exception test;
-	move exceptionInformation declaration.
-
-	* tsd.c (pthread_key_create): newkey wrongly declared.
-
-	* pthread.h: Fix comment block.
-
-2000-08-18  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	* mutex.c (pthread_mutex_destroy): Check that the mutex isn't
-	held; invalidate the mutex as early as possible to avoid
-	contention; not perfect - FIXME!
-
-	* rwlock.c (pthread_rwlock_init): Remove redundant assignment
-	to "rw".
-	(pthread_rwlock_destroy): Invalidate the rwlock before
-	freeing up any of it's resources - to avoid contention.
-
-	* private.c (ptw32_tkAssocCreate): Change assoc->lock
-	to use a dynamically initialised mutex - only consumes
-	a W32 mutex or critical section when first used,
-	not before.
-
-	* mutex.c (pthread_mutex_init): Remove redundant assignment
-	to "mx".
-	(pthread_mutexattr_destroy): Set attribute to NULL
-	before freeing it's memory - to avoid contention.
-
-	* implement.h (PTW32_EPS_CANCEL/PTW32_EPS_EXIT):
-	Must be defined for all compilers - used as generic
-	exception selectors by ptw32_throw().
-
-	* Several: Fix typos from scripted edit session
-	yesterday.
-
-	* nonportable.c (pthread_mutexattr_setforcecs_np):
-	Moved this function from mutex.c.
-	(pthread_getw32threadhandle_np): New function to
-	return the win32 thread handle that the POSIX
-	thread is using.
-	* mutex.c (pthread_mutexattr_setforcecs_np):
-	Moved to new file "nonportable.c".
-
-	* pthread.h (PTW32_BUILD): Only	redefine __except
-	and catch compiler keywords if we aren't building
-	the library (ie. PTW32_BUILD is not defined) - 
-	this is safer than defining and then undefining
-	if not building the library.
-	* implement.h: Remove __except and catch undefines.
-	* Makefile (CFLAGS): Define PTW32_BUILD.
-	* GNUmakefile (CFLAGS): Define PTW32_BUILD.
-
-	* All appropriate: Change Pthread_exception* to
-	ptw32_exception* to be consistent with internal
-	identifier naming.
-
-	* private.c (ptw32_throw): New function to provide
-	a generic exception throw for all internal
-	exceptions and EH schemes.
-	(ptw32_threadStart): pthread_exit() value is now
-	returned via the thread structure exitStatus
-	element.
-	* exit.c (pthread_exit): pthread_exit() value is now
-	returned via the thread structure exitStatus
-	element.
-	* cancel.c (ptw32_cancel_self): Now uses ptw32_throw.
-	(pthread_setcancelstate): Ditto.
-	(pthread_setcanceltype): Ditto.
-	(pthread_testcancel): Ditto.
-	(pthread_cancel): Ditto.
-	* misc.c (CancelableWait): Ditto.
-	* exit.c (pthread_exit): Ditto.
-	* All applicable: Change PTW32_ prefix to
-	PTW32_ prefix to remove leading underscores
-	from private library identifiers.
-
-2000-08-17  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* All applicable: Change _pthread_ prefix to
-	ptw32_ prefix to remove leading underscores
-	from private library identifiers (single
-	and double leading underscores are reserved in the
-	ANSI C standard for compiler implementations).
-
-	* tsd.c (pthread_create_key): Initialise temporary
-	key before returning it's address to avoid race
-	conditions.
-
-2000-08-13  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* errno.c: Add _MD precompile condition; thus far
-	had no effect when using /MD compile option but I
-	thnk it should be there.
-
-	* exit.c: Add __cplusplus to various #if lines;
-	was compiling SEH code even when VC++ had
-	C++ compile options.
-
-	* private.c: ditto.
-
-	* create.c (pthread_create): Add PT_STDCALL macro to
-	function pointer arg in _beginthread().
-
-	* pthread.h: PT_STDCALL really does need to be defined
-	in both this and impliment.h; don't set it to __cdecl
-	- this macro is only used to extend function pointer
-	casting for functions that will be passed as parameters.
-	(~PThreadCleanup): add cast and group expression.
-	(_errno): Add _MD compile conditional.
-	(PtW32NoCatchWarn): Change pragma message.
-
-	* implement.h: Move and change PT_STDCALL define.
-
-	* need_errno.h: Add _MD to compilation conditional.
-
-	* GNUmakefile: Substantial rewrite for new naming
-	convention; set for nil optimisation (turn it up
-	when we have a working library build; add target
-	"fake.a" to build a libpthreadw32.a from the VC++
-	built DLL pthreadVCE.dll.
-
-	* pthread.def (LIBRARY): Don't specify in the .def
-	file - it is specified on the linker command line
-	since we now use the same .def file for variously
-	named .dlls.
-
-	* Makefile: Substantial rewrite for new naming
-	convention; default nmake target only issues a
-	help message; run nmake with specific target
-	corresponding to the EH scheme being used.
-
-	* README: Update information; add naming convention
-	explanation.
-
-	* ANNOUNCE: Update information.
-
-2000-08-12  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* pthread.h: Add compile-time message when using
-	MSC_VER compiler and C++ EH to warn application
-	programmers to use PtW32Catch instead of catch(...)
-	if they want cancelation and pthread_exit to work.
-
-	* implement.h: Remove #include <semaphore.h>; we
-	use our own local semaphore.h.
-
-2000-08-10  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* cleanup.c (pthread_pop_cleanup): Remove _pthread
-	prefix from __except and catch keywords; implement.h
-	now simply undefines ptw32__except and
-	ptw32_catch if defined; VC++ was not textually
-	substituting ptw32_catch etc back to catch as
-	it was redefined; the reason for using the prefixed
-	version was to make it clear that it was not using
-	the pthread.h redefined catch keyword.
-
-	* private.c (ptw32_threadStart): Ditto.
-	(ptw32_callUserDestroyRoutines): Ditto.
-
-	* implement.h (ptw32__except): Remove #define.
-	(ptw32_catch): Remove #define.
-
-	* GNUmakefile (pthread.a): New target to build
-	libpthread32.a from pthread.dll using dlltool.
-
-	* buildlib.bat: Duplicate cl commands with args to
-	build C++ EH version of pthread.dll; use of .bat
-	files is redundant now that nmake compatible
-	Makefile is included; used as a kludge only now.
-
-	* Makefile: Localise some macros and fix up the clean:
-	target to extend it and work properly.
-
-	* CONTRIBUTORS: Add contributors.
-
-	* ANNOUNCE: Updated.
-
-	* README: Updated.
-
-2000-08-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* pthread.h: Remove #warning - VC++ doesn't accept it.
-
-2000-08-05  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* pthread.h (PtW32CatchAll): Add macro. When compiling
-	applications using VC++ with C++ EH rather than SEH
-	'PtW32CatchAll' must be used in place of any 'catch( ... )'
-	if the application wants pthread cancelation or
-	pthread_exit() to work.
-
-2000-08-03  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* pthread.h: Add a base class ptw32_exception for
-	library internal exceptions and change the "catch"
-	re-define macro to use it.
-
-2000-08-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* GNUmakefile (CFLAGS): Add -mthreads.
-	Add new targets to generate cpp and asm output.
-
-	* sync.c (pthread_join): Remove dead code.
-
-2000-07-25  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* sched.c (sched_get_priority_max): Handle different WinCE and
-	Win32 priority values together.
-	(sched_get_priority_min): Ditto.
-	- Tristan Savatier <tristan@mpegtv.com>
-
-	* create.c (pthread_create): Force new threads to wait until
-	pthread_create has the new thread's handle; we also retain
-	a local copy of the handle for internal use until
-	pthread_create returns.
-
-	* private.c (ptw32_threadStart): Initialise ei[].
-	(ptw32_threadStart): When beginthread is used to start the
-	thread, force waiting until the creator thread had the 
-	thread handle.
-
-	* cancel.c (ptw32_cancel_thread): Include context switch
-	code for defined(_X86_) environments in addition to _M_IX86.
-
-	* rwlock.c (pthread_rwlock_destroy): Assignment changed
-	to avoid compiler warning.
-
-	* private.c (ptw32_get_exception_services_code): Cast
-	NULL return value to avoid compiler warning.
-
-	* cleanup.c (pthread_pop_cleanup): Initialise "cleanup" variable
-	to avoid compiler warnings.
-
-	* misc.c (ptw32_new): Change "new" variable to "t" to avoid
-	confusion with the C++ keyword of the same name.
-
-	* condvar.c (cond_wait_cleanup): Initialise lastWaiter variable.
-	(cond_timedwait): Remove unused local variables. to avoid
-	compiler warnings.
-
-	* dll.c (dllMain): Remove 2000-07-21 change - problem
-	appears to be in pthread_create().
-
-2000-07-22  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* tsd.c (pthread_key_create): If a destructor was given
-	and the pthread_mutex_init failed, then would try to
-	reference a NULL pointer (*key); eliminate this section of
-	code by using a dynamically initialised mutex
-	(PTHREAD_MUTEX_INITIALIZER).
-
-	* tsd.c (pthread_setspecific): Return an error if
-	unable to set the value; simplify cryptic conditional.
-
-	* tsd.c (pthread_key_delete): Locking threadsLock relied
-	on mutex_lock returning an error if the key has no destructor.
-	ThreadsLock is only initialised if the key has a destructor.
-	Making this mutex a static could reduce the number of mutexes
-	used by an application since it is actually created only at
-	first use and it's often destroyed soon after.
-	
-2000-07-22  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* FAQ: Added Q5 and Q6.
-
-2000-07-21  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
-
-	* create.c (pthread_create): Set threadH to 0 (zero)
-	everywhere. Some assignments were using NULL. Maybe
-	it should be NULL everywhere - need to check. (I know
-	they are nearly always the same thing - but not by
-	definition.)
-
-	* dll.c: Include resource leakage work-around. This is a
-	partial FIXME which doesn't stop all leakage. The real
-	problem needs to be found and fixed.
-	- "David Baggett" <dmb@itasoftware.com>
-
-	* misc.c (pthread_self): Try to catch NULL thread handles
-	at the point where they might be generated, even though
-	they should always be valid at this point.
-
-	* tsd.c (pthread_setspecific): return an error value if
-	pthread_self() returns NULL.
-
-	* sync.c (pthread_join): return an error value if
-	pthread_self() returns NULL.
-
-	* signal.c (pthread_sigmask): return an error value if
-	pthread_self() returns NULL.
-
-2000-03-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* attr.c (pthread_attr_init): Set default stacksize to zero (0)
-	rather than PTHREAD_STACK_MIN even though these are now the same.
-
-	* pthread.h (PTHREAD_STACK_MIN): Lowered to 0.
-
-2000-01-28  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* mutex.c (pthread_mutex_init): Free mutex if it has been alloced;
-	if critical sections can be used instead of Win32 mutexes, test
-	that the critical section works and return an error if not.
-
-2000-01-07  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* cleanup.c (pthread_pop_cleanup): Include SEH code only if MSC is not
-	compiling as C++.
-	(pthread_push_cleanup): Include SEH code only if MSC is not
-	compiling as C++.
-
-	* pthread.h: Include SEH code only if MSC is not
-	compiling as C++.
-
-	* implement.h: Include SEH code only if MSC is not
-	compiling as C++.
-
-	* cancel.c (ptw32_cancel_thread): Add _M_IX86 check.
-	(pthread_testcancel): Include SEH code only if MSC is not
-	compiling as C++.
-	(ptw32_cancel_self): Include SEH code only if MSC is not
-	compiling as C++.
-
-2000-01-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* Makefile: Remove inconsistencies in 'cl' args
-	- Erik Hensema <erik.hensema@group2000.nl>
-
-2000-01-04  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* private.c (ptw32_get_exception_services_code): New; returns
-	value of EXCEPTION_PTW32_SERVICES.
-	(ptw32_processInitialize): Remove initialisation of
-	ptw32_exception_services which is no longer needed.
-
-	* pthread.h (ptw32_exception_services): Remove extern.
-	(ptw32_get_exception_services_code): Add function prototype;
-	use this to return EXCEPTION_PTW32_SERVICES value instead of
-	using the ptw32_exception_services variable which I had
-	trouble exporting through pthread.def.
-
-	* global.c (ptw32_exception_services): Remove declaration.
-
-1999-11-22  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* implement.h: Forward declare ptw32_new();
-
-	* misc.c (ptw32_new): New; alloc and initialise a new pthread_t.
-	(pthread_self): New thread struct is generated 	by new routine
-	ptw32_new().
-
-	* create.c (pthread_create): New thread struct is generated
-	by new routine ptw32_new().
-
-1999-11-21  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* global.c (ptw32_exception_services): Declare new variable. 
-
-	* private.c (ptw32_threadStart): Destroy thread's
-	cancelLock mutex; make 'catch' and '__except' usageimmune to
-	redfinitions in pthread.h.
-	(ptw32_processInitialize): Init new constant ptw32_exception_services.
-
-	* create.c (pthread_create): Initialise thread's cancelLock
-	mutex.
-
-	* cleanup.c (pthread_pop_cleanup): Make 'catch' and '__except'
-	usage immune to redfinition s in pthread.h.
-
-	* private.c: Ditto.
-
-	* pthread.h (catch): Redefine 'catch' so that C++ applications
-	won't catch our internal exceptions.
-	(__except): ditto for __except.
-
-	* implement.h (ptw32_catch): Define internal version
-	of 'catch' because 'catch' is redefined by pthread.h.
-	(__except): ditto for __except.
-	(struct pthread_t_): Add cancelLock mutex for async cancel
-	safety.
-
-	* cancel.c (ptw32_cancel_self): New; part of the async
-	cancellation implementation.
-	(ptw32_cancel_thread): Ditto; this function is X86
-	processor specific.
-	(pthread_setcancelstate): Add check for pending async
-	cancel request and cancel the calling thread if
-	required; add async-cancel safety lock.
-	(pthread_setcanceltype): Ditto.
-	- Jason Nye <jnye@nbnet.nb.ca>
-	- Erik Hensema <erik.hensema@group2000.nl>
-
-1999-11-13  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* configure.in (AC_OUTPUT): Put generated output into GNUmakefile
-	rather than Makefile. Makefile will become the MSC nmake compatible
-	version
-	- Erik Hensema <erik.hensema@group2000.nl>
-
-	* misc.c (pthread_self): Add a note about GetCurrentThread
-	returning a pseudo-handle
-	- John Bossom (John.Bossom@cognos.com>
-
-1999-11-10  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* dll.c (dllMain): Free kernel32 ASAP.
-	If TryEnterCriticalSection is not being used, then free
-	the kernel32.dll handle now, rather than leaving it until
-	DLL_PROCESS_DETACH.
-
-	Note: this is not a pedantic exercise in freeing unused
-	resources!  It is a work-around for a bug in Windows 95
-	(see microsoft knowledge base article, Q187684) which
-	does Bad Things when FreeLibrary is called within
-	the DLL_PROCESS_DETACH code, in certain situations.
-	Since w95 just happens to be a platform which does not
-	provide TryEnterCriticalSection, the bug will be
-	effortlessly avoided.
-	- Todd Owen <towen@lucidcalm.dropbear.id.au>
-
-	* sync.c (pthread_join): Make it a deferred cancelation point.
-
-	* misc.c (pthread_self): Explicitly initialise implicitly
-	created thread state to default values.
-
-1999-11-05  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.h (winsock.h): Include unconditionally.
-	(ETIMEDOUT): Change fallback value to that defined by winsock.h.
-	
-	* general: Patched for portability to WinCE. The details are
-	described in the file WinCE-PORT. Follow the instructions
-	in README.WinCE to make the appropriate changes in config.h.
-	- Tristan Savatier <tristan@mpegtv.com>
-
-1999-10-30  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* create.c (pthread_create): Explicitly initialise thread state to
-	default values.
-
-	* cancel.c (pthread_setcancelstate): Check for NULL 'oldstate'
-	for compatibility with Solaris pthreads;
-	(pthread_setcanceltype): ditto:
-	- Erik Hensema <erik.hensema@group2000.nl>
-
-1999-10-23  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.h (ctime_r): Fix incorrect argument "_tm"
-	- Erik Hensema <erik.hensema@group2000.nl>
-
-1999-10-21  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.h (_POSIX_THREADS): Only define it if it isn't
-	already defined. Projects may need to define this on
-	the CC command line under Win32 as it doesn't have unistd.h
-	- Aurelio Medina <aureliom@crt.com>
-
-1999-10-17  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* rwlock.c (pthread_rwlock_destroy): Add cast to remove compile
-	warning.
-
-	* condvar.c (pthread_cond_broadcast): Only release semaphores
-	if there are waiting threads.
-
-1999-10-15  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* condvar.c (cond_wait_cleanup): New static cleanup handler for
-	cond_timedwait;
-	(cond_timedwait): pthread_cleanup_push args changed;
-	canceling a thread while it's in pthread_cond_wait
-	will now decrement the waiters count and cleanup if it's the
-	last waiter.
-	- Lorin Hochstein <lmh@xiphos.ca> and 
-	  Peter Slacik <Peter.Slacik@tatramed.sk>;
-	the last waiter will now reset the CV's wasBroadcast flag
-	- Graham Dumpleton <Graham.Dumpleton@ra.pad.otc.telstra.com.au>.
-
-Thu Sep 16 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* rwlock.c (pthread_rwlock_destroy): Add serialisation.
-	(_rwlock_check_need_init): Check for detroyed rwlock.
-	* rwlock.c: Check return codes from _rwlock_check_need_init();
-	modify comments; serialise access to rwlock objects during
-	operations; rename rw_mutex to rw_lock.
-	* implement.h: Rename rw_mutex to rw_lock.
-	* mutex.c (pthread_mutex_destroy): Add serialisation.
-	(_mutex_check_need_init): Check for detroyed mutex.
-	* condvar.c (pthread_cond_destroy): Add serialisation.
-	(_cond_check_need_init): Check for detroyed condvar.
-	* mutex.c: Modify comments.
-	* condvar.c: Modify comments.
-
-Sat Sep 10 12:56:13 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	The following code for POSIX read/write locks was contributed
-	by Aurelio Medina.
-
-	* implement.h (pthread_rwlock_t_): Add.
-	* pthread.h (pthread_rwlock_t): Add.
-	(PTHREAD_RWLOCK_INITIALIZER): Add.
-	Add rwlock function prototypes.
-	* rwlock.c: New module.
-	* pthread.def: Add new rwlock functions.
-	* private.c (ptw32_processInitialize): initialise
-	ptw32_rwlock_test_init_lock critical section.
-	* global.c (ptw32_rwlock_test_init_lock): Add.
-
-	* mutex.c (pthread_mutex_destroy): Don't free mutex memory
-	if mutex is PTHREAD_MUTEX_INITIALIZER and has not been
-	initialised yet.
-
-Wed Sep  8 12:56:13 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* mutex.c (pthread_mutex_destroy): Free mutex memory.
-	- Milan Gardian <mg@tatramed.sk>
-
-1999-08-22  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* exit.c (pthread_exit): Fix reference to potentially
-	uninitialised pointer.
-
-1999-08-21  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_threadStart): Apply fix of 1999-08-19
-	this time to C++ and non-trapped C versions. Ommitted to
-	do this the first time through.
-
-1999-08-19  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_threadStart): Return exit status from
-	the application thread startup routine.
-	- Milan Gardian <mg@tatramed.sk>
-
-1999-08-18  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* exit.c (pthread_exit): Put status into pthread_t->exitStatus
-	- John Bossom <john.Bossom@cognos.com>
-	* private.c (ptw32_threadStart): Set pthread->exitStatus
-	on exit of try{} block.
-	- John Bossom <john.Bossom@cognos.com>
-	* sync.c (pthread_join): use pthread_exitStatus value if the
-	thread exit doesn't return a value (for Mingw32 CRTDLL
-	which uses endthread instead of _endthreadex).
-	- John Bossom <john.Bossom@cognos.com>
-
-Tue Aug 17 20:17:58 CDT 1999  Mumit Khan  <khan@xraylith.wisc.edu>
-
-        * create.c (pthread_create): Add CRTDLL suppport.
-        * exit.c (pthread_exit): Likewise.
-        * private.c (ptw32_threadStart): Likewise.
-        (ptw32_threadDestroy): Likewise.
-        * sync.c (pthread_join): Likewise.
-        * tests/join1.c (main): Warn about partial support for CRTDLL.
-
-Tue Aug 17 20:00:08 1999  Mumit Khan  <khan@xraylith.wisc.edu>
-
-        * Makefile.in (LD): Delete entry point.
-        * acconfig.h (STDCALL): Delete unused macro.
-        * configure.in: Remove test for STDCALL.
-        * config.h.in: Regenerate.
-        * errno.c (_errno): Fix self type.
-        * pthread.h (PT_STDCALL): Move from here to
-        * implement.h (PT_STDCALL): here.
-        (ptw32_threadStart): Fix prototype.
-        * private.c (ptw32_threadStart): Likewise.
-
-1999-08-14  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* exit.c (pthread_exit): Don't call pthread_self() but
-	get thread handle directly from TSD for efficiency.
-	
-1999-08-12  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_threadStart): ei[] only declared if _MSC_VER.
-
-	* exit.c (pthread_exit): Check for implicitly created threads
-	to avoid raising an unhandled exception.
-	
-1999-07-12  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* condvar.c (pthread_cond_destroy): Add critical section.
-	(cond_timedwait): Add critical section; check for timeout
-	waiting on semaphore.
-	(pthread_cond_broadcast): Add critical section.
-	- Peter Slacik <Peter.Slacik@tatramed.sk>
-
-1999-07-09  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	The following changes fix a bug identified by
-	Lorin Hochstein <lmh@xiphos.ca> and solved by
-	John Bossom <John.Bossom@Cognos.COM>.
-
-	The problem was that cleanup handlers were not executed when
-	pthread_exit() was called.
-
-	* implement.h (pthread_t_): Add exceptionInformation element for
-	C++ per-thread exception information.
-	(general): Define and rename exceptions.
-
-
-	* misc.c (CancelableWait):  PTW32_EPS_CANCEL (SEH) and
-	ptw32_exception_cancel (C++) used to identify the exception.
-
-	* cancel.c (pthread_testcancel): PTW32_EPS_CANCEL (SEH) and
-	ptw32_exception_cancel (C++) used to identify the exception.
-
-	* exit.c (pthread_exit): throw/raise an exception to return to
-	ptw32_threadStart() to exit the thread. PTW32_EPS_EXIT (SEH)
-	and ptw32_exception_exit (C++) used to identify the exception.
-
-	* private.c (ptw32_threadStart): Add pthread_exit exception trap;
-	clean up and exit the thread directly rather than via pthread_exit().
-
-Sun May 30 00:25:02 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* semaphore.h (mode_t): Conditionally typedef it.
-
-Fri May 28 13:33:05 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* condvar.c (pthread_cond_broadcast): Fix possible memory fault
-	- Mark E. Armstrong <avail@pacbell.net>
-	
-Thu May 27 13:08:46 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* condvar.c (pthread_cond_broadcast): Fix logic bug
-	- Peter Slacik <Peter.Slacik@tatramed.sk>;
-	optimise sem_post loop
-	- Bossom, John <John.Bossom@Cognos.COM>.
-
-Fri May 14 12:13:18 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* attr.c (pthread_attr_setdetachstate): Fix logic bug
-	- Mike Russo <miker@eai.com>.
-
-Sat May  8 09:42:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.def (sem_open): Add.
-	(sem_close): Add.
-	(sem_unlink): Add.
-	(sem_getvalue): Add.
-
-	* FAQ (Question 3): Add.
-
-Thu Apr  8 01:16:23 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* semaphore.c (sem_open): New function; returns an error (ENOSYS).
-	(sem_close): ditto.
-	(sem_unlink): ditto.
-	(sem_getvalue): ditto.
-
-	* semaphore.h (_POSIX_SEMAPHORES): define.
-	
-Wed Apr  7 14:09:52 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* errno.c (_REENTRANT || _MT): Invert condition.
-
-	* pthread.h (_errno): Conditionally include prototype.
-
-Wed Apr  7 09:37:00 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* *.c (comments): Remove individual attributions - these are
-	documented sufficiently elsewhere.
-
-	* implement.h (pthread.h): Remove extraneous include.
-
-Sun Apr  4 11:05:57 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* sched.c (sched.h): Include.
-
-	* sched.h: New file for POSIX 1b scheduling.
-
-	* pthread.h: Move opaque structures to implement.h; move sched_*
-	prototypes out and into sched.h.
-
-	* implement.h: Add opaque structures from pthread.h.
-
-	* sched.c (sched_yield): New function.
-
-	* condvar.c (ptw32_sem_*): Rename to sem_*; except for
-	ptw32_sem_timedwait which is an private function.
-
-Sat Apr  3 23:28:00 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* Makefile.in (OBJS): Add errno.o.
-
-Fri Apr  2 11:08:50 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* implement.h (ptw32_sem_*): Remove prototypes now defined in
-	semaphore.h.
-
-	* pthread.h (sempahore.h): Include.
-
-	* semaphore.h: New file for POSIX 1b semaphores.
-
-	* pthread.h (ptw32_sem_t): Change to sem_t. 
-
-	* semaphore.c (ptw32_sem_*): Change to sem_*; these functions
-	will be exported from the library; set errno on error.
-	- John Bossom <jebossom@cognos.com>
-	(ptw32_sem_timedwait): Moved to private.c.
-
-	* private.c (ptw32_sem_timedwait): Moved from semaphore.c;
-	set errno on error.
-
-	* errno.c (_errno): New file. New function.
-	- John Bossom
-
-	* pthread.h (pthread_t_): Add per-thread errno element.
-
-Fri Mar 26 14:11:45 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* semaphore.c (ptw32_sem_timedwait): Check for negative
-	milliseconds.
-	- Tor Lillqvist <tml@iki.fi>
-
-Wed Mar 24 11:32:07 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* misc.c (CancelableWait): Initialise exceptionInformation[2].
-	(pthread_self): Get a real Win32 thread handle for implicit threads.
-	- John Bossom <jebossom@cognos.com>
-
-	* cancel.c (pthread_testcancel): Initialise exceptionInformation[2].
-	- John Bossom <jebossom@cognos.com>
-
-	* implement.h (SE_INFORMATION): Fix values.
-	- John Bossom <jebossom@cognos.com>
-
-	* private.c (ptw32_threadDestroy): Close the thread handle.
-	- John Bossom <jebossom@cognos.com>
-
-Fri Mar 19 12:57:27 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* cancel.c (comments): Update and cleanup.
-
-Fri Mar 19 09:12:59 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_threadStart): status returns PTHREAD_CANCELED.
-
-	* pthread.h (PTHREAD_CANCELED): defined.
-
-Tue Mar 16  1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* all: Add GNU LGPL and Copyright and Warranty.
-	
-Mon Mar 15 00:20:13 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* condvar.c (pthread_cond_init): fix possible uninitialised use
-	of cv.
-
-Sun Mar 14 21:01:59 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* condvar.c (pthread_cond_destroy): don't do full cleanup if
-	static initialised cv has never been used.
-	(cond_timedwait): check result of auto-initialisation.
-
-Thu Mar 11 09:01:48 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.h (pthread_mutex_t): revert to (pthread_mutex_t *);
-	define a value to serve as PTHREAD_MUTEX_INITIALIZER.
-	(pthread_mutex_t_): remove staticinit and valid elements.
-	(pthread_cond_t): revert to (pthread_cond_t_ *);
-	define a value to serve as PTHREAD_COND_INITIALIZER.
-	(pthread_cond_t_): remove staticinit and valid elements.
-
-	* mutex.c (pthread_mutex_t args): adjust indirection of references.
-	(all functions): check for PTHREAD_MUTEX_INITIALIZER value;
-	check for NULL (invalid).
-
-	* condvar.c (pthread_cond_t args): adjust indirection of references.
-	(all functions): check for PTHREAD_COND_INITIALIZER value;
-	check for NULL (invalid).
-
-Wed Mar 10 17:18:12 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* misc.c (CancelableWait): Undo changes from Mar 8 and 7.
-
-Mon Mar  8 11:18:59 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* misc.c (CancelableWait): Ensure cancelEvent handle is the lowest
-	indexed element in the handles array. Enhance test for abandoned
-	objects.
-
-	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Trailing elements not
-	initialised are set to zero by the compiler. This avoids the
-	problem of initialising the opaque critical section element in it.
-	(PTHREAD_COND_INITIALIZER): Ditto.
-
-	* semaphore.c (ptw32_sem_timedwait): Check sem == NULL earlier.
-
-Sun Mar  7 12:31:14 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* condvar.c (pthread_cond_init): set semaphore initial value
-	to 0, not 1. cond_timedwait was returning signaled immediately.
-
-	* misc.c (CancelableWait): Place the cancel event handle first
-	in the handle table for WaitForMultipleObjects. This ensures that
-	the cancel event is recognised and acted apon if both objects
-	happen to be signaled together.
-
-	* private.c (ptw32_cond_test_init_lock): Initialise and destroy.
-
-	* implement.h (ptw32_cond_test_init_lock): Add extern.
-
-	* global.c (ptw32_cond_test_init_lock): Add declaration. 
-
-	* condvar.c (pthread_cond_destroy): check for valid initialised CV;
-	flag destroyed CVs as invalid.
-	(pthread_cond_init): pthread_cond_t is no longer just a pointer.
-	This is because PTHREAD_COND_INITIALIZER needs state info to reside
-	in pthread_cond_t so that it can initialise on first use. Will work on
-	making pthread_cond_t (and other objects like it) opaque again, if
-	possible, later.
-	(cond_timedwait): add check for statically initialisation of
-	CV; initialise on first use.
-	(pthread_cond_signal): check for valid CV.
-	(pthread_cond_broadcast): check for valid CV.
-	(_cond_check_need_init): Add.
-
-	* pthread.h (PTHREAD_COND_INITIALIZER): Fix.
-	(pthread_cond_t): no longer a pointer to pthread_cond_t_.
-	(pthread_cond_t_): add 'staticinit' and 'valid' elements.
-
-Sat Mar 6 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* implement.h: Undate comments.
-
-Sun Feb 21 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.h (PTHREAD_MUTEX_INITIALIZER): missing braces around
-	cs element initialiser.
-
-1999-02-21  Ben Elliston  <bje@cygnus.com>
-
-	* pthread.h (pthread_exit): The return type of this function is
-	void, not int.
-
-	* exit.c (pthread_exit): Do not return 0.
-
-Sat Feb 20 16:03:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* dll.c (DLLMain): Expand TryEnterCriticalSection support test.
-
-	* mutex.c (pthread_mutex_trylock): The check for
-	ptw32_try_enter_critical_section == NULL should have been
-	removed long ago.
-
-Fri Feb 19 16:03:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* sync.c (pthread_join): Fix pthread_equal() test.
-
-	* mutex.c (pthread_mutex_trylock): Check mutex != NULL before
-	using it.
-
-Thu Feb 18 16:17:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* misc.c (pthread_equal): Fix inverted result.
-
-	* Makefile.in: Use libpthread32.a as the name of the DLL export
-	library instead of pthread.lib.
-
-	* condvar.c (pthread_cond_init): cv could have been used unitialised;
-	initialise.
-
-	* create.c (pthread_create): parms could have been used unitialised;
-	initialise.
-
-	* pthread.h (struct pthread_once_t_): Remove redefinition.
-
-Sat Feb 13 03:03:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.h (struct pthread_once_t_): Replaced.
-
-	* misc.c (pthread_once): Replace with John Bossom's version;
-	has lighter weight serialisation; fixes problem of not holding
-	competing threads until after the init_routine completes.
-
-Thu Feb 11 13:34:14 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* misc.c (CancelableWait): Change C++ exception throw.
-
-	* sync.c (pthread_join): Change FIXME comment - issue resolved.
-
-Wed Feb 10 12:49:11 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* configure: Various temporary changes.
-	- Kevin Ruland <Kevin.Ruland@anheuser-busch.com>
-
-	* README: Update.
-
-	* pthread.def (pthread_attr_getstackaddr): uncomment
-	(pthread_attr_setstackaddr): uncomment
-
-Fri Feb  5 13:42:30 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* semaphore.c: Comment format changes.
-
-Thu Feb  4 10:07:28 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* global.c: Remove ptw32_exception instantiation.
-
-	* cancel.c (pthread_testcancel): Change C++ exception throw.
-
-	* implement.h: Remove extern declaration.
-
-Wed Feb  3 13:04:44 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* cleanup.c: Rename ptw32_*_cleanup() to pthread_*_cleanup().
-
-	* pthread.def: Ditto.
-	
-	* pthread.h: Ditto.
-
-	* pthread.def (pthread_cleanup_push): Remove from export list;
-	the function is defined as a macro under all compilers.
-	(pthread_cleanup_pop): Ditto.
-
-	* pthread.h: Remove #if defined().
-
-Wed Feb  3 10:13:48 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* sync.c (pthread_join): Check for NULL value_ptr arg;
-	check for detached threads.
-
-Tue Feb  2 18:07:43 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* implement.h: Add #include <pthread.h>.
-	Change sem_t to ptw32_sem_t.
-
-	Various patches by Kevin Ruland <Kevin.Ruland@anheuser-busch.com>
-
-	* signal.c (pthread_sigmask): Add and modify casts.
-	Reverse LHS/RHS bitwise assignments.
-
-	* pthread.h: Remove #include <semaphore.h>.
-	(PTW32_ATTR_VALID): Add cast.
-	(struct pthread_t_): Add sigmask element.
-
-	* dll.c: Add "extern C" for DLLMain.
-	(DllMain): Add cast.
-
-	* create.c (pthread_create): Set sigmask in thread.
-
-	* condvar.c: Remove #include. Change sem_* to ptw32_sem_*.
-
-	* attr.c: Changed #include.
-
-	* Makefile.in: Additional targets and changes to build the library
-	as a DLL.
-
-Fri Jan 29 11:56:28 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* Makefile.in (OBJS): Add semaphore.o to list.
-
-	* semaphore.c (ptw32_sem_timedwait): Move from private.c.
-	Rename sem_* to ptw32_sem_*.
-
-	* pthread.h (pthread_cond_t): Change type of sem_t.
-	_POSIX_SEMAPHORES no longer defined.
-
-	* semaphore.h: Contents moved to implement.h.
-	Removed from source tree.
-
-	* implement.h: Add semaphore function prototypes and rename all
-	functions to prepend 'ptw32_'. They are
-	now private to the pthreads-win32 implementation.
-
-	* private.c: Change #warning.
-	Move ptw32_sem_timedwait() to semaphore.c.
-
-	* cleanup.c: Change #warning.
-
-	* misc.c: Remove #include <errno.h>
-
-	* pthread.def: Cleanup CVS merge conflicts.
-
-	* global.c: Ditto.
-
-	* ChangeLog: Ditto.
-
-	* cleanup.c: Ditto.
-
-Sun Jan 24 01:34:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* semaphore.c (sem_wait): Remove second arg to 
-	pthreadCancelableWait() call.
-
-Sat Jan 23 17:36:40 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.def: Add new functions to export list.
-
-	* pthread.h (PTHREAD_MUTEX_AUTO_CS_NP): New.
-	(PTHREAD_MUTEX_FORCE_CS_NP): New.
-
-	* README: Updated.
-
-Fri Jan 22 14:31:59 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* Makefile.in (CFLAGS): Remove -fhandle-exceptions. Not needed
-	with egcs. Add -g for debugging.
-
-	* create.c (pthread_create): Replace __stdcall with PT_STDCALL
-	macro. This is a hack and must be fixed.
-
-	* misc.c (CancelableWait): Remove redundant statement.
-
-	* mutex.c (pthread_mutexattr_init): Cast calloc return value.
-
-	* misc.c (CancelableWait): Add cast.
-	(pthread_self): Add cast.
-
-	* exit.c (pthread_exit): Add cast.
-
-	* condvar.c (pthread_condattr_init): Cast calloc return value.
-
-	* cleanup.c: Reorganise conditional compilation.
-
-	* attr.c (pthread_attr_init): Remove unused 'result'.
-	Cast malloc return value.
-
-	* private.c (ptw32_callUserDestroyRoutines): Redo conditional
-	compilation.
-
-	* misc.c (CancelableWait): C++ version uses 'throw'.
-
-	* cancel.c (pthread_testcancel): Ditto.
-
-	* implement.h (class ptw32_exception): Define for C++.
-
-	* pthread.h: Fix C, C++, and Win32 SEH condition compilation
-	mayhem around pthread_cleanup_* defines. C++ version now uses John
-	Bossom's cleanup handlers.
-	(pthread_attr_t): Make 'valid' unsigned.
-	Define '_timeb' as 'timeb' for Ming32.
-	Define PT_STDCALL as nothing for Mingw32. May be temporary.
-
-	* cancel.c (pthread_testcancel): Cast return value.
-
-Wed Jan 20 09:31:28 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.h (pthread_mutexattr_t): Changed to a pointer.
-
-	* mutex.c (pthread_mutex_init): Conditionally create Win32 mutex
-	- from John Bossom's implementation.
-	(pthread_mutex_destroy): Conditionally close Win32 mutex
-	- from John Bossom's implementation.
-	(pthread_mutexattr_init): Replaced by John Bossom's version.
-	(pthread_mutexattr_destroy): Ditto.
-	(pthread_mutexattr_getpshared): New function from John Bossom's
-	implementation.
-	(pthread_mutexattr_setpshared): New function from John Bossom's
-	implementation.
-
-Tue Jan 19 18:27:42 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* pthread.h (pthreadCancelableTimedWait): New prototype.
-	(pthreadCancelableWait): Remove second argument.
-
-	* misc.c (CancelableWait): New static function is 
-	pthreadCancelableWait() renamed.
-	(pthreadCancelableWait): Now just calls CancelableWait() with
-	INFINITE timeout.
-	(pthreadCancelableTimedWait): Just calls CancelableWait()
-	with passed in timeout.
-
-	* private.c (ptw32_sem_timedwait): 'abstime' arg really is
-	absolute time. Calculate relative time to wait from current
-	time before passing timeout to new routine 
-	pthreadCancelableTimedWait().
-	- Scott Lightner <scott@curriculum.com>
-
-Tue Jan 19 10:27:39 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.h (pthread_mutexattr_setforcecs_np): New prototype.
-	
-	* mutex.c (pthread_mutexattr_init): Init 'pshared' and 'forcecs'
-	attributes to 0.
-	(pthread_mutexattr_setforcecs_np): New function (not portable).
-
-	* pthread.h (pthread_mutex_t): 
-	Add 'mutex' element. Set to NULL in PTHREAD_MUTEX_INITIALIZER.
-	The pthread_mutex_*() routines will try to optimise performance
-	by choosing either mutexes or critical sections as the basis
-	for pthread mutexes for each indevidual mutex.
-	(pthread_mutexattr_t_): Add 'forcecs' element.
-	Some applications may choose to force use of critical sections
-	if they know that:-
-	     the mutex is PROCESS_PRIVATE and, 
-	         either the OS supports TryEnterCriticalSection() or
-	         pthread_mutex_trylock() will never be called on the mutex.
-	This attribute will be setable via a non-portable routine.
-
-	Note: We don't yet support PROCESS_SHARED mutexes, so the
-	implementation as it stands will default to Win32 mutexes only if
-	the OS doesn't support TryEnterCriticalSection. On Win9x, and early
-	versions of NT 'forcecs' will need to be set in order to get
-	critical section based mutexes.
-
-Sun Jan 17 12:01:26 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Init new 'staticinit'
-	value to '1' and existing 'valid' value to '1'.
-
-	* global.c (ptw32_mutex_test_init_lock): Add.
-
-	* implement.h (ptw32_mutex_test_init_lock.): Add extern.
-
-	* private.c (ptw32_processInitialize): Init critical section for
-	global lock used by _mutex_check_need_init().
-	(ptw32_processTerminate): Ditto (:s/Init/Destroy/).
-
-	* dll.c (dllMain): Move call to FreeLibrary() so that it is only
-	called once when the process detaches.
-
-	* mutex.c (_mutex_check_need_init): New static function to test
-	and init PTHREAD_MUTEX_INITIALIZER mutexes. Provides serialised
-	access to the internal state of the uninitialised static mutex. 
-	Called from pthread_mutex_trylock() and pthread_mutex_lock() which
-	do a quick unguarded test to check if _mutex_check_need_init()
-	needs to be called. This is safe as the test is conservative
- 	and is repeated inside the guarded section of 
-	_mutex_check_need_init(). Thus in all calls except the first
-	calls to lock static mutexes, the additional overhead to lock any
-	mutex is a single memory fetch and test for zero.
-
-	* pthread.h (pthread_mutex_t_): Add 'staticinit' member. Mutexes
-	initialised by PTHREAD_MUTEX_INITIALIZER aren't really initialised
-	until the first attempt to lock it. Using the 'valid'
-	flag (which flags the mutex as destroyed or not) to record this
-	information would be messy. It is possible for a statically
-	initialised mutex such as this to be destroyed before ever being
-	used.
-
-	* mutex.c (pthread_mutex_trylock): Call _mutex_check_need_init()
-	to test/init PTHREAD_MUTEX_INITIALIZER mutexes.
-	(pthread_mutex_lock): Ditto.
-	(pthread_mutex_unlock): Add check to ensure we don't try to unlock
-	an unitialised static mutex.
-	(pthread_mutex_destroy): Add check to ensure we don't try to delete
-	a critical section that we never created. Allows us to destroy
-	a static mutex that has never been locked (and hence initialised).
-	(pthread_mutex_init): Set 'staticinit' flag to 0 for the new mutex.
-
-Sun Jan 17 12:01:26 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_sem_timedwait): Move from semaphore.c.
-
-	* semaphore.c : Remove redundant #includes.
-	(ptw32_sem_timedwait): Move to private.c.
-	(sem_wait): Add missing abstime arg to pthreadCancelableWait() call.
-
-Fri Jan 15 23:38:05 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* condvar.c (cond_timedwait): Remove comment.
-
-Fri Jan 15 15:41:28 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* pthread.h: Add new 'abstime' arg to pthreadCancelableWait()
-	prototype.
-
-	* condvar.c (cond_timedwait): New generalised function called by
-	both pthread_cond_wait() and pthread_cond_timedwait(). This is
-	essentially pthread_cond_wait() renamed and modified to add the
-	'abstime' arg and call the new ptw32_sem_timedwait() instead of
-	sem_wait().
-	(pthread_cond_wait): Now just calls the internal static
-	function cond_timedwait() with an INFINITE wait.
-	(pthread_cond_timedwait): Now implemented. Calls the internal
-	static function cond_timedwait().
-
-	* implement.h (ptw32_sem_timedwait): New internal function
-	prototype.
-
-	* misc.c (pthreadCancelableWait): Added new 'abstime' argument
-	to allow shorter than INFINITE wait.
-
-	* semaphore.c (ptw32_sem_timedwait): New function for internal
-	use.  This is essentially sem_wait() modified to add the
-        'abstime' arg and call the modified (see above)
-        pthreadCancelableWait().
-
-Thu Jan 14 14:27:13 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* cleanup.c: Correct _cplusplus to __cplusplus wherever used.
-
-	* Makefile.in: Add CC=g++ and add -fhandle-exceptions to CFLAGS.
-	The derived Makefile will compile all units of the package as C++
-	so that those which include try/catch exception handling should work
-	properly. The package should compile ok if CC=gcc, however, exception
-	handling will not be included and thus thread cancellation, for
- 	example, will not work.
-
-	* cleanup.c (ptw32_pop_cleanup): Add #warning to compile this
- 	file as C++ if using a cygwin32 environment. Perhaps the whole package
-	should be compiled using g++ under cygwin.
-
-	* private.c (ptw32_threadStart): Change #error directive
-	into #warning and bracket for __CYGWIN__ and derivative compilers.
-
-Wed Jan 13 09:34:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* build.bat: Delete old binaries before compiling/linking.
-
-Tue Jan 12 09:58:38 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* dll.c: The Microsoft compiler pragmas probably are more
-	appropriately protected by _MSC_VER than by _WIN32.
-	- Tor Lillqvist <tml@iki.fi>.
-
-	* condvar.c (pthread_cond_timedwait): Fix function description
-	comments.
-
-	* pthread.h: Define ETIMEDOUT. This should be returned by
-	pthread_cond_timedwait which is not implemented yet as of
-	snapshot-1999-01-04-1305. It was implemented in the older version.
-	The Microsoft compiler pragmas probably are more appropriately
-	protected by _MSC_VER than by _WIN32.
-	- Tor Lillqvist <tml@iki.fi>.
-
-	* pthread.def: pthread_mutex_destroy was missing from the def file
-	- Tor Lillqvist <tml@iki.fi>.
-
-	* condvar.c (pthread_cond_broadcast): Ensure we only wait on threads
-	if there were any waiting on the condition.
-	I think pthread_cond_broadcast should do the WaitForSingleObject
-	only if cv->waiters > 0? Otherwise it seems to hang, at least in the
-	testg thread program from glib.
-	- Tor Lillqvist <tml@iki.fi>. 
-
-	* semaphore.c (sem_post): Correct typo in comment.
-
-Mon Jan 11 20:33:19 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.h: Re-arrange conditional compile of pthread_cleanup-*
-	macros.
-
-	* cleanup.c (ptw32_push_cleanup): Provide conditional 
-	compile of cleanup->prev.
-
-1999-01-11  Ben Elliston  <bje@cygnus.com>
-
-	* condvar.c (pthread_cond_init): Invert logic when testing the
-	return value from calloc().
-	- Tor Lillqvist <tml@iki.fi>.
-
-Sat Jan  9 14:32:08 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* implement.h: Compile-time switch for CYGWIN derived environments
-	to use CreateThread instead of _beginthreadex. Ditto for ExitThread.
-	Patch provided by Anders Norlander  <anorland@hem2.passagen.se>.
-
-Tue Jan  5 16:33:04 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* cleanup.c (ptw32_pop_cleanup): Add C++ version of __try/__except
-	block. Move trailing "}" out of #ifdef _WIN32 block left there by
-	(rpj's) mistake.
-
-	* private.c: Remove #include <errno.h> which is included by pthread.h.
-
-1998-12-11  Ben Elliston  <bje@toilet.to.cygnus.com>
-
-	* README: Update info about subscribing to the mailing list.
-
-Mon Jan  4 11:23:40 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* all: No code changes, just cleanup.
-	- remove #if 0 /* Pre Bossom */ enclosed code.
-	- Remove some redundant #includes.
-	* pthread.h: Update implemented/unimplemented routines list.
-	* Tag the bossom merge branch getting ready to merge back to main
-	trunk.
-
-Tue Dec 29 13:11:16 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* implement.h: Move the following struct definitions to pthread.h:
-	pthread_t_, pthread_attr_t_, pthread_mutex_t_, pthread_mutex_t_,
-	pthread_mutexattr_t_, pthread_key_t_, pthread_cond_t_,
-	pthread_condattr_t_, pthread_once_t_.
-
-	* pthread.h: Add "_" prefix to pthread_push_cleanup and 
-	pthread_pop_cleanup internal routines, and associated struct and
-	typedefs.
-
-	* buildlib.bat: Add compile command for semaphore.c
-
-	* pthread.def: Comment out pthread_atfork routine name. 
-	Now unimplemented.
-
-	* tsd.c (pthread_setspecific): Rename tkAssocCreate to
-	ptw32_tkAssocCreate.
-	(pthread_key_delete): Rename tkAssocDestroy to
-	ptw32_tkAssocDestroy.
-
-	* sync.c (pthread_join): Rename threadDestroy to ptw32_threadDestroy
-
-	* sched.c (is_attr): attr is now **attr (was *attr), so add extra
-	NULL pointer test.
-	(pthread_attr_setschedparam): Increase redirection for attr which is
-	now a **.
-	(pthread_attr_getschedparam): Ditto.
-	(pthread_setschedparam): Change thread validation and rename "thread"
- 	Win32 thread Handle element name to match John Bossom's version.
-	(pthread_getschedparam): Ditto.
-
-	* private.c (ptw32_threadDestroy): Rename call to
-	callUserDestroyRoutines() as ptw32_callUserDestroyRoutines()
-
-	* misc.c: Add #include "implement.h".
-
-	* dll.c: Remove defined(KLUDGE) wrapped code.
-
-	* fork.c: Remove redefinition of ENOMEM.
-	Remove pthread_atfork() and fork() with #if 0/#endif.
-
-	* create.c (pthread_create): Rename threadStart and threadDestroy calls
-	to ptw32_threadStart and ptw32_threadDestroy.
-
-	* implement.h: Rename "detachedstate" to "detachstate".
-
-	* attr.c: Rename "detachedstate" to "detachstate".
-
-Mon Dec 28 09:54:39 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* semaphore.c: Initial version. From John Bossom's implementation.
-	* semaphore.h: Initial version. From John Bossom's implementation.
-
-Mon Dec 28 09:54:39 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.h (pthread_attr_t_): Change to *pthread_attr_t.
-
-	* attr.c (pthread_attr_setstacksize): Merge with John Bossom's version.
-	(pthread_attr_getstacksize): Merge with John Bossom's version.
-	(pthread_attr_setstackaddr): Merge with John Bossom's version.
-	(pthread_attr_getstackaddr): Merge with John Bossom's version.
-	(pthread_attr_init): Merge with John Bossom's version.
-	(pthread_attr_destroy): Merge with John Bossom's version.
-	(pthread_attr_getdetachstate): Merge with John Bossom's version.
-	(pthread_attr_setdetachstate): Merge with John Bossom's version.
-	(is_attr): attr is now **attr (was *attr), so add extra NULL pointer
-	test.
-
-	* implement.h (pthread_attr_t_): Add and rename elements in JEB's
-	version to correspond to original, so that it can be used with
-	original attr routines.
-
-	* pthread.h: Add #endif at end which was truncated in merging.
-
-Sun Dec 20 14:51:58 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* misc.c (pthreadCancelableWait): New function by John Bossom. Non-standard
-	but provides a hook that can be used to implement cancellation points in
-	applications that use this library.
-
-	* pthread.h (pthread_cleanup_pop): C++ (non-WIN32) version uses
-	try/catch to emulate John Bossom's WIN32 __try/__finally behaviour.
-	In the WIN32 version __finally block, add a test for AbnormalTermination otherwise
-	cleanup is only run if the cleanup_pop execute arg is non-zero. Cancellation
-	should cause the cleanup to run irrespective of the execute arg.
-
-	* condvar.c (pthread_condattr_init): Replaced by John Bossom's version.
-	(pthread_condattr_destroy): Replaced by John Bossom's version.
-	(pthread_condattr_getpshared): Replaced by John Bossom's version.
-	(pthread_condattr_setpshared): Replaced by John Bossom's version.
-	(pthread_cond_init): Replaced by John Bossom's version.
-	Fix comment (refered to mutex rather than condition variable).
-	(pthread_cond_destroy): Replaced by John Bossom's version.
-	(pthread_cond_wait): Replaced by John Bossom's version.
-	(pthread_cond_timedwait): Replaced by John Bossom's version.
-	(pthread_cond_signal): Replaced by John Bossom's version.
-	(pthread_cond_broadcast): Replaced by John Bossom's version.
-
-Thu Dec 17 19:10:46 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* tsd.c (pthread_key_create): Replaced by John Bossom's version.
-	(pthread_key_delete): Replaced by John Bossom's version.
-	(pthread_setspecific): Replaced by John Bossom's version.
-	(pthread_getspecific): Replaced by John Bossom's version.
-
-Mon Dec  7 09:44:40 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* cancel.c (pthread_setcancelstate): Replaced by John Bossom's version.
-	(pthread_setcanceltype): Replaced by John Bossom's version.
-	(pthread_testcancel): Replaced by John Bossom's version.
-	(pthread_cancel): Replaced by John Bossom's version.
-	
-	* exit.c (pthread_exit): Replaced by John Bossom's version.
-
-	* misc.c (pthread_self): Replaced by John Bossom's version.
-	(pthread_equal): Replaced by John Bossom's version.
-
-	* sync.c (pthread_detach): Replaced by John Bossom's version.
-	(pthread_join): Replaced by John Bossom's version.
-
-	* create.c (pthread_create): Replaced by John Bossom's version.
-
-	* private.c (ptw32_processInitialize): New by John Bossom.
-	(ptw32_processTerminate): Non-public function by John Bossom.
-	(ptw32_threadStart): Non-public function by John Bossom.
- 	(ptw32_threadDestroy): Non-public function by John Bossom.
-	(ptw32_cleanupStack): Non-public function by John Bossom.
-	(ptw32_tkAssocCreate): Non-public function by John Bossom.
-	(ptw32_tkAssocDestroy): Non-public function by John Bossom.
-	(ptw32_callUserDestroyRoutines): Non-public function by John Bossom.
-
-	* implement.h: Added John Bossom's non-API structures and
-	declarations.
-
-	* dll.c (PthreadsEntryPoint): Cast return value of GetProcAddress
-	to resolve compile warning from MSVC.
-
-	* dll.c (DLLmain): Replaced by John Bossom's version.
-	* dll.c (PthreadsEntryPoint):
-	Re-applied Anders Norlander's patch:-
-	Initialize ptw32_try_enter_critical_section at startup
-	and release kernel32 handle when DLL is being unloaded.
-
-Sun Dec  6 21:54:35 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* buildlib.bat: Fix args to CL when building the .DLL
-
-	* cleanup.c (ptw32_destructor_run_all): Fix TSD key management.
-	This is a tidy-up before TSD and Thread management is completely
-	replaced by John Bossom's code.
-
-	* tsd.c (pthread_key_create): Fix TSD key management.
-
-	* global.c (ptw32_key_virgin_next): Initialise.
-
-	* build.bat: New DOS script to compile and link a pthreads app
-	using Microsoft's CL compiler linker.
-	* buildlib.bat: New DOS script to compile all the object files
-	and create pthread.lib and pthread.dll using Microsoft's CL
-	compiler linker.
-
-1998-12-05  Anders Norlander  <anorland@hem2.passagen.se>
-
-	* implement.h (ptw32_try_enter_critical_section): New extern
-	* dll.c (ptw32_try_enter_critical_section): New pointer to
-	TryEnterCriticalSection if it exists; otherwise NULL.
-	* dll.c (PthreadsEntryPoint):
-	Initialize ptw32_try_enter_critical_section at startup
-	and release kernel32 handle when DLL is being unloaded.
-	* mutex.c (pthread_mutex_trylock): Replaced check for NT with
-	a check if ptw32_try_enter_critical_section is valid
-	pointer to a function. Call ptw32_try_enter_critical_section
-	instead of TryEnterCriticalSection to avoid errors on Win95.
-
-Thu Dec 3 13:32:00 1998  Ross Johnson  <rpj@ise.canberra.edu.au>
-
-	* README: Correct cygwin32 compatibility statement.
-
-Sun Nov 15 21:24:06 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* cleanup.c (ptw32_destructor_run_all): Declare missing void * arg.
-	Fixup CVS merge conflicts.
-
-1998-10-30  Ben Elliston  <bje@cygnus.com>
-
-	* condvar.c (cond_wait): Fix semantic error. Test for equality
-	instead of making an assignment.
-
-Fri Oct 30 15:15:50 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* cleanup.c (ptw32_handler_push): Fixed bug appending new
-	handler to list reported by Peter Slacik
-	<Peter.Slacik@leibinger.freinet.de>.
-	(new_thread): Rename poorly named local variable to
-	"new_handler".
-
-Sat Oct 24 18:34:59 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* global.c: Add TSD key management array and index declarations.
-
-	* implement.h: Ditto for externs.
-
-Fri Oct 23 00:08:09 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* implement.h (PTW32_TSD_KEY_REUSE): Add enum.
-
-	* private.c (ptw32_delete_thread): Add call to
-	ptw32_destructor_run_all() to clean up the threads keys.
-
-	* cleanup.c (ptw32_destructor_run_all): Check for no more dirty
-	keys to run destructors on. Assume that the destructor call always
-	succeeds and set the key value to NULL.
-
-Thu Oct 22 21:44:44 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* tsd.c (pthread_setspecific): Add key management code.
-	(pthread_key_create): Ditto.
-	(pthread_key_delete): Ditto.
-
-	* implement.h (struct ptw32_tsd_key): Add status member.
-
-	* tsd.c: Add description of pthread_key_delete() from the
-	standard as a comment.
-
-Fri Oct 16 17:38:47 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* cleanup.c (ptw32_destructor_run_all): Fix and improve
-	stepping through the key table.
-
-Thu Oct 15 14:05:01 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* private.c (ptw32_new_thread): Remove init of destructorstack.
-	No longer an element of pthread_t.
-
-	* tsd.c (pthread_setspecific): Fix type declaration and cast.
-	(pthread_getspecific): Ditto.
-	(pthread_getspecific): Change error return value to NULL if key
-	is not in use.
-
-Thu Oct 15 11:53:21 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* global.c (ptw32_tsd_key_table): Fix declaration.
-
-	* implement.h(ptw32_TSD_keys_TlsIndex): Add missing extern.
-	(ptw32_tsd_mutex): Ditto.
-
-	* create.c (ptw32_start_call): Fix "keys" array declaration.
-	Add comment.
-
-	* tsd.c (pthread_setspecific): Fix type declaration and cast.
-	(pthread_getspecific): Ditto.
-
-	* cleanup.c (ptw32_destructor_run_all): Declare missing loop
-	counter.
-
-Wed Oct 14 21:09:24 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_new_thread): Increment ptw32_threads_count.
-	(ptw32_delete_thread): Decrement ptw32_threads_count.
-	Remove some comments.
-
-	* exit.c (ptw32_exit): : Fix two pthread_mutex_lock() calls that
- 	should have been pthread_mutex_unlock() calls.
-	(ptw32_vacuum): Remove call to ptw32_destructor_pop_all().
-
-	* create.c (pthread_create): Fix two pthread_mutex_lock() calls that
- 	should have been pthread_mutex_unlock() calls.
-
-	* global.c (ptw32_tsd_mutex): Add mutex for TSD operations.
-
-	* tsd.c (pthread_key_create): Add critical section.
-	(pthread_setspecific): Ditto.
-	(pthread_getspecific): Ditto.
-	(pthread_key_delete): Ditto.
-
-	* sync.c (pthread_join): Fix two pthread_mutex_lock() calls that
- 	should have been pthread_mutex_unlock() calls.
-
-Mon Oct 12 00:00:44 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* implement.h (ptw32_tsd_key_table): New.
-
-	* create.c (ptw32_start_call): Initialise per-thread TSD keys
-	to NULL.
-
-	* misc.c (pthread_once): Correct typo in comment.
-
-	* implement.h (ptw32_destructor_push): Remove.
-	(ptw32_destructor_pop): Remove.
-	(ptw32_destructor_run_all): Rename from ptw32_destructor_pop_all.
-	(PTW32_TSD_KEY_DELETED): Add enum.
-	(PTW32_TSD_KEY_INUSE): Add enum.
-
-	* cleanup.c (ptw32_destructor_push): Remove.
-	(ptw32_destructor_pop): Remove.
-	(ptw32_destructor_run_all): Totally revamped TSD.
-
-	* dll.c (ptw32_TSD_keys_TlsIndex): Initialise.
-
-	* tsd.c (pthread_setspecific): Totally revamped TSD.
-	(pthread_getspecific): Ditto.
-	(pthread_create): Ditto.
-	(pthread_delete): Ditto.
-
-Sun Oct 11 22:44:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* global.c (ptw32_tsd_key_table): Add new global.
-
-	* implement.h (ptw32_tsd_key_t and struct ptw32_tsd_key):
-	Add.
-	(struct _pthread): Remove destructorstack.
-
-	* cleanup.c (ptw32_destructor_run_all): Rename from
- 	ptw32_destructor_pop_all. The key destructor stack was made
- 	global rather than per-thread. No longer removes destructor nodes
-	from the stack. Comments updated.
-
-1998-10-06  Ben Elliston  <bje@cygnus.com>
-
-	* condvar.c (cond_wait): Use POSIX, not Win32 mutex calls.
-	(pthread_cond_broadcast): Likewise.
-	(pthread_cond_signal): Likewise.
-
-1998-10-05  Ben Elliston  <bje@cygnus.com>
-
-	* pthread.def: Update. Some functions aren't available yet, others
-	are macros in <pthread.h>.
-
-	* tests/join.c: Remove; useless.
-
-Mon Oct  5 14:25:08 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* pthread.def: New file for building the DLL.
-
-1998-10-05  Ben Elliston  <bje@cygnus.com>
-
-	* misc.c (pthread_equal): Correct inverted logic bug.
-	(pthread_once): Use the POSIX mutex primitives, not Win32. Remove
-	irrelevant FIXME comment.
-
-	* global.c (PTHREAD_MUTEX_INITIALIZER): Move to pthread.h.
-
-	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Define.
-	(pthread_mutex_t): Reimplement as a struct containing a valid
-	flag. If the flag is ever down upon entry to a mutex operation,
-	we call pthread_mutex_create() to initialise the object. This
-	fixes the problem of how to handle statically initialised objects
-	that can't call InitializeCriticalSection() due to their context.
-	(PTHREAD_ONCE_INIT): Define.
-
-	* mutex.c (pthread_mutex_init): Set valid flag.
-	(pthread_mutex_destroy): Clear valid flag.
-	(pthread_mutex_lock): Check and handle the valid flag.
-	(pthread_mutex_unlock): Likewise.
-	(pthread_mutex_trylock): Likewise.
-
-	* tests/mutex3.c: New file; test for the static initialisation
-	macro. Passes.
-
-	* tests/create1.c: New file; test pthread_create(). Passes.
-	
-	* tests/equal.c: Poor test; remove.
-	
-	* tests/equal1.c New file; test pthread_equal(). Passes.
-
-	* tests/once1.c: New file; test for pthread_once(). Passes.
-
-	* tests/self.c: Remove; rename to self1.c.
-
-	* tests/self1.c: This is the old self.c.
-
-	* tests/self2.c: New file. Test pthread_self() with a single
-	thread. Passes.
-
-	* tests/self3.c: New file. Test pthread_self() with a couple of
-	threads to ensure their thread IDs differ. Passes.
-	
-1998-10-04  Ben Elliston  <bje@cygnus.com>
-
-	* tests/mutex2.c: Test pthread_mutex_trylock(). Passes.
-
-	* tests/mutex1.c: New basic test for mutex functions (it passes).
-	(main): Eliminate warning.
-
-	* configure.in: Test for __stdcall, not _stdcall. Typo.
-
-	* configure: Regenerate.
-
-	* attr.c (pthread_attr_setstackaddr): Remove FIXME comment. Win32
-	does know about ENOSYS after all.
-	(pthread_attr_setstackaddr): Likewise.
-
-1998-10-03  Ben Elliston  <bje@cygnus.com>
-
-	* configure.in: Test for the `_stdcall' keyword.  Define `STDCALL'
-	to `_stdcall' if we have it, null otherwise.
-
-	* configure: Regenerate.
-
-	* acconfig.h (STDCALL): New define.
-
-	* config.h.in: Regenerate.
-
-	* create.c (ptw32_start_call): Add STDCALL prefix.
-	
-	* mutex.c (pthread_mutex_init): Correct function signature.
-
-	* attr.c (pthread_attr_init): Only zero out the `sigmask' member
-	if we have the sigset_t type.
-
-	* pthread.h: No need to include <unistd.h>.  It doesn't even exist
-	on Win32! Again, an artifact of cross-compilation.	
-	(pthread_sigmask): Only provide if we have the sigset_t type.
-
-	* process.h: Remove. This was a stand-in before we started doing
-	native compilation under Win32.
-
-	* pthread.h (pthread_mutex_init): Make `attr' argument const.
-
-1998-10-02  Ben Elliston  <bje@cygnus.com>
-
-	* COPYING: Remove.
-
-	* COPYING.LIB: Add. This library is under the LGPL.
-
-1998-09-13  Ben Elliston  <bje@cygnus.com>
-
-	* configure.in: Test for required system features.
-
-	* configure: Generate. 
-
-	* acconfig.h: New file.
-
-	* config.h.in: Generate.
-
-	* Makefile.in: Renamed from Makefile.
-
-	* COPYING: Import from a recent GNU package.
-
-	* config.guess: Likewise.
-
-	* config.sub: Likewise.
-
-	* install-sh: Likewise.
-
-	* config.h: Remove.  
-
-	* Makefile: Likewise.
-
-1998-09-12  Ben Elliston  <bje@cygnus.com>
-
-	* windows.h: No longer needed; remove.
-
-	* windows.c: Likewise.
-
-Sat Sep 12 20:09:24 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* windows.h: Remove error number definitions. These are in <errno.h>
-	
-	* tsd.c: Add comment explaining rationale for not building
-	POSIX TSD on top of Win32 TLS.
-
-1998-09-12  Ben Elliston  <bje@cygnus.com>
-
-	* {most}.c: Include <errno.h> to get POSIX error values.
-
-	* signal.c (pthread_sigmask): Only provide if HAVE_SIGSET_T is
-	defined.
- 
-	* config.h: #undef features, don't #define them.  This will be
-	generated by autoconf very soon.
-	
-1998-08-11  Ben Elliston  <bje@cygnus.com>
-
-	* Makefile (LIB): Define.
-	(clean): Define target.
-	(all): Build a library not just the object files.
-
-	* pthread.h: Provide a definition for struct timespec if we don't
-	already have one.
-
-	* windows.c (TlsGetValue): Bug fix.
-	
-Thu Aug  6 15:19:22 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* misc.c (pthread_once): Fix arg 1 of EnterCriticalSection()
- 	and LeaveCriticalSection() calls to pass address-of lock.
-
-	* fork.c (pthread_atfork): Typecast (void (*)(void *)) funcptr
-	in each ptw32_handler_push() call.
-
-	* exit.c (ptw32_exit): Fix attr arg in 
-	pthread_attr_getdetachstate() call.
-
-	* private.c (ptw32_new_thread): Typecast (HANDLE) NULL.
-	(ptw32_delete_thread): Ditto.
-
-	* implement.h: (PTW32_MAX_THREADS): Add define. This keeps
-	changing in an attempt to make thread administration data types
-	opaque and cleanup DLL startup.
-
-	* dll.c (PthreadsEntryPoint): 
-	(ptw32_virgins): Remove malloc() and free() calls.
-	(ptw32_reuse): Ditto.
-	(ptw32_win32handle_map): Ditto.
-	(ptw32_threads_mutex_table): Ditto.
-
-	* global.c (_POSIX_THREAD_THREADS_MAX): Initialise with 
-	PTW32_MAX_THREADS.
-	(ptw32_virgins): Ditto.
-	(ptw32_reuse): Ditto.
-	(ptw32_win32handle_map): Ditto.
-	(ptw32_threads_mutex_table): Ditto.
-
-	* create.c (pthread_create): Typecast (HANDLE) NULL.
-	Typecast (unsigned (*)(void *)) start_routine.
-
-	* condvar.c (pthread_cond_init): Add address-of operator & to
-	arg 1 of pthread_mutex_init() call.
-	(pthread_cond_destroy): Add address-of operator & to
-	arg 1 of pthread_mutex_destroy() call. 
-
-	* cleanup.c (ptw32_destructor_pop_all): Add (int) cast to 
-	pthread_getspecific() arg.
-	(ptw32_destructor_pop): Add (void *) cast to "if" conditional.
-	(ptw32_destructor_push): Add (void *) cast to
-	ptw32_handler_push() "key" arg.
-	(malloc.h): Add include.
-
-	* implement.h (ptw32_destructor_pop): Add prototype.
-
-	* tsd.c (implement.h): Add include.
-
-	* sync.c (pthread_join): Remove target_thread_mutex and it's
-	initialisation. Rename getdetachedstate to getdetachstate.
-	Remove unused variable "exitcode".
-	(pthread_detach): Remove target_thread_mutex and it's
-	initialisation. Rename getdetachedstate to getdetachstate.
-	Rename setdetachedstate to setdetachstate.
-
-	* signal.c (pthread_sigmask): Rename SIG_SET to SIG_SETMASK.
-	Cast "set" to (long *) in assignment to passify compiler warning.
-	Add address-of operator & to thread->attr.sigmask in memcpy() call
-	and assignment.
-	(pthread_sigmask): Add address-of operator & to thread->attr.sigmask
-	in memcpy() call and assignment.
-
-	* windows.h (THREAD_PRIORITY_ERROR_RETURN): Add.
-	(THREAD_PRIORITY_LOWEST): Add.
-	(THREAD_PRIORITY_HIGHEST): Add.
-
-	* sched.c (is_attr): Add function.
-	(implement.h): Add include.
-	(pthread_setschedparam): Rename all instances of "sched_policy"
-	to "sched_priority".
-	(pthread_getschedparam): Ditto.
-
-Tue Aug  4 16:57:58 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* private.c (ptw32_delete_thread): Fix typo. Add missing ';'.
-
-	* global.c (ptw32_virgins): Change types from pointer to 
-	array pointer.
-	(ptw32_reuse): Ditto.
-	(ptw32_win32handle_map): Ditto.
-	(ptw32_threads_mutex_table): Ditto.
-
-	* implement.h(ptw32_virgins): Change types from pointer to 
-	array pointer.
-	(ptw32_reuse): Ditto.
-	(ptw32_win32handle_map): Ditto.
-	(ptw32_threads_mutex_table): Ditto.
-
-	* private.c (ptw32_delete_thread): Fix "entry" should be "thread".
-
-	* misc.c (pthread_self): Add extern for ptw32_threadID_TlsIndex.
-
-	* global.c: Add comment.
-
-	* misc.c (pthread_once): Fix member -> dereferences.
-	Change ptw32_once_flag to once_control->flag in "if" test.
-
-Tue Aug  4 00:09:30 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* implement.h(ptw32_virgins): Add extern.
-	(ptw32_virgin_next): Ditto.
-	(ptw32_reuse): Ditto.
-	(ptw32_reuse_top): Ditto.
-	(ptw32_win32handle_map): Ditto.
-	(ptw32_threads_mutex_table): Ditto.
-
-	* global.c (ptw32_virgins): Changed from array to pointer.
-	Storage allocation for the array moved into dll.c.
-	(ptw32_reuse): Ditto.
-	(ptw32_win32handle_map): Ditto.
-	(ptw32_threads_mutex_table): Ditto.
-
-	* dll.c (PthreadsEntryPoint): Set up thread admin storage when
-	DLL is loaded.
-
-	* fork.c (pthread_atfork): Fix function pointer arg to all
-	ptw32_handler_push() calls. Change "arg" arg to NULL in child push.
-
-	* exit.c: Add windows.h and process.h includes.
-	(ptw32_exit): Add local detachstate declaration.
-	(ptw32_exit): Fix incorrect name for pthread_attr_getdetachstate().
-
-	* pthread.h (_POSIX_THREAD_ATTR_STACKSIZE): Move from global.c
-	(_POSIX_THREAD_ATTR_STACKADDR): Ditto.
-
-	* create.c (pthread_create): Fix #if should be #ifdef.
-	(ptw32_start_call): Remove usused variables.
-
-	* process.h: Create.
-
-	* windows.h: Move _beginthreadex and _endthreadex into
-	process.h
-
-Mon Aug  3 21:19:57 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* condvar.c (pthread_cond_init): Add NULL attr to
-	pthread_mutex_init() call - default attributes will be used.
-	(cond_wait): Fix typo.
-	(cond_wait): Fix typo - cv was ev.
-	(pthread_cond_broadcast): Fix two identical typos.
-
-	* cleanup.c (ptw32_destructor_pop_all): Remove _ prefix from
-	PTHREAD_DESTRUCTOR_ITERATIONS.
-
-	* pthread.h: Move _POSIX_* values into posix.h
-
-	* pthread.h: Fix typo in pthread_mutex_init() prototype.
-
-	* attr.c (pthread_attr_init): Fix error in priority member init.
-
-	* windows.h (THREAD_PRIORITY_NORMAL): Add.
-
-	* pthread.h (sched_param): Add missing ';' to struct definition. 
-
-	* attr.c (pthread_attr_init): Remove obsolete pthread_attr_t
-	member initialisation - cancelstate, canceltype, cancel_pending.
-	(is_attr): Make arg "attr" a const.
-
-	* implement.h (PTW32_HANDLER_POP_LIFO): Remove definition.
-	(PTW32_HANDLER_POP_FIFO): Ditto.
-	(PTW32_VALID): Add missing newline escape (\).
-	(ptw32_handler_node): Make element "next" a pointer.
-
-1998-08-02  Ben Elliston  <bje@cygnus.com>
-
-	* windows.h: Remove duplicate TlsSetValue() prototype.  Add 
-	TlsGetValue() prototype.
-	(FALSE): Define.
-	(TRUE): Likewise.
-	Add forgotten errno values.  Guard against multiple #includes.
-
-	* windows.c: New file.  Implement stubs for Win32 functions.
-
-	* Makefile (SRCS): Remove.  Not explicitly needed.
-	(CFLAGS): Add -Wall for all warnings with GCC.
-
-Sun Aug  2 19:03:42 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* config.h: Create. This is a temporary stand-in for autoconf yet
-	to be done.
- 	(HAVE_SIGNAL_H): Add.
-
-	* pthread.h: Minor rearrangement for temporary config.h.
-
-Fri Jul 31 14:00:29 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* cleanup.c (ptw32_destructor_pop): Implement. Removes
-	destructors associated with a key without executing them.
-	(ptw32_destructor_pop_all): Add FIXME comment.
-
-	* tsd.c (pthread_key_delete): Add call to ptw32_destructor_pop().
-
-Fri Jul 31 00:05:45 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* tsd.c (pthread_key_create): Update to properly associate
-	the destructor routine with the key.
-	(pthread_key_delete): Add FIXME comment.
-
-	* exit.c (ptw32_vacuum): Add call to
-	ptw32_destructor_pop_all().
-
-	* implement.h (ptw32_handler_pop_all): Add prototype.
-	(ptw32_destructor_pop_all): Ditto.
-
-	* cleanup.c (ptw32_destructor_push): Implement. This is just a
-	call to ptw32_handler_push().
-	(ptw32_destructor_pop_all): Implement. This is significantly
-	different to ptw32_handler_pop_all().
-
-	* Makefile (SRCS): Create. Preliminary.
-
-	* windows.h: Create. Contains Win32 definitions for compile
-	testing. This is just a standin for the real one.
-
-	* pthread.h (SIG_UNBLOCK): Fix typo. Was SIG_BLOCK.
-	(windows.h): Add include. Required for CRITICAL_SECTION.
-	(pthread_cond_t): Move enum declaration outside of struct
-	definition.
-	(unistd.h): Add include - may be temporary.
-
-	* condvar.c (windows.h): Add include.
-
-	* implement.h (PTW32_THIS): Remove - no longer required.
-	(PTW32_STACK): Use pthread_self() instead of PTW32_THIS.
-
-Thu Jul 30 23:12:45 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* implement.h: Remove ptw32_find_entry() prototype.
-
-	* private.c: Extend comments.
-	Remove ptw32_find_entry() - no longer needed.
-
-	* create.c (ptw32_start_call): Add call to TlsSetValue() to
-	store the thread ID.
-
-	* dll.c (PthreadsEntryPoint): Implement. This is called
-	whenever a process loads the DLL. Used to initialise thread
-	local storage.
-
-	* implement.h: Add ptw32_threadID_TlsIndex.
-	Add ()s around PTW32_VALID expression.
-
-	* misc.c (pthread_self): Re-implement using Win32 TLS to store
-	the threads own ID.
-
-Wed Jul 29 11:39:03 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* private.c: Corrections in comments.
-	(ptw32_new_thread): Alter "if" flow to be more natural.
-
-	* cleanup.c (ptw32_handler_push): Same as below.
-
-	* create.c (pthread_create): Same as below.
-
-	* private.c (ptw32_new_thread): Rename "new" to "new_thread".
-	Since when has a C programmer been required to know C++?
-
-Tue Jul 28 14:04:29 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* implement.h: Add PTW32_VALID macro.
-
-	* sync.c (pthread_join): Modify to use the new thread
-	type and ptw32_delete_thread(). Rename "target" to "thread".
-	Remove extra local variable "target".
-	(pthread_detach): Ditto.
-
-	* signal.c (pthread_sigmask): Move init of "us" out of inner block.
-	Fix instance of "this" should have been "us". Rename "us" to "thread".
-
-	* sched.c (pthread_setschedparam): Modify to use the new thread
-	type.
-	(pthread_getschedparam): Ditto.
-
-	* private.c (ptw32_find_thread): Fix return type and arg.
-
-	* implement.h: Remove PTW32_YES and PTW32_NO.
-	(ptw32_new_thread): Add prototype.
-	(ptw32_find_thread): Ditto.
-	(ptw32_delete_thread): Ditto.
-	(ptw32_new_thread_entry): Remove prototype.
-	(ptw32_find_thread_entry): Ditto.
-	(ptw32_delete_thread_entry): Ditto.
-	(  PTW32_NEW, PTW32_INUSE, PTW32_EXITED, PTW32_REUSE):
-	Add.
-
-
-	* create.c (pthread_create): Minor rename "us" to "new" (I need
-	these cues but it doesn't stop me coming out with some major bugs
-	at times).
-	Load start_routine and arg into the thread so the wrapper can
-	call it.
-
-	* exit.c (pthread_exit): Fix pthread_this should be pthread_self.
-
-	* cancel.c (pthread_setcancelstate): Change
- 	ptw32_threads_thread_t * to pthread_t and init with
- 	pthread_this().
-	(pthread_setcanceltype): Ditto.
-
-	* exit.c (ptw32_exit): Add new pthread_t arg.
-	Rename ptw32_delete_thread_entry to ptw32_delete_thread.
-	Rename "us" to "thread".
-	(pthread_exit): Call ptw32_exit with added thread arg.
-
-	* create.c (ptw32_start_call): Insert missing ")".
-	Add "us" arg to ptw32_exit() call.
-	(pthread_create): Modify to use new thread allocation scheme.
-
-	* private.c: Added detailed explanation of the new thread
-	allocation scheme.
-	(ptw32_new_thread): Totally rewritten to use
-	new thread allocation scheme.
-	(ptw32_delete_thread): Ditto.
-	(ptw32_find_thread): Obsolete.
-
-Mon Jul 27 17:46:37 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* create.c (pthread_create): Start of rewrite. Not completed yet.
-
-	* private.c (ptw32_new_thread_entry): Start of rewrite. Not
-	complete.
-
-	* implement.h (ptw32_threads_thread): Rename, remove thread
-	member, add win32handle and ptstatus members.
-	(ptw32_t): Add.
-
-	* pthread.h: pthread_t is no longer mapped directly to a Win32
-	HANDLE type. This is so we can let the Win32 thread terminate and
-	reuse the HANDLE while pthreads holds it's own thread ID until
-	the last waiting join exits.
-
-Mon Jul 27 00:20:37 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_delete_thread_entry): Destroy the thread
- 	entry attribute object before deleting the thread entry itself.
-
-	* attr.c (pthread_attr_init): Initialise cancel_pending = FALSE.
-	(pthread_attr_setdetachstate): Rename "detached" to "detachedstate".
-	(pthread_attr_getdetachstate): Ditto.
-
-	* exit.c (ptw32_exit): Fix incorrect check for detachedstate.
-
-	* implement.h (ptw32_call_t): Remove env member. 
-
-Sun Jul 26 13:06:12 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* implement.h (ptw32_new_thread_entry): Fix prototype.
-	(ptw32_find_thread_entry): Ditto.
-	(ptw32_delete_thread_entry): Ditto.
-	(ptw32_exit): Add prototype.
-
-	* exit.c (ptw32_exit): New function. Called from pthread_exit()
-	and ptw32_start_call() to exit the thread. It allows an extra
-	argument which is the return code passed to _endthreadex().
-	(ptw32_exit): Move thread entry delete call from ptw32_vacuum()
-	into here. Add more explanation of thread entry deletion.
-	(ptw32_exit): Clarify comment.
-
-	* create.c (ptw32_start_call): Change pthread_exit() call to
-	ptw32_exit() call.
-
-	* exit.c (ptw32_vacuum): Add thread entry deletion code
-	moved from ptw32_start_call(). See next item.
-	(pthread_exit): Remove longjmp(). Add mutex lock around thread table
-	manipulation code. This routine now calls _enthreadex().
-
-	* create.c (ptw32_start_call): Remove setjmp() call and move
-	cleanup code out. Call pthread_exit(NULL) to terminate the thread.
-
-1998-07-26  Ben Elliston  <bje@cygnus.com>
-
-	* tsd.c (pthread_getspecific): Update comments.
-
-	* mutex.c (pthread_mutexattr_setpshared): Not supported; remove.
-	(pthread_mutexattr_getpshared): Likewise.
-
-	* pthread.h (pthread_mutexattr_setpshared): Remove prototype.
-	(pthread_mutexattr_getpshared): Likewise.
-
-Sun Jul 26 00:09:59 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* sync.c: Rename all instances of ptw32_count_mutex to
-	ptw32_table_mutex.
-
-	* implement.h: Rename ptw32_count_mutex to
-	ptw32_table_mutex.
-
-	* global.c: Rename ptw32_count_mutex to
-	ptw32_table_mutex.
-
-	* create.c (pthread_create): Add critical sections.
-	(ptw32_start_call): Rename ptw32_count_mutex to
-	ptw32_table_mutex.
-
-	* cancel.c (pthread_setcancelstate): Fix indirection bug and rename
-	"this" to "us".
-
-	* signal.c (pthread_sigmask): Rename "this" to "us" and fix some
-	minor syntax errors. Declare "us" and initialise it.
-
-	* sync.c (pthread_detach): Rename "this" to "target".
-
-	* pthread.h: Converting PTHREAD_* defines to alias the (const int)
-	values in global.c.
-
-	* global.c: Started converting PTHREAD_* defines to (const int) as
- 	a part of making the eventual pthreads DLL binary compatible
- 	through version changes.
-
-	* condvar.c (cond_wait): Add cancelation point. This applies the
-	point to both pthread_cond_wait() and pthread_cond_timedwait().
-
-	* exit.c (pthread_exit): Rename "this" to "us".
-
-	* implement.h: Add comment.
-
-	* sync.c (pthread_join): I've satisfied myself that pthread_detach()
-	does set the detached attribute in the thread entry attributes
-	to PTHREAD_CREATE_DETACHED. "if" conditions were changed to test
-	that attribute instead of a separate flag.
-
-	* create.c (pthread_create): Rename "this" to "us".
-	(pthread_create): cancelstate and canceltype are not attributes
-	so the copy to thread entry attribute storage was removed.
-	Only the thread itself can change it's cancelstate or canceltype,
-	ie. the thread must exist already.
-
-	* private.c (ptw32_delete_thread_entry): Mutex locks removed.
-	Mutexes must be applied at the caller level.
-	(ptw32_new_thread_entry): Ditto.
-	(ptw32_new_thread_entry): Init cancelstate, canceltype, and
-	cancel_pending to default values.
-	(ptw32_new_thread_entry): Rename "this" to "new".
-	(ptw32_find_thread_entry): Rename "this" to "entry".
-	(ptw32_delete_thread_entry): Rename "thread_entry" to "entry".
-
-	* create.c (ptw32_start_call): Mutexes changed to
-	ptw32_count_mutex. All access to the threads table entries is
-	under the one mutex. Otherwise chaos reigns.
-
-Sat Jul 25 23:16:51 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* implement.h (ptw32_threads_thread): Move cancelstate and
- 	canceltype members out of pthread_attr_t into here.
-
-	* fork.c (fork): Add comment.
-
-1998-07-25  Ben Elliston  <bje@cygnus.com>
-
-	* fork.c (fork): Autoconfiscate.
-
-Sat Jul 25 00:00:13 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* create.c (ptw32_start_call): Set thread priority.  Ensure our
- 	thread entry is removed from the thread table but only if
- 	pthread_detach() was called and there are no waiting joins.
-	(pthread_create): Set detach flag in thread entry if the 
-	thread is created PTHREAD_CREATE_DETACHED.
-
-	* pthread.h (pthread_attr_t): Rename member "detachedstate".
-
-	* attr.c (pthread_attr_init): Rename attr members.
-
-	* exit.c (pthread_exit): Fix indirection mistake.
-
-	* implement.h (PTW32_THREADS_TABLE_INDEX): Add.
-
-	* exit.c (ptw32_vacuum): Fix incorrect args to
-	ptw32_handler_pop_all() calls.
-	Make thread entry removal conditional.
-
-	* sync.c (pthread_join): Add multiple join and async detach handling.
-
-	* implement.h (PTW32_THREADS_TABLE_INDEX): Add.
-
-	* global.c (ptw32_threads_mutex_table): Add.
-
-	* implement.h (ptw32_once_flag): Remove.
-	(ptw32_once_lock): Ditto.
-	(ptw32_threads_mutex_table): Add.
-
-	* global.c (ptw32_once_flag): Remove.
-	(ptw32_once_lock): Ditto.
-
-	* sync.c (pthread_join): Fix tests involving new return value
-	from ptw32_find_thread_entry().
-	(pthread_detach): Ditto.
-
-	* private.c (ptw32_find_thread_entry): Failure return code
-	changed from -1 to NULL.
-
-Fri Jul 24 23:09:33 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* create.c (pthread_create): Change . to -> in sigmask memcpy() args.
-
-	* pthread.h: (pthread_cancel): Add function prototype.
-	(pthread_testcancel): Ditto.
-
-1998-07-24  Ben Elliston  <bje@cygnus.com>
-
-	* pthread.h (pthread_condattr_t): Rename dummy structure member.
-	(pthread_mutexattr_t): Likewise.
-
-Fri Jul 24 21:13:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* cancel.c (pthread_cancel): Implement.
-	(pthread_testcancel): Implement.
-
-	* exit.c (pthread_exit): Add comment explaining the longjmp().
-
-	* implement.h (ptw32_threads_thread_t): New member cancelthread.
-	(PTW32_YES): Define.
-	(PTW32_NO): Define.
-	(RND_SIZEOF): Remove.
-
-	* create.c (pthread_create): Rename cancelability to cancelstate.
-
-	* pthread.h (pthread_attr_t): Rename cancelability to cancelstate.
-	(PTHREAD_CANCELED): Define.
-
-1998-07-24  Ben Elliston  <bje@cygnus.com>
-
-	* pthread.h (SIG_BLOCK): Define if not already defined.
-	(SIG_UNBLOCK): Likewise.
-	(SIG_SETMASK): Likewise.
-	(pthread_attr_t): Add signal mask member.
-	(pthread_sigmask): Add function prototype.
-
-	* signal.c (pthread_sigmask): Implement.
-
-	* create.c: #include <string.h> to get a prototype for memcpy().
-	(pthread_create): New threads inherit their creator's signal
-	mask.  Copy the signal mask to the new thread structure if we know
-	about signals.
-	
-Fri Jul 24 16:33:17 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* fork.c (pthread_atfork): Add all the necessary push calls.
-	Local implementation semantics:
-	If we get an ENOMEM at any time then ALL handlers
-	(including those from previous pthread_atfork() calls) will be
-	popped off each of the three atfork stacks before we return.
-	(fork): Add all the necessary pop calls. Add the thread cancellation
-	and join calls to the child fork.
-	Add #includes.
-
-	* implement.h: (ptw32_handler_push): Fix return type and stack arg
-	type in prototype.
-	(ptw32_handler_pop): Fix stack arg type in prototype.
-	(ptw32_handler_pop_all): Fix stack arg type in prototype.
-
-	* cleanup.c (ptw32_handler_push): Change return type to int and
-	return ENOMEM if malloc() fails.
-
-	* sync.c (pthread_detach): Use equality test, not assignment.
-
-	* create.c (ptw32_start_call): Add call to Win32 CloseHandle()
-	if thread is detached.
-
-1998-07-24  Ben Elliston  <bje@cygnus.com>
-
-	* sync.c (pthread_detach): Close the Win32 thread handle to
-	emulate detached (or daemon) threads.
-
-Fri Jul 24 03:00:25 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* sync.c (pthread_join): Save valueptr arg in joinvalueptr for
-	pthread_exit() to use.
-
-	* private.c (ptw32_new_thread_entry): Initialise joinvalueptr to
-	NULL.
-
-	* create.c (ptw32_start_call): Rewrite to facilitate joins.
-	pthread_exit() will do a longjmp() back to here. Does appropriate
-	cleanup and exit/return from the thread.
-	(pthread_create): _beginthreadex() now passes a pointer to our
-	thread table entry instead of just the call member of that entry.
-
-	* implement.h (ptw32_threads_thread): New member 
-	void ** joinvalueptr.
-	(ptw32_call_t): New member jmpbuf env.
-
-	* exit.c (pthread_exit): Major rewrite to handle joins and handing
-	value pointer to joining thread. Uses longjmp() back to 
-	ptw32_start_call().
-
-	* create.c (pthread_create): Ensure values of new attribute members
-	are copied to the thread attribute object.
-
-	* attr.c (pthread_attr_destroy):  Fix merge conflicts.
-	(pthread_attr_getdetachstate):  Fix merge conflicts.
-	(pthread_attr_setdetachstate):  Fix merge conflicts.
-
-	* pthread.h:  Fix merge conflicts.
-
-	* sync.c (pthread_join): Fix merge conflicts.
-
-Fri Jul 24 00:21:21 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* sync.c (pthread_join): Add check for valid and joinable
-	thread.
-	(pthread_detach): Implement. After checking for a valid and joinable
-	thread, it's still a no-op.
-
-	* private.c (ptw32_find_thread_entry): Bug prevented returning
-	an error value in some cases.
-
-	* attr.c (pthread_attr_setdetachedstate): Implement.
-	(pthread_attr_getdetachedstate): Implement.
-
-	* implement.h: Move more hidden definitions into here from
-	pthread.h.
-
-1998-07-24  Ben Elliston  <bje@cygnus.com>
-
-	* pthread.h (PTHREAD_CREATE_JOINABLE): Define.
-	(PTHREAD_CREATE_DETACHED): Likewise.
-	(pthread_attr_t): Add new structure member `detached'.
-	(pthread_attr_getdetachstate): Add function prototype.
-	(pthread_attr_setdetachstate): Likewise.
-
-	* sync.c (pthread_join): Return if the target thread is detached.
-
-	* attr.c (pthread_attr_init): Initialise cancelability and
-	canceltype structure members.
-	(pthread_attr_getdetachstate): Implement.
-	(pthread_attr_setdetachstate): Likewise.
-
-	* implement.h (PTW32_CANCEL_DEFAULTS): Remove.  Bit fields
-	proved to be too cumbersome.  Set the defaults in attr.c using the
-	public PTHREAD_CANCEL_* constants.
-
-	* cancel.c: New file.
-
-	* pthread.h (sched_param): Define this type.
-	(pthread_attr_getschedparam): Add function prototype.
-	(pthread_attr_setschedparam): Likewise.
-	(pthread_setcancelstate): Likewise.
-	(pthread_setcanceltype): Likewise.
-	(sched_get_priority_min): Likewise.
-	(sched_get_priority_max): Likewise.
-	(pthread_mutexattr_setprotocol): Remove; not supported.
-	(pthread_mutexattr_getprotocol): Likewise.
-	(pthread_mutexattr_setprioceiling): Likewise.
-	(pthread_mutexattr_getprioceiling): Likewise.
-	(pthread_attr_t): Add canceltype member.  Update comments.
-	(SCHED_OTHER): Define this scheduling policy constant.
-	(SCHED_FIFO): Likewise.
-	(SCHED_RR): Likewise.
-	(SCHED_MIN): Define the lowest possible value for this constant.
-	(SCHED_MAX): Likewise, the maximum possible value.
-	(PTHREAD_CANCEL_ASYNCHRONOUS): Redefine.
-	(PTHREAD_CANCEL_DEFERRED): Likewise.
-	
-	* sched.c: New file.
-	(pthread_setschedparam): Implement.
-	(pthread_getschedparam): Implement.
-	(sched_get_priority_max): Validate policy argument.
-	(sched_get_priority_min): Likewise.
-
-	* mutex.c (pthread_mutexattr_setprotocol): Remove; not supported.
-	(pthread_mutexattr_getprotocol): Likewise.
-	(pthread_mutexattr_setprioceiling): Likewise.
-	(pthread_mutexattr_getprioceiling): Likewise.
-
-Fri Jul 24 00:21:21 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* create.c (pthread_create): Arg to ptw32_new_thread_entry()
-	changed. See next entry. Move mutex locks out. Changes made yesterday
-	and today allow us to start the new thread running rather than
-	temporarily suspended.
-
-	* private.c (ptw32_new_thread_entry): ptw32_thread_table
-	was changed back to a table of thread structures rather than pointers.
-	As such we're trading storage for increaded speed. This routine
-	was modified to work with the new table. Mutex lock put in around
-	global data accesses.
-	(ptw32_find_thread_entry): Ditto
-	(ptw32_delete_thread_entry): Ditto
-
-Thu Jul 23 23:25:30 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* global.c: New. Global data objects declared here. These moved from
-	pthread.h.
-
-	* pthread.h: Move implementation hidden definitions into
-	implement.h.
-
-	* implement.h: Move implementation hidden definitions from
-	pthread.h. Add constants to index into the different handler stacks.
-
-	* cleanup.c (ptw32_handler_push): Simplify args. Restructure.
-	(ptw32_handler_pop): Simplify args. Restructure.
-	(ptw32_handler_pop_all): Simplify args. Restructure.
-
-Wed Jul 22 00:16:22 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* attr.c, implement.h, pthread.h, ChangeLog: Resolve CVS merge
-	conflicts.
-
-	* private.c (ptw32_find_thread_entry): Changes to return type
-	to support leaner ptw32_threads_table[] which now only stores
-	ptw32_thread_thread_t *.
-	(ptw32_new_thread_entry): Internal changes.
-	(ptw32_delete_thread_entry): Internal changes to avoid contention.
- 	Calling routines changed accordingly.
-
-	* pthread.h: Modified cleanup macros to use new generic push and pop.
-	Added destructor and atfork stacks to ptw32_threads_thread_t.
-
-	* cleanup.c (ptw32_handler_push, ptw32_handler_pop,
-	ptw32_handler_pop_all): Renamed cleanup push and pop routines
-	and made generic to handle destructors and atfork handlers as
-	well.
-
-	* create.c (ptw32_start_call): New function is a wrapper for
-	all new threads. It allows us to do some cleanup when the thread
-	returns, ie. that is otherwise only done if the thread is cancelled.
-
-	* exit.c (ptw32_vacuum): New function contains code from 
-	pthread_exit() that we need in the new ptw32_start_call()
-	as well.
-
-	* implement.h: Various additions and minor changes.
-
-	* pthread.h: Various additions and minor changes.
-	Change cleanup handler macros to use generic handler push and pop
-	functions.
-
-	* attr.c: Minor mods to all functions.
-	(is_attr): Implemented missing function.
-
-	* create.c (pthread_create): More clean up.
-
-	* private.c (ptw32_find_thread_entry): Implement.
-	(ptw32_delete_thread_entry): Implement.
-	(ptw32_new_thread_entry): Implement.
-	These functions manipulate the implementations internal thread
-	table and are part of general code cleanup and modularisation.
-	They replace ptw32_getthreadindex() which was removed.
-
-	* exit.c (pthread_exit): Changed to use the new code above.
-
-	* pthread.h: Add cancelability constants. Update comments.
-
-1998-07-22  Ben Elliston  <bje@cygnus.com>
-
-	* attr.c (pthread_setstacksize): Update test of attr argument.
-	(pthread_getstacksize): Likewise.
-	(pthread_setstackaddr): Likewise.
-	(pthread_getstackaddr): Likewise.
-	(pthread_attr_init): No need to allocate any storage.
-	(pthread_attr_destroy): No need to free any storage.
-
-	* mutex.c (is_attr): Not likely to be needed; remove.
-	(remove_attr): Likewise.
-	(insert_attr): Likewise.
-
-	* implement.h (ptw32_mutexattr_t): Moved to a public definition
-	in pthread.h.  There was little gain in hiding these details.
-	(ptw32_condattr_t): Likewise.
-	(ptw32_attr_t): Likewise.
-
-	* pthread.h (pthread_atfork): Add function prototype.
-	(pthread_attr_t): Moved here from implement.h.
-
-	* fork.c (pthread_atfork): Preliminary implementation.
-	(ptw32_fork): Likewise.
-
-Wed Jul 22 00:16:22 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* cleanup.c (ptw32_cleanup_push): Implement.
-	(ptw32_cleanup_pop): Implement.
-	(ptw32_do_cancellation): Implement.
-	These are private to the implementation. The real cleanup functions
-	are macros. See below.
-
-	* pthread.h (pthread_cleanup_push): Implement as a macro.
-	(pthread_cleanup_pop): Implement as a macro.
-	Because these are macros which start and end a block, the POSIX scoping
-	requirement is observed. See the comment in the file.
-
-	* exit.c (pthread_exit): Refine the code.
-
-	* create.c (pthread_create): Code cleanup.
-
-	* implement.h (RND_SIZEOF): Add RND_SIZEOF(T) to round sizeof(T)
-	up to multiple of DWORD.
-	Add function prototypes.
-
-	* private.c (ptw32_getthreadindex): "*thread" should have been 
-	"thread". Detect empty slot fail condition.
-
-1998-07-20  Ben Elliston  <bje@cygnus.com>
-
-	* misc.c (pthread_once): Implement.  Don't use a per-application
-	flag and mutex--make `pthread_once_t' contain these elements in
-	their structure.  The earlier version had incorrect semantics.
-	
-	* pthread.h (ptw32_once_flag): Add new variable.  Remove.
-	(ptw32_once_lock): Add new mutex lock to ensure integrity of
-	access to ptw32_once_flag.  Remove.
-	(pthread_once): Add function prototype.
-	(pthread_once_t): Define this type.
-	
-Mon Jul 20 02:31:05 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* private.c (ptw32_getthreadindex): Implement.
-
-	* pthread.h: Add application static data dependent on
-	_PTHREADS_BUILD_DLL define. This is needed to avoid allocating
-	non-sharable static data within the pthread DLL.
-
-	* implement.h: Add ptw32_cleanup_stack_t, ptw32_cleanup_node_t
-	and PTW32_HASH_INDEX.
-
-	* exit.c (pthread_exit): Begin work on cleanup and de-allocate
-	thread-private storage.
-
-	* create.c (pthread_create): Add thread to thread table.
-	Keep a thread-private copy of the attributes with default values
-	filled in when necessary. Same for the cleanup stack. Make 
-	pthread_create C run-time library friendly by using _beginthreadex()
-	instead of CreateThread(). Fix error returns.
-
-Sun Jul 19 16:26:23 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* implement.h: Rename pthreads_thread_count to ptw32_threads_count.
-	Create ptw32_threads_thread_t struct to keep thread specific data.
-
-	* create.c: Rename pthreads_thread_count to ptw32_threads_count.
-	(pthread_create): Handle errors from CreateThread().
-
-1998-07-19  Ben Elliston  <bje@cygnus.com>
-
-	* condvar.c (pthread_cond_wait): Generalise.  Moved from here ..
-	(cond_wait): To here.
-	(pthread_cond_timedwait): Implement; use generalised cond_wait().
-
-	* pthread.h (pthread_key_t): Define this type.
-	(pthread_key_create): Add function prototype.
-	(pthread_setspecific): Likewise.
-	(pthread_getspecific): Likwise.
-	(pthread_key_delete): Likewise.
-
-	* tsd.c (pthread_key_create): Implement.
-	(pthread_setspecific): Likewise.
-	(pthread_getspecific): Likewise.
-	(pthread_key_delete): Likewise.
-
-	* mutex.c (pthread_mutex_trylock): Return ENOSYS if this function
-	is called on a Win32 platform which is not Windows NT.
-
-1998-07-18  Ben Elliston  <bje@cygnus.com>
-
-	* condvar.c (pthread_condattr_init): Do not attempt to malloc any
-	storage; none is needed now that condattr_t is an empty struct.
-	(pthread_condattr_destory): Likewise; do not free storage.
-	(pthread_condattr_setpshared): No longer supported; return ENOSYS.
-	(pthread_condattr_getpshared): Likewise.
-	(pthread_cond_init): Implement with help from Douglas Schmidt.
-	Remember to initialise the cv's internal mutex.
-	(pthread_cond_wait): Likewise.
-	(pthread_cond_signal): Likewise.
-	(pthread_cond_broadcast): Likewise.
-	(pthread_cond_timedwait): Preliminary implementation, but I need
-	to see some API documentation for `WaitForMultipleObject'.
-	(pthread_destory): Implement.
-
-	* pthread.h (pthread_cond_init): Add function protoype.
-	(pthread_cond_broadcast): Likewise.
-	(pthread_cond_signal): Likewise.
-	(pthread_cond_timedwait): Likewise.
-	(pthread_cond_wait): Likewise.
-	(pthread_cond_destroy): Likewise.
-	(pthread_cond_t): Define this type.  Fix for u_int.  Do not assume
-	that the mutex contained withing the pthread_cond_t structure will
-	be a critical section.  Use our new POSIX type!
-
-	* implement.h (ptw32_condattr_t): Remove shared attribute.
-
-1998-07-17  Ben Elliston  <bje@cygnus.com>
-
-	* pthread.h (PTHREADS_PROCESS_PRIVATE): Remove.
-	(PTHREAD_PROCESS_SHARED): Likewise.  No support for mutexes shared
-	across processes for now.
-	(pthread_mutex_t): Use a Win32 CRITICAL_SECTION type for better
-	performance.
-	
-	* implement.h (ptw32_mutexattr_t): Remove shared attribute.
-	
-	* mutex.c (pthread_mutexattr_setpshared): This optional function
-	is no longer supported, since we want to implement POSIX mutex
-	variables using the much more efficient Win32 critical section
-	primitives.  Critical section objects in Win32 cannot be shared
-	between processes.
-	(pthread_mutexattr_getpshared): Likewise.
-	(pthread_mutexattr_init): No need to malloc any storage; the
-	attributes structure is now empty.
-	(pthread_mutexattr_destroy): This is now a nop.
-	(pthread_mutex_init): Use InitializeCriticalSection().
-	(pthread_mutex_destroy): Use DeleteCriticalSection().
-	(pthread_mutex_lock): Use EnterCriticalSection().
-	(pthread_mutex_trylock): Use TryEnterCriticalSection().  This is
-	not supported by Windows 9x, but trylock is a hack anyway, IMHO.
-	(pthread_mutex_unlock): Use LeaveCriticalSection().
-
-1998-07-14  Ben Elliston  <bje@cygnus.com>
-
-	* attr.c (pthread_attr_setstacksize): Implement.
-	(pthread_attr_getstacksize): Likewise.
-	(pthread_attr_setstackaddr): Likewise.
-	(pthread_attr_getstackaddr): Likewise.
-	(pthread_attr_init): Likewise.
-	(pthread_attr_destroy): Likewise.
-	
-	* condvar.c (pthread_condattr_init): Add `_cond' to function name.
-
-	* mutex.c (pthread_mutex_lock): Add `_mutex' to function name.
-	(pthread_mutex_trylock): Likewise.
-	(pthread_mutex_unlock): Likewise.
-
-	* pthread.h (pthread_condattr_setpshared): Fix typo.
-	(pthread_attr_init): Add function prototype.
-	(pthread_attr_destroy): Likewise.
-	(pthread_attr_setstacksize): Likewise.
-	(pthread_attr_getstacksize): Likewise.
-	(pthread_attr_setstackaddr): Likewise.
-	(pthread_attr_getstackaddr): Likewise.
-	
-Mon Jul 13 01:09:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* implement.h: Wrap in #ifndef _IMPLEMENT_H
-
-	* create.c (pthread_create): Map stacksize attr to Win32.
-
-	* mutex.c: Include implement.h
-
-1998-07-13  Ben Elliston  <bje@cygnus.com>
-
-	* condvar.c (pthread_condattr_init): Implement.
-	(pthread_condattr_destroy): Likewise.
-	(pthread_condattr_setpshared): Likewise.
-	(pthread_condattr_getpshared): Likewise.
-	
-	* implement.h (PTHREAD_THREADS_MAX): Remove trailing semicolon.
-	(PTHREAD_STACK_MIN): Specify; needs confirming.
-	(ptw32_attr_t): Define this type.
-	(ptw32_condattr_t): Likewise.
-
-	* pthread.h (pthread_mutex_t): Define this type.
-	(pthread_condattr_t): Likewise.
-	(pthread_mutex_destroy): Add function prototype.
-	(pthread_lock): Likewise.
-	(pthread_trylock): Likewise.
-	(pthread_unlock): Likewise.
-	(pthread_condattr_init): Likewise.
-	(pthread_condattr_destroy): Likewise.
-	(pthread_condattr_setpshared): Likewise.
-	(pthread_condattr_getpshared): Likewise.
-
-	* mutex.c (pthread_mutex_init): Implement.
-	(pthread_mutex_destroy): Likewise.
-	(pthread_lock): Likewise.
-	(pthread_trylock): Likewise.
-	(pthread_unlock): Likewise.
-
-1998-07-12  Ben Elliston  <bje@cygnus.com>
-
-	* implement.h (ptw32_mutexattr_t): Define this implementation
-	internal type.  Application programmers only see a mutex attribute
-	object as a void pointer.
-
-	* pthread.h (pthread_mutexattr_t): Define this type.
-	(pthread_mutexattr_init): Add function prototype.
-	(pthread_mutexattr_destroy): Likewise.
-	(pthread_mutexattr_setpshared): Likewise.
-	(pthread_mutexattr_getpshared): Likewise.
-	(pthread_mutexattr_setprotocol): Likewise.
-	(pthread_mutexattr_getprotocol): Likewise.
-	(pthread_mutexattr_setprioceiling): Likewise.
-	(pthread_mutexattr_getprioceiling): Likewise.
-	(PTHREAD_PROCESS_PRIVATE): Define.
-	(PTHREAD_PROCESS_SHARED): Define.
-
-	* mutex.c (pthread_mutexattr_init): Implement.
-	(pthread_mutexattr_destroy): Implement.
-	(pthread_mutexattr_setprotocol): Implement.
-	(pthread_mutexattr_getprotocol): Likewise.
-	(pthread_mutexattr_setprioceiling): Likewise.
-	(pthread_mutexattr_getprioceiling): Likewise.
-	(pthread_mutexattr_setpshared): Likewise.
-	(pthread_mutexattr_getpshared): Likewise.
-	(insert_attr): New function; very preliminary implementation!
-	(is_attr): Likewise.
-	(remove_attr): Likewise.
-	
-Sat Jul 11 14:48:54 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* implement.h: Preliminary implementation specific defines.
-
-	* create.c (pthread_create): Preliminary implementation.
-
-1998-07-11  Ben Elliston  <bje@cygnus.com>
-
-	* sync.c (pthread_join): Implement.
-
-	* misc.c (pthread_equal): Likewise.
-	
-	* pthread.h (pthread_join): Add function prototype.
-	(pthread_equal): Likewise.
-	
-1998-07-10  Ben Elliston  <bje@cygnus.com>
-
-	* misc.c (pthread_self): Implement.
-
-	* exit.c (pthread_exit): Implement.
-
-	* pthread.h (pthread_exit): Add function prototype.
-	(pthread_self): Likewise.
-	(pthread_t): Define this type.
-
-1998-07-09  Ben Elliston  <bje@cygnus.com>
-
-	* create.c (pthread_create): A dummy stub right now.
-
-	* pthread.h (pthread_create): Add function prototype.
+2001-06-25  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	* create.c (pthread_create): Add priority inheritance
+	attributes.
+	* mutex.c (pthread_mutex_lock): Remove some overhead for
+	PTHREAD_MUTEX_NORMAL mutex types. Specifically, avoid
+	calling pthread_self() and pthread_equal() to check/set
+	the mutex owner. Introduce a new pseudo owner for this
+	type. Test results suggest increases in speed of up to
+	90% for non-blocking locks.
+	This is the default type of mutex used internally by other
+	synchronising objects, ie. condition variables and
+	read-write locks. The test rwlock7.c shows about a
+	30-35% speed increase over snapshot 2001-06-06. The
+	price of this is that the application developer
+	must ensure correct behaviour, or explicitly set the
+	mutex to a safer type such as PTHREAD_MUTEX_ERRORCHECK.
+	For example, PTHREAD_MUTEX_NORMAL (or PTHREAD_MUTEX_DEFAULT)
+	type mutexes will not return an error if a thread which is not
+	the owner calls pthread_mutex_unlock. The call will succeed
+	in unlocking the mutex if it is currently locked, but a
+	subsequent unlock by the true owner will then fail with EPERM.
+	This is however consistent with some other implementations.
+	(pthread_mutex_unlock): Likewise.
+	(pthread_mutex_trylock): Likewise.
+	(pthread_mutex_destroy): Likewise.
+	* attr.c (pthread_attr_init): PTHREAD_EXPLICIT_SCHED is the
+	default inheritance attribute; THREAD_PRIORITY_NORMAL is
+	the default priority for new threads.
+	* sched.c (pthread_attr_setschedpolicy): Added routine.
+	(pthread_attr_getschedpolicy): Added routine.
+	(pthread_attr_setinheritsched): Added routine.
+	(pthread_attr_getinheritsched): Added routine.
+	* pthread.h (sched_rr_set_interval): Added as a macro;
+	returns -1 with errno set to ENOSYS.
+
+2001-06-23  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	*sched.c (pthread_attr_setschedparam): Add priority range
+	check.
+	(sched_setscheduler): New function; checks for a valid
+	pid and policy; checks for permission to set information
+	in the target process; expects pid to be a Win32 process ID,
+	not a process handle; the only scheduler policy allowed is
+	SCHED_OTHER.
+	(sched_getscheduler): Likewise, but checks for permission
+	to query.
+	* pthread.h (SCHED_*): Moved to sched.h as defined in the
+	POSIX standard.
+	* sched.h (SCHED_*): Moved from pthread.h.
+	(pid_t): Defined if necessary.
+	(sched_setscheduler): Defined.
+	(sched_getscheduler): Defined.
+	* pthread.def (sched_setscheduler): Exported.
+	(sched_getscheduler): Likewise.
+
+2001-06-23  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	Contributed by -  Ralf Brese <Ralf.Brese@pdb4.siemens.de>
+
+	* create.c (pthread_create): Set thread priority from
+	thread attributes.
+
+2001-06-18  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	* Made organisational-only changes to UWIN additions.
+	* dll.c (dllMain): Moved UWIN process attach code
+	to pthread_win32_process_attach_np(); moved
+	instance of pthread_count to global.c.
+	* global.c (pthread_count): Moved from dll.c.
+	* nonportable.c (pthread_win32_process_attach_np):
+	Moved _UWIN code to here from dll.c.
+	* implement.h (pthread_count): Define extern int.
+	* create.c (pthread_count): Remove extern int.
+	* private.c (pthread_count): Likewise.
+	* exit.c (pthread_count): Likewise.
+
+2001-06-18  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	Contributed by -  David Korn <dgk@research.att.com>
+
+	* dll.c: Added changes necessary to work with UWIN.
+	* create.c: Likewise.
+	* pthread.h: Likewise.
+	* misc.c: Likewise.
+	* exit.c: Likewise.
+	* private.c: Likewise.
+	* implement.h: Likewise.
+	There is some room at the start of struct pthread_t_
+	to implement the signal semantics in UWIN's posix.dll
+	although this is not yet complete.
+	* Nmakefile: Compatible with UWIN's Nmake utility.
+	* Nmakefile.tests: Likewise - for running the tests.
+
+2001-06-08  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	* semaphore.h (sem_t): Fixed for compile and test.
+	* implement.h (sem_t_): Likewise.
+	* semaphore.c: Likewise.
+	* private.c (ptw32_sem_timedwait): Updated to use new
+	opaque sem_t.
+
+2001-06-06  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	* semaphore.h (sem_t): Is now an opaque pointer;
+	moved actual definition to implement.h.
+	* implement.h (sem_t_): Move here from semaphore.h;
+	was the definition of sem_t.
+	* semaphore.c: Wherever necessary, changed use of sem
+	from that of a pointer to a pointer-pointer; added
+	extra checks for a valid sem_t; NULL sem_t when
+	it is destroyed; added extra checks when creating
+	and destroying sem_t elements in the NEED_SEM
+	code branches; changed from using a pthread_mutex_t
+	((*sem)->mutex) to CRITICAL_SECTION ((*sem)->sem_lock_cs)
+	in NEED_SEM branches for access serialisation.
+
+2001-06-06  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	* mutex.c (pthread_mutexattr_init): Remove 
+	ptw32_mutex_default_kind.
+	
+2001-06-05  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	* nonportable.c (pthread_mutex_setdefaultkind_np):
+	Remove - should not have been included in the first place.
+	(pthread_mutex_getdefaultkind_np): Likewise.
+	* global.c (ptw32_mutex_default_kind): Likewise.
+	* mutex.c (pthread_mutex_init): Remove use of
+	ptw32_mutex_default_kind.
+	* pthread.h (pthread_mutex_setdefaultkind_np): Likewise.
+	(pthread_mutex_getdefaultkind_np): Likewise.
+	* pthread.def (pthread_mutexattr_setkind_np): Added.
+	(pthread_mutexattr_getkind_np): Likewise.
+
+	* README: Many changes that should have gone in before
+	the last snapshot.
+	* README.NONPORTABLE: New - referred to by ANNOUNCE
+	but never created; documents the non-portable routines
+	included in the library - moved from README with new
+	routines added.
+	* ANNOUNCE (pthread_mutexattr_setkind_np): Added to
+	compliance list.
+	(pthread_mutexattr_getkind_np): Likewise.
+
+2001-06-04  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	* condvar.c: Add original description of the algorithm as
+	developed by Terekhov and Thomas, plus reference to
+	README.CV.
+
+2001-06-03  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	Contributed by  - Alexander Terekhov <TEREKHOV@de.ibm.com>
+	                - Louis Thomas <lthomas@arbitrade.com>
+
+	* condvar.c (pthread_cond_init): Completely revamped.
+	(pthread_cond_destroy): Likewise.
+	(ptw32_cond_wait_cleanup): Likewise.
+	(ptw32_cond_timedwait): Likewise.
+	(ptw32_cond_unblock): New general signaling routine.
+	(pthread_cond_signal): Now calls ptw32_cond_unblock.
+	(pthread_cond_broadcast): Likewise.
+	* implement.h (pthread_cond_t_): Revamped.
+	* README.CV: New; explanation of the above changes.
+
+2001-05-30  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	* pthread.h (rand_r): Fake using _seed argument to quell
+	compiler warning (compiler should optimise this away later).
+
+	* GNUmakefile (OPT): Leave symbolic information out of the library
+	and increase optimisation level - for smaller faster prebuilt
+	dlls.
+	
+2001-05-29  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	Contributed by  - Milan Gardian <Milan.Gardian@LEIBINGER.com>
+
+	* Makefile: fix typo.
+	* pthreads.h: Fix problems with stdcall/cdecl conventions, in particular
+	remove the need for PT_STDCALL everywhere; remove warning supression.
+	* (errno): Fix the longstanding "inconsistent dll linkage" problem
+	with errno; now also works with /MD debugging libs - 
+	warnings emerged when compiling pthreads library with /MD (or /MDd)
+	compiler switch, instead of /MT (or /MTd) (i.e. when compiling pthreads
+	using Multithreaded DLL CRT instead of Multithreaded statically linked
+	CRT).
+	* create.c (pthread_create): Likewise; fix typo.
+	* private.c (ptw32_threadStart): Eliminate use of terminate() which doesn't
+	throw exceptions.
+	* Remove unnecessary #includes from a number of modules -
+	[I had to #include malloc.h in implement.h for gcc - rpj].
+
+2001-05-29  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	Contributed by 	- Thomas Pfaff <tpfaff@gmx.net>
+
+	* pthread.h (PTHREAD_MUTEX_DEFAULT): New; equivalent to
+	PTHREAD_MUTEX_DEFAULT_NP.
+	* (PTHREAD_MUTEX_NORMAL): Similarly.
+	* (PTHREAD_MUTEX_ERRORCHECK): Similarly.
+	* (PTHREAD_MUTEX_RECURSIVE): Similarly.
+	* (pthread_mutex_setdefaultkind_np): New; Linux compatibility stub
+	for pthread_mutexattr_settype.
+	* (pthread_mutexattr_getkind_np): New; Linux compatibility stub
+	for pthread_mutexattr_gettype.
+	* mutex.c (pthread_mutexattr_settype): New; allow
+	the following types of mutex:
+	  PTHREAD_MUTEX_DEFAULT_NP
+	  PTHREAD_MUTEX_NORMAL_NP
+	  PTHREAD_MUTEX_ERRORCHECK_NP
+	  PTHREAD_MUTEX_RECURSIVE_NP
+	* Note that PTHREAD_MUTEX_DEFAULT is equivalent to
+	PTHREAD_MUTEX_NORMAL - ie. mutexes should no longer
+	be recursive by default, and a thread will deadlock if it
+	tries to relock a mutex it already owns. This is inline with
+	other pthreads implementations.
+	* (pthread_mutex_lock): Process the lock request
+	according to the mutex type.
+	* (pthread_mutex_init): Eliminate use of Win32 mutexes as the
+	basis of POSIX mutexes - instead, a combination of one critical section
+	and one semaphore are used in conjunction with Win32 Interlocked* routines.
+	* (pthread_mutex_destroy): Likewise.
+	* (pthread_mutex_lock): Likewise.
+	* (pthread_mutex_trylock): Likewise.
+	* (pthread_mutex_unlock): Likewise.
+	* Use longjmp/setjmp to implement cancelation when building the library
+	using a C compiler which doesn't support exceptions, e.g. gcc -x c (note
+	that gcc -x c++ uses exceptions).
+	* Also fixed some of the same typos and eliminated PT_STDCALL as
+	Milan Gardian's patches above.
+
+2001-02-07  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	Contributed by  - Alexander Terekhov <TEREKHOV@de.ibm.com>
+	
+	* rwlock.c: Revamped.
+	* implement.h (pthread_rwlock_t_): Redefined.
+	This implementation does not have reader/writer starvation problem.
+	Rwlock attempts to behave more like a normal mutex with
+	races and scheduling policy determining who is more important;
+	It also supports recursive locking,
+	has less synchronization overhead (no broadcasts at all,
+	readers are not blocked on any condition variable) and seem to
+	be faster than the current implementation [W98 appears to be
+	approximately 15 percent faster at least - on top of speed increase
+	from Thomas Pfaff's changes to mutex.c - rpj].
+
+2000-12-29  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* Makefile: Back-out "for" loops which don't work.
+
+	* GNUmakefile: Remove the fake.a target; add the "realclean"
+	target; don't remove built libs under the "clean" target.
+
+	* config.h: Add a guard against multiple inclusion.
+
+	* semaphore.h: Add some defines from config.h to make
+	semaphore.h independent of config.h when building apps.
+
+	* pthread.h (_errno): Back-out previous fix until we know how to
+	fix it properly.
+
+	* implement.h (lockCount): Add missing element to pthread_mutex_t_.
+
+	* sync.c (pthread_join): Spelling fix in comment.
+
+	* private.c (ptw32_threadStart): Reset original termination
+	function (C++).
+	(ptw32_threadStart): Cleanup detached threads early in case
+	the library is statically linked.
+	(ptw32_callUserDestroyRoutines): Remove [SEH] __try block from
+	destructor call so that unhandled exceptions will be passed through
+	to the 	system; call terminate() from [C++] try block for the same
+	reason.
+
+	* tsd.c (pthread_getspecific): Add comment.
+
+	* mutex.c (pthread_mutex_init): Initialise new elements in
+	pthread_mutex_t.
+	(pthread_mutex_unlock): Invert "pthread_equal()" test.
+
+2000-12-28  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* semaphore.c (mode_t): Use ifndef HAVE_MODE_T to include definition.
+
+	* config.h.in (HAVE_MODE_T): Added.
+	(_UWIN): Start adding defines for the UWIN package.
+
+	* private.c (ptw32_threadStart): Unhandled exceptions are
+	now passed through to the system to deal with. This is consistent
+	with normal Windows behaviour. C++ applications may use
+	set_terminate() to override the default behaviour which is
+	to call ptw32_terminate(). Ptw32_terminate() cleans up some
+	POSIX thread stuff before calling the system default function
+	which calls abort(). The users termination function should conform
+	to standard C++ semantics which is to not return. It should
+	exit the thread (call pthread_exit()) or exit the application.
+	* private.c (ptw32_terminate): Added as the default set_terminate()
+	function. It calls the system default function after cleaning up
+	some POSIX thread stuff.
+
+	* implement.h (ptw32_try_enter_critical_section): Move
+	declaration.
+	* global.c (ptw32_try_enter_critical_section): Moved
+	from dll.c.
+	* dll.c: Move process and thread attach/detach code into
+	functions in nonportable.c.
+	* nonportable.c (pthread_win32_process_attach_np): Process
+	attach code from dll.c is now available to static linked
+	applications.
+	* nonportable.c (pthread_win32_process_detach_np): Likewise.
+	* nonportable.c (pthread_win32_thread_attach_np): Likewise.
+	* nonportable.c (pthread_win32_thread_detach_np): Likewise.
+
+	* pthread.h: Add new non-portable prototypes for static
+	linked applications.
+
+	* GNUmakefile (OPT): Increase optimisation flag and remove
+	debug info flag.
+
+	* pthread.def: Add new non-portable exports for static
+	linked applications.
+
+2000-12-11  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* FAQ: Update Answer 6 re getting a fully working
+	Mingw32 built library.
+
+2000-10-10  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+ 
+        * misc.c (pthread_self): Restore Win32 "last error"
+        cleared by TlsGetValue() call in
+        pthread_getspecific()
+        - "Steven Reddie" <smr@essemer.com.au>
+ 
+2000-09-20  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+ 
+        * mutex.c (pthread_mutex_lock): Record the owner
+        of the mutex. This requires also keeping count of
+        recursive locks ourselves rather than leaving it
+        to Win32 since we need to know when to NULL the
+        thread owner when the mutex is unlocked.
+        (pthread_mutex_trylock): Likewise.
+        (pthread_mutex_unlock): Check that the calling
+        thread owns the mutex, decrement the recursive
+        lock count, and NULL the owner if zero. Return
+        EPERM if the mutex is owned by another thread.
+        * implement.h (pthread_mutex_t_): Add ownerThread
+        and lockCount members.
+        - reported by Arthur Kantor <akantor@bexusa.com>
+
+2000-09-13  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	* mutex.c (pthread_mutex_init): Call
+	TryEnterCriticalSection through the pointer
+	rather than directly so that the dll can load
+	on Windows versions that can't resolve the
+	function, eg. Windows 95
+	- "Jef Gearhart" <jgearhart@tpssys.com>
+
+2000-09-09  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* pthread.h (ctime_r): Fix arg.
+
+2000-09-08  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* GNUmakefile(_WIN32_WINNT=0x400): Define in CFLAGS;
+	doesn't seem to be needed though.
+
+	* cancel.c (pthread_cancel): Must get "self" through
+	calling pthread_self() which will ensure a POSIX thread
+	struct is built for non-POSIX threads; return an error
+	if this fails
+	- Ollie Leahy <ollie@mpt.ie>
+	(pthread_setcancelstate): Likewise.
+	(pthread_setcanceltype): Likewise.
+	* misc.c (ptw32_cancelable_wait): Likewise.
+
+	* private.c (ptw32_tkAssocCreate): Remove unused #if 0
+	wrapped code.
+
+	* pthread.h (ptw32_get_exception_services_code):
+	Needed to be forward declared unconditionally.
+
+2000-09-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* cancel.c (pthread_cancel): If called from the main
+	thread "self" would be NULL; get "self" via pthread_self()
+	instead of directly from TLS so that an implicit
+	pthread object is created.
+
+	* misc.c (pthread_equal): Strengthen test for NULLs.
+
+2000-09-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* condvar.c (ptw32_cond_wait_cleanup): Ensure that all
+	waking threads check if they are the last, and notify
+	the broadcaster if so - even if an error occurs in the
+	waiter.
+
+	* semaphore.c (_decrease_semaphore): Should be
+	a call to ptw32_decrease_semaphore.
+	(_increase_semaphore): Should be a call to
+	ptw32_increase_semaphore.
+
+	* misc.c (ptw32_cancelable_wait): Renamed from
+	CancelableWait.
+	* rwlock.c (_rwlock_check*): Renamed to
+	ptw32_rwlock_check*.
+	* mutex.c (_mutex_check*): Renamed to ptw32_mutex_check*.
+	* condvar.c (cond_timed*): Renamed to ptw32_cond_timed*.
+	(_cond_check*): Renamed to ptw32_cond_check*.
+	(cond_wait_cleanup*): Rename to ptw32_cond_wait_cleanup*.
+	(ptw32_cond_timedwait): Add comments.
+
+2000-08-22  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	* private.c (ptw32_throw): Fix exception test;
+	move exceptionInformation declaration.
+
+	* tsd.c (pthread_key_create): newkey wrongly declared.
+
+	* pthread.h: Fix comment block.
+
+2000-08-18  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	* mutex.c (pthread_mutex_destroy): Check that the mutex isn't
+	held; invalidate the mutex as early as possible to avoid
+	contention; not perfect - FIXME!
+
+	* rwlock.c (pthread_rwlock_init): Remove redundant assignment
+	to "rw".
+	(pthread_rwlock_destroy): Invalidate the rwlock before
+	freeing up any of it's resources - to avoid contention.
+
+	* private.c (ptw32_tkAssocCreate): Change assoc->lock
+	to use a dynamically initialised mutex - only consumes
+	a W32 mutex or critical section when first used,
+	not before.
+
+	* mutex.c (pthread_mutex_init): Remove redundant assignment
+	to "mx".
+	(pthread_mutexattr_destroy): Set attribute to NULL
+	before freeing it's memory - to avoid contention.
+
+	* implement.h (PTW32_EPS_CANCEL/PTW32_EPS_EXIT):
+	Must be defined for all compilers - used as generic
+	exception selectors by ptw32_throw().
+
+	* Several: Fix typos from scripted edit session
+	yesterday.
+
+	* nonportable.c (pthread_mutexattr_setforcecs_np):
+	Moved this function from mutex.c.
+	(pthread_getw32threadhandle_np): New function to
+	return the win32 thread handle that the POSIX
+	thread is using.
+	* mutex.c (pthread_mutexattr_setforcecs_np):
+	Moved to new file "nonportable.c".
+
+	* pthread.h (PTW32_BUILD): Only	redefine __except
+	and catch compiler keywords if we aren't building
+	the library (ie. PTW32_BUILD is not defined) - 
+	this is safer than defining and then undefining
+	if not building the library.
+	* implement.h: Remove __except and catch undefines.
+	* Makefile (CFLAGS): Define PTW32_BUILD.
+	* GNUmakefile (CFLAGS): Define PTW32_BUILD.
+
+	* All appropriate: Change Pthread_exception* to
+	ptw32_exception* to be consistent with internal
+	identifier naming.
+
+	* private.c (ptw32_throw): New function to provide
+	a generic exception throw for all internal
+	exceptions and EH schemes.
+	(ptw32_threadStart): pthread_exit() value is now
+	returned via the thread structure exitStatus
+	element.
+	* exit.c (pthread_exit): pthread_exit() value is now
+	returned via the thread structure exitStatus
+	element.
+	* cancel.c (ptw32_cancel_self): Now uses ptw32_throw.
+	(pthread_setcancelstate): Ditto.
+	(pthread_setcanceltype): Ditto.
+	(pthread_testcancel): Ditto.
+	(pthread_cancel): Ditto.
+	* misc.c (CancelableWait): Ditto.
+	* exit.c (pthread_exit): Ditto.
+	* All applicable: Change PTW32_ prefix to
+	PTW32_ prefix to remove leading underscores
+	from private library identifiers.
+
+2000-08-17  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* All applicable: Change _pthread_ prefix to
+	ptw32_ prefix to remove leading underscores
+	from private library identifiers (single
+	and double leading underscores are reserved in the
+	ANSI C standard for compiler implementations).
+
+	* tsd.c (pthread_create_key): Initialise temporary
+	key before returning it's address to avoid race
+	conditions.
+
+2000-08-13  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* errno.c: Add _MD precompile condition; thus far
+	had no effect when using /MD compile option but I
+	thnk it should be there.
+
+	* exit.c: Add __cplusplus to various #if lines;
+	was compiling SEH code even when VC++ had
+	C++ compile options.
+
+	* private.c: ditto.
+
+	* create.c (pthread_create): Add PT_STDCALL macro to
+	function pointer arg in _beginthread().
+
+	* pthread.h: PT_STDCALL really does need to be defined
+	in both this and impliment.h; don't set it to __cdecl
+	- this macro is only used to extend function pointer
+	casting for functions that will be passed as parameters.
+	(~PThreadCleanup): add cast and group expression.
+	(_errno): Add _MD compile conditional.
+	(PtW32NoCatchWarn): Change pragma message.
+
+	* implement.h: Move and change PT_STDCALL define.
+
+	* need_errno.h: Add _MD to compilation conditional.
+
+	* GNUmakefile: Substantial rewrite for new naming
+	convention; set for nil optimisation (turn it up
+	when we have a working library build; add target
+	"fake.a" to build a libpthreadw32.a from the VC++
+	built DLL pthreadVCE.dll.
+
+	* pthread.def (LIBRARY): Don't specify in the .def
+	file - it is specified on the linker command line
+	since we now use the same .def file for variously
+	named .dlls.
+
+	* Makefile: Substantial rewrite for new naming
+	convention; default nmake target only issues a
+	help message; run nmake with specific target
+	corresponding to the EH scheme being used.
+
+	* README: Update information; add naming convention
+	explanation.
+
+	* ANNOUNCE: Update information.
+
+2000-08-12  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* pthread.h: Add compile-time message when using
+	MSC_VER compiler and C++ EH to warn application
+	programmers to use PtW32Catch instead of catch(...)
+	if they want cancelation and pthread_exit to work.
+
+	* implement.h: Remove #include <semaphore.h>; we
+	use our own local semaphore.h.
+
+2000-08-10  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* cleanup.c (pthread_pop_cleanup): Remove _pthread
+	prefix from __except and catch keywords; implement.h
+	now simply undefines ptw32__except and
+	ptw32_catch if defined; VC++ was not textually
+	substituting ptw32_catch etc back to catch as
+	it was redefined; the reason for using the prefixed
+	version was to make it clear that it was not using
+	the pthread.h redefined catch keyword.
+
+	* private.c (ptw32_threadStart): Ditto.
+	(ptw32_callUserDestroyRoutines): Ditto.
+
+	* implement.h (ptw32__except): Remove #define.
+	(ptw32_catch): Remove #define.
+
+	* GNUmakefile (pthread.a): New target to build
+	libpthread32.a from pthread.dll using dlltool.
+
+	* buildlib.bat: Duplicate cl commands with args to
+	build C++ EH version of pthread.dll; use of .bat
+	files is redundant now that nmake compatible
+	Makefile is included; used as a kludge only now.
+
+	* Makefile: Localise some macros and fix up the clean:
+	target to extend it and work properly.
+
+	* CONTRIBUTORS: Add contributors.
+
+	* ANNOUNCE: Updated.
+
+	* README: Updated.
+
+2000-08-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* pthread.h: Remove #warning - VC++ doesn't accept it.
+
+2000-08-05  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* pthread.h (PtW32CatchAll): Add macro. When compiling
+	applications using VC++ with C++ EH rather than SEH
+	'PtW32CatchAll' must be used in place of any 'catch( ... )'
+	if the application wants pthread cancelation or
+	pthread_exit() to work.
+
+2000-08-03  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* pthread.h: Add a base class ptw32_exception for
+	library internal exceptions and change the "catch"
+	re-define macro to use it.
+
+2000-08-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* GNUmakefile (CFLAGS): Add -mthreads.
+	Add new targets to generate cpp and asm output.
+
+	* sync.c (pthread_join): Remove dead code.
+
+2000-07-25  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* sched.c (sched_get_priority_max): Handle different WinCE and
+	Win32 priority values together.
+	(sched_get_priority_min): Ditto.
+	- Tristan Savatier <tristan@mpegtv.com>
+
+	* create.c (pthread_create): Force new threads to wait until
+	pthread_create has the new thread's handle; we also retain
+	a local copy of the handle for internal use until
+	pthread_create returns.
+
+	* private.c (ptw32_threadStart): Initialise ei[].
+	(ptw32_threadStart): When beginthread is used to start the
+	thread, force waiting until the creator thread had the 
+	thread handle.
+
+	* cancel.c (ptw32_cancel_thread): Include context switch
+	code for defined(_X86_) environments in addition to _M_IX86.
+
+	* rwlock.c (pthread_rwlock_destroy): Assignment changed
+	to avoid compiler warning.
+
+	* private.c (ptw32_get_exception_services_code): Cast
+	NULL return value to avoid compiler warning.
+
+	* cleanup.c (pthread_pop_cleanup): Initialise "cleanup" variable
+	to avoid compiler warnings.
+
+	* misc.c (ptw32_new): Change "new" variable to "t" to avoid
+	confusion with the C++ keyword of the same name.
+
+	* condvar.c (cond_wait_cleanup): Initialise lastWaiter variable.
+	(cond_timedwait): Remove unused local variables. to avoid
+	compiler warnings.
+
+	* dll.c (dllMain): Remove 2000-07-21 change - problem
+	appears to be in pthread_create().
+
+2000-07-22  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* tsd.c (pthread_key_create): If a destructor was given
+	and the pthread_mutex_init failed, then would try to
+	reference a NULL pointer (*key); eliminate this section of
+	code by using a dynamically initialised mutex
+	(PTHREAD_MUTEX_INITIALIZER).
+
+	* tsd.c (pthread_setspecific): Return an error if
+	unable to set the value; simplify cryptic conditional.
+
+	* tsd.c (pthread_key_delete): Locking threadsLock relied
+	on mutex_lock returning an error if the key has no destructor.
+	ThreadsLock is only initialised if the key has a destructor.
+	Making this mutex a static could reduce the number of mutexes
+	used by an application since it is actually created only at
+	first use and it's often destroyed soon after.
+	
+2000-07-22  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* FAQ: Added Q5 and Q6.
+
+2000-07-21  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	* create.c (pthread_create): Set threadH to 0 (zero)
+	everywhere. Some assignments were using NULL. Maybe
+	it should be NULL everywhere - need to check. (I know
+	they are nearly always the same thing - but not by
+	definition.)
+
+	* dll.c: Include resource leakage work-around. This is a
+	partial FIXME which doesn't stop all leakage. The real
+	problem needs to be found and fixed.
+	- "David Baggett" <dmb@itasoftware.com>
+
+	* misc.c (pthread_self): Try to catch NULL thread handles
+	at the point where they might be generated, even though
+	they should always be valid at this point.
+
+	* tsd.c (pthread_setspecific): return an error value if
+	pthread_self() returns NULL.
+
+	* sync.c (pthread_join): return an error value if
+	pthread_self() returns NULL.
+
+	* signal.c (pthread_sigmask): return an error value if
+	pthread_self() returns NULL.
+
+2000-03-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* attr.c (pthread_attr_init): Set default stacksize to zero (0)
+	rather than PTHREAD_STACK_MIN even though these are now the same.
+
+	* pthread.h (PTHREAD_STACK_MIN): Lowered to 0.
+
+2000-01-28  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* mutex.c (pthread_mutex_init): Free mutex if it has been alloced;
+	if critical sections can be used instead of Win32 mutexes, test
+	that the critical section works and return an error if not.
+
+2000-01-07  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* cleanup.c (pthread_pop_cleanup): Include SEH code only if MSC is not
+	compiling as C++.
+	(pthread_push_cleanup): Include SEH code only if MSC is not
+	compiling as C++.
+
+	* pthread.h: Include SEH code only if MSC is not
+	compiling as C++.
+
+	* implement.h: Include SEH code only if MSC is not
+	compiling as C++.
+
+	* cancel.c (ptw32_cancel_thread): Add _M_IX86 check.
+	(pthread_testcancel): Include SEH code only if MSC is not
+	compiling as C++.
+	(ptw32_cancel_self): Include SEH code only if MSC is not
+	compiling as C++.
+
+2000-01-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* Makefile: Remove inconsistencies in 'cl' args
+	- Erik Hensema <erik.hensema@group2000.nl>
+
+2000-01-04  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* private.c (ptw32_get_exception_services_code): New; returns
+	value of EXCEPTION_PTW32_SERVICES.
+	(ptw32_processInitialize): Remove initialisation of
+	ptw32_exception_services which is no longer needed.
+
+	* pthread.h (ptw32_exception_services): Remove extern.
+	(ptw32_get_exception_services_code): Add function prototype;
+	use this to return EXCEPTION_PTW32_SERVICES value instead of
+	using the ptw32_exception_services variable which I had
+	trouble exporting through pthread.def.
+
+	* global.c (ptw32_exception_services): Remove declaration.
+
+1999-11-22  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* implement.h: Forward declare ptw32_new();
+
+	* misc.c (ptw32_new): New; alloc and initialise a new pthread_t.
+	(pthread_self): New thread struct is generated 	by new routine
+	ptw32_new().
+
+	* create.c (pthread_create): New thread struct is generated
+	by new routine ptw32_new().
+
+1999-11-21  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* global.c (ptw32_exception_services): Declare new variable. 
+
+	* private.c (ptw32_threadStart): Destroy thread's
+	cancelLock mutex; make 'catch' and '__except' usageimmune to
+	redfinitions in pthread.h.
+	(ptw32_processInitialize): Init new constant ptw32_exception_services.
+
+	* create.c (pthread_create): Initialise thread's cancelLock
+	mutex.
+
+	* cleanup.c (pthread_pop_cleanup): Make 'catch' and '__except'
+	usage immune to redfinition s in pthread.h.
+
+	* private.c: Ditto.
+
+	* pthread.h (catch): Redefine 'catch' so that C++ applications
+	won't catch our internal exceptions.
+	(__except): ditto for __except.
+
+	* implement.h (ptw32_catch): Define internal version
+	of 'catch' because 'catch' is redefined by pthread.h.
+	(__except): ditto for __except.
+	(struct pthread_t_): Add cancelLock mutex for async cancel
+	safety.
+
+	* cancel.c (ptw32_cancel_self): New; part of the async
+	cancellation implementation.
+	(ptw32_cancel_thread): Ditto; this function is X86
+	processor specific.
+	(pthread_setcancelstate): Add check for pending async
+	cancel request and cancel the calling thread if
+	required; add async-cancel safety lock.
+	(pthread_setcanceltype): Ditto.
+	- Jason Nye <jnye@nbnet.nb.ca>
+	- Erik Hensema <erik.hensema@group2000.nl>
+
+1999-11-13  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* configure.in (AC_OUTPUT): Put generated output into GNUmakefile
+	rather than Makefile. Makefile will become the MSC nmake compatible
+	version
+	- Erik Hensema <erik.hensema@group2000.nl>
+
+	* misc.c (pthread_self): Add a note about GetCurrentThread
+	returning a pseudo-handle
+	- John Bossom (John.Bossom@cognos.com>
+
+1999-11-10  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* dll.c (dllMain): Free kernel32 ASAP.
+	If TryEnterCriticalSection is not being used, then free
+	the kernel32.dll handle now, rather than leaving it until
+	DLL_PROCESS_DETACH.
+
+	Note: this is not a pedantic exercise in freeing unused
+	resources!  It is a work-around for a bug in Windows 95
+	(see microsoft knowledge base article, Q187684) which
+	does Bad Things when FreeLibrary is called within
+	the DLL_PROCESS_DETACH code, in certain situations.
+	Since w95 just happens to be a platform which does not
+	provide TryEnterCriticalSection, the bug will be
+	effortlessly avoided.
+	- Todd Owen <towen@lucidcalm.dropbear.id.au>
+
+	* sync.c (pthread_join): Make it a deferred cancelation point.
+
+	* misc.c (pthread_self): Explicitly initialise implicitly
+	created thread state to default values.
+
+1999-11-05  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.h (winsock.h): Include unconditionally.
+	(ETIMEDOUT): Change fallback value to that defined by winsock.h.
+	
+	* general: Patched for portability to WinCE. The details are
+	described in the file WinCE-PORT. Follow the instructions
+	in README.WinCE to make the appropriate changes in config.h.
+	- Tristan Savatier <tristan@mpegtv.com>
+
+1999-10-30  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* create.c (pthread_create): Explicitly initialise thread state to
+	default values.
+
+	* cancel.c (pthread_setcancelstate): Check for NULL 'oldstate'
+	for compatibility with Solaris pthreads;
+	(pthread_setcanceltype): ditto:
+	- Erik Hensema <erik.hensema@group2000.nl>
+
+1999-10-23  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.h (ctime_r): Fix incorrect argument "_tm"
+	- Erik Hensema <erik.hensema@group2000.nl>
+
+1999-10-21  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.h (_POSIX_THREADS): Only define it if it isn't
+	already defined. Projects may need to define this on
+	the CC command line under Win32 as it doesn't have unistd.h
+	- Aurelio Medina <aureliom@crt.com>
+
+1999-10-17  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* rwlock.c (pthread_rwlock_destroy): Add cast to remove compile
+	warning.
+
+	* condvar.c (pthread_cond_broadcast): Only release semaphores
+	if there are waiting threads.
+
+1999-10-15  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* condvar.c (cond_wait_cleanup): New static cleanup handler for
+	cond_timedwait;
+	(cond_timedwait): pthread_cleanup_push args changed;
+	canceling a thread while it's in pthread_cond_wait
+	will now decrement the waiters count and cleanup if it's the
+	last waiter.
+	- Lorin Hochstein <lmh@xiphos.ca> and 
+	  Peter Slacik <Peter.Slacik@tatramed.sk>;
+	the last waiter will now reset the CV's wasBroadcast flag
+	- Graham Dumpleton <Graham.Dumpleton@ra.pad.otc.telstra.com.au>.
+
+Thu Sep 16 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* rwlock.c (pthread_rwlock_destroy): Add serialisation.
+	(_rwlock_check_need_init): Check for detroyed rwlock.
+	* rwlock.c: Check return codes from _rwlock_check_need_init();
+	modify comments; serialise access to rwlock objects during
+	operations; rename rw_mutex to rw_lock.
+	* implement.h: Rename rw_mutex to rw_lock.
+	* mutex.c (pthread_mutex_destroy): Add serialisation.
+	(_mutex_check_need_init): Check for detroyed mutex.
+	* condvar.c (pthread_cond_destroy): Add serialisation.
+	(_cond_check_need_init): Check for detroyed condvar.
+	* mutex.c: Modify comments.
+	* condvar.c: Modify comments.
+
+Sat Sep 10 12:56:13 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	The following code for POSIX read/write locks was contributed
+	by Aurelio Medina.
+
+	* implement.h (pthread_rwlock_t_): Add.
+	* pthread.h (pthread_rwlock_t): Add.
+	(PTHREAD_RWLOCK_INITIALIZER): Add.
+	Add rwlock function prototypes.
+	* rwlock.c: New module.
+	* pthread.def: Add new rwlock functions.
+	* private.c (ptw32_processInitialize): initialise
+	ptw32_rwlock_test_init_lock critical section.
+	* global.c (ptw32_rwlock_test_init_lock): Add.
+
+	* mutex.c (pthread_mutex_destroy): Don't free mutex memory
+	if mutex is PTHREAD_MUTEX_INITIALIZER and has not been
+	initialised yet.
+
+Wed Sep  8 12:56:13 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* mutex.c (pthread_mutex_destroy): Free mutex memory.
+	- Milan Gardian <mg@tatramed.sk>
+
+1999-08-22  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* exit.c (pthread_exit): Fix reference to potentially
+	uninitialised pointer.
+
+1999-08-21  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* private.c (ptw32_threadStart): Apply fix of 1999-08-19
+	this time to C++ and non-trapped C versions. Ommitted to
+	do this the first time through.
+
+1999-08-19  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* private.c (ptw32_threadStart): Return exit status from
+	the application thread startup routine.
+	- Milan Gardian <mg@tatramed.sk>
+
+1999-08-18  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* exit.c (pthread_exit): Put status into pthread_t->exitStatus
+	- John Bossom <john.Bossom@cognos.com>
+	* private.c (ptw32_threadStart): Set pthread->exitStatus
+	on exit of try{} block.
+	- John Bossom <john.Bossom@cognos.com>
+	* sync.c (pthread_join): use pthread_exitStatus value if the
+	thread exit doesn't return a value (for Mingw32 CRTDLL
+	which uses endthread instead of _endthreadex).
+	- John Bossom <john.Bossom@cognos.com>
+
+Tue Aug 17 20:17:58 CDT 1999  Mumit Khan  <khan@xraylith.wisc.edu>
+
+        * create.c (pthread_create): Add CRTDLL suppport.
+        * exit.c (pthread_exit): Likewise.
+        * private.c (ptw32_threadStart): Likewise.
+        (ptw32_threadDestroy): Likewise.
+        * sync.c (pthread_join): Likewise.
+        * tests/join1.c (main): Warn about partial support for CRTDLL.
+
+Tue Aug 17 20:00:08 1999  Mumit Khan  <khan@xraylith.wisc.edu>
+
+        * Makefile.in (LD): Delete entry point.
+        * acconfig.h (STDCALL): Delete unused macro.
+        * configure.in: Remove test for STDCALL.
+        * config.h.in: Regenerate.
+        * errno.c (_errno): Fix self type.
+        * pthread.h (PT_STDCALL): Move from here to
+        * implement.h (PT_STDCALL): here.
+        (ptw32_threadStart): Fix prototype.
+        * private.c (ptw32_threadStart): Likewise.
+
+1999-08-14  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* exit.c (pthread_exit): Don't call pthread_self() but
+	get thread handle directly from TSD for efficiency.
+	
+1999-08-12  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* private.c (ptw32_threadStart): ei[] only declared if _MSC_VER.
+
+	* exit.c (pthread_exit): Check for implicitly created threads
+	to avoid raising an unhandled exception.
+	
+1999-07-12  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* condvar.c (pthread_cond_destroy): Add critical section.
+	(cond_timedwait): Add critical section; check for timeout
+	waiting on semaphore.
+	(pthread_cond_broadcast): Add critical section.
+	- Peter Slacik <Peter.Slacik@tatramed.sk>
+
+1999-07-09  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	The following changes fix a bug identified by
+	Lorin Hochstein <lmh@xiphos.ca> and solved by
+	John Bossom <John.Bossom@Cognos.COM>.
+
+	The problem was that cleanup handlers were not executed when
+	pthread_exit() was called.
+
+	* implement.h (pthread_t_): Add exceptionInformation element for
+	C++ per-thread exception information.
+	(general): Define and rename exceptions.
+
+
+	* misc.c (CancelableWait):  PTW32_EPS_CANCEL (SEH) and
+	ptw32_exception_cancel (C++) used to identify the exception.
+
+	* cancel.c (pthread_testcancel): PTW32_EPS_CANCEL (SEH) and
+	ptw32_exception_cancel (C++) used to identify the exception.
+
+	* exit.c (pthread_exit): throw/raise an exception to return to
+	ptw32_threadStart() to exit the thread. PTW32_EPS_EXIT (SEH)
+	and ptw32_exception_exit (C++) used to identify the exception.
+
+	* private.c (ptw32_threadStart): Add pthread_exit exception trap;
+	clean up and exit the thread directly rather than via pthread_exit().
+
+Sun May 30 00:25:02 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* semaphore.h (mode_t): Conditionally typedef it.
+
+Fri May 28 13:33:05 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* condvar.c (pthread_cond_broadcast): Fix possible memory fault
+	- Mark E. Armstrong <avail@pacbell.net>
+	
+Thu May 27 13:08:46 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* condvar.c (pthread_cond_broadcast): Fix logic bug
+	- Peter Slacik <Peter.Slacik@tatramed.sk>;
+	optimise sem_post loop
+	- Bossom, John <John.Bossom@Cognos.COM>.
+
+Fri May 14 12:13:18 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* attr.c (pthread_attr_setdetachstate): Fix logic bug
+	- Mike Russo <miker@eai.com>.
+
+Sat May  8 09:42:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.def (sem_open): Add.
+	(sem_close): Add.
+	(sem_unlink): Add.
+	(sem_getvalue): Add.
+
+	* FAQ (Question 3): Add.
+
+Thu Apr  8 01:16:23 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* semaphore.c (sem_open): New function; returns an error (ENOSYS).
+	(sem_close): ditto.
+	(sem_unlink): ditto.
+	(sem_getvalue): ditto.
+
+	* semaphore.h (_POSIX_SEMAPHORES): define.
+	
+Wed Apr  7 14:09:52 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* errno.c (_REENTRANT || _MT): Invert condition.
+
+	* pthread.h (_errno): Conditionally include prototype.
+
+Wed Apr  7 09:37:00 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* *.c (comments): Remove individual attributions - these are
+	documented sufficiently elsewhere.
+
+	* implement.h (pthread.h): Remove extraneous include.
+
+Sun Apr  4 11:05:57 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* sched.c (sched.h): Include.
+
+	* sched.h: New file for POSIX 1b scheduling.
+
+	* pthread.h: Move opaque structures to implement.h; move sched_*
+	prototypes out and into sched.h.
+
+	* implement.h: Add opaque structures from pthread.h.
+
+	* sched.c (sched_yield): New function.
+
+	* condvar.c (ptw32_sem_*): Rename to sem_*; except for
+	ptw32_sem_timedwait which is an private function.
+
+Sat Apr  3 23:28:00 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* Makefile.in (OBJS): Add errno.o.
+
+Fri Apr  2 11:08:50 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* implement.h (ptw32_sem_*): Remove prototypes now defined in
+	semaphore.h.
+
+	* pthread.h (sempahore.h): Include.
+
+	* semaphore.h: New file for POSIX 1b semaphores.
+
+	* pthread.h (ptw32_sem_t): Change to sem_t. 
+
+	* semaphore.c (ptw32_sem_*): Change to sem_*; these functions
+	will be exported from the library; set errno on error.
+	- John Bossom <jebossom@cognos.com>
+	(ptw32_sem_timedwait): Moved to private.c.
+
+	* private.c (ptw32_sem_timedwait): Moved from semaphore.c;
+	set errno on error.
+
+	* errno.c (_errno): New file. New function.
+	- John Bossom
+
+	* pthread.h (pthread_t_): Add per-thread errno element.
+
+Fri Mar 26 14:11:45 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* semaphore.c (ptw32_sem_timedwait): Check for negative
+	milliseconds.
+	- Tor Lillqvist <tml@iki.fi>
+
+Wed Mar 24 11:32:07 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* misc.c (CancelableWait): Initialise exceptionInformation[2].
+	(pthread_self): Get a real Win32 thread handle for implicit threads.
+	- John Bossom <jebossom@cognos.com>
+
+	* cancel.c (pthread_testcancel): Initialise exceptionInformation[2].
+	- John Bossom <jebossom@cognos.com>
+
+	* implement.h (SE_INFORMATION): Fix values.
+	- John Bossom <jebossom@cognos.com>
+
+	* private.c (ptw32_threadDestroy): Close the thread handle.
+	- John Bossom <jebossom@cognos.com>
+
+Fri Mar 19 12:57:27 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* cancel.c (comments): Update and cleanup.
+
+Fri Mar 19 09:12:59 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* private.c (ptw32_threadStart): status returns PTHREAD_CANCELED.
+
+	* pthread.h (PTHREAD_CANCELED): defined.
+
+Tue Mar 16  1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* all: Add GNU LGPL and Copyright and Warranty.
+	
+Mon Mar 15 00:20:13 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* condvar.c (pthread_cond_init): fix possible uninitialised use
+	of cv.
+
+Sun Mar 14 21:01:59 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* condvar.c (pthread_cond_destroy): don't do full cleanup if
+	static initialised cv has never been used.
+	(cond_timedwait): check result of auto-initialisation.
+
+Thu Mar 11 09:01:48 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.h (pthread_mutex_t): revert to (pthread_mutex_t *);
+	define a value to serve as PTHREAD_MUTEX_INITIALIZER.
+	(pthread_mutex_t_): remove staticinit and valid elements.
+	(pthread_cond_t): revert to (pthread_cond_t_ *);
+	define a value to serve as PTHREAD_COND_INITIALIZER.
+	(pthread_cond_t_): remove staticinit and valid elements.
+
+	* mutex.c (pthread_mutex_t args): adjust indirection of references.
+	(all functions): check for PTHREAD_MUTEX_INITIALIZER value;
+	check for NULL (invalid).
+
+	* condvar.c (pthread_cond_t args): adjust indirection of references.
+	(all functions): check for PTHREAD_COND_INITIALIZER value;
+	check for NULL (invalid).
+
+Wed Mar 10 17:18:12 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* misc.c (CancelableWait): Undo changes from Mar 8 and 7.
+
+Mon Mar  8 11:18:59 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* misc.c (CancelableWait): Ensure cancelEvent handle is the lowest
+	indexed element in the handles array. Enhance test for abandoned
+	objects.
+
+	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Trailing elements not
+	initialised are set to zero by the compiler. This avoids the
+	problem of initialising the opaque critical section element in it.
+	(PTHREAD_COND_INITIALIZER): Ditto.
+
+	* semaphore.c (ptw32_sem_timedwait): Check sem == NULL earlier.
+
+Sun Mar  7 12:31:14 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* condvar.c (pthread_cond_init): set semaphore initial value
+	to 0, not 1. cond_timedwait was returning signaled immediately.
+
+	* misc.c (CancelableWait): Place the cancel event handle first
+	in the handle table for WaitForMultipleObjects. This ensures that
+	the cancel event is recognised and acted apon if both objects
+	happen to be signaled together.
+
+	* private.c (ptw32_cond_test_init_lock): Initialise and destroy.
+
+	* implement.h (ptw32_cond_test_init_lock): Add extern.
+
+	* global.c (ptw32_cond_test_init_lock): Add declaration. 
+
+	* condvar.c (pthread_cond_destroy): check for valid initialised CV;
+	flag destroyed CVs as invalid.
+	(pthread_cond_init): pthread_cond_t is no longer just a pointer.
+	This is because PTHREAD_COND_INITIALIZER needs state info to reside
+	in pthread_cond_t so that it can initialise on first use. Will work on
+	making pthread_cond_t (and other objects like it) opaque again, if
+	possible, later.
+	(cond_timedwait): add check for statically initialisation of
+	CV; initialise on first use.
+	(pthread_cond_signal): check for valid CV.
+	(pthread_cond_broadcast): check for valid CV.
+	(_cond_check_need_init): Add.
+
+	* pthread.h (PTHREAD_COND_INITIALIZER): Fix.
+	(pthread_cond_t): no longer a pointer to pthread_cond_t_.
+	(pthread_cond_t_): add 'staticinit' and 'valid' elements.
+
+Sat Mar 6 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* implement.h: Undate comments.
+
+Sun Feb 21 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.h (PTHREAD_MUTEX_INITIALIZER): missing braces around
+	cs element initialiser.
+
+1999-02-21  Ben Elliston  <bje@cygnus.com>
+
+	* pthread.h (pthread_exit): The return type of this function is
+	void, not int.
+
+	* exit.c (pthread_exit): Do not return 0.
+
+Sat Feb 20 16:03:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* dll.c (DLLMain): Expand TryEnterCriticalSection support test.
+
+	* mutex.c (pthread_mutex_trylock): The check for
+	ptw32_try_enter_critical_section == NULL should have been
+	removed long ago.
+
+Fri Feb 19 16:03:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* sync.c (pthread_join): Fix pthread_equal() test.
+
+	* mutex.c (pthread_mutex_trylock): Check mutex != NULL before
+	using it.
+
+Thu Feb 18 16:17:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* misc.c (pthread_equal): Fix inverted result.
+
+	* Makefile.in: Use libpthread32.a as the name of the DLL export
+	library instead of pthread.lib.
+
+	* condvar.c (pthread_cond_init): cv could have been used unitialised;
+	initialise.
+
+	* create.c (pthread_create): parms could have been used unitialised;
+	initialise.
+
+	* pthread.h (struct pthread_once_t_): Remove redefinition.
+
+Sat Feb 13 03:03:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.h (struct pthread_once_t_): Replaced.
+
+	* misc.c (pthread_once): Replace with John Bossom's version;
+	has lighter weight serialisation; fixes problem of not holding
+	competing threads until after the init_routine completes.
+
+Thu Feb 11 13:34:14 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* misc.c (CancelableWait): Change C++ exception throw.
+
+	* sync.c (pthread_join): Change FIXME comment - issue resolved.
+
+Wed Feb 10 12:49:11 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* configure: Various temporary changes.
+	- Kevin Ruland <Kevin.Ruland@anheuser-busch.com>
+
+	* README: Update.
+
+	* pthread.def (pthread_attr_getstackaddr): uncomment
+	(pthread_attr_setstackaddr): uncomment
+
+Fri Feb  5 13:42:30 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* semaphore.c: Comment format changes.
+
+Thu Feb  4 10:07:28 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* global.c: Remove ptw32_exception instantiation.
+
+	* cancel.c (pthread_testcancel): Change C++ exception throw.
+
+	* implement.h: Remove extern declaration.
+
+Wed Feb  3 13:04:44 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* cleanup.c: Rename ptw32_*_cleanup() to pthread_*_cleanup().
+
+	* pthread.def: Ditto.
+	
+	* pthread.h: Ditto.
+
+	* pthread.def (pthread_cleanup_push): Remove from export list;
+	the function is defined as a macro under all compilers.
+	(pthread_cleanup_pop): Ditto.
+
+	* pthread.h: Remove #if defined().
+
+Wed Feb  3 10:13:48 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* sync.c (pthread_join): Check for NULL value_ptr arg;
+	check for detached threads.
+
+Tue Feb  2 18:07:43 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* implement.h: Add #include <pthread.h>.
+	Change sem_t to ptw32_sem_t.
+
+	Various patches by Kevin Ruland <Kevin.Ruland@anheuser-busch.com>
+
+	* signal.c (pthread_sigmask): Add and modify casts.
+	Reverse LHS/RHS bitwise assignments.
+
+	* pthread.h: Remove #include <semaphore.h>.
+	(PTW32_ATTR_VALID): Add cast.
+	(struct pthread_t_): Add sigmask element.
+
+	* dll.c: Add "extern C" for DLLMain.
+	(DllMain): Add cast.
+
+	* create.c (pthread_create): Set sigmask in thread.
+
+	* condvar.c: Remove #include. Change sem_* to ptw32_sem_*.
+
+	* attr.c: Changed #include.
+
+	* Makefile.in: Additional targets and changes to build the library
+	as a DLL.
+
+Fri Jan 29 11:56:28 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* Makefile.in (OBJS): Add semaphore.o to list.
+
+	* semaphore.c (ptw32_sem_timedwait): Move from private.c.
+	Rename sem_* to ptw32_sem_*.
+
+	* pthread.h (pthread_cond_t): Change type of sem_t.
+	_POSIX_SEMAPHORES no longer defined.
+
+	* semaphore.h: Contents moved to implement.h.
+	Removed from source tree.
+
+	* implement.h: Add semaphore function prototypes and rename all
+	functions to prepend 'ptw32_'. They are
+	now private to the pthreads-win32 implementation.
+
+	* private.c: Change #warning.
+	Move ptw32_sem_timedwait() to semaphore.c.
+
+	* cleanup.c: Change #warning.
+
+	* misc.c: Remove #include <errno.h>
+
+	* pthread.def: Cleanup CVS merge conflicts.
+
+	* global.c: Ditto.
+
+	* ChangeLog: Ditto.
+
+	* cleanup.c: Ditto.
+
+Sun Jan 24 01:34:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* semaphore.c (sem_wait): Remove second arg to 
+	pthreadCancelableWait() call.
+
+Sat Jan 23 17:36:40 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.def: Add new functions to export list.
+
+	* pthread.h (PTHREAD_MUTEX_AUTO_CS_NP): New.
+	(PTHREAD_MUTEX_FORCE_CS_NP): New.
+
+	* README: Updated.
+
+Fri Jan 22 14:31:59 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* Makefile.in (CFLAGS): Remove -fhandle-exceptions. Not needed
+	with egcs. Add -g for debugging.
+
+	* create.c (pthread_create): Replace __stdcall with PT_STDCALL
+	macro. This is a hack and must be fixed.
+
+	* misc.c (CancelableWait): Remove redundant statement.
+
+	* mutex.c (pthread_mutexattr_init): Cast calloc return value.
+
+	* misc.c (CancelableWait): Add cast.
+	(pthread_self): Add cast.
+
+	* exit.c (pthread_exit): Add cast.
+
+	* condvar.c (pthread_condattr_init): Cast calloc return value.
+
+	* cleanup.c: Reorganise conditional compilation.
+
+	* attr.c (pthread_attr_init): Remove unused 'result'.
+	Cast malloc return value.
+
+	* private.c (ptw32_callUserDestroyRoutines): Redo conditional
+	compilation.
+
+	* misc.c (CancelableWait): C++ version uses 'throw'.
+
+	* cancel.c (pthread_testcancel): Ditto.
+
+	* implement.h (class ptw32_exception): Define for C++.
+
+	* pthread.h: Fix C, C++, and Win32 SEH condition compilation
+	mayhem around pthread_cleanup_* defines. C++ version now uses John
+	Bossom's cleanup handlers.
+	(pthread_attr_t): Make 'valid' unsigned.
+	Define '_timeb' as 'timeb' for Ming32.
+	Define PT_STDCALL as nothing for Mingw32. May be temporary.
+
+	* cancel.c (pthread_testcancel): Cast return value.
+
+Wed Jan 20 09:31:28 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.h (pthread_mutexattr_t): Changed to a pointer.
+
+	* mutex.c (pthread_mutex_init): Conditionally create Win32 mutex
+	- from John Bossom's implementation.
+	(pthread_mutex_destroy): Conditionally close Win32 mutex
+	- from John Bossom's implementation.
+	(pthread_mutexattr_init): Replaced by John Bossom's version.
+	(pthread_mutexattr_destroy): Ditto.
+	(pthread_mutexattr_getpshared): New function from John Bossom's
+	implementation.
+	(pthread_mutexattr_setpshared): New function from John Bossom's
+	implementation.
+
+Tue Jan 19 18:27:42 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* pthread.h (pthreadCancelableTimedWait): New prototype.
+	(pthreadCancelableWait): Remove second argument.
+
+	* misc.c (CancelableWait): New static function is 
+	pthreadCancelableWait() renamed.
+	(pthreadCancelableWait): Now just calls CancelableWait() with
+	INFINITE timeout.
+	(pthreadCancelableTimedWait): Just calls CancelableWait()
+	with passed in timeout.
+
+	* private.c (ptw32_sem_timedwait): 'abstime' arg really is
+	absolute time. Calculate relative time to wait from current
+	time before passing timeout to new routine 
+	pthreadCancelableTimedWait().
+	- Scott Lightner <scott@curriculum.com>
+
+Tue Jan 19 10:27:39 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.h (pthread_mutexattr_setforcecs_np): New prototype.
+	
+	* mutex.c (pthread_mutexattr_init): Init 'pshared' and 'forcecs'
+	attributes to 0.
+	(pthread_mutexattr_setforcecs_np): New function (not portable).
+
+	* pthread.h (pthread_mutex_t): 
+	Add 'mutex' element. Set to NULL in PTHREAD_MUTEX_INITIALIZER.
+	The pthread_mutex_*() routines will try to optimise performance
+	by choosing either mutexes or critical sections as the basis
+	for pthread mutexes for each indevidual mutex.
+	(pthread_mutexattr_t_): Add 'forcecs' element.
+	Some applications may choose to force use of critical sections
+	if they know that:-
+	     the mutex is PROCESS_PRIVATE and, 
+	         either the OS supports TryEnterCriticalSection() or
+	         pthread_mutex_trylock() will never be called on the mutex.
+	This attribute will be setable via a non-portable routine.
+
+	Note: We don't yet support PROCESS_SHARED mutexes, so the
+	implementation as it stands will default to Win32 mutexes only if
+	the OS doesn't support TryEnterCriticalSection. On Win9x, and early
+	versions of NT 'forcecs' will need to be set in order to get
+	critical section based mutexes.
+
+Sun Jan 17 12:01:26 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Init new 'staticinit'
+	value to '1' and existing 'valid' value to '1'.
+
+	* global.c (ptw32_mutex_test_init_lock): Add.
+
+	* implement.h (ptw32_mutex_test_init_lock.): Add extern.
+
+	* private.c (ptw32_processInitialize): Init critical section for
+	global lock used by _mutex_check_need_init().
+	(ptw32_processTerminate): Ditto (:s/Init/Destroy/).
+
+	* dll.c (dllMain): Move call to FreeLibrary() so that it is only
+	called once when the process detaches.
+
+	* mutex.c (_mutex_check_need_init): New static function to test
+	and init PTHREAD_MUTEX_INITIALIZER mutexes. Provides serialised
+	access to the internal state of the uninitialised static mutex. 
+	Called from pthread_mutex_trylock() and pthread_mutex_lock() which
+	do a quick unguarded test to check if _mutex_check_need_init()
+	needs to be called. This is safe as the test is conservative
+ 	and is repeated inside the guarded section of 
+	_mutex_check_need_init(). Thus in all calls except the first
+	calls to lock static mutexes, the additional overhead to lock any
+	mutex is a single memory fetch and test for zero.
+
+	* pthread.h (pthread_mutex_t_): Add 'staticinit' member. Mutexes
+	initialised by PTHREAD_MUTEX_INITIALIZER aren't really initialised
+	until the first attempt to lock it. Using the 'valid'
+	flag (which flags the mutex as destroyed or not) to record this
+	information would be messy. It is possible for a statically
+	initialised mutex such as this to be destroyed before ever being
+	used.
+
+	* mutex.c (pthread_mutex_trylock): Call _mutex_check_need_init()
+	to test/init PTHREAD_MUTEX_INITIALIZER mutexes.
+	(pthread_mutex_lock): Ditto.
+	(pthread_mutex_unlock): Add check to ensure we don't try to unlock
+	an unitialised static mutex.
+	(pthread_mutex_destroy): Add check to ensure we don't try to delete
+	a critical section that we never created. Allows us to destroy
+	a static mutex that has never been locked (and hence initialised).
+	(pthread_mutex_init): Set 'staticinit' flag to 0 for the new mutex.
+
+Sun Jan 17 12:01:26 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* private.c (ptw32_sem_timedwait): Move from semaphore.c.
+
+	* semaphore.c : Remove redundant #includes.
+	(ptw32_sem_timedwait): Move to private.c.
+	(sem_wait): Add missing abstime arg to pthreadCancelableWait() call.
+
+Fri Jan 15 23:38:05 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* condvar.c (cond_timedwait): Remove comment.
+
+Fri Jan 15 15:41:28 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* pthread.h: Add new 'abstime' arg to pthreadCancelableWait()
+	prototype.
+
+	* condvar.c (cond_timedwait): New generalised function called by
+	both pthread_cond_wait() and pthread_cond_timedwait(). This is
+	essentially pthread_cond_wait() renamed and modified to add the
+	'abstime' arg and call the new ptw32_sem_timedwait() instead of
+	sem_wait().
+	(pthread_cond_wait): Now just calls the internal static
+	function cond_timedwait() with an INFINITE wait.
+	(pthread_cond_timedwait): Now implemented. Calls the internal
+	static function cond_timedwait().
+
+	* implement.h (ptw32_sem_timedwait): New internal function
+	prototype.
+
+	* misc.c (pthreadCancelableWait): Added new 'abstime' argument
+	to allow shorter than INFINITE wait.
+
+	* semaphore.c (ptw32_sem_timedwait): New function for internal
+	use.  This is essentially sem_wait() modified to add the
+        'abstime' arg and call the modified (see above)
+        pthreadCancelableWait().
+
+Thu Jan 14 14:27:13 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* cleanup.c: Correct _cplusplus to __cplusplus wherever used.
+
+	* Makefile.in: Add CC=g++ and add -fhandle-exceptions to CFLAGS.
+	The derived Makefile will compile all units of the package as C++
+	so that those which include try/catch exception handling should work
+	properly. The package should compile ok if CC=gcc, however, exception
+	handling will not be included and thus thread cancellation, for
+ 	example, will not work.
+
+	* cleanup.c (ptw32_pop_cleanup): Add #warning to compile this
+ 	file as C++ if using a cygwin32 environment. Perhaps the whole package
+	should be compiled using g++ under cygwin.
+
+	* private.c (ptw32_threadStart): Change #error directive
+	into #warning and bracket for __CYGWIN__ and derivative compilers.
+
+Wed Jan 13 09:34:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* build.bat: Delete old binaries before compiling/linking.
+
+Tue Jan 12 09:58:38 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* dll.c: The Microsoft compiler pragmas probably are more
+	appropriately protected by _MSC_VER than by _WIN32.
+	- Tor Lillqvist <tml@iki.fi>.
+
+	* condvar.c (pthread_cond_timedwait): Fix function description
+	comments.
+
+	* pthread.h: Define ETIMEDOUT. This should be returned by
+	pthread_cond_timedwait which is not implemented yet as of
+	snapshot-1999-01-04-1305. It was implemented in the older version.
+	The Microsoft compiler pragmas probably are more appropriately
+	protected by _MSC_VER than by _WIN32.
+	- Tor Lillqvist <tml@iki.fi>.
+
+	* pthread.def: pthread_mutex_destroy was missing from the def file
+	- Tor Lillqvist <tml@iki.fi>.
+
+	* condvar.c (pthread_cond_broadcast): Ensure we only wait on threads
+	if there were any waiting on the condition.
+	I think pthread_cond_broadcast should do the WaitForSingleObject
+	only if cv->waiters > 0? Otherwise it seems to hang, at least in the
+	testg thread program from glib.
+	- Tor Lillqvist <tml@iki.fi>. 
+
+	* semaphore.c (sem_post): Correct typo in comment.
+
+Mon Jan 11 20:33:19 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.h: Re-arrange conditional compile of pthread_cleanup-*
+	macros.
+
+	* cleanup.c (ptw32_push_cleanup): Provide conditional 
+	compile of cleanup->prev.
+
+1999-01-11  Ben Elliston  <bje@cygnus.com>
+
+	* condvar.c (pthread_cond_init): Invert logic when testing the
+	return value from calloc().
+	- Tor Lillqvist <tml@iki.fi>.
+
+Sat Jan  9 14:32:08 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* implement.h: Compile-time switch for CYGWIN derived environments
+	to use CreateThread instead of _beginthreadex. Ditto for ExitThread.
+	Patch provided by Anders Norlander  <anorland@hem2.passagen.se>.
+
+Tue Jan  5 16:33:04 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* cleanup.c (ptw32_pop_cleanup): Add C++ version of __try/__except
+	block. Move trailing "}" out of #ifdef _WIN32 block left there by
+	(rpj's) mistake.
+
+	* private.c: Remove #include <errno.h> which is included by pthread.h.
+
+1998-12-11  Ben Elliston  <bje@toilet.to.cygnus.com>
+
+	* README: Update info about subscribing to the mailing list.
+
+Mon Jan  4 11:23:40 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* all: No code changes, just cleanup.
+	- remove #if 0 /* Pre Bossom */ enclosed code.
+	- Remove some redundant #includes.
+	* pthread.h: Update implemented/unimplemented routines list.
+	* Tag the bossom merge branch getting ready to merge back to main
+	trunk.
+
+Tue Dec 29 13:11:16 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* implement.h: Move the following struct definitions to pthread.h:
+	pthread_t_, pthread_attr_t_, pthread_mutex_t_, pthread_mutex_t_,
+	pthread_mutexattr_t_, pthread_key_t_, pthread_cond_t_,
+	pthread_condattr_t_, pthread_once_t_.
+
+	* pthread.h: Add "_" prefix to pthread_push_cleanup and 
+	pthread_pop_cleanup internal routines, and associated struct and
+	typedefs.
+
+	* buildlib.bat: Add compile command for semaphore.c
+
+	* pthread.def: Comment out pthread_atfork routine name. 
+	Now unimplemented.
+
+	* tsd.c (pthread_setspecific): Rename tkAssocCreate to
+	ptw32_tkAssocCreate.
+	(pthread_key_delete): Rename tkAssocDestroy to
+	ptw32_tkAssocDestroy.
+
+	* sync.c (pthread_join): Rename threadDestroy to ptw32_threadDestroy
+
+	* sched.c (is_attr): attr is now **attr (was *attr), so add extra
+	NULL pointer test.
+	(pthread_attr_setschedparam): Increase redirection for attr which is
+	now a **.
+	(pthread_attr_getschedparam): Ditto.
+	(pthread_setschedparam): Change thread validation and rename "thread"
+ 	Win32 thread Handle element name to match John Bossom's version.
+	(pthread_getschedparam): Ditto.
+
+	* private.c (ptw32_threadDestroy): Rename call to
+	callUserDestroyRoutines() as ptw32_callUserDestroyRoutines()
+
+	* misc.c: Add #include "implement.h".
+
+	* dll.c: Remove defined(KLUDGE) wrapped code.
+
+	* fork.c: Remove redefinition of ENOMEM.
+	Remove pthread_atfork() and fork() with #if 0/#endif.
+
+	* create.c (pthread_create): Rename threadStart and threadDestroy calls
+	to ptw32_threadStart and ptw32_threadDestroy.
+
+	* implement.h: Rename "detachedstate" to "detachstate".
+
+	* attr.c: Rename "detachedstate" to "detachstate".
+
+Mon Dec 28 09:54:39 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* semaphore.c: Initial version. From John Bossom's implementation.
+	* semaphore.h: Initial version. From John Bossom's implementation.
+
+Mon Dec 28 09:54:39 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.h (pthread_attr_t_): Change to *pthread_attr_t.
+
+	* attr.c (pthread_attr_setstacksize): Merge with John Bossom's version.
+	(pthread_attr_getstacksize): Merge with John Bossom's version.
+	(pthread_attr_setstackaddr): Merge with John Bossom's version.
+	(pthread_attr_getstackaddr): Merge with John Bossom's version.
+	(pthread_attr_init): Merge with John Bossom's version.
+	(pthread_attr_destroy): Merge with John Bossom's version.
+	(pthread_attr_getdetachstate): Merge with John Bossom's version.
+	(pthread_attr_setdetachstate): Merge with John Bossom's version.
+	(is_attr): attr is now **attr (was *attr), so add extra NULL pointer
+	test.
+
+	* implement.h (pthread_attr_t_): Add and rename elements in JEB's
+	version to correspond to original, so that it can be used with
+	original attr routines.
+
+	* pthread.h: Add #endif at end which was truncated in merging.
+
+Sun Dec 20 14:51:58 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* misc.c (pthreadCancelableWait): New function by John Bossom. Non-standard
+	but provides a hook that can be used to implement cancellation points in
+	applications that use this library.
+
+	* pthread.h (pthread_cleanup_pop): C++ (non-WIN32) version uses
+	try/catch to emulate John Bossom's WIN32 __try/__finally behaviour.
+	In the WIN32 version __finally block, add a test for AbnormalTermination otherwise
+	cleanup is only run if the cleanup_pop execute arg is non-zero. Cancellation
+	should cause the cleanup to run irrespective of the execute arg.
+
+	* condvar.c (pthread_condattr_init): Replaced by John Bossom's version.
+	(pthread_condattr_destroy): Replaced by John Bossom's version.
+	(pthread_condattr_getpshared): Replaced by John Bossom's version.
+	(pthread_condattr_setpshared): Replaced by John Bossom's version.
+	(pthread_cond_init): Replaced by John Bossom's version.
+	Fix comment (refered to mutex rather than condition variable).
+	(pthread_cond_destroy): Replaced by John Bossom's version.
+	(pthread_cond_wait): Replaced by John Bossom's version.
+	(pthread_cond_timedwait): Replaced by John Bossom's version.
+	(pthread_cond_signal): Replaced by John Bossom's version.
+	(pthread_cond_broadcast): Replaced by John Bossom's version.
+
+Thu Dec 17 19:10:46 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* tsd.c (pthread_key_create): Replaced by John Bossom's version.
+	(pthread_key_delete): Replaced by John Bossom's version.
+	(pthread_setspecific): Replaced by John Bossom's version.
+	(pthread_getspecific): Replaced by John Bossom's version.
+
+Mon Dec  7 09:44:40 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* cancel.c (pthread_setcancelstate): Replaced by John Bossom's version.
+	(pthread_setcanceltype): Replaced by John Bossom's version.
+	(pthread_testcancel): Replaced by John Bossom's version.
+	(pthread_cancel): Replaced by John Bossom's version.
+	
+	* exit.c (pthread_exit): Replaced by John Bossom's version.
+
+	* misc.c (pthread_self): Replaced by John Bossom's version.
+	(pthread_equal): Replaced by John Bossom's version.
+
+	* sync.c (pthread_detach): Replaced by John Bossom's version.
+	(pthread_join): Replaced by John Bossom's version.
+
+	* create.c (pthread_create): Replaced by John Bossom's version.
+
+	* private.c (ptw32_processInitialize): New by John Bossom.
+	(ptw32_processTerminate): Non-public function by John Bossom.
+	(ptw32_threadStart): Non-public function by John Bossom.
+ 	(ptw32_threadDestroy): Non-public function by John Bossom.
+	(ptw32_cleanupStack): Non-public function by John Bossom.
+	(ptw32_tkAssocCreate): Non-public function by John Bossom.
+	(ptw32_tkAssocDestroy): Non-public function by John Bossom.
+	(ptw32_callUserDestroyRoutines): Non-public function by John Bossom.
+
+	* implement.h: Added John Bossom's non-API structures and
+	declarations.
+
+	* dll.c (PthreadsEntryPoint): Cast return value of GetProcAddress
+	to resolve compile warning from MSVC.
+
+	* dll.c (DLLmain): Replaced by John Bossom's version.
+	* dll.c (PthreadsEntryPoint):
+	Re-applied Anders Norlander's patch:-
+	Initialize ptw32_try_enter_critical_section at startup
+	and release kernel32 handle when DLL is being unloaded.
+
+Sun Dec  6 21:54:35 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* buildlib.bat: Fix args to CL when building the .DLL
+
+	* cleanup.c (ptw32_destructor_run_all): Fix TSD key management.
+	This is a tidy-up before TSD and Thread management is completely
+	replaced by John Bossom's code.
+
+	* tsd.c (pthread_key_create): Fix TSD key management.
+
+	* global.c (ptw32_key_virgin_next): Initialise.
+
+	* build.bat: New DOS script to compile and link a pthreads app
+	using Microsoft's CL compiler linker.
+	* buildlib.bat: New DOS script to compile all the object files
+	and create pthread.lib and pthread.dll using Microsoft's CL
+	compiler linker.
+
+1998-12-05  Anders Norlander  <anorland@hem2.passagen.se>
+
+	* implement.h (ptw32_try_enter_critical_section): New extern
+	* dll.c (ptw32_try_enter_critical_section): New pointer to
+	TryEnterCriticalSection if it exists; otherwise NULL.
+	* dll.c (PthreadsEntryPoint):
+	Initialize ptw32_try_enter_critical_section at startup
+	and release kernel32 handle when DLL is being unloaded.
+	* mutex.c (pthread_mutex_trylock): Replaced check for NT with
+	a check if ptw32_try_enter_critical_section is valid
+	pointer to a function. Call ptw32_try_enter_critical_section
+	instead of TryEnterCriticalSection to avoid errors on Win95.
+
+Thu Dec 3 13:32:00 1998  Ross Johnson  <rpj@ise.canberra.edu.au>
+
+	* README: Correct cygwin32 compatibility statement.
+
+Sun Nov 15 21:24:06 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* cleanup.c (ptw32_destructor_run_all): Declare missing void * arg.
+	Fixup CVS merge conflicts.
+
+1998-10-30  Ben Elliston  <bje@cygnus.com>
+
+	* condvar.c (cond_wait): Fix semantic error. Test for equality
+	instead of making an assignment.
+
+Fri Oct 30 15:15:50 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* cleanup.c (ptw32_handler_push): Fixed bug appending new
+	handler to list reported by Peter Slacik
+	<Peter.Slacik@leibinger.freinet.de>.
+	(new_thread): Rename poorly named local variable to
+	"new_handler".
+
+Sat Oct 24 18:34:59 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* global.c: Add TSD key management array and index declarations.
+
+	* implement.h: Ditto for externs.
+
+Fri Oct 23 00:08:09 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* implement.h (PTW32_TSD_KEY_REUSE): Add enum.
+
+	* private.c (ptw32_delete_thread): Add call to
+	ptw32_destructor_run_all() to clean up the threads keys.
+
+	* cleanup.c (ptw32_destructor_run_all): Check for no more dirty
+	keys to run destructors on. Assume that the destructor call always
+	succeeds and set the key value to NULL.
+
+Thu Oct 22 21:44:44 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* tsd.c (pthread_setspecific): Add key management code.
+	(pthread_key_create): Ditto.
+	(pthread_key_delete): Ditto.
+
+	* implement.h (struct ptw32_tsd_key): Add status member.
+
+	* tsd.c: Add description of pthread_key_delete() from the
+	standard as a comment.
+
+Fri Oct 16 17:38:47 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* cleanup.c (ptw32_destructor_run_all): Fix and improve
+	stepping through the key table.
+
+Thu Oct 15 14:05:01 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* private.c (ptw32_new_thread): Remove init of destructorstack.
+	No longer an element of pthread_t.
+
+	* tsd.c (pthread_setspecific): Fix type declaration and cast.
+	(pthread_getspecific): Ditto.
+	(pthread_getspecific): Change error return value to NULL if key
+	is not in use.
+
+Thu Oct 15 11:53:21 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* global.c (ptw32_tsd_key_table): Fix declaration.
+
+	* implement.h(ptw32_TSD_keys_TlsIndex): Add missing extern.
+	(ptw32_tsd_mutex): Ditto.
+
+	* create.c (ptw32_start_call): Fix "keys" array declaration.
+	Add comment.
+
+	* tsd.c (pthread_setspecific): Fix type declaration and cast.
+	(pthread_getspecific): Ditto.
+
+	* cleanup.c (ptw32_destructor_run_all): Declare missing loop
+	counter.
+
+Wed Oct 14 21:09:24 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* private.c (ptw32_new_thread): Increment ptw32_threads_count.
+	(ptw32_delete_thread): Decrement ptw32_threads_count.
+	Remove some comments.
+
+	* exit.c (ptw32_exit): : Fix two pthread_mutex_lock() calls that
+ 	should have been pthread_mutex_unlock() calls.
+	(ptw32_vacuum): Remove call to ptw32_destructor_pop_all().
+
+	* create.c (pthread_create): Fix two pthread_mutex_lock() calls that
+ 	should have been pthread_mutex_unlock() calls.
+
+	* global.c (ptw32_tsd_mutex): Add mutex for TSD operations.
+
+	* tsd.c (pthread_key_create): Add critical section.
+	(pthread_setspecific): Ditto.
+	(pthread_getspecific): Ditto.
+	(pthread_key_delete): Ditto.
+
+	* sync.c (pthread_join): Fix two pthread_mutex_lock() calls that
+ 	should have been pthread_mutex_unlock() calls.
+
+Mon Oct 12 00:00:44 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* implement.h (ptw32_tsd_key_table): New.
+
+	* create.c (ptw32_start_call): Initialise per-thread TSD keys
+	to NULL.
+
+	* misc.c (pthread_once): Correct typo in comment.
+
+	* implement.h (ptw32_destructor_push): Remove.
+	(ptw32_destructor_pop): Remove.
+	(ptw32_destructor_run_all): Rename from ptw32_destructor_pop_all.
+	(PTW32_TSD_KEY_DELETED): Add enum.
+	(PTW32_TSD_KEY_INUSE): Add enum.
+
+	* cleanup.c (ptw32_destructor_push): Remove.
+	(ptw32_destructor_pop): Remove.
+	(ptw32_destructor_run_all): Totally revamped TSD.
+
+	* dll.c (ptw32_TSD_keys_TlsIndex): Initialise.
+
+	* tsd.c (pthread_setspecific): Totally revamped TSD.
+	(pthread_getspecific): Ditto.
+	(pthread_create): Ditto.
+	(pthread_delete): Ditto.
+
+Sun Oct 11 22:44:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* global.c (ptw32_tsd_key_table): Add new global.
+
+	* implement.h (ptw32_tsd_key_t and struct ptw32_tsd_key):
+	Add.
+	(struct _pthread): Remove destructorstack.
+
+	* cleanup.c (ptw32_destructor_run_all): Rename from
+ 	ptw32_destructor_pop_all. The key destructor stack was made
+ 	global rather than per-thread. No longer removes destructor nodes
+	from the stack. Comments updated.
+
+1998-10-06  Ben Elliston  <bje@cygnus.com>
+
+	* condvar.c (cond_wait): Use POSIX, not Win32 mutex calls.
+	(pthread_cond_broadcast): Likewise.
+	(pthread_cond_signal): Likewise.
+
+1998-10-05  Ben Elliston  <bje@cygnus.com>
+
+	* pthread.def: Update. Some functions aren't available yet, others
+	are macros in <pthread.h>.
+
+	* tests/join.c: Remove; useless.
+
+Mon Oct  5 14:25:08 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* pthread.def: New file for building the DLL.
+
+1998-10-05  Ben Elliston  <bje@cygnus.com>
+
+	* misc.c (pthread_equal): Correct inverted logic bug.
+	(pthread_once): Use the POSIX mutex primitives, not Win32. Remove
+	irrelevant FIXME comment.
+
+	* global.c (PTHREAD_MUTEX_INITIALIZER): Move to pthread.h.
+
+	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Define.
+	(pthread_mutex_t): Reimplement as a struct containing a valid
+	flag. If the flag is ever down upon entry to a mutex operation,
+	we call pthread_mutex_create() to initialise the object. This
+	fixes the problem of how to handle statically initialised objects
+	that can't call InitializeCriticalSection() due to their context.
+	(PTHREAD_ONCE_INIT): Define.
+
+	* mutex.c (pthread_mutex_init): Set valid flag.
+	(pthread_mutex_destroy): Clear valid flag.
+	(pthread_mutex_lock): Check and handle the valid flag.
+	(pthread_mutex_unlock): Likewise.
+	(pthread_mutex_trylock): Likewise.
+
+	* tests/mutex3.c: New file; test for the static initialisation
+	macro. Passes.
+
+	* tests/create1.c: New file; test pthread_create(). Passes.
+	
+	* tests/equal.c: Poor test; remove.
+	
+	* tests/equal1.c New file; test pthread_equal(). Passes.
+
+	* tests/once1.c: New file; test for pthread_once(). Passes.
+
+	* tests/self.c: Remove; rename to self1.c.
+
+	* tests/self1.c: This is the old self.c.
+
+	* tests/self2.c: New file. Test pthread_self() with a single
+	thread. Passes.
+
+	* tests/self3.c: New file. Test pthread_self() with a couple of
+	threads to ensure their thread IDs differ. Passes.
+	
+1998-10-04  Ben Elliston  <bje@cygnus.com>
+
+	* tests/mutex2.c: Test pthread_mutex_trylock(). Passes.
+
+	* tests/mutex1.c: New basic test for mutex functions (it passes).
+	(main): Eliminate warning.
+
+	* configure.in: Test for __stdcall, not _stdcall. Typo.
+
+	* configure: Regenerate.
+
+	* attr.c (pthread_attr_setstackaddr): Remove FIXME comment. Win32
+	does know about ENOSYS after all.
+	(pthread_attr_setstackaddr): Likewise.
+
+1998-10-03  Ben Elliston  <bje@cygnus.com>
+
+	* configure.in: Test for the `_stdcall' keyword.  Define `STDCALL'
+	to `_stdcall' if we have it, null otherwise.
+
+	* configure: Regenerate.
+
+	* acconfig.h (STDCALL): New define.
+
+	* config.h.in: Regenerate.
+
+	* create.c (ptw32_start_call): Add STDCALL prefix.
+	
+	* mutex.c (pthread_mutex_init): Correct function signature.
+
+	* attr.c (pthread_attr_init): Only zero out the `sigmask' member
+	if we have the sigset_t type.
+
+	* pthread.h: No need to include <unistd.h>.  It doesn't even exist
+	on Win32! Again, an artifact of cross-compilation.	
+	(pthread_sigmask): Only provide if we have the sigset_t type.
+
+	* process.h: Remove. This was a stand-in before we started doing
+	native compilation under Win32.
+
+	* pthread.h (pthread_mutex_init): Make `attr' argument const.
+
+1998-10-02  Ben Elliston  <bje@cygnus.com>
+
+	* COPYING: Remove.
+
+	* COPYING.LIB: Add. This library is under the LGPL.
+
+1998-09-13  Ben Elliston  <bje@cygnus.com>
+
+	* configure.in: Test for required system features.
+
+	* configure: Generate. 
+
+	* acconfig.h: New file.
+
+	* config.h.in: Generate.
+
+	* Makefile.in: Renamed from Makefile.
+
+	* COPYING: Import from a recent GNU package.
+
+	* config.guess: Likewise.
+
+	* config.sub: Likewise.
+
+	* install-sh: Likewise.
+
+	* config.h: Remove.  
+
+	* Makefile: Likewise.
+
+1998-09-12  Ben Elliston  <bje@cygnus.com>
+
+	* windows.h: No longer needed; remove.
+
+	* windows.c: Likewise.
+
+Sat Sep 12 20:09:24 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* windows.h: Remove error number definitions. These are in <errno.h>
+	
+	* tsd.c: Add comment explaining rationale for not building
+	POSIX TSD on top of Win32 TLS.
+
+1998-09-12  Ben Elliston  <bje@cygnus.com>
+
+	* {most}.c: Include <errno.h> to get POSIX error values.
+
+	* signal.c (pthread_sigmask): Only provide if HAVE_SIGSET_T is
+	defined.
+ 
+	* config.h: #undef features, don't #define them.  This will be
+	generated by autoconf very soon.
+	
+1998-08-11  Ben Elliston  <bje@cygnus.com>
+
+	* Makefile (LIB): Define.
+	(clean): Define target.
+	(all): Build a library not just the object files.
+
+	* pthread.h: Provide a definition for struct timespec if we don't
+	already have one.
+
+	* windows.c (TlsGetValue): Bug fix.
+	
+Thu Aug  6 15:19:22 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* misc.c (pthread_once): Fix arg 1 of EnterCriticalSection()
+ 	and LeaveCriticalSection() calls to pass address-of lock.
+
+	* fork.c (pthread_atfork): Typecast (void (*)(void *)) funcptr
+	in each ptw32_handler_push() call.
+
+	* exit.c (ptw32_exit): Fix attr arg in 
+	pthread_attr_getdetachstate() call.
+
+	* private.c (ptw32_new_thread): Typecast (HANDLE) NULL.
+	(ptw32_delete_thread): Ditto.
+
+	* implement.h: (PTW32_MAX_THREADS): Add define. This keeps
+	changing in an attempt to make thread administration data types
+	opaque and cleanup DLL startup.
+
+	* dll.c (PthreadsEntryPoint): 
+	(ptw32_virgins): Remove malloc() and free() calls.
+	(ptw32_reuse): Ditto.
+	(ptw32_win32handle_map): Ditto.
+	(ptw32_threads_mutex_table): Ditto.
+
+	* global.c (_POSIX_THREAD_THREADS_MAX): Initialise with 
+	PTW32_MAX_THREADS.
+	(ptw32_virgins): Ditto.
+	(ptw32_reuse): Ditto.
+	(ptw32_win32handle_map): Ditto.
+	(ptw32_threads_mutex_table): Ditto.
+
+	* create.c (pthread_create): Typecast (HANDLE) NULL.
+	Typecast (unsigned (*)(void *)) start_routine.
+
+	* condvar.c (pthread_cond_init): Add address-of operator & to
+	arg 1 of pthread_mutex_init() call.
+	(pthread_cond_destroy): Add address-of operator & to
+	arg 1 of pthread_mutex_destroy() call. 
+
+	* cleanup.c (ptw32_destructor_pop_all): Add (int) cast to 
+	pthread_getspecific() arg.
+	(ptw32_destructor_pop): Add (void *) cast to "if" conditional.
+	(ptw32_destructor_push): Add (void *) cast to
+	ptw32_handler_push() "key" arg.
+	(malloc.h): Add include.
+
+	* implement.h (ptw32_destructor_pop): Add prototype.
+
+	* tsd.c (implement.h): Add include.
+
+	* sync.c (pthread_join): Remove target_thread_mutex and it's
+	initialisation. Rename getdetachedstate to getdetachstate.
+	Remove unused variable "exitcode".
+	(pthread_detach): Remove target_thread_mutex and it's
+	initialisation. Rename getdetachedstate to getdetachstate.
+	Rename setdetachedstate to setdetachstate.
+
+	* signal.c (pthread_sigmask): Rename SIG_SET to SIG_SETMASK.
+	Cast "set" to (long *) in assignment to passify compiler warning.
+	Add address-of operator & to thread->attr.sigmask in memcpy() call
+	and assignment.
+	(pthread_sigmask): Add address-of operator & to thread->attr.sigmask
+	in memcpy() call and assignment.
+
+	* windows.h (THREAD_PRIORITY_ERROR_RETURN): Add.
+	(THREAD_PRIORITY_LOWEST): Add.
+	(THREAD_PRIORITY_HIGHEST): Add.
+
+	* sched.c (is_attr): Add function.
+	(implement.h): Add include.
+	(pthread_setschedparam): Rename all instances of "sched_policy"
+	to "sched_priority".
+	(pthread_getschedparam): Ditto.
+
+Tue Aug  4 16:57:58 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* private.c (ptw32_delete_thread): Fix typo. Add missing ';'.
+
+	* global.c (ptw32_virgins): Change types from pointer to 
+	array pointer.
+	(ptw32_reuse): Ditto.
+	(ptw32_win32handle_map): Ditto.
+	(ptw32_threads_mutex_table): Ditto.
+
+	* implement.h(ptw32_virgins): Change types from pointer to 
+	array pointer.
+	(ptw32_reuse): Ditto.
+	(ptw32_win32handle_map): Ditto.
+	(ptw32_threads_mutex_table): Ditto.
+
+	* private.c (ptw32_delete_thread): Fix "entry" should be "thread".
+
+	* misc.c (pthread_self): Add extern for ptw32_threadID_TlsIndex.
+
+	* global.c: Add comment.
+
+	* misc.c (pthread_once): Fix member -> dereferences.
+	Change ptw32_once_flag to once_control->flag in "if" test.
+
+Tue Aug  4 00:09:30 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* implement.h(ptw32_virgins): Add extern.
+	(ptw32_virgin_next): Ditto.
+	(ptw32_reuse): Ditto.
+	(ptw32_reuse_top): Ditto.
+	(ptw32_win32handle_map): Ditto.
+	(ptw32_threads_mutex_table): Ditto.
+
+	* global.c (ptw32_virgins): Changed from array to pointer.
+	Storage allocation for the array moved into dll.c.
+	(ptw32_reuse): Ditto.
+	(ptw32_win32handle_map): Ditto.
+	(ptw32_threads_mutex_table): Ditto.
+
+	* dll.c (PthreadsEntryPoint): Set up thread admin storage when
+	DLL is loaded.
+
+	* fork.c (pthread_atfork): Fix function pointer arg to all
+	ptw32_handler_push() calls. Change "arg" arg to NULL in child push.
+
+	* exit.c: Add windows.h and process.h includes.
+	(ptw32_exit): Add local detachstate declaration.
+	(ptw32_exit): Fix incorrect name for pthread_attr_getdetachstate().
+
+	* pthread.h (_POSIX_THREAD_ATTR_STACKSIZE): Move from global.c
+	(_POSIX_THREAD_ATTR_STACKADDR): Ditto.
+
+	* create.c (pthread_create): Fix #if should be #ifdef.
+	(ptw32_start_call): Remove usused variables.
+
+	* process.h: Create.
+
+	* windows.h: Move _beginthreadex and _endthreadex into
+	process.h
+
+Mon Aug  3 21:19:57 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* condvar.c (pthread_cond_init): Add NULL attr to
+	pthread_mutex_init() call - default attributes will be used.
+	(cond_wait): Fix typo.
+	(cond_wait): Fix typo - cv was ev.
+	(pthread_cond_broadcast): Fix two identical typos.
+
+	* cleanup.c (ptw32_destructor_pop_all): Remove _ prefix from
+	PTHREAD_DESTRUCTOR_ITERATIONS.
+
+	* pthread.h: Move _POSIX_* values into posix.h
+
+	* pthread.h: Fix typo in pthread_mutex_init() prototype.
+
+	* attr.c (pthread_attr_init): Fix error in priority member init.
+
+	* windows.h (THREAD_PRIORITY_NORMAL): Add.
+
+	* pthread.h (sched_param): Add missing ';' to struct definition. 
+
+	* attr.c (pthread_attr_init): Remove obsolete pthread_attr_t
+	member initialisation - cancelstate, canceltype, cancel_pending.
+	(is_attr): Make arg "attr" a const.
+
+	* implement.h (PTW32_HANDLER_POP_LIFO): Remove definition.
+	(PTW32_HANDLER_POP_FIFO): Ditto.
+	(PTW32_VALID): Add missing newline escape (\).
+	(ptw32_handler_node): Make element "next" a pointer.
+
+1998-08-02  Ben Elliston  <bje@cygnus.com>
+
+	* windows.h: Remove duplicate TlsSetValue() prototype.  Add 
+	TlsGetValue() prototype.
+	(FALSE): Define.
+	(TRUE): Likewise.
+	Add forgotten errno values.  Guard against multiple #includes.
+
+	* windows.c: New file.  Implement stubs for Win32 functions.
+
+	* Makefile (SRCS): Remove.  Not explicitly needed.
+	(CFLAGS): Add -Wall for all warnings with GCC.
+
+Sun Aug  2 19:03:42 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* config.h: Create. This is a temporary stand-in for autoconf yet
+	to be done.
+ 	(HAVE_SIGNAL_H): Add.
+
+	* pthread.h: Minor rearrangement for temporary config.h.
+
+Fri Jul 31 14:00:29 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* cleanup.c (ptw32_destructor_pop): Implement. Removes
+	destructors associated with a key without executing them.
+	(ptw32_destructor_pop_all): Add FIXME comment.
+
+	* tsd.c (pthread_key_delete): Add call to ptw32_destructor_pop().
+
+Fri Jul 31 00:05:45 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* tsd.c (pthread_key_create): Update to properly associate
+	the destructor routine with the key.
+	(pthread_key_delete): Add FIXME comment.
+
+	* exit.c (ptw32_vacuum): Add call to
+	ptw32_destructor_pop_all().
+
+	* implement.h (ptw32_handler_pop_all): Add prototype.
+	(ptw32_destructor_pop_all): Ditto.
+
+	* cleanup.c (ptw32_destructor_push): Implement. This is just a
+	call to ptw32_handler_push().
+	(ptw32_destructor_pop_all): Implement. This is significantly
+	different to ptw32_handler_pop_all().
+
+	* Makefile (SRCS): Create. Preliminary.
+
+	* windows.h: Create. Contains Win32 definitions for compile
+	testing. This is just a standin for the real one.
+
+	* pthread.h (SIG_UNBLOCK): Fix typo. Was SIG_BLOCK.
+	(windows.h): Add include. Required for CRITICAL_SECTION.
+	(pthread_cond_t): Move enum declaration outside of struct
+	definition.
+	(unistd.h): Add include - may be temporary.
+
+	* condvar.c (windows.h): Add include.
+
+	* implement.h (PTW32_THIS): Remove - no longer required.
+	(PTW32_STACK): Use pthread_self() instead of PTW32_THIS.
+
+Thu Jul 30 23:12:45 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* implement.h: Remove ptw32_find_entry() prototype.
+
+	* private.c: Extend comments.
+	Remove ptw32_find_entry() - no longer needed.
+
+	* create.c (ptw32_start_call): Add call to TlsSetValue() to
+	store the thread ID.
+
+	* dll.c (PthreadsEntryPoint): Implement. This is called
+	whenever a process loads the DLL. Used to initialise thread
+	local storage.
+
+	* implement.h: Add ptw32_threadID_TlsIndex.
+	Add ()s around PTW32_VALID expression.
+
+	* misc.c (pthread_self): Re-implement using Win32 TLS to store
+	the threads own ID.
+
+Wed Jul 29 11:39:03 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* private.c: Corrections in comments.
+	(ptw32_new_thread): Alter "if" flow to be more natural.
+
+	* cleanup.c (ptw32_handler_push): Same as below.
+
+	* create.c (pthread_create): Same as below.
+
+	* private.c (ptw32_new_thread): Rename "new" to "new_thread".
+	Since when has a C programmer been required to know C++?
+
+Tue Jul 28 14:04:29 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* implement.h: Add PTW32_VALID macro.
+
+	* sync.c (pthread_join): Modify to use the new thread
+	type and ptw32_delete_thread(). Rename "target" to "thread".
+	Remove extra local variable "target".
+	(pthread_detach): Ditto.
+
+	* signal.c (pthread_sigmask): Move init of "us" out of inner block.
+	Fix instance of "this" should have been "us". Rename "us" to "thread".
+
+	* sched.c (pthread_setschedparam): Modify to use the new thread
+	type.
+	(pthread_getschedparam): Ditto.
+
+	* private.c (ptw32_find_thread): Fix return type and arg.
+
+	* implement.h: Remove PTW32_YES and PTW32_NO.
+	(ptw32_new_thread): Add prototype.
+	(ptw32_find_thread): Ditto.
+	(ptw32_delete_thread): Ditto.
+	(ptw32_new_thread_entry): Remove prototype.
+	(ptw32_find_thread_entry): Ditto.
+	(ptw32_delete_thread_entry): Ditto.
+	(  PTW32_NEW, PTW32_INUSE, PTW32_EXITED, PTW32_REUSE):
+	Add.
+
+
+	* create.c (pthread_create): Minor rename "us" to "new" (I need
+	these cues but it doesn't stop me coming out with some major bugs
+	at times).
+	Load start_routine and arg into the thread so the wrapper can
+	call it.
+
+	* exit.c (pthread_exit): Fix pthread_this should be pthread_self.
+
+	* cancel.c (pthread_setcancelstate): Change
+ 	ptw32_threads_thread_t * to pthread_t and init with
+ 	pthread_this().
+	(pthread_setcanceltype): Ditto.
+
+	* exit.c (ptw32_exit): Add new pthread_t arg.
+	Rename ptw32_delete_thread_entry to ptw32_delete_thread.
+	Rename "us" to "thread".
+	(pthread_exit): Call ptw32_exit with added thread arg.
+
+	* create.c (ptw32_start_call): Insert missing ")".
+	Add "us" arg to ptw32_exit() call.
+	(pthread_create): Modify to use new thread allocation scheme.
+
+	* private.c: Added detailed explanation of the new thread
+	allocation scheme.
+	(ptw32_new_thread): Totally rewritten to use
+	new thread allocation scheme.
+	(ptw32_delete_thread): Ditto.
+	(ptw32_find_thread): Obsolete.
+
+Mon Jul 27 17:46:37 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* create.c (pthread_create): Start of rewrite. Not completed yet.
+
+	* private.c (ptw32_new_thread_entry): Start of rewrite. Not
+	complete.
+
+	* implement.h (ptw32_threads_thread): Rename, remove thread
+	member, add win32handle and ptstatus members.
+	(ptw32_t): Add.
+
+	* pthread.h: pthread_t is no longer mapped directly to a Win32
+	HANDLE type. This is so we can let the Win32 thread terminate and
+	reuse the HANDLE while pthreads holds it's own thread ID until
+	the last waiting join exits.
+
+Mon Jul 27 00:20:37 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* private.c (ptw32_delete_thread_entry): Destroy the thread
+ 	entry attribute object before deleting the thread entry itself.
+
+	* attr.c (pthread_attr_init): Initialise cancel_pending = FALSE.
+	(pthread_attr_setdetachstate): Rename "detached" to "detachedstate".
+	(pthread_attr_getdetachstate): Ditto.
+
+	* exit.c (ptw32_exit): Fix incorrect check for detachedstate.
+
+	* implement.h (ptw32_call_t): Remove env member. 
+
+Sun Jul 26 13:06:12 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* implement.h (ptw32_new_thread_entry): Fix prototype.
+	(ptw32_find_thread_entry): Ditto.
+	(ptw32_delete_thread_entry): Ditto.
+	(ptw32_exit): Add prototype.
+
+	* exit.c (ptw32_exit): New function. Called from pthread_exit()
+	and ptw32_start_call() to exit the thread. It allows an extra
+	argument which is the return code passed to _endthreadex().
+	(ptw32_exit): Move thread entry delete call from ptw32_vacuum()
+	into here. Add more explanation of thread entry deletion.
+	(ptw32_exit): Clarify comment.
+
+	* create.c (ptw32_start_call): Change pthread_exit() call to
+	ptw32_exit() call.
+
+	* exit.c (ptw32_vacuum): Add thread entry deletion code
+	moved from ptw32_start_call(). See next item.
+	(pthread_exit): Remove longjmp(). Add mutex lock around thread table
+	manipulation code. This routine now calls _enthreadex().
+
+	* create.c (ptw32_start_call): Remove setjmp() call and move
+	cleanup code out. Call pthread_exit(NULL) to terminate the thread.
+
+1998-07-26  Ben Elliston  <bje@cygnus.com>
+
+	* tsd.c (pthread_getspecific): Update comments.
+
+	* mutex.c (pthread_mutexattr_setpshared): Not supported; remove.
+	(pthread_mutexattr_getpshared): Likewise.
+
+	* pthread.h (pthread_mutexattr_setpshared): Remove prototype.
+	(pthread_mutexattr_getpshared): Likewise.
+
+Sun Jul 26 00:09:59 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* sync.c: Rename all instances of ptw32_count_mutex to
+	ptw32_table_mutex.
+
+	* implement.h: Rename ptw32_count_mutex to
+	ptw32_table_mutex.
+
+	* global.c: Rename ptw32_count_mutex to
+	ptw32_table_mutex.
+
+	* create.c (pthread_create): Add critical sections.
+	(ptw32_start_call): Rename ptw32_count_mutex to
+	ptw32_table_mutex.
+
+	* cancel.c (pthread_setcancelstate): Fix indirection bug and rename
+	"this" to "us".
+
+	* signal.c (pthread_sigmask): Rename "this" to "us" and fix some
+	minor syntax errors. Declare "us" and initialise it.
+
+	* sync.c (pthread_detach): Rename "this" to "target".
+
+	* pthread.h: Converting PTHREAD_* defines to alias the (const int)
+	values in global.c.
+
+	* global.c: Started converting PTHREAD_* defines to (const int) as
+ 	a part of making the eventual pthreads DLL binary compatible
+ 	through version changes.
+
+	* condvar.c (cond_wait): Add cancelation point. This applies the
+	point to both pthread_cond_wait() and pthread_cond_timedwait().
+
+	* exit.c (pthread_exit): Rename "this" to "us".
+
+	* implement.h: Add comment.
+
+	* sync.c (pthread_join): I've satisfied myself that pthread_detach()
+	does set the detached attribute in the thread entry attributes
+	to PTHREAD_CREATE_DETACHED. "if" conditions were changed to test
+	that attribute instead of a separate flag.
+
+	* create.c (pthread_create): Rename "this" to "us".
+	(pthread_create): cancelstate and canceltype are not attributes
+	so the copy to thread entry attribute storage was removed.
+	Only the thread itself can change it's cancelstate or canceltype,
+	ie. the thread must exist already.
+
+	* private.c (ptw32_delete_thread_entry): Mutex locks removed.
+	Mutexes must be applied at the caller level.
+	(ptw32_new_thread_entry): Ditto.
+	(ptw32_new_thread_entry): Init cancelstate, canceltype, and
+	cancel_pending to default values.
+	(ptw32_new_thread_entry): Rename "this" to "new".
+	(ptw32_find_thread_entry): Rename "this" to "entry".
+	(ptw32_delete_thread_entry): Rename "thread_entry" to "entry".
+
+	* create.c (ptw32_start_call): Mutexes changed to
+	ptw32_count_mutex. All access to the threads table entries is
+	under the one mutex. Otherwise chaos reigns.
+
+Sat Jul 25 23:16:51 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* implement.h (ptw32_threads_thread): Move cancelstate and
+ 	canceltype members out of pthread_attr_t into here.
+
+	* fork.c (fork): Add comment.
+
+1998-07-25  Ben Elliston  <bje@cygnus.com>
+
+	* fork.c (fork): Autoconfiscate.
+
+Sat Jul 25 00:00:13 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* create.c (ptw32_start_call): Set thread priority.  Ensure our
+ 	thread entry is removed from the thread table but only if
+ 	pthread_detach() was called and there are no waiting joins.
+	(pthread_create): Set detach flag in thread entry if the 
+	thread is created PTHREAD_CREATE_DETACHED.
+
+	* pthread.h (pthread_attr_t): Rename member "detachedstate".
+
+	* attr.c (pthread_attr_init): Rename attr members.
+
+	* exit.c (pthread_exit): Fix indirection mistake.
+
+	* implement.h (PTW32_THREADS_TABLE_INDEX): Add.
+
+	* exit.c (ptw32_vacuum): Fix incorrect args to
+	ptw32_handler_pop_all() calls.
+	Make thread entry removal conditional.
+
+	* sync.c (pthread_join): Add multiple join and async detach handling.
+
+	* implement.h (PTW32_THREADS_TABLE_INDEX): Add.
+
+	* global.c (ptw32_threads_mutex_table): Add.
+
+	* implement.h (ptw32_once_flag): Remove.
+	(ptw32_once_lock): Ditto.
+	(ptw32_threads_mutex_table): Add.
+
+	* global.c (ptw32_once_flag): Remove.
+	(ptw32_once_lock): Ditto.
+
+	* sync.c (pthread_join): Fix tests involving new return value
+	from ptw32_find_thread_entry().
+	(pthread_detach): Ditto.
+
+	* private.c (ptw32_find_thread_entry): Failure return code
+	changed from -1 to NULL.
+
+Fri Jul 24 23:09:33 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* create.c (pthread_create): Change . to -> in sigmask memcpy() args.
+
+	* pthread.h: (pthread_cancel): Add function prototype.
+	(pthread_testcancel): Ditto.
+
+1998-07-24  Ben Elliston  <bje@cygnus.com>
+
+	* pthread.h (pthread_condattr_t): Rename dummy structure member.
+	(pthread_mutexattr_t): Likewise.
+
+Fri Jul 24 21:13:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* cancel.c (pthread_cancel): Implement.
+	(pthread_testcancel): Implement.
+
+	* exit.c (pthread_exit): Add comment explaining the longjmp().
+
+	* implement.h (ptw32_threads_thread_t): New member cancelthread.
+	(PTW32_YES): Define.
+	(PTW32_NO): Define.
+	(RND_SIZEOF): Remove.
+
+	* create.c (pthread_create): Rename cancelability to cancelstate.
+
+	* pthread.h (pthread_attr_t): Rename cancelability to cancelstate.
+	(PTHREAD_CANCELED): Define.
+
+1998-07-24  Ben Elliston  <bje@cygnus.com>
+
+	* pthread.h (SIG_BLOCK): Define if not already defined.
+	(SIG_UNBLOCK): Likewise.
+	(SIG_SETMASK): Likewise.
+	(pthread_attr_t): Add signal mask member.
+	(pthread_sigmask): Add function prototype.
+
+	* signal.c (pthread_sigmask): Implement.
+
+	* create.c: #include <string.h> to get a prototype for memcpy().
+	(pthread_create): New threads inherit their creator's signal
+	mask.  Copy the signal mask to the new thread structure if we know
+	about signals.
+	
+Fri Jul 24 16:33:17 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* fork.c (pthread_atfork): Add all the necessary push calls.
+	Local implementation semantics:
+	If we get an ENOMEM at any time then ALL handlers
+	(including those from previous pthread_atfork() calls) will be
+	popped off each of the three atfork stacks before we return.
+	(fork): Add all the necessary pop calls. Add the thread cancellation
+	and join calls to the child fork.
+	Add #includes.
+
+	* implement.h: (ptw32_handler_push): Fix return type and stack arg
+	type in prototype.
+	(ptw32_handler_pop): Fix stack arg type in prototype.
+	(ptw32_handler_pop_all): Fix stack arg type in prototype.
+
+	* cleanup.c (ptw32_handler_push): Change return type to int and
+	return ENOMEM if malloc() fails.
+
+	* sync.c (pthread_detach): Use equality test, not assignment.
+
+	* create.c (ptw32_start_call): Add call to Win32 CloseHandle()
+	if thread is detached.
+
+1998-07-24  Ben Elliston  <bje@cygnus.com>
+
+	* sync.c (pthread_detach): Close the Win32 thread handle to
+	emulate detached (or daemon) threads.
+
+Fri Jul 24 03:00:25 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* sync.c (pthread_join): Save valueptr arg in joinvalueptr for
+	pthread_exit() to use.
+
+	* private.c (ptw32_new_thread_entry): Initialise joinvalueptr to
+	NULL.
+
+	* create.c (ptw32_start_call): Rewrite to facilitate joins.
+	pthread_exit() will do a longjmp() back to here. Does appropriate
+	cleanup and exit/return from the thread.
+	(pthread_create): _beginthreadex() now passes a pointer to our
+	thread table entry instead of just the call member of that entry.
+
+	* implement.h (ptw32_threads_thread): New member 
+	void ** joinvalueptr.
+	(ptw32_call_t): New member jmpbuf env.
+
+	* exit.c (pthread_exit): Major rewrite to handle joins and handing
+	value pointer to joining thread. Uses longjmp() back to 
+	ptw32_start_call().
+
+	* create.c (pthread_create): Ensure values of new attribute members
+	are copied to the thread attribute object.
+
+	* attr.c (pthread_attr_destroy):  Fix merge conflicts.
+	(pthread_attr_getdetachstate):  Fix merge conflicts.
+	(pthread_attr_setdetachstate):  Fix merge conflicts.
+
+	* pthread.h:  Fix merge conflicts.
+
+	* sync.c (pthread_join): Fix merge conflicts.
+
+Fri Jul 24 00:21:21 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* sync.c (pthread_join): Add check for valid and joinable
+	thread.
+	(pthread_detach): Implement. After checking for a valid and joinable
+	thread, it's still a no-op.
+
+	* private.c (ptw32_find_thread_entry): Bug prevented returning
+	an error value in some cases.
+
+	* attr.c (pthread_attr_setdetachedstate): Implement.
+	(pthread_attr_getdetachedstate): Implement.
+
+	* implement.h: Move more hidden definitions into here from
+	pthread.h.
+
+1998-07-24  Ben Elliston  <bje@cygnus.com>
+
+	* pthread.h (PTHREAD_CREATE_JOINABLE): Define.
+	(PTHREAD_CREATE_DETACHED): Likewise.
+	(pthread_attr_t): Add new structure member `detached'.
+	(pthread_attr_getdetachstate): Add function prototype.
+	(pthread_attr_setdetachstate): Likewise.
+
+	* sync.c (pthread_join): Return if the target thread is detached.
+
+	* attr.c (pthread_attr_init): Initialise cancelability and
+	canceltype structure members.
+	(pthread_attr_getdetachstate): Implement.
+	(pthread_attr_setdetachstate): Likewise.
+
+	* implement.h (PTW32_CANCEL_DEFAULTS): Remove.  Bit fields
+	proved to be too cumbersome.  Set the defaults in attr.c using the
+	public PTHREAD_CANCEL_* constants.
+
+	* cancel.c: New file.
+
+	* pthread.h (sched_param): Define this type.
+	(pthread_attr_getschedparam): Add function prototype.
+	(pthread_attr_setschedparam): Likewise.
+	(pthread_setcancelstate): Likewise.
+	(pthread_setcanceltype): Likewise.
+	(sched_get_priority_min): Likewise.
+	(sched_get_priority_max): Likewise.
+	(pthread_mutexattr_setprotocol): Remove; not supported.
+	(pthread_mutexattr_getprotocol): Likewise.
+	(pthread_mutexattr_setprioceiling): Likewise.
+	(pthread_mutexattr_getprioceiling): Likewise.
+	(pthread_attr_t): Add canceltype member.  Update comments.
+	(SCHED_OTHER): Define this scheduling policy constant.
+	(SCHED_FIFO): Likewise.
+	(SCHED_RR): Likewise.
+	(SCHED_MIN): Define the lowest possible value for this constant.
+	(SCHED_MAX): Likewise, the maximum possible value.
+	(PTHREAD_CANCEL_ASYNCHRONOUS): Redefine.
+	(PTHREAD_CANCEL_DEFERRED): Likewise.
+	
+	* sched.c: New file.
+	(pthread_setschedparam): Implement.
+	(pthread_getschedparam): Implement.
+	(sched_get_priority_max): Validate policy argument.
+	(sched_get_priority_min): Likewise.
+
+	* mutex.c (pthread_mutexattr_setprotocol): Remove; not supported.
+	(pthread_mutexattr_getprotocol): Likewise.
+	(pthread_mutexattr_setprioceiling): Likewise.
+	(pthread_mutexattr_getprioceiling): Likewise.
+
+Fri Jul 24 00:21:21 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* create.c (pthread_create): Arg to ptw32_new_thread_entry()
+	changed. See next entry. Move mutex locks out. Changes made yesterday
+	and today allow us to start the new thread running rather than
+	temporarily suspended.
+
+	* private.c (ptw32_new_thread_entry): ptw32_thread_table
+	was changed back to a table of thread structures rather than pointers.
+	As such we're trading storage for increaded speed. This routine
+	was modified to work with the new table. Mutex lock put in around
+	global data accesses.
+	(ptw32_find_thread_entry): Ditto
+	(ptw32_delete_thread_entry): Ditto
+
+Thu Jul 23 23:25:30 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* global.c: New. Global data objects declared here. These moved from
+	pthread.h.
+
+	* pthread.h: Move implementation hidden definitions into
+	implement.h.
+
+	* implement.h: Move implementation hidden definitions from
+	pthread.h. Add constants to index into the different handler stacks.
+
+	* cleanup.c (ptw32_handler_push): Simplify args. Restructure.
+	(ptw32_handler_pop): Simplify args. Restructure.
+	(ptw32_handler_pop_all): Simplify args. Restructure.
+
+Wed Jul 22 00:16:22 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* attr.c, implement.h, pthread.h, ChangeLog: Resolve CVS merge
+	conflicts.
+
+	* private.c (ptw32_find_thread_entry): Changes to return type
+	to support leaner ptw32_threads_table[] which now only stores
+	ptw32_thread_thread_t *.
+	(ptw32_new_thread_entry): Internal changes.
+	(ptw32_delete_thread_entry): Internal changes to avoid contention.
+ 	Calling routines changed accordingly.
+
+	* pthread.h: Modified cleanup macros to use new generic push and pop.
+	Added destructor and atfork stacks to ptw32_threads_thread_t.
+
+	* cleanup.c (ptw32_handler_push, ptw32_handler_pop,
+	ptw32_handler_pop_all): Renamed cleanup push and pop routines
+	and made generic to handle destructors and atfork handlers as
+	well.
+
+	* create.c (ptw32_start_call): New function is a wrapper for
+	all new threads. It allows us to do some cleanup when the thread
+	returns, ie. that is otherwise only done if the thread is cancelled.
+
+	* exit.c (ptw32_vacuum): New function contains code from 
+	pthread_exit() that we need in the new ptw32_start_call()
+	as well.
+
+	* implement.h: Various additions and minor changes.
+
+	* pthread.h: Various additions and minor changes.
+	Change cleanup handler macros to use generic handler push and pop
+	functions.
+
+	* attr.c: Minor mods to all functions.
+	(is_attr): Implemented missing function.
+
+	* create.c (pthread_create): More clean up.
+
+	* private.c (ptw32_find_thread_entry): Implement.
+	(ptw32_delete_thread_entry): Implement.
+	(ptw32_new_thread_entry): Implement.
+	These functions manipulate the implementations internal thread
+	table and are part of general code cleanup and modularisation.
+	They replace ptw32_getthreadindex() which was removed.
+
+	* exit.c (pthread_exit): Changed to use the new code above.
+
+	* pthread.h: Add cancelability constants. Update comments.
+
+1998-07-22  Ben Elliston  <bje@cygnus.com>
+
+	* attr.c (pthread_setstacksize): Update test of attr argument.
+	(pthread_getstacksize): Likewise.
+	(pthread_setstackaddr): Likewise.
+	(pthread_getstackaddr): Likewise.
+	(pthread_attr_init): No need to allocate any storage.
+	(pthread_attr_destroy): No need to free any storage.
+
+	* mutex.c (is_attr): Not likely to be needed; remove.
+	(remove_attr): Likewise.
+	(insert_attr): Likewise.
+
+	* implement.h (ptw32_mutexattr_t): Moved to a public definition
+	in pthread.h.  There was little gain in hiding these details.
+	(ptw32_condattr_t): Likewise.
+	(ptw32_attr_t): Likewise.
+
+	* pthread.h (pthread_atfork): Add function prototype.
+	(pthread_attr_t): Moved here from implement.h.
+
+	* fork.c (pthread_atfork): Preliminary implementation.
+	(ptw32_fork): Likewise.
+
+Wed Jul 22 00:16:22 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* cleanup.c (ptw32_cleanup_push): Implement.
+	(ptw32_cleanup_pop): Implement.
+	(ptw32_do_cancellation): Implement.
+	These are private to the implementation. The real cleanup functions
+	are macros. See below.
+
+	* pthread.h (pthread_cleanup_push): Implement as a macro.
+	(pthread_cleanup_pop): Implement as a macro.
+	Because these are macros which start and end a block, the POSIX scoping
+	requirement is observed. See the comment in the file.
+
+	* exit.c (pthread_exit): Refine the code.
+
+	* create.c (pthread_create): Code cleanup.
+
+	* implement.h (RND_SIZEOF): Add RND_SIZEOF(T) to round sizeof(T)
+	up to multiple of DWORD.
+	Add function prototypes.
+
+	* private.c (ptw32_getthreadindex): "*thread" should have been 
+	"thread". Detect empty slot fail condition.
+
+1998-07-20  Ben Elliston  <bje@cygnus.com>
+
+	* misc.c (pthread_once): Implement.  Don't use a per-application
+	flag and mutex--make `pthread_once_t' contain these elements in
+	their structure.  The earlier version had incorrect semantics.
+	
+	* pthread.h (ptw32_once_flag): Add new variable.  Remove.
+	(ptw32_once_lock): Add new mutex lock to ensure integrity of
+	access to ptw32_once_flag.  Remove.
+	(pthread_once): Add function prototype.
+	(pthread_once_t): Define this type.
+	
+Mon Jul 20 02:31:05 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* private.c (ptw32_getthreadindex): Implement.
+
+	* pthread.h: Add application static data dependent on
+	_PTHREADS_BUILD_DLL define. This is needed to avoid allocating
+	non-sharable static data within the pthread DLL.
+
+	* implement.h: Add ptw32_cleanup_stack_t, ptw32_cleanup_node_t
+	and PTW32_HASH_INDEX.
+
+	* exit.c (pthread_exit): Begin work on cleanup and de-allocate
+	thread-private storage.
+
+	* create.c (pthread_create): Add thread to thread table.
+	Keep a thread-private copy of the attributes with default values
+	filled in when necessary. Same for the cleanup stack. Make 
+	pthread_create C run-time library friendly by using _beginthreadex()
+	instead of CreateThread(). Fix error returns.
+
+Sun Jul 19 16:26:23 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* implement.h: Rename pthreads_thread_count to ptw32_threads_count.
+	Create ptw32_threads_thread_t struct to keep thread specific data.
+
+	* create.c: Rename pthreads_thread_count to ptw32_threads_count.
+	(pthread_create): Handle errors from CreateThread().
+
+1998-07-19  Ben Elliston  <bje@cygnus.com>
+
+	* condvar.c (pthread_cond_wait): Generalise.  Moved from here ..
+	(cond_wait): To here.
+	(pthread_cond_timedwait): Implement; use generalised cond_wait().
+
+	* pthread.h (pthread_key_t): Define this type.
+	(pthread_key_create): Add function prototype.
+	(pthread_setspecific): Likewise.
+	(pthread_getspecific): Likwise.
+	(pthread_key_delete): Likewise.
+
+	* tsd.c (pthread_key_create): Implement.
+	(pthread_setspecific): Likewise.
+	(pthread_getspecific): Likewise.
+	(pthread_key_delete): Likewise.
+
+	* mutex.c (pthread_mutex_trylock): Return ENOSYS if this function
+	is called on a Win32 platform which is not Windows NT.
+
+1998-07-18  Ben Elliston  <bje@cygnus.com>
+
+	* condvar.c (pthread_condattr_init): Do not attempt to malloc any
+	storage; none is needed now that condattr_t is an empty struct.
+	(pthread_condattr_destory): Likewise; do not free storage.
+	(pthread_condattr_setpshared): No longer supported; return ENOSYS.
+	(pthread_condattr_getpshared): Likewise.
+	(pthread_cond_init): Implement with help from Douglas Schmidt.
+	Remember to initialise the cv's internal mutex.
+	(pthread_cond_wait): Likewise.
+	(pthread_cond_signal): Likewise.
+	(pthread_cond_broadcast): Likewise.
+	(pthread_cond_timedwait): Preliminary implementation, but I need
+	to see some API documentation for `WaitForMultipleObject'.
+	(pthread_destory): Implement.
+
+	* pthread.h (pthread_cond_init): Add function protoype.
+	(pthread_cond_broadcast): Likewise.
+	(pthread_cond_signal): Likewise.
+	(pthread_cond_timedwait): Likewise.
+	(pthread_cond_wait): Likewise.
+	(pthread_cond_destroy): Likewise.
+	(pthread_cond_t): Define this type.  Fix for u_int.  Do not assume
+	that the mutex contained withing the pthread_cond_t structure will
+	be a critical section.  Use our new POSIX type!
+
+	* implement.h (ptw32_condattr_t): Remove shared attribute.
+
+1998-07-17  Ben Elliston  <bje@cygnus.com>
+
+	* pthread.h (PTHREADS_PROCESS_PRIVATE): Remove.
+	(PTHREAD_PROCESS_SHARED): Likewise.  No support for mutexes shared
+	across processes for now.
+	(pthread_mutex_t): Use a Win32 CRITICAL_SECTION type for better
+	performance.
+	
+	* implement.h (ptw32_mutexattr_t): Remove shared attribute.
+	
+	* mutex.c (pthread_mutexattr_setpshared): This optional function
+	is no longer supported, since we want to implement POSIX mutex
+	variables using the much more efficient Win32 critical section
+	primitives.  Critical section objects in Win32 cannot be shared
+	between processes.
+	(pthread_mutexattr_getpshared): Likewise.
+	(pthread_mutexattr_init): No need to malloc any storage; the
+	attributes structure is now empty.
+	(pthread_mutexattr_destroy): This is now a nop.
+	(pthread_mutex_init): Use InitializeCriticalSection().
+	(pthread_mutex_destroy): Use DeleteCriticalSection().
+	(pthread_mutex_lock): Use EnterCriticalSection().
+	(pthread_mutex_trylock): Use TryEnterCriticalSection().  This is
+	not supported by Windows 9x, but trylock is a hack anyway, IMHO.
+	(pthread_mutex_unlock): Use LeaveCriticalSection().
+
+1998-07-14  Ben Elliston  <bje@cygnus.com>
+
+	* attr.c (pthread_attr_setstacksize): Implement.
+	(pthread_attr_getstacksize): Likewise.
+	(pthread_attr_setstackaddr): Likewise.
+	(pthread_attr_getstackaddr): Likewise.
+	(pthread_attr_init): Likewise.
+	(pthread_attr_destroy): Likewise.
+	
+	* condvar.c (pthread_condattr_init): Add `_cond' to function name.
+
+	* mutex.c (pthread_mutex_lock): Add `_mutex' to function name.
+	(pthread_mutex_trylock): Likewise.
+	(pthread_mutex_unlock): Likewise.
+
+	* pthread.h (pthread_condattr_setpshared): Fix typo.
+	(pthread_attr_init): Add function prototype.
+	(pthread_attr_destroy): Likewise.
+	(pthread_attr_setstacksize): Likewise.
+	(pthread_attr_getstacksize): Likewise.
+	(pthread_attr_setstackaddr): Likewise.
+	(pthread_attr_getstackaddr): Likewise.
+	
+Mon Jul 13 01:09:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* implement.h: Wrap in #ifndef _IMPLEMENT_H
+
+	* create.c (pthread_create): Map stacksize attr to Win32.
+
+	* mutex.c: Include implement.h
+
+1998-07-13  Ben Elliston  <bje@cygnus.com>
+
+	* condvar.c (pthread_condattr_init): Implement.
+	(pthread_condattr_destroy): Likewise.
+	(pthread_condattr_setpshared): Likewise.
+	(pthread_condattr_getpshared): Likewise.
+	
+	* implement.h (PTHREAD_THREADS_MAX): Remove trailing semicolon.
+	(PTHREAD_STACK_MIN): Specify; needs confirming.
+	(ptw32_attr_t): Define this type.
+	(ptw32_condattr_t): Likewise.
+
+	* pthread.h (pthread_mutex_t): Define this type.
+	(pthread_condattr_t): Likewise.
+	(pthread_mutex_destroy): Add function prototype.
+	(pthread_lock): Likewise.
+	(pthread_trylock): Likewise.
+	(pthread_unlock): Likewise.
+	(pthread_condattr_init): Likewise.
+	(pthread_condattr_destroy): Likewise.
+	(pthread_condattr_setpshared): Likewise.
+	(pthread_condattr_getpshared): Likewise.
+
+	* mutex.c (pthread_mutex_init): Implement.
+	(pthread_mutex_destroy): Likewise.
+	(pthread_lock): Likewise.
+	(pthread_trylock): Likewise.
+	(pthread_unlock): Likewise.
+
+1998-07-12  Ben Elliston  <bje@cygnus.com>
+
+	* implement.h (ptw32_mutexattr_t): Define this implementation
+	internal type.  Application programmers only see a mutex attribute
+	object as a void pointer.
+
+	* pthread.h (pthread_mutexattr_t): Define this type.
+	(pthread_mutexattr_init): Add function prototype.
+	(pthread_mutexattr_destroy): Likewise.
+	(pthread_mutexattr_setpshared): Likewise.
+	(pthread_mutexattr_getpshared): Likewise.
+	(pthread_mutexattr_setprotocol): Likewise.
+	(pthread_mutexattr_getprotocol): Likewise.
+	(pthread_mutexattr_setprioceiling): Likewise.
+	(pthread_mutexattr_getprioceiling): Likewise.
+	(PTHREAD_PROCESS_PRIVATE): Define.
+	(PTHREAD_PROCESS_SHARED): Define.
+
+	* mutex.c (pthread_mutexattr_init): Implement.
+	(pthread_mutexattr_destroy): Implement.
+	(pthread_mutexattr_setprotocol): Implement.
+	(pthread_mutexattr_getprotocol): Likewise.
+	(pthread_mutexattr_setprioceiling): Likewise.
+	(pthread_mutexattr_getprioceiling): Likewise.
+	(pthread_mutexattr_setpshared): Likewise.
+	(pthread_mutexattr_getpshared): Likewise.
+	(insert_attr): New function; very preliminary implementation!
+	(is_attr): Likewise.
+	(remove_attr): Likewise.
+	
+Sat Jul 11 14:48:54 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* implement.h: Preliminary implementation specific defines.
+
+	* create.c (pthread_create): Preliminary implementation.
+
+1998-07-11  Ben Elliston  <bje@cygnus.com>
+
+	* sync.c (pthread_join): Implement.
+
+	* misc.c (pthread_equal): Likewise.
+	
+	* pthread.h (pthread_join): Add function prototype.
+	(pthread_equal): Likewise.
+	
+1998-07-10  Ben Elliston  <bje@cygnus.com>
+
+	* misc.c (pthread_self): Implement.
+
+	* exit.c (pthread_exit): Implement.
+
+	* pthread.h (pthread_exit): Add function prototype.
+	(pthread_self): Likewise.
+	(pthread_t): Define this type.
+
+1998-07-09  Ben Elliston  <bje@cygnus.com>
+
+	* create.c (pthread_create): A dummy stub right now.
+
+	* pthread.h (pthread_create): Add function prototype.
diff --git a/Nmakefile b/Nmakefile
index 49c2766..f5e5a5d 100644
--- a/Nmakefile
+++ b/Nmakefile
@@ -3,7 +3,7 @@
  */
 
 VERSION = -
-CCFLAGS = -g $(CC.DLL)
+CCFLAGS = -V -g $(CC.DLL)
 PTW32_BUILD	== 1
 _MT		== 1
 _timeb		== timeb
diff --git a/Nmakefile.tests b/Nmakefile.tests
index 5ba32ff..4829938 100644
--- a/Nmakefile.tests
+++ b/Nmakefile.tests
@@ -78,15 +78,21 @@ cleanup3::	cleanup3.c
 exception1::	exception1.c
 exception2::	exception2.c
 exception3::	exception3.c
+priority1::	priority1.c
+priority2::	priority2.c
+inherit1::	inherit1.c
+benchtest1::	benchtest1.c
+benchtest2::	benchtest2.c
 
 loadfree:	:test:
+mutex5		:test: loadfree
 mutex1		:test: loadfree
 mutex2		:test: loadfree
 exit1		:test: loadfree
 condvar1	:test: loadfree
 self1		:test: loadfree
 condvar2	:test:	condvar1
-create1.	:test:	mutex2
+create1 	:test:	mutex2
 cancel1		:test:	create1
 cancel2		:test:	cancel1
 mutex3		:test:	create1
@@ -124,8 +130,12 @@ cleanup0	:test:	cancel5
 cleanup1	:test:	cleanup0
 cleanup2	:test:	cleanup1
 cleanup3	:test:	cleanup2
+priority1	:test:  join1
+priority2	:test:  priority1
+inherit1	:test:  join1
 exception1	:test:	cancel4
 exception2	:test:	exception1
+benchtest1	:test:  mutex3
+benchtest2	:test:  benchtest1
 exception3	:test:	exception2
-tryentercs	:test:
-tryentercs2	:test:
+
diff --git a/attr.c b/attr.c
index 0f2f2f1..c56833c 100644
--- a/attr.c
+++ b/attr.c
@@ -346,8 +346,13 @@ pthread_attr_init(pthread_attr_t *attr)
   memset(&(attr_result->sigmask), 0, sizeof(sigset_t));
 #endif /* HAVE_SIGSET_T */
 
-  /* Priority uses Win32 priority values. */
-  attr_result->priority = THREAD_PRIORITY_NORMAL;
+  /*
+   * Win32 sets new threads to THREAD_PRIORITY_NORMAL and
+   * not to that of the parent thread. We choose to default to
+   * this arrangement.
+   */
+  attr_result->param.sched_priority = THREAD_PRIORITY_NORMAL;
+  attr_result->inheritsched = PTHREAD_EXPLICIT_SCHED;
 
   attr_result->valid = PTW32_ATTR_VALID;
 
@@ -498,6 +503,7 @@ pthread_attr_setdetachstate(pthread_attr_t *attr,
   return 0;
 }
 
+
 int
 pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
 {
diff --git a/create.c b/create.c
index b8fd864..d36300d 100644
--- a/create.c
+++ b/create.c
@@ -84,10 +84,10 @@ pthread_create (pthread_t * tid,
 
   thread->cancelEvent =
     CreateEvent (
-		  0,
-		  (int) TRUE,	/* manualReset  */
-		  (int) FALSE,	/* setSignaled  */
-		  NULL);
+                 0,
+                 (int) TRUE,	/* manualReset  */
+                 (int) FALSE,	/* setSignaled  */
+                 NULL);
 
   if (thread->cancelEvent == NULL)
     {
@@ -142,16 +142,34 @@ pthread_create (pthread_t * tid,
 
   thread->threadH = threadH = (HANDLE)
     _beginthreadex (
-		     (void *) NULL,	/* No security info             */
-		     (unsigned) stackSize,	/* default stack size   */
-		     ptw32_threadStart,
-		     parms,
-		     (unsigned) CREATE_SUSPENDED,
-		     (unsigned *) &(thread->thread));
-
-  if (threadH != 0 && run)
+                    (void *) NULL,	/* No security info             */
+                    (unsigned) stackSize,	/* default stack size   */
+                    ptw32_threadStart,
+                    parms,
+                    (unsigned) CREATE_SUSPENDED,
+                    (unsigned *) &(thread->thread));
+
+  if (threadH != 0)
     {
-      ResumeThread(threadH);
+      /*
+       * PTHREAD_EXPLICIT_SCHED is the default because Win32 threads
+       * don't inherit their creator's priority. They are started with
+       * THREAD_PRIORITY_NORMAL (win32 value). The result of not supplying
+       * an 'attr' arg to pthread_create() is equivalent to defaulting to
+       * PTHREAD_EXPLICIT_SCHED and priority THREAD_PRIORITY_NORMAL.
+       */
+      if (attr != NULL && *attr != NULL)
+        {
+          (void) SetThreadPriority(thread->threadH,
+                                   PTHREAD_INHERIT_SCHED == (*attr)->inheritsched
+                                   ? GetThreadPriority(GetCurrentThread())
+                                   : (*attr)->param.sched_priority );
+        }
+
+      if (run)
+        {
+          ResumeThread(threadH);
+        }
     }
 
 #else /* __MINGW32__ && ! __MSVCRT__ */
@@ -164,9 +182,9 @@ pthread_create (pthread_t * tid,
 
   thread->threadH = threadH = (HANDLE)
     _beginthread (
-		   ptw32_threadStart,
-		   (unsigned) stackSize,	/* default stack size   */
-		   parms);
+                  ptw32_threadStart,
+                  (unsigned) stackSize,	/* default stack size   */
+                  parms);
 
   /*
    * Make the return code match _beginthreadex's.
@@ -175,14 +193,32 @@ pthread_create (pthread_t * tid,
     {
       thread->threadH = threadH = 0;
     }
-  else if (! run)
+  else
     {
-      /* 
-       * beginthread does not allow for create flags, so we do it now.
-       * Note that beginthread itself creates the thread in SUSPENDED
-       * mode, and then calls ResumeThread to start it.
+      if (! run)
+        {
+          /* 
+           * beginthread does not allow for create flags, so we do it now.
+           * Note that beginthread itself creates the thread in SUSPENDED
+           * mode, and then calls ResumeThread to start it.
+           */
+          SuspendThread (threadH);
+        }
+      
+      /*
+       * PTHREAD_EXPLICIT_SCHED is the default because Win32 threads
+       * don't inherit their creator's priority. They are started with
+       * THREAD_PRIORITY_NORMAL (win32 value). The result of not supplying
+       * an 'attr' arg to pthread_create() is equivalent to defaulting to
+       * PTHREAD_EXPLICIT_SCHED and priority THREAD_PRIORITY_NORMAL.
        */
-      SuspendThread (threadH);
+      if (attr != NULL && *attr != NULL)
+        {
+          (void) SetThreadPriority(thread->threadH,
+                                   PTHREAD_INHERIT_SCHED == (*attr)->inheritsched
+                                   ? GetThreadPriority(GetCurrentThread())
+                                   : (*attr)->param.sched_priority );
+        }
     }
 
   (void) pthread_mutex_unlock(&thread->cancelLock);
diff --git a/implement.h b/implement.h
index da094c8..e2acba3 100644
--- a/implement.h
+++ b/implement.h
@@ -35,8 +35,9 @@
 #include <limits.h>
 #endif
 
-/* changed include from <semaphore.h> to use local file during development */
+/* use local include files during development */
 #include "semaphore.h"
+#include "sched.h"
 
 typedef enum {
   /*
@@ -107,7 +108,8 @@ struct pthread_attr_t_ {
   void *stackaddr;
   size_t stacksize;
   int detachstate;
-  int priority;
+  struct sched_param param;
+  int inheritsched;
 #if HAVE_SIGSET_T
   sigset_t sigmask;
 #endif /* HAVE_SIGSET_T */
@@ -319,7 +321,12 @@ struct ThreadKeyAssoc {
 #define PTW32_EPS_EXIT        		(1)
 #define PTW32_EPS_CANCEL       		(2)
 
-#define PTW32_MUTEX_LOCK_IDX_INIT	(-1)
+/* Mutex constants */
+enum {
+  PTW32_MUTEX_LOCK_IDX_INIT	= -1,
+  PTW32_MUTEX_OWNER_ANONYMOUS = 1
+};
+
 
 /* Declared in global.c */
 extern int ptw32_processInitialized;
diff --git a/mutex.c b/mutex.c
index b1e2693..0396e5f 100644
--- a/mutex.c
+++ b/mutex.c
@@ -180,8 +180,14 @@ pthread_mutex_destroy(pthread_mutex_t *mutex)
        * The mutex type may not be RECURSIVE therefore trylock may return EBUSY if
        * we already own the mutex. Here we are assuming that it's OK to destroy
        * a mutex that we own and have locked recursively. Is this correct?
+       *
+       * For FAST mutexes we record the owner as ANONYMOUS for speed. In this
+       * case we assume that the thread calling pthread_mutex_destroy() is the
+       * owner, if the mutex is owned at all.
        */
-      if (result == 0 || pthread_equal( mx->ownerThread, pthread_self() ) )
+      if (result == 0
+          || mx->ownerThread == (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS
+          || pthread_equal( mx->ownerThread, pthread_self() ) )
         {
           /*
            * FIXME!!!
@@ -634,7 +640,9 @@ pthread_mutex_lock(pthread_mutex_t *mutex)
   if( 0 == InterlockedIncrement( &mx->lock_idx ) )
     {
       mx->recursive_count = 1;
-      mx->ownerThread = pthread_self();
+      mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP
+                         ? pthread_self()
+                         : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS);
     }
   else
     {
@@ -656,7 +664,9 @@ pthread_mutex_lock(pthread_mutex_t *mutex)
         {
           WaitForSingleObject( mx->wait_sema, INFINITE );
           mx->recursive_count = 1;
-          mx->ownerThread = pthread_self();
+          mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP
+                             ? pthread_self()
+                             : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS);
         }
     }
 
@@ -683,10 +693,11 @@ pthread_mutex_unlock(pthread_mutex_t *mutex)
    */
   if (mx != (pthread_mutex_t) PTW32_OBJECT_AUTO_INIT)
     {
-      if (pthread_equal(mx->ownerThread, pthread_self()))
+      if (mx->ownerThread == (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS
+          || pthread_equal(mx->ownerThread, pthread_self()))
 	{
-          if( mx->kind != PTHREAD_MUTEX_RECURSIVE_NP ||
-              0 == --mx->recursive_count )
+          if( mx->kind != PTHREAD_MUTEX_RECURSIVE_NP
+              || 0 == --mx->recursive_count )
 	    {
 	      mx->ownerThread = NULL;
 	      
@@ -748,7 +759,9 @@ pthread_mutex_trylock(pthread_mutex_t *mutex)
           if( 0 == InterlockedIncrement( &mx->lock_idx ) )
 	    {
               mx->recursive_count = 1;
-              mx->ownerThread = pthread_self();
+              mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP
+                                 ? pthread_self()
+                                 : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS);
 	    }
           else
             {
diff --git a/pthread.def b/pthread.def
index 15383aa..2915077 100644
--- a/pthread.def
+++ b/pthread.def
@@ -1,5 +1,5 @@
 ; pthread.def
-; Last updated: $Date: 2001/06/05 07:48:19 $
+; Last updated: $Date: 2001/07/01 13:23:10 $
 
 ; Currently unimplemented functions are commented out.
 
@@ -10,23 +10,23 @@ ptw32_processInitialize
 ;pthread_atfork
 pthread_attr_destroy
 pthread_attr_getdetachstate
-;pthread_attr_getinheritsched
+pthread_attr_getinheritsched
 pthread_attr_getschedparam
-;pthread_attr_getschedpolicy
+pthread_attr_getschedpolicy
 pthread_attr_getscope
 pthread_attr_getstackaddr
 pthread_attr_getstacksize
 pthread_attr_init
 pthread_attr_setdetachstate
-;pthread_attr_setinheritsched
+pthread_attr_setinheritsched
 pthread_attr_setschedparam
-;pthread_attr_setschedpolicy
+pthread_attr_setschedpolicy
 pthread_attr_setscope
 pthread_attr_setstackaddr
 pthread_attr_setstacksize
 pthread_cancel
 ;
-; These two are implemented as macros
+; These two are implemented as macros in pthread.h
 ;
 ;pthread_cleanup_pop
 ;pthread_cleanup_push
@@ -82,6 +82,9 @@ pthread_testcancel
 ;
 sched_get_priority_min
 sched_get_priority_max
+sched_rr_set_interval
+sched_getscheduler
+sched_setscheduler
 sched_yield
 sem_init
 sem_destroy
diff --git a/pthread.h b/pthread.h
index d4cfd13..a860cd1 100644
--- a/pthread.h
+++ b/pthread.h
@@ -22,6 +22,9 @@
 #if !defined( PTHREAD_H )
 #define PTHREAD_H
 
+#if !defined( PTW32_HEADER )
+#define PTW32_HEADER
+
 #ifdef _UWIN
 #   define HAVE_STRUCT_TIMESPEC 1
 #   define HAVE_SIGNAL_H        1
@@ -29,6 +32,8 @@
 #   pragma comment(lib, "pthread")
 #endif
 
+#endif /* PTW32_HEADER */
+
 /*
  * -------------------------------------------------------------
  *
@@ -120,7 +125,8 @@
 
 #include <setjmp.h>
 
-#ifndef HAVE_STRUCT_TIMESPEC
+#if ! defined(HAVE_STRUCT_TIMESPEC) && ! defined(PTW32_TIMESPEC)
+#define PTW32_TIMESPEC
 struct timespec {
 	long tv_sec;
 	long tv_nsec;
@@ -145,11 +151,13 @@ struct timespec {
 #include <winsock.h>
 
 #ifdef NEED_ERRNO
-#include "need_errno.h"
+#  include "need_errno.h"
 #else
-#include <errno.h>
+#  include <errno.h>
 #endif
 
+#include <sched.h>
+
 /*
  * In case ETIMEDOUT hasn't been defined above somehow.
  */
@@ -157,6 +165,15 @@ struct timespec {
 #define ETIMEDOUT 10060     /* This is the value in winsock.h. */
 #endif
 
+/*
+ * Several systems don't define ENOTSUP. If not, we use
+ * the same value as Solaris.
+ */
+#ifndef ENOTSUP
+#  define ENOTSUP 48
+#endif
+
+
 #ifdef __cplusplus
 extern "C"
 {
@@ -185,7 +202,7 @@ extern "C"
  *                              pthread_attr_getstackaddr
  *                              pthread_attr_setstackaddr
  *
- * _POSIX_THREAD_PRIORITY_SCHEDULING (not set)
+ * _POSIX_THREAD_PRIORITY_SCHEDULING (set)
  *                      If set, you can use realtime scheduling.
  *                      Indicates the availability of:
  *                              pthread_attr_getinheritsched
@@ -198,8 +215,9 @@ extern "C"
  *                              pthread_attr_setscope
  *                              pthread_getschedparam
  *                              pthread_setschedparam
- *                              pthread_get_priority_max
- *                              pthread_get_priority_min
+ *                              sched_get_priority_max
+ *                              sched_get_priority_min
+ *                              sched_rr_set_interval
  *
  * _POSIX_THREAD_PRIO_INHERIT (not set)
  *                      If set, you can create priority inheritance
@@ -263,16 +281,16 @@ extern "C"
 #ifndef _POSIX_THREADS
 #define _POSIX_THREADS
 #endif
-#define _POSIX_THREAD_SAFE_FUNCTIONS
 
+#define _POSIX_THREAD_SAFE_FUNCTIONS
 #define _POSIX_THREAD_ATTR_STACKSIZE
+#define _POSIX_THREAD_PRIORITY_SCHEDULING
 
 #if defined( KLUDGE )
 /*
  * The following are not supported
  */
 #define _POSIX_THREAD_ATTR_STACKADDR
-#define _POSIX_THREAD_PRIORITY_SCHEDULING
 #define _POSIX_THREAD_PRIO_INHERIT
 #define _POSIX_THREAD_PRIO_PROTECT
 #define _POSIX_THREAD_PROCESS_SHARED
@@ -335,36 +353,44 @@ typedef struct pthread_rwlockattr_t_ *pthread_rwlockattr_t;
  * ====================
  */
 
+enum {
 /*
  * pthread_attr_{get,set}detachstate
  */
-#define PTHREAD_CREATE_JOINABLE		0
-#define PTHREAD_CREATE_DETACHED		1
+  PTHREAD_CREATE_JOINABLE	= 0,  /* Default */
+  PTHREAD_CREATE_DETACHED	= 1,
+
+/*
+ * pthread_attr_{get,set}inheritsched
+ */
+  PTHREAD_INHERIT_SCHED		= 0,
+  PTHREAD_EXPLICIT_SCHED	= 1,  /* Default */
 
 /*
- * pthread_attr{get,set}inheritsched
+ * pthread_{get,set}scope
  */
-#define PTHREAD_INHERIT_SCHED		0
-#define PTHREAD_EXPLICIT_SCHED		1
+  PTHREAD_SCOPE_PROCESS		= 0,
+  PTHREAD_SCOPE_SYSTEM		= 1,  /* Default */
 
 /*
  * pthread_setcancelstate paramters
  */
-#define PTHREAD_CANCEL_ENABLE		0
-#define PTHREAD_CANCEL_DISABLE		1
+  PTHREAD_CANCEL_ENABLE		= 0,  /* Default */
+  PTHREAD_CANCEL_DISABLE	= 1,
 
 /*
  * pthread_setcanceltype parameters
  */
-#define PTHREAD_CANCEL_ASYNCHRONOUS	0
-#define PTHREAD_CANCEL_DEFERRED		1
+  PTHREAD_CANCEL_ASYNCHRONOUS	= 0,
+  PTHREAD_CANCEL_DEFERRED	= 1,  /* Default */
 
 /*
  * pthread_mutexattr_{get,set}pshared
  * pthread_condattr_{get,set}pshared
  */
-#define PTHREAD_PROCESS_PRIVATE		0
-#define PTHREAD_PROCESS_SHARED		1
+  PTHREAD_PROCESS_PRIVATE	= 0,
+  PTHREAD_PROCESS_SHARED	= 1
+};
 
 /*
  * ====================
@@ -411,28 +437,6 @@ enum
 };
 
 
-/*
- * ====================
- * ====================
- * Scheduling
- * ====================
- * ====================
- */
-
-/* Thread scheduling policies */
-
-#define SCHED_OTHER 0
-#define SCHED_FIFO  1
-#define SCHED_RR    2
-
-#define SCHED_MIN   SCHED_OTHER
-#define SCHED_MAX   SCHED_RR
-
-struct sched_param {
-  int sched_priority;
-};
-
-
 /* There are three implementations of cancel cleanup.
  * Note that pthread.h is included in both application
  * compilation units and also internally for the library.
@@ -657,6 +661,18 @@ int pthread_attr_getschedparam (const pthread_attr_t *attr,
 int pthread_attr_setschedparam (pthread_attr_t *attr,
                                 const struct sched_param *param);
 
+int pthread_attr_setschedpolicy (pthread_attr_t *,
+                                 int);
+
+int pthread_attr_getschedpolicy (pthread_attr_t *,
+                                 int *);
+
+int pthread_attr_setinheritsched(pthread_attr_t * attr,
+                                 int inheritsched);
+
+int pthread_attr_getinheritsched(pthread_attr_t * attr,
+                                 int * inheritsched);
+
 int pthread_attr_setscope (pthread_attr_t *,
                            int);
  
diff --git a/sched.c b/sched.c
index 0f83a43..6f558ab 100644
--- a/sched.c
+++ b/sched.c
@@ -23,8 +23,6 @@
  * MA 02111-1307, USA
  */
 
-#define ENOSUP 0
-
 #include "pthread.h"
 #include "implement.h"
 #include "sched.h"
@@ -37,19 +35,78 @@ is_attr(const pthread_attr_t *attr)
 	  (*attr)->valid != PTW32_ATTR_VALID) ? 1 : 0;
 }
 
+
+int
+pthread_attr_setschedpolicy(pthread_attr_t *attr,
+                            int policy)
+{
+  if (is_attr(attr) != 0)
+    {
+      return EINVAL;
+    }
+
+  if (policy != SCHED_OTHER)
+    {
+      return ENOTSUP;
+    }
+
+  return 0;
+}
+
+
+int
+pthread_attr_getschedpolicy(pthread_attr_t *attr,
+                            int * policy)
+{
+  if (is_attr(attr) != 0 || policy == NULL)
+    {
+      return EINVAL;
+    }
+
+  /*
+   * Validate the policy arg.
+   * Check that a policy constant wasn't passed rather than &policy.
+   */
+  if (policy <= (int *) SCHED_MAX)
+    {
+      return EINVAL;
+    }
+
+  *policy = SCHED_OTHER;
+
+  return 0;
+}
+
+
 int
 pthread_attr_setschedparam(pthread_attr_t *attr,
 			   const struct sched_param *param)
 {
+  int priority;
+
   if (is_attr(attr) != 0 || param == NULL)
     {
       return EINVAL;
     }
 
-  (*attr)->priority = param->sched_priority;
+  priority = param->sched_priority;
+
+  /*
+   * Validate priority level. Don't check the
+   * return values of the function calls because
+   * we're sure they will succeed.
+   */
+  if (priority < sched_get_priority_min(SCHED_OTHER) ||
+      priority > sched_get_priority_max(SCHED_OTHER))
+    {
+      return EINVAL;
+    }
+
+  memcpy(&(*attr)->param, param, sizeof(*param));
   return 0;
 }
 
+
 int 
 pthread_attr_getschedparam(const pthread_attr_t *attr,
 			       struct sched_param *param)
@@ -59,11 +116,47 @@ pthread_attr_getschedparam(const pthread_attr_t *attr,
       return EINVAL;
     }
   
-  param->sched_priority = (*attr)->priority;
+  memcpy(param, &(*attr)->param, sizeof(*param));
   return 0;
 }
 
-int pthread_setschedparam(pthread_t thread, int policy,
+
+int
+pthread_attr_setinheritsched(pthread_attr_t * attr,
+                             int inheritsched)
+{
+  if (is_attr(attr) != 0)
+    {
+      return EINVAL;
+    }
+
+  if (PTHREAD_INHERIT_SCHED != inheritsched
+      && PTHREAD_EXPLICIT_SCHED != inheritsched)
+    {
+      return EINVAL;
+    }
+
+  (*attr)->inheritsched = inheritsched;
+  return 0;
+}
+
+
+int
+pthread_attr_getinheritsched(pthread_attr_t * attr,
+                             int * inheritsched)
+{
+  if (is_attr(attr) != 0 || inheritsched == NULL)
+    {
+      return EINVAL;
+    }
+
+  *inheritsched = (*attr)->inheritsched;
+  return 0;
+}
+
+
+int
+pthread_setschedparam(pthread_t thread, int policy,
 			  const struct sched_param *param)
 {
   /* Validate the thread id. */
@@ -81,12 +174,16 @@ int pthread_setschedparam(pthread_t thread, int policy,
   /* Ensure the policy is SCHED_OTHER. */
   if (policy != SCHED_OTHER)
     {
-      return ENOSUP;
+      return ENOTSUP;
     }
 
-  /* Validate priority level. */
-  if (param->sched_priority < sched_get_priority_min(policy) ||
-      param->sched_priority > sched_get_priority_max(policy))
+  /*
+   * Validate priority level. Don't check the
+   * return values of the function calls because
+   * we're sure they will succeed.
+   */
+  if (param->sched_priority < sched_get_priority_min(SCHED_OTHER) ||
+      param->sched_priority > sched_get_priority_max(SCHED_OTHER))
     {
       return EINVAL;
     }
@@ -97,7 +194,9 @@ int pthread_setschedparam(pthread_t thread, int policy,
   return 0;
 }
 
-int pthread_getschedparam(pthread_t thread, int *policy,
+
+int
+pthread_getschedparam(pthread_t thread, int *policy,
 			  struct sched_param *param)
 {
   int prio;
@@ -108,8 +207,11 @@ int pthread_getschedparam(pthread_t thread, int *policy,
       return EINVAL;
     }
 
-  /* Validate the param structure. */
-  if (param == NULL)
+  /*
+   * Validate the policy and param args.
+   * Check that a policy constant wasn't passed rather than &policy.
+   */
+  if (policy <= (int *) SCHED_MAX || param == NULL)
     {
       return EINVAL;
     }
@@ -141,14 +243,24 @@ int pthread_getschedparam(pthread_t thread, int *policy,
  * sched_get_priority_max() returns 1
  */
 
+
 #define sched_Max(a,b)  ((a)<(b)?(b):(a))
 #define sched_Min(a,b)  ((a)>(b)?(b):(a))
 
-int sched_get_priority_max(int policy)
+
+int
+sched_get_priority_max(int policy)
 {
   if (policy < SCHED_MIN || policy > SCHED_MAX)
     {
-      return EINVAL;
+      errno = EINVAL;
+      return -1;
+    }
+
+  if (policy != SCHED_OTHER)
+    {
+      errno = ENOTSUP;
+      return -1;
     }
 
 #if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
@@ -160,11 +272,20 @@ int sched_get_priority_max(int policy)
 #endif
 }
 
-int sched_get_priority_min(int policy)
+
+int
+sched_get_priority_min(int policy)
 {
   if (policy < SCHED_MIN || policy > SCHED_MAX)
     {
-      return EINVAL;
+      errno = EINVAL;
+      return -1;
+    }
+
+  if (policy != SCHED_OTHER)
+    {
+      errno = ENOTSUP;
+      return -1;
     }
 
 #if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
@@ -176,7 +297,259 @@ int sched_get_priority_min(int policy)
 #endif
 }
 
-int sched_yield(void)
+
+int
+sched_rr_get_interval(pid_t pid, struct timespec * interval)
+     /*
+      * ------------------------------------------------------
+      * DOCPUBLIC
+      *      This function updates the timespec structure
+      *      referenced by the interval argument to contain
+      *      the current quantum for the process executing
+      *      under the SCHED_RR policy. If a process, running under
+      *      the round-robin scheduling policy, runs without
+      *      blocking or yielding for more than this amount of
+      *      time, it may be preempted by another runnable
+      *      process (at the same priority).
+      *
+      *      If the PID argument is zero, the current execution
+      *      time limit for the calling process is returned.
+      *
+      * PARAMETERS
+      *      pid    Process identifier.
+      *
+      *
+      * DESCRIPTION
+      *      This function updates the timespec structure
+      *      referenced by the interval argument to contain
+      *      the current quantum for the process executing
+      *      under the SCHED_RR policy. If a process, running under
+      *      the round-robin scheduling policy, runs without
+      *      blocking or yielding for more than this amount of
+      *      time, it may be preempted by another runnable
+      *      process (at the same priority).
+      *
+      *      If the PID argument is zero, the current execution
+      *      time limit for the calling process is returned.
+      *
+      * RESULTS
+      *      We don't support SCHED_RR so this routine always fails.
+      *
+      *      NOTE: Since this is part of POSIX 1003.1b
+      *                (realtime extensions), it is defined as returning
+      *                -1 if an error occurs and sets errno to the actual
+      *                error.
+      *
+      *      errno:  ESRCH           Pid doesn't refer to a valid process.
+      *              EPERM           The process referenced by pid does
+      *                              not allow query access.
+      *              ENOTSUP         SCHED_RR is not supported.
+      *
+      * ------------------------------------------------------
+      */
+{
+  /*
+   * Provide other valid side-effects
+   * such as EPERM and ESRCH errors.
+   */
+  if (0 != pid)
+    {
+      DWORD selfPid = GetCurrentProcessId();
+
+      if (pid != selfPid)
+        {
+          HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
+
+          if (NULL == h)
+            {
+              errno = (GetLastError() == (0xFF & ERROR_ACCESS_DENIED)
+                       ? EPERM
+                       : ESRCH );
+
+              return -1;
+            }
+
+          (void) CloseHandle(h);
+        }
+    }
+
+  /*
+   * We can't return ENOSYS and stay strictly compliant with the
+   * standard. We don't support round-robin scheduling so
+   * we return ENOTSUP instead. This is consistent with
+   * routines which return ENOTSUP if SCHED_RR is given
+   * as the policy parameter.
+   */
+  errno = ENOTSUP;
+  return -1;
+}
+
+
+int
+sched_setscheduler(pid_t pid, int policy)
+     /*
+      * ------------------------------------------------------
+      * DOCPUBLIC
+      *      This function returns sets the scheduling policy and
+      *      scheduling parameters of the process specified by pid
+      *      to policy and the parameters specified in the
+      *      sched_param structure pointed to by param, respectively.
+      *      The value of the sched_priority member in the sched_param
+      *      structure is any integer within the inclusive priority
+      *      range for the scheduling policy specified by policy.
+      *      If the value of pid is negative, the behaviour of the
+      *      sched_setscheduler() function is unspecified.
+      *
+      * PARAMETERS
+      *      pid        Identifier of the process in which the
+      *                 policy will be set.
+      *      policy     The new policy value.
+      *
+      *
+      * DESCRIPTION
+      *      This function returns sets the scheduling policy and
+      *      scheduling parameters of the process specified by pid
+      *      to policy and the parameters specified in the
+      *      sched_param structure pointed to by param, respectively.
+      *      The value of the sched_priority member in the sched_param
+      *      structure is any integer within the inclusive priority
+      *      range for the scheduling policy specified by policy.
+      *      If the value of pid is negative, the behaviour of the
+      *      sched_setscheduler() function is unspecified.
+      *
+      * RESULTS
+      *      SCHED_OTHER            on success this is the only possible
+      *                             value that can be returned.
+      *
+      *      NOTE: Since this is part of POSIX 1003.1b
+      *                (realtime extensions), it is defined as returning
+      *                -1 if an error occurs and sets errno to the actual
+      *                error.
+      *
+      *      errno:  ESRCH           'pid' doesn't refer to an existing
+      *                              process.
+      *              EPERM           The process referenced by pid does
+      *                              not allow set access.
+      *              EINVAL          'policy' is not a valid policy value.
+      *              ENOSYS          the policy specified is not supported.
+      *
+      * ------------------------------------------------------
+      */
+{
+  /*
+   * Win32 only has one policy which we call SCHED_OTHER.
+   * However, we try to provide other valid side-effects
+   * such as EPERM and ESRCH errors.
+   */
+  if (0 != pid)
+    {
+      DWORD selfPid = GetCurrentProcessId();
+
+      if (pid != selfPid)
+        {
+          HANDLE h = OpenProcess(PROCESS_SET_INFORMATION, FALSE, pid);
+
+          if (NULL == h)
+            {
+              errno = (GetLastError() == (0xFF & ERROR_ACCESS_DENIED)
+                       ? EPERM
+                       : ESRCH );
+
+              return -1;
+            }
+
+          (void) CloseHandle(h);
+        }
+    }
+
+  if (policy < SCHED_MIN || policy > SCHED_MAX)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  if (SCHED_OTHER != policy)
+    {
+      errno = ENOSYS;
+      return -1;
+    }
+
+  /*
+   * Don't set anything because there is nothing to set.
+   * Just return the current (the only possible) value.
+   */
+  return SCHED_OTHER;
+}
+
+
+int
+sched_getscheduler(pid_t pid)
+     /*
+      * ------------------------------------------------------
+      * DOCPUBLIC
+      *      This function returns the scheduling policy of the
+      *      process specified by pid. If the value of pid is
+      *      negative, the behaviour of the sched_getscheduler()
+      *      function is unspecified.
+      *
+      * PARAMETERS
+      *      pid    Process identifier.
+      *
+      *
+      * DESCRIPTION
+      *      This function returns the scheduling policy of the
+      *      process specified by pid. If the value of pid is
+      *      negative, the behaviour of the sched_getscheduler()
+      *      function is unspecified.
+      *
+      * RESULTS
+      *      SCHED_OTHER            on success this is the only possible
+      *                             value that can be returned.
+      *
+      *      NOTE: Since this is part of POSIX 1003.1b
+      *                (realtime extensions), it is defined as returning
+      *                -1 if an error occurs and sets errno to the actual
+      *                error.
+      *
+      *      errno:  ESRCH           Pid doesn't refer to a valid process.
+      *              EPERM           The process referenced by pid does
+      *                              not allow query access.
+      *
+      * ------------------------------------------------------
+      */
+{
+  /*
+   * Win32 only has one policy which we call SCHED_OTHER.
+   * However, we try to provide other valid side-effects
+   * such as EPERM and ESRCH errors.
+   */
+  if (0 != pid)
+    {
+      DWORD selfPid = GetCurrentProcessId();
+
+      if (pid != selfPid)
+        {
+          HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
+
+          if (NULL == h)
+            {
+              errno = (GetLastError() == (0xFF & ERROR_ACCESS_DENIED)
+                       ? EPERM
+                       : ESRCH );
+
+              return -1;
+            }
+
+          (void) CloseHandle(h);
+        }
+    }
+
+  return SCHED_OTHER;
+}
+
+
+int
+sched_yield(void)
      /*
       * ------------------------------------------------------
       * DOCPUBLIC
@@ -196,8 +569,7 @@ int sched_yield(void)
       *                error.
       *
       * RESULTS
-      *              0               successfully created semaphore,
-      *              ENOSYS          sched_yield not supported,
+      *              0               always succeeds
       *
       * ------------------------------------------------------
       */
diff --git a/sched.h b/sched.h
index eff9d6b..e4e02a2 100644
--- a/sched.h
+++ b/sched.h
@@ -28,6 +28,49 @@
 #ifndef _SCHED_H
 #define _SCHED_H
 
+#if !defined( PTW32_HEADER )
+#define PTW32_HEADER
+
+#ifdef _UWIN
+#   define HAVE_STRUCT_TIMESPEC 1
+#   define HAVE_SIGNAL_H        1
+#   undef HAVE_CONFIG_H
+#   pragma comment(lib, "pthread")
+#endif
+
+#endif /* PTW32_HEADER */
+
+#if defined(__MINGW32__) || defined(_UWIN)
+/* For pid_t */
+#  include <sys/types.h>
+/* Required by Unix 98 - including sched.h makes time.h available */
+#  include <time.h>
+#else
+typedef DWORD pid_t;
+#endif
+
+#if ! defined(HAVE_STRUCT_TIMESPEC) && ! defined(PTW32_TIMESPEC)
+#define PTW32_TIMESPEC
+struct timespec {
+	long tv_sec;
+	long tv_nsec;
+};
+#endif /* HAVE_STRUCT_TIMESPEC */
+
+
+/* Thread scheduling policies */
+enum {
+  SCHED_OTHER = 0,
+  SCHED_FIFO,
+  SCHED_RR,
+  SCHED_MIN   = SCHED_OTHER,
+  SCHED_MAX   = SCHED_RR
+};
+
+struct sched_param {
+  int sched_priority;
+};
+
 #ifdef __cplusplus
 extern "C"
 {
@@ -39,6 +82,11 @@ int sched_get_priority_min (int policy);
 
 int sched_get_priority_max (int policy);
 
+int sched_setscheduler (pid_t pid, int policy);
+
+int sched_getscheduler (pid_t pid);
+
+int sched_rr_get_interval(pid_t pid, struct timespec * interval);
 
 #ifdef __cplusplus
 }                               /* End of extern "C" */
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 27f8dfe..231d9fe 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,504 +1,513 @@
-2001-06-8  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* mutex5.c: Insert inert change to quell compiler warnings.
-	* condvar3_2.c: Remove unused variable.
-	
-2001-06-3  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* condvar2_1.c: New test.
-	* condvar3_1.c: New test.
-	* condvar3_2.c: New test.
-
-2001-05-30  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* mutex1n.c: New test.
-	* mutex1e.c: New test.
-	* mutex1r.c: New test.
-	* mutex4.c: Now locks and unlocks a mutex.
-	* mutex5.c: New test.
-	* mutex6.c: New test.
-	* mutex6n.c: New test.
-	* mutex6e.c: New test.
-	* mutex6r.c: New test.
-	* Makefile: Added new tests; reorganised.
-	* GNUmakefile: Likewise.
-	* rwlock6.c: Fix to properly prove read-while-write locking
-	and single writer locking.
-
-2001-05-29  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* Makefile: Reorganisation.
-	* GNUmakefile: Likewise.
-	- Thomas Pfaff <tpfaff@gmx.net>
-
-	* exception1.c: Add stdio.h include to define fprintf and stderr
-	in non-exception C version of main().
-	* exception2.c: Likewise.
-	* exception3.c: Likewise.
-
-	* Makefile (rwlock7): Add new test.
-	* GNUmakefile (rwlock7): Add new test.
-	* rwlock7.c: New test.
-	* rwlock6.c: Changed to test that writer has priority.
-
-	* eyal1.c (main): Unlock each mutex_start lock before destroying
-	it.
-
-2000-12-29  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* GNUmakefile: Add mutex4 test; ensure libpthreadw32.a is
-	removed for "clean" target.
-	* Makefile: Add mutex4 test.
-
-	* exception3.c: Remove SEH code; automatically pass the test
-	under SEH (which is an N/A environment).
-
-	* mutex4.c: New test.
-
-	* eyal1.c (do_work_unit): Add a dummy "if" to force the
-	optimiser to retain code; reduce thread work loads.
-
-	* condvar8.c (main): Add an additional "assert" for debugging;
-	increase pthread_cond_signal timeout.
-
-2000-12-28  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* eyal1.c: Increase thread work loads.
-	* exception2.c: New test.
-	* exception3.c: New test.
-	* Makefile: Add new tests exception2.c and exception3.c.
-	* GNUmakefile: Likewise.
-
-2000-12-11  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* cleanup3.c: Remove unused variable.
-	* cleanup2.c: Likewise.
-	* exception1.c: Throw an exception rather than use
-	a deliberate zero divide so that catch(...) will
-	handle it under Mingw32. Mingw32 now builds the
-	library correctly to pass all tests - see Thomas
-	Pfaff's detailed instructions re needed changes
-	to Mingw32 in the Pthreads-Win32 FAQ.
-
-2000-09-08  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* cancel5.c: New; tests calling pthread_cancel()
-	from the main thread without first creating a
-	POSIX thread struct for the non-POSIX main thread
-	- this forces pthread_cancel() to create one via
-	pthread_self().
-	* Makefile (cancel5): Add new test.
-	* GNUmakefile (cancel5): Likewise.
-
-2000-08-17  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* create2.c: New; Test that pthread_t contains
-	the W32 HANDLE before it calls the thread routine
-	proper.
-
-2000-08-13  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* condvar3.c: Minor change to eliminate compiler
-	warning.
-
-	* condvar4.c: ditto.
-
-	* condvar5.c: ditto.
-
-	* condvar6.c: ditto.
-
-	* condvar7.c: ditto.
-
-	* condvar8.c: ditto.
-
-	* condvar9.c: ditto.
-
-	* exit1.c: Function needed return statement.
-
-	* cleanup1.c: Remove unnecessary printf arg.
-
-	* cleanup2.c: Fix cast.
-
-	* rwlock6.c: Fix casts.
-
-	* exception1.c (PtW32CatchAll): Had the wrong name;
-	fix casts.
-
-	* cancel3.c: Remove unused waitLock variable.
-
-	* GNUmakefile: Change library/dll naming; add new tests;
-	general minor changes.
-
-	* Makefile: Change library/dll naming; add targets for
-	testing each of the two VC++ EH scheme versions;
-	default target now issues help message; compile warnings
-	now interpreted as errors to stop the make; add new
-	tests; restructure to remove prerequisites needed
-	otherwise.
-
-	* README: Updated.
-
-
-2000-08-10  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* eyal1.c (main): Change implicit cast to explicit
-	cast when passing "print_server" function pointer;
-	G++ no longer allows implicit func parameter casts.
-
-	* cleanup1.c: Remove unused "waitLock".
-	(main): Fix implicit parameter cast.
-
-	* cancel2.c (main): Fix implicit parameter cast.
-
-	* cancel4.c (main): Fix implicit parameter cast.
-
-	* cancel3.c (main): Fix implicit parameter cast.
-
-	* GNUmakefile: Renamed from Makefile; Add missing
-	cancel1 and cancel2 test targets.
-
-	* Makefile: Converted for use with MS nmake.
-
-2000-08-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* ccl.bat: Add /nologo to remove extraneous output.
-
-	* exception1.c (exceptionedThread): Init 'dummy';
-	put expression into if condition to prevent optimising away;
-	remove unused variable.
-
-	* cancel4.c (mythread): Cast return value to avoid warnings.
-
-	* cancel2.c (mythread): Missing #endif.
-
-	* condvar9.c (mythread): Cast return value to avoid warnings.
-
-	* condvar8.c (mythread): Cast return value to avoid warnings.
-
-	* condvar7.c (mythread): Cast return value to avoid warnings.
-
-	* cleanup3.c (mythread): Cast return value to avoid warnings.
-
-	* cleanup2.c (mythread): Cast return value to avoid warnings.
-
-	* cleanup1.c (mythread): Cast return value to avoid warnings.
-
-	* condvar5.c (mythread): Cast return value to avoid warnings.
-
-	* condvar3.c (mythread): Cast return value to avoid warnings.
-
-	* condvar6.c (mythread): Cast return value to avoid warnings.
-
-	* condvar4.c (mythread): Cast return value to avoid warnings.
-
-2000-08-05  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* cancel2.c: Use PtW32CatchAll macro if defined.
-
-	* exception1.c: Use PtW32CatchAll macro if defined.
-
-2000-08-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* tsd1.c: Fix typecasts of &result [g++ is now very fussy].
-	
-	* test.h (assert): Return 0's explicitly to allay
-	g++ errors.
-	
-	* join2.c: Add explicit typecasts.
-	
-	* join1.c: Add explicit typecasts.
-	
-	* join0.c: Add explicit typecasts.
-	
-	* eyal1.c: Add explicit typecasts.
-	
-	* count1.c (main): Add type cast to remove g++ parse warning
-	[gcc-2.95.2 seems to have tightened up on this].
-
-	* Makefile (GLANG): Use c++ explicitly.
-	Remove MSVC sections (was commented out).
-	Add target to generate cpp output.
-
-2000-07-25  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* runtest.bat: modified to work under W98.
-	
-	* runall.bat: Add new tests; modified to work under W98.
-	It was ok under NT.
-
-	* Makefile: Add new tests.
-
-	* exception1.c: New; Test passing exceptions back to the
-	application and retaining library internal exceptions.
-
-	* join0.c: New; Test a single join.
-
-2000-01-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* cleanup1.c: New; Test cleanup handler executes (when thread is
-	canceled).
-
-	* cleanup2.c: New; Test cleanup handler executes (when thread is
-	not canceled).
-
-	* cleanup3.c: New; Test cleanup handler does not execute
-	(when thread is not canceled).
-
-2000-01-04  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* cancel4.c: New; Test cancelation does not occur in deferred
-	cancelation threads with no cancelation points.
-
-	* cancel3.c: New; Test asynchronous cancelation.
-
-	* context1.c: New; Test context switching method for async
-	cancelation.
-
-1999-11-23  Ross Johnson  <rpj@special.ise.canberra.edu.au>
-
-	* test.h: Add header includes; include local header versions rather
-	than system versions; rearrange the assert macro defines.
-
-1999-11-07  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* loadfree.c: New. Test loading and freeing the library (DLL).
-
-1999-10-30  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* cancel1.c: New. Test pthread_setcancelstate and
-	pthread_setcanceltype functions.
-	* eyal1.c (waste_time): Change calculation to avoid FP exception
-	on Aplhas
-	- Rich Peters <rpeters@micro-magic.com>
-
-Oct 14 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* condvar7.c: New. Test broadcast after waiting thread is canceled.
-	* condvar8.c: New. Test multiple broadcasts.
-	* condvar9.c: New. Test multiple broadcasts with thread
-	cancelation.
-	
-Sep 16 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* rwlock6.c: New test.
-
-Sep 15 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* rwlock1.c: New test.
-	* rwlock2.c: New test.
-	* rwlock3.c: New test.
-	* rwlock4.c: New test.
-	* rwlock5.c: New test.
-
-Aug 22 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* runall.bat (join2): Add test.
-
-Aug 19 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* join2.c: New test.
-
-Wed Aug 12 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* Makefile (LIBS): Add -L.
-
-Mon May 31 10:25:01 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* Makefile (GLANG): Add GCC language option.
-
-Sat May 29 23:29:04 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* runall.bat (condvar5): Add new test.
-
-	* runall.bat (condvar6): Add new test.
-
-	* Makefile (condvar5) : Add new test.
-	
-	* Makefile (condvar6) : Add new test.
-	
-	* condvar5.c: New test for pthread_cond_broadcast().
-
-	* condvar6.c: New test for pthread_cond_broadcast().
-
-Sun Apr  4 12:04:28 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* tsd1.c (mythread): Change Sleep(0) to sched_yield().
-	(sched.h): Include.
-
-	* condvar3.c (mythread): Remove redundant Sleep().
-
-	* runtest.bat: Re-organised to make more informative.
-
-Fri Mar 19 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* *.bat: redirect unwanted output to nul:
-
-	* runall.bat: new.
-
-	* cancel1.c: new. Not part of suite yet.
-	
-Mon Mar 15 00:17:55 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* mutex1.c: only test mutex init and destroy; add assertions.
-
-	* count1.c: raise number of spawned threads to 60 (appears to
-	be the limit under Win98).
-
-Sun Mar 14 21:31:02 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* test.h (assert): add assertion trace option.
-	Use:
-	"#define ASSERT_TRACE 1" to turn it on,
-	"#define ASSERT_TRACE 0" to turn it off (default).
-
-	* condvar3.c (main): add more assertions.
-
-	* condvar4.c (main): add more assertions.
-
-	* condvar1.c (main): add more assertions.
-
-Fri Mar 12 08:34:15 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* condvar4.c (cvthing): switch the order of the INITIALIZERs.
-
-	* eyal1.c (main): Fix trylock loop; was not waiting for thread to lock
-	the "started" mutex.
-
-Wed Mar 10 10:41:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* tryentercs.c: Apply typo patch from bje.
-
-	* tryentercs2.c: Ditto.
-
-Sun Mar  7 10:41:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* Makefile (condvar3, condvar4): Add tests.
-
-	* condvar4.c (General): Reduce to simple test case; prerequisite
-	is condvar3.c; add description.
-
-	* condvar3.c (General): Reduce to simple test case; prerequisite
-	is condvar2.c; add description.
-
-	* condvar2.c (General): Reduce to simple test case; prerequisite
-	is condvar1.c; add description.
-
-	* condvar1.c (General): Reduce to simple test case; add
-	description.
-
-	* Template.c (Comments): Add generic test detail.
-
-1999-02-23  Ross Johnson  <rpj@ise.canberra.edu.au>
-
-        * Template.c: Revamp.
-
-        * condvar1.c: Add.
-
-        * condvar2.c: Add.
-
-        * Makefile: Add condvar1 condvar2 tests.
-
-        * exit1.c, exit2.c, exit3.c: Cosmetic changes.
-
-1999-02-23  Ross Johnson  <rpj@ise.canberra.edu.au>
-
-	* Makefile: Some refinement.
-
-	* *.c: More exhaustive checking through assertions; clean up;
-	add some more tests.
-
-	* Makefile: Now actually runs the tests.
-
-	* tests.h: Define our own assert macro. The Mingw32
-	version pops up a dialog but we want to run non-interactively.
-
-	* equal1.c: use assert a little more directly so that it
-	prints the actual call statement.
-
-	* exit1.c: Modify to return 0 on success, 1 on failure.
-
-1999-02-22  Ross Johnson  <rpj@ise.canberra.edu.au>
-
-	* self2.c: Bring up to date.
-
-	* self3.c: Ditto.
-
-1999-02-21  Ben Elliston  <bje@cygnus.com>
-
-	* README: Update.
-
-	* Makefile: New file. Run all tests automatically. Primitive tests
-	are run first; more complex tests are run last.
-
-	* count1.c: New test. Validate the thread count.
-
-	* exit2.c: Perform a simpler test.
-	
-	* exit3.c: New test. Replaces exit2.c, since exit2.c needs to
-	perform simpler checking first.
-
-	* create1.c: Update to use the new testsuite exiting convention.
-	
-	* equal1.c: Likewise.
-
-	* mutex1.c: Likewise.
-
-	* mutex2.c: Likewise.
-
-	* once1.c: Likewise.
-
-	* self2.c: Likewise.
-
-	* self3.c: Likewise.
-
-	* tsd1.c: Likewise.
-
-1999-02-20  Ross Johnson  <rpj@ise.canberra.edu.au>
-
-	* mutex2.c: Test static mutex initialisation.
-
-	* test.h: New. Declares a table mapping error numbers to
-	error names.
-
-1999-01-17  Ross Johnson  <rpj@ise.canberra.edu.au>
-
-	* runtest: New script to build and run a test in the tests directory.
-
-Wed Dec 30 11:22:44 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* tsd1.c: Re-written. See comments at start of file.
-	* Template.c: New. Contains skeleton code and comment template
-	intended to fully document the test.
-
-Fri Oct 16 17:59:49 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* tsd1.c (destroy_key): Add function. Change diagnostics.
-
-Thu Oct 15 17:42:37 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
-
-	* tsd1.c (mythread): Fix some casts and add some message
-	output. Fix inverted conditional.
-
-Mon Oct 12 02:12:29 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
-
-	* tsd1.c: New. Test TSD using 1 key and 2 threads.
-
-1998-09-13  Ben Elliston  <bje@cygnus.com>
-
-	* eyal1.c: New file; contributed by Eyal Lebedinsky
-	<eyal@eyal.emu.id.au>.
-
-1998-09-12  Ben Elliston  <bje@cygnus.com>
-
-	* exit2.c (func): Return a value.
-	(main): Call the right thread entry function.
-
-1998-07-22  Ben Elliston  <bje@cygnus.com>
-
-	* exit2.c (main): Fix size of pthread_t array.
-
-1998-07-10  Ben Elliston  <bje@cygnus.com>
-
-	* exit2.c: New file; test pthread_exit() harder.
-
-	* exit1.c: New file; test pthread_exit().
+2001-06-25  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	priority1.c: New test.
+	priority2.c: New test.
+	inherit1.c: New test.
+	benchtest1.c: New; timing mutexes.
+	benchtest2.c: New; timing mutexes.
+	mutex4.c: Modified to test all mutex types.
+
+2001-06-8  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* mutex5.c: Insert inert change to quell compiler warnings.
+	* condvar3_2.c: Remove unused variable.
+	
+2001-06-3  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* condvar2_1.c: New test.
+	* condvar3_1.c: New test.
+	* condvar3_2.c: New test.
+
+2001-05-30  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* mutex1n.c: New test.
+	* mutex1e.c: New test.
+	* mutex1r.c: New test.
+	* mutex4.c: Now locks and unlocks a mutex.
+	* mutex5.c: New test.
+	* mutex6.c: New test.
+	* mutex6n.c: New test.
+	* mutex6e.c: New test.
+	* mutex6r.c: New test.
+	* Makefile: Added new tests; reorganised.
+	* GNUmakefile: Likewise.
+	* rwlock6.c: Fix to properly prove read-while-write locking
+	and single writer locking.
+
+2001-05-29  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* Makefile: Reorganisation.
+	* GNUmakefile: Likewise.
+	- Thomas Pfaff <tpfaff@gmx.net>
+
+	* exception1.c: Add stdio.h include to define fprintf and stderr
+	in non-exception C version of main().
+	* exception2.c: Likewise.
+	* exception3.c: Likewise.
+
+	* Makefile (rwlock7): Add new test.
+	* GNUmakefile (rwlock7): Add new test.
+	* rwlock7.c: New test.
+	* rwlock6.c: Changed to test that writer has priority.
+
+	* eyal1.c (main): Unlock each mutex_start lock before destroying
+	it.
+
+2000-12-29  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* GNUmakefile: Add mutex4 test; ensure libpthreadw32.a is
+	removed for "clean" target.
+	* Makefile: Add mutex4 test.
+
+	* exception3.c: Remove SEH code; automatically pass the test
+	under SEH (which is an N/A environment).
+
+	* mutex4.c: New test.
+
+	* eyal1.c (do_work_unit): Add a dummy "if" to force the
+	optimiser to retain code; reduce thread work loads.
+
+	* condvar8.c (main): Add an additional "assert" for debugging;
+	increase pthread_cond_signal timeout.
+
+2000-12-28  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* eyal1.c: Increase thread work loads.
+	* exception2.c: New test.
+	* exception3.c: New test.
+	* Makefile: Add new tests exception2.c and exception3.c.
+	* GNUmakefile: Likewise.
+
+2000-12-11  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* cleanup3.c: Remove unused variable.
+	* cleanup2.c: Likewise.
+	* exception1.c: Throw an exception rather than use
+	a deliberate zero divide so that catch(...) will
+	handle it under Mingw32. Mingw32 now builds the
+	library correctly to pass all tests - see Thomas
+	Pfaff's detailed instructions re needed changes
+	to Mingw32 in the Pthreads-Win32 FAQ.
+
+2000-09-08  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* cancel5.c: New; tests calling pthread_cancel()
+	from the main thread without first creating a
+	POSIX thread struct for the non-POSIX main thread
+	- this forces pthread_cancel() to create one via
+	pthread_self().
+	* Makefile (cancel5): Add new test.
+	* GNUmakefile (cancel5): Likewise.
+
+2000-08-17  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* create2.c: New; Test that pthread_t contains
+	the W32 HANDLE before it calls the thread routine
+	proper.
+
+2000-08-13  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* condvar3.c: Minor change to eliminate compiler
+	warning.
+
+	* condvar4.c: ditto.
+
+	* condvar5.c: ditto.
+
+	* condvar6.c: ditto.
+
+	* condvar7.c: ditto.
+
+	* condvar8.c: ditto.
+
+	* condvar9.c: ditto.
+
+	* exit1.c: Function needed return statement.
+
+	* cleanup1.c: Remove unnecessary printf arg.
+
+	* cleanup2.c: Fix cast.
+
+	* rwlock6.c: Fix casts.
+
+	* exception1.c (PtW32CatchAll): Had the wrong name;
+	fix casts.
+
+	* cancel3.c: Remove unused waitLock variable.
+
+	* GNUmakefile: Change library/dll naming; add new tests;
+	general minor changes.
+
+	* Makefile: Change library/dll naming; add targets for
+	testing each of the two VC++ EH scheme versions;
+	default target now issues help message; compile warnings
+	now interpreted as errors to stop the make; add new
+	tests; restructure to remove prerequisites needed
+	otherwise.
+
+	* README: Updated.
+
+
+2000-08-10  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* eyal1.c (main): Change implicit cast to explicit
+	cast when passing "print_server" function pointer;
+	G++ no longer allows implicit func parameter casts.
+
+	* cleanup1.c: Remove unused "waitLock".
+	(main): Fix implicit parameter cast.
+
+	* cancel2.c (main): Fix implicit parameter cast.
+
+	* cancel4.c (main): Fix implicit parameter cast.
+
+	* cancel3.c (main): Fix implicit parameter cast.
+
+	* GNUmakefile: Renamed from Makefile; Add missing
+	cancel1 and cancel2 test targets.
+
+	* Makefile: Converted for use with MS nmake.
+
+2000-08-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* ccl.bat: Add /nologo to remove extraneous output.
+
+	* exception1.c (exceptionedThread): Init 'dummy';
+	put expression into if condition to prevent optimising away;
+	remove unused variable.
+
+	* cancel4.c (mythread): Cast return value to avoid warnings.
+
+	* cancel2.c (mythread): Missing #endif.
+
+	* condvar9.c (mythread): Cast return value to avoid warnings.
+
+	* condvar8.c (mythread): Cast return value to avoid warnings.
+
+	* condvar7.c (mythread): Cast return value to avoid warnings.
+
+	* cleanup3.c (mythread): Cast return value to avoid warnings.
+
+	* cleanup2.c (mythread): Cast return value to avoid warnings.
+
+	* cleanup1.c (mythread): Cast return value to avoid warnings.
+
+	* condvar5.c (mythread): Cast return value to avoid warnings.
+
+	* condvar3.c (mythread): Cast return value to avoid warnings.
+
+	* condvar6.c (mythread): Cast return value to avoid warnings.
+
+	* condvar4.c (mythread): Cast return value to avoid warnings.
+
+2000-08-05  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* cancel2.c: Use PtW32CatchAll macro if defined.
+
+	* exception1.c: Use PtW32CatchAll macro if defined.
+
+2000-08-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* tsd1.c: Fix typecasts of &result [g++ is now very fussy].
+	
+	* test.h (assert): Return 0's explicitly to allay
+	g++ errors.
+	
+	* join2.c: Add explicit typecasts.
+	
+	* join1.c: Add explicit typecasts.
+	
+	* join0.c: Add explicit typecasts.
+	
+	* eyal1.c: Add explicit typecasts.
+	
+	* count1.c (main): Add type cast to remove g++ parse warning
+	[gcc-2.95.2 seems to have tightened up on this].
+
+	* Makefile (GLANG): Use c++ explicitly.
+	Remove MSVC sections (was commented out).
+	Add target to generate cpp output.
+
+2000-07-25  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* runtest.bat: modified to work under W98.
+	
+	* runall.bat: Add new tests; modified to work under W98.
+	It was ok under NT.
+
+	* Makefile: Add new tests.
+
+	* exception1.c: New; Test passing exceptions back to the
+	application and retaining library internal exceptions.
+
+	* join0.c: New; Test a single join.
+
+2000-01-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* cleanup1.c: New; Test cleanup handler executes (when thread is
+	canceled).
+
+	* cleanup2.c: New; Test cleanup handler executes (when thread is
+	not canceled).
+
+	* cleanup3.c: New; Test cleanup handler does not execute
+	(when thread is not canceled).
+
+2000-01-04  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* cancel4.c: New; Test cancelation does not occur in deferred
+	cancelation threads with no cancelation points.
+
+	* cancel3.c: New; Test asynchronous cancelation.
+
+	* context1.c: New; Test context switching method for async
+	cancelation.
+
+1999-11-23  Ross Johnson  <rpj@special.ise.canberra.edu.au>
+
+	* test.h: Add header includes; include local header versions rather
+	than system versions; rearrange the assert macro defines.
+
+1999-11-07  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* loadfree.c: New. Test loading and freeing the library (DLL).
+
+1999-10-30  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* cancel1.c: New. Test pthread_setcancelstate and
+	pthread_setcanceltype functions.
+	* eyal1.c (waste_time): Change calculation to avoid FP exception
+	on Aplhas
+	- Rich Peters <rpeters@micro-magic.com>
+
+Oct 14 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* condvar7.c: New. Test broadcast after waiting thread is canceled.
+	* condvar8.c: New. Test multiple broadcasts.
+	* condvar9.c: New. Test multiple broadcasts with thread
+	cancelation.
+	
+Sep 16 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* rwlock6.c: New test.
+
+Sep 15 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* rwlock1.c: New test.
+	* rwlock2.c: New test.
+	* rwlock3.c: New test.
+	* rwlock4.c: New test.
+	* rwlock5.c: New test.
+
+Aug 22 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* runall.bat (join2): Add test.
+
+Aug 19 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* join2.c: New test.
+
+Wed Aug 12 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* Makefile (LIBS): Add -L.
+
+Mon May 31 10:25:01 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* Makefile (GLANG): Add GCC language option.
+
+Sat May 29 23:29:04 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* runall.bat (condvar5): Add new test.
+
+	* runall.bat (condvar6): Add new test.
+
+	* Makefile (condvar5) : Add new test.
+	
+	* Makefile (condvar6) : Add new test.
+	
+	* condvar5.c: New test for pthread_cond_broadcast().
+
+	* condvar6.c: New test for pthread_cond_broadcast().
+
+Sun Apr  4 12:04:28 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* tsd1.c (mythread): Change Sleep(0) to sched_yield().
+	(sched.h): Include.
+
+	* condvar3.c (mythread): Remove redundant Sleep().
+
+	* runtest.bat: Re-organised to make more informative.
+
+Fri Mar 19 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* *.bat: redirect unwanted output to nul:
+
+	* runall.bat: new.
+
+	* cancel1.c: new. Not part of suite yet.
+	
+Mon Mar 15 00:17:55 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* mutex1.c: only test mutex init and destroy; add assertions.
+
+	* count1.c: raise number of spawned threads to 60 (appears to
+	be the limit under Win98).
+
+Sun Mar 14 21:31:02 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* test.h (assert): add assertion trace option.
+	Use:
+	"#define ASSERT_TRACE 1" to turn it on,
+	"#define ASSERT_TRACE 0" to turn it off (default).
+
+	* condvar3.c (main): add more assertions.
+
+	* condvar4.c (main): add more assertions.
+
+	* condvar1.c (main): add more assertions.
+
+Fri Mar 12 08:34:15 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* condvar4.c (cvthing): switch the order of the INITIALIZERs.
+
+	* eyal1.c (main): Fix trylock loop; was not waiting for thread to lock
+	the "started" mutex.
+
+Wed Mar 10 10:41:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* tryentercs.c: Apply typo patch from bje.
+
+	* tryentercs2.c: Ditto.
+
+Sun Mar  7 10:41:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* Makefile (condvar3, condvar4): Add tests.
+
+	* condvar4.c (General): Reduce to simple test case; prerequisite
+	is condvar3.c; add description.
+
+	* condvar3.c (General): Reduce to simple test case; prerequisite
+	is condvar2.c; add description.
+
+	* condvar2.c (General): Reduce to simple test case; prerequisite
+	is condvar1.c; add description.
+
+	* condvar1.c (General): Reduce to simple test case; add
+	description.
+
+	* Template.c (Comments): Add generic test detail.
+
+1999-02-23  Ross Johnson  <rpj@ise.canberra.edu.au>
+
+        * Template.c: Revamp.
+
+        * condvar1.c: Add.
+
+        * condvar2.c: Add.
+
+        * Makefile: Add condvar1 condvar2 tests.
+
+        * exit1.c, exit2.c, exit3.c: Cosmetic changes.
+
+1999-02-23  Ross Johnson  <rpj@ise.canberra.edu.au>
+
+	* Makefile: Some refinement.
+
+	* *.c: More exhaustive checking through assertions; clean up;
+	add some more tests.
+
+	* Makefile: Now actually runs the tests.
+
+	* tests.h: Define our own assert macro. The Mingw32
+	version pops up a dialog but we want to run non-interactively.
+
+	* equal1.c: use assert a little more directly so that it
+	prints the actual call statement.
+
+	* exit1.c: Modify to return 0 on success, 1 on failure.
+
+1999-02-22  Ross Johnson  <rpj@ise.canberra.edu.au>
+
+	* self2.c: Bring up to date.
+
+	* self3.c: Ditto.
+
+1999-02-21  Ben Elliston  <bje@cygnus.com>
+
+	* README: Update.
+
+	* Makefile: New file. Run all tests automatically. Primitive tests
+	are run first; more complex tests are run last.
+
+	* count1.c: New test. Validate the thread count.
+
+	* exit2.c: Perform a simpler test.
+	
+	* exit3.c: New test. Replaces exit2.c, since exit2.c needs to
+	perform simpler checking first.
+
+	* create1.c: Update to use the new testsuite exiting convention.
+	
+	* equal1.c: Likewise.
+
+	* mutex1.c: Likewise.
+
+	* mutex2.c: Likewise.
+
+	* once1.c: Likewise.
+
+	* self2.c: Likewise.
+
+	* self3.c: Likewise.
+
+	* tsd1.c: Likewise.
+
+1999-02-20  Ross Johnson  <rpj@ise.canberra.edu.au>
+
+	* mutex2.c: Test static mutex initialisation.
+
+	* test.h: New. Declares a table mapping error numbers to
+	error names.
+
+1999-01-17  Ross Johnson  <rpj@ise.canberra.edu.au>
+
+	* runtest: New script to build and run a test in the tests directory.
+
+Wed Dec 30 11:22:44 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* tsd1.c: Re-written. See comments at start of file.
+	* Template.c: New. Contains skeleton code and comment template
+	intended to fully document the test.
+
+Fri Oct 16 17:59:49 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* tsd1.c (destroy_key): Add function. Change diagnostics.
+
+Thu Oct 15 17:42:37 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
+
+	* tsd1.c (mythread): Fix some casts and add some message
+	output. Fix inverted conditional.
+
+Mon Oct 12 02:12:29 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
+
+	* tsd1.c: New. Test TSD using 1 key and 2 threads.
+
+1998-09-13  Ben Elliston  <bje@cygnus.com>
+
+	* eyal1.c: New file; contributed by Eyal Lebedinsky
+	<eyal@eyal.emu.id.au>.
+
+1998-09-12  Ben Elliston  <bje@cygnus.com>
+
+	* exit2.c (func): Return a value.
+	(main): Call the right thread entry function.
+
+1998-07-22  Ben Elliston  <bje@cygnus.com>
+
+	* exit2.c (main): Fix size of pthread_t array.
+
+1998-07-10  Ben Elliston  <bje@cygnus.com>
+
+	* exit2.c: New file; test pthread_exit() harder.
+
+	* exit1.c: New file; test pthread_exit().
diff --git a/tests/GNUmakefile b/tests/GNUmakefile
index b14db76..2eabdae 100644
--- a/tests/GNUmakefile
+++ b/tests/GNUmakefile
@@ -46,7 +46,10 @@ TESTS	= loadfree \
 	  rwlock1 rwlock2 rwlock3 rwlock4 rwlock5 rwlock6 rwlock7 \
 	  context1 cancel3 cancel4 cancel5 \
 	  cleanup0 cleanup1 cleanup2 cleanup3 \
-	  exception1 exception2 exception3
+	  priority1 priority2 inherit1 \
+	  exception1 exception2 \
+	  benchtest1 benchtest2 \
+	  exception3
 
 PASSES	= $(TESTS:%=%.pass)
 
@@ -71,6 +74,8 @@ all-GC: $(PASSES)
 all-GCE: $(PASSES)
 	@ $(ECHO) ALL TESTS PASSED! Congratulations!
 
+benchtest1.pass: mutex3.pass
+benchtest2.pass: benchtest1.pass
 cancel1.pass: create1.pass
 cancel2.pass: cancel1.pass
 cancel2_1.pass: cancel2.pass
@@ -105,6 +110,7 @@ exit1.pass:
 exit2.pass: create1.pass
 exit3.pass: create1.pass
 eyal1.pass: tsd1.pass
+inherit1.pass: join1.pass
 join0.pass: create1.pass
 join1.pass: create1.pass
 join2.pass: create1.pass
@@ -118,6 +124,8 @@ mutex3.pass: create1.pass
 mutex4.pass: mutex3.pass
 mutex5.pass:
 once1.pass: create1.pass
+priority1.pass: join1.pass
+priority2.pass: priority1.pass
 rwlock1.pass: condvar6.pass
 rwlock2.pass: rwlock1.pass
 rwlock3.pass: rwlock2.pass
diff --git a/tests/Makefile b/tests/Makefile
index afcc156..d7b36b0 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -55,7 +55,9 @@ PASSES= loadfree.pass \
 	  context1.pass  \
 	  cancel3.pass  cancel4.pass  cancel5.pass  \
 	  cleanup0.pass  cleanup1.pass  cleanup2.pass  cleanup3.pass  \
-	  exception1.pass  exception2.pass  exception3.pass
+	  priority1.pass priority2.pass inherit1.pass  \
+	  exception1.pass  exception2.pass  \
+	  benchtest1.pass benchtest2.pass exception3.pass  \
 
 all:
 	@ $(ECHO) Run one of the following command lines:
@@ -114,6 +116,8 @@ clean:
 	- $(RM) *.exe
 	- $(RM) *.pass
 
+benchtest1.pass: mutex3.pass
+benchtest2.pass: benchtest1.pass
 cancel1.pass: create1.pass
 cancel2.pass: cancel1.pass
 cancel3.pass: context1.pass
@@ -147,6 +151,7 @@ exit1.pass:
 exit2.pass: create1.pass
 exit3.pass: create1.pass
 eyal1.pass: tsd1.pass
+inherit1.pass: join1.pass
 join0.pass: create1.pass
 join1.pass: create1.pass
 join2.pass: create1.pass
@@ -160,6 +165,8 @@ mutex3.pass: create1.pass
 mutex4.pass: mutex3.pass
 mutex5.pass:
 once1.pass: create1.pass
+priority1.pass: join1.pass
+priority2.pass: priority1.pass
 rwlock1.pass: condvar6.pass
 rwlock2.pass: rwlock1.pass
 rwlock3.pass: rwlock2.pass
diff --git a/tests/benchtest1.c b/tests/benchtest1.c
new file mode 100644
index 0000000..883c24f
--- /dev/null
+++ b/tests/benchtest1.c
@@ -0,0 +1,117 @@
+/*
+ * benchtest1.c
+ *
+ * Measure time taken to complete an elementary operation.
+ *
+ * - Mutex
+ *   Single thread iteration over lock/unlock for each mutex type.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+#ifdef __GNUC__
+#include <stdlib.h>
+#endif
+
+#define ITERATIONS      10000000L
+
+pthread_mutex_t mx;
+pthread_mutexattr_t ma;
+struct _timeb currSysTimeStart;
+struct _timeb currSysTimeStop;
+long durationMilliSecs;
+long overHeadMilliSecs = 0;
+
+#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \
+                                               - (_TStart.time*1000+_TStart.millitm))
+
+/*
+ * Dummy use of j, otherwise the loop may be removed by the optimiser
+ * when doing the overhead timing with an empty loop.
+ */
+#define TESTSTART \
+  { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++;
+
+#define TESTSTOP \
+  }; _ftime(&currSysTimeStop); if (j + k == i) j++; }
+
+
+void
+runTest (char * testNameString, int mType)
+{
+#ifdef PTHREAD_MUTEX_DEFAULT
+  pthread_mutexattr_settype(&ma, mType);
+#endif
+  pthread_mutex_init(&mx, &ma);
+
+  TESTSTART
+  (void) pthread_mutex_lock(&mx);
+  (void) pthread_mutex_unlock(&mx);
+  TESTSTOP
+
+  pthread_mutex_destroy(&mx);
+
+  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop)
+    - overHeadMilliSecs;
+
+  printf( "%-25s %15ld %15ld %15.3f\n",
+          testNameString,
+          ITERATIONS,
+          durationMilliSecs,
+          (float) durationMilliSecs * 1E3 / ITERATIONS);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  pthread_mutexattr_init(&ma);
+
+  printf( "Single thread, non-blocking mutex locks/unlocks.\n\n");
+  printf( "%-25s %15s %15s %15s\n",
+          "Test",
+          "Iterations",
+          "Total(msec)",
+          "lock/unlock(usec)");
+
+  /*
+   * Time the loop overhead so we can subtract it from the actual test times.
+   */
+
+  TESTSTART
+  TESTSTOP
+
+  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop)
+    - overHeadMilliSecs;
+
+  printf( "%-25s %15ld %15ld\n",
+          "Overhead",
+          ITERATIONS,
+          durationMilliSecs);
+
+  overHeadMilliSecs = durationMilliSecs;
+
+  /*
+   * Now we can start the actual tests
+   */
+#ifdef PTHREAD_MUTEX_DEFAULT
+  runTest("PTHREAD_MUTEX_DEFAULT", PTHREAD_MUTEX_DEFAULT);
+
+  runTest("PTHREAD_MUTEX_NORMAL", PTHREAD_MUTEX_NORMAL);
+
+  runTest("PTHREAD_MUTEX_ERRORCHECK", PTHREAD_MUTEX_ERRORCHECK);
+
+  runTest("PTHREAD_MUTEX_RECURSIVE", PTHREAD_MUTEX_RECURSIVE);
+#else
+  runTest("Non-blocking lock", 0);
+#endif
+
+  /*
+   * End of tests.
+   */
+
+  pthread_mutexattr_destroy(&ma);
+
+  return 0;
+}
diff --git a/tests/benchtest2.c b/tests/benchtest2.c
new file mode 100644
index 0000000..f2932b9
--- /dev/null
+++ b/tests/benchtest2.c
@@ -0,0 +1,183 @@
+/*
+ * benchtest1.c
+ *
+ * Measure time taken to complete an elementary operation.
+ *
+ * - Mutex
+ *   Two threads iterate over lock/unlock for each mutex type.
+ *   The two threads are forced into lock-step using two mutexes,
+ *   forcing the threads to block on each lock operation. The
+ *   time measured is therefore the worst case senario.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+#ifdef __GNUC__
+#include <stdlib.h>
+#endif
+
+#define ITERATIONS      100000L
+
+pthread_mutex_t gate1, gate2;
+pthread_mutexattr_t ma;
+long durationMilliSecs;
+long overHeadMilliSecs = 0;
+struct _timeb currSysTimeStart;
+struct _timeb currSysTimeStop;
+pthread_t worker;
+int running = 0;
+
+#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \
+                                               - (_TStart.time*1000+_TStart.millitm))
+
+/*
+ * Dummy use of j, otherwise the loop may be removed by the optimiser
+ * when doing the overhead timing with an empty loop.
+ */
+#define TESTSTART \
+  { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++;
+
+#define TESTSTOP \
+  }; _ftime(&currSysTimeStop); if (j + k == i) j++; }
+
+
+void *
+overheadThread(void * arg)
+{
+  do
+    {
+      sched_yield();
+    }
+  while (running);
+
+  return NULL;
+}
+
+
+void *
+workerThread(void * arg)
+{
+  do
+    {
+      (void) pthread_mutex_lock(&gate1);
+      (void) pthread_mutex_lock(&gate2);
+      (void) pthread_mutex_unlock(&gate1);
+      sched_yield();
+      (void) pthread_mutex_unlock(&gate2);
+    }
+  while (running);
+
+  return NULL;
+}
+
+void
+runTest (char * testNameString, int mType)
+{
+#ifdef PTHREAD_MUTEX_DEFAULT
+  pthread_mutexattr_settype(&ma, mType);
+#endif
+  pthread_mutex_init(&gate1, &ma);
+  pthread_mutex_init(&gate2, &ma);
+
+  (void) pthread_mutex_lock(&gate1);
+  (void) pthread_mutex_lock(&gate2);
+
+  running = 1;
+
+  (void) pthread_create(&worker, NULL, workerThread, NULL);
+
+  TESTSTART
+  (void) pthread_mutex_unlock(&gate1);
+  sched_yield();
+  (void) pthread_mutex_unlock(&gate2);
+  (void) pthread_mutex_lock(&gate1);
+  (void) pthread_mutex_lock(&gate2);
+  TESTSTOP
+
+  running = 0;
+
+  (void) pthread_mutex_unlock(&gate2);
+  (void) pthread_mutex_unlock(&gate1);
+
+  (void) pthread_join(worker, NULL);
+
+  pthread_mutex_destroy(&gate2);
+  pthread_mutex_destroy(&gate1);
+
+  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop)
+    - overHeadMilliSecs;
+
+  printf( "%-25s %15ld %15ld %15.3f\n",
+          testNameString,
+          ITERATIONS,
+          durationMilliSecs,
+          (float) durationMilliSecs * 1E3 / ITERATIONS / 4   /* Four locks/unlocks per iteration */);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  pthread_mutexattr_init(&ma);
+
+  printf( "Two threads, blocking mutex locks/unlocks.\n\n");
+
+  printf( "%-25s %15s %15s %15s\n",
+          "Test",
+          "Iterations",
+          "Total(msec)",
+          "lock/unlock(usec)");
+
+  /*
+   * Time the loop overhead so we can subtract it from the actual test times.
+   */
+
+  running = 1;
+
+  (void) pthread_create(&worker, NULL, overheadThread, NULL);
+
+  TESTSTART
+  sched_yield();
+  TESTSTOP
+
+  running = 0;
+
+  (void) pthread_join(worker, NULL);
+
+  pthread_mutex_destroy(&gate2);
+  pthread_mutex_destroy(&gate1);
+
+  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop)
+    - overHeadMilliSecs;
+
+  printf( "%-25s %15ld %15ld\n",
+          "Overhead",
+          ITERATIONS,
+          durationMilliSecs);
+
+  overHeadMilliSecs = durationMilliSecs;
+
+  /*
+   * Now we can start the actual tests
+   */
+#ifdef PTHREAD_MUTEX_DEFAULT
+  runTest("PTHREAD_MUTEX_DEFAULT", PTHREAD_MUTEX_DEFAULT);
+
+  runTest("PTHREAD_MUTEX_NORMAL", PTHREAD_MUTEX_NORMAL);
+
+  runTest("PTHREAD_MUTEX_ERRORCHECK", PTHREAD_MUTEX_ERRORCHECK);
+
+  runTest("PTHREAD_MUTEX_RECURSIVE", PTHREAD_MUTEX_RECURSIVE);
+#else
+  runTest("Blocking locks", 0);
+#endif
+
+  /*
+   * End of tests.
+   */
+
+  pthread_mutexattr_destroy(&ma);
+
+  return 0;
+}
diff --git a/tests/cancel5.c b/tests/cancel5.c
index 7d7262a..b12cc1c 100644
--- a/tests/cancel5.c
+++ b/tests/cancel5.c
@@ -1,177 +1,177 @@
-/*
- * File: cancel5.c
- *
- * Test Synopsis: Test calling pthread_cancel from the main thread
- *                without calling pthread_self() in main.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel, pthread_join
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#if defined(_MSC_VER) || defined(__cplusplus)
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 4
-};
-
-typedef struct bag_t_ bag_t;
-struct bag_t_ {
-  int threadnum;
-  int started;
-  /* Add more per-thread state variables here */
-  int count;
-};
-
-static bag_t threadbag[NUMTHREADS + 1];
-
-void *
-mythread(void * arg)
-{
-  int result = ((int)PTHREAD_CANCELED + 1);
-  bag_t * bag = (bag_t *) arg;
-
-  assert(bag == &threadbag[bag->threadnum]);
-  assert(bag->started == 0);
-  bag->started = 1;
-
-  /* Set to known state and type */
-
-  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
-
-  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
-
-  /*
-   * We wait up to 10 seconds, waking every 0.1 seconds,
-   * for a cancelation to be applied to us.
-   */
-  for (bag->count = 0; bag->count < 100; bag->count++)
-    Sleep(100);
-
-  return (void *) result;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t t[NUMTHREADS + 1];
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      threadbag[i].started = 0;
-      threadbag[i].threadnum = i;
-      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(500);
-
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      assert(pthread_cancel(t[i]) == 0);
-    }
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 100);
-
-  /*
-   * Standard check that all threads started.
-   */
-  for (i = 1; i <= NUMTHREADS; i++)
-    { 
-      if (!threadbag[i].started)
-	{
-	  failed |= !threadbag[i].started;
-	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
-	}
-    }
-
-  assert(!failed);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 1; i <= NUMTHREADS; i++)
-    {
-      int fail = 0;
-      int result = 0;
-
-      /*
-       * The thread does not contain any cancelation points, so
-       * a return value of PTHREAD_CANCELED confirms that async
-       * cancelation succeeded.
-       */
-      assert(pthread_join(t[i], (void **) &result) == 0);
-
-      fail = (result != (int) PTHREAD_CANCELED);
-
-      if (fail)
-	{
-	  fprintf(stderr, "Thread %d: started %d: count %d\n",
-		  i,
-		  threadbag[i].started,
-		  threadbag[i].count);
-	}
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
-#else /* defined(_MSC_VER) || defined(__cplusplus) */
-
-int
-main()
-{
-  return 0;
-}
-
-#endif /* defined(_MSC_VER) || defined(__cplusplus) */
+/*
+ * File: cancel5.c
+ *
+ * Test Synopsis: Test calling pthread_cancel from the main thread
+ *                without calling pthread_self() in main.
+ *
+ * Test Method (Validation or Falsification):
+ * - 
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * - 
+ *
+ * Cases Tested:
+ * - 
+ *
+ * Description:
+ * - 
+ *
+ * Environment:
+ * - 
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ *   pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#if defined(_MSC_VER) || defined(__cplusplus)
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+  NUMTHREADS = 4
+};
+
+typedef struct bag_t_ bag_t;
+struct bag_t_ {
+  int threadnum;
+  int started;
+  /* Add more per-thread state variables here */
+  int count;
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+void *
+mythread(void * arg)
+{
+  int result = ((int)PTHREAD_CANCELED + 1);
+  bag_t * bag = (bag_t *) arg;
+
+  assert(bag == &threadbag[bag->threadnum]);
+  assert(bag->started == 0);
+  bag->started = 1;
+
+  /* Set to known state and type */
+
+  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
+
+  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
+
+  /*
+   * We wait up to 10 seconds, waking every 0.1 seconds,
+   * for a cancelation to be applied to us.
+   */
+  for (bag->count = 0; bag->count < 100; bag->count++)
+    Sleep(100);
+
+  return (void *) result;
+}
+
+int
+main()
+{
+  int failed = 0;
+  int i;
+  pthread_t t[NUMTHREADS + 1];
+
+  for (i = 1; i <= NUMTHREADS; i++)
+    {
+      threadbag[i].started = 0;
+      threadbag[i].threadnum = i;
+      assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
+    }
+
+  /*
+   * Code to control or munipulate child threads should probably go here.
+   */
+  Sleep(500);
+
+  for (i = 1; i <= NUMTHREADS; i++)
+    {
+      assert(pthread_cancel(t[i]) == 0);
+    }
+
+  /*
+   * Give threads time to run.
+   */
+  Sleep(NUMTHREADS * 100);
+
+  /*
+   * Standard check that all threads started.
+   */
+  for (i = 1; i <= NUMTHREADS; i++)
+    { 
+      if (!threadbag[i].started)
+	{
+	  failed |= !threadbag[i].started;
+	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
+	}
+    }
+
+  assert(!failed);
+
+  /*
+   * Check any results here. Set "failed" and only print output on failure.
+   */
+  failed = 0;
+  for (i = 1; i <= NUMTHREADS; i++)
+    {
+      int fail = 0;
+      int result = 0;
+
+      /*
+       * The thread does not contain any cancelation points, so
+       * a return value of PTHREAD_CANCELED confirms that async
+       * cancelation succeeded.
+       */
+      assert(pthread_join(t[i], (void **) &result) == 0);
+
+      fail = (result != (int) PTHREAD_CANCELED);
+
+      if (fail)
+	{
+	  fprintf(stderr, "Thread %d: started %d: count %d\n",
+		  i,
+		  threadbag[i].started,
+		  threadbag[i].count);
+	}
+      failed = (failed || fail);
+    }
+
+  assert(!failed);
+
+  /*
+   * Success.
+   */
+  return 0;
+}
+
+#else /* defined(_MSC_VER) || defined(__cplusplus) */
+
+int
+main()
+{
+  return 0;
+}
+
+#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/tests/exception1.c b/tests/exception1.c
index 60038cd..e6ca461 100644
--- a/tests/exception1.c
+++ b/tests/exception1.c
@@ -1,231 +1,231 @@
-/*
- * File: exception1.c
- *
- * Test Synopsis: Test passing of exceptions back to the application.
- *
- * Test Method (Validation or Falsification):
- * - 
- *
- * Requirements Tested:
- * -
- *
- * Features Tested:
- * - 
- *
- * Cases Tested:
- * - 
- *
- * Description:
- * - 
- *
- * Environment:
- * - 
- *
- * Input:
- * - None.
- *
- * Output:
- * - File name, Line number, and failed expression on failure.
- * - No output on success.
- *
- * Assumptions:
- * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
- *   pthread_testcancel, pthread_cancel, pthread_join
- *
- * Pass Criteria:
- * - Process returns zero exit status.
- *
- * Fail Criteria:
- * - Process returns non-zero exit status.
- */
-
-#if defined(_MSC_VER) || defined(__cplusplus)
-
-#include "test.h"
-
-/*
- * Create NUMTHREADS threads in addition to the Main thread.
- */
-enum {
-  NUMTHREADS = 4
-};
-
-void *
-exceptionedThread(void * arg)
-{
-  int dummy = 0;
-  int result = ((int)PTHREAD_CANCELED + 1);
-  /* Set to async cancelable */
-
-  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
-
-  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
-
-  Sleep(100);
-
-#if defined(_MSC_VER) && !defined(__cplusplus)
-  __try
-  {
-    int zero = 0;
-    int one = 1;
-    /*
-     * The deliberate exception condition (zero devide) is
-     * in an "if" to avoid being optimised out.
-     */
-    if (dummy == one/zero)
-      Sleep(0);
-  }
-  __except (EXCEPTION_EXECUTE_HANDLER)
-  {
-    /* Should get into here. */
-    result = ((int)PTHREAD_CANCELED + 2);
-  }
-#elif defined(__cplusplus)
-  try
-  {
-    /*
-     * I had a zero divide exception here but it
-     * wasn't being caught by the catch(...)
-     * below under Mingw32. That could be a problem.
-     */
-    throw dummy;
-  }
-#if defined(PtW32CatchAll)
-  PtW32CatchAll
-#else
-  catch (...)
-#endif
-  {
-    /* Should get into here. */
-    result = ((int)PTHREAD_CANCELED + 2);
-  }
-#endif
-
-  return (void *) result;
-}
-
-void *
-canceledThread(void * arg)
-{
-  int result = ((int)PTHREAD_CANCELED + 1);
-  int count;
-
-  /* Set to async cancelable */
-
-  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
-
-  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
-
-#if defined(_MSC_VER) && !defined(__cplusplus)
-  __try
-  {
-    /*
-     * We wait up to 10 seconds, waking every 0.1 seconds,
-     * for a cancelation to be applied to us.
-     */
-    for (count = 0; count < 100; count++)
-      Sleep(100);
-  }
-  __except (EXCEPTION_EXECUTE_HANDLER)
-  {
-    /* Should NOT get into here. */
-    result = ((int)PTHREAD_CANCELED + 2);
-  }
-#elif defined(__cplusplus)
-  try
-  {
-    /*
-     * We wait up to 10 seconds, waking every 0.1 seconds,
-     * for a cancelation to be applied to us.
-     */
-    for (count = 0; count < 100; count++)
-      Sleep(100);
-  }
-#if defined(PtW32CatchAll)
-  PtW32CatchAll
-#else
-  catch (...)
-#endif
-  {
-    /* Should NOT get into here. */
-    result = ((int)PTHREAD_CANCELED + 2);
-  }
-#endif
-
-  return (void *) result;
-}
-
-int
-main()
-{
-  int failed = 0;
-  int i;
-  pthread_t mt;
-  pthread_t et[NUMTHREADS];
-  pthread_t ct[NUMTHREADS];
-
-  assert((mt = pthread_self()) != NULL);
-
-  for (i = 0; i < NUMTHREADS; i++)
-    {
-      assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0);
-      assert(pthread_create(&ct[i], NULL, canceledThread, NULL) == 0);
-    }
-
-  /*
-   * Code to control or munipulate child threads should probably go here.
-   */
-  Sleep(1000);
-
-  for (i = 0; i < NUMTHREADS; i++)
-    {
-      assert(pthread_cancel(ct[i]) == 0);
-    }
-
-  /*
-   * Give threads time to run.
-   */
-  Sleep(NUMTHREADS * 1000);
-
-  /*
-   * Check any results here. Set "failed" and only print output on failure.
-   */
-  failed = 0;
-  for (i = 0; i < NUMTHREADS; i++)
-    {
-      int fail = 0;
-      int result = 0;
-
-	/* Canceled thread */
-      assert(pthread_join(ct[i], (void **) &result) == 0);
-      assert(!(fail = (result != (int) PTHREAD_CANCELED)));
-
-      failed = (failed || fail);
-
-      /* Exceptioned thread */
-      assert(pthread_join(et[i], (void **) &result) == 0);
-      assert(!(fail = (result != ((int) PTHREAD_CANCELED + 2))));
-
-      failed = (failed || fail);
-    }
-
-  assert(!failed);
-
-  /*
-   * Success.
-   */
-  return 0;
-}
-
-#else /* defined(_MSC_VER) || defined(__cplusplus) */
-
-#include <stdio.h>
-
-int
-main()
-{
-  fprintf(stderr, "Test N/A for this compiler environment.\n");
-  return 0;
-}
-
-#endif /* defined(_MSC_VER) || defined(__cplusplus) */
+/*
+ * File: exception1.c
+ *
+ * Test Synopsis: Test passing of exceptions back to the application.
+ *
+ * Test Method (Validation or Falsification):
+ * - 
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * - 
+ *
+ * Cases Tested:
+ * - 
+ *
+ * Description:
+ * - 
+ *
+ * Environment:
+ * - 
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ *   pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#if defined(_MSC_VER) || defined(__cplusplus)
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+  NUMTHREADS = 4
+};
+
+void *
+exceptionedThread(void * arg)
+{
+  int dummy = 0;
+  int result = ((int)PTHREAD_CANCELED + 1);
+  /* Set to async cancelable */
+
+  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
+
+  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
+
+  Sleep(100);
+
+#if defined(_MSC_VER) && !defined(__cplusplus)
+  __try
+  {
+    int zero = 0;
+    int one = 1;
+    /*
+     * The deliberate exception condition (zero devide) is
+     * in an "if" to avoid being optimised out.
+     */
+    if (dummy == one/zero)
+      Sleep(0);
+  }
+  __except (EXCEPTION_EXECUTE_HANDLER)
+  {
+    /* Should get into here. */
+    result = ((int)PTHREAD_CANCELED + 2);
+  }
+#elif defined(__cplusplus)
+  try
+  {
+    /*
+     * I had a zero divide exception here but it
+     * wasn't being caught by the catch(...)
+     * below under Mingw32. That could be a problem.
+     */
+    throw dummy;
+  }
+#if defined(PtW32CatchAll)
+  PtW32CatchAll
+#else
+  catch (...)
+#endif
+  {
+    /* Should get into here. */
+    result = ((int)PTHREAD_CANCELED + 2);
+  }
+#endif
+
+  return (void *) result;
+}
+
+void *
+canceledThread(void * arg)
+{
+  int result = ((int)PTHREAD_CANCELED + 1);
+  int count;
+
+  /* Set to async cancelable */
+
+  assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
+
+  assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
+
+#if defined(_MSC_VER) && !defined(__cplusplus)
+  __try
+  {
+    /*
+     * We wait up to 10 seconds, waking every 0.1 seconds,
+     * for a cancelation to be applied to us.
+     */
+    for (count = 0; count < 100; count++)
+      Sleep(100);
+  }
+  __except (EXCEPTION_EXECUTE_HANDLER)
+  {
+    /* Should NOT get into here. */
+    result = ((int)PTHREAD_CANCELED + 2);
+  }
+#elif defined(__cplusplus)
+  try
+  {
+    /*
+     * We wait up to 10 seconds, waking every 0.1 seconds,
+     * for a cancelation to be applied to us.
+     */
+    for (count = 0; count < 100; count++)
+      Sleep(100);
+  }
+#if defined(PtW32CatchAll)
+  PtW32CatchAll
+#else
+  catch (...)
+#endif
+  {
+    /* Should NOT get into here. */
+    result = ((int)PTHREAD_CANCELED + 2);
+  }
+#endif
+
+  return (void *) result;
+}
+
+int
+main()
+{
+  int failed = 0;
+  int i;
+  pthread_t mt;
+  pthread_t et[NUMTHREADS];
+  pthread_t ct[NUMTHREADS];
+
+  assert((mt = pthread_self()) != NULL);
+
+  for (i = 0; i < NUMTHREADS; i++)
+    {
+      assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0);
+      assert(pthread_create(&ct[i], NULL, canceledThread, NULL) == 0);
+    }
+
+  /*
+   * Code to control or munipulate child threads should probably go here.
+   */
+  Sleep(1000);
+
+  for (i = 0; i < NUMTHREADS; i++)
+    {
+      assert(pthread_cancel(ct[i]) == 0);
+    }
+
+  /*
+   * Give threads time to run.
+   */
+  Sleep(NUMTHREADS * 1000);
+
+  /*
+   * Check any results here. Set "failed" and only print output on failure.
+   */
+  failed = 0;
+  for (i = 0; i < NUMTHREADS; i++)
+    {
+      int fail = 0;
+      int result = 0;
+
+	/* Canceled thread */
+      assert(pthread_join(ct[i], (void **) &result) == 0);
+      assert(!(fail = (result != (int) PTHREAD_CANCELED)));
+
+      failed = (failed || fail);
+
+      /* Exceptioned thread */
+      assert(pthread_join(et[i], (void **) &result) == 0);
+      assert(!(fail = (result != ((int) PTHREAD_CANCELED + 2))));
+
+      failed = (failed || fail);
+    }
+
+  assert(!failed);
+
+  /*
+   * Success.
+   */
+  return 0;
+}
+
+#else /* defined(_MSC_VER) || defined(__cplusplus) */
+
+#include <stdio.h>
+
+int
+main()
+{
+  fprintf(stderr, "Test N/A for this compiler environment.\n");
+  return 0;
+}
+
+#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/tests/inherit1.c b/tests/inherit1.c
new file mode 100644
index 0000000..a909eb7
--- /dev/null
+++ b/tests/inherit1.c
@@ -0,0 +1,99 @@
+/*
+ * File: inherit1.c
+ *
+ * Test Synopsis:
+ * - Test thread priority inheritance.
+ *
+ * Test Method (Validation or Falsification):
+ * - 
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+void * func(void * arg)
+{
+  int policy;
+  struct sched_param param;
+
+  assert(pthread_getschedparam(pthread_self(), &policy, &param) == 0);
+  return (void *) param.sched_priority;
+}
+
+int
+main()
+{
+  pthread_t t;
+  pthread_t mainThread = pthread_self();
+  pthread_attr_t attr;
+  void * result = NULL;
+  struct sched_param param;
+  struct sched_param mainParam;
+  int maxPrio;
+  int minPrio;
+  int prio;
+  int policy;
+  int inheritsched = -1;
+
+  assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1);
+  assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1);
+
+  assert(pthread_attr_init(&attr) == 0);
+  assert(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED) == 0);
+  assert(pthread_attr_getinheritsched(&attr, &inheritsched) == 0);
+  assert(inheritsched == PTHREAD_INHERIT_SCHED);
+
+  for (prio = minPrio; prio < maxPrio; prio++)
+    {
+      mainParam.sched_priority = prio;
+
+      /* Change the main thread priority */
+      assert(pthread_setschedparam(mainThread, SCHED_OTHER, &mainParam) == 0);
+      assert(pthread_getschedparam(mainThread, &policy, &mainParam) == 0);
+      assert(policy == SCHED_OTHER);
+      assert(mainParam.sched_priority == prio);
+
+      for (param.sched_priority = prio;
+           param.sched_priority <= maxPrio;
+           param.sched_priority++)
+        {
+          /* The new thread create should ignore this new priority */
+          assert(pthread_attr_setschedparam(&attr, &param) == 0);
+          assert(pthread_create(&t, &attr, func, NULL) == 0);
+          pthread_join(t, &result);
+          assert((int) result == mainParam.sched_priority);
+        }
+    }
+
+  return 0;
+}
diff --git a/tests/mutex3.c b/tests/mutex3.c
index 26cb070..07e75b1 100644
--- a/tests/mutex3.c
+++ b/tests/mutex3.c
@@ -33,8 +33,7 @@ main()
   assert(pthread_mutex_lock(&mutex1) == 0);
 
   assert(pthread_create(&t, NULL, func, NULL) == 0);
-
-  Sleep(2000);
+  assert(pthread_join(t, NULL) == 0);
 
   assert(pthread_mutex_unlock(&mutex1) == 0);
 
diff --git a/tests/mutex4.c b/tests/mutex4.c
index 7b989d0..1bf236b 100644
--- a/tests/mutex4.c
+++ b/tests/mutex4.c
@@ -13,42 +13,61 @@
 
 static int wasHere = 0;
 
-static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
-
-void * locker(void * arg)
-{
-  wasHere++;
-  assert(pthread_mutex_lock(&mutex1) == 0);
-  Sleep(1000);
-  assert(pthread_mutex_unlock(&mutex1) == 0);
-
-  wasHere++;
-  return 0;
-}
+static pthread_mutex_t mutex1;
  
 void * unlocker(void * arg)
 {
-  wasHere++;
-
-  /* Wait for locker to lock mutex1 */
-  Sleep(500);
-
-  assert(pthread_mutex_unlock(&mutex1) == EPERM);
+  int expectedResult = (int) arg;
 
   wasHere++;
-  return 0;
+  assert(pthread_mutex_unlock(&mutex1) == expectedResult);
+  wasHere++;
+  return NULL;
 }
  
 int
 main()
 {
   pthread_t t;
+  pthread_mutexattr_t ma;
 
-  assert(pthread_create(&t, NULL, locker, NULL) == 0);
-  assert(pthread_create(&t, NULL, unlocker, NULL) == 0);
-  Sleep(2000);
+  assert(pthread_mutexattr_init(&ma) == 0);
 
-  assert(wasHere == 4);
+  wasHere = 0;
+  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_DEFAULT) == 0);
+  assert(pthread_mutex_init(&mutex1, &ma) == 0);
+  assert(pthread_mutex_lock(&mutex1) == 0);
+  assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0);
+  assert(pthread_join(t, NULL) == 0);
+  assert(pthread_mutex_unlock(&mutex1) == EPERM);
+  assert(wasHere == 2);
+
+  wasHere = 0;
+  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_NORMAL) == 0);
+  assert(pthread_mutex_init(&mutex1, &ma) == 0);
+  assert(pthread_mutex_lock(&mutex1) == 0);
+  assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0);
+  assert(pthread_join(t, NULL) == 0);
+  assert(pthread_mutex_unlock(&mutex1) == EPERM);
+  assert(wasHere == 2);
+
+  wasHere = 0;
+  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0);
+  assert(pthread_mutex_init(&mutex1, &ma) == 0);
+  assert(pthread_mutex_lock(&mutex1) == 0);
+  assert(pthread_create(&t, NULL, unlocker, (void *) EPERM) == 0);
+  assert(pthread_join(t, NULL) == 0);
+  assert(pthread_mutex_unlock(&mutex1) == 0);
+  assert(wasHere == 2);
+
+  wasHere = 0;
+  assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE) == 0);
+  assert(pthread_mutex_init(&mutex1, &ma) == 0);
+  assert(pthread_mutex_lock(&mutex1) == 0);
+  assert(pthread_create(&t, NULL, unlocker, (void *) EPERM) == 0);
+  assert(pthread_join(t, NULL) == 0);
+  assert(pthread_mutex_unlock(&mutex1) == 0);
+  assert(wasHere == 2);
 
   return 0;
 }
diff --git a/tests/mutex5.c b/tests/mutex5.c
index d7b9064..1f90e19 100644
--- a/tests/mutex5.c
+++ b/tests/mutex5.c
@@ -13,18 +13,18 @@ int
 main()
 {
   int mxType = -1;
-  int bool = 0;   /* Use to quell GNU compiler warnings. */
+  int success = 0;   /* Use to quell GNU compiler warnings. */
 
-  assert(bool = PTHREAD_MUTEX_DEFAULT == PTHREAD_MUTEX_NORMAL);
-  assert(bool = PTHREAD_MUTEX_DEFAULT != PTHREAD_MUTEX_ERRORCHECK);
-  assert(bool = PTHREAD_MUTEX_DEFAULT != PTHREAD_MUTEX_RECURSIVE);
-  assert(bool = PTHREAD_MUTEX_RECURSIVE != PTHREAD_MUTEX_ERRORCHECK);
+  assert(success = PTHREAD_MUTEX_DEFAULT == PTHREAD_MUTEX_NORMAL);
+  assert(success = PTHREAD_MUTEX_DEFAULT != PTHREAD_MUTEX_ERRORCHECK);
+  assert(success = PTHREAD_MUTEX_DEFAULT != PTHREAD_MUTEX_RECURSIVE);
+  assert(success = PTHREAD_MUTEX_RECURSIVE != PTHREAD_MUTEX_ERRORCHECK);
 
-  assert(bool = PTHREAD_MUTEX_NORMAL == PTHREAD_MUTEX_FAST_NP);
-  assert(bool = PTHREAD_MUTEX_RECURSIVE == PTHREAD_MUTEX_RECURSIVE_NP);
-  assert(bool = PTHREAD_MUTEX_ERRORCHECK == PTHREAD_MUTEX_ERRORCHECK_NP);
+  assert(success = PTHREAD_MUTEX_NORMAL == PTHREAD_MUTEX_FAST_NP);
+  assert(success = PTHREAD_MUTEX_RECURSIVE == PTHREAD_MUTEX_RECURSIVE_NP);
+  assert(success = PTHREAD_MUTEX_ERRORCHECK == PTHREAD_MUTEX_ERRORCHECK_NP);
 
-  if (bool == bool)
+  if (success == success)
     {
       assert(pthread_mutexattr_init(&mxAttr) == 0);
       assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
diff --git a/tests/priority1.c b/tests/priority1.c
new file mode 100644
index 0000000..a311028
--- /dev/null
+++ b/tests/priority1.c
@@ -0,0 +1,78 @@
+/*
+ * File: priority1.c
+ *
+ * Test Synopsis:
+ * - Test thread priority explicit setting using thread attribute.
+ *
+ * Test Method (Validation or Falsification):
+ * - 
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+void * func(void * arg)
+{
+  int policy;
+  struct sched_param param;
+
+  assert(pthread_getschedparam(pthread_self(), &policy, &param) == 0);
+  assert(policy == SCHED_OTHER);
+  return (void *) param.sched_priority;
+}
+ 
+int
+main()
+{
+  pthread_t t;
+  pthread_attr_t attr;
+  void * result = NULL;
+  struct sched_param param;
+  int maxPrio = sched_get_priority_max(SCHED_OTHER);
+  int minPrio = sched_get_priority_min(SCHED_OTHER);
+
+  assert(pthread_attr_init(&attr) == 0);
+  assert(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0);
+
+  for (param.sched_priority = minPrio;
+       param.sched_priority <= maxPrio;
+       param.sched_priority++)
+    {
+      assert(pthread_attr_setschedparam(&attr, &param) == 0);
+      assert(pthread_create(&t, &attr, func, NULL) == 0);
+      pthread_join(t, &result);
+      assert((int) result == param.sched_priority);
+    }
+
+  return 0;
+}
diff --git a/tests/priority2.c b/tests/priority2.c
new file mode 100644
index 0000000..4dcf385
--- /dev/null
+++ b/tests/priority2.c
@@ -0,0 +1,80 @@
+/*
+ * File: priority2.c
+ *
+ * Test Synopsis:
+ * - Test thread priority setting after creation.
+ *
+ * Test Method (Validation or Falsification):
+ * - 
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+pthread_mutex_t startMx = PTHREAD_MUTEX_INITIALIZER;
+
+void * func(void * arg)
+{
+  int policy;
+  struct sched_param param;
+
+  assert(pthread_mutex_lock(&startMx) == 0);
+  assert(pthread_getschedparam(pthread_self(), &policy, &param) == 0);
+  assert(pthread_mutex_unlock(&startMx) == 0);
+  assert(policy == SCHED_OTHER);
+  return (void *) param.sched_priority;
+}
+ 
+int
+main()
+{
+  pthread_t t;
+  void * result = NULL;
+  struct sched_param param;
+  int maxPrio = sched_get_priority_max(SCHED_OTHER);
+  int minPrio = sched_get_priority_min(SCHED_OTHER);
+
+  for (param.sched_priority = minPrio;
+       param.sched_priority <= maxPrio;
+       param.sched_priority++)
+    {
+      assert(pthread_mutex_lock(&startMx) == 0);
+      assert(pthread_create(&t, NULL, func, NULL) == 0);
+      assert(pthread_setschedparam(t, SCHED_OTHER, &param) == 0);
+      assert(pthread_mutex_unlock(&startMx) == 0);
+      pthread_join(t, &result);
+      assert((int) result == param.sched_priority);
+    }
+
+  return 0;
+}
-- 
cgit v1.2.3