diff options
| author | rpj <rpj> | 2001-07-01 13:23:10 +0000 | 
|---|---|---|
| committer | rpj <rpj> | 2001-07-01 13:23:10 +0000 | 
| commit | a311086d622d3c778e1da57cfae167c0ab1c0fb4 (patch) | |
| tree | 760a76a351c18331ff92239366804bd4b866dea6 | |
| parent | 528fccade9ca5f90db376e08b2cb85b3fc822a45 (diff) | |
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.
| -rw-r--r-- | ANNOUNCE | 238 | ||||
| -rw-r--r-- | CONTRIBUTORS | 2 | ||||
| -rw-r--r-- | ChangeLog | 6347 | ||||
| -rw-r--r-- | Nmakefile | 2 | ||||
| -rw-r--r-- | Nmakefile.tests | 16 | ||||
| -rw-r--r-- | attr.c | 10 | ||||
| -rw-r--r-- | create.c | 80 | ||||
| -rw-r--r-- | implement.h | 13 | ||||
| -rw-r--r-- | mutex.c | 27 | ||||
| -rw-r--r-- | pthread.def | 15 | ||||
| -rw-r--r-- | pthread.h | 98 | ||||
| -rw-r--r-- | sched.c | 410 | ||||
| -rw-r--r-- | sched.h | 48 | ||||
| -rw-r--r-- | tests/ChangeLog | 1017 | ||||
| -rw-r--r-- | tests/GNUmakefile | 10 | ||||
| -rw-r--r-- | tests/Makefile | 9 | ||||
| -rw-r--r-- | tests/benchtest1.c | 117 | ||||
| -rw-r--r-- | tests/benchtest2.c | 183 | ||||
| -rw-r--r-- | tests/cancel5.c | 354 | ||||
| -rw-r--r-- | tests/exception1.c | 462 | ||||
| -rw-r--r-- | tests/inherit1.c | 99 | ||||
| -rw-r--r-- | tests/mutex3.c | 3 | ||||
| -rw-r--r-- | tests/mutex4.c | 65 | ||||
| -rw-r--r-- | tests/mutex5.c | 18 | ||||
| -rw-r--r-- | tests/priority1.c | 78 | ||||
| -rw-r--r-- | tests/priority2.c | 80 | 
26 files changed, 5521 insertions, 4280 deletions
| @@ -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
 +
 @@ -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. @@ -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: + @@ -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)  { @@ -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; @@ -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
 @@ -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); @@ -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        *        * ------------------------------------------------------        */ @@ -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, ¶m) == 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, ¶m) == 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, ¶m) == 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, ¶m) == 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, ¶m) == 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, ¶m) == 0); +      assert(pthread_mutex_unlock(&startMx) == 0); +      pthread_join(t, &result); +      assert((int) result == param.sched_priority); +    } + +  return 0; +} | 
