diff options
| author | rpj <rpj> | 2005-04-25 14:42:37 +0000 | 
|---|---|---|
| committer | rpj <rpj> | 2005-04-25 14:42:37 +0000 | 
| commit | 3ef98898333255b8000e9ab4801652c42fd5aacc (patch) | |
| tree | 58fbe722c2011a392ffb47ad56b97fe44e2fe59c | |
| parent | 75a3015fd7412637a02b1b016b367f5deadfde94 (diff) | |
''
| -rw-r--r-- | ANNOUNCE | 930 | ||||
| -rw-r--r-- | BUGS | 214 | ||||
| -rw-r--r-- | Bmakefile | 530 | ||||
| -rw-r--r-- | CONTRIBUTORS | 238 | ||||
| -rw-r--r-- | ChangeLog | 9168 | ||||
| -rw-r--r-- | GNUmakefile | 1140 | ||||
| -rw-r--r-- | Makefile | 1004 | ||||
| -rw-r--r-- | NEWS | 1772 | ||||
| -rw-r--r-- | Nmakefile | 48 | ||||
| -rw-r--r-- | Nmakefile.tests | 520 | ||||
| -rw-r--r-- | README | 1136 | ||||
| -rw-r--r-- | README.Borland | 80 | ||||
| -rw-r--r-- | implement.h | 1302 | ||||
| -rw-r--r-- | private.c | 112 | ||||
| -rw-r--r-- | pthread.dsp | 284 | ||||
| -rw-r--r-- | pthread.dsw | 58 | ||||
| -rw-r--r-- | pthread.h | 2782 | ||||
| -rw-r--r-- | pthread_mutex_timedlock.c | 392 | ||||
| -rw-r--r-- | pthread_once.c | 806 | ||||
| -rw-r--r-- | ptw32_increase_semaphore.c | 146 | ||||
| -rw-r--r-- | ptw32_relmillisecs.c | 240 | ||||
| -rw-r--r-- | ptw32_semwait.c | 236 | ||||
| -rw-r--r-- | sem_destroy.c | 292 | ||||
| -rw-r--r-- | sem_getvalue.c | 202 | ||||
| -rw-r--r-- | sem_init.c | 328 | ||||
| -rw-r--r-- | sem_post.c | 224 | ||||
| -rw-r--r-- | sem_post_multiple.c | 242 | ||||
| -rw-r--r-- | sem_timedwait.c | 440 | ||||
| -rw-r--r-- | sem_trywait.c | 216 | ||||
| -rw-r--r-- | sem_wait.c | 324 | ||||
| -rw-r--r-- | semaphore.c | 138 | ||||
| -rw-r--r-- | tests/Bmakefile | 690 | ||||
| -rw-r--r-- | tests/ChangeLog | 1746 | ||||
| -rw-r--r-- | tests/GNUmakefile | 698 | ||||
| -rw-r--r-- | tests/Makefile | 738 | ||||
| -rw-r--r-- | tests/README.benchtests | 194 | ||||
| -rw-r--r-- | tests/Wmakefile | 682 | ||||
| -rw-r--r-- | tests/benchtest1.c | 498 | ||||
| -rw-r--r-- | tests/benchtest5.c | 318 | ||||
| -rw-r--r-- | tests/condvar3.c | 296 | ||||
| -rw-r--r-- | tests/condvar3_1.c | 402 | ||||
| -rw-r--r-- | tests/condvar3_2.c | 386 | ||||
| -rw-r--r-- | tests/condvar3_3.c | 264 | ||||
| -rw-r--r-- | tests/condvar4.c | 338 | ||||
| -rw-r--r-- | tests/condvar5.c | 336 | ||||
| -rw-r--r-- | tests/condvar6.c | 484 | ||||
| -rw-r--r-- | tests/condvar7.c | 514 | ||||
| -rw-r--r-- | tests/condvar8.c | 516 | ||||
| -rw-r--r-- | tests/condvar9.c | 534 | ||||
| -rw-r--r-- | tests/once4.c | 382 | ||||
| -rw-r--r-- | tests/semaphore1.c | 318 | 
51 files changed, 17939 insertions, 17939 deletions
@@ -1,465 +1,465 @@ -	     PTHREADS-WIN32 RELEASE 2.3.0 (2005-04-12)
 -	     -----------------------------------------
 -	 Web Site: http://sources.redhat.com/pthreads-win32/
 -	FTP Site: ftp://sources.redhat.com/pub/pthreads-win32
 -	 Maintainer: Ross Johnson <rpj@callisto.canberra.edu.au>
 -
 -
 -We are pleased to announce the availability of a new release of
 -Pthreads-win32, an Open Source Software implementation of the
 -Threads component of the POSIX 1003.1 2001 Standard for Microsoft's
 -Win32 environment. Some functions from other sections of POSIX
 -1003.1 2001 are also supported including semaphores and scheduling
 -functions.
 -
 -Some common non-portable functions are also implemented for
 -additional compatibility, as are a few functions specific
 -to pthreads-win32 for easier integration with Win32 applications.
 -
 -Pthreads-win32 is free software, distributed under the GNU Lesser
 -General Public License (LGPL).
 -
 -
 -Acknowledgements
 -----------------
 -This library is based originally on a Win32 pthreads
 -implementation contributed by John Bossom <John.Bossom@cognos.com>.
 -
 -The implementation of Condition Variables uses algorithms developed
 -by Alexander Terekhov and Louis Thomas.
 -
 -The implementation of POSIX mutexes has been improved by Thomas Pfaff
 -and later by Alexander Terekhov.
 -
 -The implementation of Spinlocks and Barriers was contributed
 -by Ross Johnson.
 -
 -The implementation of read/write locks was contributed by
 -Aurelio Medina and improved by Alexander Terekhov.
 -
 -Many others have contributed significant time and effort to solve crutial
 -problems in order to make the library workable, robust and reliable.
 -
 -There is also a separate CONTRIBUTORS file. This file and others are
 -on the web site:
 -
 -	http://sources.redhat.com/pthreads-win32
 -
 -As much as possible, the ChangeLog file acknowledges contributions to the
 -code base in more detail.
 -
 -
 -Changes since the last release
 -------------------------------
 -These are now documented in the NEWS file.
 -See the ChangeLog file also.
 -
 -
 -Known Bugs
 -----------
 -These are now documented in the BUGS file.
 -
 -
 -Level of standards conformance
 -------------------------------
 -
 -The following POSIX 1003.1 2001 options are defined and set to 200112L:
 -
 -      _POSIX_THREADS
 -      _POSIX_THREAD_SAFE_FUNCTIONS
 -      _POSIX_THREAD_ATTR_STACKSIZE
 -      _POSIX_THREAD_PRIORITY_SCHEDULING
 -      _POSIX_SEMAPHORES
 -      _POSIX_READER_WRITER_LOCKS
 -      _POSIX_SPIN_LOCKS
 -      _POSIX_BARRIERS
 -
 -
 -The following POSIX 1003.1 2001 options are defined and set to -1:
 -
 -      _POSIX_THREAD_ATTR_STACKADDR
 -      _POSIX_THREAD_PRIO_INHERIT
 -      _POSIX_THREAD_PRIO_PROTECT
 -      _POSIX_THREAD_PROCESS_SHARED
 -
 -
 -The following POSIX 1003.1 2001 options are defined and set:
 -
 -      _POSIX_THREAD_THREADS_MAX
 -      _POSIX_SEM_VALUE_MAX
 -      _POSIX_SEM_NSEMS_MAX
 -      PTHREAD_DESTRUCTOR_ITERATIONS
 -      PTHREAD_KEYS_MAX
 -      PTHREAD_STACK_MIN
 -      PTHREAD_THREADS_MAX
 -      
 -
 -The following functions are implemented:
 -
 -      ---------------------------
 -      PThreads
 -      ---------------------------
 -      pthread_attr_init
 -      pthread_attr_destroy
 -      pthread_attr_getdetachstate
 -      pthread_attr_getstackaddr
 -      pthread_attr_getstacksize
 -      pthread_attr_setdetachstate
 -      pthread_attr_setstackaddr
 -      pthread_attr_setstacksize
 -
 -      pthread_create
 -      pthread_detach
 -      pthread_equal
 -      pthread_exit
 -      pthread_join
 -      pthread_once
 -      pthread_self
 -
 -      pthread_cancel
 -      pthread_cleanup_pop
 -      pthread_cleanup_push
 -      pthread_setcancelstate
 -      pthread_setcanceltype
 -      pthread_testcancel
 -
 -      ---------------------------
 -      Thread Specific Data
 -      ---------------------------
 -      pthread_key_create
 -      pthread_key_delete
 -      pthread_setspecific
 -      pthread_getspecific
 -
 -      ---------------------------
 -      Mutexes
 -      ---------------------------
 -      pthread_mutexattr_init
 -      pthread_mutexattr_destroy
 -      pthread_mutexattr_getpshared
 -      pthread_mutexattr_setpshared
 -      pthread_mutexattr_gettype
 -      pthread_mutexattr_settype (types: PTHREAD_MUTEX_DEFAULT
 -					PTHREAD_MUTEX_NORMAL
 -					PTHREAD_MUTEX_ERRORCHECK
 -					PTHREAD_MUTEX_RECURSIVE  )
 -      pthread_mutex_init
 -      pthread_mutex_destroy
 -      pthread_mutex_lock
 -      pthread_mutex_trylock
 -      pthread_mutex_timedlock
 -      pthread_mutex_unlock
 -
 -      ---------------------------
 -      Condition Variables
 -      ---------------------------
 -      pthread_condattr_init
 -      pthread_condattr_destroy
 -      pthread_condattr_getpshared
 -      pthread_condattr_setpshared
 -
 -      pthread_cond_init
 -      pthread_cond_destroy
 -      pthread_cond_wait
 -      pthread_cond_timedwait
 -      pthread_cond_signal
 -      pthread_cond_broadcast
 -
 -      ---------------------------
 -      Read/Write Locks
 -      ---------------------------
 -      pthread_rwlock_init
 -      pthread_rwlock_destroy
 -      pthread_rwlock_tryrdlock
 -      pthread_rwlock_trywrlock
 -      pthread_rwlock_rdlock
 -      pthread_rwlock_timedrdlock
 -      pthread_rwlock_rwlock
 -      pthread_rwlock_timedwrlock
 -      pthread_rwlock_unlock
 -      pthread_rwlockattr_init
 -      pthread_rwlockattr_destroy
 -      pthread_rwlockattr_getpshared
 -      pthread_rwlockattr_setpshared
 -
 -      ---------------------------
 -      Spin Locks
 -      ---------------------------
 -      pthread_spin_init
 -      pthread_spin_destroy
 -      pthread_spin_lock
 -      pthread_spin_unlock
 -      pthread_spin_trylock
 -
 -      ---------------------------
 -      Barriers
 -      ---------------------------
 -      pthread_barrier_init
 -      pthread_barrier_destroy
 -      pthread_barrier_wait
 -      pthread_barrierattr_init
 -      pthread_barrierattr_destroy
 -      pthread_barrierattr_getpshared
 -      pthread_barrierattr_setpshared
 -
 -      ---------------------------
 -      Semaphores
 -      ---------------------------
 -      sem_init
 -      sem_destroy
 -      sem_post
 -      sem_wait
 -      sem_trywait
 -      sem_timedwait
 -      sem_open		     (returns an error ENOSYS)
 -      sem_close 	     (returns an error ENOSYS)
 -      sem_unlink	     (returns an error ENOSYS)
 -      sem_getvalue	     (returns an error ENOSYS)
 -
 -      ---------------------------
 -      RealTime Scheduling
 -      ---------------------------
 -      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
 -      pthread_setconcurrency
 -      pthread_attr_getscope
 -      pthread_attr_setscope  (only supports PTHREAD_SCOPE_SYSTEM)
 -      sched_get_priority_max
 -      sched_get_priority_min
 -      sched_rr_get_interval  (returns an error ENOTSUP)
 -      sched_setscheduler     (only supports SCHED_OTHER)
 -      sched_getscheduler     (only supports SCHED_OTHER)
 -      sched_yield
 -
 -      ---------------------------
 -      Signals
 -      ---------------------------
 -      pthread_sigmask
 -      pthread_kill           (only supports zero sig value,
 -                              for thread validity checking)
 -
 -      ---------------------------
 -      Non-portable routines (see the README.NONPORTABLE file for usage)
 -      ---------------------------
 -      pthread_getw32threadhandle_np
 -      pthread_timechange_handler_np
 -      pthread_delay_np
 -      pthread_mutexattr_getkind_np
 -      pthread_mutexattr_setkind_np	(types: PTHREAD_MUTEX_FAST_NP,
 -						PTHREAD_MUTEX_ERRORCHECK_NP,
 -						PTHREAD_MUTEX_RECURSIVE_NP,
 -						PTHREAD_MUTEX_ADAPTIVE_NP,
 -						PTHREAD_MUTEX_TIMED_NP)
 -      pthread_num_processors_np
 -      pthread_win32_process_attach_np	(Required when statically linking
 -                                         the library)
 -      pthread_win32_process_detach_np	(Required when statically linking
 -                                         the library)
 -      pthread_win32_thread_attach_np	(Required when statically linking
 -                                         the library)
 -      pthread_win32_thread_detach_np	(Required when statically linking
 -                                         the library)
 -
 -      ---------------------------
 -      Static Initializers
 -      ---------------------------
 -      PTHREAD_ONCE_INIT
 -      PTHREAD_MUTEX_INITIALIZER
 -      PTHREAD_RECURSIVE_MUTEX_INITIALIZER
 -      PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
 -      PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
 -      PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
 -      PTHREAD_COND_INITIALIZER
 -      PTHREAD_RWLOCK_INITIALIZER
 -      PTHREAD_SPINLOCK_INITIALIZER
 -
 -      ---------------------------
 -      Thread-Safe C Runtime Library (macros)
 -      ---------------------------
 -      strtok_r
 -      asctime_r
 -      ctime_r
 -      gmtime_r
 -      localtime_r
 -      rand_r
 -
 -
 -The following functions are not implemented:
 -      
 -      ---------------------------
 -      RealTime Scheduling
 -      ---------------------------
 -      pthread_mutex_getprioceiling
 -      pthread_mutex_setprioceiling
 -      pthread_mutex_attr_getprioceiling
 -      pthread_mutex_attr_getprotocol
 -      pthread_mutex_attr_setprioceiling
 -      pthread_mutex_attr_setprotocol
 -
 -      ---------------------------
 -      Fork Handlers
 -      ---------------------------
 -      pthread_atfork
 -
 -      ---------------------------
 -      Stdio
 -      --------------------------- 
 -      flockfile
 -      ftrylockfile
 -      funlockfile
 -      getc_unlocked
 -      getchar_unlocked	
 -      putc_unlocked
 -      putchar_unlocked
 -
 -      ---------------------------
 -      Thread-Safe C Runtime Library
 -      ---------------------------
 -      readdir_r
 -      getgrgid_r
 -      getgrnam_r
 -      getpwuid_r
 -      getpwnam_r
 -      
 -      ---------------------------
 -      Signals
 -      ---------------------------
 -      sigtimedwait
 -      sigwait
 -      sigwaitinfo
 -
 -      ---------------------------
 -      General
 -      ---------------------------
 -      sysconf      
 -
 -The library includes two non-API functions for creating cancellation
 -points in applications and libraries:
 -      
 -      pthreadCancelableWait
 -      pthreadCancelableTimedWait
 -
 -      
 -Availability
 ------------- 
 -
 -The prebuilt DLL, export libs (for both MSVC and Mingw32), and the header
 -files (pthread.h, semaphore.h, sched.h) are available along with the
 -complete source code.
 -
 -The source code can be found at:
 -
 -	ftp://sources.redhat.com/pub/pthreads-win32
 -
 -and as individual source code files at
 -
 -	ftp://sources.redhat.com/pub/pthreads-win32/source
 -
 -The pre-built DLL, export libraries and include files can be found at:
 -
 -	ftp://sources.redhat.com/pub/pthreads-win32/dll-latest
 -
 -
 -      
 -Mailing List 
 -------------  
 -      
 -There is a mailing list for discussing pthreads on Win32. To join,
 -send email to:
 -
 -	pthreads-win32-subscribe@sourceware.cygnus.com
 -      
 -
 -Application Development Environments
 -------------------------------------
 -
 -See the README file for more information.
 -      
 -MSVC:
 -MSVC using SEH works. Distribute pthreadVSE.dll with your application.
 -MSVC using C++ EH works. Distribute pthreadVCE.dll with your application.
 -MSVC using C setjmp/longjmp works. Distribute pthreadVC.dll with your application.
 -
 -
 -Mingw32:
 -See the FAQ, Questions 6 and 10.
 -
 -Mingw using C++ EH works. Distribute pthreadGCE.dll with your application.
 -Mingw using C setjmp/longjmp works. Distribute pthreadGC.dll with your application.
 -
 -
 -Cygwin: (http://sourceware.cygnus.com/cygwin/)
 -Developers using Cygwin will not need pthreads-win32 since it has POSIX threads
 -support. Refer to its documentation for details and extent.
 -
 -
 -UWIN:
 -UWIN is a complete Unix-like environment for Windows from AT&T. Pthreads-win32
 -doesn't currently support UWIN (and vice versa), but that may change in the
 -future.
 -
 -Generally:
 -For convenience, the following pre-built files are available on the FTP site
 -(see Availability above):
 -
 -	pthread.h	- for POSIX 1c threads
 -	semaphore.h	- for POSIX 1b semaphores
 -	sched.h 	- for POSIX 1b scheduling
 -	pthreadVCE.dll	- built with MSVC++ compiler using C++ EH
 -	pthreadVCE.lib
 -	pthreadVC.dll	- built with MSVC compiler using C setjmp/longjmp
 -	pthreadVC.lib
 -	pthreadVSE.dll	- built with MSVC compiler using SEH
 -	pthreadVSE.lib
 -	pthreadGCE.dll	- built with Mingw32 G++ 2.95.2-1
 -	pthreadGC.dll	- built with Mingw32 GCC 2.95.2-1 using setjmp/longjmp
 -	libpthreadGCE.a - derived from pthreadGCE.dll
 -	libpthreadGC.a	- derived from pthreadGC.dll
 -	gcc.dll 	- needed if distributing applications that use
 -			  pthreadGCE.dll (but see the FAQ Q 10 for the latest
 -			  related information)
 -
 -These are the only files you need in order to build POSIX threads
 -applications for Win32 using either MSVC or Mingw32.
 -
 -See the FAQ file in the source tree for additional information.
 -
 -
 -Documentation
 --------------
 -
 -For the authoritative reference, see the online POSIX
 -standard reference at:
 -
 -       http://www.OpenGroup.org
 -
 -For POSIX Thread API programming, several reference books are
 -available:
 -
 -       Programming with POSIX Threads
 -       David R. Butenhof
 -       Addison-Wesley (pub)
 -
 -       Pthreads Programming
 -       By Bradford Nichols, Dick Buttlar & Jacqueline Proulx Farrell
 -       O'Reilly (pub)
 -
 -On the web: see the links at the bottom of the pthreads-win32 site:
 -
 -       http://sources.redhat.com/pthreads-win32/
 -
 -       Currently, there is no documentation included in the package apart
 -       from the copious comments in the source code.
 -
 -
 -
 -Enjoy!
 -
 -Ross Johnson
 +	     PTHREADS-WIN32 RELEASE 2.3.0 (2005-04-12) +	     ----------------------------------------- +	 Web Site: http://sources.redhat.com/pthreads-win32/ +	FTP Site: ftp://sources.redhat.com/pub/pthreads-win32 +	 Maintainer: Ross Johnson <rpj@callisto.canberra.edu.au> + + +We are pleased to announce the availability of a new release of +Pthreads-win32, an Open Source Software implementation of the +Threads component of the POSIX 1003.1 2001 Standard for Microsoft's +Win32 environment. Some functions from other sections of POSIX +1003.1 2001 are also supported including semaphores and scheduling +functions. + +Some common non-portable functions are also implemented for +additional compatibility, as are a few functions specific +to pthreads-win32 for easier integration with Win32 applications. + +Pthreads-win32 is free software, distributed under the GNU Lesser +General Public License (LGPL). + + +Acknowledgements +---------------- +This library is based originally on a Win32 pthreads +implementation contributed by John Bossom <John.Bossom@cognos.com>. + +The implementation of Condition Variables uses algorithms developed +by Alexander Terekhov and Louis Thomas. + +The implementation of POSIX mutexes has been improved by Thomas Pfaff +and later by Alexander Terekhov. + +The implementation of Spinlocks and Barriers was contributed +by Ross Johnson. + +The implementation of read/write locks was contributed by +Aurelio Medina and improved by Alexander Terekhov. + +Many others have contributed significant time and effort to solve crutial +problems in order to make the library workable, robust and reliable. + +There is also a separate CONTRIBUTORS file. This file and others are +on the web site: + +	http://sources.redhat.com/pthreads-win32 + +As much as possible, the ChangeLog file acknowledges contributions to the +code base in more detail. + + +Changes since the last release +------------------------------ +These are now documented in the NEWS file. +See the ChangeLog file also. + + +Known Bugs +---------- +These are now documented in the BUGS file. + + +Level of standards conformance +------------------------------ + +The following POSIX 1003.1 2001 options are defined and set to 200112L: + +      _POSIX_THREADS +      _POSIX_THREAD_SAFE_FUNCTIONS +      _POSIX_THREAD_ATTR_STACKSIZE +      _POSIX_THREAD_PRIORITY_SCHEDULING +      _POSIX_SEMAPHORES +      _POSIX_READER_WRITER_LOCKS +      _POSIX_SPIN_LOCKS +      _POSIX_BARRIERS + + +The following POSIX 1003.1 2001 options are defined and set to -1: + +      _POSIX_THREAD_ATTR_STACKADDR +      _POSIX_THREAD_PRIO_INHERIT +      _POSIX_THREAD_PRIO_PROTECT +      _POSIX_THREAD_PROCESS_SHARED + + +The following POSIX 1003.1 2001 options are defined and set: + +      _POSIX_THREAD_THREADS_MAX +      _POSIX_SEM_VALUE_MAX +      _POSIX_SEM_NSEMS_MAX +      PTHREAD_DESTRUCTOR_ITERATIONS +      PTHREAD_KEYS_MAX +      PTHREAD_STACK_MIN +      PTHREAD_THREADS_MAX +       + +The following functions are implemented: + +      --------------------------- +      PThreads +      --------------------------- +      pthread_attr_init +      pthread_attr_destroy +      pthread_attr_getdetachstate +      pthread_attr_getstackaddr +      pthread_attr_getstacksize +      pthread_attr_setdetachstate +      pthread_attr_setstackaddr +      pthread_attr_setstacksize + +      pthread_create +      pthread_detach +      pthread_equal +      pthread_exit +      pthread_join +      pthread_once +      pthread_self + +      pthread_cancel +      pthread_cleanup_pop +      pthread_cleanup_push +      pthread_setcancelstate +      pthread_setcanceltype +      pthread_testcancel + +      --------------------------- +      Thread Specific Data +      --------------------------- +      pthread_key_create +      pthread_key_delete +      pthread_setspecific +      pthread_getspecific + +      --------------------------- +      Mutexes +      --------------------------- +      pthread_mutexattr_init +      pthread_mutexattr_destroy +      pthread_mutexattr_getpshared +      pthread_mutexattr_setpshared +      pthread_mutexattr_gettype +      pthread_mutexattr_settype (types: PTHREAD_MUTEX_DEFAULT +					PTHREAD_MUTEX_NORMAL +					PTHREAD_MUTEX_ERRORCHECK +					PTHREAD_MUTEX_RECURSIVE  ) +      pthread_mutex_init +      pthread_mutex_destroy +      pthread_mutex_lock +      pthread_mutex_trylock +      pthread_mutex_timedlock +      pthread_mutex_unlock + +      --------------------------- +      Condition Variables +      --------------------------- +      pthread_condattr_init +      pthread_condattr_destroy +      pthread_condattr_getpshared +      pthread_condattr_setpshared + +      pthread_cond_init +      pthread_cond_destroy +      pthread_cond_wait +      pthread_cond_timedwait +      pthread_cond_signal +      pthread_cond_broadcast + +      --------------------------- +      Read/Write Locks +      --------------------------- +      pthread_rwlock_init +      pthread_rwlock_destroy +      pthread_rwlock_tryrdlock +      pthread_rwlock_trywrlock +      pthread_rwlock_rdlock +      pthread_rwlock_timedrdlock +      pthread_rwlock_rwlock +      pthread_rwlock_timedwrlock +      pthread_rwlock_unlock +      pthread_rwlockattr_init +      pthread_rwlockattr_destroy +      pthread_rwlockattr_getpshared +      pthread_rwlockattr_setpshared + +      --------------------------- +      Spin Locks +      --------------------------- +      pthread_spin_init +      pthread_spin_destroy +      pthread_spin_lock +      pthread_spin_unlock +      pthread_spin_trylock + +      --------------------------- +      Barriers +      --------------------------- +      pthread_barrier_init +      pthread_barrier_destroy +      pthread_barrier_wait +      pthread_barrierattr_init +      pthread_barrierattr_destroy +      pthread_barrierattr_getpshared +      pthread_barrierattr_setpshared + +      --------------------------- +      Semaphores +      --------------------------- +      sem_init +      sem_destroy +      sem_post +      sem_wait +      sem_trywait +      sem_timedwait +      sem_open		     (returns an error ENOSYS) +      sem_close 	     (returns an error ENOSYS) +      sem_unlink	     (returns an error ENOSYS) +      sem_getvalue	     (returns an error ENOSYS) + +      --------------------------- +      RealTime Scheduling +      --------------------------- +      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 +      pthread_setconcurrency +      pthread_attr_getscope +      pthread_attr_setscope  (only supports PTHREAD_SCOPE_SYSTEM) +      sched_get_priority_max +      sched_get_priority_min +      sched_rr_get_interval  (returns an error ENOTSUP) +      sched_setscheduler     (only supports SCHED_OTHER) +      sched_getscheduler     (only supports SCHED_OTHER) +      sched_yield + +      --------------------------- +      Signals +      --------------------------- +      pthread_sigmask +      pthread_kill           (only supports zero sig value, +                              for thread validity checking) + +      --------------------------- +      Non-portable routines (see the README.NONPORTABLE file for usage) +      --------------------------- +      pthread_getw32threadhandle_np +      pthread_timechange_handler_np +      pthread_delay_np +      pthread_mutexattr_getkind_np +      pthread_mutexattr_setkind_np	(types: PTHREAD_MUTEX_FAST_NP, +						PTHREAD_MUTEX_ERRORCHECK_NP, +						PTHREAD_MUTEX_RECURSIVE_NP, +						PTHREAD_MUTEX_ADAPTIVE_NP, +						PTHREAD_MUTEX_TIMED_NP) +      pthread_num_processors_np +      pthread_win32_process_attach_np	(Required when statically linking +                                         the library) +      pthread_win32_process_detach_np	(Required when statically linking +                                         the library) +      pthread_win32_thread_attach_np	(Required when statically linking +                                         the library) +      pthread_win32_thread_detach_np	(Required when statically linking +                                         the library) + +      --------------------------- +      Static Initializers +      --------------------------- +      PTHREAD_ONCE_INIT +      PTHREAD_MUTEX_INITIALIZER +      PTHREAD_RECURSIVE_MUTEX_INITIALIZER +      PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP +      PTHREAD_ERRORCHECK_MUTEX_INITIALIZER +      PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP +      PTHREAD_COND_INITIALIZER +      PTHREAD_RWLOCK_INITIALIZER +      PTHREAD_SPINLOCK_INITIALIZER + +      --------------------------- +      Thread-Safe C Runtime Library (macros) +      --------------------------- +      strtok_r +      asctime_r +      ctime_r +      gmtime_r +      localtime_r +      rand_r + + +The following functions are not implemented: +       +      --------------------------- +      RealTime Scheduling +      --------------------------- +      pthread_mutex_getprioceiling +      pthread_mutex_setprioceiling +      pthread_mutex_attr_getprioceiling +      pthread_mutex_attr_getprotocol +      pthread_mutex_attr_setprioceiling +      pthread_mutex_attr_setprotocol + +      --------------------------- +      Fork Handlers +      --------------------------- +      pthread_atfork + +      --------------------------- +      Stdio +      ---------------------------  +      flockfile +      ftrylockfile +      funlockfile +      getc_unlocked +      getchar_unlocked	 +      putc_unlocked +      putchar_unlocked + +      --------------------------- +      Thread-Safe C Runtime Library +      --------------------------- +      readdir_r +      getgrgid_r +      getgrnam_r +      getpwuid_r +      getpwnam_r +       +      --------------------------- +      Signals +      --------------------------- +      sigtimedwait +      sigwait +      sigwaitinfo + +      --------------------------- +      General +      --------------------------- +      sysconf       + +The library includes two non-API functions for creating cancellation +points in applications and libraries: +       +      pthreadCancelableWait +      pthreadCancelableTimedWait + +       +Availability +------------  + +The prebuilt DLL, export libs (for both MSVC and Mingw32), and the header +files (pthread.h, semaphore.h, sched.h) are available along with the +complete source code. + +The source code can be found at: + +	ftp://sources.redhat.com/pub/pthreads-win32 + +and as individual source code files at + +	ftp://sources.redhat.com/pub/pthreads-win32/source + +The pre-built DLL, export libraries and include files can be found at: + +	ftp://sources.redhat.com/pub/pthreads-win32/dll-latest + + +       +Mailing List  +------------   +       +There is a mailing list for discussing pthreads on Win32. To join, +send email to: + +	pthreads-win32-subscribe@sourceware.cygnus.com +       + +Application Development Environments +------------------------------------ + +See the README file for more information. +       +MSVC: +MSVC using SEH works. Distribute pthreadVSE.dll with your application. +MSVC using C++ EH works. Distribute pthreadVCE.dll with your application. +MSVC using C setjmp/longjmp works. Distribute pthreadVC.dll with your application. + + +Mingw32: +See the FAQ, Questions 6 and 10. + +Mingw using C++ EH works. Distribute pthreadGCE.dll with your application. +Mingw using C setjmp/longjmp works. Distribute pthreadGC.dll with your application. + + +Cygwin: (http://sourceware.cygnus.com/cygwin/) +Developers using Cygwin will not need pthreads-win32 since it has POSIX threads +support. Refer to its documentation for details and extent. + + +UWIN: +UWIN is a complete Unix-like environment for Windows from AT&T. Pthreads-win32 +doesn't currently support UWIN (and vice versa), but that may change in the +future. + +Generally: +For convenience, the following pre-built files are available on the FTP site +(see Availability above): + +	pthread.h	- for POSIX 1c threads +	semaphore.h	- for POSIX 1b semaphores +	sched.h 	- for POSIX 1b scheduling +	pthreadVCE.dll	- built with MSVC++ compiler using C++ EH +	pthreadVCE.lib +	pthreadVC.dll	- built with MSVC compiler using C setjmp/longjmp +	pthreadVC.lib +	pthreadVSE.dll	- built with MSVC compiler using SEH +	pthreadVSE.lib +	pthreadGCE.dll	- built with Mingw32 G++ 2.95.2-1 +	pthreadGC.dll	- built with Mingw32 GCC 2.95.2-1 using setjmp/longjmp +	libpthreadGCE.a - derived from pthreadGCE.dll +	libpthreadGC.a	- derived from pthreadGC.dll +	gcc.dll 	- needed if distributing applications that use +			  pthreadGCE.dll (but see the FAQ Q 10 for the latest +			  related information) + +These are the only files you need in order to build POSIX threads +applications for Win32 using either MSVC or Mingw32. + +See the FAQ file in the source tree for additional information. + + +Documentation +------------- + +For the authoritative reference, see the online POSIX +standard reference at: + +       http://www.OpenGroup.org + +For POSIX Thread API programming, several reference books are +available: + +       Programming with POSIX Threads +       David R. Butenhof +       Addison-Wesley (pub) + +       Pthreads Programming +       By Bradford Nichols, Dick Buttlar & Jacqueline Proulx Farrell +       O'Reilly (pub) + +On the web: see the links at the bottom of the pthreads-win32 site: + +       http://sources.redhat.com/pthreads-win32/ + +       Currently, there is no documentation included in the package apart +       from the copious comments in the source code. + + + +Enjoy! + +Ross Johnson @@ -1,114 +1,114 @@ -----------
 -Known bugs
 -----------
 -
 -1. Not strictly a bug, more of a gotcha.
 -
 -   Under MS VC++ (only tested with version 6.0), a term_func
 -   set via the standard C++ set_terminate() function causes the
 -   application to abort.
 -
 -   Notes from the MSVC++ manual:
 -         1) A term_func() should call exit(), otherwise
 -            abort() will be called on return to the caller.
 -            A call to abort() raises SIGABRT and the default signal handler
 -            for all signals terminates the calling program with
 -            exit code 3.
 -         2) A term_func() must not throw an exception. Therefore
 -            term_func() should not call pthread_exit(), which
 -            works by throwing an exception (pthreadVCE or pthreadVSE)
 -            or by calling longjmp (pthreadVC).
 -
 -   Workaround: avoid using pthread_exit() in C++ applications. Exit
 -   threads by dropping through the end of the thread routine.
 -
 -2. Cancellation problems in optimised code
 -   - Milan Gardian
 -
 +---------- +Known bugs +---------- + +1. Not strictly a bug, more of a gotcha. + +   Under MS VC++ (only tested with version 6.0), a term_func +   set via the standard C++ set_terminate() function causes the +   application to abort. + +   Notes from the MSVC++ manual: +         1) A term_func() should call exit(), otherwise +            abort() will be called on return to the caller. +            A call to abort() raises SIGABRT and the default signal handler +            for all signals terminates the calling program with +            exit code 3. +         2) A term_func() must not throw an exception. Therefore +            term_func() should not call pthread_exit(), which +            works by throwing an exception (pthreadVCE or pthreadVSE) +            or by calling longjmp (pthreadVC). + +   Workaround: avoid using pthread_exit() in C++ applications. Exit +   threads by dropping through the end of the thread routine. + +2. Cancellation problems in optimised code +   - Milan Gardian +     This is suspected to be a compiler bug in VC6.0, and also seen in     VC7.0 and VS .NET 2003. The GNU C++ compiler does not have a problem     with this, and it has been reported that the Intel C++ 8.1 compiler     and Visual C++ 2005 Express Edition Beta2 pass tests\semaphore4.c     (which exposes the bug). -   Workaround [rpj - 2 Feb 2002]
 -   -----------------------------
 -   [Please note: this workaround did not solve a similar problem in
 -   snapshot-2004-11-03 or later, even though similar symptoms were seen.
 -   tests\semaphore4.c fails in that snapshot for the VCE version of the
 +   Workaround [rpj - 2 Feb 2002] +   ----------------------------- +   [Please note: this workaround did not solve a similar problem in +   snapshot-2004-11-03 or later, even though similar symptoms were seen. +   tests\semaphore4.c fails in that snapshot for the VCE version of the     DLL.] -
 -   The problem disappears when /Ob0 is used, i.e. /O2 /Ob0 works OK,
 -   but if you want to use inlining optimisation you can be much more
 -   specific about where it's switched off and on by using a pragma.
 -
 -   So the inlining optimisation is interfering with the way that cleanup
 -   handlers are run. It appears to relate to auto-inlining of class methods
 -   since this is the only auto inlining that is performed at /O1 optimisation
 -   (functions with the "inline" qualifier are also inlined, but the problem
 -   doesn't appear to involve any such functions in the library or testsuite).
 -
 -   In order to confirm the inlining culprit, the following use of pragmas
 -   eliminate the problem but I don't know how to make it transparent, putting
 -   it in, say, pthread.h where pthread_cleanup_push defined as a macro.
 -
 -   #pragma inline_depth(0)
 -     pthread_cleanup_push(handlerFunc, (void *) &arg);
 -
 -        /* ... */
 -
 -     pthread_cleanup_pop(0);
 -   #pragma inline_depth()
 -
 -   Note the empty () pragma value after the pop macro. This resets depth to the
 -   default. Or you can specify a non-zero depth here.
 -
 -   The pragma is also needed (and now used) within the library itself wherever
 -   cleanup handlers are used (condvar.c and rwlock.c).
 -
 -   Use of these pragmas allows compiler optimisations /O1 and /O2 to be
 -   used for either or both the library and applications.
 -
 -   Experimenting further, I found that wrapping the actual cleanup handler
 -   function with #pragma auto_inline(off|on) does NOT work.
 -
 -   MSVC6.0 doesn't appear to support the C99 standard's _Pragma directive,
 -   however, later versions may. This form is embeddable inside #define
 -   macros, which would be ideal because it would mean that it could be added
 -   to the push/pop macro definitions in pthread.h and hidden from the
 -   application programmer.
 -
 -   [/rpj]
 -
 -   Original problem description
 -   ----------------------------
 -
 -   The cancellation (actually, cleanup-after-cancel) tests fail when using VC
 -   (professional) optimisation switches (/O1 or /O2) in pthreads library. I
 -   have not investigated which concrete optimisation technique causes this
 -   problem (/Og, /Oi, /Ot, /Oy, /Ob1, /Gs, /Gf, /Gy, etc.), but here is a
 -   summary of builds and corresponding failures:
 -
 -     * pthreads VSE (optimised tests): OK
 -     * pthreads VCE (optimised tests): Failed "cleanup1" test (runtime)
 -
 -     * pthreads VSE (DLL in CRT, optimised tests): OK
 -     * pthreads VCE (DLL in CRT, optimised tests): Failed "cleanup1" test
 -   (runtime)
 -
 -   Please note that while in VSE version of the pthreads library the
 -   optimisation does not really have any impact on the tests (they pass OK), in
 -   VCE version addition of optimisation (/O2 in this case) causes the tests to
 -   fail uniformly - either in "cleanup0" or "cleanup1" test cases.
 -
 -   Please note that all the tests above use default pthreads DLL (no
 -   optimisations, linked with either static or DLL CRT, based on test type).
 -   Therefore the problem lies not within the pthreads DLL but within the
 -   compiled client code (the application using pthreads -> involvement of
 -   "pthread.h").
 -
 -   I think the message of this section is that usage of VCE version of pthreads
 -   in applications relying on cancellation/cleanup AND using optimisations for
 -   creation of production code is highly unreliable for the current version of
 -   the pthreads library.
 -
 + +   The problem disappears when /Ob0 is used, i.e. /O2 /Ob0 works OK, +   but if you want to use inlining optimisation you can be much more +   specific about where it's switched off and on by using a pragma. + +   So the inlining optimisation is interfering with the way that cleanup +   handlers are run. It appears to relate to auto-inlining of class methods +   since this is the only auto inlining that is performed at /O1 optimisation +   (functions with the "inline" qualifier are also inlined, but the problem +   doesn't appear to involve any such functions in the library or testsuite). + +   In order to confirm the inlining culprit, the following use of pragmas +   eliminate the problem but I don't know how to make it transparent, putting +   it in, say, pthread.h where pthread_cleanup_push defined as a macro. + +   #pragma inline_depth(0) +     pthread_cleanup_push(handlerFunc, (void *) &arg); + +        /* ... */ + +     pthread_cleanup_pop(0); +   #pragma inline_depth() + +   Note the empty () pragma value after the pop macro. This resets depth to the +   default. Or you can specify a non-zero depth here. + +   The pragma is also needed (and now used) within the library itself wherever +   cleanup handlers are used (condvar.c and rwlock.c). + +   Use of these pragmas allows compiler optimisations /O1 and /O2 to be +   used for either or both the library and applications. + +   Experimenting further, I found that wrapping the actual cleanup handler +   function with #pragma auto_inline(off|on) does NOT work. + +   MSVC6.0 doesn't appear to support the C99 standard's _Pragma directive, +   however, later versions may. This form is embeddable inside #define +   macros, which would be ideal because it would mean that it could be added +   to the push/pop macro definitions in pthread.h and hidden from the +   application programmer. + +   [/rpj] + +   Original problem description +   ---------------------------- + +   The cancellation (actually, cleanup-after-cancel) tests fail when using VC +   (professional) optimisation switches (/O1 or /O2) in pthreads library. I +   have not investigated which concrete optimisation technique causes this +   problem (/Og, /Oi, /Ot, /Oy, /Ob1, /Gs, /Gf, /Gy, etc.), but here is a +   summary of builds and corresponding failures: + +     * pthreads VSE (optimised tests): OK +     * pthreads VCE (optimised tests): Failed "cleanup1" test (runtime) + +     * pthreads VSE (DLL in CRT, optimised tests): OK +     * pthreads VCE (DLL in CRT, optimised tests): Failed "cleanup1" test +   (runtime) + +   Please note that while in VSE version of the pthreads library the +   optimisation does not really have any impact on the tests (they pass OK), in +   VCE version addition of optimisation (/O2 in this case) causes the tests to +   fail uniformly - either in "cleanup0" or "cleanup1" test cases. + +   Please note that all the tests above use default pthreads DLL (no +   optimisations, linked with either static or DLL CRT, based on test type). +   Therefore the problem lies not within the pthreads DLL but within the +   compiled client code (the application using pthreads -> involvement of +   "pthread.h"). + +   I think the message of this section is that usage of VCE version of pthreads +   in applications relying on cancellation/cleanup AND using optimisations for +   creation of production code is highly unreliable for the current version of +   the pthreads library. + @@ -1,265 +1,265 @@ -# This makefile is compatible with BCB make.  Use "make -fBMakefile" to compile.
 -# 
 -# The variables $DLLDEST and $LIBDEST hold the destination directories for the
 -# dll and the lib, respectively. Probably all that needs to change is $DEVROOT.
 -#
 -# Currently only the recommended pthreadBC.dll is built by this makefile.
 -#
 -
 -
 -DLL_VER	= 2
 -
 -DEVROOT	= .
 -
 -DLLDEST	= $(DEVROOT)\DLL
 -LIBDEST	= $(DEVROOT)\DLL
 -
 -DLLS	= pthreadBC$(DLL_VER).dll
 -
 -OPTIM	= /O2
 -
 -RC	= brcc32
 -RCFLAGS	= -i.
 -
 -CFLAGS	= /q /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H=1 /4 /tWD /tWM \
 -	  /w-aus /w-asc /w-par
 -
 -#C cleanup code
 -BCFLAGS	= $(PTW32_FLAGS) $(CFLAGS)
 -
 -# Agregate modules for inlinability
 -DLL_OBJS	= \
 -		attr.obj \
 -		barrier.obj \
 -		cancel.obj \
 -		cleanup.obj \
 -		condvar.obj \
 -		create.obj \
 -		dll.obj \
 -		errno.obj \
 -		exit.obj \
 -		fork.obj \
 -		global.obj \
 -		misc.obj \
 -		mutex.obj \
 -		nonportable.obj \
 -		private.obj \
 -		rwlock.obj \
 -		sched.obj \
 -		semaphore.obj \
 -		signal.obj \
 -		spin.obj \
 -		sync.obj \
 -		tsd.obj
 -
 -INCL	= config.h implement.h semaphore.h pthread.h need_errno.h
 -
 -ATTR_SRCS	= \
 -		pthread_attr_init.c \
 -		pthread_attr_destroy.c \
 -		pthread_attr_getdetachstate.c \
 -		pthread_attr_setdetachstate.c \
 -		pthread_attr_getstackaddr.c \
 -		pthread_attr_setstackaddr.c \
 -		pthread_attr_getstacksize.c \
 -		pthread_attr_setstacksize.c \
 -		pthread_attr_getscope.c \
 -		pthread_attr_setscope.c
 -
 -BARRIER_SRCS = \
 -		pthread_barrier_init.c \
 -		pthread_barrier_destroy.c \
 -		pthread_barrier_wait.c \
 -		pthread_barrierattr_init.c \
 -		pthread_barrierattr_destroy.c \
 -		pthread_barrierattr_setpshared.c \
 -		pthread_barrierattr_getpshared.c
 -
 -CANCEL_SRCS	= \
 -		pthread_setcancelstate.c \
 -		pthread_setcanceltype.c \
 -		pthread_testcancel.c \
 -		pthread_cancel.c 
 -
 -CONDVAR_SRCS	= \
 -		ptw32_cond_check_need_init.c \
 -		pthread_condattr_destroy.c \
 -		pthread_condattr_getpshared.c \
 -		pthread_condattr_init.c \
 -		pthread_condattr_setpshared.c \
 -		pthread_cond_destroy.c \
 -		pthread_cond_init.c \
 -		pthread_cond_signal.c \
 -		pthread_cond_wait.c
 -
 -EXIT_SRCS	= \
 -		pthread_exit.c
 -
 -MISC_SRCS	= \
 -		pthread_equal.c \
 -		pthread_getconcurrency.c \
 -		pthread_once.c \
 -		pthread_self.c \
 -		pthread_setconcurrency.c \
 -		ptw32_calloc.c \
 -		ptw32_new.c \
 -		w32_CancelableWait.c
 -
 -MUTEX_SRCS	= \
 -		ptw32_mutex_check_need_init.c \
 -		pthread_mutex_init.c \
 -		pthread_mutex_destroy.c \
 -		pthread_mutexattr_init.c \
 -		pthread_mutexattr_destroy.c \
 -		pthread_mutexattr_getpshared.c \
 -		pthread_mutexattr_setpshared.c \
 -		pthread_mutexattr_settype.c \
 -		pthread_mutexattr_gettype.c \
 -		pthread_mutex_lock.c \
 -		pthread_mutex_timedlock.c \
 -		pthread_mutex_unlock.c \
 -		pthread_mutex_trylock.c
 -
 -NONPORTABLE_SRCS = \
 -		pthread_mutexattr_setkind_np.c \
 -		pthread_mutexattr_getkind_np.c \
 -		pthread_getw32threadhandle_np.c \
 -		pthread_delay_np.c \
 -		pthread_num_processors_np.c \
 -		pthread_win32_attach_detach_np.c \
 -		pthread_timechange_handler_np.c 
 -
 -PRIVATE_SRCS	= \
 -		ptw32_is_attr.c \
 -		ptw32_processInitialize.c \
 -		ptw32_processTerminate.c \
 -		ptw32_threadStart.c \
 -		ptw32_threadDestroy.c \
 -		ptw32_tkAssocCreate.c \
 -		ptw32_tkAssocDestroy.c \
 -		ptw32_callUserDestroyRoutines.c \
 -		ptw32_timespec.c \
 -		ptw32_relmillisecs.c \
 -		ptw32_throw.c \
 -		ptw32_InterlockedCompareExchange.c \
 -		ptw32_getprocessors.c
 -
 -RWLOCK_SRCS	= \
 -		ptw32_rwlock_check_need_init.c \
 -		ptw32_rwlock_cancelwrwait.c \
 -		pthread_rwlock_init.c \
 -		pthread_rwlock_destroy.c \
 -		pthread_rwlockattr_init.c \
 -		pthread_rwlockattr_destroy.c \
 -		pthread_rwlockattr_getpshared.c \
 -		pthread_rwlockattr_setpshared.c \
 -		pthread_rwlock_rdlock.c \
 -		pthread_rwlock_timedrdlock.c \
 -		pthread_rwlock_wrlock.c \
 -		pthread_rwlock_timedwrlock.c \
 -		pthread_rwlock_unlock.c \
 -		pthread_rwlock_tryrdlock.c \
 -		pthread_rwlock_trywrlock.c
 -
 -SCHED_SRCS	= \
 -		pthread_attr_setschedpolicy.c \
 -		pthread_attr_getschedpolicy.c \
 -		pthread_attr_setschedparam.c \
 -		pthread_attr_getschedparam.c \
 -		pthread_attr_setinheritsched.c \
 -		pthread_attr_getinheritsched.c \
 -		pthread_setschedparam.c \
 -		pthread_getschedparam.c \
 -		sched_get_priority_max.c \
 -		sched_get_priority_min.c \
 -		sched_setscheduler.c \
 -		sched_getscheduler.c \
 -		sched_yield.c
 -
 -SEMAPHORE_SRCS = \
 -		sem_init.c \
 -		sem_destroy.c \
 -		sem_trywait.c \
 -		sem_timedwait.c \
 -		sem_wait.c \
 -		sem_post.c \
 -		sem_post_multiple.c \
 -		sem_getvalue.c \
 -		sem_open.c \
 -		sem_close.c \
 -		sem_unlink.c
 -
 -SPIN_SRCS	= \
 -		ptw32_spinlock_check_need_init.c \
 -		pthread_spin_init.c \
 -		pthread_spin_destroy.c \
 -		pthread_spin_lock.c \
 -		pthread_spin_unlock.c \
 -		pthread_spin_trylock.c
 -
 -SYNC_SRCS	= \
 -		pthread_detach.c \
 -		pthread_join.c
 -
 -TSD_SRCS	= \
 -		pthread_key_create.c \
 -		pthread_key_delete.c \
 -		pthread_setspecific.c \
 -		pthread_getspecific.c
 -
 -
 -all: clean $(DLLS)
 -
 -realclean: clean
 -	if exist *.dll del *.dll
 -	if exist *.lib del *.lib
 -	if exist *.stamp del *.stamp
 -
 -clean:
 -	if exist *.obj del *.obj
 -	if exist *.ilk del *.ilk
 -	if exist *.ilc del *.ilc
 -	if exist *.ild del *.ild
 -	if exist *.ilf del *.ilf
 -	if exist *.ils del *.ils
 -	if exist *.tds del *.tds
 -	if exist *.pdb del *.pdb
 -	if exist *.exp del *.exp
 -	if exist *.map del *.map
 -	if exist *.o del *.o
 -	if exist *.i del *.i
 -	if exist *.res del *.res
 -
 -
 -install: $(DLLS)
 -	copy pthread*.dll $(DLLDEST)
 -	copy pthread*.lib $(LIBDEST)
 -
 -$(DLLS): $(DLL_OBJS) version.res
 -	ilink32 /Tpd /Gi c0d32x.obj $(DLL_OBJS), \
 -		$@, ,\
 -		cw32mt.lib import32.lib, ,\
 -		version.res
 -
 -.c.obj:
 -	$(CC) $(OPTIM) $(BCFLAGS) -c $<
 -
 -.rc.res:
 -	$(RC) $(RCFLAGS) $<
 -
 -attr.obj:	attr.c $(ATTR_SRCS) $(INCL)
 -barrier.obj:	barrier.c $(BARRIER_SRCS) $(INCL)
 -cancel.obj:	cancel.c $(CANCEL_SRCS) $(INCL)
 -condvar.obj:	condvar.c $(CONDVAR_SRCS) $(INCL)
 -exit.obj:	exit.c $(EXIT_SRCS) $(INCL)
 -misc.obj:	misc.c $(MISC_SRCS) $(INCL)
 -mutex.obj:	mutex.c $(MUTEX_SRCS) $(INCL)
 -nonportable.obj:	nonportable.c $(NONPORTABLE_SRCS) $(INCL)
 -private.obj:	private.c $(PRIVATE_SRCS) $(INCL)
 -rwlock.obj:	rwlock.c $(RWLOCK_SRCS) $(INCL)
 -sched.obj:	sched.c $(SCHED_SRCS) $(INCL)
 -semaphore.obj:	semaphore.c $(SEMAPHORE_SRCS) $(INCL)
 -spin.obj:	spin.c $(SPIN_SRCS) $(INCL)
 -sync.obj:	sync.c $(SYNC_SRCS) $(INCL)
 -tsd.obj:	tsd.c $(TSD_SRCS) $(INCL)
 -version.res:	version.rc $(INCL)
 +# This makefile is compatible with BCB make.  Use "make -fBMakefile" to compile. +#  +# The variables $DLLDEST and $LIBDEST hold the destination directories for the +# dll and the lib, respectively. Probably all that needs to change is $DEVROOT. +# +# Currently only the recommended pthreadBC.dll is built by this makefile. +# + + +DLL_VER	= 2 + +DEVROOT	= . + +DLLDEST	= $(DEVROOT)\DLL +LIBDEST	= $(DEVROOT)\DLL + +DLLS	= pthreadBC$(DLL_VER).dll + +OPTIM	= /O2 + +RC	= brcc32 +RCFLAGS	= -i. + +CFLAGS	= /q /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H=1 /4 /tWD /tWM \ +	  /w-aus /w-asc /w-par + +#C cleanup code +BCFLAGS	= $(PTW32_FLAGS) $(CFLAGS) + +# Agregate modules for inlinability +DLL_OBJS	= \ +		attr.obj \ +		barrier.obj \ +		cancel.obj \ +		cleanup.obj \ +		condvar.obj \ +		create.obj \ +		dll.obj \ +		errno.obj \ +		exit.obj \ +		fork.obj \ +		global.obj \ +		misc.obj \ +		mutex.obj \ +		nonportable.obj \ +		private.obj \ +		rwlock.obj \ +		sched.obj \ +		semaphore.obj \ +		signal.obj \ +		spin.obj \ +		sync.obj \ +		tsd.obj + +INCL	= config.h implement.h semaphore.h pthread.h need_errno.h + +ATTR_SRCS	= \ +		pthread_attr_init.c \ +		pthread_attr_destroy.c \ +		pthread_attr_getdetachstate.c \ +		pthread_attr_setdetachstate.c \ +		pthread_attr_getstackaddr.c \ +		pthread_attr_setstackaddr.c \ +		pthread_attr_getstacksize.c \ +		pthread_attr_setstacksize.c \ +		pthread_attr_getscope.c \ +		pthread_attr_setscope.c + +BARRIER_SRCS = \ +		pthread_barrier_init.c \ +		pthread_barrier_destroy.c \ +		pthread_barrier_wait.c \ +		pthread_barrierattr_init.c \ +		pthread_barrierattr_destroy.c \ +		pthread_barrierattr_setpshared.c \ +		pthread_barrierattr_getpshared.c + +CANCEL_SRCS	= \ +		pthread_setcancelstate.c \ +		pthread_setcanceltype.c \ +		pthread_testcancel.c \ +		pthread_cancel.c  + +CONDVAR_SRCS	= \ +		ptw32_cond_check_need_init.c \ +		pthread_condattr_destroy.c \ +		pthread_condattr_getpshared.c \ +		pthread_condattr_init.c \ +		pthread_condattr_setpshared.c \ +		pthread_cond_destroy.c \ +		pthread_cond_init.c \ +		pthread_cond_signal.c \ +		pthread_cond_wait.c + +EXIT_SRCS	= \ +		pthread_exit.c + +MISC_SRCS	= \ +		pthread_equal.c \ +		pthread_getconcurrency.c \ +		pthread_once.c \ +		pthread_self.c \ +		pthread_setconcurrency.c \ +		ptw32_calloc.c \ +		ptw32_new.c \ +		w32_CancelableWait.c + +MUTEX_SRCS	= \ +		ptw32_mutex_check_need_init.c \ +		pthread_mutex_init.c \ +		pthread_mutex_destroy.c \ +		pthread_mutexattr_init.c \ +		pthread_mutexattr_destroy.c \ +		pthread_mutexattr_getpshared.c \ +		pthread_mutexattr_setpshared.c \ +		pthread_mutexattr_settype.c \ +		pthread_mutexattr_gettype.c \ +		pthread_mutex_lock.c \ +		pthread_mutex_timedlock.c \ +		pthread_mutex_unlock.c \ +		pthread_mutex_trylock.c + +NONPORTABLE_SRCS = \ +		pthread_mutexattr_setkind_np.c \ +		pthread_mutexattr_getkind_np.c \ +		pthread_getw32threadhandle_np.c \ +		pthread_delay_np.c \ +		pthread_num_processors_np.c \ +		pthread_win32_attach_detach_np.c \ +		pthread_timechange_handler_np.c  + +PRIVATE_SRCS	= \ +		ptw32_is_attr.c \ +		ptw32_processInitialize.c \ +		ptw32_processTerminate.c \ +		ptw32_threadStart.c \ +		ptw32_threadDestroy.c \ +		ptw32_tkAssocCreate.c \ +		ptw32_tkAssocDestroy.c \ +		ptw32_callUserDestroyRoutines.c \ +		ptw32_timespec.c \ +		ptw32_relmillisecs.c \ +		ptw32_throw.c \ +		ptw32_InterlockedCompareExchange.c \ +		ptw32_getprocessors.c + +RWLOCK_SRCS	= \ +		ptw32_rwlock_check_need_init.c \ +		ptw32_rwlock_cancelwrwait.c \ +		pthread_rwlock_init.c \ +		pthread_rwlock_destroy.c \ +		pthread_rwlockattr_init.c \ +		pthread_rwlockattr_destroy.c \ +		pthread_rwlockattr_getpshared.c \ +		pthread_rwlockattr_setpshared.c \ +		pthread_rwlock_rdlock.c \ +		pthread_rwlock_timedrdlock.c \ +		pthread_rwlock_wrlock.c \ +		pthread_rwlock_timedwrlock.c \ +		pthread_rwlock_unlock.c \ +		pthread_rwlock_tryrdlock.c \ +		pthread_rwlock_trywrlock.c + +SCHED_SRCS	= \ +		pthread_attr_setschedpolicy.c \ +		pthread_attr_getschedpolicy.c \ +		pthread_attr_setschedparam.c \ +		pthread_attr_getschedparam.c \ +		pthread_attr_setinheritsched.c \ +		pthread_attr_getinheritsched.c \ +		pthread_setschedparam.c \ +		pthread_getschedparam.c \ +		sched_get_priority_max.c \ +		sched_get_priority_min.c \ +		sched_setscheduler.c \ +		sched_getscheduler.c \ +		sched_yield.c + +SEMAPHORE_SRCS = \ +		sem_init.c \ +		sem_destroy.c \ +		sem_trywait.c \ +		sem_timedwait.c \ +		sem_wait.c \ +		sem_post.c \ +		sem_post_multiple.c \ +		sem_getvalue.c \ +		sem_open.c \ +		sem_close.c \ +		sem_unlink.c + +SPIN_SRCS	= \ +		ptw32_spinlock_check_need_init.c \ +		pthread_spin_init.c \ +		pthread_spin_destroy.c \ +		pthread_spin_lock.c \ +		pthread_spin_unlock.c \ +		pthread_spin_trylock.c + +SYNC_SRCS	= \ +		pthread_detach.c \ +		pthread_join.c + +TSD_SRCS	= \ +		pthread_key_create.c \ +		pthread_key_delete.c \ +		pthread_setspecific.c \ +		pthread_getspecific.c + + +all: clean $(DLLS) + +realclean: clean +	if exist *.dll del *.dll +	if exist *.lib del *.lib +	if exist *.stamp del *.stamp + +clean: +	if exist *.obj del *.obj +	if exist *.ilk del *.ilk +	if exist *.ilc del *.ilc +	if exist *.ild del *.ild +	if exist *.ilf del *.ilf +	if exist *.ils del *.ils +	if exist *.tds del *.tds +	if exist *.pdb del *.pdb +	if exist *.exp del *.exp +	if exist *.map del *.map +	if exist *.o del *.o +	if exist *.i del *.i +	if exist *.res del *.res + + +install: $(DLLS) +	copy pthread*.dll $(DLLDEST) +	copy pthread*.lib $(LIBDEST) + +$(DLLS): $(DLL_OBJS) version.res +	ilink32 /Tpd /Gi c0d32x.obj $(DLL_OBJS), \ +		$@, ,\ +		cw32mt.lib import32.lib, ,\ +		version.res + +.c.obj: +	$(CC) $(OPTIM) $(BCFLAGS) -c $< + +.rc.res: +	$(RC) $(RCFLAGS) $< + +attr.obj:	attr.c $(ATTR_SRCS) $(INCL) +barrier.obj:	barrier.c $(BARRIER_SRCS) $(INCL) +cancel.obj:	cancel.c $(CANCEL_SRCS) $(INCL) +condvar.obj:	condvar.c $(CONDVAR_SRCS) $(INCL) +exit.obj:	exit.c $(EXIT_SRCS) $(INCL) +misc.obj:	misc.c $(MISC_SRCS) $(INCL) +mutex.obj:	mutex.c $(MUTEX_SRCS) $(INCL) +nonportable.obj:	nonportable.c $(NONPORTABLE_SRCS) $(INCL) +private.obj:	private.c $(PRIVATE_SRCS) $(INCL) +rwlock.obj:	rwlock.c $(RWLOCK_SRCS) $(INCL) +sched.obj:	sched.c $(SCHED_SRCS) $(INCL) +semaphore.obj:	semaphore.c $(SEMAPHORE_SRCS) $(INCL) +spin.obj:	spin.c $(SPIN_SRCS) $(INCL) +sync.obj:	sync.c $(SYNC_SRCS) $(INCL) +tsd.obj:	tsd.c $(TSD_SRCS) $(INCL) +version.res:	version.rc $(INCL) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 63bb70c..bece51e 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,123 +1,123 @@ -Contributors (in approximate order of appearance)
 +Contributors (in approximate order of appearance) -[See also the ChangeLog file where individuals are
 -attributed in log entries. Likewise in the FAQ file.]
 +[See also the ChangeLog file where individuals are +attributed in log entries. Likewise in the FAQ file.] -Ben Elliston		bje at cygnus dot com
 -					Initiated the project;
 -					setup the project infrastructure (CVS, web page, etc.);
 -					early prototype routines.
 -Ross Johnson		rpj at callisto dot canberra dot edu dot au
 -					early prototype routines;
 -					ongoing project coordination/maintenance;
 -					implementation of spin locks and barriers;
 -					various enhancements;
 -					bug fixes;
 -					documentation;
 -					testsuite.
 -Robert Colquhoun	rjc at trump dot net dot au
 -					Early bug fixes.
 -John E. Bossom		John dot Bossom at cognos dot com
 -					Contributed substantial original working implementation;
 -					bug fixes;
 -					ongoing guidance and standards interpretation.
 -Anders Norlander	anorland at hem2 dot passagen dot se
 -					Early enhancements and runtime checking for supported
 -					Win32 routines.
 -Tor Lillqvist		tml at iki dot fi
 -					General enhancements;
 -					early bug fixes to condition variables.
 -Scott Lightner		scott at curriculum dot com
 -					Bug fix.
 -Kevin Ruland		Kevin dot Ruland at anheuser-busch dot com
 -					Various bug fixes.
 -Mike Russo		miker at eai dot com
 -					Bug fix.
 -Mark E. Armstrong	avail at pacbell dot net
 -					Bug fixes.
 -Lorin Hochstein 	lmh at xiphos dot ca
 -					general bug fixes; bug fixes to condition variables.
 -Peter Slacik		Peter dot Slacik at tatramed dot sk
 -					Bug fixes.
 -Mumit Khan		khan at xraylith dot wisc dot edu
 -					Fixes to work with Mingw32.
 -Milan Gardian		mg at tatramed dot sk
 -					Bug fixes and reports/analyses of obscure problems.
 -Aurelio Medina		aureliom at crt dot com
 -					First implementation of read-write locks.
 -Graham Dumpleton	Graham dot Dumpleton at ra dot pad dot otc dot telstra dot com dot au
 -					Bug fix in condition variables.
 -Tristan Savatier	tristan at mpegtv dot com
 -					WinCE port.
 -Erik Hensema		erik at hensema dot xs4all dot nl
 -					Bug fixes.
 -Rich Peters		rpeters at micro-magic dot com
 -Todd Owen		towen at lucidcalm dot dropbear dot id dot au
 -					Bug fixes to dll loading.
 -Jason Nye		jnye at nbnet dot nb dot ca
 -					Implementation of async cancelation.
 -Fred Forester		fforest at eticomm dot net
 -Kevin D. Clark		kclark at cabletron dot com
 -David Baggett		dmb at itasoftware dot com
 -					Bug fixes.
 -Paul Redondo		paul at matchvision dot com
 -Scott McCaskill 	scott at 3dfx dot com
 -					Bug fixes.
 -Jef Gearhart		jgearhart at tpssys dot com
 -					Bug fix.
 -Arthur Kantor		akantor at bexusa dot com
 -					Mutex enhancements.
 -Steven Reddie		smr at essemer dot com dot au
 -					Bug fix.
 -Alexander Terekhov	TEREKHOV at de dot ibm dot com
 -					Re-implemented and improved read-write locks;
 -					(with Louis Thomas) re-implemented and improved
 -					condition variables;
 -					enhancements to semaphores;
 -					enhancements to mutexes;
 -					new mutex implementation in 'futex' style;
 -					system clock change handling re CV timeouts;
 -					bug fixes.
 -Thomas Pfaff		tpfaff at gmx dot net
 -					Changes to make C version usable with C++ applications;
 -					re-implemented mutex routines to avoid Win32 mutexes
 -					and TryEnterCriticalSection;
 -					procedure to fix Mingw32 thread-safety issues.
 -Franco Bez		franco dot bez at gmx dot de
 -					procedure to fix Mingw32 thread-safety issues.
 -Louis Thomas		lthomas at arbitrade dot com
 -					(with Alexander Terekhov) re-implemented and improved
 -					condition variables.
 -David Korn		dgk at research dot att dot com
 -					Ported to UWIN.
 -Phil Frisbie, Jr.	phil at hawksoft dot com
 -					Bug fix.
 -Ralf Brese		Ralf dot Brese at pdb4 dot siemens dot de
 -					Bug fix.
 -prionx at juno dot com 	prionx at juno dot com
 -					Bug fixes.
 -Max Woodbury		mtew at cds dot duke dot edu
 -					POSIX versioning conditionals;
 -					reduced namespace pollution;
 -					idea to separate routines to reduce statically
 -					linked image sizes.
 -Rob Fanner		rfanner at stonethree dot com
 -					Bug fix.
 -Michael Johnson 	michaelj at maine dot rr dot com
 -					Bug fix.
 -Nicolas Barry		boozai at yahoo dot com
 -					Bug fixes.
 -Piet van Bruggen	pietvb at newbridges dot nl
 -					Bug fix.
 -Makoto Kato		raven at oldskool dot jp
 -					AMD64 port.
 -Panagiotis E. Hadjidoukas	peh at hpclab dot ceid dot upatras dot gr
 -					Contributed the QueueUserAPCEx package which
 -					makes preemptive async cancelation possible.
 -Will Bryant		will dot bryant at ecosm dot com
 -					Borland compiler patch and makefile.
 -Anuj Goyal		anuj dot goyal at gmail dot com
 -					Port to Digital Mars compiler.
 -Gottlob Frege		gottlobfrege at  gmail dot com
 +Ben Elliston		bje at cygnus dot com +					Initiated the project; +					setup the project infrastructure (CVS, web page, etc.); +					early prototype routines. +Ross Johnson		rpj at callisto dot canberra dot edu dot au +					early prototype routines; +					ongoing project coordination/maintenance; +					implementation of spin locks and barriers; +					various enhancements; +					bug fixes; +					documentation; +					testsuite. +Robert Colquhoun	rjc at trump dot net dot au +					Early bug fixes. +John E. Bossom		John dot Bossom at cognos dot com +					Contributed substantial original working implementation; +					bug fixes; +					ongoing guidance and standards interpretation. +Anders Norlander	anorland at hem2 dot passagen dot se +					Early enhancements and runtime checking for supported +					Win32 routines. +Tor Lillqvist		tml at iki dot fi +					General enhancements; +					early bug fixes to condition variables. +Scott Lightner		scott at curriculum dot com +					Bug fix. +Kevin Ruland		Kevin dot Ruland at anheuser-busch dot com +					Various bug fixes. +Mike Russo		miker at eai dot com +					Bug fix. +Mark E. Armstrong	avail at pacbell dot net +					Bug fixes. +Lorin Hochstein 	lmh at xiphos dot ca +					general bug fixes; bug fixes to condition variables. +Peter Slacik		Peter dot Slacik at tatramed dot sk +					Bug fixes. +Mumit Khan		khan at xraylith dot wisc dot edu +					Fixes to work with Mingw32. +Milan Gardian		mg at tatramed dot sk +					Bug fixes and reports/analyses of obscure problems. +Aurelio Medina		aureliom at crt dot com +					First implementation of read-write locks. +Graham Dumpleton	Graham dot Dumpleton at ra dot pad dot otc dot telstra dot com dot au +					Bug fix in condition variables. +Tristan Savatier	tristan at mpegtv dot com +					WinCE port. +Erik Hensema		erik at hensema dot xs4all dot nl +					Bug fixes. +Rich Peters		rpeters at micro-magic dot com +Todd Owen		towen at lucidcalm dot dropbear dot id dot au +					Bug fixes to dll loading. +Jason Nye		jnye at nbnet dot nb dot ca +					Implementation of async cancelation. +Fred Forester		fforest at eticomm dot net +Kevin D. Clark		kclark at cabletron dot com +David Baggett		dmb at itasoftware dot com +					Bug fixes. +Paul Redondo		paul at matchvision dot com +Scott McCaskill 	scott at 3dfx dot com +					Bug fixes. +Jef Gearhart		jgearhart at tpssys dot com +					Bug fix. +Arthur Kantor		akantor at bexusa dot com +					Mutex enhancements. +Steven Reddie		smr at essemer dot com dot au +					Bug fix. +Alexander Terekhov	TEREKHOV at de dot ibm dot com +					Re-implemented and improved read-write locks; +					(with Louis Thomas) re-implemented and improved +					condition variables; +					enhancements to semaphores; +					enhancements to mutexes; +					new mutex implementation in 'futex' style; +					system clock change handling re CV timeouts; +					bug fixes. +Thomas Pfaff		tpfaff at gmx dot net +					Changes to make C version usable with C++ applications; +					re-implemented mutex routines to avoid Win32 mutexes +					and TryEnterCriticalSection; +					procedure to fix Mingw32 thread-safety issues. +Franco Bez		franco dot bez at gmx dot de +					procedure to fix Mingw32 thread-safety issues. +Louis Thomas		lthomas at arbitrade dot com +					(with Alexander Terekhov) re-implemented and improved +					condition variables. +David Korn		dgk at research dot att dot com +					Ported to UWIN. +Phil Frisbie, Jr.	phil at hawksoft dot com +					Bug fix. +Ralf Brese		Ralf dot Brese at pdb4 dot siemens dot de +					Bug fix. +prionx at juno dot com 	prionx at juno dot com +					Bug fixes. +Max Woodbury		mtew at cds dot duke dot edu +					POSIX versioning conditionals; +					reduced namespace pollution; +					idea to separate routines to reduce statically +					linked image sizes. +Rob Fanner		rfanner at stonethree dot com +					Bug fix. +Michael Johnson 	michaelj at maine dot rr dot com +					Bug fix. +Nicolas Barry		boozai at yahoo dot com +					Bug fixes. +Piet van Bruggen	pietvb at newbridges dot nl +					Bug fix. +Makoto Kato		raven at oldskool dot jp +					AMD64 port. +Panagiotis E. Hadjidoukas	peh at hpclab dot ceid dot upatras dot gr +					Contributed the QueueUserAPCEx package which +					makes preemptive async cancelation possible. +Will Bryant		will dot bryant at ecosm dot com +					Borland compiler patch and makefile. +Anuj Goyal		anuj dot goyal at gmail dot com +					Port to Digital Mars compiler. +Gottlob Frege		gottlobfrege at  gmail dot com  					re-implemented pthread_once (version 2)  					(pthread_once cancellation added by rpj). @@ -72,4587 +72,4587 @@  	* pthread_setcancelstate.c: Don't check for an async cancel event  	if the library is using alertable async cancel.. -2005-03-14  Ross Johnson  <ross at callisto.canberra.edu.au>
 - -	* pthread_once.c (pthread_once): Downgrade interlocked operations to simple
 -	memory operations where these are protected by the critical section; edit
 -	comments.
 - -2005-03-13  Ross Johnson  <rpj at callisto.canberra.edu.au>
 - -	* pthread_once.c (pthread_once): Completely redesigned; a change was
 -	required to the ABI (pthread_once_t_), and resulting in a version
 -	compatibility index increment.
 - -	NOTES:
 -	The design (based on pseudo code contributed by Gottlob Frege) avoids
 -	creating a kernel object if there is no contention. See URL for details:-
 -	http://sources.redhat.com/ml/pthreads-win32/2005/msg00029.html
 -	This uses late initialisation similar to the technique already used for
 -	pthreads-win32 mutexes and semaphores (from Alexander Terekhov).
 - -	The subsequent cancelation cleanup additions (by rpj) could not be implemented
 -	without sacrificing some of the efficiency in Gottlob's design. In particular,
 -	although each once_control uses it's own event to block on, a global CS is
 -	required to manage it - since the event must be either re-usable or
 -	re-creatable under cancelation. This is not needed in the non-cancelable
 -	design because it is able to mark the event as closed (forever).
 - -	When uncontested, a CS operation is equivalent to an Interlocked operation
 -	in speed. So, in the final design with cancelability, an uncontested
 -	once_control operation involves a minimum of five interlocked operations
 -	(including the LeaveCS operation).
 -	
 -	ALTERNATIVES:
 -	An alternative design from Alexander Terekhov proposed using a named mutex,
 -	as sketched below:-
 - -	  if (!once_control) { // May be in TLS
 -	    named_mutex::guard guard(&once_control2);
 -	      if (!once_control2) {
 -	         <init>
 -	         once_control2 = true;
 -	      }
 -	    once_control = true;
 -	  }
 -	
 -	A more detailed description of this can be found here:-
 -	http://groups.yahoo.com/group/boost/message/15442
 - -	[Although the definition of a suitable PTHREAD_ONCE_INIT precludes use of the
 -	TLS located flag, this is not critical.]
 -	
 -	There are three primary concerns though:-
 -	1) The [named] mutex is 'created' even in the uncontended case.
 -	2) A system wide unique name must be generated.
 -	3) Win32 mutexes are VERY slow even in the uncontended 	case. An uncontested
 -	Win32 mutex lock operation can be 50 (or more) times slower than an
 -	uncontested EnterCS operation.
 - -	Ultimately, the named mutex trick is making use of the global locks maintained
 -	by the kernel.
 - -	* pthread.h (pthread_once_t_): One flag and an event HANDLE added.
 -	(PTHREAD_ONCE_INIT): Additional values included.
 - -2005-03-08  Ross Johnson  <rpj at callisto.canberra.edu.au>
 - -	* pthread_once.c (pthread_once): Redesigned to elliminate potential
 -	starvation problem.
 -	- reported by Gottlob Frege  <gottlobfrege at gmail.com>
 - -	* ptw32_threadDestroy.c (ptw32_threadDestroy): Implicit threads were
 -	not closing their Win32 thread duplicate handle.
 -	- reported by Dmitrii Semii <bogolt at gmail.com>
 - -2005-01-25  Ralf Kubis  <RKubis at mc.com>
 - -	* Attempted acquisition of recursive mutex was causing waiting
 -	threads to not be woken when the mutex is released.
 - -	* GNUmakefile (GCE): Generate correct version resource comments.
 - -2005-01-01  Konstantin Voronkov  <beowinkle at yahoo.com>
 -
 -	* pthread_mutex_lock.c (pthread_mutex_lock): The new atomic exchange
 -	mutex algorithm is known to allow a thread to steal the lock off
 -	FIFO waiting threads. The next waiting FIFO thread gets a spurious
 -	wake-up and must attempt to re-acquire the lock. The woken thread
 -	was setting itself as the mutex's owner before the re-acquisition.
 -
 -2004-11-22  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): Undo change
 -	from 2004-11-02.
 -	* Makefile (DLL_VER): Added for DLL naming suffix - see README.
 -	* GNUmakefile (DLL_VER): Likewise.
 -	* Wmakefile (DLL_VER): Likewise.
 -	* Bmakefile (DLL_VER): Likewise.
 -	* pthread.dsw (version.rc): Added to MSVS workspace.
 -
 -2004-11-20  Boudewijn Dekker  <b.dekker at ellipsis.nl>
 -
 -	* pthread_getspecific.c (pthread_getspecific): Check for
 -	invalid (NULL) key argument.
 -
 -2004-11-19  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* config.h (PTW32_THREAD_ID_REUSE_INCREMENT): Added to allow
 -	building the library for either unique thread IDs like Solaris
 -	or non-unique thread IDs like Linux; allows application developers
 -	to override the library's default insensitivity to some apps
 -	that may not be strictly POSIX compliant.
 -	* version.rc: New resource module to encode version information
 -	within the DLL.
 -	* pthread.h: Added PTW32_VERSION* defines and grouped sections
 -	required by resource compiler together; bulk of file is skipped
 -	if RC_INVOKED. Defined some error numbers and other names for
 -	Borland compiler.
 -
 -2004-11-02  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): Lock CV mutex at
 -	start of cleanup handler rather than at the end.
 -	* implement.h (PTW32_THREAD_REUSE_EMPTY): Renamed from *_BOTTOM.
 -	(ptw32_threadReuseBottom): New global variable.
 -	* global.c (ptw32_threadReuseBottom): Declare new variable.
 -	* ptw32_reuse.c (ptw32_reuse): Change reuse LIFO stack to LILO queue
 -	to more evenly distribute use of reusable thread IDs; use renamed
 -	PTW32_THREAD_REUSE_EMPTY.
 -	* ptw32_processTerminate.c (ptw2_processTerminate): Use renamed
 -	PTW32_THREAD_REUSE_EMPTY.
 -
 -2004-10-31  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* implement.h (PThreadState): Add new state value
 -	'PThreadStateCancelPending'.
 -	* pthread_testcancel.c (pthread_testcancel): Use new thread
 -	'PThreadStateCancelPending' state as short cut to avoid entering
 -	kernel space via WaitForSingleObject() call. This was obviated
 -	by user space sema acquisition in sem_wait() and sem_timedwait(),
 -	which are also cancelation points. A call to pthread_testcancel()
 -	was required, which introduced a kernel call, effectively nullifying
 -	any gains made by the user space sem acquisition checks.
 -	* pthread_cancel.c (pthread_cancel): Set new thread
 -	'PThreadStateCancelPending' state.
 -
 -2004-10-29  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* implement.h (pthread_t): Renamed to ptw32_thread_t; struct contains
 -	all thread state.
 -	* pthread.h (ptw32_handle_t): New general purpose struct to serve
 -	as a handle for various reusable object IDs - currently only used
 -	by pthread_t; contains a pointer to ptw32_thread_t (thread state)
 -	and a general purpose uint for use as a reuse counter or flags etc.
 -	(pthread_t): typedef'ed to ptw32_handle_t; the uint is the reuse
 -	counter that allows the library to maintain unique POSIX thread IDs.
 -	When the pthread struct reuse stack was introduced, threads would
 -	often acquire an identical ID to a previously destroyed thread. The
 -	same was true for the pre-reuse stack library, by virtue of pthread_t
 -	being the address of the thread struct. The new pthread_t retains
 -	the reuse stack but provides virtually unique thread IDs.
 -	* sem_wait.c (ptw32_sem_wait_cleanup): New routine used for
 -	cancelation cleanup.
 -	* sem_timedwait.c (ptw32_sem_timedwait_cleanup): Likewise.
 -
 -2004-10-22  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* sem_init.c (sem_init): Introduce a 'lock' element in order to
 -	replace the interlocked operations with conventional serialisation.
 -	This is needed in order to be able to atomically modify the sema
 -	value and perform Win32 sema release operations. Win32 semaphores are
 -	used instead of events in order to support efficient multiple posting.
 -	If the whole modify/release isn't atomic, a race between
 -	sem_timedwait() and sem_post() could result in a release when there is
 -	no waiting semaphore, which would cause too many threads to proceed.
 -	* sem_wait.c (sem_wait): Use new 'lock'element.
 -	* sem_timedwait.c (sem_timedwait): Likewise.
 -	* sem_trywait.c (sem_trywait): Likewise.
 -	* sem_post.c (sem_post): Likewise.
 -	* sem_post_multiple.c (sem_post_multiple): Likewise.
 -	* sem_getvalue.c (sem_getvalue): Likewise.
 -	* ptw32_semwait.c (ptw32_semwait): Likewise.
 -	* sem_destroy.c (sem_destroy): Likewise; also tightened the conditions
 -	for semaphore destruction; in particular, a semaphore will not be
 -	destroyed if it has waiters.
 -	* sem_timedwait.c (sem_timedwait): Added cancel cleanup handler to
 -	restore sema value when cancelled.
 -	* sem_wait.c (sem_wait): Likewise.
 -
 -2004-10-21  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread_mutex_unlock.c (pthread_mutex_unlock): Must use PulseEvent()
 -	rather than SetEvent() to reset the event if there are no waiters.
 -
 -2004-10-19  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* sem_init.c (sem_init): New semaphore model based on the same idea
 -	as mutexes, i.e. user space interlocked check to avoid 
 -	unnecessarily entering kernel space. Wraps the Win32 semaphore and
 -	keeps it's own counter. Although the motivation to do this has existed
 -	for a long time, credit goes to Alexander Terekhov for providing
 -	the logic. I have deviated slightly from AT's logic to add the waiters
 -	count, which has made the code more complicated by adding cancelation
 -	cleanup. This also appears to have broken the VCE (C++ EH) version of
 -	the library (the same problem as previously reported - see BUGS #2),
 -	only apparently not fixable using the usual workaround, nor by turning
 -	all optimisation off. The GCE version works fine, so it is presumed to
 -	be a bug in MSVC++ 6.0. The cancelation exception is thrown and caught
 -	correctly, but the cleanup class destructor is never called. The failing
 -	test is tests\semaphore4.c.
 -	* sem_wait.c (sem_wait): Implemented user space check model.
 -	* sem_post.c (sem_post): Likewise.
 -	* sem_trywait.c (sem_trywait): Likewise.
 -	* sem_timedwait.c (sem_timedwait): Likewise.
 -	* sem_post_multiple.c (sem_post_multiple): Likewise.
 -	* sem_getvalue.c (sem_getvalue): Likewise.
 -	* ptw32_semwait.c (ptw32_semwait): Likewise.
 -	* implement.h (sem_t_): Add counter element.
 -
 -2004-10-15  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* implement.h (pthread_mutex_t_): Use an event in place of
 -	the POSIX semaphore.
 -	* pthread_mutex_init.c: Create the event; remove semaphore init.
 -	* pthread_mutex_destroy.c: Delete the event.
 -	* pthread_mutex_lock.c: Replace the semaphore wait with the event wait.
 -	* pthread_mutex_trylock.c: Likewise.
 -	* pthread_mutex_timedlock.c: Likewise.
 -	* pthread_mutex_unlock.c: Set the event.
 -	
 -2004-10-14  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread_mutex_lock.c (pthread_mutex_lock): New algorithm using
 -	Terekhov's xchg based variation of Drepper's cmpxchg model.
 -	Theoretically, xchg uses fewer clock cycles than cmpxchg (using IA-32
 -	as a reference), however, in my opinion bus locking dominates the
 -	equation on smp systems, so the model with the least number of bus
 -	lock operations in the execution path should win, which is Terekhov's
 -	variant. On IA-32 uni-processor systems, it's faster to use the
 -	CMPXCHG instruction without locking the bus than to use the XCHG
 -	instruction, which always locks the bus. This makes the two variants
 -	equal for the non-contended lock (fast lane) execution path on up
 -	IA-32. Testing shows that the xchg variant is faster on up IA-32 as
 -	well if the test forces higher lock contention frequency, even though
 -	kernel calls should be dominating the times (on up IA-32, both
 -	variants used CMPXCHG instructions and neither locked the bus).
 -	* pthread_mutex_timedlock.c pthread_mutex_timedlock(): Similarly.
 -	* pthread_mutex_trylock.c (pthread_mutex_trylock): Similarly.
 -	* pthread_mutex_unlock.c (pthread_mutex_unlock): Similarly.
 -	* ptw32_InterlockedCompareExchange.c (ptw32_InterlockExchange): New
 -	function.
 -	(PTW32_INTERLOCKED_EXCHANGE): Sets up macro to use inlined
 -	ptw32_InterlockedExchange.
 -	* implement.h (PTW32_INTERLOCKED_EXCHANGE): Set default to
 -	InterlockedExchange().
 -	* Makefile: Building using /Ob2 so that asm sections within inline
 -	functions are inlined.
 -
 -2004-10-08  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread_mutex_destroy.c (pthread_mutex_destroy): Critical Section
 -	element is no longer required.
 -	* pthread_mutex_init.c (pthread_mutex_init): Likewise.
 -	* pthread_mutex_lock.c (pthread_mutex_lock): New algorithm following
 -	Drepper's paper at http://people.redhat.com/drepper/futex.pdf, but
 -	using the existing semaphore in place of the futex described in the
 -	paper. Idea suggested by Alexander Terekhov - see:
 -	http://sources.redhat.com/ml/pthreads-win32/2003/msg00108.html
 -	* pthread_mutex_timedlock.c pthread_mutex_timedlock(): Similarly.
 -	* pthread_mutex_trylock.c (pthread_mutex_trylock): Similarly.
 -	* pthread_mutex_unlock.c (pthread_mutex_unlock): Similarly.
 -	* pthread_barrier_wait.c (pthread_barrier_wait): Use inlined version
 -	of InterlockedCompareExchange() if possible - determined at
 -	build-time.
 -	* pthread_spin_destroy.c pthread_spin_destroy(): Likewise.
 -	* pthread_spin_lock.c pthread_spin_lock():Likewise.
 -	* pthread_spin_trylock.c (pthread_spin_trylock):Likewise.
 -	* pthread_spin_unlock.c (pthread_spin_unlock):Likewise.
 -	* ptw32_InterlockedCompareExchange.c: Sets up macro for inlined use.
 -	* implement.h (pthread_mutex_t_): Remove Critical Section element.
 -	(PTW32_INTERLOCKED_COMPARE_EXCHANGE): Set to default non-inlined
 -	version of InterlockedCompareExchange().
 -	* private.c: Include ptw32_InterlockedCompareExchange.c first for
 -	inlining.
 -	* GNUmakefile: Add commandline option to use inlined
 -	InterlockedCompareExchange().
 -	* Makefile: Likewise.
 -
 -2004-09-27  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread_mutex_lock.c (pthread_mutex_lock): Separate
 -	PTHREAD_MUTEX_NORMAL logic since we do not need to keep or check some
 -	state required by other mutex types; do not check mutex pointer arg
 -	for validity - leave this to the system since we are only checking
 -	for NULL pointers. This should improve speed of NORMAL mutexes and
 -	marginally improve speed of other type.
 -	* pthread_mutex_trylock.c (pthread_mutex_trylock): Likewise.
 -	* pthread_mutex_unlock.c (pthread_mutex_unlock): Likewise; also avoid
 -	entering the critical section for the no-waiters case, with approx.
 -	30% reduction in lock/unlock overhead for this case.
 -	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise; also
 -	no longer keeps mutex if post-timeout second attempt succeeds - this
 -	will assist applications that wish to impose strict lock deadlines,
 -	rather than simply to escape from frozen locks.
 -
 -2004-09-09  Tristan Savatier  <tristan at mpegtv.com>
 -	* pthread.h (struct pthread_once_t_): Qualify the 'done' element
 -	as 'volatile'.
 -	* pthread_once.c: Concerned about possible race condition,
 -	specifically on MPU systems re concurrent access to multibyte types.
 -	[Maintainer's note: the race condition is harmless on SPU systems
 -	and only a problem on MPU systems if concurrent access results in an
 -	exception (presumably generated by a hardware interrupt). There are
 -	other instances of similar harmless race conditions that have not
 -	been identified as issues.]
 -
 -2004-09-09  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread.h: Declare additional types as volatile.
 -
 -2004-08-27  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread_barrier_wait.c (pthread_barrier_wait): Remove excessive code
 -	by substituting the internal non-cancelable version of sem_wait
 -	(ptw32_semwait).
 -
 -2004-08-25  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread_join.c (pthread_join): Rewrite and re-order the conditional
 -	tests in an attempt to improve efficiency and remove a race
 -	condition.
 -
 -2004-08-23  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* create.c (pthread_create): Don't create a thread if the thread
 -	id pointer location (first arg) is inaccessible. A memory
 -	protection fault will result if the thread id arg isn't an accessible
 -	location. This is consistent with GNU/Linux but different to
 -	Solaris or MKS (and possibly others), which accept NULL as meaning
 -	'don't return the created thread's ID'. Applications that run
 -	using pthreads-win32 will run on all other POSIX threads
 -	implementations, at least w.r.t. this feature.
 -
 -	It was decided not to copy the Solaris et al behaviour because,
 -	although it would have simplified some application porting (but only
 -	from Solaris to Windows), the feature is not technically necessary,
 -	and the alternative segfault behaviour helps avoid buggy application
 -	code.
 -
 -2004-07-01  Anuj Goyal  <anuj.goyal at gmail.com>
 -
 -	* builddmc.bat: New; Windows bat file to build the library.
 -	* config.h (__DMC__): Support for Digital Mars compiler.
 -	* create.c (__DMC__): Likewise.
 -	* pthread_exit.c (__DMC__): Likewise.
 -	* pthread_join.c (__DMC__): Likewise.
 -	* ptw32_threadDestroy.c (__DMC__): Likewise.
 -	* ptw32_threadStart.c (__DMC__): Likewise.
 -	* ptw32_throw.c (__DMC__): Likewise.
 -
 -2004-06-29  Anuj Goyal  <anuj.goyal at gmail.com>
 -
 -	* pthread.h (__DMC__): Initial support for Digital Mars compiler.
 -
 -2004-06-29  Will Bryant  <will.bryant at ecosm.com>
 -
 -	* README.Borland: New; description of Borland changes.
 -	* Bmakefile: New makefile for the Borland make utility.
 -	* ptw32_InterlockedCompareExchange.c:
 -	Add Borland compatible asm code.
 -
 -2004-06-26  Jason Bard  <BardJA at Npt.NUWC.Navy.Mil>
 -
 -	* pthread.h (HAVE_STRUCT_TIMESPEC): If undefined, define it
 -	to avoid timespec struct redefined errors elsewhere in an
 -	application.
 -
 -2004-06-21  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread.h (PTHREAD_RECURSIVE_MUTEX_INITIALIZER): Mutex
 -	initialiser added for compatibility with Linux threads and
 -	others; currently not included in SUSV3.
 -	* pthread.h (PTHREAD_ERRORCHECK_MUTEX_INITIALIZER): Likewise.
 -	* pthread.h (PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP): Likewise.
 -	* pthread.h (PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP): Likewise.
 -
 -	* ptw32_mutex_check_need_init.c (ptw32_mutex_check_need_init): 
 -	Add new initialisers.
 -
 -	* pthread_mutex_lock.c (pthread_mutex_lock): Check for new
 -	initialisers.
 -	* pthread_mutex_trylock.c (pthread_mutex_trylock): Likewise.
 -	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise.
 -	* pthread_mutex_unlock.c (pthread_mutex_unlock): Likewise.
 -	* pthread_mutex_destroy.c (pthread_mutex_destroy): Likewise.
 -
 -2004-05-20  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* README.NONPORTABLE: Document pthread_win32_test_features_np().
 -	* FAQ: Update various answers.
 -
 -2004-05-19  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* Makefile: Don't define _WIN32_WINNT on compiler command line.
 -	* GNUmakefile: Likewise.
 -
 -2004-05-16  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread_cancel.c (pthread_cancel): Adapted to use auto-detected
 -	QueueUserAPCEx features at run-time.
 -	(ptw32_RegisterCancelation): Drop in replacement for QueueUserAPCEx()
 -	if it can't be used. Provides older style non-preemptive async
 -	cancelation.
 -	* pthread_win32_attach_detach_np.c (pthread_win32_attach_np):
 -	Auto-detect quserex.dll and the availability of alertdrv.sys;
 -	initialise and close on process attach/detach.
 -	* global.c (ptw32_register_cancelation): Pointer to either
 -	QueueUserAPCEx() or ptw32_RegisterCancelation() depending on
 -	availability. QueueUserAPCEx makes pre-emptive async cancelation
 -	possible.
 -	* implement.h: Add definitions and prototypes related to QueueUserAPC.
 -
 -2004-05-16  Panagiotis E. Hadjidoukas <peh at hpclab.ceid.upatras.gr>
 -
 -	* QueueUserAPCEx (separate contributed package): Provides preemptive
 -	APC feature.
 -	* pthread_cancel.c (pthread_cancel): Initial integration of
 -	QueueUserAPCEx into pthreads-win32 to provide true pre-emptive
 -	async cancelation of threads, including blocked threads.
 -
 -2004-05-06  Makoto Kato  <raven at oldskool.jp>
 -
 -	* pthread.h (DWORD_PTR): Define typedef for older MSVC.
 -	* pthread_cancel.c (AMD64): Add architecture specific Context register.
 -	* ptw32_getprocessors.c: Use correct types (DWORD_PTR) for mask
 -	variables.
 -
 -2004-04-06  P. van Bruggen  <pietvb at newbridges.nl>
 -
 -	* ptw32_threadDestroy.c: Destroy threadLock mutex to
 -	close a memory leak.
 -
 -2004-02-13  Gustav Hallberg  <gustav at virtutech.com>
 -
 -	* pthread_equal.c: Remove redundant equality logic.
 -
 -2003-12-10  Philippe Di Cristo  <philipped at voicebox.com>
 -
 -	* sem_timedwait.c (sem_timedwait): Fix timeout calculations.
 -
 -2003-10-20  Alexander Terekhov  <TEREKHOV at de.ibm.com>
 -
 -	* pthread_mutex_timedlock.c (ptw32_semwait): Move to individual module.
 -	* ptw32_semwait.c: New module.
 -	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): Replace cancelable
 -	sem_wait() call with non-cancelable ptw32_semwait() call.
 -	* pthread.c (private.c): Re-order for inlining. GNU C warned that
 -	function ptw32_semwait() was defined 'inline' after it was called.
 -	* pthread_cond_signal.c (ptw32_cond_unblock): Likewise.
 -	* pthread_delay_np.c: Disable Watcom warning with comment.
 -	* *.c (process.h): Remove include from .c files. This is conditionally
 -	included by the common project include files.
 -
 -2003-10-20  James Ewing  <james.ewing at sveasoft.com>
 -
 -	* ptw32_getprocessors.c: Some Win32 environments don't have
 -	GetProcessAffinityMask(), so always return CPU count = 1 for them.
 -	* config.h (NEED_PROCESSOR_AFFINITY_MASK): Define for WinCE.
 -	
 -2003-10-15  Ross Johnson  <ross at callisto.canberra.edu.au>
 -
 -	* Re-indented all .c files using default GNU style to remove assorted
 -	editor ugliness (used GNU indent utility in default style).
 -
 -2003-10-15  Alex Blanco  <Alex.Blanco at motorola.com>
 -
 -	* sem_init.c (sem_init): Would call CreateSemaphore even if the sema
 -	struct calloc failed; was not freeing calloced memory if either
 -	CreateSemaphore or CreateEvent failed.
 -
 -2003-10-14  Ross Johnson  <ross at callisto.canberra.edu.au>
 -
 -	* pthread.h: Add Watcom compiler compatibility. Esssentially just add
 -	the cdecl attribute to all exposed function prototypes so that Watcom
 -	generates function call code compatible with non-Watcom built libraries.
 -	By default, Watcom uses registers to pass function args if possible rather
 -	than pushing to stack.
 -	* semaphore.h: Likewise.
 -	* sched.h: Likewise.
 -	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): Define with cdecl attribute
 -	for Watcom compatibility. This routine is called via pthread_cleanup_push so
 -	it had to match function arg definition.
 -	* Wmakefile: New makefile for Watcom builds.
 -
 -2003-09-14  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread_setschedparam.c (pthread_setschedparam): Attempt to map
 -	all priority levels between max and min (as returned by
 -	sched_get_priority_min/max) to reasonable Win32 priority levels - i.e.
 -	levels between THREAD_PRIORITY_LOWEST/IDLE to THREAD_PRIORITY_LOWEST and
 -	between THREAD_PRIORITY_HIGHEST/TIME_CRITICAL to THREAD_PRIORITY_HIGHEST
 -	while others remain unchanged; record specified thread priority level
 -	for return by pthread_getschedparam.
 -
 -	Note that, previously, specified levels not matching Win32 priority levels
 -	would silently leave the current thread priority unaltered.
 -
 -	* pthread_getschedparam.c (pthread_getschedparam): Return the priority
 -	level specified by the latest pthread_setschedparam or pthread_create rather
 -	than the actual running thread priority as returned by GetThreadPriority - as
 -	required by POSIX. I.e. temporary or adjusted actual priority levels are not
 -	returned by this routine.
 -
 -	* pthread_create.c (pthread_create): For priority levels specified via
 -	pthread attributes, attempt to map all priority levels between max and
 -	min (as returned by sched_get_priority_min/max) to reasonable Win32
 -	priority levels; record priority level given via attributes, or
 -	inherited from parent thread, for later return by pthread_getschedparam.
 -
 -	* ptw32_new.c (ptw32_new): Initialise pthread_t_ sched_priority element.
 -
 -	* pthread_self.c (pthread_self): Set newly created implicit POSIX thread
 -	sched_priority to Win32 thread's current actual priority. Temporarily
 -	altered priorities can't be avoided in this case.
 -
 -	* implement.h (struct pthread_t_): Add new sched_priority element.
 -
 -2003-09-12  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* sched_get_priority_min.c (sched_get_priority_min): On error should return -1
 -	with errno set.
 -	* sched_get_priority_max.c (sched_get_priority_max): Likewise.
 -
 -2003-09-03  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* w32_cancelableWait.c (ptw32_cancelable_wait): Allow cancelation
 -	of implicit POSIX threads as well.
 -
 -2003-09-02  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread_win32_attach_detach_np.c (pthread_win32_thread_detach_np):
 -	Add comment.
 -
 -	* pthread_exit.c (pthread_exit): Fix to recycle the POSIX thread handle in
 -	addition to calling user TSD destructors. Move the implicit POSIX thread exit
 -	handling to ptw32_throw to centralise the logic.
 -
 -	* ptw32_throw.c (ptw32_throw): Implicit POSIX threads have no point
 -	to jump or throw to, so cleanup and exit the thread here in this case. For
 -	processes using the C runtime, the exit code will be set to the POSIX
 -	reason for the throw (i.e. PTHREAD_CANCEL or the value given to pthread_exit).
 -	Note that pthread_exit() already had similar logic, which has been moved to
 -	here.
 -
 -	* ptw32_threadDestroy.c (ptw32_threadDestroy): Don't close the Win32 handle
 -	of implicit POSIX threads - expect this to be done by Win32?
 -
 -2003-09-01  Ross Johnson  <rpj at callisto.canberra.edu.au>
 -
 -	* pthread_self.c (pthread_self): The newly aquired pthread_t must be
 -	assigned to the reuse stack, not freed, if the routine fails somehow.
 -
 -2003-08-13  Ross Johnson  <rpj at ise.canberra.edu.au>
 -
 -	* pthread_getschedparam.c (pthread_getschedparam): An invalid thread ID
 -	parameter was returning an incorrect error value; now uses a more exhaustive
 -	check for validity.
 -
 -	* pthread_setschedparam.c (pthread_setschedparam): Likewise.
 -
 -	* pthread_join.c (pthread_join): Now uses a more exhaustive
 -	check for validity.
 -
 -	* pthread_detach.c (pthread_detach): Likewise.
 -
 -	* pthread_cancel.c (pthread_cancel): Likewise.
 -
 -	* ptw32_threadDestroy.c (ptw32_threadDestroy): pthread_t structs are
 -	never freed - push them onto a stack for reuse.
 -
 -	* ptw32_new.c (ptw32_new): Check for reusable pthread_t before dynamically
 -	allocating new memory for the struct.
 -
 -	* pthread_kill.c (pthread_kill): New file; new routine; takes only a zero
 -	signal arg so that applications can check the thread arg for validity; checks
 -	that the underlying Win32 thread HANDLE is valid.
 -
 -	* pthread.h (pthread_kill): Add prototype.
 -
 -	* ptw32_reuse.c (ptw32_threadReusePop): New file; new routine; pop a
 -	pthread_t off the reuse stack. pthread_t_ structs that have been destroyed, i.e.
 -	have exited detached or have been joined, are cleaned up and put onto a reuse
 -	stack. Consequently, thread IDs are no longer freed once calloced. The library
 -	will attempt to get a struct off this stack before asking the system to alloc
 -	new memory when creating threads. The stack is guarded by a global mutex.
 -	(ptw32_threadReusePush): New routine; push a pthread_t onto the reuse stack.
 -
 -	* implement.h (ptw32_threadReusePush): Add new prototype.
 -	(ptw32_threadReusePop): Likewise.
 -	(pthread_t): Add new element.
 -
 -	* ptw32_processTerminate.c (ptw32_processTerminate): Delete the thread
 -	reuse lock; free all thread ID structs on the thread reuse stack.
 -
 -	* ptw32_processInitialize.c (ptw32_processInitialize): Initialise the
 -	thread reuse lock.
 -
 -2003-07-19  Ross Johnson  <rpj at ise.canberra.edu.au>
 -
 -	* GNUmakefile: modified to work under MsysDTK environment.
 -	* pthread_spin_lock.c (pthread_spin_lock): Check for NULL arg.
 -	* pthread_spin_unlock.c (pthread_spin_unlock): Likewise.
 -	* pthread_spin_trylock.c (pthread_spin_trylock): Likewise;
 -	fix incorrect pointer value if lock is dynamically initialised by
 -	this function.
 -	* sem_init.c (sem_init): Initialise sem_t value to quell compiler warning.
 -	* sem_destroy.c (sem_destroy): Likewise.
 -	* ptw32_threadStart.c (non-MSVC code sections): Include <exception> rather
 -	than old-style <new.h>; fix all std:: namespace entities such as
 -	std::terminate_handler instances and associated methods.
 -	* ptw32_callUserDestroyRoutines.c (non-MSVC code sections): Likewise.
 -
 -2003-06-24  Piet van Bruggen  <pietvb at newbridges.nl>
 -
 -	* pthread_spin_destroy.c (pthread_spin_destroy): Was not freeing the
 -	spinlock struct.
 -
 -2003-06-22  Nicolas Barry  <boozai at yahoo.com>
 -
 -	* pthread_mutex_destroy.c (pthread_mutex_destroy): When called
 -	with a recursive mutex that was locked by the current thread, the
 -	function was failing with a success return code.
 -
 -2003-05-15  Steven Reddie  <Steven.Reddie at ca.com>
 -
 -	* pthread_win32_attach_detach_np.c (pthread_win32_process_detach_np):
 -	NULLify ptw32_selfThreadKey after the thread is destroyed, otherwise
 -	destructors calling pthreads routines might resurrect it again, creating
 -	memory leaks. Call the underlying Win32 Tls routine directly rather than
 -	pthread_setspecific().
 -	(pthread_win32_thread_detach_np): Likewise.
 -
 -2003-05-14  Viv  <vcotirlea at hotmail.com>
 -
 -	* pthread.dsp: Change /MT compile flag to /MD.
 -
 -2003-03-04  Alexander Terekhov  <TEREKHOV at de.ibm.com>
 -
 -	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Fix failure to
 -	set ownership of mutex on second grab after abstime timeout.
 -	- bug reported by Robert Strycek <strycek at posam.sk>
 -
 -2002-12-17  Thomas Pfaff  <tpfaff at gmx.net>
 -
 -	* pthread_mutex_lock.c (ptw32_semwait): New static routine to provide
 -	a non-cancelable sem_wait() function. This is consistent with the
 -	way that pthread_mutex_timedlock.c does it.
 -	(pthread_mutex_lock): Use ptw32_semwait() instead of sem_wait().
 -
 -2002-12-11  Thomas Pfaff  <tpfaff at gmx.net>
 -
 -	* pthread_mutex_trylock.c: Should return EBUSY rather than EDEADLK.
 -	* pthread_mutex_destroy.c: Remove redundant ownership test (the
 -	trylock call does this for us); do not destroy a recursively locked
 -	mutex.
 -
 -2002-09-20  Michael Johnson  <michaelj at maine.rr.com>
 -
 -	* pthread_cond_destroy.c (pthread_cond_destroy): 
 -	When two different threads exist, and one is attempting to
 -	destroy a condition variable while the other is attempting to
 -	initialize a condition variable that was created with
 -	PTHREAD_COND_INITIALIZER, a deadlock can occur. Shrink
 -	the ptw32_cond_list_lock critical section to fix it.
 -
 -2002-07-31  Ross Johnson  <rpj at special.ise.canberra.edu.au>
 -
 -	* ptw32_threadStart.c (ptw32_threadStart): Thread cancelLock
 -	destruction moved to ptw32_threadDestroy().
 -
 -	* ptw32_threadDestroy.c (ptw32_threadDestroy):  Destroy
 -	the thread's cancelLock. Moved here from ptw32_threadStart.c
 -	to cleanup implicit threads as well.
 -
 -2002-07-30  Alexander Terekhov  <TEREKHOV at de.ibm.com>
 -
 -	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): 
 -	Remove code designed to avoid/prevent spurious wakeup
 -	problems. It is believed that the sem_timedwait() call
 -	is consuming a CV signal that it shouldn't and this is
 -	breaking the avoidance logic.
 -
 -2002-07-30  Ross Johnson  <rpj at ise.canberra.edu.au>
 -
 -	* sem_timedwait.c (sem_timedwait): Tighten checks for
 -	unreasonable abstime values - that would result in
 -	unexpected timeout values.
 -
 -	* w32_CancelableWait.c (ptw32_cancelable_wait):
 -	Tighten up return value checking and add comments.
 -
 -
 -2002-06-08  Ross Johnson  <rpj at special.ise.canberra.edu.au>
 -
 -	* sem_getvalue.c (sem_getvalue): Now returns a value for the
 -	NEED_SEM version (i.e. earlier versions of WinCE).
 -
 -
 -2002-06-04  Rob Fanner  <rfanner at stonethree.com>
 -
 -	* sem_getvalue.c (sem_getvalue): The Johnson M. Hart
 -	approach didn't work - we are forced to take an
 -	intrusive approach. We try to decrement the sema
 -	and then immediately release it again to get the
 -	value. There is a small probability that this may
 -	block other threads, but only momentarily.
 -
 -2002-06-03  Ross Johnson  <rpj at ise.canberra.edu.au>
 -
 -	* sem_init.c (sem_init): Initialise Win32 semaphores
 -	to _POSIX_SEM_VALUE_MAX (which this implementation
 -	defines in pthread.h) so that sem_getvalue() can use
 -	the trick described in the comments in sem_getvalue().
 -	* pthread.h (_POSIX_SEM_VALUE_MAX): Defined.
 -	(_POSIX_SEM_NSEMS_MAX): Defined - not used but may be
 -	useful for source code portability.
 -
 -2002-06-03  Rob Fanner  <rfanner at stonethree.com>
 -
 -	* sem_getvalue.c (sem_getvalue): Did not work on NT.
 -	Use approach suggested by Johnson M. Hart in his book
 -	"Win32 System Programming".
 -
 -2002-02-28  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* errno.c: Compiler directive was incorrectly including code.
 -	* pthread.h: Conditionally added some #defines from config.h
 -	needed when not building the library. e.g. NEED_ERRNO, NEED_SEM.
 -	(PTW32_DLLPORT): Now only defined if _DLL defined.
 -	(_errno): Compiler directive was incorrectly including prototype.
 -	* sched.h: Conditionally added some #defines from config.h
 -	needed when not building the library.
 -	* semaphore.h: Replace an instance of NEED_SEM that should
 -	have been NEED_ERRNO. This change currently has nil effect.
 -
 -	* GNUmakefile: Correct some recent changes.
 -
 -	* Makefile: Add rule to generate pre-processor output.
 -
 -2002-02-23  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* pthread_rwlock_timedrdlock.c: New - untested.
 -	* pthread_rwlock_timedwrlock.c: New - untested.
 -	
 -	* Testsuite passed (except known MSVC++ problems)
 -
 -	* pthread_cond_destroy.c: Expand the time change
 -	critical section to solve deadlock problem.
 -
 -	* pthread.c: Add all remaining C modules.
 -	* pthread.h: Use dllexport/dllimport attributes on functions
 -	to avoid using pthread.def.
 -	* sched.h: Likewise.
 -	* semaphore.h: Likewise.
 -	* GNUmakefile: Add new targets for single translation
 -	unit build to maximise inlining potential; generate
 -	pthread.def automatically.
 -	* Makefile: Likewise, but no longer uses pthread.def.
 -
 -2002-02-20  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* pthread_cond_destroy.c (pthread_cond_destroy):
 -	Enter the time change critical section earlier.
 -
 -2002-02-17  Ross Johnson  <rpj at setup1.ise.canberra.edu.au
 -
 -	* Testsuite passed.
 -
 -	* pthread_timechange_handler_np.c: New; following
 -	a suggestion from Alexander Terekhov that CVs should
 -	be broadcast so that they all re-evaluate their
 -	condition variables and reset a new timeout if
 -	required, whenever an application receives a
 -	WM_TIMECHANGE message. This message indicates that
 -	the system time has been changed. Therefore, CVs
 -	waiting for a timeout set as an abs_time will possibly
 -	not wake up at the expected time. Some applications
 -	may not be tolerant of this.
 -	* pthread_cond_init.c: Add CV to linked list.
 -	* pthread_cond_destroy.c: Remove CV from linked list.
 -	* global.c (ptw32_cond_list_head): New variable.
 -	(ptw32_cond_list_tail): New variable.
 -	(ptw32_cond_list_cs): New critical section.
 -	* ptw32_processInitialize (ptw32_cond_list_cs): Initialize.
 -	* ptw32_processTerminate (ptw32_cond_list_cs): Delete.
 -
 -
 -	* Reduce executable size.
 -	  -----------------------
 -	When linking with the static library, only those
 -	routines actually called, either directly or indirectly
 -	should be included.
 -
 -	[Gcc has the -ffunction-segments option to do this but MSVC
 -	doesn't have this feature as far as I can determine. Other
 -	compilers are undetermined as well. - rpj]
 -
 -	* spin.c: Split file into function segments.
 -	* ptw32_spinlock_check_need_init.c: Separated routine from spin.c.
 -	* pthread_spin_init.c: Likewise.
 -	* pthread_spin_destroy.c: Likewise.
 -	* pthread_spin_lock.c: Likewise.
 -	* pthread_spin_unlock.c: Likewise.
 -	* pthread_spin_trylock.c: Likewise.
 -
 -	* sync.c: Split file into function segments.
 -	* pthread_detach.c: Separated routine from sync.c.
 -	* pthread_join.c: Likewise.
 -
 -	* tsd.c: Split file into function segments.
 -	* pthread_key_create.c: Separated routine from tsd.c.
 -	* pthread_key_delete.c: Likewise.
 -	* pthread_setspecific.c: Likewise.
 -	* pthread_getspecific.c: Likewise.
 -
 -	* sched.c: Split file into function segments.
 -	* pthread_attr_setschedpolicy.c: Separated routine from sched.c.
 -	* pthread_attr_getschedpolicy.c: Likewise.
 -	* pthread_attr_setschedparam.c: Likewise.
 -	* pthread_attr_getschedparam.c: Likewise.
 -	* pthread_attr_setinheritsched.c: Likewise.
 -	* pthread_attr_getinheritsched.c: Likewise.
 -	* pthread_setschedparam.c: Likewise.
 -	* pthread_getschedparam.c: Likewise.
 -	* sched_get_priority_max.c: Likewise.
 -	* sched_get_priority_min.c: Likewise.
 -	* sched_setscheduler.c: Likewise.
 -	* sched_getscheduler.c: Likewise.
 -	* sched_yield.c: Likewise.
 -
 -
 -2002-02-16  Ross Johnson  <rpj at setup1.ise.canberra.edu.au
 -
 -	Reduce executable size.
 -	-----------------------
 -	When linking with the static library, only those
 -	routines actually called, either directly or indirectly
 -	should be included.
 -
 -	[Gcc has the -ffunction-segments option to do this but MSVC
 -	doesn't have this feature as far as I can determine. Other
 -	compilers are undetermined as well. - rpj]
 -
 -	* mutex.c: Split file into function segments.
 -	* pthread_mutexattr_destroy.c: Separated routine from mutex.c
 -	* pthread_mutexattr_getpshared.c: Likewise.
 -	* pthread_mutexattr_gettype.c: Likewise.
 -	* pthread_mutexattr_init.c: Likewise.
 -	* pthread_mutexattr_setpshared.c: Likewise.
 -	* pthread_mutexattr_settype.c: Likewise.
 -	* ptw32_mutex_check_need_init.c: Likewise.
 -	* pthread_mutex_destroy.c: Likewise.
 -	* pthread_mutex_init.c: Likewise.
 -	* pthread_mutex_lock.c: Likewise.
 -	* pthread_mutex_timedlock.c: Likewise.
 -	* pthread_mutex_trylock.c: Likewise.
 -	* pthread_mutex_unlock.c: Likewise.
 -	
 -	* private.c: Split file into function segments.
 -	* ptw32_InterlockedCompareExchange.c: Separated routine from private.c
 -	* ptw32_callUserDestroyRoutines.c: Likewise.
 -	* ptw32_getprocessors.c: Likewise.
 -	* ptw32_processInitialize.c: Likewise.
 -	* ptw32_processTerminate.c: Likewise.
 -	* ptw32_threadDestroy.c: Likewise.
 -	* ptw32_threadStart.c: Likewise.
 -	* ptw32_throw.c: Likewise.
 -	* ptw32_timespec.c: Likewise.
 -	* ptw32_tkAssocCreate.c: Likewise.
 -	* ptw32_tkAssocDestroy.c: Likewise.
 -
 -	* rwlock.c: Split file into function segments.
 -	* pthread_rwlockattr_destroy.c: Separated routine from rwlock.c
 -	* pthread_rwlockattr_getpshared.c: Likewise.
 -	* pthread_rwlockattr_init.c: Likewise.
 -	* pthread_rwlockattr_setpshared.c: Likewise.
 -	* ptw32_rwlock_check_need_init.c: Likewise.
 -	* pthread_rwlock_destroy.c: Likewise.
 -	* pthread_rwlock_init.c: Likewise.
 -	* pthread_rwlock_rdlock.c: Likewise.
 -	* pthread_rwlock_tryrdlock.c: Likewise.
 -	* pthread_rwlock_trywrlock.c: Likewise.
 -	* pthread_rwlock_unlock.c: Likewise.
 -	* pthread_rwlock_wrlock.c: Likewise.
 -
 -2002-02-10  Ross Johnson  <rpj at setup1.ise.canberra.edu.au
 -
 -	Reduce executable size.
 -	-----------------------
 -	When linking with the static library, only those
 -	routines actually called, either directly or indirectly
 -	should be included.
 -
 -	[Gcc has the -ffunction-segments option to do this but MSVC
 -	doesn't have this feature as far as I can determine. Other
 -	compilers are undetermined as well. - rpj]
 -
 -	* nonportable.c: Split file into function segments.
 -	* np_delay.c: Separated routine from nonportable.c
 -	* np_getw32threadhandle.c: Likewise.
 -	* np_mutexattr_setkind.c: Likewise.
 -	* np_mutexattr_getkind.c: Likewise.
 -	* np_num_processors.c: Likewise.
 -	* np_win32_attach_detach.c: Likewise.
 -
 -	* misc.c: Split file into function segments.
 -	* pthread_equal.c: Separated routine from nonportable.c.
 -	* pthread_getconcurrency.c: Likewise.
 -	* pthread_once.c: Likewise.
 -	* pthread_self.c: Likewise.
 -	* pthread_setconcurrency.c: Likewise.
 -	* ptw32_calloc.c: Likewise.
 -	* ptw32_new.c: Likewise.
 -	* w32_CancelableWait.c: Likewise.
 -	
 -2002-02-09  Ross Johnson  <rpj at setup1.ise.canberra.edu.au
 -
 -	Reduce executable size.
 -	-----------------------
 -	When linking with the static library, only those
 -	routines actually called, either directly or indirectly
 -	should be included.
 -
 -	[Gcc has the -ffunction-segments option to do this but MSVC
 -	doesn't have this feature as far as I can determine. Other
 -	compilers are undetermined as well. - rpj]
 -
 -	* condvar.c: Split file into function segments.
 -	* pthread_condattr_destroy.c: Separated routine from condvar.c.
 -	* pthread_condattr_getpshared.c: Likewise.
 -	* pthread_condattr_init.c: Likewise.
 -	* pthread_condattr_setpshared.c: Likewise.
 -	* ptw32_cond_check_need_init.c: Likewise.
 -	* pthread_cond_destroy.c: Likewise.
 -	* pthread_cond_init.c: Likewise.
 -	* pthread_cond_signal.c: Likewise.
 -	* pthread_cond_wait.c: Likewise.
 -	
 -2002-02-07  Alexander Terekhov<TEREKHOV at de.ibm.com>
 -
 -	* nonportable.c (pthread_delay_np): Make a true
 -	cancelation point. Deferred cancels will interrupt the
 -	wait.
 -
 -2002-02-07  Ross Johnson  <rpj at setup1.ise.canberra.edu.au
 -
 -	* misc.c (ptw32_new): Add creation of cancelEvent so that
 -	implicit POSIX threads (Win32 threads with a POSIX face)
 -	are cancelable; mainly so that pthread_delay_np doesn't fail
 -	if called from the main thread.
 -	* create.c (pthread_create): Remove creation of cancelEvent
 -	from here; now in ptw32_new().
 -
 -	Reduce executable size.
 -	-----------------------
 -	When linking with the static library, only those
 -	routines actually called, either directly or indirectly
 -	should be included.
 -
 -	[Gcc has the -ffunction-segments option to do this but MSVC
 -	doesn't have this feature as far as I can determine. Other
 -	compilers are undetermined as well. - rpj]
 -
 -	* barrier.c: All routines are now in separate compilation units;
 -	This file is used to congregate the separate modules for
 -	potential inline optimisation and backward build compatibility.
 -	* cancel.c: Likewise.
 -	* pthread_barrierattr_destroy.c: Separated routine from cancel.c.
 -	* pthread_barrierattr_getpshared.c: Likewise.
 -	* pthread_barrierattr_init.c: Likewise.
 -	* pthread_barrierattr_setpshared.c: Likewise.
 -	* pthread_barrier_destroy.c: Likewise.
 -	* pthread_barrier_init.c: Likewise.
 -	* pthread_barrier_wait.c: Likewise.
 -	* pthread_cancel.c: Likewise.
 -	* pthread_setcancelstate.c: Likewise.
 -	* pthread_setcanceltype.c: Likewise.
 -	* pthread_testcancel.c: Likewise.
 -
 -2002-02-04  Max Woodbury <mtew at cds.duke.edu>
 -
 -	Reduced name space pollution.
 -	-----------------------------
 -	When the appropriate symbols are defined, the headers
 -	will restrict the definitions of new names. In particular,
 -	it must be possible to NOT include the <windows.h>
 -	header and related definitions with some combination
 -	of symbol definitions. Secondly, it should be possible
 -	that additional definitions should be limited to POSIX 
 -	compliant symbols by the definition of appropriate symbols.
 -
 -	* pthread.h: POSIX conditionals.
 -	* sched.h: POSIX conditionals.
 -	* semaphore.h: POSIX conditionals.
 -
 -	* semaphore.c: Included <limits.h>.
 -	(sem_init): Changed magic 0x7FFFFFFFL to INT_MAX.
 -	(sem_getvalue): Trial version.
 -
 -	Reduce executable size.
 -	-----------------------
 -	When linking with the static library, only those
 -	routines actually called, either directly or indirectly
 -	should be included.
 -
 -	[Gcc has the -ffunction-segments option to do this but MSVC
 -	doesn't have this feature as far as I can determine. Other
 -	compilers are undetermined as well. - rpj]
 -
 -	* semaphore.c: All routines are now in separate compilation units;
 -	This file is used to congregate the separate modules for
 -	potential inline optimisation and backward build compatibility.
 -	* sem_close.c: Separated routine from semaphore.c.
 -	* ptw32_decrease_semaphore.c: Likewise.
 -	* sem_destroy.c: Likewise.
 -	* sem_getvalue.c: Likewise.
 -	* ptw32_increase_semaphore.c: Likewise.
 -	* sem_init.c: Likewise.
 -	* sem_open.c: Likewise.
 -	* sem_post.c: Likewise.
 -	* sem_post_multiple.c: Likewise.
 -	* sem_timedwait.c: Likewise.
 -	* sem_trywait.c: Likewise.
 -	* sem_unlink.c: Likewise.
 -	* sem_wait.c: Likewise.
 -
 -2002-02-04  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	The following extends the idea above to the rest of pthreads-win32 - rpj
 -	
 -	* attr.c: All routines are now in separate compilation units;
 -	This file is used to congregate the separate modules for
 -	potential inline optimisation and backward build compatibility.
 -	* pthread_attr_destroy.c: Separated routine from attr.c.
 -	* pthread_attr_getdetachstate.c: Likewise.
 -	* pthread_attr_getscope.c: Likewise.
 -	* pthread_attr_getstackaddr.c: Likewise.
 -	* pthread_attr_getstacksize.c: Likewise.
 -	* pthread_attr_init.c: Likewise.
 -	* pthread_attr_is_attr.c: Likewise.
 -	* pthread_attr_setdetachstate.c: Likewise.
 -	* pthread_attr_setscope.c: Likewise.
 -	* pthread_attr_setstackaddr.c: Likewise.
 -	* pthread_attr_setstacksize.c: Likewise.
 -
 -	* pthread.c: Agregation of agregate modules for super-inlineability.
 -
 -2002-02-02  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* cancel.c: Rearranged some code and introduced checks
 -	to disable cancelation at the start of a thread's cancelation
 -	run to prevent double cancelation. The main problem
 -	arises if a thread is canceling and then receives a subsequent
 -	async cancel request.
 -	* private.c: Likewise.
 -	* condvar.c: Place pragmas around cleanup_push/pop to turn
 -	off inline optimisation (/Obn where n>0 - MSVC only). Various
 -	optimisation switches in MSVC turn this on, which interferes with
 -	the way that cleanup handlers are run in C++ EH and SEH
 -	code. Application code compiled with inline optimisation must
 -	also wrap cleanup_push/pop blocks with the pragmas, e.g.
 -	  #pragma inline_depth(0)
 -	  pthread_cleanup_push(...)
 -	    ...
 -	  pthread_cleanup_pop(...)
 -	  #pragma inline_depth(8)
 -	* rwlock.c: Likewise.
 -	* mutex.c: Remove attempts to inline some functions.
 -	* signal.c: Modify misleading comment.
 -
 -2002-02-01  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* semaphore.c (sem_trywait): Fix missing errno return
 -	for systems that define NEED_SEM (e.g. early WinCE).
 -	* mutex.c (pthread_mutex_timedlock): Return ENOTSUP
 -	for systems that define NEED_SEM since they don't
 -	have sem_trywait().
 -
 -2002-01-27  Ross Johnson  <rpj at special.ise.canberra.edu.au>
 -
 -	* mutex.c (pthread_mutex_timedlock): New function suggested by
 -	Alexander Terekhov. The logic required to implement this
 -	properly came from Alexander, with some collaboration
 -	with Thomas Pfaff.
 -	(pthread_mutex_unlock): Wrap the waiters check and sema
 -	post in a critical section to prevent a race with
 -	pthread_mutex_timedlock.
 -	(ptw32_timed_semwait): New function;
 -	returns a special result if the absolute timeout parameter
 -	represents a time already passed when called; used by
 -	pthread_mutex_timedwait(). Have deliberately not reused
 -	the name "ptw32_sem_timedwait" because they are not the same
 -	routine.
 -	* condvar.c (ptw32_cond_timedwait): Use the new sem_timedwait()
 -	instead of ptw32_sem_timedwait(), which now has a different
 -	function. See previous.
 -	* implement.h: Remove prototype for ptw32_sem_timedwait.
 -	See next.
 -	(pthread_mutex_t_): Add critical section element for access
 -	to lock_idx during mutex post-timeout processing.
 -	* semaphore.h (sem_timedwait): See next.
 -	* semaphore.c (sem_timedwait): See next.
 -	* private.c (ptw32_sem_timedwait): Move to semaphore.c
 -	and rename as sem_timedwait().
 -
 -2002-01-18  Ross Johnson  <rpj at special.ise.canberra.edu.au>
 -
 -	* sync.c (pthread_join): Was getting the exit code from the
 -	calling thread rather than the joined thread if
 -	defined(__MINGW32__) && !defined(__MSVCRT__).
 -
 -2002-01-15  Ross Johnson  <rpj at special.ise.canberra.edu.au>
 -
 -	* pthread.h: Unless the build explicitly defines __CLEANUP_SEH,
 -	__CLEANUP_CXX, or __CLEANUP_C, then the build defaults to
 -	__CLEANUP_C style cleanup. This style uses setjmp/longjmp
 -	in the cancelation and thread exit implementations and therefore
 -	won't do stack unwinding if linked to applications that have it
 -	(e.g. C++ apps). This is currently consistent with most/all
 -	commercial Unix POSIX threads implementations.
 -
 -	* spin.c (pthread_spin_init): Edit renamed function call.
 -	* nonportable.c (pthread_num_processors_np): New.
 -	(pthread_getprocessors_np): Renamed to ptw32_getprocessors
 -	and moved to private.c.
 -	* private.c (pthread_getprocessors): Moved here from
 -	nonportable.c.
 -	* pthread.def (pthread_getprocessors_np): Removed
 -	from export list.
 -
 -	* rwlock.c (pthread_rwlockattr_init): New.
 -	(pthread_rwlockattr_destroy): New.
 -	(pthread_rwlockattr_getpshared): New.
 -	(pthread_rwlockattr_setpshared): New.
 -
 -2002-01-14  Ross Johnson  <rpj at special.ise.canberra.edu.au>
 -
 -	* attr.c (pthread_attr_setscope): Fix struct pointer
 -	indirection error introduced 2002-01-04.
 -	(pthread_attr_getscope): Likewise.
 -
 -2002-01-12  Ross Johnson  <rpj at special.ise.canberra.edu.au>
 -
 -	* pthread.dsp (SOURCE): Add missing source files.
 -
 -2002-01-08  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* mutex.c (pthread_mutex_trylock): use
 -	ptw32_interlocked_compare_exchange function pointer
 -	rather than ptw32_InterlockedCompareExchange() directly
 -	to retain portability to non-iX86 processors,
 -	e.g. WinCE etc. The pointer will point to the native
 -	OS version of InterlockedCompareExchange() if the
 -	OS supports it (see ChangeLog entry of 2001-10-17).
 -
 -2002-01-07  Thomas Pfaff <tpfaff at gmx.net>, Alexander Terekhov <TEREKHOV at de.ibm.com>
 -
 -	* mutex.c (pthread_mutex_init): Remove critical
 -	section calls.
 -	(pthread_mutex_destroy): Likewise.
 -	(pthread_mutex_unlock): Likewise.
 -	(pthread_mutex_trylock): Likewise; uses
 -	ptw32_InterlockedCompareExchange() to avoid need for
 -	critical section; library is no longer i386 compatible;
 -	recursive mutexes now increment the lock count rather
 -	than return EBUSY; errorcheck mutexes return EDEADLCK
 -	rather than EBUSY. This behaviour is consistent with the
 -	Solaris pthreads implementation.
 -	* implement.h (pthread_mutex_t_): Remove critical
 -	section element - no longer needed.
 -	
 -
 -2002-01-04  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* attr.c (pthread_attr_setscope): Add more error
 -	checking and actually store the scope value even
 -	though it's not really necessary.
 -	(pthread_attr_getscope): Return stored value.
 -	* implement.h (pthread_attr_t_): Add new scope element.
 -	* ANNOUNCE: Fix out of date comment next to
 -	pthread_attr_setscope in conformance section.
 -
 -2001-12-21  Alexander Terekhov <TEREKHOV at de.ibm.com>
 -
 -	* mutex.c (pthread_mutex_lock): Decrementing lock_idx was
 -	not thread-safe.
 -	(pthread_mutex_trylock): Likewise.
 -
 -2001-10-26  prionx@juno.com
 -
 -	* semaphore.c (sem_init): Fix typo and missing bracket
 -	in conditionally compiled code. Only older versions of
 -	WinCE require this code, hence it doesn't normally get
 -	tested; somehow when sem_t reverted to an opaque struct
 -	the calloc NULL check was left in the conditionally included
 -	section.
 -	(sem_destroy): Likewise, the calloced sem_t wasn't being freed.
 -
 -2001-10-25  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* GNUmakefile (libwsock32): Add to linker flags for
 -	WSAGetLastError() and WSASetLastError().
 -	* Makefile (wsock32.lib): Likewise.
 -	* create.c: Minor mostly inert changes.
 -	* implement.h (PTW32_MAX): Move into here and renamed
 -	from sched.h.
 -	(PTW32_MIN): Likewise.
 -	* GNUmakefile (TEST_ICE): Define if testing internal
 -	implementation of InterlockedCompareExchange.
 -	* Makefile (TEST_ICE): Likewise.
 -	* private.c (TEST_ICE): Likewise.
 -	
 -2001-10-24  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* attr.c (pthread_attr_setstacksize): Quell warning
 -	from LCC by conditionally compiling the stacksize
 -	validity check. LCC correctly warns that the condition
 -	(stacksize < PTHREAD_STACK_MIN) is suspicious
 -	because STACK_MIN is 0 and stacksize is of type
 -	size_t (or unsigned int).
 -
 -2001-10-17  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* barrier.c: Move _LONG and _LPLONG defines into
 -	implement.h; rename to PTW32_INTERLOCKED_LONG and
 -	PTW32_INTERLOCKED_LPLONG respectively.
 -	* spin.c: Likewise; ptw32_interlocked_compare_exchange used
 -	in place of InterlockedCompareExchange directly.
 -	* global.c (ptw32_interlocked_compare_exchange): Add
 -	prototype for this new routine pointer to be used when
 -	InterlockedCompareExchange isn't supported by Windows.
 -	* nonportable.c (pthread_win32_process_attach_np): Check for
 -	support of InterlockedCompareExchange in kernel32 and assign its
 -	address to ptw32_interlocked_compare_exchange if it exists, or
 -	our own ix86 specific implementation ptw32_InterlockedCompareExchange.
 -	*private.c (ptw32_InterlockedCompareExchange): An
 -	implementation of InterlockedCompareExchange() which is
 -	specific to ix86; written directly in assembler for either
 -	MSVC or GNU C; needed because Windows 95 doesn't support
 -	InterlockedCompareExchange().
 -
 -	* sched.c (sched_get_priority_min): Extend to return
 -	THREAD_PRIORITY_IDLE.
 -	(sched_get_priority_max): Extend to return
 -	THREAD_PRIORITY_CRITICAL.
 -
 -2001-10-15  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* spin.c (pthread_spin_lock): PTHREAD_SPINLOCK_INITIALIZER
 -	was causing a program fault.
 -	(pthread_spin_init): Could have alloced memory
 -	without freeing under some error conditions.
 -
 -	* mutex.c (pthread_mutex_init): Move memory
 -	allocation of mutex struct after checking for
 -	PROCESS_SHARED.
 -
 -2001-10-12  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* spin.c (pthread_spin_unlock): Was not returning
 -	EPERM if the spinlock was not locked, for multi CPU
 -	machines.
 -
 -2001-10-08  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* spin.c (pthread_spin_trylock): Was not returning
 -	EBUSY for multi CPU machines.
 -
 -2001-08-24  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* condvar.c (pthread_cond_destroy): Remove cv element
 -	that is no longer used.
 -	* implement.h: Likewise.
 -
 -2001-08-23  Alexander Terekhov <TEREKHOV at de.ibm.com>
 -
 -	* condvar.c (pthread_cond_destroy): fix bug with
 -	respect to deadlock in the case of concurrent
 -	_destroy/_unblock; a condition variable can be destroyed
 -	immediately after all the threads that are blocked on
 -	it are awakened.
 -
 -2001-08-23  Phil Frisbie, Jr. <phil at hawksoft.com>
 -
 -	* tsd.c (pthread_getspecific): Preserve the last
 -	winsock error [from WSAGetLastError()].
 -
 -2001-07-18  Scott McCaskill <scott at magruder.org>
 -
 -	* mutex.c (pthread_mutexattr_init): Return ENOMEM
 -	immediately and don't dereference the NULL pointer
 -	if calloc fails.
 -	(pthread_mutexattr_getpshared): Don't dereference
 -	a pointer that is possibly NULL.
 -	* barrier.c (pthread_barrierattr_init): Likewise
 -	(pthread_barrierattr_getpshared): Don't dereference
 -	a pointer that is possibly NULL.
 -	* condvar.c (pthread_condattr_getpshared): Don't dereference
 -	a pointer that is possibly NULL.
 -
 -2001-07-15  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* rwlock.c (pthread_rwlock_wrlock): Is allowed to be
 -	a cancelation point; re-enable deferred cancelability
 -	around the CV call.
 -
 -2001-07-10  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* barrier.c: Still more revamping. The exclusive access
 -	mutex isn't really needed so it has been removed and replaced
 -	by an InterlockedDecrement(). nSerial has been removed.
 -	iStep is now dual-purpose. The process shared attribute
 -	is now stored in the barrier struct.
 -	* implement.h (pthread_barrier_t_): Lost some/gained one
 -	elements.
 -	* private.c (ptw32_threadStart): Removed some comments.
 -
 -2001-07-10  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* barrier.c: Revamped to fix the race condition. Two alternating
 -	semaphores are used instead of the PulseEvent. Also improved
 -	overall throughput by returning PTHREAD_BARRIER_SERIAL_THREAD
 -	to the first waking thread.
 -	* implement.h (pthread_barrier_t_): Revamped.
 -
 -2001-07-09  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* barrier.c: Fix several bugs in all routines. Now passes
 -	tests/barrier5.c which is fairly rigorous. There is still
 -	a non-optimal work-around for a race condition between
 -	the barrier breeched event signal and event wait. Basically
 -	the last (signalling) thread to hit the barrier yields
 -	to allow any other threads, which may have lost the race,
 -	to complete.
 -
 -2001-07-07  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* barrier.c: Changed synchronisation mechanism to a
 -	Win32 manual reset Event and use PulseEvent to signal
 -	waiting threads. If the implementation continued to use
 -	a semaphore it would require a second semaphore and
 -	some management to use them alternately as barriers. A
 -	single semaphore allows threads to cascade from one barrier
 -	through the next, leaving some threads blocked at the first.
 -	* implement.h (pthread_barrier_t_): As per above.
 -	* general: Made a number of other routines inlinable.
 -
 -2001-07-07  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* spin.c: Revamped and working; included static initialiser.
 -	Now beta level.
 -	* barrier.c: Likewise.
 -	* condvar.c: Macro constant change; inline auto init routine.
 -	* mutex.c: Likewise.
 -	* rwlock.c: Likewise.
 -	* private.c: Add support for spinlock initialiser.
 -	* global.c: Likewise.
 -	* implement.h: Likewise.
 -	* pthread.h (PTHREAD_SPINLOCK_INITIALIZER): Fix typo.
 -
 -2001-07-05  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* barrier.c: Remove static initialisation - irrelevent
 -	for this object.
 -	* pthread.h (PTHREAD_BARRIER_INITIALIZER): Removed.
 -	* rwlock.c (pthread_rwlock_wrlock): This routine is
 -	not a cancelation point - disable deferred
 -	cancelation around call to pthread_cond_wait().
 -
 -2001-07-05  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* spin.c: New module implementing spin locks.
 -	* barrier.c: New module implementing barriers.
 -	* pthread.h (_POSIX_SPIN_LOCKS): defined.
 -	(_POSIX_BARRIERS): Defined.
 -	(pthread_spin_*): Defined.
 -	(pthread_barrier*): Defined.
 -	(PTHREAD_BARRIER_SERIAL_THREAD): Defined.
 -	* implement.h (pthread_spinlock_t_): Defined.
 -	(pthread_barrier_t_): Defined.
 -	(pthread_barrierattr_t_): Defined.
 -
 -	* mutex.c (pthread_mutex_lock): Return with the error
 -	if an auto-initialiser initialisation fails.
 -
 -	* nonportable.c (pthread_getprocessors_np): New; gets the
 -	number of available processors for the current process.
 -
 -2001-07-03  Ross Johnson  <rpj at setup1.ise.canberra.edu.au>
 -
 -	* pthread.h (_POSIX_READER_WRITER_LOCKS): Define it
 -	if not already defined.
 -
 -2001-07-01  Alexander Terekhov <TEREKHOV at de.ibm.com>
 -
 -	* condvar.c: Fixed lost signal bug reported by Timur Aydin
 -	(taydin@snet.net).
 -	[RPJ (me) didn't translate the original algorithm
 -	correctly.]
 -	* semaphore.c: Added sem_post_multiple; this is a useful
 -	routine, but it doesn't appear to be standard. For now it's
 -	not an exported function.
 -	
 -2001-06-25  Ross Johnson  <rpj at 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 at 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  Ralf Brese <Ralf.Brese at pdb4.siemens.de>
 -
 -	* create.c (pthread_create): Set thread priority from
 -	thread attributes.
 -
 -2001-06-18  Ross Johnson  <rpj at 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  David Korn <dgk at 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 at 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 at 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 at setup1.ise.canberra.edu.au>
 -
 -	* mutex.c (pthread_mutexattr_init): Remove 
 -	ptw32_mutex_default_kind.
 -	
 -2001-06-05  Ross Johnson  <rpj at 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 at 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  Alexander Terekhov <TEREKHOV at de.ibm.com>, Louis Thomas <lthomas at 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 at 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  Milan Gardian <Milan.Gardian at 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  Thomas Pfaff <tpfaff at 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  Alexander Terekhov <TEREKHOV at 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 at 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 at 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 at special.ise.canberra.edu.au>
 -
 -	* FAQ: Update Answer 6 re getting a fully working
 -	Mingw32 built library.
 -
 -2000-10-10  Steven Reddie <smr at essemer.com.au>
 - 
 -        * misc.c (pthread_self): Restore Win32 "last error"
 -        cleared by TlsGetValue() call in
 -        pthread_getspecific()
 - 
 -2000-09-20  Arthur Kantor <akantor at bexusa.com>
 - 
 -        * 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.
 -
 -2000-09-13  Jef Gearhart <jgearhart at tpssys.com>
 -
 -	* 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
 -
 -2000-09-09  Ross Johnson  <rpj at special.ise.canberra.edu.au>
 -
 -	* pthread.h (ctime_r): Fix arg.
 -
 -2000-09-08  Ross Johnson  <rpj at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at special.ise.canberra.edu.au>
 -
 -	* pthread.h: Remove #warning - VC++ doesn't accept it.
 -
 -2000-08-05  Ross Johnson  <rpj at 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 at 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 at 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  Tristan Savatier <tristan at mpegtv.com>
 -
 -	* sched.c (sched_get_priority_max): Handle different WinCE and
 -	Win32 priority values together.
 -	(sched_get_priority_min): Ditto.
 -
 -2000-07-25  Ross Johnson  <rpj at special.ise.canberra.edu.au>
 -
 -	* 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 at 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 at special.ise.canberra.edu.au>
 -
 -	* FAQ: Added Q5 and Q6.
 -
 -2000-07-21  David Baggett <dmb at itasoftware.com>
 -
 -	* 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.
 -
 -2000-07-21  Ross Johnson  <rpj at 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.)
 -
 -	* 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 at 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 at 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 at 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  Erik Hensema <erik.hensema at group2000.nl>
 -
 -	* Makefile: Remove inconsistencies in 'cl' args
 -
 -2000-01-04  Ross Johnson  <rpj at 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 at 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 at 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.
 -
 -1999-11-21  Jason Nye <jnye at nbnet.nb.ca>, Erik Hensema <erik.hensema at group2000.nl>
 -
 -	* 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.
 -
 -1999-11-13  Erik Hensema <erik.hensema at group2000.nl>
 -
 -	* configure.in (AC_OUTPUT): Put generated output into GNUmakefile
 -	rather than Makefile. Makefile will become the MSC nmake compatible
 -	version
 -
 -1999-11-13  John Bossom (John.Bossom@cognos.com>
 -
 -	* misc.c (pthread_self): Add a note about GetCurrentThread
 -	returning a pseudo-handle
 -
 -1999-11-10  Todd Owen <towen at lucidcalm.dropbear.id.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.
 -
 -1999-11-10  Ross Johnson  <rpj at ixobrychus.canberra.edu.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  Tristan Savatier <tristan at mpegtv.com>
 -
 -	* 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.
 -
 -1999-10-30  Erik Hensema <erik.hensema at group2000.nl>
 -
 -	* 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:
 -
 -1999-10-23  Erik Hensema <erik.hensema at group2000.nl>
 -
 -	* pthread.h (ctime_r): Fix incorrect argument "_tm"
 -
 -1999-10-21  Aurelio Medina <aureliom at crt.com>
 -
 -	* 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
 -
 -1999-10-17  Ross Johnson  <rpj at 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  Lorin Hochstein <lmh at xiphos.ca>, Peter Slacik <Peter.Slacik at tatramed.sk>
 -
 -	* 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.
 -
 -1999-10-15  Graham Dumpleton <Graham.Dumpleton at ra.pad.otc.telstra.com.au>
 -
 -	* condvar.c (cond_wait_cleanup): the last waiter will now reset the CV's
 -	wasBroadcast flag
 -
 -Thu Sep 16 1999  Ross Johnson  <rpj at 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.
 -
 -1999-08-10  Aurelio Medina  <aureliom at crt.com>
 -
 -	* 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.
 -
 -1999-08-08 Milan Gardian <mg at tatramed.sk>
 -
 -	* mutex.c (pthread_mutex_destroy): Free mutex memory.
 -
 -1999-08-22  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
 -
 -	* exit.c (pthread_exit): Fix reference to potentially
 -	uninitialised pointer.
 -
 -1999-08-21  Ross Johnson  <rpj at 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 at ixobrychus.canberra.edu.au>
 -
 -	* private.c (ptw32_threadStart): Return exit status from
 -	the application thread startup routine.
 -	- Milan Gardian <mg at tatramed.sk>
 -
 -1999-08-18  John Bossom <john.Bossom at cognos.com>
 -
 -	* exit.c (pthread_exit): Put status into pthread_t->exitStatus
 -	* private.c (ptw32_threadStart): Set pthread->exitStatus
 -	on exit of try{} block.
 -	* 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).
 -
 -Tue Aug 17 20:17:58 CDT 1999  Mumit Khan  <khan at 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 at 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 at 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 at 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  Peter Slacik <Peter.Slacik at tatramed.sk>
 -
 -	* 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.
 -
 -1999-07-09  Lorin Hochstein <lmh at xiphos.ca>, John Bossom <John.Bossom at 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.
 -
 -1999-07-09  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
 -
 -	* 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 at ixobrychus.canberra.edu.au>
 -
 -	* semaphore.h (mode_t): Conditionally typedef it.
 -
 -Fri May 28 13:33:05 1999  Mark E. Armstrong <avail at pacbell.net>
 -
 -	* condvar.c (pthread_cond_broadcast): Fix possible memory fault
 -	
 -Thu May 27 13:08:46 1999  Peter Slacik <Peter.Slacik at tatramed.sk>
 -
 -	* condvar.c (pthread_cond_broadcast): Fix logic bug
 -
 -Thu May 27 13:08:46 1999  Bossom, John <John.Bossom at Cognos.COM>
 -
 -	* condvar.c (pthread_cond_broadcast): optimise sem_post loop
 -
 -Fri May 14 12:13:18 1999  Mike Russo <miker at eai.com>
 -
 -	* attr.c (pthread_attr_setdetachstate): Fix logic bug
 -
 -Sat May  8 09:42:30 1999  Ross Johnson  <rpj at 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 at 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 at 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 at 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 at 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 at ixobrychus.canberra.edu.au>
 -
 -	* Makefile.in (OBJS): Add errno.o.
 -
 -Fri Apr  2 11:08:50 1999  Ross Johnson  <rpj at 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.
 -
 -	* semaphore.c (ptw32_sem_timedwait): Moved to private.c.
 -
 -	* pthread.h (ptw32_sem_t): Change to sem_t. 
 -
 -	* private.c (ptw32_sem_timedwait): Moved from semaphore.c;
 -	set errno on error.
 -
 -	* pthread.h (pthread_t_): Add per-thread errno element.
 -
 -Fri Apr  2 11:08:50 1999  John Bossom <jebossom at cognos.com>
 -
 -	* semaphore.c (ptw32_sem_*): Change to sem_*; these functions
 -	will be exported from the library; set errno on error.
 -
 -	* errno.c (_errno): New file. New function.
 -
 -Fri Mar 26 14:11:45 1999  Tor Lillqvist <tml at iki.fi>
 -
 -	* semaphore.c (ptw32_sem_timedwait): Check for negative
 -	milliseconds.
 -
 -Wed Mar 24 11:32:07 1999  John Bossom <jebossom at cognos.com>
 -
 -	* misc.c (CancelableWait): Initialise exceptionInformation[2].
 -	(pthread_self): Get a real Win32 thread handle for implicit threads.
 -
 -	* cancel.c (pthread_testcancel): Initialise exceptionInformation[2].
 -
 -	* implement.h (SE_INFORMATION): Fix values.
 -
 -	* private.c (ptw32_threadDestroy): Close the thread handle.
 -
 -Fri Mar 19 12:57:27 1999  Ross Johnson  <rpj at swan.canberra.edu.au>
 -
 -	* cancel.c (comments): Update and cleanup.
 -
 -Fri Mar 19 09:12:59 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
 -
 -	* private.c (ptw32_threadStart): status returns PTHREAD_CANCELED.
 -
 -	* pthread.h (PTHREAD_CANCELED): defined.
 -
 -Tue Mar 16  1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
 -
 -	* all: Add GNU LGPL and Copyright and Warranty.
 -	
 -Mon Mar 15 00:20:13 1999  Ross Johnson  <rpj at 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 at 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 at 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 at ixobrychus.canberra.edu.au>
 -
 -	* misc.c (CancelableWait): Undo changes from Mar 8 and 7.
 -
 -Mon Mar  8 11:18:59 1999  Ross Johnson  <rpj at 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 at 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 at ixobrychus.canberra.edu.au>
 -
 -	* implement.h: Undate comments.
 -
 -Sun Feb 21 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
 -
 -	* pthread.h (PTHREAD_MUTEX_INITIALIZER): missing braces around
 -	cs element initialiser.
 -
 -1999-02-21  Ben Elliston  <bje at 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 at 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 at 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 at 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 at 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 at 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 at ixobrychus.canberra.edu.au>
 -
 -	* configure: Various temporary changes.
 -	- Kevin Ruland <Kevin.Ruland at 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 at swan.canberra.edu.au>
 -
 -	* semaphore.c: Comment format changes.
 -
 -Thu Feb  4 10:07:28 1999  Ross Johnson  <rpj at 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 at 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 at 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 at swan.canberra.edu.au>
 -
 -	* implement.h: Add #include <pthread.h>.
 -	Change sem_t to ptw32_sem_t.
 -
 -Tue Feb  2 18:07:43 1999  Kevin Ruland <Kevin.Ruland at 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 at 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 at ixobrychus.canberra.edu.au>
 -
 -	* semaphore.c (sem_wait): Remove second arg to 
 -	pthreadCancelableWait() call.
 -
 -Sat Jan 23 17:36:40 1999  Ross Johnson  <rpj at 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 at 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 at 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 at 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.
 -
 -Tue Jan 19 18:27:42 1999  Scott Lightner <scott at curriculum.com>
 -
 -	* 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().
 -
 -Tue Jan 19 10:27:39 1999  Ross Johnson  <rpj at 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 at 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 at 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 at ixobrychus.canberra.edu.au>
 -
 -	* condvar.c (cond_timedwait): Remove comment.
 -
 -Fri Jan 15 15:41:28 1999  Ross Johnson  <rpj at 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 at 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 at ixobrychus.canberra.edu.au>
 -
 -	* build.bat: Delete old binaries before compiling/linking.
 -
 -Tue Jan 12 09:58:38 1999  Tor Lillqvist <tml at iki.fi>
 -
 -	* dll.c: The Microsoft compiler pragmas probably are more
 -	appropriately protected by _MSC_VER than by _WIN32.
 -
 -	* 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.
 -
 -	* pthread.def: pthread_mutex_destroy was missing from the def file
 -
 -	* 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.
 -
 -Tue Jan 12 09:58:38 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
 -
 -	* condvar.c (pthread_cond_timedwait): Fix function description
 -	comments.
 -
 -	* semaphore.c (sem_post): Correct typo in comment.
 -
 -Mon Jan 11 20:33:19 1999  Ross Johnson  <rpj at 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  Tor Lillqvist <tml at iki.fi>
 -
 -	* condvar.c (pthread_cond_init): Invert logic when testing the
 -	return value from calloc().
 -
 -Sat Jan  9 14:32:08 1999  Ross Johnson  <rpj at 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 at hem2.passagen.se>.
 -
 -Tue Jan  5 16:33:04 1999  Ross Johnson  <rpj at 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 at toilet.to.cygnus.com>
 -
 -	* README: Update info about subscribing to the mailing list.
 -
 -Mon Jan  4 11:23:40 1999  Ross Johnson  <rpj at 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 at 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  John Bossom
 -
 -	* semaphore.c: Initial version.
 -	* semaphore.h: Initial version.
 -
 -Mon Dec 28 09:54:39 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
 -
 -	* pthread.h (pthread_attr_t_): Change to *pthread_attr_t.
 -
 -Mon Dec 28 09:54:39 1998  John Bossom, Ben Elliston
 -
 -	* attr.c (pthread_attr_setstacksize): Merge with John's version.
 -	(pthread_attr_getstacksize): Merge with John's version.
 -	(pthread_attr_setstackaddr): Merge with John's version.
 -	(pthread_attr_getstackaddr): Merge with John's version.
 -	(pthread_attr_init): Merge with John's version.
 -	(pthread_attr_destroy): Merge with John's version.
 -	(pthread_attr_getdetachstate): Merge with John's version.
 -	(pthread_attr_setdetachstate): Merge with John's version.
 -	(is_attr): attr is now **attr (was *attr), so add extra NULL pointer
 -	test.
 -
 -Mon Dec 28 09:54:39 1998  Ross Johnson
 -
 -	* 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 at 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 at 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  John Bossom
 -
 -	* cancel.c (pthread_setcancelstate): Replaced.
 -	(pthread_setcanceltype): Replaced.
 -	(pthread_testcancel): Replaced.
 -	(pthread_cancel): Replaced.
 -	
 -	* exit.c (pthread_exit): Replaced.
 -
 -	* misc.c (pthread_self): Replaced.
 -	(pthread_equal): Replaced.
 -
 -	* sync.c (pthread_detach): Replaced.
 -	(pthread_join): Replaced.
 -
 -	* create.c (pthread_create): Replaced.
 -
 -	* private.c (ptw32_processInitialize): New.
 -	(ptw32_processTerminate): New.
 -	(ptw32_threadStart): New.
 - 	(ptw32_threadDestroy): New.
 -	(ptw32_cleanupStack): New.
 -	(ptw32_tkAssocCreate): New.
 -	(ptw32_tkAssocDestroy): New.
 -	(ptw32_callUserDestroyRoutines): New.
 -
 -	* implement.h: Added non-API structures and declarations.
 -
 -	* dll.c (PthreadsEntryPoint): Cast return value of GetProcAddress
 -	to resolve compile warning from MSVC.
 -
 -	* dll.c (DLLmain): Replaced.
 -	* 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 at 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 at 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 at ise.canberra.edu.au>
 -
 -	* README: Correct cygwin32 compatibility statement.
 -
 -Sun Nov 15 21:24:06 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au>
 -
 -	* cleanup.c (ptw32_destructor_run_all): Declare missing void * arg.
 -	Fixup CVS merge conflicts.
 -
 -1998-10-30  Ben Elliston  <bje at 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 at swan.canberra.edu.au>
 -
 -	* cleanup.c (ptw32_handler_push): Fixed bug appending new
 -	handler to list reported by Peter Slacik
 -	<Peter.Slacik at leibinger.freinet.de>.
 -	(new_thread): Rename poorly named local variable to
 -	"new_handler".
 -
 -Sat Oct 24 18:34:59 1998  Ross Johnson  <rpj at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at ixobrychus.canberra.edu.au>
 -
 -	* pthread.def: New file for building the DLL.
 -
 -1998-10-05  Ben Elliston  <bje at 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 at 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 at 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 at cygnus.com>
 -
 -	* COPYING: Remove.
 -
 -	* COPYING.LIB: Add. This library is under the LGPL.
 -
 -1998-09-13  Ben Elliston  <bje at 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 at cygnus.com>
 -
 -	* windows.h: No longer needed; remove.
 -
 -	* windows.c: Likewise.
 -
 -Sat Sep 12 20:09:24 1998  Ross Johnson  <rpj at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at cygnus.com>
 -
 -	* fork.c (fork): Autoconfiscate.
 -
 -Sat Jul 25 00:00:13 1998  Ross Johnson  <rpj at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at ixobrychus.canberra.edu.au>
 -
 -	* implement.h: Preliminary implementation specific defines.
 -
 -	* create.c (pthread_create): Preliminary implementation.
 -
 -1998-07-11  Ben Elliston  <bje at 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 at 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 at cygnus.com>
 -
 -	* create.c (pthread_create): A dummy stub right now.
 -
 -	* pthread.h (pthread_create): Add function prototype.
 +2005-03-14  Ross Johnson  <ross at callisto.canberra.edu.au> + +	* pthread_once.c (pthread_once): Downgrade interlocked operations to simple +	memory operations where these are protected by the critical section; edit +	comments. + +2005-03-13  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_once.c (pthread_once): Completely redesigned; a change was +	required to the ABI (pthread_once_t_), and resulting in a version +	compatibility index increment. + +	NOTES: +	The design (based on pseudo code contributed by Gottlob Frege) avoids +	creating a kernel object if there is no contention. See URL for details:- +	http://sources.redhat.com/ml/pthreads-win32/2005/msg00029.html +	This uses late initialisation similar to the technique already used for +	pthreads-win32 mutexes and semaphores (from Alexander Terekhov). + +	The subsequent cancelation cleanup additions (by rpj) could not be implemented +	without sacrificing some of the efficiency in Gottlob's design. In particular, +	although each once_control uses it's own event to block on, a global CS is +	required to manage it - since the event must be either re-usable or +	re-creatable under cancelation. This is not needed in the non-cancelable +	design because it is able to mark the event as closed (forever). + +	When uncontested, a CS operation is equivalent to an Interlocked operation +	in speed. So, in the final design with cancelability, an uncontested +	once_control operation involves a minimum of five interlocked operations +	(including the LeaveCS operation). +	 +	ALTERNATIVES: +	An alternative design from Alexander Terekhov proposed using a named mutex, +	as sketched below:- + +	  if (!once_control) { // May be in TLS +	    named_mutex::guard guard(&once_control2); +	      if (!once_control2) { +	         <init> +	         once_control2 = true; +	      } +	    once_control = true; +	  } +	 +	A more detailed description of this can be found here:- +	http://groups.yahoo.com/group/boost/message/15442 + +	[Although the definition of a suitable PTHREAD_ONCE_INIT precludes use of the +	TLS located flag, this is not critical.] +	 +	There are three primary concerns though:- +	1) The [named] mutex is 'created' even in the uncontended case. +	2) A system wide unique name must be generated. +	3) Win32 mutexes are VERY slow even in the uncontended 	case. An uncontested +	Win32 mutex lock operation can be 50 (or more) times slower than an +	uncontested EnterCS operation. + +	Ultimately, the named mutex trick is making use of the global locks maintained +	by the kernel. + +	* pthread.h (pthread_once_t_): One flag and an event HANDLE added. +	(PTHREAD_ONCE_INIT): Additional values included. + +2005-03-08  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_once.c (pthread_once): Redesigned to elliminate potential +	starvation problem. +	- reported by Gottlob Frege  <gottlobfrege at gmail.com> + +	* ptw32_threadDestroy.c (ptw32_threadDestroy): Implicit threads were +	not closing their Win32 thread duplicate handle. +	- reported by Dmitrii Semii <bogolt at gmail.com> + +2005-01-25  Ralf Kubis  <RKubis at mc.com> + +	* Attempted acquisition of recursive mutex was causing waiting +	threads to not be woken when the mutex is released. + +	* GNUmakefile (GCE): Generate correct version resource comments. + +2005-01-01  Konstantin Voronkov  <beowinkle at yahoo.com> + +	* pthread_mutex_lock.c (pthread_mutex_lock): The new atomic exchange +	mutex algorithm is known to allow a thread to steal the lock off +	FIFO waiting threads. The next waiting FIFO thread gets a spurious +	wake-up and must attempt to re-acquire the lock. The woken thread +	was setting itself as the mutex's owner before the re-acquisition. + +2004-11-22  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): Undo change +	from 2004-11-02. +	* Makefile (DLL_VER): Added for DLL naming suffix - see README. +	* GNUmakefile (DLL_VER): Likewise. +	* Wmakefile (DLL_VER): Likewise. +	* Bmakefile (DLL_VER): Likewise. +	* pthread.dsw (version.rc): Added to MSVS workspace. + +2004-11-20  Boudewijn Dekker  <b.dekker at ellipsis.nl> + +	* pthread_getspecific.c (pthread_getspecific): Check for +	invalid (NULL) key argument. + +2004-11-19  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* config.h (PTW32_THREAD_ID_REUSE_INCREMENT): Added to allow +	building the library for either unique thread IDs like Solaris +	or non-unique thread IDs like Linux; allows application developers +	to override the library's default insensitivity to some apps +	that may not be strictly POSIX compliant. +	* version.rc: New resource module to encode version information +	within the DLL. +	* pthread.h: Added PTW32_VERSION* defines and grouped sections +	required by resource compiler together; bulk of file is skipped +	if RC_INVOKED. Defined some error numbers and other names for +	Borland compiler. + +2004-11-02  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): Lock CV mutex at +	start of cleanup handler rather than at the end. +	* implement.h (PTW32_THREAD_REUSE_EMPTY): Renamed from *_BOTTOM. +	(ptw32_threadReuseBottom): New global variable. +	* global.c (ptw32_threadReuseBottom): Declare new variable. +	* ptw32_reuse.c (ptw32_reuse): Change reuse LIFO stack to LILO queue +	to more evenly distribute use of reusable thread IDs; use renamed +	PTW32_THREAD_REUSE_EMPTY. +	* ptw32_processTerminate.c (ptw2_processTerminate): Use renamed +	PTW32_THREAD_REUSE_EMPTY. + +2004-10-31  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* implement.h (PThreadState): Add new state value +	'PThreadStateCancelPending'. +	* pthread_testcancel.c (pthread_testcancel): Use new thread +	'PThreadStateCancelPending' state as short cut to avoid entering +	kernel space via WaitForSingleObject() call. This was obviated +	by user space sema acquisition in sem_wait() and sem_timedwait(), +	which are also cancelation points. A call to pthread_testcancel() +	was required, which introduced a kernel call, effectively nullifying +	any gains made by the user space sem acquisition checks. +	* pthread_cancel.c (pthread_cancel): Set new thread +	'PThreadStateCancelPending' state. + +2004-10-29  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* implement.h (pthread_t): Renamed to ptw32_thread_t; struct contains +	all thread state. +	* pthread.h (ptw32_handle_t): New general purpose struct to serve +	as a handle for various reusable object IDs - currently only used +	by pthread_t; contains a pointer to ptw32_thread_t (thread state) +	and a general purpose uint for use as a reuse counter or flags etc. +	(pthread_t): typedef'ed to ptw32_handle_t; the uint is the reuse +	counter that allows the library to maintain unique POSIX thread IDs. +	When the pthread struct reuse stack was introduced, threads would +	often acquire an identical ID to a previously destroyed thread. The +	same was true for the pre-reuse stack library, by virtue of pthread_t +	being the address of the thread struct. The new pthread_t retains +	the reuse stack but provides virtually unique thread IDs. +	* sem_wait.c (ptw32_sem_wait_cleanup): New routine used for +	cancelation cleanup. +	* sem_timedwait.c (ptw32_sem_timedwait_cleanup): Likewise. + +2004-10-22  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* sem_init.c (sem_init): Introduce a 'lock' element in order to +	replace the interlocked operations with conventional serialisation. +	This is needed in order to be able to atomically modify the sema +	value and perform Win32 sema release operations. Win32 semaphores are +	used instead of events in order to support efficient multiple posting. +	If the whole modify/release isn't atomic, a race between +	sem_timedwait() and sem_post() could result in a release when there is +	no waiting semaphore, which would cause too many threads to proceed. +	* sem_wait.c (sem_wait): Use new 'lock'element. +	* sem_timedwait.c (sem_timedwait): Likewise. +	* sem_trywait.c (sem_trywait): Likewise. +	* sem_post.c (sem_post): Likewise. +	* sem_post_multiple.c (sem_post_multiple): Likewise. +	* sem_getvalue.c (sem_getvalue): Likewise. +	* ptw32_semwait.c (ptw32_semwait): Likewise. +	* sem_destroy.c (sem_destroy): Likewise; also tightened the conditions +	for semaphore destruction; in particular, a semaphore will not be +	destroyed if it has waiters. +	* sem_timedwait.c (sem_timedwait): Added cancel cleanup handler to +	restore sema value when cancelled. +	* sem_wait.c (sem_wait): Likewise. + +2004-10-21  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_mutex_unlock.c (pthread_mutex_unlock): Must use PulseEvent() +	rather than SetEvent() to reset the event if there are no waiters. + +2004-10-19  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* sem_init.c (sem_init): New semaphore model based on the same idea +	as mutexes, i.e. user space interlocked check to avoid  +	unnecessarily entering kernel space. Wraps the Win32 semaphore and +	keeps it's own counter. Although the motivation to do this has existed +	for a long time, credit goes to Alexander Terekhov for providing +	the logic. I have deviated slightly from AT's logic to add the waiters +	count, which has made the code more complicated by adding cancelation +	cleanup. This also appears to have broken the VCE (C++ EH) version of +	the library (the same problem as previously reported - see BUGS #2), +	only apparently not fixable using the usual workaround, nor by turning +	all optimisation off. The GCE version works fine, so it is presumed to +	be a bug in MSVC++ 6.0. The cancelation exception is thrown and caught +	correctly, but the cleanup class destructor is never called. The failing +	test is tests\semaphore4.c. +	* sem_wait.c (sem_wait): Implemented user space check model. +	* sem_post.c (sem_post): Likewise. +	* sem_trywait.c (sem_trywait): Likewise. +	* sem_timedwait.c (sem_timedwait): Likewise. +	* sem_post_multiple.c (sem_post_multiple): Likewise. +	* sem_getvalue.c (sem_getvalue): Likewise. +	* ptw32_semwait.c (ptw32_semwait): Likewise. +	* implement.h (sem_t_): Add counter element. + +2004-10-15  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* implement.h (pthread_mutex_t_): Use an event in place of +	the POSIX semaphore. +	* pthread_mutex_init.c: Create the event; remove semaphore init. +	* pthread_mutex_destroy.c: Delete the event. +	* pthread_mutex_lock.c: Replace the semaphore wait with the event wait. +	* pthread_mutex_trylock.c: Likewise. +	* pthread_mutex_timedlock.c: Likewise. +	* pthread_mutex_unlock.c: Set the event. +	 +2004-10-14  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_mutex_lock.c (pthread_mutex_lock): New algorithm using +	Terekhov's xchg based variation of Drepper's cmpxchg model. +	Theoretically, xchg uses fewer clock cycles than cmpxchg (using IA-32 +	as a reference), however, in my opinion bus locking dominates the +	equation on smp systems, so the model with the least number of bus +	lock operations in the execution path should win, which is Terekhov's +	variant. On IA-32 uni-processor systems, it's faster to use the +	CMPXCHG instruction without locking the bus than to use the XCHG +	instruction, which always locks the bus. This makes the two variants +	equal for the non-contended lock (fast lane) execution path on up +	IA-32. Testing shows that the xchg variant is faster on up IA-32 as +	well if the test forces higher lock contention frequency, even though +	kernel calls should be dominating the times (on up IA-32, both +	variants used CMPXCHG instructions and neither locked the bus). +	* pthread_mutex_timedlock.c pthread_mutex_timedlock(): Similarly. +	* pthread_mutex_trylock.c (pthread_mutex_trylock): Similarly. +	* pthread_mutex_unlock.c (pthread_mutex_unlock): Similarly. +	* ptw32_InterlockedCompareExchange.c (ptw32_InterlockExchange): New +	function. +	(PTW32_INTERLOCKED_EXCHANGE): Sets up macro to use inlined +	ptw32_InterlockedExchange. +	* implement.h (PTW32_INTERLOCKED_EXCHANGE): Set default to +	InterlockedExchange(). +	* Makefile: Building using /Ob2 so that asm sections within inline +	functions are inlined. + +2004-10-08  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_mutex_destroy.c (pthread_mutex_destroy): Critical Section +	element is no longer required. +	* pthread_mutex_init.c (pthread_mutex_init): Likewise. +	* pthread_mutex_lock.c (pthread_mutex_lock): New algorithm following +	Drepper's paper at http://people.redhat.com/drepper/futex.pdf, but +	using the existing semaphore in place of the futex described in the +	paper. Idea suggested by Alexander Terekhov - see: +	http://sources.redhat.com/ml/pthreads-win32/2003/msg00108.html +	* pthread_mutex_timedlock.c pthread_mutex_timedlock(): Similarly. +	* pthread_mutex_trylock.c (pthread_mutex_trylock): Similarly. +	* pthread_mutex_unlock.c (pthread_mutex_unlock): Similarly. +	* pthread_barrier_wait.c (pthread_barrier_wait): Use inlined version +	of InterlockedCompareExchange() if possible - determined at +	build-time. +	* pthread_spin_destroy.c pthread_spin_destroy(): Likewise. +	* pthread_spin_lock.c pthread_spin_lock():Likewise. +	* pthread_spin_trylock.c (pthread_spin_trylock):Likewise. +	* pthread_spin_unlock.c (pthread_spin_unlock):Likewise. +	* ptw32_InterlockedCompareExchange.c: Sets up macro for inlined use. +	* implement.h (pthread_mutex_t_): Remove Critical Section element. +	(PTW32_INTERLOCKED_COMPARE_EXCHANGE): Set to default non-inlined +	version of InterlockedCompareExchange(). +	* private.c: Include ptw32_InterlockedCompareExchange.c first for +	inlining. +	* GNUmakefile: Add commandline option to use inlined +	InterlockedCompareExchange(). +	* Makefile: Likewise. + +2004-09-27  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_mutex_lock.c (pthread_mutex_lock): Separate +	PTHREAD_MUTEX_NORMAL logic since we do not need to keep or check some +	state required by other mutex types; do not check mutex pointer arg +	for validity - leave this to the system since we are only checking +	for NULL pointers. This should improve speed of NORMAL mutexes and +	marginally improve speed of other type. +	* pthread_mutex_trylock.c (pthread_mutex_trylock): Likewise. +	* pthread_mutex_unlock.c (pthread_mutex_unlock): Likewise; also avoid +	entering the critical section for the no-waiters case, with approx. +	30% reduction in lock/unlock overhead for this case. +	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise; also +	no longer keeps mutex if post-timeout second attempt succeeds - this +	will assist applications that wish to impose strict lock deadlines, +	rather than simply to escape from frozen locks. + +2004-09-09  Tristan Savatier  <tristan at mpegtv.com> +	* pthread.h (struct pthread_once_t_): Qualify the 'done' element +	as 'volatile'. +	* pthread_once.c: Concerned about possible race condition, +	specifically on MPU systems re concurrent access to multibyte types. +	[Maintainer's note: the race condition is harmless on SPU systems +	and only a problem on MPU systems if concurrent access results in an +	exception (presumably generated by a hardware interrupt). There are +	other instances of similar harmless race conditions that have not +	been identified as issues.] + +2004-09-09  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread.h: Declare additional types as volatile. + +2004-08-27  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_barrier_wait.c (pthread_barrier_wait): Remove excessive code +	by substituting the internal non-cancelable version of sem_wait +	(ptw32_semwait). + +2004-08-25  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_join.c (pthread_join): Rewrite and re-order the conditional +	tests in an attempt to improve efficiency and remove a race +	condition. + +2004-08-23  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* create.c (pthread_create): Don't create a thread if the thread +	id pointer location (first arg) is inaccessible. A memory +	protection fault will result if the thread id arg isn't an accessible +	location. This is consistent with GNU/Linux but different to +	Solaris or MKS (and possibly others), which accept NULL as meaning +	'don't return the created thread's ID'. Applications that run +	using pthreads-win32 will run on all other POSIX threads +	implementations, at least w.r.t. this feature. + +	It was decided not to copy the Solaris et al behaviour because, +	although it would have simplified some application porting (but only +	from Solaris to Windows), the feature is not technically necessary, +	and the alternative segfault behaviour helps avoid buggy application +	code. + +2004-07-01  Anuj Goyal  <anuj.goyal at gmail.com> + +	* builddmc.bat: New; Windows bat file to build the library. +	* config.h (__DMC__): Support for Digital Mars compiler. +	* create.c (__DMC__): Likewise. +	* pthread_exit.c (__DMC__): Likewise. +	* pthread_join.c (__DMC__): Likewise. +	* ptw32_threadDestroy.c (__DMC__): Likewise. +	* ptw32_threadStart.c (__DMC__): Likewise. +	* ptw32_throw.c (__DMC__): Likewise. + +2004-06-29  Anuj Goyal  <anuj.goyal at gmail.com> + +	* pthread.h (__DMC__): Initial support for Digital Mars compiler. + +2004-06-29  Will Bryant  <will.bryant at ecosm.com> + +	* README.Borland: New; description of Borland changes. +	* Bmakefile: New makefile for the Borland make utility. +	* ptw32_InterlockedCompareExchange.c: +	Add Borland compatible asm code. + +2004-06-26  Jason Bard  <BardJA at Npt.NUWC.Navy.Mil> + +	* pthread.h (HAVE_STRUCT_TIMESPEC): If undefined, define it +	to avoid timespec struct redefined errors elsewhere in an +	application. + +2004-06-21  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread.h (PTHREAD_RECURSIVE_MUTEX_INITIALIZER): Mutex +	initialiser added for compatibility with Linux threads and +	others; currently not included in SUSV3. +	* pthread.h (PTHREAD_ERRORCHECK_MUTEX_INITIALIZER): Likewise. +	* pthread.h (PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP): Likewise. +	* pthread.h (PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP): Likewise. + +	* ptw32_mutex_check_need_init.c (ptw32_mutex_check_need_init):  +	Add new initialisers. + +	* pthread_mutex_lock.c (pthread_mutex_lock): Check for new +	initialisers. +	* pthread_mutex_trylock.c (pthread_mutex_trylock): Likewise. +	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise. +	* pthread_mutex_unlock.c (pthread_mutex_unlock): Likewise. +	* pthread_mutex_destroy.c (pthread_mutex_destroy): Likewise. + +2004-05-20  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* README.NONPORTABLE: Document pthread_win32_test_features_np(). +	* FAQ: Update various answers. + +2004-05-19  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* Makefile: Don't define _WIN32_WINNT on compiler command line. +	* GNUmakefile: Likewise. + +2004-05-16  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_cancel.c (pthread_cancel): Adapted to use auto-detected +	QueueUserAPCEx features at run-time. +	(ptw32_RegisterCancelation): Drop in replacement for QueueUserAPCEx() +	if it can't be used. Provides older style non-preemptive async +	cancelation. +	* pthread_win32_attach_detach_np.c (pthread_win32_attach_np): +	Auto-detect quserex.dll and the availability of alertdrv.sys; +	initialise and close on process attach/detach. +	* global.c (ptw32_register_cancelation): Pointer to either +	QueueUserAPCEx() or ptw32_RegisterCancelation() depending on +	availability. QueueUserAPCEx makes pre-emptive async cancelation +	possible. +	* implement.h: Add definitions and prototypes related to QueueUserAPC. + +2004-05-16  Panagiotis E. Hadjidoukas <peh at hpclab.ceid.upatras.gr> + +	* QueueUserAPCEx (separate contributed package): Provides preemptive +	APC feature. +	* pthread_cancel.c (pthread_cancel): Initial integration of +	QueueUserAPCEx into pthreads-win32 to provide true pre-emptive +	async cancelation of threads, including blocked threads. + +2004-05-06  Makoto Kato  <raven at oldskool.jp> + +	* pthread.h (DWORD_PTR): Define typedef for older MSVC. +	* pthread_cancel.c (AMD64): Add architecture specific Context register. +	* ptw32_getprocessors.c: Use correct types (DWORD_PTR) for mask +	variables. + +2004-04-06  P. van Bruggen  <pietvb at newbridges.nl> + +	* ptw32_threadDestroy.c: Destroy threadLock mutex to +	close a memory leak. + +2004-02-13  Gustav Hallberg  <gustav at virtutech.com> + +	* pthread_equal.c: Remove redundant equality logic. + +2003-12-10  Philippe Di Cristo  <philipped at voicebox.com> + +	* sem_timedwait.c (sem_timedwait): Fix timeout calculations. + +2003-10-20  Alexander Terekhov  <TEREKHOV at de.ibm.com> + +	* pthread_mutex_timedlock.c (ptw32_semwait): Move to individual module. +	* ptw32_semwait.c: New module. +	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): Replace cancelable +	sem_wait() call with non-cancelable ptw32_semwait() call. +	* pthread.c (private.c): Re-order for inlining. GNU C warned that +	function ptw32_semwait() was defined 'inline' after it was called. +	* pthread_cond_signal.c (ptw32_cond_unblock): Likewise. +	* pthread_delay_np.c: Disable Watcom warning with comment. +	* *.c (process.h): Remove include from .c files. This is conditionally +	included by the common project include files. + +2003-10-20  James Ewing  <james.ewing at sveasoft.com> + +	* ptw32_getprocessors.c: Some Win32 environments don't have +	GetProcessAffinityMask(), so always return CPU count = 1 for them. +	* config.h (NEED_PROCESSOR_AFFINITY_MASK): Define for WinCE. +	 +2003-10-15  Ross Johnson  <ross at callisto.canberra.edu.au> + +	* Re-indented all .c files using default GNU style to remove assorted +	editor ugliness (used GNU indent utility in default style). + +2003-10-15  Alex Blanco  <Alex.Blanco at motorola.com> + +	* sem_init.c (sem_init): Would call CreateSemaphore even if the sema +	struct calloc failed; was not freeing calloced memory if either +	CreateSemaphore or CreateEvent failed. + +2003-10-14  Ross Johnson  <ross at callisto.canberra.edu.au> + +	* pthread.h: Add Watcom compiler compatibility. Esssentially just add +	the cdecl attribute to all exposed function prototypes so that Watcom +	generates function call code compatible with non-Watcom built libraries. +	By default, Watcom uses registers to pass function args if possible rather +	than pushing to stack. +	* semaphore.h: Likewise. +	* sched.h: Likewise. +	* pthread_cond_wait.c (ptw32_cond_wait_cleanup): Define with cdecl attribute +	for Watcom compatibility. This routine is called via pthread_cleanup_push so +	it had to match function arg definition. +	* Wmakefile: New makefile for Watcom builds. + +2003-09-14  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_setschedparam.c (pthread_setschedparam): Attempt to map +	all priority levels between max and min (as returned by +	sched_get_priority_min/max) to reasonable Win32 priority levels - i.e. +	levels between THREAD_PRIORITY_LOWEST/IDLE to THREAD_PRIORITY_LOWEST and +	between THREAD_PRIORITY_HIGHEST/TIME_CRITICAL to THREAD_PRIORITY_HIGHEST +	while others remain unchanged; record specified thread priority level +	for return by pthread_getschedparam. + +	Note that, previously, specified levels not matching Win32 priority levels +	would silently leave the current thread priority unaltered. + +	* pthread_getschedparam.c (pthread_getschedparam): Return the priority +	level specified by the latest pthread_setschedparam or pthread_create rather +	than the actual running thread priority as returned by GetThreadPriority - as +	required by POSIX. I.e. temporary or adjusted actual priority levels are not +	returned by this routine. + +	* pthread_create.c (pthread_create): For priority levels specified via +	pthread attributes, attempt to map all priority levels between max and +	min (as returned by sched_get_priority_min/max) to reasonable Win32 +	priority levels; record priority level given via attributes, or +	inherited from parent thread, for later return by pthread_getschedparam. + +	* ptw32_new.c (ptw32_new): Initialise pthread_t_ sched_priority element. + +	* pthread_self.c (pthread_self): Set newly created implicit POSIX thread +	sched_priority to Win32 thread's current actual priority. Temporarily +	altered priorities can't be avoided in this case. + +	* implement.h (struct pthread_t_): Add new sched_priority element. + +2003-09-12  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* sched_get_priority_min.c (sched_get_priority_min): On error should return -1 +	with errno set. +	* sched_get_priority_max.c (sched_get_priority_max): Likewise. + +2003-09-03  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* w32_cancelableWait.c (ptw32_cancelable_wait): Allow cancelation +	of implicit POSIX threads as well. + +2003-09-02  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_win32_attach_detach_np.c (pthread_win32_thread_detach_np): +	Add comment. + +	* pthread_exit.c (pthread_exit): Fix to recycle the POSIX thread handle in +	addition to calling user TSD destructors. Move the implicit POSIX thread exit +	handling to ptw32_throw to centralise the logic. + +	* ptw32_throw.c (ptw32_throw): Implicit POSIX threads have no point +	to jump or throw to, so cleanup and exit the thread here in this case. For +	processes using the C runtime, the exit code will be set to the POSIX +	reason for the throw (i.e. PTHREAD_CANCEL or the value given to pthread_exit). +	Note that pthread_exit() already had similar logic, which has been moved to +	here. + +	* ptw32_threadDestroy.c (ptw32_threadDestroy): Don't close the Win32 handle +	of implicit POSIX threads - expect this to be done by Win32? + +2003-09-01  Ross Johnson  <rpj at callisto.canberra.edu.au> + +	* pthread_self.c (pthread_self): The newly aquired pthread_t must be +	assigned to the reuse stack, not freed, if the routine fails somehow. + +2003-08-13  Ross Johnson  <rpj at ise.canberra.edu.au> + +	* pthread_getschedparam.c (pthread_getschedparam): An invalid thread ID +	parameter was returning an incorrect error value; now uses a more exhaustive +	check for validity. + +	* pthread_setschedparam.c (pthread_setschedparam): Likewise. + +	* pthread_join.c (pthread_join): Now uses a more exhaustive +	check for validity. + +	* pthread_detach.c (pthread_detach): Likewise. + +	* pthread_cancel.c (pthread_cancel): Likewise. + +	* ptw32_threadDestroy.c (ptw32_threadDestroy): pthread_t structs are +	never freed - push them onto a stack for reuse. + +	* ptw32_new.c (ptw32_new): Check for reusable pthread_t before dynamically +	allocating new memory for the struct. + +	* pthread_kill.c (pthread_kill): New file; new routine; takes only a zero +	signal arg so that applications can check the thread arg for validity; checks +	that the underlying Win32 thread HANDLE is valid. + +	* pthread.h (pthread_kill): Add prototype. + +	* ptw32_reuse.c (ptw32_threadReusePop): New file; new routine; pop a +	pthread_t off the reuse stack. pthread_t_ structs that have been destroyed, i.e. +	have exited detached or have been joined, are cleaned up and put onto a reuse +	stack. Consequently, thread IDs are no longer freed once calloced. The library +	will attempt to get a struct off this stack before asking the system to alloc +	new memory when creating threads. The stack is guarded by a global mutex. +	(ptw32_threadReusePush): New routine; push a pthread_t onto the reuse stack. + +	* implement.h (ptw32_threadReusePush): Add new prototype. +	(ptw32_threadReusePop): Likewise. +	(pthread_t): Add new element. + +	* ptw32_processTerminate.c (ptw32_processTerminate): Delete the thread +	reuse lock; free all thread ID structs on the thread reuse stack. + +	* ptw32_processInitialize.c (ptw32_processInitialize): Initialise the +	thread reuse lock. + +2003-07-19  Ross Johnson  <rpj at ise.canberra.edu.au> + +	* GNUmakefile: modified to work under MsysDTK environment. +	* pthread_spin_lock.c (pthread_spin_lock): Check for NULL arg. +	* pthread_spin_unlock.c (pthread_spin_unlock): Likewise. +	* pthread_spin_trylock.c (pthread_spin_trylock): Likewise; +	fix incorrect pointer value if lock is dynamically initialised by +	this function. +	* sem_init.c (sem_init): Initialise sem_t value to quell compiler warning. +	* sem_destroy.c (sem_destroy): Likewise. +	* ptw32_threadStart.c (non-MSVC code sections): Include <exception> rather +	than old-style <new.h>; fix all std:: namespace entities such as +	std::terminate_handler instances and associated methods. +	* ptw32_callUserDestroyRoutines.c (non-MSVC code sections): Likewise. + +2003-06-24  Piet van Bruggen  <pietvb at newbridges.nl> + +	* pthread_spin_destroy.c (pthread_spin_destroy): Was not freeing the +	spinlock struct. + +2003-06-22  Nicolas Barry  <boozai at yahoo.com> + +	* pthread_mutex_destroy.c (pthread_mutex_destroy): When called +	with a recursive mutex that was locked by the current thread, the +	function was failing with a success return code. + +2003-05-15  Steven Reddie  <Steven.Reddie at ca.com> + +	* pthread_win32_attach_detach_np.c (pthread_win32_process_detach_np): +	NULLify ptw32_selfThreadKey after the thread is destroyed, otherwise +	destructors calling pthreads routines might resurrect it again, creating +	memory leaks. Call the underlying Win32 Tls routine directly rather than +	pthread_setspecific(). +	(pthread_win32_thread_detach_np): Likewise. + +2003-05-14  Viv  <vcotirlea at hotmail.com> + +	* pthread.dsp: Change /MT compile flag to /MD. + +2003-03-04  Alexander Terekhov  <TEREKHOV at de.ibm.com> + +	* pthread_mutex_timedlock.c (pthread_mutex_timedlock): Fix failure to +	set ownership of mutex on second grab after abstime timeout. +	- bug reported by Robert Strycek <strycek at posam.sk> + +2002-12-17  Thomas Pfaff  <tpfaff at gmx.net> + +	* pthread_mutex_lock.c (ptw32_semwait): New static routine to provide +	a non-cancelable sem_wait() function. This is consistent with the +	way that pthread_mutex_timedlock.c does it. +	(pthread_mutex_lock): Use ptw32_semwait() instead of sem_wait(). + +2002-12-11  Thomas Pfaff  <tpfaff at gmx.net> + +	* pthread_mutex_trylock.c: Should return EBUSY rather than EDEADLK. +	* pthread_mutex_destroy.c: Remove redundant ownership test (the +	trylock call does this for us); do not destroy a recursively locked +	mutex. + +2002-09-20  Michael Johnson  <michaelj at maine.rr.com> + +	* pthread_cond_destroy.c (pthread_cond_destroy):  +	When two different threads exist, and one is attempting to +	destroy a condition variable while the other is attempting to +	initialize a condition variable that was created with +	PTHREAD_COND_INITIALIZER, a deadlock can occur. Shrink +	the ptw32_cond_list_lock critical section to fix it. + +2002-07-31  Ross Johnson  <rpj at special.ise.canberra.edu.au> + +	* ptw32_threadStart.c (ptw32_threadStart): Thread cancelLock +	destruction moved to ptw32_threadDestroy(). + +	* ptw32_threadDestroy.c (ptw32_threadDestroy):  Destroy +	the thread's cancelLock. Moved here from ptw32_threadStart.c +	to cleanup implicit threads as well. + +2002-07-30  Alexander Terekhov  <TEREKHOV at de.ibm.com> + +	* pthread_cond_wait.c (ptw32_cond_wait_cleanup):  +	Remove code designed to avoid/prevent spurious wakeup +	problems. It is believed that the sem_timedwait() call +	is consuming a CV signal that it shouldn't and this is +	breaking the avoidance logic. + +2002-07-30  Ross Johnson  <rpj at ise.canberra.edu.au> + +	* sem_timedwait.c (sem_timedwait): Tighten checks for +	unreasonable abstime values - that would result in +	unexpected timeout values. + +	* w32_CancelableWait.c (ptw32_cancelable_wait): +	Tighten up return value checking and add comments. + + +2002-06-08  Ross Johnson  <rpj at special.ise.canberra.edu.au> + +	* sem_getvalue.c (sem_getvalue): Now returns a value for the +	NEED_SEM version (i.e. earlier versions of WinCE). + + +2002-06-04  Rob Fanner  <rfanner at stonethree.com> + +	* sem_getvalue.c (sem_getvalue): The Johnson M. Hart +	approach didn't work - we are forced to take an +	intrusive approach. We try to decrement the sema +	and then immediately release it again to get the +	value. There is a small probability that this may +	block other threads, but only momentarily. + +2002-06-03  Ross Johnson  <rpj at ise.canberra.edu.au> + +	* sem_init.c (sem_init): Initialise Win32 semaphores +	to _POSIX_SEM_VALUE_MAX (which this implementation +	defines in pthread.h) so that sem_getvalue() can use +	the trick described in the comments in sem_getvalue(). +	* pthread.h (_POSIX_SEM_VALUE_MAX): Defined. +	(_POSIX_SEM_NSEMS_MAX): Defined - not used but may be +	useful for source code portability. + +2002-06-03  Rob Fanner  <rfanner at stonethree.com> + +	* sem_getvalue.c (sem_getvalue): Did not work on NT. +	Use approach suggested by Johnson M. Hart in his book +	"Win32 System Programming". + +2002-02-28  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* errno.c: Compiler directive was incorrectly including code. +	* pthread.h: Conditionally added some #defines from config.h +	needed when not building the library. e.g. NEED_ERRNO, NEED_SEM. +	(PTW32_DLLPORT): Now only defined if _DLL defined. +	(_errno): Compiler directive was incorrectly including prototype. +	* sched.h: Conditionally added some #defines from config.h +	needed when not building the library. +	* semaphore.h: Replace an instance of NEED_SEM that should +	have been NEED_ERRNO. This change currently has nil effect. + +	* GNUmakefile: Correct some recent changes. + +	* Makefile: Add rule to generate pre-processor output. + +2002-02-23  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* pthread_rwlock_timedrdlock.c: New - untested. +	* pthread_rwlock_timedwrlock.c: New - untested. +	 +	* Testsuite passed (except known MSVC++ problems) + +	* pthread_cond_destroy.c: Expand the time change +	critical section to solve deadlock problem. + +	* pthread.c: Add all remaining C modules. +	* pthread.h: Use dllexport/dllimport attributes on functions +	to avoid using pthread.def. +	* sched.h: Likewise. +	* semaphore.h: Likewise. +	* GNUmakefile: Add new targets for single translation +	unit build to maximise inlining potential; generate +	pthread.def automatically. +	* Makefile: Likewise, but no longer uses pthread.def. + +2002-02-20  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* pthread_cond_destroy.c (pthread_cond_destroy): +	Enter the time change critical section earlier. + +2002-02-17  Ross Johnson  <rpj at setup1.ise.canberra.edu.au + +	* Testsuite passed. + +	* pthread_timechange_handler_np.c: New; following +	a suggestion from Alexander Terekhov that CVs should +	be broadcast so that they all re-evaluate their +	condition variables and reset a new timeout if +	required, whenever an application receives a +	WM_TIMECHANGE message. This message indicates that +	the system time has been changed. Therefore, CVs +	waiting for a timeout set as an abs_time will possibly +	not wake up at the expected time. Some applications +	may not be tolerant of this. +	* pthread_cond_init.c: Add CV to linked list. +	* pthread_cond_destroy.c: Remove CV from linked list. +	* global.c (ptw32_cond_list_head): New variable. +	(ptw32_cond_list_tail): New variable. +	(ptw32_cond_list_cs): New critical section. +	* ptw32_processInitialize (ptw32_cond_list_cs): Initialize. +	* ptw32_processTerminate (ptw32_cond_list_cs): Delete. + + +	* Reduce executable size. +	  ----------------------- +	When linking with the static library, only those +	routines actually called, either directly or indirectly +	should be included. + +	[Gcc has the -ffunction-segments option to do this but MSVC +	doesn't have this feature as far as I can determine. Other +	compilers are undetermined as well. - rpj] + +	* spin.c: Split file into function segments. +	* ptw32_spinlock_check_need_init.c: Separated routine from spin.c. +	* pthread_spin_init.c: Likewise. +	* pthread_spin_destroy.c: Likewise. +	* pthread_spin_lock.c: Likewise. +	* pthread_spin_unlock.c: Likewise. +	* pthread_spin_trylock.c: Likewise. + +	* sync.c: Split file into function segments. +	* pthread_detach.c: Separated routine from sync.c. +	* pthread_join.c: Likewise. + +	* tsd.c: Split file into function segments. +	* pthread_key_create.c: Separated routine from tsd.c. +	* pthread_key_delete.c: Likewise. +	* pthread_setspecific.c: Likewise. +	* pthread_getspecific.c: Likewise. + +	* sched.c: Split file into function segments. +	* pthread_attr_setschedpolicy.c: Separated routine from sched.c. +	* pthread_attr_getschedpolicy.c: Likewise. +	* pthread_attr_setschedparam.c: Likewise. +	* pthread_attr_getschedparam.c: Likewise. +	* pthread_attr_setinheritsched.c: Likewise. +	* pthread_attr_getinheritsched.c: Likewise. +	* pthread_setschedparam.c: Likewise. +	* pthread_getschedparam.c: Likewise. +	* sched_get_priority_max.c: Likewise. +	* sched_get_priority_min.c: Likewise. +	* sched_setscheduler.c: Likewise. +	* sched_getscheduler.c: Likewise. +	* sched_yield.c: Likewise. + + +2002-02-16  Ross Johnson  <rpj at setup1.ise.canberra.edu.au + +	Reduce executable size. +	----------------------- +	When linking with the static library, only those +	routines actually called, either directly or indirectly +	should be included. + +	[Gcc has the -ffunction-segments option to do this but MSVC +	doesn't have this feature as far as I can determine. Other +	compilers are undetermined as well. - rpj] + +	* mutex.c: Split file into function segments. +	* pthread_mutexattr_destroy.c: Separated routine from mutex.c +	* pthread_mutexattr_getpshared.c: Likewise. +	* pthread_mutexattr_gettype.c: Likewise. +	* pthread_mutexattr_init.c: Likewise. +	* pthread_mutexattr_setpshared.c: Likewise. +	* pthread_mutexattr_settype.c: Likewise. +	* ptw32_mutex_check_need_init.c: Likewise. +	* pthread_mutex_destroy.c: Likewise. +	* pthread_mutex_init.c: Likewise. +	* pthread_mutex_lock.c: Likewise. +	* pthread_mutex_timedlock.c: Likewise. +	* pthread_mutex_trylock.c: Likewise. +	* pthread_mutex_unlock.c: Likewise. +	 +	* private.c: Split file into function segments. +	* ptw32_InterlockedCompareExchange.c: Separated routine from private.c +	* ptw32_callUserDestroyRoutines.c: Likewise. +	* ptw32_getprocessors.c: Likewise. +	* ptw32_processInitialize.c: Likewise. +	* ptw32_processTerminate.c: Likewise. +	* ptw32_threadDestroy.c: Likewise. +	* ptw32_threadStart.c: Likewise. +	* ptw32_throw.c: Likewise. +	* ptw32_timespec.c: Likewise. +	* ptw32_tkAssocCreate.c: Likewise. +	* ptw32_tkAssocDestroy.c: Likewise. + +	* rwlock.c: Split file into function segments. +	* pthread_rwlockattr_destroy.c: Separated routine from rwlock.c +	* pthread_rwlockattr_getpshared.c: Likewise. +	* pthread_rwlockattr_init.c: Likewise. +	* pthread_rwlockattr_setpshared.c: Likewise. +	* ptw32_rwlock_check_need_init.c: Likewise. +	* pthread_rwlock_destroy.c: Likewise. +	* pthread_rwlock_init.c: Likewise. +	* pthread_rwlock_rdlock.c: Likewise. +	* pthread_rwlock_tryrdlock.c: Likewise. +	* pthread_rwlock_trywrlock.c: Likewise. +	* pthread_rwlock_unlock.c: Likewise. +	* pthread_rwlock_wrlock.c: Likewise. + +2002-02-10  Ross Johnson  <rpj at setup1.ise.canberra.edu.au + +	Reduce executable size. +	----------------------- +	When linking with the static library, only those +	routines actually called, either directly or indirectly +	should be included. + +	[Gcc has the -ffunction-segments option to do this but MSVC +	doesn't have this feature as far as I can determine. Other +	compilers are undetermined as well. - rpj] + +	* nonportable.c: Split file into function segments. +	* np_delay.c: Separated routine from nonportable.c +	* np_getw32threadhandle.c: Likewise. +	* np_mutexattr_setkind.c: Likewise. +	* np_mutexattr_getkind.c: Likewise. +	* np_num_processors.c: Likewise. +	* np_win32_attach_detach.c: Likewise. + +	* misc.c: Split file into function segments. +	* pthread_equal.c: Separated routine from nonportable.c. +	* pthread_getconcurrency.c: Likewise. +	* pthread_once.c: Likewise. +	* pthread_self.c: Likewise. +	* pthread_setconcurrency.c: Likewise. +	* ptw32_calloc.c: Likewise. +	* ptw32_new.c: Likewise. +	* w32_CancelableWait.c: Likewise. +	 +2002-02-09  Ross Johnson  <rpj at setup1.ise.canberra.edu.au + +	Reduce executable size. +	----------------------- +	When linking with the static library, only those +	routines actually called, either directly or indirectly +	should be included. + +	[Gcc has the -ffunction-segments option to do this but MSVC +	doesn't have this feature as far as I can determine. Other +	compilers are undetermined as well. - rpj] + +	* condvar.c: Split file into function segments. +	* pthread_condattr_destroy.c: Separated routine from condvar.c. +	* pthread_condattr_getpshared.c: Likewise. +	* pthread_condattr_init.c: Likewise. +	* pthread_condattr_setpshared.c: Likewise. +	* ptw32_cond_check_need_init.c: Likewise. +	* pthread_cond_destroy.c: Likewise. +	* pthread_cond_init.c: Likewise. +	* pthread_cond_signal.c: Likewise. +	* pthread_cond_wait.c: Likewise. +	 +2002-02-07  Alexander Terekhov<TEREKHOV at de.ibm.com> + +	* nonportable.c (pthread_delay_np): Make a true +	cancelation point. Deferred cancels will interrupt the +	wait. + +2002-02-07  Ross Johnson  <rpj at setup1.ise.canberra.edu.au + +	* misc.c (ptw32_new): Add creation of cancelEvent so that +	implicit POSIX threads (Win32 threads with a POSIX face) +	are cancelable; mainly so that pthread_delay_np doesn't fail +	if called from the main thread. +	* create.c (pthread_create): Remove creation of cancelEvent +	from here; now in ptw32_new(). + +	Reduce executable size. +	----------------------- +	When linking with the static library, only those +	routines actually called, either directly or indirectly +	should be included. + +	[Gcc has the -ffunction-segments option to do this but MSVC +	doesn't have this feature as far as I can determine. Other +	compilers are undetermined as well. - rpj] + +	* barrier.c: All routines are now in separate compilation units; +	This file is used to congregate the separate modules for +	potential inline optimisation and backward build compatibility. +	* cancel.c: Likewise. +	* pthread_barrierattr_destroy.c: Separated routine from cancel.c. +	* pthread_barrierattr_getpshared.c: Likewise. +	* pthread_barrierattr_init.c: Likewise. +	* pthread_barrierattr_setpshared.c: Likewise. +	* pthread_barrier_destroy.c: Likewise. +	* pthread_barrier_init.c: Likewise. +	* pthread_barrier_wait.c: Likewise. +	* pthread_cancel.c: Likewise. +	* pthread_setcancelstate.c: Likewise. +	* pthread_setcanceltype.c: Likewise. +	* pthread_testcancel.c: Likewise. + +2002-02-04  Max Woodbury <mtew at cds.duke.edu> + +	Reduced name space pollution. +	----------------------------- +	When the appropriate symbols are defined, the headers +	will restrict the definitions of new names. In particular, +	it must be possible to NOT include the <windows.h> +	header and related definitions with some combination +	of symbol definitions. Secondly, it should be possible +	that additional definitions should be limited to POSIX  +	compliant symbols by the definition of appropriate symbols. + +	* pthread.h: POSIX conditionals. +	* sched.h: POSIX conditionals. +	* semaphore.h: POSIX conditionals. + +	* semaphore.c: Included <limits.h>. +	(sem_init): Changed magic 0x7FFFFFFFL to INT_MAX. +	(sem_getvalue): Trial version. + +	Reduce executable size. +	----------------------- +	When linking with the static library, only those +	routines actually called, either directly or indirectly +	should be included. + +	[Gcc has the -ffunction-segments option to do this but MSVC +	doesn't have this feature as far as I can determine. Other +	compilers are undetermined as well. - rpj] + +	* semaphore.c: All routines are now in separate compilation units; +	This file is used to congregate the separate modules for +	potential inline optimisation and backward build compatibility. +	* sem_close.c: Separated routine from semaphore.c. +	* ptw32_decrease_semaphore.c: Likewise. +	* sem_destroy.c: Likewise. +	* sem_getvalue.c: Likewise. +	* ptw32_increase_semaphore.c: Likewise. +	* sem_init.c: Likewise. +	* sem_open.c: Likewise. +	* sem_post.c: Likewise. +	* sem_post_multiple.c: Likewise. +	* sem_timedwait.c: Likewise. +	* sem_trywait.c: Likewise. +	* sem_unlink.c: Likewise. +	* sem_wait.c: Likewise. + +2002-02-04  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	The following extends the idea above to the rest of pthreads-win32 - rpj +	 +	* attr.c: All routines are now in separate compilation units; +	This file is used to congregate the separate modules for +	potential inline optimisation and backward build compatibility. +	* pthread_attr_destroy.c: Separated routine from attr.c. +	* pthread_attr_getdetachstate.c: Likewise. +	* pthread_attr_getscope.c: Likewise. +	* pthread_attr_getstackaddr.c: Likewise. +	* pthread_attr_getstacksize.c: Likewise. +	* pthread_attr_init.c: Likewise. +	* pthread_attr_is_attr.c: Likewise. +	* pthread_attr_setdetachstate.c: Likewise. +	* pthread_attr_setscope.c: Likewise. +	* pthread_attr_setstackaddr.c: Likewise. +	* pthread_attr_setstacksize.c: Likewise. + +	* pthread.c: Agregation of agregate modules for super-inlineability. + +2002-02-02  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* cancel.c: Rearranged some code and introduced checks +	to disable cancelation at the start of a thread's cancelation +	run to prevent double cancelation. The main problem +	arises if a thread is canceling and then receives a subsequent +	async cancel request. +	* private.c: Likewise. +	* condvar.c: Place pragmas around cleanup_push/pop to turn +	off inline optimisation (/Obn where n>0 - MSVC only). Various +	optimisation switches in MSVC turn this on, which interferes with +	the way that cleanup handlers are run in C++ EH and SEH +	code. Application code compiled with inline optimisation must +	also wrap cleanup_push/pop blocks with the pragmas, e.g. +	  #pragma inline_depth(0) +	  pthread_cleanup_push(...) +	    ... +	  pthread_cleanup_pop(...) +	  #pragma inline_depth(8) +	* rwlock.c: Likewise. +	* mutex.c: Remove attempts to inline some functions. +	* signal.c: Modify misleading comment. + +2002-02-01  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* semaphore.c (sem_trywait): Fix missing errno return +	for systems that define NEED_SEM (e.g. early WinCE). +	* mutex.c (pthread_mutex_timedlock): Return ENOTSUP +	for systems that define NEED_SEM since they don't +	have sem_trywait(). + +2002-01-27  Ross Johnson  <rpj at special.ise.canberra.edu.au> + +	* mutex.c (pthread_mutex_timedlock): New function suggested by +	Alexander Terekhov. The logic required to implement this +	properly came from Alexander, with some collaboration +	with Thomas Pfaff. +	(pthread_mutex_unlock): Wrap the waiters check and sema +	post in a critical section to prevent a race with +	pthread_mutex_timedlock. +	(ptw32_timed_semwait): New function; +	returns a special result if the absolute timeout parameter +	represents a time already passed when called; used by +	pthread_mutex_timedwait(). Have deliberately not reused +	the name "ptw32_sem_timedwait" because they are not the same +	routine. +	* condvar.c (ptw32_cond_timedwait): Use the new sem_timedwait() +	instead of ptw32_sem_timedwait(), which now has a different +	function. See previous. +	* implement.h: Remove prototype for ptw32_sem_timedwait. +	See next. +	(pthread_mutex_t_): Add critical section element for access +	to lock_idx during mutex post-timeout processing. +	* semaphore.h (sem_timedwait): See next. +	* semaphore.c (sem_timedwait): See next. +	* private.c (ptw32_sem_timedwait): Move to semaphore.c +	and rename as sem_timedwait(). + +2002-01-18  Ross Johnson  <rpj at special.ise.canberra.edu.au> + +	* sync.c (pthread_join): Was getting the exit code from the +	calling thread rather than the joined thread if +	defined(__MINGW32__) && !defined(__MSVCRT__). + +2002-01-15  Ross Johnson  <rpj at special.ise.canberra.edu.au> + +	* pthread.h: Unless the build explicitly defines __CLEANUP_SEH, +	__CLEANUP_CXX, or __CLEANUP_C, then the build defaults to +	__CLEANUP_C style cleanup. This style uses setjmp/longjmp +	in the cancelation and thread exit implementations and therefore +	won't do stack unwinding if linked to applications that have it +	(e.g. C++ apps). This is currently consistent with most/all +	commercial Unix POSIX threads implementations. + +	* spin.c (pthread_spin_init): Edit renamed function call. +	* nonportable.c (pthread_num_processors_np): New. +	(pthread_getprocessors_np): Renamed to ptw32_getprocessors +	and moved to private.c. +	* private.c (pthread_getprocessors): Moved here from +	nonportable.c. +	* pthread.def (pthread_getprocessors_np): Removed +	from export list. + +	* rwlock.c (pthread_rwlockattr_init): New. +	(pthread_rwlockattr_destroy): New. +	(pthread_rwlockattr_getpshared): New. +	(pthread_rwlockattr_setpshared): New. + +2002-01-14  Ross Johnson  <rpj at special.ise.canberra.edu.au> + +	* attr.c (pthread_attr_setscope): Fix struct pointer +	indirection error introduced 2002-01-04. +	(pthread_attr_getscope): Likewise. + +2002-01-12  Ross Johnson  <rpj at special.ise.canberra.edu.au> + +	* pthread.dsp (SOURCE): Add missing source files. + +2002-01-08  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* mutex.c (pthread_mutex_trylock): use +	ptw32_interlocked_compare_exchange function pointer +	rather than ptw32_InterlockedCompareExchange() directly +	to retain portability to non-iX86 processors, +	e.g. WinCE etc. The pointer will point to the native +	OS version of InterlockedCompareExchange() if the +	OS supports it (see ChangeLog entry of 2001-10-17). + +2002-01-07  Thomas Pfaff <tpfaff at gmx.net>, Alexander Terekhov <TEREKHOV at de.ibm.com> + +	* mutex.c (pthread_mutex_init): Remove critical +	section calls. +	(pthread_mutex_destroy): Likewise. +	(pthread_mutex_unlock): Likewise. +	(pthread_mutex_trylock): Likewise; uses +	ptw32_InterlockedCompareExchange() to avoid need for +	critical section; library is no longer i386 compatible; +	recursive mutexes now increment the lock count rather +	than return EBUSY; errorcheck mutexes return EDEADLCK +	rather than EBUSY. This behaviour is consistent with the +	Solaris pthreads implementation. +	* implement.h (pthread_mutex_t_): Remove critical +	section element - no longer needed. +	 + +2002-01-04  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* attr.c (pthread_attr_setscope): Add more error +	checking and actually store the scope value even +	though it's not really necessary. +	(pthread_attr_getscope): Return stored value. +	* implement.h (pthread_attr_t_): Add new scope element. +	* ANNOUNCE: Fix out of date comment next to +	pthread_attr_setscope in conformance section. + +2001-12-21  Alexander Terekhov <TEREKHOV at de.ibm.com> + +	* mutex.c (pthread_mutex_lock): Decrementing lock_idx was +	not thread-safe. +	(pthread_mutex_trylock): Likewise. + +2001-10-26  prionx@juno.com + +	* semaphore.c (sem_init): Fix typo and missing bracket +	in conditionally compiled code. Only older versions of +	WinCE require this code, hence it doesn't normally get +	tested; somehow when sem_t reverted to an opaque struct +	the calloc NULL check was left in the conditionally included +	section. +	(sem_destroy): Likewise, the calloced sem_t wasn't being freed. + +2001-10-25  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* GNUmakefile (libwsock32): Add to linker flags for +	WSAGetLastError() and WSASetLastError(). +	* Makefile (wsock32.lib): Likewise. +	* create.c: Minor mostly inert changes. +	* implement.h (PTW32_MAX): Move into here and renamed +	from sched.h. +	(PTW32_MIN): Likewise. +	* GNUmakefile (TEST_ICE): Define if testing internal +	implementation of InterlockedCompareExchange. +	* Makefile (TEST_ICE): Likewise. +	* private.c (TEST_ICE): Likewise. +	 +2001-10-24  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* attr.c (pthread_attr_setstacksize): Quell warning +	from LCC by conditionally compiling the stacksize +	validity check. LCC correctly warns that the condition +	(stacksize < PTHREAD_STACK_MIN) is suspicious +	because STACK_MIN is 0 and stacksize is of type +	size_t (or unsigned int). + +2001-10-17  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* barrier.c: Move _LONG and _LPLONG defines into +	implement.h; rename to PTW32_INTERLOCKED_LONG and +	PTW32_INTERLOCKED_LPLONG respectively. +	* spin.c: Likewise; ptw32_interlocked_compare_exchange used +	in place of InterlockedCompareExchange directly. +	* global.c (ptw32_interlocked_compare_exchange): Add +	prototype for this new routine pointer to be used when +	InterlockedCompareExchange isn't supported by Windows. +	* nonportable.c (pthread_win32_process_attach_np): Check for +	support of InterlockedCompareExchange in kernel32 and assign its +	address to ptw32_interlocked_compare_exchange if it exists, or +	our own ix86 specific implementation ptw32_InterlockedCompareExchange. +	*private.c (ptw32_InterlockedCompareExchange): An +	implementation of InterlockedCompareExchange() which is +	specific to ix86; written directly in assembler for either +	MSVC or GNU C; needed because Windows 95 doesn't support +	InterlockedCompareExchange(). + +	* sched.c (sched_get_priority_min): Extend to return +	THREAD_PRIORITY_IDLE. +	(sched_get_priority_max): Extend to return +	THREAD_PRIORITY_CRITICAL. + +2001-10-15  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* spin.c (pthread_spin_lock): PTHREAD_SPINLOCK_INITIALIZER +	was causing a program fault. +	(pthread_spin_init): Could have alloced memory +	without freeing under some error conditions. + +	* mutex.c (pthread_mutex_init): Move memory +	allocation of mutex struct after checking for +	PROCESS_SHARED. + +2001-10-12  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* spin.c (pthread_spin_unlock): Was not returning +	EPERM if the spinlock was not locked, for multi CPU +	machines. + +2001-10-08  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* spin.c (pthread_spin_trylock): Was not returning +	EBUSY for multi CPU machines. + +2001-08-24  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* condvar.c (pthread_cond_destroy): Remove cv element +	that is no longer used. +	* implement.h: Likewise. + +2001-08-23  Alexander Terekhov <TEREKHOV at de.ibm.com> + +	* condvar.c (pthread_cond_destroy): fix bug with +	respect to deadlock in the case of concurrent +	_destroy/_unblock; a condition variable can be destroyed +	immediately after all the threads that are blocked on +	it are awakened. + +2001-08-23  Phil Frisbie, Jr. <phil at hawksoft.com> + +	* tsd.c (pthread_getspecific): Preserve the last +	winsock error [from WSAGetLastError()]. + +2001-07-18  Scott McCaskill <scott at magruder.org> + +	* mutex.c (pthread_mutexattr_init): Return ENOMEM +	immediately and don't dereference the NULL pointer +	if calloc fails. +	(pthread_mutexattr_getpshared): Don't dereference +	a pointer that is possibly NULL. +	* barrier.c (pthread_barrierattr_init): Likewise +	(pthread_barrierattr_getpshared): Don't dereference +	a pointer that is possibly NULL. +	* condvar.c (pthread_condattr_getpshared): Don't dereference +	a pointer that is possibly NULL. + +2001-07-15  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* rwlock.c (pthread_rwlock_wrlock): Is allowed to be +	a cancelation point; re-enable deferred cancelability +	around the CV call. + +2001-07-10  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* barrier.c: Still more revamping. The exclusive access +	mutex isn't really needed so it has been removed and replaced +	by an InterlockedDecrement(). nSerial has been removed. +	iStep is now dual-purpose. The process shared attribute +	is now stored in the barrier struct. +	* implement.h (pthread_barrier_t_): Lost some/gained one +	elements. +	* private.c (ptw32_threadStart): Removed some comments. + +2001-07-10  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* barrier.c: Revamped to fix the race condition. Two alternating +	semaphores are used instead of the PulseEvent. Also improved +	overall throughput by returning PTHREAD_BARRIER_SERIAL_THREAD +	to the first waking thread. +	* implement.h (pthread_barrier_t_): Revamped. + +2001-07-09  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* barrier.c: Fix several bugs in all routines. Now passes +	tests/barrier5.c which is fairly rigorous. There is still +	a non-optimal work-around for a race condition between +	the barrier breeched event signal and event wait. Basically +	the last (signalling) thread to hit the barrier yields +	to allow any other threads, which may have lost the race, +	to complete. + +2001-07-07  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* barrier.c: Changed synchronisation mechanism to a +	Win32 manual reset Event and use PulseEvent to signal +	waiting threads. If the implementation continued to use +	a semaphore it would require a second semaphore and +	some management to use them alternately as barriers. A +	single semaphore allows threads to cascade from one barrier +	through the next, leaving some threads blocked at the first. +	* implement.h (pthread_barrier_t_): As per above. +	* general: Made a number of other routines inlinable. + +2001-07-07  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* spin.c: Revamped and working; included static initialiser. +	Now beta level. +	* barrier.c: Likewise. +	* condvar.c: Macro constant change; inline auto init routine. +	* mutex.c: Likewise. +	* rwlock.c: Likewise. +	* private.c: Add support for spinlock initialiser. +	* global.c: Likewise. +	* implement.h: Likewise. +	* pthread.h (PTHREAD_SPINLOCK_INITIALIZER): Fix typo. + +2001-07-05  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* barrier.c: Remove static initialisation - irrelevent +	for this object. +	* pthread.h (PTHREAD_BARRIER_INITIALIZER): Removed. +	* rwlock.c (pthread_rwlock_wrlock): This routine is +	not a cancelation point - disable deferred +	cancelation around call to pthread_cond_wait(). + +2001-07-05  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* spin.c: New module implementing spin locks. +	* barrier.c: New module implementing barriers. +	* pthread.h (_POSIX_SPIN_LOCKS): defined. +	(_POSIX_BARRIERS): Defined. +	(pthread_spin_*): Defined. +	(pthread_barrier*): Defined. +	(PTHREAD_BARRIER_SERIAL_THREAD): Defined. +	* implement.h (pthread_spinlock_t_): Defined. +	(pthread_barrier_t_): Defined. +	(pthread_barrierattr_t_): Defined. + +	* mutex.c (pthread_mutex_lock): Return with the error +	if an auto-initialiser initialisation fails. + +	* nonportable.c (pthread_getprocessors_np): New; gets the +	number of available processors for the current process. + +2001-07-03  Ross Johnson  <rpj at setup1.ise.canberra.edu.au> + +	* pthread.h (_POSIX_READER_WRITER_LOCKS): Define it +	if not already defined. + +2001-07-01  Alexander Terekhov <TEREKHOV at de.ibm.com> + +	* condvar.c: Fixed lost signal bug reported by Timur Aydin +	(taydin@snet.net). +	[RPJ (me) didn't translate the original algorithm +	correctly.] +	* semaphore.c: Added sem_post_multiple; this is a useful +	routine, but it doesn't appear to be standard. For now it's +	not an exported function. +	 +2001-06-25  Ross Johnson  <rpj at 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 at 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  Ralf Brese <Ralf.Brese at pdb4.siemens.de> + +	* create.c (pthread_create): Set thread priority from +	thread attributes. + +2001-06-18  Ross Johnson  <rpj at 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  David Korn <dgk at 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 at 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 at 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 at setup1.ise.canberra.edu.au> + +	* mutex.c (pthread_mutexattr_init): Remove  +	ptw32_mutex_default_kind. +	 +2001-06-05  Ross Johnson  <rpj at 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 at 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  Alexander Terekhov <TEREKHOV at de.ibm.com>, Louis Thomas <lthomas at 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 at 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  Milan Gardian <Milan.Gardian at 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  Thomas Pfaff <tpfaff at 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  Alexander Terekhov <TEREKHOV at 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 at 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 at 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 at special.ise.canberra.edu.au> + +	* FAQ: Update Answer 6 re getting a fully working +	Mingw32 built library. + +2000-10-10  Steven Reddie <smr at essemer.com.au> +  +        * misc.c (pthread_self): Restore Win32 "last error" +        cleared by TlsGetValue() call in +        pthread_getspecific() +  +2000-09-20  Arthur Kantor <akantor at bexusa.com> +  +        * 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. + +2000-09-13  Jef Gearhart <jgearhart at tpssys.com> + +	* 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 + +2000-09-09  Ross Johnson  <rpj at special.ise.canberra.edu.au> + +	* pthread.h (ctime_r): Fix arg. + +2000-09-08  Ross Johnson  <rpj at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at special.ise.canberra.edu.au> + +	* pthread.h: Remove #warning - VC++ doesn't accept it. + +2000-08-05  Ross Johnson  <rpj at 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 at 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 at 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  Tristan Savatier <tristan at mpegtv.com> + +	* sched.c (sched_get_priority_max): Handle different WinCE and +	Win32 priority values together. +	(sched_get_priority_min): Ditto. + +2000-07-25  Ross Johnson  <rpj at special.ise.canberra.edu.au> + +	* 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 at 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 at special.ise.canberra.edu.au> + +	* FAQ: Added Q5 and Q6. + +2000-07-21  David Baggett <dmb at itasoftware.com> + +	* 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. + +2000-07-21  Ross Johnson  <rpj at 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.) + +	* 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 at 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 at 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 at 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  Erik Hensema <erik.hensema at group2000.nl> + +	* Makefile: Remove inconsistencies in 'cl' args + +2000-01-04  Ross Johnson  <rpj at 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 at 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 at 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. + +1999-11-21  Jason Nye <jnye at nbnet.nb.ca>, Erik Hensema <erik.hensema at group2000.nl> + +	* 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. + +1999-11-13  Erik Hensema <erik.hensema at group2000.nl> + +	* configure.in (AC_OUTPUT): Put generated output into GNUmakefile +	rather than Makefile. Makefile will become the MSC nmake compatible +	version + +1999-11-13  John Bossom (John.Bossom@cognos.com> + +	* misc.c (pthread_self): Add a note about GetCurrentThread +	returning a pseudo-handle + +1999-11-10  Todd Owen <towen at lucidcalm.dropbear.id.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. + +1999-11-10  Ross Johnson  <rpj at ixobrychus.canberra.edu.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  Tristan Savatier <tristan at mpegtv.com> + +	* 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. + +1999-10-30  Erik Hensema <erik.hensema at group2000.nl> + +	* 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: + +1999-10-23  Erik Hensema <erik.hensema at group2000.nl> + +	* pthread.h (ctime_r): Fix incorrect argument "_tm" + +1999-10-21  Aurelio Medina <aureliom at crt.com> + +	* 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 + +1999-10-17  Ross Johnson  <rpj at 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  Lorin Hochstein <lmh at xiphos.ca>, Peter Slacik <Peter.Slacik at tatramed.sk> + +	* 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. + +1999-10-15  Graham Dumpleton <Graham.Dumpleton at ra.pad.otc.telstra.com.au> + +	* condvar.c (cond_wait_cleanup): the last waiter will now reset the CV's +	wasBroadcast flag + +Thu Sep 16 1999  Ross Johnson  <rpj at 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. + +1999-08-10  Aurelio Medina  <aureliom at crt.com> + +	* 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. + +1999-08-08 Milan Gardian <mg at tatramed.sk> + +	* mutex.c (pthread_mutex_destroy): Free mutex memory. + +1999-08-22  Ross Johnson  <rpj at ixobrychus.canberra.edu.au> + +	* exit.c (pthread_exit): Fix reference to potentially +	uninitialised pointer. + +1999-08-21  Ross Johnson  <rpj at 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 at ixobrychus.canberra.edu.au> + +	* private.c (ptw32_threadStart): Return exit status from +	the application thread startup routine. +	- Milan Gardian <mg at tatramed.sk> + +1999-08-18  John Bossom <john.Bossom at cognos.com> + +	* exit.c (pthread_exit): Put status into pthread_t->exitStatus +	* private.c (ptw32_threadStart): Set pthread->exitStatus +	on exit of try{} block. +	* 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). + +Tue Aug 17 20:17:58 CDT 1999  Mumit Khan  <khan at 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 at 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 at 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 at 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  Peter Slacik <Peter.Slacik at tatramed.sk> + +	* 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. + +1999-07-09  Lorin Hochstein <lmh at xiphos.ca>, John Bossom <John.Bossom at 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. + +1999-07-09  Ross Johnson  <rpj at ixobrychus.canberra.edu.au> + +	* 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 at ixobrychus.canberra.edu.au> + +	* semaphore.h (mode_t): Conditionally typedef it. + +Fri May 28 13:33:05 1999  Mark E. Armstrong <avail at pacbell.net> + +	* condvar.c (pthread_cond_broadcast): Fix possible memory fault +	 +Thu May 27 13:08:46 1999  Peter Slacik <Peter.Slacik at tatramed.sk> + +	* condvar.c (pthread_cond_broadcast): Fix logic bug + +Thu May 27 13:08:46 1999  Bossom, John <John.Bossom at Cognos.COM> + +	* condvar.c (pthread_cond_broadcast): optimise sem_post loop + +Fri May 14 12:13:18 1999  Mike Russo <miker at eai.com> + +	* attr.c (pthread_attr_setdetachstate): Fix logic bug + +Sat May  8 09:42:30 1999  Ross Johnson  <rpj at 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 at 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 at 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 at 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 at 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 at ixobrychus.canberra.edu.au> + +	* Makefile.in (OBJS): Add errno.o. + +Fri Apr  2 11:08:50 1999  Ross Johnson  <rpj at 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. + +	* semaphore.c (ptw32_sem_timedwait): Moved to private.c. + +	* pthread.h (ptw32_sem_t): Change to sem_t.  + +	* private.c (ptw32_sem_timedwait): Moved from semaphore.c; +	set errno on error. + +	* pthread.h (pthread_t_): Add per-thread errno element. + +Fri Apr  2 11:08:50 1999  John Bossom <jebossom at cognos.com> + +	* semaphore.c (ptw32_sem_*): Change to sem_*; these functions +	will be exported from the library; set errno on error. + +	* errno.c (_errno): New file. New function. + +Fri Mar 26 14:11:45 1999  Tor Lillqvist <tml at iki.fi> + +	* semaphore.c (ptw32_sem_timedwait): Check for negative +	milliseconds. + +Wed Mar 24 11:32:07 1999  John Bossom <jebossom at cognos.com> + +	* misc.c (CancelableWait): Initialise exceptionInformation[2]. +	(pthread_self): Get a real Win32 thread handle for implicit threads. + +	* cancel.c (pthread_testcancel): Initialise exceptionInformation[2]. + +	* implement.h (SE_INFORMATION): Fix values. + +	* private.c (ptw32_threadDestroy): Close the thread handle. + +Fri Mar 19 12:57:27 1999  Ross Johnson  <rpj at swan.canberra.edu.au> + +	* cancel.c (comments): Update and cleanup. + +Fri Mar 19 09:12:59 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au> + +	* private.c (ptw32_threadStart): status returns PTHREAD_CANCELED. + +	* pthread.h (PTHREAD_CANCELED): defined. + +Tue Mar 16  1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au> + +	* all: Add GNU LGPL and Copyright and Warranty. +	 +Mon Mar 15 00:20:13 1999  Ross Johnson  <rpj at 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 at 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 at 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 at ixobrychus.canberra.edu.au> + +	* misc.c (CancelableWait): Undo changes from Mar 8 and 7. + +Mon Mar  8 11:18:59 1999  Ross Johnson  <rpj at 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 at 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 at ixobrychus.canberra.edu.au> + +	* implement.h: Undate comments. + +Sun Feb 21 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au> + +	* pthread.h (PTHREAD_MUTEX_INITIALIZER): missing braces around +	cs element initialiser. + +1999-02-21  Ben Elliston  <bje at 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 at 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 at 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 at 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 at 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 at 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 at ixobrychus.canberra.edu.au> + +	* configure: Various temporary changes. +	- Kevin Ruland <Kevin.Ruland at 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 at swan.canberra.edu.au> + +	* semaphore.c: Comment format changes. + +Thu Feb  4 10:07:28 1999  Ross Johnson  <rpj at 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 at 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 at 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 at swan.canberra.edu.au> + +	* implement.h: Add #include <pthread.h>. +	Change sem_t to ptw32_sem_t. + +Tue Feb  2 18:07:43 1999  Kevin Ruland <Kevin.Ruland at 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 at 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 at ixobrychus.canberra.edu.au> + +	* semaphore.c (sem_wait): Remove second arg to  +	pthreadCancelableWait() call. + +Sat Jan 23 17:36:40 1999  Ross Johnson  <rpj at 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 at 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 at 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 at 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. + +Tue Jan 19 18:27:42 1999  Scott Lightner <scott at curriculum.com> + +	* 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(). + +Tue Jan 19 10:27:39 1999  Ross Johnson  <rpj at 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 at 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 at 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 at ixobrychus.canberra.edu.au> + +	* condvar.c (cond_timedwait): Remove comment. + +Fri Jan 15 15:41:28 1999  Ross Johnson  <rpj at 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 at 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 at ixobrychus.canberra.edu.au> + +	* build.bat: Delete old binaries before compiling/linking. + +Tue Jan 12 09:58:38 1999  Tor Lillqvist <tml at iki.fi> + +	* dll.c: The Microsoft compiler pragmas probably are more +	appropriately protected by _MSC_VER than by _WIN32. + +	* 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. + +	* pthread.def: pthread_mutex_destroy was missing from the def file + +	* 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. + +Tue Jan 12 09:58:38 1999  Ross Johnson  <rpj at ixobrychus.canberra.edu.au> + +	* condvar.c (pthread_cond_timedwait): Fix function description +	comments. + +	* semaphore.c (sem_post): Correct typo in comment. + +Mon Jan 11 20:33:19 1999  Ross Johnson  <rpj at 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  Tor Lillqvist <tml at iki.fi> + +	* condvar.c (pthread_cond_init): Invert logic when testing the +	return value from calloc(). + +Sat Jan  9 14:32:08 1999  Ross Johnson  <rpj at 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 at hem2.passagen.se>. + +Tue Jan  5 16:33:04 1999  Ross Johnson  <rpj at 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 at toilet.to.cygnus.com> + +	* README: Update info about subscribing to the mailing list. + +Mon Jan  4 11:23:40 1999  Ross Johnson  <rpj at 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 at 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  John Bossom + +	* semaphore.c: Initial version. +	* semaphore.h: Initial version. + +Mon Dec 28 09:54:39 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au> + +	* pthread.h (pthread_attr_t_): Change to *pthread_attr_t. + +Mon Dec 28 09:54:39 1998  John Bossom, Ben Elliston + +	* attr.c (pthread_attr_setstacksize): Merge with John's version. +	(pthread_attr_getstacksize): Merge with John's version. +	(pthread_attr_setstackaddr): Merge with John's version. +	(pthread_attr_getstackaddr): Merge with John's version. +	(pthread_attr_init): Merge with John's version. +	(pthread_attr_destroy): Merge with John's version. +	(pthread_attr_getdetachstate): Merge with John's version. +	(pthread_attr_setdetachstate): Merge with John's version. +	(is_attr): attr is now **attr (was *attr), so add extra NULL pointer +	test. + +Mon Dec 28 09:54:39 1998  Ross Johnson + +	* 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 at 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 at 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  John Bossom + +	* cancel.c (pthread_setcancelstate): Replaced. +	(pthread_setcanceltype): Replaced. +	(pthread_testcancel): Replaced. +	(pthread_cancel): Replaced. +	 +	* exit.c (pthread_exit): Replaced. + +	* misc.c (pthread_self): Replaced. +	(pthread_equal): Replaced. + +	* sync.c (pthread_detach): Replaced. +	(pthread_join): Replaced. + +	* create.c (pthread_create): Replaced. + +	* private.c (ptw32_processInitialize): New. +	(ptw32_processTerminate): New. +	(ptw32_threadStart): New. + 	(ptw32_threadDestroy): New. +	(ptw32_cleanupStack): New. +	(ptw32_tkAssocCreate): New. +	(ptw32_tkAssocDestroy): New. +	(ptw32_callUserDestroyRoutines): New. + +	* implement.h: Added non-API structures and declarations. + +	* dll.c (PthreadsEntryPoint): Cast return value of GetProcAddress +	to resolve compile warning from MSVC. + +	* dll.c (DLLmain): Replaced. +	* 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 at 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 at 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 at ise.canberra.edu.au> + +	* README: Correct cygwin32 compatibility statement. + +Sun Nov 15 21:24:06 1998  Ross Johnson  <rpj at ixobrychus.canberra.edu.au> + +	* cleanup.c (ptw32_destructor_run_all): Declare missing void * arg. +	Fixup CVS merge conflicts. + +1998-10-30  Ben Elliston  <bje at 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 at swan.canberra.edu.au> + +	* cleanup.c (ptw32_handler_push): Fixed bug appending new +	handler to list reported by Peter Slacik +	<Peter.Slacik at leibinger.freinet.de>. +	(new_thread): Rename poorly named local variable to +	"new_handler". + +Sat Oct 24 18:34:59 1998  Ross Johnson  <rpj at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at ixobrychus.canberra.edu.au> + +	* pthread.def: New file for building the DLL. + +1998-10-05  Ben Elliston  <bje at 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 at 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 at 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 at cygnus.com> + +	* COPYING: Remove. + +	* COPYING.LIB: Add. This library is under the LGPL. + +1998-09-13  Ben Elliston  <bje at 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 at cygnus.com> + +	* windows.h: No longer needed; remove. + +	* windows.c: Likewise. + +Sat Sep 12 20:09:24 1998  Ross Johnson  <rpj at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at cygnus.com> + +	* fork.c (fork): Autoconfiscate. + +Sat Jul 25 00:00:13 1998  Ross Johnson  <rpj at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at ixobrychus.canberra.edu.au> + +	* implement.h: Preliminary implementation specific defines. + +	* create.c (pthread_create): Preliminary implementation. + +1998-07-11  Ben Elliston  <bje at 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 at 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 at cygnus.com> + +	* create.c (pthread_create): A dummy stub right now. + +	* pthread.h (pthread_create): Add function prototype. diff --git a/GNUmakefile b/GNUmakefile index 2d034c0..60b2d81 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,570 +1,570 @@ -#
 -# --------------------------------------------------------------------------
 -#
 -#      Pthreads-win32 - POSIX Threads Library for Win32
 -#      Copyright(C) 1998 John E. Bossom
 -#      Copyright(C) 1999,2005 Pthreads-win32 contributors
 -# 
 -#      Contact Email: rpj@callisto.canberra.edu.au
 -# 
 -#      The current list of contributors is contained
 -#      in the file CONTRIBUTORS included with the source
 -#      code distribution. The list can also be seen at the
 -#      following World Wide Web location:
 -#      http://sources.redhat.com/pthreads-win32/contributors.html
 -# 
 -#      This library is free software; you can redistribute it and/or
 -#      modify it under the terms of the GNU Lesser General Public
 -#      License as published by the Free Software Foundation; either
 -#      version 2 of the License, or (at your option) any later version.
 -# 
 -#      This library is distributed in the hope that it will be useful,
 -#      but WITHOUT ANY WARRANTY; without even the implied warranty of
 -#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 -#      Lesser General Public License for more details.
 -# 
 -#      You should have received a copy of the GNU Lesser General Public
 -#      License along with this library in the file COPYING.LIB;
 -#      if not, write to the Free Software Foundation, Inc.,
 -#      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 -#
 -
 -DLL_VER	= 2
 -DLL_VERD= $(DLL_VER)d
 -
 -DEVROOT	= C:\PTHREADS
 -
 -DLLDEST	= $(DEVROOT)\DLL
 -LIBDEST	= $(DEVROOT)\DLL
 -
 -# If Running MsysDTK
 -RM	= rm -f
 -MV	= mv -f
 -CP	= cp -f
 -RC	= windres
 -
 -# If not.
 -#RM	= erase
 -#MV	= rename
 -#CP	= copy
 -
 -AR	= ar
 -
 -OPT	= $(CLEANUP) -O3 -finline-functions
 -DOPT	= $(CLEANUP) -g -O0
 -XOPT	=
 -
 -RCFLAGS		= --include-dir=.
 -LFLAGS		= -lwsock32
 -
 -# ----------------------------------------------------------------------
 -# The library can be built with some alternative behaviour to
 -# facilitate development of applications on Win32 that will be ported
 -# to other POSIX systems. Nothing definable here will make the library
 -# non-compliant, but applications that make assumptions that POSIX
 -# does not garrantee may fail or misbehave under some settings.
 -#
 -# PTW32_THREAD_ID_REUSE_INCREMENT
 -# Purpose:
 -# POSIX says that applications should assume that thread IDs can be
 -# recycled. However, Solaris and some other systems use a [very large]
 -# sequence number as the thread ID, which provides virtual uniqueness.
 -#
 -# Usage:
 -# Set to any value in the range: 0 <= value <= 2^wordsize
 -#
 -# Examples:
 -# Set to 0 to emulate non recycle-unique behaviour like Linux or *BSD.
 -# Set to 1 for recycle-unique thread IDs like Solaris (this is the default).
 -# Set to some other +ve value to emulate smaller word size types (i.e. will
 -# wrap sooner). This might be useful to emulate some embedded systems.
 -#
 -#PTW32_FLAGS	= "-DPTW32_THREAD_ID_REUSE_INCREMENT=0"
 -#
 -# ----------------------------------------------------------------------
 -
 -GC_CFLAGS	= $(PTW32_FLAGS) 
 -GCE_CFLAGS	= $(PTW32_FLAGS) -mthreads
 -
 -## Mingw32
 -MAKE		= make
 -CFLAGS	= $(OPT) $(XOPT) -I. -DHAVE_CONFIG_H -Wall
 -
 -DLL_INLINED_OBJS	= \
 -		pthread.o \
 -		version.o
 -
 -# Agregate modules for inlinability
 -DLL_OBJS	= \
 -		attr.o \
 -		barrier.o \
 -		cancel.o \
 -		cleanup.o \
 -		condvar.o \
 -		create.o \
 -		dll.o \
 -		errno.o \
 -		exit.o \
 -		fork.o \
 -		global.o \
 -		misc.o \
 -		mutex.o \
 -		nonportable.o \
 -		private.o \
 -		rwlock.o \
 -		sched.o \
 -		semaphore.o \
 -		signal.o \
 -		spin.o \
 -		sync.o \
 -		tsd.o \
 -		version.o
 -
 -# Separate modules for minimum size statically linked images
 -SMALL_STATIC_OBJS	= \
 -		pthread_attr_init.o \
 -		pthread_attr_destroy.o \
 -		pthread_attr_getdetachstate.o \
 -		pthread_attr_setdetachstate.o \
 -		pthread_attr_getstackaddr.o \
 -		pthread_attr_setstackaddr.o \
 -		pthread_attr_getstacksize.o \
 -		pthread_attr_setstacksize.o \
 -		pthread_attr_getscope.o \
 -		pthread_attr_setscope.o \
 -		pthread_attr_setschedpolicy.o \
 -		pthread_attr_getschedpolicy.o \
 -		pthread_attr_setschedparam.o \
 -		pthread_attr_getschedparam.o \
 -		pthread_attr_setinheritsched.o \
 -		pthread_attr_getinheritsched.o \
 -		pthread_barrier_init.o \
 -		pthread_barrier_destroy.o \
 -		pthread_barrier_wait.o \
 -		pthread_barrierattr_init.o \
 -		pthread_barrierattr_destroy.o \
 -		pthread_barrierattr_setpshared.o \
 -		pthread_barrierattr_getpshared.o \
 -		pthread_setcancelstate.o \
 -		pthread_setcanceltype.o \
 -		pthread_testcancel.o \
 -		pthread_cancel.o \
 -		cleanup.o \
 -		pthread_condattr_destroy.o \
 -		pthread_condattr_getpshared.o \
 -		pthread_condattr_init.o \
 -		pthread_condattr_setpshared.o \
 -		pthread_cond_destroy.o \
 -		pthread_cond_init.o \
 -		pthread_cond_signal.o \
 -		pthread_cond_wait.o \
 -		create.o \
 -		dll.o \
 -		errno.o \
 -		pthread_exit.o \
 -		fork.o \
 -		global.o \
 -		pthread_mutex_init.o \
 -		pthread_mutex_destroy.o \
 -		pthread_mutexattr_init.o \
 -		pthread_mutexattr_destroy.o \
 -		pthread_mutexattr_getpshared.o \
 -		pthread_mutexattr_setpshared.o \
 -		pthread_mutexattr_settype.o \
 -		pthread_mutexattr_gettype.o \
 -		pthread_mutex_lock.o \
 -		pthread_mutex_timedlock.o \
 -		pthread_mutex_unlock.o \
 -		pthread_mutex_trylock.o \
 -		pthread_mutexattr_setkind_np.o \
 -		pthread_mutexattr_getkind_np.o \
 -		pthread_getw32threadhandle_np.o \
 -		pthread_delay_np.o \
 -		pthread_num_processors_np.o \
 -		pthread_win32_attach_detach_np.o \
 -		pthread_equal.o \
 -		pthread_getconcurrency.o \
 -		pthread_once.o \
 -		pthread_self.o \
 -		pthread_setconcurrency.o \
 -		pthread_rwlock_init.o \
 -		pthread_rwlock_destroy.o \
 -		pthread_rwlockattr_init.o \
 -		pthread_rwlockattr_destroy.o \
 -		pthread_rwlockattr_getpshared.o \
 -		pthread_rwlockattr_setpshared.o \
 -		pthread_rwlock_rdlock.o \
 -		pthread_rwlock_wrlock.o \
 -		pthread_rwlock_unlock.o \
 -		pthread_rwlock_tryrdlock.o \
 -		pthread_rwlock_trywrlock.o \
 -		pthread_setschedparam.o \
 -		pthread_getschedparam.o \
 -		pthread_timechange_handler_np.o \
 -		ptw32_is_attr.o \
 -		ptw32_cond_check_need_init.o \
 -		ptw32_mutex_check_need_init.o \
 -		ptw32_processInitialize.o \
 -		ptw32_processTerminate.o \
 -		ptw32_threadStart.o \
 -		ptw32_threadDestroy.o \
 -		ptw32_tkAssocCreate.o \
 -		ptw32_tkAssocDestroy.o \
 -		ptw32_callUserDestroyRoutines.o \
 -		ptw32_timespec.o \
 -		ptw32_throw.o \
 -		ptw32_InterlockedCompareExchange.o \
 -		ptw32_getprocessors.o \
 -		ptw32_calloc.o \
 -		ptw32_new.o \
 -		ptw32_reuse.o \
 -		ptw32_semwait.o \
 -		ptw32_relmillisecs.o \
 -		ptw32_rwlock_check_need_init.o \
 -		sched_get_priority_max.o \
 -		sched_get_priority_min.o \
 -		sched_setscheduler.o \
 -		sched_getscheduler.o \
 -		sched_yield.o \
 -		sem_init.o \
 -		sem_destroy.o \
 -		sem_trywait.o \
 -		sem_timedwait.o \
 -		sem_wait.o \
 -		sem_post.o \
 -		sem_post_multiple.o \
 -		sem_getvalue.o \
 -		sem_open.o \
 -		sem_close.o \
 -		sem_unlink.o \
 -		signal.o \
 -		pthread_kill.o \
 -		ptw32_spinlock_check_need_init.o \
 -		pthread_spin_init.o \
 -		pthread_spin_destroy.o \
 -		pthread_spin_lock.o \
 -		pthread_spin_unlock.o \
 -		pthread_spin_trylock.o \
 -		pthread_detach.o \
 -		pthread_join.o \
 -		pthread_key_create.o \
 -		pthread_key_delete.o \
 -		pthread_setspecific.o \
 -		pthread_getspecific.o \
 -		w32_CancelableWait.o \
 -		version.o
 -
 -INCL	= \
 -		config.h \
 -		implement.h \
 -		semaphore.h \
 -		pthread.h \
 -		need_errno.h
 -
 -ATTR_SRCS	= \
 -		pthread_attr_init.c \
 -		pthread_attr_destroy.c \
 -		pthread_attr_getdetachstate.c \
 -		pthread_attr_setdetachstate.c \
 -		pthread_attr_getstackaddr.c \
 -		pthread_attr_setstackaddr.c \
 -		pthread_attr_getstacksize.c \
 -		pthread_attr_setstacksize.c \
 -		pthread_attr_getscope.c \
 -		pthread_attr_setscope.c
 -
 -BARRIER_SRCS = \
 -		pthread_barrier_init.c \
 -		pthread_barrier_destroy.c \
 -		pthread_barrier_wait.c \
 -		pthread_barrierattr_init.c \
 -		pthread_barrierattr_destroy.c \
 -		pthread_barrierattr_setpshared.c \
 -		pthread_barrierattr_getpshared.c
 -
 -CANCEL_SRCS	= \
 -		pthread_setcancelstate.c \
 -		pthread_setcanceltype.c \
 -		pthread_testcancel.c \
 -		pthread_cancel.c 
 -
 -CONDVAR_SRCS	= \
 -		ptw32_cond_check_need_init.c \
 -		pthread_condattr_destroy.c \
 -		pthread_condattr_getpshared.c \
 -		pthread_condattr_init.c \
 -		pthread_condattr_setpshared.c \
 -		pthread_cond_destroy.c \
 -		pthread_cond_init.c \
 -		pthread_cond_signal.c \
 -		pthread_cond_wait.c
 -
 -EXIT_SRCS	= \
 -		pthread_exit.c
 -
 -MISC_SRCS	= \
 -		pthread_equal.c \
 -		pthread_getconcurrency.c \
 -		pthread_kill.c \
 -		pthread_once.c \
 -		pthread_self.c \
 -		pthread_setconcurrency.c \
 -		ptw32_calloc.c \
 -		ptw32_new.c \
 -		ptw32_reuse.c \
 -		w32_CancelableWait.c
 -
 -MUTEX_SRCS	= \
 -		ptw32_mutex_check_need_init.c \
 -		pthread_mutex_init.c \
 -		pthread_mutex_destroy.c \
 -		pthread_mutexattr_init.c \
 -		pthread_mutexattr_destroy.c \
 -		pthread_mutexattr_getpshared.c \
 -		pthread_mutexattr_setpshared.c \
 -		pthread_mutexattr_settype.c \
 -		pthread_mutexattr_gettype.c \
 -		pthread_mutex_lock.c \
 -		pthread_mutex_timedlock.c \
 -		pthread_mutex_unlock.c \
 -		pthread_mutex_trylock.c
 -
 -NONPORTABLE_SRCS = \
 -		pthread_mutexattr_setkind_np.c \
 -		pthread_mutexattr_getkind_np.c \
 -		pthread_getw32threadhandle_np.c \
 -		pthread_delay_np.c \
 -		pthread_num_processors_np.c \
 -		pthread_win32_attach_detach_np.c \
 -		pthread_timechange_handler_np.c 
 -
 -PRIVATE_SRCS	= \
 -		ptw32_is_attr.c \
 -		ptw32_processInitialize.c \
 -		ptw32_processTerminate.c \
 -		ptw32_threadStart.c \
 -		ptw32_threadDestroy.c \
 -		ptw32_tkAssocCreate.c \
 -		ptw32_tkAssocDestroy.c \
 -		ptw32_callUserDestroyRoutines.c \
 -		ptw32_semwait.c \
 -		ptw32_relmillisecs.c \
 -		ptw32_timespec.c \
 -		ptw32_throw.c \
 -		ptw32_InterlockedCompareExchange.c \
 -		ptw32_getprocessors.c
 -
 -RWLOCK_SRCS	= \
 -		ptw32_rwlock_check_need_init.c \
 -		ptw32_rwlock_cancelwrwait.c \
 -		pthread_rwlock_init.c \
 -		pthread_rwlock_destroy.c \
 -		pthread_rwlockattr_init.c \
 -		pthread_rwlockattr_destroy.c \
 -		pthread_rwlockattr_getpshared.c \
 -		pthread_rwlockattr_setpshared.c \
 -		pthread_rwlock_rdlock.c \
 -		pthread_rwlock_timedrdlock.c \
 -		pthread_rwlock_wrlock.c \
 -		pthread_rwlock_timedwrlock.c \
 -		pthread_rwlock_unlock.c \
 -		pthread_rwlock_tryrdlock.c \
 -		pthread_rwlock_trywrlock.c
 -
 -SCHED_SRCS	= \
 -		pthread_attr_setschedpolicy.c \
 -		pthread_attr_getschedpolicy.c \
 -		pthread_attr_setschedparam.c \
 -		pthread_attr_getschedparam.c \
 -		pthread_attr_setinheritsched.c \
 -		pthread_attr_getinheritsched.c \
 -		pthread_setschedparam.c \
 -		pthread_getschedparam.c \
 -		sched_get_priority_max.c \
 -		sched_get_priority_min.c \
 -		sched_setscheduler.c \
 -		sched_getscheduler.c \
 -		sched_yield.c
 -
 -SEMAPHORE_SRCS = \
 -		sem_init.c \
 -		sem_destroy.c \
 -		sem_trywait.c \
 -		sem_timedwait.c \
 -		sem_wait.c \
 -		sem_post.c \
 -		sem_post_multiple.c \
 -		sem_getvalue.c \
 -		sem_open.c \
 -		sem_close.c \
 -		sem_unlink.c
 -
 -SPIN_SRCS	= \
 -		ptw32_spinlock_check_need_init.c \
 -		pthread_spin_init.c \
 -		pthread_spin_destroy.c \
 -		pthread_spin_lock.c \
 -		pthread_spin_unlock.c \
 -		pthread_spin_trylock.c
 -
 -SYNC_SRCS	= \
 -		pthread_detach.c \
 -		pthread_join.c
 -
 -TSD_SRCS	= \
 -		pthread_key_create.c \
 -		pthread_key_delete.c \
 -		pthread_setspecific.c \
 -		pthread_getspecific.c
 -
 -
 -GCE_DLL	= pthreadGCE$(DLL_VER).dll
 -GCED_DLL= pthreadGCE$(DLL_VERD).dll
 -GCE_LIB	= libpthreadGCE$(DLL_VER).a
 -GCED_LIB= libpthreadGCE$(DLL_VERD).a
 -GCE_INLINED_STAMP = pthreadGCE$(DLL_VER).stamp
 -GCED_INLINED_STAMP = pthreadGCE$(DLL_VERD).stamp
 -
 -GC_DLL 	= pthreadGC$(DLL_VER).dll
 -GCD_DLL	= pthreadGC$(DLL_VERD).dll
 -GC_LIB	= libpthreadGC$(DLL_VER).a
 -GCD_LIB	= libpthreadGC$(DLL_VERD).a
 -GC_INLINED_STAMP = pthreadGC$(DLL_VER).stamp
 -GCD_INLINED_STAMP = pthreadGC$(DLL_VERD).stamp
 -GC_STATIC_STAMP = libpthreadGC$(DLL_VER).stamp
 -GCD_STATIC_STAMP = libpthreadGC$(DLL_VERD).stamp
 -
 -PTHREAD_DEF	= pthread.def
 -
 -help:
 -	@ echo "Run one of the following command lines:"
 -	@ echo "make clean GC            (to build the GNU C dll with C cleanup code)"
 -	@ echo "make clean GCE           (to build the GNU C dll with C++ exception handling)"
 -	@ echo "make clean GC-inlined    (to build the GNU C inlined dll with C cleanup code)"
 -	@ echo "make clean GCE-inlined   (to build the GNU C inlined dll with C++ exception handling)"
 -	@ echo "make clean GC-static     (to build the GNU C inlined static lib with C cleanup code)"
 -	@ echo "make clean GC-debug      (to build the GNU C debug dll with C cleanup code)"
 -	@ echo "make clean GCE-debug     (to build the GNU C debug dll with C++ exception handling)"
 -	@ echo "make clean GC-inlined-debug    (to build the GNU C inlined debug dll with C cleanup code)"
 -	@ echo "make clean GCE-inlined-debug   (to build the GNU C inlined debug dll with C++ exception handling)"
 -	@ echo "make clean GC-static-debug     (to build the GNU C inlined static debug lib with C cleanup code)"
 -
 -all:
 -	@ $(MAKE) clean GCE
 -	@ $(MAKE) clean GC
 -
 -GC:
 -		$(MAKE) CC=gcc CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" $(GC_DLL)
 -
 -GC-debug:
 -		$(MAKE) CC=gcc CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="$(DOPT)" $(GCD_DLL)
 -
 -GCE:
 -		$(MAKE) CC=g++ CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" $(GCE_DLL)
 -
 -GCE-debug:
 -		$(MAKE) CC=g++ CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="$(DOPT)" $(GCED_DLL)
 -
 -GC-inlined:
 -		$(MAKE) CC=gcc XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_INLINED_STAMP)
 -
 -GC-inlined-debug:
 -		$(MAKE) CC=gcc XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="$(DOPT)" $(GCD_INLINED_STAMP)
 -
 -GCE-inlined:
 -		$(MAKE) CC=g++ XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GCE_INLINED_STAMP)
 -
 -GCE-inlined-debug:
 -		$(MAKE) CC=g++ XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="$(DOPT)" $(GCED_INLINED_STAMP)
 -
 -GC-static:
 -		$(MAKE) CC=gcc XOPT="-DPTW32_BUILD_INLINED -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_STATIC_STAMP)
 -
 -GC-static-debug:
 -		$(MAKE) CC=gcc XOPT="-DPTW32_BUILD_INLINED -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="$(DOPT)" $(GCD_STATIC_STAMP)
 -
 -tests:
 -	@ cd tests
 -	@ $(MAKE) auto
 -
 -%.pre: %.c
 -	$(CC) -E -o $@ $(CFLAGS) $^
 -
 -%.s: %.c
 -	$(CC) -c $(CFLAGS) -Wa,-ahl $^ > $@
 -
 -%.o: %.rc
 -	$(RC) $(RCFLAGS) $(CLEANUP) -o $@ $<
 -
 -.SUFFIXES: .dll .rc .c .o
 -
 -.c.o:;		 $(CC) -c -o $@ $(CFLAGS) $(XC_FLAGS) $<
 -
 -
 -$(GC_DLL) $(GCD_DLL): $(DLL_OBJS)
 -	$(CC) $(OPT) -shared -o $(GC_DLL) $(DLL_OBJS) $(LFLAGS)
 -	dlltool -z pthread.def $(DLL_OBJS)
 -	dlltool -k --dllname $@ --output-lib $(GC_LIB) --def $(PTHREAD_DEF)
 -
 -$(GCE_DLL): $(DLL_OBJS)
 -	$(CC) $(OPT) -mthreads -shared -o $(GCE_DLL) $(DLL_OBJS) $(LFLAGS)
 -	dlltool -z pthread.def $(DLL_OBJS)
 -	dlltool -k --dllname $@ --output-lib $(GCE_LIB) --def $(PTHREAD_DEF)
 -
 -$(GC_INLINED_STAMP) $(GCD_INLINED_STAMP): $(DLL_INLINED_OBJS)
 -	$(CC) $(OPT) $(XOPT) -shared -o $(GC_DLL) $(DLL_INLINED_OBJS) $(LFLAGS)
 -	dlltool -z pthread.def $(DLL_INLINED_OBJS)
 -	dlltool -k --dllname $(GC_DLL) --output-lib $(GC_LIB) --def $(PTHREAD_DEF)
 -	echo touched > $(GC_INLINED_STAMP)
 -
 -$(GCE_INLINED_STAMP) $(GCED_INLINED_STAMP): $(DLL_INLINED_OBJS)
 -	$(CC) $(OPT) $(XOPT) -mthreads -shared -o $(GCE_DLL) $(DLL_INLINED_OBJS)  $(LFLAGS)
 -	dlltool -z pthread.def $(DLL_INLINED_OBJS)
 -	dlltool -k --dllname $(GCE_DLL) --output-lib $(GCE_LIB) --def $(PTHREAD_DEF)
 -	echo touched > $(GCE_INLINED_STAMP)
 -
 -$(GC_STATIC_STAMP) $(GCD_STATIC_STAMP): $(DLL_INLINED_OBJS)
 -	$(RM) $(GC_LIB)
 -	$(AR) -rv $(GC_LIB) $(DLL_INLINED_OBJS)
 -	echo touched > $(GC_STATIC_STAMP)
 -
 -clean:
 -	-$(RM) *~
 -	-$(RM) *.i
 -	-$(RM) *.o
 -	-$(RM) *.obj
 -	-$(RM) *.exe
 -	-$(RM) $(PTHREAD_DEF)
 -
 -realclean: clean
 -	-$(RM) $(GC_LIB)
 -	-$(RM) $(GCE_LIB)
 -	-$(RM) $(GC_DLL)
 -	-$(RM) $(GCE_DLL)
 -	-$(RM) $(GC_INLINED_STAMP)
 -	-$(RM) $(GCE_INLINED_STAMP)
 -	-$(RM) $(GC_STATIC_STAMP)
 -	-$(RM) $(GCD_LIB)
 -	-$(RM) $(GCED_LIB)
 -	-$(RM) $(GCD_DLL)
 -	-$(RM) $(GCED_DLL)
 -	-$(RM) $(GCD_INLINED_STAMP)
 -	-$(RM) $(GCED_INLINED_STAMP)
 -	-$(RM) $(GCD_STATIC_STAMP)
 -
 -attr.o:		attr.c $(ATTR_SRCS) $(INCL)
 -barrier.o:	barrier.c $(BARRIER_SRCS) $(INCL)
 -cancel.o:	cancel.c $(CANCEL_SRCS) $(INCL)
 -condvar.o:	condvar.c $(CONDVAR_SRCS) $(INCL)
 -exit.o:		exit.c $(EXIT_SRCS) $(INCL)
 -misc.o:		misc.c $(MISC_SRCS) $(INCL)
 -mutex.o:	mutex.c $(MUTEX_SRCS) $(INCL)
 -nonportable.o:	nonportable.c $(NONPORTABLE_SRCS) $(INCL)
 -private.o:	private.c $(PRIVATE_SRCS) $(INCL)
 -rwlock.o:	rwlock.c $(RWLOCK_SRCS) $(INCL)
 -sched.o:	sched.c $(SCHED_SRCS) $(INCL)
 -semaphore.o:	semaphore.c $(SEMAPHORE_SRCS) $(INCL)
 -spin.o:		spin.c $(SPIN_SRCS) $(INCL)
 -sync.o:		sync.c $(SYNC_SRCS) $(INCL)
 -tsd.o:		tsd.c $(TSD_SRCS) $(INCL)
 -version.o:	version.rc $(INCL)
 +# +# -------------------------------------------------------------------------- +# +#      Pthreads-win32 - POSIX Threads Library for Win32 +#      Copyright(C) 1998 John E. Bossom +#      Copyright(C) 1999,2005 Pthreads-win32 contributors +#  +#      Contact Email: rpj@callisto.canberra.edu.au +#  +#      The current list of contributors is contained +#      in the file CONTRIBUTORS included with the source +#      code distribution. The list can also be seen at the +#      following World Wide Web location: +#      http://sources.redhat.com/pthreads-win32/contributors.html +#  +#      This library is free software; you can redistribute it and/or +#      modify it under the terms of the GNU Lesser General Public +#      License as published by the Free Software Foundation; either +#      version 2 of the License, or (at your option) any later version. +#  +#      This library is distributed in the hope that it will be useful, +#      but WITHOUT ANY WARRANTY; without even the implied warranty of +#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +#      Lesser General Public License for more details. +#  +#      You should have received a copy of the GNU Lesser General Public +#      License along with this library in the file COPYING.LIB; +#      if not, write to the Free Software Foundation, Inc., +#      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# + +DLL_VER	= 2 +DLL_VERD= $(DLL_VER)d + +DEVROOT	= C:\PTHREADS + +DLLDEST	= $(DEVROOT)\DLL +LIBDEST	= $(DEVROOT)\DLL + +# If Running MsysDTK +RM	= rm -f +MV	= mv -f +CP	= cp -f +RC	= windres + +# If not. +#RM	= erase +#MV	= rename +#CP	= copy + +AR	= ar + +OPT	= $(CLEANUP) -O3 -finline-functions +DOPT	= $(CLEANUP) -g -O0 +XOPT	= + +RCFLAGS		= --include-dir=. +LFLAGS		= -lwsock32 + +# ---------------------------------------------------------------------- +# The library can be built with some alternative behaviour to +# facilitate development of applications on Win32 that will be ported +# to other POSIX systems. Nothing definable here will make the library +# non-compliant, but applications that make assumptions that POSIX +# does not garrantee may fail or misbehave under some settings. +# +# PTW32_THREAD_ID_REUSE_INCREMENT +# Purpose: +# POSIX says that applications should assume that thread IDs can be +# recycled. However, Solaris and some other systems use a [very large] +# sequence number as the thread ID, which provides virtual uniqueness. +# +# Usage: +# Set to any value in the range: 0 <= value <= 2^wordsize +# +# Examples: +# Set to 0 to emulate non recycle-unique behaviour like Linux or *BSD. +# Set to 1 for recycle-unique thread IDs like Solaris (this is the default). +# Set to some other +ve value to emulate smaller word size types (i.e. will +# wrap sooner). This might be useful to emulate some embedded systems. +# +#PTW32_FLAGS	= "-DPTW32_THREAD_ID_REUSE_INCREMENT=0" +# +# ---------------------------------------------------------------------- + +GC_CFLAGS	= $(PTW32_FLAGS)  +GCE_CFLAGS	= $(PTW32_FLAGS) -mthreads + +## Mingw32 +MAKE		= make +CFLAGS	= $(OPT) $(XOPT) -I. -DHAVE_CONFIG_H -Wall + +DLL_INLINED_OBJS	= \ +		pthread.o \ +		version.o + +# Agregate modules for inlinability +DLL_OBJS	= \ +		attr.o \ +		barrier.o \ +		cancel.o \ +		cleanup.o \ +		condvar.o \ +		create.o \ +		dll.o \ +		errno.o \ +		exit.o \ +		fork.o \ +		global.o \ +		misc.o \ +		mutex.o \ +		nonportable.o \ +		private.o \ +		rwlock.o \ +		sched.o \ +		semaphore.o \ +		signal.o \ +		spin.o \ +		sync.o \ +		tsd.o \ +		version.o + +# Separate modules for minimum size statically linked images +SMALL_STATIC_OBJS	= \ +		pthread_attr_init.o \ +		pthread_attr_destroy.o \ +		pthread_attr_getdetachstate.o \ +		pthread_attr_setdetachstate.o \ +		pthread_attr_getstackaddr.o \ +		pthread_attr_setstackaddr.o \ +		pthread_attr_getstacksize.o \ +		pthread_attr_setstacksize.o \ +		pthread_attr_getscope.o \ +		pthread_attr_setscope.o \ +		pthread_attr_setschedpolicy.o \ +		pthread_attr_getschedpolicy.o \ +		pthread_attr_setschedparam.o \ +		pthread_attr_getschedparam.o \ +		pthread_attr_setinheritsched.o \ +		pthread_attr_getinheritsched.o \ +		pthread_barrier_init.o \ +		pthread_barrier_destroy.o \ +		pthread_barrier_wait.o \ +		pthread_barrierattr_init.o \ +		pthread_barrierattr_destroy.o \ +		pthread_barrierattr_setpshared.o \ +		pthread_barrierattr_getpshared.o \ +		pthread_setcancelstate.o \ +		pthread_setcanceltype.o \ +		pthread_testcancel.o \ +		pthread_cancel.o \ +		cleanup.o \ +		pthread_condattr_destroy.o \ +		pthread_condattr_getpshared.o \ +		pthread_condattr_init.o \ +		pthread_condattr_setpshared.o \ +		pthread_cond_destroy.o \ +		pthread_cond_init.o \ +		pthread_cond_signal.o \ +		pthread_cond_wait.o \ +		create.o \ +		dll.o \ +		errno.o \ +		pthread_exit.o \ +		fork.o \ +		global.o \ +		pthread_mutex_init.o \ +		pthread_mutex_destroy.o \ +		pthread_mutexattr_init.o \ +		pthread_mutexattr_destroy.o \ +		pthread_mutexattr_getpshared.o \ +		pthread_mutexattr_setpshared.o \ +		pthread_mutexattr_settype.o \ +		pthread_mutexattr_gettype.o \ +		pthread_mutex_lock.o \ +		pthread_mutex_timedlock.o \ +		pthread_mutex_unlock.o \ +		pthread_mutex_trylock.o \ +		pthread_mutexattr_setkind_np.o \ +		pthread_mutexattr_getkind_np.o \ +		pthread_getw32threadhandle_np.o \ +		pthread_delay_np.o \ +		pthread_num_processors_np.o \ +		pthread_win32_attach_detach_np.o \ +		pthread_equal.o \ +		pthread_getconcurrency.o \ +		pthread_once.o \ +		pthread_self.o \ +		pthread_setconcurrency.o \ +		pthread_rwlock_init.o \ +		pthread_rwlock_destroy.o \ +		pthread_rwlockattr_init.o \ +		pthread_rwlockattr_destroy.o \ +		pthread_rwlockattr_getpshared.o \ +		pthread_rwlockattr_setpshared.o \ +		pthread_rwlock_rdlock.o \ +		pthread_rwlock_wrlock.o \ +		pthread_rwlock_unlock.o \ +		pthread_rwlock_tryrdlock.o \ +		pthread_rwlock_trywrlock.o \ +		pthread_setschedparam.o \ +		pthread_getschedparam.o \ +		pthread_timechange_handler_np.o \ +		ptw32_is_attr.o \ +		ptw32_cond_check_need_init.o \ +		ptw32_mutex_check_need_init.o \ +		ptw32_processInitialize.o \ +		ptw32_processTerminate.o \ +		ptw32_threadStart.o \ +		ptw32_threadDestroy.o \ +		ptw32_tkAssocCreate.o \ +		ptw32_tkAssocDestroy.o \ +		ptw32_callUserDestroyRoutines.o \ +		ptw32_timespec.o \ +		ptw32_throw.o \ +		ptw32_InterlockedCompareExchange.o \ +		ptw32_getprocessors.o \ +		ptw32_calloc.o \ +		ptw32_new.o \ +		ptw32_reuse.o \ +		ptw32_semwait.o \ +		ptw32_relmillisecs.o \ +		ptw32_rwlock_check_need_init.o \ +		sched_get_priority_max.o \ +		sched_get_priority_min.o \ +		sched_setscheduler.o \ +		sched_getscheduler.o \ +		sched_yield.o \ +		sem_init.o \ +		sem_destroy.o \ +		sem_trywait.o \ +		sem_timedwait.o \ +		sem_wait.o \ +		sem_post.o \ +		sem_post_multiple.o \ +		sem_getvalue.o \ +		sem_open.o \ +		sem_close.o \ +		sem_unlink.o \ +		signal.o \ +		pthread_kill.o \ +		ptw32_spinlock_check_need_init.o \ +		pthread_spin_init.o \ +		pthread_spin_destroy.o \ +		pthread_spin_lock.o \ +		pthread_spin_unlock.o \ +		pthread_spin_trylock.o \ +		pthread_detach.o \ +		pthread_join.o \ +		pthread_key_create.o \ +		pthread_key_delete.o \ +		pthread_setspecific.o \ +		pthread_getspecific.o \ +		w32_CancelableWait.o \ +		version.o + +INCL	= \ +		config.h \ +		implement.h \ +		semaphore.h \ +		pthread.h \ +		need_errno.h + +ATTR_SRCS	= \ +		pthread_attr_init.c \ +		pthread_attr_destroy.c \ +		pthread_attr_getdetachstate.c \ +		pthread_attr_setdetachstate.c \ +		pthread_attr_getstackaddr.c \ +		pthread_attr_setstackaddr.c \ +		pthread_attr_getstacksize.c \ +		pthread_attr_setstacksize.c \ +		pthread_attr_getscope.c \ +		pthread_attr_setscope.c + +BARRIER_SRCS = \ +		pthread_barrier_init.c \ +		pthread_barrier_destroy.c \ +		pthread_barrier_wait.c \ +		pthread_barrierattr_init.c \ +		pthread_barrierattr_destroy.c \ +		pthread_barrierattr_setpshared.c \ +		pthread_barrierattr_getpshared.c + +CANCEL_SRCS	= \ +		pthread_setcancelstate.c \ +		pthread_setcanceltype.c \ +		pthread_testcancel.c \ +		pthread_cancel.c  + +CONDVAR_SRCS	= \ +		ptw32_cond_check_need_init.c \ +		pthread_condattr_destroy.c \ +		pthread_condattr_getpshared.c \ +		pthread_condattr_init.c \ +		pthread_condattr_setpshared.c \ +		pthread_cond_destroy.c \ +		pthread_cond_init.c \ +		pthread_cond_signal.c \ +		pthread_cond_wait.c + +EXIT_SRCS	= \ +		pthread_exit.c + +MISC_SRCS	= \ +		pthread_equal.c \ +		pthread_getconcurrency.c \ +		pthread_kill.c \ +		pthread_once.c \ +		pthread_self.c \ +		pthread_setconcurrency.c \ +		ptw32_calloc.c \ +		ptw32_new.c \ +		ptw32_reuse.c \ +		w32_CancelableWait.c + +MUTEX_SRCS	= \ +		ptw32_mutex_check_need_init.c \ +		pthread_mutex_init.c \ +		pthread_mutex_destroy.c \ +		pthread_mutexattr_init.c \ +		pthread_mutexattr_destroy.c \ +		pthread_mutexattr_getpshared.c \ +		pthread_mutexattr_setpshared.c \ +		pthread_mutexattr_settype.c \ +		pthread_mutexattr_gettype.c \ +		pthread_mutex_lock.c \ +		pthread_mutex_timedlock.c \ +		pthread_mutex_unlock.c \ +		pthread_mutex_trylock.c + +NONPORTABLE_SRCS = \ +		pthread_mutexattr_setkind_np.c \ +		pthread_mutexattr_getkind_np.c \ +		pthread_getw32threadhandle_np.c \ +		pthread_delay_np.c \ +		pthread_num_processors_np.c \ +		pthread_win32_attach_detach_np.c \ +		pthread_timechange_handler_np.c  + +PRIVATE_SRCS	= \ +		ptw32_is_attr.c \ +		ptw32_processInitialize.c \ +		ptw32_processTerminate.c \ +		ptw32_threadStart.c \ +		ptw32_threadDestroy.c \ +		ptw32_tkAssocCreate.c \ +		ptw32_tkAssocDestroy.c \ +		ptw32_callUserDestroyRoutines.c \ +		ptw32_semwait.c \ +		ptw32_relmillisecs.c \ +		ptw32_timespec.c \ +		ptw32_throw.c \ +		ptw32_InterlockedCompareExchange.c \ +		ptw32_getprocessors.c + +RWLOCK_SRCS	= \ +		ptw32_rwlock_check_need_init.c \ +		ptw32_rwlock_cancelwrwait.c \ +		pthread_rwlock_init.c \ +		pthread_rwlock_destroy.c \ +		pthread_rwlockattr_init.c \ +		pthread_rwlockattr_destroy.c \ +		pthread_rwlockattr_getpshared.c \ +		pthread_rwlockattr_setpshared.c \ +		pthread_rwlock_rdlock.c \ +		pthread_rwlock_timedrdlock.c \ +		pthread_rwlock_wrlock.c \ +		pthread_rwlock_timedwrlock.c \ +		pthread_rwlock_unlock.c \ +		pthread_rwlock_tryrdlock.c \ +		pthread_rwlock_trywrlock.c + +SCHED_SRCS	= \ +		pthread_attr_setschedpolicy.c \ +		pthread_attr_getschedpolicy.c \ +		pthread_attr_setschedparam.c \ +		pthread_attr_getschedparam.c \ +		pthread_attr_setinheritsched.c \ +		pthread_attr_getinheritsched.c \ +		pthread_setschedparam.c \ +		pthread_getschedparam.c \ +		sched_get_priority_max.c \ +		sched_get_priority_min.c \ +		sched_setscheduler.c \ +		sched_getscheduler.c \ +		sched_yield.c + +SEMAPHORE_SRCS = \ +		sem_init.c \ +		sem_destroy.c \ +		sem_trywait.c \ +		sem_timedwait.c \ +		sem_wait.c \ +		sem_post.c \ +		sem_post_multiple.c \ +		sem_getvalue.c \ +		sem_open.c \ +		sem_close.c \ +		sem_unlink.c + +SPIN_SRCS	= \ +		ptw32_spinlock_check_need_init.c \ +		pthread_spin_init.c \ +		pthread_spin_destroy.c \ +		pthread_spin_lock.c \ +		pthread_spin_unlock.c \ +		pthread_spin_trylock.c + +SYNC_SRCS	= \ +		pthread_detach.c \ +		pthread_join.c + +TSD_SRCS	= \ +		pthread_key_create.c \ +		pthread_key_delete.c \ +		pthread_setspecific.c \ +		pthread_getspecific.c + + +GCE_DLL	= pthreadGCE$(DLL_VER).dll +GCED_DLL= pthreadGCE$(DLL_VERD).dll +GCE_LIB	= libpthreadGCE$(DLL_VER).a +GCED_LIB= libpthreadGCE$(DLL_VERD).a +GCE_INLINED_STAMP = pthreadGCE$(DLL_VER).stamp +GCED_INLINED_STAMP = pthreadGCE$(DLL_VERD).stamp + +GC_DLL 	= pthreadGC$(DLL_VER).dll +GCD_DLL	= pthreadGC$(DLL_VERD).dll +GC_LIB	= libpthreadGC$(DLL_VER).a +GCD_LIB	= libpthreadGC$(DLL_VERD).a +GC_INLINED_STAMP = pthreadGC$(DLL_VER).stamp +GCD_INLINED_STAMP = pthreadGC$(DLL_VERD).stamp +GC_STATIC_STAMP = libpthreadGC$(DLL_VER).stamp +GCD_STATIC_STAMP = libpthreadGC$(DLL_VERD).stamp + +PTHREAD_DEF	= pthread.def + +help: +	@ echo "Run one of the following command lines:" +	@ echo "make clean GC            (to build the GNU C dll with C cleanup code)" +	@ echo "make clean GCE           (to build the GNU C dll with C++ exception handling)" +	@ echo "make clean GC-inlined    (to build the GNU C inlined dll with C cleanup code)" +	@ echo "make clean GCE-inlined   (to build the GNU C inlined dll with C++ exception handling)" +	@ echo "make clean GC-static     (to build the GNU C inlined static lib with C cleanup code)" +	@ echo "make clean GC-debug      (to build the GNU C debug dll with C cleanup code)" +	@ echo "make clean GCE-debug     (to build the GNU C debug dll with C++ exception handling)" +	@ echo "make clean GC-inlined-debug    (to build the GNU C inlined debug dll with C cleanup code)" +	@ echo "make clean GCE-inlined-debug   (to build the GNU C inlined debug dll with C++ exception handling)" +	@ echo "make clean GC-static-debug     (to build the GNU C inlined static debug lib with C cleanup code)" + +all: +	@ $(MAKE) clean GCE +	@ $(MAKE) clean GC + +GC: +		$(MAKE) CC=gcc CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" $(GC_DLL) + +GC-debug: +		$(MAKE) CC=gcc CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="$(DOPT)" $(GCD_DLL) + +GCE: +		$(MAKE) CC=g++ CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" $(GCE_DLL) + +GCE-debug: +		$(MAKE) CC=g++ CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="$(DOPT)" $(GCED_DLL) + +GC-inlined: +		$(MAKE) CC=gcc XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_INLINED_STAMP) + +GC-inlined-debug: +		$(MAKE) CC=gcc XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="$(DOPT)" $(GCD_INLINED_STAMP) + +GCE-inlined: +		$(MAKE) CC=g++ XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GCE_INLINED_STAMP) + +GCE-inlined-debug: +		$(MAKE) CC=g++ XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="$(DOPT)" $(GCED_INLINED_STAMP) + +GC-static: +		$(MAKE) CC=gcc XOPT="-DPTW32_BUILD_INLINED -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_STATIC_STAMP) + +GC-static-debug: +		$(MAKE) CC=gcc XOPT="-DPTW32_BUILD_INLINED -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="$(DOPT)" $(GCD_STATIC_STAMP) + +tests: +	@ cd tests +	@ $(MAKE) auto + +%.pre: %.c +	$(CC) -E -o $@ $(CFLAGS) $^ + +%.s: %.c +	$(CC) -c $(CFLAGS) -Wa,-ahl $^ > $@ + +%.o: %.rc +	$(RC) $(RCFLAGS) $(CLEANUP) -o $@ $< + +.SUFFIXES: .dll .rc .c .o + +.c.o:;		 $(CC) -c -o $@ $(CFLAGS) $(XC_FLAGS) $< + + +$(GC_DLL) $(GCD_DLL): $(DLL_OBJS) +	$(CC) $(OPT) -shared -o $(GC_DLL) $(DLL_OBJS) $(LFLAGS) +	dlltool -z pthread.def $(DLL_OBJS) +	dlltool -k --dllname $@ --output-lib $(GC_LIB) --def $(PTHREAD_DEF) + +$(GCE_DLL): $(DLL_OBJS) +	$(CC) $(OPT) -mthreads -shared -o $(GCE_DLL) $(DLL_OBJS) $(LFLAGS) +	dlltool -z pthread.def $(DLL_OBJS) +	dlltool -k --dllname $@ --output-lib $(GCE_LIB) --def $(PTHREAD_DEF) + +$(GC_INLINED_STAMP) $(GCD_INLINED_STAMP): $(DLL_INLINED_OBJS) +	$(CC) $(OPT) $(XOPT) -shared -o $(GC_DLL) $(DLL_INLINED_OBJS) $(LFLAGS) +	dlltool -z pthread.def $(DLL_INLINED_OBJS) +	dlltool -k --dllname $(GC_DLL) --output-lib $(GC_LIB) --def $(PTHREAD_DEF) +	echo touched > $(GC_INLINED_STAMP) + +$(GCE_INLINED_STAMP) $(GCED_INLINED_STAMP): $(DLL_INLINED_OBJS) +	$(CC) $(OPT) $(XOPT) -mthreads -shared -o $(GCE_DLL) $(DLL_INLINED_OBJS)  $(LFLAGS) +	dlltool -z pthread.def $(DLL_INLINED_OBJS) +	dlltool -k --dllname $(GCE_DLL) --output-lib $(GCE_LIB) --def $(PTHREAD_DEF) +	echo touched > $(GCE_INLINED_STAMP) + +$(GC_STATIC_STAMP) $(GCD_STATIC_STAMP): $(DLL_INLINED_OBJS) +	$(RM) $(GC_LIB) +	$(AR) -rv $(GC_LIB) $(DLL_INLINED_OBJS) +	echo touched > $(GC_STATIC_STAMP) + +clean: +	-$(RM) *~ +	-$(RM) *.i +	-$(RM) *.o +	-$(RM) *.obj +	-$(RM) *.exe +	-$(RM) $(PTHREAD_DEF) + +realclean: clean +	-$(RM) $(GC_LIB) +	-$(RM) $(GCE_LIB) +	-$(RM) $(GC_DLL) +	-$(RM) $(GCE_DLL) +	-$(RM) $(GC_INLINED_STAMP) +	-$(RM) $(GCE_INLINED_STAMP) +	-$(RM) $(GC_STATIC_STAMP) +	-$(RM) $(GCD_LIB) +	-$(RM) $(GCED_LIB) +	-$(RM) $(GCD_DLL) +	-$(RM) $(GCED_DLL) +	-$(RM) $(GCD_INLINED_STAMP) +	-$(RM) $(GCED_INLINED_STAMP) +	-$(RM) $(GCD_STATIC_STAMP) + +attr.o:		attr.c $(ATTR_SRCS) $(INCL) +barrier.o:	barrier.c $(BARRIER_SRCS) $(INCL) +cancel.o:	cancel.c $(CANCEL_SRCS) $(INCL) +condvar.o:	condvar.c $(CONDVAR_SRCS) $(INCL) +exit.o:		exit.c $(EXIT_SRCS) $(INCL) +misc.o:		misc.c $(MISC_SRCS) $(INCL) +mutex.o:	mutex.c $(MUTEX_SRCS) $(INCL) +nonportable.o:	nonportable.c $(NONPORTABLE_SRCS) $(INCL) +private.o:	private.c $(PRIVATE_SRCS) $(INCL) +rwlock.o:	rwlock.c $(RWLOCK_SRCS) $(INCL) +sched.o:	sched.c $(SCHED_SRCS) $(INCL) +semaphore.o:	semaphore.c $(SEMAPHORE_SRCS) $(INCL) +spin.o:		spin.c $(SPIN_SRCS) $(INCL) +sync.o:		sync.c $(SYNC_SRCS) $(INCL) +tsd.o:		tsd.c $(TSD_SRCS) $(INCL) +version.o:	version.rc $(INCL) @@ -1,502 +1,502 @@ -# This makefile is compatible with MS nmake and can be used as a
 -# replacement for buildlib.bat. I've changed the target from an ordinary dll
 -# (/LD) to a debugging dll (/LDd).
 -# 
 -# The variables $DLLDEST and $LIBDEST hold the destination directories for the
 -# dll and the lib, respectively. Probably all that needs to change is $DEVROOT.
 -
 -
 -# DLL_VER:
 -# See pthread.h and README - This number is computed as 'current - age'
 -DLL_VER	= 2
 -DLL_VERD= $(DLL_VER)d
 -
 -DEVROOT	= C:\pthreads
 -
 -DLLDEST	= $(DEVROOT)\DLL
 -LIBDEST	= $(DEVROOT)\LIB
 -HDRDEST	= $(DEVROOT)\INCLUDE
 -
 -DLLS	= pthreadVCE$(DLL_VER).dll pthreadVSE$(DLL_VER).dll pthreadVC$(DLL_VER).dll \
 -		  pthreadVCE$(DLL_VERD).dll pthreadVSE$(DLL_VERD).dll pthreadVC$(DLL_VERD).dll
 -INLINED_STAMPS	= pthreadVCE$(DLL_VER).stamp pthreadVSE$(DLL_VER).stamp pthreadVC$(DLL_VER).stamp \
 -				  pthreadVCE$(DLL_VERD).stamp pthreadVSE$(DLL_VERD).stamp pthreadVC$(DLL_VERD).stamp
 -STATIC_STAMPS	= pthreadVCE$(DLL_VER).static pthreadVSE$(DLL_VER).static pthreadVC$(DLL_VER).static \
 -				  pthreadVCE$(DLL_VERD).static pthreadVSE$(DLL_VERD).static pthreadVC$(DLL_VERD).static
 -
 -OPTIM	= /O2 /Ob2
 -OPTIMD	=
 -
 -CFLAGS	= /W3 /MD /nologo /Yd /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H
 -CFLAGSD	= /Zi $(CFLAGS)
 -
 -
 -# Default cleanup style
 -CLEANUP	= __CLEANUP_C
 -
 -# C++ Exceptions
 -VCEFLAGS	= /GX /TP $(CFLAGS)
 -VCEFLAGSD	= /GX /TP $(CFLAGSD)
 -#Structured Exceptions
 -VSEFLAGS	= $(CFLAGS)
 -VSEFLAGSD	= $(CFLAGSD)
 -#C cleanup code
 -VCFLAGS	= $(CFLAGS)
 -VCFLAGSD= $(CFLAGSD)
 -
 -DLL_INLINED_OBJS = \
 -		pthread.obj \
 -		version.res
 -
 -# Aggregate modules for inlinability
 -DLL_OBJS	= \
 -		attr.obj \
 -		barrier.obj \
 -		cancel.obj \
 -		cleanup.obj \
 -		condvar.obj \
 -		create.obj \
 -		dll.obj \
 -		errno.obj \
 -		exit.obj \
 -		fork.obj \
 -		global.obj \
 -		misc.obj \
 -		mutex.obj \
 -		nonportable.obj \
 -		private.obj \
 -		rwlock.obj \
 -		sched.obj \
 -		semaphore.obj \
 -		signal.obj \
 -		spin.obj \
 -		sync.obj \
 -		tsd.obj \
 -		version.res
 -
 -# Separate modules for minimising the size of statically linked images
 -SMALL_STATIC_OBJS	= \
 -		pthread_attr_init.obj \
 -		pthread_attr_destroy.obj \
 -		pthread_attr_getdetachstate.obj \
 -		pthread_attr_setdetachstate.obj \
 -		pthread_attr_getstackaddr.obj \
 -		pthread_attr_setstackaddr.obj \
 -		pthread_attr_getstacksize.obj \
 -		pthread_attr_setstacksize.obj \
 -		pthread_attr_getscope.obj \
 -		pthread_attr_setscope.obj \
 -		pthread_attr_setschedpolicy.obj \
 -		pthread_attr_getschedpolicy.obj \
 -		pthread_attr_setschedparam.obj \
 -		pthread_attr_getschedparam.obj \
 -		pthread_attr_setinheritsched.obj \
 -		pthread_attr_getinheritsched.obj \
 -		pthread_barrier_init.obj \
 -		pthread_barrier_destroy.obj \
 -		pthread_barrier_wait.obj \
 -		pthread_barrierattr_init.obj \
 -		pthread_barrierattr_destroy.obj \
 -		pthread_barrierattr_setpshared.obj \
 -		pthread_barrierattr_getpshared.obj \
 -		pthread_setcancelstate.obj \
 -		pthread_setcanceltype.obj \
 -		pthread_testcancel.obj \
 -		pthread_cancel.obj \
 -		cleanup.obj \
 -		pthread_condattr_destroy.obj \
 -		pthread_condattr_getpshared.obj \
 -		pthread_condattr_init.obj \
 -		pthread_condattr_setpshared.obj \
 -		pthread_cond_destroy.obj \
 -		pthread_cond_init.obj \
 -		pthread_cond_signal.obj \
 -		pthread_cond_wait.obj \
 -		create.obj \
 -		dll.obj \
 -		errno.obj \
 -		pthread_exit.obj \
 -		fork.obj \
 -		global.obj \
 -		pthread_mutex_init.obj \
 -		pthread_mutex_destroy.obj \
 -		pthread_mutexattr_init.obj \
 -		pthread_mutexattr_destroy.obj \
 -		pthread_mutexattr_getpshared.obj \
 -		pthread_mutexattr_setpshared.obj \
 -		pthread_mutexattr_settype.obj \
 -		pthread_mutexattr_gettype.obj \
 -		pthread_mutex_lock.obj \
 -		pthread_mutex_timedlock.obj \
 -		pthread_mutex_unlock.obj \
 -		pthread_mutex_trylock.obj \
 -		pthread_mutexattr_setkind_np.obj \
 -		pthread_mutexattr_getkind_np.obj \
 -		pthread_getw32threadhandle_np.obj \
 -		pthread_delay_np.obj \
 -		pthread_num_processors_np.obj \
 -		pthread_win32_attach_detach_np.obj \
 -		pthread_equal.obj \
 -		pthread_getconcurrency.obj \
 -		pthread_once.obj \
 -		pthread_self.obj \
 -		pthread_setconcurrency.obj \
 -		pthread_rwlock_init.obj \
 -		pthread_rwlock_destroy.obj \
 -		pthread_rwlockattr_init.obj \
 -		pthread_rwlockattr_destroy.obj \
 -		pthread_rwlockattr_getpshared.obj \
 -		pthread_rwlockattr_setpshared.obj \
 -		pthread_rwlock_rdlock.obj \
 -		pthread_rwlock_wrlock.obj \
 -		pthread_rwlock_unlock.obj \
 -		pthread_rwlock_tryrdlock.obj \
 -		pthread_rwlock_trywrlock.obj \
 -		pthread_setschedparam.obj \
 -		pthread_getschedparam.obj \
 -		pthread_timechange_handler_np.obj \
 -		ptw32_is_attr.obj \
 -		ptw32_processInitialize.obj \
 -		ptw32_processTerminate.obj \
 -		ptw32_threadStart.obj \
 -		ptw32_threadDestroy.obj \
 -		ptw32_tkAssocCreate.obj \
 -		ptw32_tkAssocDestroy.obj \
 -		ptw32_callUserDestroyRoutines.obj \
 -		ptw32_timespec.obj \
 -		ptw32_throw.obj \
 -		ptw32_InterlockedCompareExchange.obj \
 -		ptw32_getprocessors.obj \
 -		ptw32_calloc.obj \
 -		ptw32_new.obj \
 -		ptw32_reuse.obj \
 -		ptw32_rwlock_check_need_init.obj \
 -		ptw32_cond_check_need_init.obj \
 -		ptw32_mutex_check_need_init.obj \
 -		ptw32_semwait.obj \
 -		ptw32_relmillisecs.obj \
 -		sched_get_priority_max.obj \
 -		sched_get_priority_min.obj \
 -		sched_setscheduler.obj \
 -		sched_getscheduler.obj \
 -		sched_yield.obj \
 -		sem_init.obj \
 -		sem_destroy.obj \
 -		sem_trywait.obj \
 -		sem_timedwait.obj \
 -		sem_wait.obj \
 -		sem_post.obj \
 -		sem_post_multiple.obj \
 -		sem_getvalue.obj \
 -		sem_open.obj \
 -		sem_close.obj \
 -		sem_unlink.obj \
 -		signal.obj \
 -		pthread_kill.obj \
 -		ptw32_spinlock_check_need_init.obj \
 -		pthread_spin_init.obj \
 -		pthread_spin_destroy.obj \
 -		pthread_spin_lock.obj \
 -		pthread_spin_unlock.obj \
 -		pthread_spin_trylock.obj \
 -		pthread_detach.obj \
 -		pthread_join.obj \
 -		pthread_key_create.obj \
 -		pthread_key_delete.obj \
 -		pthread_setspecific.obj \
 -		pthread_getspecific.obj \
 -		w32_CancelableWait.obj \
 -		version.res
 -
 -INCL	= config.h implement.h semaphore.h pthread.h need_errno.h
 -
 -ATTR_SRCS	= \
 -		pthread_attr_init.c \
 -		pthread_attr_destroy.c \
 -		pthread_attr_getdetachstate.c \
 -		pthread_attr_setdetachstate.c \
 -		pthread_attr_getstackaddr.c \
 -		pthread_attr_setstackaddr.c \
 -		pthread_attr_getstacksize.c \
 -		pthread_attr_setstacksize.c \
 -		pthread_attr_getscope.c \
 -		pthread_attr_setscope.c
 -
 -BARRIER_SRCS = \
 -		pthread_barrier_init.c \
 -		pthread_barrier_destroy.c \
 -		pthread_barrier_wait.c \
 -		pthread_barrierattr_init.c \
 -		pthread_barrierattr_destroy.c \
 -		pthread_barrierattr_setpshared.c \
 -		pthread_barrierattr_getpshared.c
 -
 -CANCEL_SRCS	= \
 -		pthread_setcancelstate.c \
 -		pthread_setcanceltype.c \
 -		pthread_testcancel.c \
 -		pthread_cancel.c 
 -
 -CONDVAR_SRCS	= \
 -		ptw32_cond_check_need_init.c \
 -		pthread_condattr_destroy.c \
 -		pthread_condattr_getpshared.c \
 -		pthread_condattr_init.c \
 -		pthread_condattr_setpshared.c \
 -		pthread_cond_destroy.c \
 -		pthread_cond_init.c \
 -		pthread_cond_signal.c \
 -		pthread_cond_wait.c
 -
 -EXIT_SRCS	= \
 -		pthread_exit.c
 -
 -MISC_SRCS	= \
 -		pthread_equal.c \
 -		pthread_getconcurrency.c \
 -		pthread_kill.c \
 -		pthread_once.c \
 -		pthread_self.c \
 -		pthread_setconcurrency.c \
 -		ptw32_calloc.c \
 -		ptw32_new.c \
 -		ptw32_reuse.c \
 -		ptw32_relmillisecs.c \
 -		w32_CancelableWait.c
 -
 -MUTEX_SRCS	= \
 -		ptw32_mutex_check_need_init.c \
 -		pthread_mutex_init.c \
 -		pthread_mutex_destroy.c \
 -		pthread_mutexattr_init.c \
 -		pthread_mutexattr_destroy.c \
 -		pthread_mutexattr_getpshared.c \
 -		pthread_mutexattr_setpshared.c \
 -		pthread_mutexattr_settype.c \
 -		pthread_mutexattr_gettype.c \
 -		pthread_mutex_lock.c \
 -		pthread_mutex_timedlock.c \
 -		pthread_mutex_unlock.c \
 -		pthread_mutex_trylock.c
 -
 -NONPORTABLE_SRCS = \
 -		pthread_mutexattr_setkind_np.c \
 -		pthread_mutexattr_getkind_np.c \
 -		pthread_getw32threadhandle_np.c \
 -		pthread_delay_np.c \
 -		pthread_num_processors_np.c \
 -		pthread_win32_attach_detach_np.c \
 -		pthread_timechange_handler_np.c 
 -
 -PRIVATE_SRCS	= \
 -		ptw32_is_attr.c \
 -		ptw32_processInitialize.c \
 -		ptw32_processTerminate.c \
 -		ptw32_threadStart.c \
 -		ptw32_threadDestroy.c \
 -		ptw32_tkAssocCreate.c \
 -		ptw32_tkAssocDestroy.c \
 -		ptw32_callUserDestroyRoutines.c \
 -		ptw32_semwait.c \
 -		ptw32_timespec.c \
 -		ptw32_throw.c \
 -		ptw32_InterlockedCompareExchange.c \
 -		ptw32_getprocessors.c
 -
 -RWLOCK_SRCS	= \
 -		ptw32_rwlock_check_need_init.c \
 -		ptw32_rwlock_cancelwrwait.c \
 -		pthread_rwlock_init.c \
 -		pthread_rwlock_destroy.c \
 -		pthread_rwlockattr_init.c \
 -		pthread_rwlockattr_destroy.c \
 -		pthread_rwlockattr_getpshared.c \
 -		pthread_rwlockattr_setpshared.c \
 -		pthread_rwlock_rdlock.c \
 -		pthread_rwlock_timedrdlock.c \
 -		pthread_rwlock_wrlock.c \
 -		pthread_rwlock_timedwrlock.c \
 -		pthread_rwlock_unlock.c \
 -		pthread_rwlock_tryrdlock.c \
 -		pthread_rwlock_trywrlock.c
 -
 -SCHED_SRCS	= \
 -		pthread_attr_setschedpolicy.c \
 -		pthread_attr_getschedpolicy.c \
 -		pthread_attr_setschedparam.c \
 -		pthread_attr_getschedparam.c \
 -		pthread_attr_setinheritsched.c \
 -		pthread_attr_getinheritsched.c \
 -		pthread_setschedparam.c \
 -		pthread_getschedparam.c \
 -		sched_get_priority_max.c \
 -		sched_get_priority_min.c \
 -		sched_setscheduler.c \
 -		sched_getscheduler.c \
 -		sched_yield.c
 -
 -SEMAPHORE_SRCS = \
 -		sem_init.c \
 -		sem_destroy.c \
 -		sem_trywait.c \
 -		sem_timedwait.c \
 -		sem_wait.c \
 -		sem_post.c \
 -		sem_post_multiple.c \
 -		sem_getvalue.c \
 -		sem_open.c \
 -		sem_close.c \
 -		sem_unlink.c
 -
 -SPIN_SRCS	= \
 -		ptw32_spinlock_check_need_init.c \
 -		pthread_spin_init.c \
 -		pthread_spin_destroy.c \
 -		pthread_spin_lock.c \
 -		pthread_spin_unlock.c \
 -		pthread_spin_trylock.c
 -
 -SYNC_SRCS	= \
 -		pthread_detach.c \
 -		pthread_join.c
 -
 -TSD_SRCS	= \
 -		pthread_key_create.c \
 -		pthread_key_delete.c \
 -		pthread_setspecific.c \
 -		pthread_getspecific.c
 -
 -
 -help:
 -	@ echo Run one of the following command lines:
 -	@ echo nmake clean VCE   (to build the MSVC dll with C++ exception handling)
 -	@ echo nmake clean VSE   (to build the MSVC dll with structured exception handling)
 -	@ echo nmake clean VC    (to build the MSVC dll with C cleanup code)
 -	@ echo nmake clean VCE-inlined   (to build the MSVC inlined dll with C++ exception handling)
 -	@ echo nmake clean VSE-inlined   (to build the MSVC inlined dll with structured exception handling)
 -	@ echo nmake clean VC-inlined    (to build the MSVC inlined dll with C cleanup code)
 -	@ echo nmake clean VC-static     (to build the MSVC static lib with C cleanup code)
 -	@ echo nmake clean VCE-debug   (to build the debug MSVC dll with C++ exception handling)
 -	@ echo nmake clean VSE-debug   (to build the debug MSVC dll with structured exception handling)
 -	@ echo nmake clean VC-debug    (to build the debug MSVC dll with C cleanup code)
 -	@ echo nmake clean VCE-inlined-debug   (to build the debug MSVC inlined dll with C++ exception handling)
 -	@ echo nmake clean VSE-inlined-debug   (to build the debug MSVC inlined dll with structured exception handling)
 -	@ echo nmake clean VC-inlined-debug    (to build the debug MSVC inlined dll with C cleanup code)
 -	@ echo nmake clean VC-static-debug     (to build the debug MSVC static lib with C cleanup code)
 -
 -all:
 -	@ nmake clean VCE-inlined
 -	@ nmake clean VSE-inlined
 -	@ nmake clean VC-inlined
 -	@ nmake clean VCE-inlined-debug
 -	@ nmake clean VSE-inlined-debug
 -	@ nmake clean VC-inlined-debug
 -
 -VCE:
 -	@ nmake /nologo EHFLAGS="$(OPTIM) $(VCEFLAGS)" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VER).dll
 -
 -VCE-debug:
 -	@ nmake /nologo EHFLAGS="$(OPTIMD) $(VCEFLAGSD)" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VERD).dll
 -
 -VSE:
 -	@ nmake /nologo EHFLAGS="$(OPTIM) $(VSEFLAGS)" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VER).dll
 -
 -VSE-debug:
 -	@ nmake /nologo EHFLAGS="$(OPTIMD) $(VSEFLAGSD)" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VERD).dll
 -
 -VC:
 -	@ nmake /nologo EHFLAGS="$(OPTIM) $(VCFLAGS)" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).dll
 -
 -VC-debug:
 -	@ nmake /nologo EHFLAGS="$(OPTIMD) $(VCFLAGSD)" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).dll
 -
 -#
 -# The so-called inlined DLL is just a single translation unit with
 -# inlining optimisation turned on.
 -#
 -VCE-inlined:
 -	@ nmake /nologo EHFLAGS="$(OPTIM) $(VCEFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VER).stamp
 -
 -VCE-inlined-debug:
 -	@ nmake /nologo EHFLAGS="$(OPTIMD) $(VCEFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VERD).stamp
 -
 -VSE-inlined:
 -	@ nmake /nologo EHFLAGS="$(OPTIM) $(VSEFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VER).stamp
 -
 -VSE-inlined-debug:
 -	@ nmake /nologo EHFLAGS="$(OPTIMD) $(VSEFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VERD).stamp
 -
 -VC-inlined:
 -	@ nmake /nologo EHFLAGS="$(OPTIM) $(VCFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).stamp
 -
 -VC-inlined-debug:
 -	nmake /nologo EHFLAGS="$(OPTIMD) $(VCFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).stamp
 -
 -VC-static:
 -	@ nmake /nologo EHFLAGS="$(OPTIM) $(VCFLAGS) /DPTW32_BUILD_INLINED /DPTW32_STATIC_LIB" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).static
 -
 -VC-static-debug:
 -	@ nmake /nologo EHFLAGS="$(OPTIMD) $(VCFLAGSD) /DPTW32_BUILD_INLINED /DPTW32_STATIC_LIB" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).static
 -
 -realclean: clean
 -	if exist pthread*.dll del pthread*.dll
 -	if exist pthread*.lib del pthread*.lib
 -	if exist *.stamp del *.stamp
 -
 -clean:
 -	if exist *.obj del *.obj
 -	if exist *.ilk del *.ilk
 -	if exist *.pdb del *.pdb
 -	if exist *.exp del *.exp
 -	if exist *.map del *.map
 -	if exist *.o del *.o
 -	if exist *.i del *.i
 -	if exist *.res del *.res
 -
 -
 -install: $(DLLS)
 -	copy pthread*.dll $(DLLDEST)
 -	copy pthread*.lib $(LIBDEST)
 -	copy pthread.h $(HDRDEST)
 -	copy sched.h $(HDRDEST)
 -	copy semaphore.h $(HDRDEST)
 -
 -$(DLLS): $(DLL_OBJS)
 -	cl /LDd /Zi /nologo $(DLL_OBJS) \
 -		/link /nodefaultlib:libcmt /implib:$*.lib \
 -		msvcrt.lib wsock32.lib /out:$@
 -
 -$(INLINED_STAMPS): $(DLL_INLINED_OBJS)
 -	cl /LDd /Zi /nologo $(DLL_INLINED_OBJS) \
 -		/link /nodefaultlib:libcmt /implib:$*.lib \
 -		msvcrt.lib wsock32.lib /out:$*.dll
 -
 -$(STATIC_STAMPS): $(DLL_INLINED_OBJS)
 -	if exist $*.lib del $*.lib
 -	lib $(DLL_INLINED_OBJS) /out:$*.lib
 -
 -.c.obj:
 -	cl $(EHFLAGS) /D$(CLEANUP) -c $<
 -
 -.rc.res:
 -	rc /dPTW32_RC_MSC /d$(CLEANUP) $<
 -
 -.c.i:
 -	cl /P /O2 /Ob1 $(VCFLAGS) $<
 -
 -attr.obj:	attr.c $(ATTR_SRCS) $(INCL)
 -barrier.obj:	barrier.c $(BARRIER_SRCS) $(INCL)
 -cancel.obj:	cancel.c $(CANCEL_SRCS) $(INCL)
 -condvar.obj:	condvar.c $(CONDVAR_SRCS) $(INCL)
 -exit.obj:	exit.c $(EXIT_SRCS) $(INCL)
 -misc.obj:	misc.c $(MISC_SRCS) $(INCL)
 -mutex.obj:	mutex.c $(MUTEX_SRCS) $(INCL)
 -nonportable.obj:	nonportable.c $(NONPORTABLE_SRCS) $(INCL)
 -private.obj:	private.c $(PRIVATE_SRCS) $(INCL)
 -rwlock.obj:	rwlock.c $(RWLOCK_SRCS) $(INCL)
 -sched.obj:	sched.c $(SCHED_SRCS) $(INCL)
 -semaphore.obj:	semaphore.c $(SEMAPHORE_SRCS) $(INCL)
 -spin.obj:	spin.c $(SPIN_SRCS) $(INCL)
 -sync.obj:	sync.c $(SYNC_SRCS) $(INCL)
 -tsd.obj:	tsd.c $(TSD_SRCS) $(INCL)
 -version.res:	version.rc $(INCL)
 +# This makefile is compatible with MS nmake and can be used as a +# replacement for buildlib.bat. I've changed the target from an ordinary dll +# (/LD) to a debugging dll (/LDd). +#  +# The variables $DLLDEST and $LIBDEST hold the destination directories for the +# dll and the lib, respectively. Probably all that needs to change is $DEVROOT. + + +# DLL_VER: +# See pthread.h and README - This number is computed as 'current - age' +DLL_VER	= 2 +DLL_VERD= $(DLL_VER)d + +DEVROOT	= C:\pthreads + +DLLDEST	= $(DEVROOT)\DLL +LIBDEST	= $(DEVROOT)\LIB +HDRDEST	= $(DEVROOT)\INCLUDE + +DLLS	= pthreadVCE$(DLL_VER).dll pthreadVSE$(DLL_VER).dll pthreadVC$(DLL_VER).dll \ +		  pthreadVCE$(DLL_VERD).dll pthreadVSE$(DLL_VERD).dll pthreadVC$(DLL_VERD).dll +INLINED_STAMPS	= pthreadVCE$(DLL_VER).stamp pthreadVSE$(DLL_VER).stamp pthreadVC$(DLL_VER).stamp \ +				  pthreadVCE$(DLL_VERD).stamp pthreadVSE$(DLL_VERD).stamp pthreadVC$(DLL_VERD).stamp +STATIC_STAMPS	= pthreadVCE$(DLL_VER).static pthreadVSE$(DLL_VER).static pthreadVC$(DLL_VER).static \ +				  pthreadVCE$(DLL_VERD).static pthreadVSE$(DLL_VERD).static pthreadVC$(DLL_VERD).static + +OPTIM	= /O2 /Ob2 +OPTIMD	= + +CFLAGS	= /W3 /MD /nologo /Yd /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H +CFLAGSD	= /Zi $(CFLAGS) + + +# Default cleanup style +CLEANUP	= __CLEANUP_C + +# C++ Exceptions +VCEFLAGS	= /GX /TP $(CFLAGS) +VCEFLAGSD	= /GX /TP $(CFLAGSD) +#Structured Exceptions +VSEFLAGS	= $(CFLAGS) +VSEFLAGSD	= $(CFLAGSD) +#C cleanup code +VCFLAGS	= $(CFLAGS) +VCFLAGSD= $(CFLAGSD) + +DLL_INLINED_OBJS = \ +		pthread.obj \ +		version.res + +# Aggregate modules for inlinability +DLL_OBJS	= \ +		attr.obj \ +		barrier.obj \ +		cancel.obj \ +		cleanup.obj \ +		condvar.obj \ +		create.obj \ +		dll.obj \ +		errno.obj \ +		exit.obj \ +		fork.obj \ +		global.obj \ +		misc.obj \ +		mutex.obj \ +		nonportable.obj \ +		private.obj \ +		rwlock.obj \ +		sched.obj \ +		semaphore.obj \ +		signal.obj \ +		spin.obj \ +		sync.obj \ +		tsd.obj \ +		version.res + +# Separate modules for minimising the size of statically linked images +SMALL_STATIC_OBJS	= \ +		pthread_attr_init.obj \ +		pthread_attr_destroy.obj \ +		pthread_attr_getdetachstate.obj \ +		pthread_attr_setdetachstate.obj \ +		pthread_attr_getstackaddr.obj \ +		pthread_attr_setstackaddr.obj \ +		pthread_attr_getstacksize.obj \ +		pthread_attr_setstacksize.obj \ +		pthread_attr_getscope.obj \ +		pthread_attr_setscope.obj \ +		pthread_attr_setschedpolicy.obj \ +		pthread_attr_getschedpolicy.obj \ +		pthread_attr_setschedparam.obj \ +		pthread_attr_getschedparam.obj \ +		pthread_attr_setinheritsched.obj \ +		pthread_attr_getinheritsched.obj \ +		pthread_barrier_init.obj \ +		pthread_barrier_destroy.obj \ +		pthread_barrier_wait.obj \ +		pthread_barrierattr_init.obj \ +		pthread_barrierattr_destroy.obj \ +		pthread_barrierattr_setpshared.obj \ +		pthread_barrierattr_getpshared.obj \ +		pthread_setcancelstate.obj \ +		pthread_setcanceltype.obj \ +		pthread_testcancel.obj \ +		pthread_cancel.obj \ +		cleanup.obj \ +		pthread_condattr_destroy.obj \ +		pthread_condattr_getpshared.obj \ +		pthread_condattr_init.obj \ +		pthread_condattr_setpshared.obj \ +		pthread_cond_destroy.obj \ +		pthread_cond_init.obj \ +		pthread_cond_signal.obj \ +		pthread_cond_wait.obj \ +		create.obj \ +		dll.obj \ +		errno.obj \ +		pthread_exit.obj \ +		fork.obj \ +		global.obj \ +		pthread_mutex_init.obj \ +		pthread_mutex_destroy.obj \ +		pthread_mutexattr_init.obj \ +		pthread_mutexattr_destroy.obj \ +		pthread_mutexattr_getpshared.obj \ +		pthread_mutexattr_setpshared.obj \ +		pthread_mutexattr_settype.obj \ +		pthread_mutexattr_gettype.obj \ +		pthread_mutex_lock.obj \ +		pthread_mutex_timedlock.obj \ +		pthread_mutex_unlock.obj \ +		pthread_mutex_trylock.obj \ +		pthread_mutexattr_setkind_np.obj \ +		pthread_mutexattr_getkind_np.obj \ +		pthread_getw32threadhandle_np.obj \ +		pthread_delay_np.obj \ +		pthread_num_processors_np.obj \ +		pthread_win32_attach_detach_np.obj \ +		pthread_equal.obj \ +		pthread_getconcurrency.obj \ +		pthread_once.obj \ +		pthread_self.obj \ +		pthread_setconcurrency.obj \ +		pthread_rwlock_init.obj \ +		pthread_rwlock_destroy.obj \ +		pthread_rwlockattr_init.obj \ +		pthread_rwlockattr_destroy.obj \ +		pthread_rwlockattr_getpshared.obj \ +		pthread_rwlockattr_setpshared.obj \ +		pthread_rwlock_rdlock.obj \ +		pthread_rwlock_wrlock.obj \ +		pthread_rwlock_unlock.obj \ +		pthread_rwlock_tryrdlock.obj \ +		pthread_rwlock_trywrlock.obj \ +		pthread_setschedparam.obj \ +		pthread_getschedparam.obj \ +		pthread_timechange_handler_np.obj \ +		ptw32_is_attr.obj \ +		ptw32_processInitialize.obj \ +		ptw32_processTerminate.obj \ +		ptw32_threadStart.obj \ +		ptw32_threadDestroy.obj \ +		ptw32_tkAssocCreate.obj \ +		ptw32_tkAssocDestroy.obj \ +		ptw32_callUserDestroyRoutines.obj \ +		ptw32_timespec.obj \ +		ptw32_throw.obj \ +		ptw32_InterlockedCompareExchange.obj \ +		ptw32_getprocessors.obj \ +		ptw32_calloc.obj \ +		ptw32_new.obj \ +		ptw32_reuse.obj \ +		ptw32_rwlock_check_need_init.obj \ +		ptw32_cond_check_need_init.obj \ +		ptw32_mutex_check_need_init.obj \ +		ptw32_semwait.obj \ +		ptw32_relmillisecs.obj \ +		sched_get_priority_max.obj \ +		sched_get_priority_min.obj \ +		sched_setscheduler.obj \ +		sched_getscheduler.obj \ +		sched_yield.obj \ +		sem_init.obj \ +		sem_destroy.obj \ +		sem_trywait.obj \ +		sem_timedwait.obj \ +		sem_wait.obj \ +		sem_post.obj \ +		sem_post_multiple.obj \ +		sem_getvalue.obj \ +		sem_open.obj \ +		sem_close.obj \ +		sem_unlink.obj \ +		signal.obj \ +		pthread_kill.obj \ +		ptw32_spinlock_check_need_init.obj \ +		pthread_spin_init.obj \ +		pthread_spin_destroy.obj \ +		pthread_spin_lock.obj \ +		pthread_spin_unlock.obj \ +		pthread_spin_trylock.obj \ +		pthread_detach.obj \ +		pthread_join.obj \ +		pthread_key_create.obj \ +		pthread_key_delete.obj \ +		pthread_setspecific.obj \ +		pthread_getspecific.obj \ +		w32_CancelableWait.obj \ +		version.res + +INCL	= config.h implement.h semaphore.h pthread.h need_errno.h + +ATTR_SRCS	= \ +		pthread_attr_init.c \ +		pthread_attr_destroy.c \ +		pthread_attr_getdetachstate.c \ +		pthread_attr_setdetachstate.c \ +		pthread_attr_getstackaddr.c \ +		pthread_attr_setstackaddr.c \ +		pthread_attr_getstacksize.c \ +		pthread_attr_setstacksize.c \ +		pthread_attr_getscope.c \ +		pthread_attr_setscope.c + +BARRIER_SRCS = \ +		pthread_barrier_init.c \ +		pthread_barrier_destroy.c \ +		pthread_barrier_wait.c \ +		pthread_barrierattr_init.c \ +		pthread_barrierattr_destroy.c \ +		pthread_barrierattr_setpshared.c \ +		pthread_barrierattr_getpshared.c + +CANCEL_SRCS	= \ +		pthread_setcancelstate.c \ +		pthread_setcanceltype.c \ +		pthread_testcancel.c \ +		pthread_cancel.c  + +CONDVAR_SRCS	= \ +		ptw32_cond_check_need_init.c \ +		pthread_condattr_destroy.c \ +		pthread_condattr_getpshared.c \ +		pthread_condattr_init.c \ +		pthread_condattr_setpshared.c \ +		pthread_cond_destroy.c \ +		pthread_cond_init.c \ +		pthread_cond_signal.c \ +		pthread_cond_wait.c + +EXIT_SRCS	= \ +		pthread_exit.c + +MISC_SRCS	= \ +		pthread_equal.c \ +		pthread_getconcurrency.c \ +		pthread_kill.c \ +		pthread_once.c \ +		pthread_self.c \ +		pthread_setconcurrency.c \ +		ptw32_calloc.c \ +		ptw32_new.c \ +		ptw32_reuse.c \ +		ptw32_relmillisecs.c \ +		w32_CancelableWait.c + +MUTEX_SRCS	= \ +		ptw32_mutex_check_need_init.c \ +		pthread_mutex_init.c \ +		pthread_mutex_destroy.c \ +		pthread_mutexattr_init.c \ +		pthread_mutexattr_destroy.c \ +		pthread_mutexattr_getpshared.c \ +		pthread_mutexattr_setpshared.c \ +		pthread_mutexattr_settype.c \ +		pthread_mutexattr_gettype.c \ +		pthread_mutex_lock.c \ +		pthread_mutex_timedlock.c \ +		pthread_mutex_unlock.c \ +		pthread_mutex_trylock.c + +NONPORTABLE_SRCS = \ +		pthread_mutexattr_setkind_np.c \ +		pthread_mutexattr_getkind_np.c \ +		pthread_getw32threadhandle_np.c \ +		pthread_delay_np.c \ +		pthread_num_processors_np.c \ +		pthread_win32_attach_detach_np.c \ +		pthread_timechange_handler_np.c  + +PRIVATE_SRCS	= \ +		ptw32_is_attr.c \ +		ptw32_processInitialize.c \ +		ptw32_processTerminate.c \ +		ptw32_threadStart.c \ +		ptw32_threadDestroy.c \ +		ptw32_tkAssocCreate.c \ +		ptw32_tkAssocDestroy.c \ +		ptw32_callUserDestroyRoutines.c \ +		ptw32_semwait.c \ +		ptw32_timespec.c \ +		ptw32_throw.c \ +		ptw32_InterlockedCompareExchange.c \ +		ptw32_getprocessors.c + +RWLOCK_SRCS	= \ +		ptw32_rwlock_check_need_init.c \ +		ptw32_rwlock_cancelwrwait.c \ +		pthread_rwlock_init.c \ +		pthread_rwlock_destroy.c \ +		pthread_rwlockattr_init.c \ +		pthread_rwlockattr_destroy.c \ +		pthread_rwlockattr_getpshared.c \ +		pthread_rwlockattr_setpshared.c \ +		pthread_rwlock_rdlock.c \ +		pthread_rwlock_timedrdlock.c \ +		pthread_rwlock_wrlock.c \ +		pthread_rwlock_timedwrlock.c \ +		pthread_rwlock_unlock.c \ +		pthread_rwlock_tryrdlock.c \ +		pthread_rwlock_trywrlock.c + +SCHED_SRCS	= \ +		pthread_attr_setschedpolicy.c \ +		pthread_attr_getschedpolicy.c \ +		pthread_attr_setschedparam.c \ +		pthread_attr_getschedparam.c \ +		pthread_attr_setinheritsched.c \ +		pthread_attr_getinheritsched.c \ +		pthread_setschedparam.c \ +		pthread_getschedparam.c \ +		sched_get_priority_max.c \ +		sched_get_priority_min.c \ +		sched_setscheduler.c \ +		sched_getscheduler.c \ +		sched_yield.c + +SEMAPHORE_SRCS = \ +		sem_init.c \ +		sem_destroy.c \ +		sem_trywait.c \ +		sem_timedwait.c \ +		sem_wait.c \ +		sem_post.c \ +		sem_post_multiple.c \ +		sem_getvalue.c \ +		sem_open.c \ +		sem_close.c \ +		sem_unlink.c + +SPIN_SRCS	= \ +		ptw32_spinlock_check_need_init.c \ +		pthread_spin_init.c \ +		pthread_spin_destroy.c \ +		pthread_spin_lock.c \ +		pthread_spin_unlock.c \ +		pthread_spin_trylock.c + +SYNC_SRCS	= \ +		pthread_detach.c \ +		pthread_join.c + +TSD_SRCS	= \ +		pthread_key_create.c \ +		pthread_key_delete.c \ +		pthread_setspecific.c \ +		pthread_getspecific.c + + +help: +	@ echo Run one of the following command lines: +	@ echo nmake clean VCE   (to build the MSVC dll with C++ exception handling) +	@ echo nmake clean VSE   (to build the MSVC dll with structured exception handling) +	@ echo nmake clean VC    (to build the MSVC dll with C cleanup code) +	@ echo nmake clean VCE-inlined   (to build the MSVC inlined dll with C++ exception handling) +	@ echo nmake clean VSE-inlined   (to build the MSVC inlined dll with structured exception handling) +	@ echo nmake clean VC-inlined    (to build the MSVC inlined dll with C cleanup code) +	@ echo nmake clean VC-static     (to build the MSVC static lib with C cleanup code) +	@ echo nmake clean VCE-debug   (to build the debug MSVC dll with C++ exception handling) +	@ echo nmake clean VSE-debug   (to build the debug MSVC dll with structured exception handling) +	@ echo nmake clean VC-debug    (to build the debug MSVC dll with C cleanup code) +	@ echo nmake clean VCE-inlined-debug   (to build the debug MSVC inlined dll with C++ exception handling) +	@ echo nmake clean VSE-inlined-debug   (to build the debug MSVC inlined dll with structured exception handling) +	@ echo nmake clean VC-inlined-debug    (to build the debug MSVC inlined dll with C cleanup code) +	@ echo nmake clean VC-static-debug     (to build the debug MSVC static lib with C cleanup code) + +all: +	@ nmake clean VCE-inlined +	@ nmake clean VSE-inlined +	@ nmake clean VC-inlined +	@ nmake clean VCE-inlined-debug +	@ nmake clean VSE-inlined-debug +	@ nmake clean VC-inlined-debug + +VCE: +	@ nmake /nologo EHFLAGS="$(OPTIM) $(VCEFLAGS)" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VER).dll + +VCE-debug: +	@ nmake /nologo EHFLAGS="$(OPTIMD) $(VCEFLAGSD)" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VERD).dll + +VSE: +	@ nmake /nologo EHFLAGS="$(OPTIM) $(VSEFLAGS)" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VER).dll + +VSE-debug: +	@ nmake /nologo EHFLAGS="$(OPTIMD) $(VSEFLAGSD)" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VERD).dll + +VC: +	@ nmake /nologo EHFLAGS="$(OPTIM) $(VCFLAGS)" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).dll + +VC-debug: +	@ nmake /nologo EHFLAGS="$(OPTIMD) $(VCFLAGSD)" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).dll + +# +# The so-called inlined DLL is just a single translation unit with +# inlining optimisation turned on. +# +VCE-inlined: +	@ nmake /nologo EHFLAGS="$(OPTIM) $(VCEFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VER).stamp + +VCE-inlined-debug: +	@ nmake /nologo EHFLAGS="$(OPTIMD) $(VCEFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VERD).stamp + +VSE-inlined: +	@ nmake /nologo EHFLAGS="$(OPTIM) $(VSEFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VER).stamp + +VSE-inlined-debug: +	@ nmake /nologo EHFLAGS="$(OPTIMD) $(VSEFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VERD).stamp + +VC-inlined: +	@ nmake /nologo EHFLAGS="$(OPTIM) $(VCFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).stamp + +VC-inlined-debug: +	nmake /nologo EHFLAGS="$(OPTIMD) $(VCFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).stamp + +VC-static: +	@ nmake /nologo EHFLAGS="$(OPTIM) $(VCFLAGS) /DPTW32_BUILD_INLINED /DPTW32_STATIC_LIB" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).static + +VC-static-debug: +	@ nmake /nologo EHFLAGS="$(OPTIMD) $(VCFLAGSD) /DPTW32_BUILD_INLINED /DPTW32_STATIC_LIB" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).static + +realclean: clean +	if exist pthread*.dll del pthread*.dll +	if exist pthread*.lib del pthread*.lib +	if exist *.stamp del *.stamp + +clean: +	if exist *.obj del *.obj +	if exist *.ilk del *.ilk +	if exist *.pdb del *.pdb +	if exist *.exp del *.exp +	if exist *.map del *.map +	if exist *.o del *.o +	if exist *.i del *.i +	if exist *.res del *.res + + +install: $(DLLS) +	copy pthread*.dll $(DLLDEST) +	copy pthread*.lib $(LIBDEST) +	copy pthread.h $(HDRDEST) +	copy sched.h $(HDRDEST) +	copy semaphore.h $(HDRDEST) + +$(DLLS): $(DLL_OBJS) +	cl /LDd /Zi /nologo $(DLL_OBJS) \ +		/link /nodefaultlib:libcmt /implib:$*.lib \ +		msvcrt.lib wsock32.lib /out:$@ + +$(INLINED_STAMPS): $(DLL_INLINED_OBJS) +	cl /LDd /Zi /nologo $(DLL_INLINED_OBJS) \ +		/link /nodefaultlib:libcmt /implib:$*.lib \ +		msvcrt.lib wsock32.lib /out:$*.dll + +$(STATIC_STAMPS): $(DLL_INLINED_OBJS) +	if exist $*.lib del $*.lib +	lib $(DLL_INLINED_OBJS) /out:$*.lib + +.c.obj: +	cl $(EHFLAGS) /D$(CLEANUP) -c $< + +.rc.res: +	rc /dPTW32_RC_MSC /d$(CLEANUP) $< + +.c.i: +	cl /P /O2 /Ob1 $(VCFLAGS) $< + +attr.obj:	attr.c $(ATTR_SRCS) $(INCL) +barrier.obj:	barrier.c $(BARRIER_SRCS) $(INCL) +cancel.obj:	cancel.c $(CANCEL_SRCS) $(INCL) +condvar.obj:	condvar.c $(CONDVAR_SRCS) $(INCL) +exit.obj:	exit.c $(EXIT_SRCS) $(INCL) +misc.obj:	misc.c $(MISC_SRCS) $(INCL) +mutex.obj:	mutex.c $(MUTEX_SRCS) $(INCL) +nonportable.obj:	nonportable.c $(NONPORTABLE_SRCS) $(INCL) +private.obj:	private.c $(PRIVATE_SRCS) $(INCL) +rwlock.obj:	rwlock.c $(RWLOCK_SRCS) $(INCL) +sched.obj:	sched.c $(SCHED_SRCS) $(INCL) +semaphore.obj:	semaphore.c $(SEMAPHORE_SRCS) $(INCL) +spin.obj:	spin.c $(SPIN_SRCS) $(INCL) +sync.obj:	sync.c $(SYNC_SRCS) $(INCL) +tsd.obj:	tsd.c $(TSD_SRCS) $(INCL) +version.res:	version.rc $(INCL) @@ -1,886 +1,886 @@ -RELEASE 2.3.0
 --------------
 -(2005-04-12)
 -
 -General
 --------
 -
 -Release 1.7.0 is a backport of features and bug fixes new in
 -this release. See earlier notes under Release 2.0.0/General.
 -
 -Bugs fixed
 -----------
 -
 -* Fixed pthread_once potential for post once_routine cancellation
 -hanging due to starvation. See comments in pthread_once.c.
 -Momentary priority boosting is used to ensure that, after a
 -once_routine is cancelled, the thread that will run the
 -once_routine is not starved by higher priority waiting threads at
 -critical times. Priority boosting occurs only AFTER a once_routine 
 -cancellation, and is applied only to that once_control. The
 -once_routine is run at the thread's normal base priority.
 -
 -New tests
 ----------
 -
 -* once4.c: Aggressively tests pthread_once() under realtime
 -conditions using threads with varying priorities. Windows'
 -random priority boosting does not occur for threads with realtime
 -priority levels.
 -
 -
 -RELEASE 2.2.0
 --------------
 -(2005-04-04)
 -
 -General
 --------
 -
 -* Added makefile targets to build static link versions of the library.
 -Both MinGW and MSVC. Please note that this does not imply any change
 -to the LGPL licensing, which still imposes psecific conditions on
 -distributing software that has been statically linked with this library.
 -
 -* There is a known bug in pthread_once(). Cancellation of the init_routine
 -exposes a potential starvation (i.e. deadlock) problem if a waiting thread
 -has a higher priority than the initting thread. This problem will be fixed
 -in version 3.0.0 of the library.
 -
 -Bugs fixed
 -----------
 -
 -* Fix integer overrun error in sem_timedwait().
 -Kevin Lussier
 -
 -* Fix preprocessor directives for static linking.
 -Dimitar Panayotov
 -
 -
 -RELEASE 2.1.0
 --------------
 -(2005-03-16)
 -
 -Bugs fixed
 -----------
 -
 -* Reverse change to pthread_setcancelstate() in 2.0.0.
 -
 -
 -RELEASE 2.0.0
 --------------
 -(2005-03-16)
 -
 -General
 --------
 -
 -This release represents an ABI change and the DLL version naming has
 -incremented from 1 to 2, e.g. pthreadVC2.dll.
 -
 -Version 1.4.0 back-ports the new functionality included in this
 -release. Please distribute DLLs built from that version with updates
 -to applications built on pthreads-win32 version 1.x.x.
 -
 -The package naming has changed, replacing the snapshot date with 
 -the version number + descriptive information. E.g. this
 -release is "pthreads-w32-2-0-0-release".
 -
 -Bugs fixed
 -----------
 -
 -* pthread_setcancelstate() no longer checks for a pending
 -async cancel event if the library is using alertable async
 -cancel. See the README file (Prerequisites section) for info
 -on adding alertable async cancelation.
 -
 -New features
 -------------
 -
 -* pthread_once() now supports init_routine cancellability.
 -
 -New tests
 ----------
 -
 -* Agressively test pthread_once() init_routine cancellability.
 -
 -
 -SNAPSHOT 2005-03-08
 --------------------
 -Version 1.3.0
 -
 -Bug reports (fixed)
 --------------------
 -
 -* Implicitly created threads leave Win32 handles behind after exiting.
 -- Dmitrii Semii
 -
 -* pthread_once() starvation problem.
 -- Gottlob Frege
 -
 -New tests
 ----------
 -
 -* More intense testing of pthread_once().
 -
 -
 -SNAPSHOT 2005-01-25
 --------------------
 -Version 1.2.0
 -
 -Bug fixes
 ----------
 -
 -* Attempted acquisition of a recursive mutex could cause waiting threads
 -to not be woken when the mutex was released.
 -- Ralf Kubis  <RKubis at mc.com>
 -
 -* Various package omissions have been fixed.
 -
 -
 -SNAPSHOT 2005-01-03
 --------------------
 -Version 1.1.0
 -
 -Bug fixes
 ----------
 -
 -* Unlocking recursive or errorcheck mutexes would sometimes
 -unexpectedly return an EPERM error (bug introduced in
 -snapshot-2004-11-03).
 -- Konstantin Voronkov  <beowinkle at yahoo.com>
 -
 -
 -SNAPSHOT 2004-11-22
 --------------------
 -Version 1.0.0
 -
 -This snapshot primarily fixes the condvar bug introduced in
 -snapshot-2004-11-03. DLL versioning has also been included to allow
 -applications to runtime check the Microsoft compatible DLL version
 -information, and to extend the DLL naming system for ABI and major
 -(non-backward compatible) API changes. See the README file for details.
 -
 -Bug fixes
 ----------
 -
 -* Condition variables no longer deadlock (bug introduced in
 -snapshot-2004-11-03).
 -- Alexander Kotliarov and Nicolas at saintmac
 -
 -* DLL naming extended to avoid 'DLL hell' in the future, and to
 -accommodate the ABI change introduced in snapshot-2004-11-03. Snapshot
 -2004-11-03 will be removed from FTP sites.
 -
 -New features
 -------------
 -
 -* A Microsoft-style version resource has been added to the DLL for
 -applications that wish to check DLL compatibility at runtime.
 -
 -* Pthreads-win32 DLL naming has been extended to allow incompatible DLL
 -versions to co-exist in the same filesystem. See the README file for details,
 -but briefly: while the version information inside the DLL will change with
 -each release from now on, the DLL version names will only change if the new
 -DLL is not backward compatible with older applications.
 -
 -The versioning scheme has been borrowed from GNU Libtool, and the DLL
 -naming scheme is from Cygwin. Provided the Libtool-style numbering rules are
 -honoured, the Cygwin DLL naming scheme automatcally ensures that DLL name
 -changes are minimal and that applications will not load an incompatible
 -pthreads-win32 DLL.
 -
 -Those who use the pre-built DLLs will find that the DLL/LIB names have a new
 -suffix (1) in this snapshot. E.g. pthreadVC1.dll etc.
 -
 -* The POSIX thread ID reuse uniqueness feature introduced in the last snapshot
 -has been kept as default, but the behaviour can now be controlled when the DLL
 -is built to effectively switch it off. This makes the library much more
 -sensitive to applications that assume that POSIX thread IDs are unique, i.e.
 -are not strictly compliant with POSIX. See the PTW32_THREAD_ID_REUSE_INCREMENT
 -macro comments in config.h for details.
 -
 -Other changes
 --------------
 -Certain POSIX macros have changed.
 -
 -These changes are intended to conform to the Single Unix Specification version 3,
 -which states that, if set to 0 (zero) or not defined, then applications may use
 -sysconf() to determine their values at runtime. Pthreads-win32 does not
 -implement sysconf().
 -
 -The following macros are no longer undefined, but defined and set to -1
 -(not implemented):
 -
 -      _POSIX_THREAD_ATTR_STACKADDR
 -      _POSIX_THREAD_PRIO_INHERIT
 -      _POSIX_THREAD_PRIO_PROTECT
 -      _POSIX_THREAD_PROCESS_SHARED
 -
 -The following macros are defined and set to 200112L (implemented):
 -
 -      _POSIX_THREADS
 -      _POSIX_THREAD_SAFE_FUNCTIONS
 -      _POSIX_THREAD_ATTR_STACKSIZE
 -      _POSIX_THREAD_PRIORITY_SCHEDULING
 -      _POSIX_SEMAPHORES
 -      _POSIX_READER_WRITER_LOCKS
 -      _POSIX_SPIN_LOCKS
 -      _POSIX_BARRIERS
 -
 -The following macros are defined and set to appropriate values:
 -
 -      _POSIX_THREAD_THREADS_MAX
 -      _POSIX_SEM_VALUE_MAX
 -      _POSIX_SEM_NSEMS_MAX
 -      PTHREAD_DESTRUCTOR_ITERATIONS
 -      PTHREAD_KEYS_MAX
 -      PTHREAD_STACK_MIN
 -      PTHREAD_THREADS_MAX
 -
 -
 -SNAPSHOT 2004-11-03
 --------------------
 -
 -DLLs produced from this snapshot cannot be used with older applications without
 -recompiling the application, due to a change to pthread_t to provide unique POSIX
 -thread IDs.
 -
 -Although this snapshot passes the extended test suite, many of the changes are
 -fairly major, and some applications may show different behaviour than previously,
 -so adopt with care. Hopefully, any changed behaviour will be due to the library
 -being better at it's job, not worse.
 -
 -Bug fixes
 ----------
 -
 -* pthread_create() no longer accepts NULL as the thread reference arg.
 -A segfault (memory access fault) will result, and no thread will be
 -created.
 -
 -* pthread_barrier_wait() no longer acts as a cancelation point.
 -
 -* Fix potential race condition in pthread_once()
 -- Tristan Savatier  <tristan at mpegtv.com>
 -
 -* Changes to pthread_cond_destroy() exposed some coding weaknesses in several
 -test suite mini-apps because pthread_cond_destroy() now returns EBUSY if the CV
 -is still in use.
 -
 -New features
 -------------
 -
 -* Added for compatibility:
 -PTHREAD_RECURSIVE_MUTEX_INITIALIZER,
 -PTHREAD_ERRORCHECK_MUTEX_INITIALIZER,
 -PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
 -PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
 -
 -* Initial support for Digital Mars compiler
 -- Anuj Goyal  <anuj.goyal at gmail.com>
 -
 -* Faster Mutexes. These have been been rewritten following a model provided by
 -Alexander Terekhov that reduces kernel space checks, and eliminates some additional
 -critical sections used to manage a race between timedlock expiration and unlock.
 -Please be aware that the new mutexes do not enforce strict absolute FIFO scheduling
 -of mutexes, however any out-of-order lock acquisition should be very rare.
 -
 -* Faster semaphores. Following a similar model to mutexes above, these have been
 -rewritten to use preliminary users space checks.
 -
 -* sem_getvalue() now returns the number of waiters.
 -
 -* The POSIX thread ID now has much stronger uniqueness characteristics. The library
 -garrantees not to reuse the same thread ID for at least 2^(wordsize) thread
 -destruction/creation cycles.
 -
 -New tests
 ----------
 -
 -* semaphore4.c: Tests cancelation of the new sem_wait().
 -
 -* semaphore4t.c: Likewise for sem_timedwait().
 -
 -* rwlock8.c: Tests and times the slow execution paths of r/w locks, and the CVs,
 -mutexes, and semaphores that they're built on.
 -
 -
 -SNAPSHOT 2004-05-16
 --------------------
 -
 -Attempt to add Watcom to the list of compilers that can build the library.
 -This failed in the end due to it's non-thread-aware errno. The library
 -builds but the test suite fails. See README.Watcom for more details.
 -
 -Bug fixes
 ----------
 -* Bug and memory leak in sem_init()
 -- Alex Blanco  <Alex.Blanco at motorola.com>
 -
 -* ptw32_getprocessors() now returns CPU count of 1 for WinCE.
 -- James Ewing  <james.ewing at sveasoft.com>
 -
 -* pthread_cond_wait() could be canceled at a point where it should not
 -be cancelable. Fixed.
 -- Alexander Terekhov  <TEREKHOV at de.ibm.com>
 -
 -* sem_timedwait() had an incorrect timeout calculation.
 -- Philippe Di Cristo  <philipped at voicebox.com>
 -
 -* Fix a memory leak left behind after threads are destroyed.
 -- P. van Bruggen  <pietvb at newbridges.nl>
 -
 -New features
 -------------
 -* Ported to AMD64.
 -- Makoto Kato  <raven at oldskool.jp>
 -
 -* True pre-emptive asynchronous cancelation of threads. This is optional
 -and requires that Panagiotis E. Hadjidoukas's QueueUserAPCEx package be
 -installed. This package is included in the pthreads-win32 self-unpacking
 -Zip archive starting from this snapshot. See the README.txt file inside
 -the package for installation details.
 -
 -Note: If you don't use async cancelation in your application, or don't need
 -to cancel threads that are blocked on system resources such as network I/O,
 -then the default non-preemptive async cancelation is probably good enough.
 -However, pthreads-win32 auto-detects the availability of these components
 -at run-time, so you don't need to rebuild the library from source if you
 -change your mind later.
 -
 -All of the advice available in books and elsewhere on the undesirability
 -of using async cancelation in any application still stands, but this
 -feature is a welcome addition with respect to the library's conformance to
 -the POSIX standard.
 -
 -SNAPSHOT 2003-09-18
 --------------------
 -
 -Cleanup of thread priority management. In particular, setting of thread
 -priority now attempts to map invalid Win32 values within the range returned
 -by sched_get_priority_min/max() to useful values. See README.NONPORTABLE
 -under "Thread priority".
 -
 -Bug fixes
 ----------
 -* pthread_getschedparam() now returns the priority given by the most recent
 -call to pthread_setschedparam() or established by pthread_create(), as
 -required by the standard. Previously, pthread_getschedparam() incorrectly
 -returned the running thread priority at the time of the call, which may have
 -been adjusted or temporarily promoted/demoted.
 -
 -* sched_get_priority_min() and sched_get_priority_max() now return -1 on error
 -and set errno. Previously, they incorrectly returned the error value directly.
 -
 -
 -SNAPSHOT 2003-09-04
 --------------------
 -
 -Bug fixes
 ----------
 -* ptw32_cancelableWait() now allows cancelation of waiting implicit POSIX
 -threads.
 -
 -New test
 ---------
 -* cancel8.c tests cancelation of Win32 threads waiting at a POSIX cancelation
 -point.
 -
 -
 -SNAPSHOT 2003-09-03
 --------------------
 -
 -Bug fixes
 ----------
 -* pthread_self() would free the newly created implicit POSIX thread handle if
 -DuplicateHandle failed instead of recycle it (very unlikely).
 -
 -* pthread_exit() was neither freeing nor recycling the POSIX thread struct
 -for implicit POSIX threads.
 -
 -New feature - Cancelation of/by Win32 (non-POSIX) threads
 ----------------------------------------------------------
 -Since John Bossom's original implementation, the library has allowed non-POSIX
 -initialised threads (Win32 threads) to call pthreads-win32 routines and
 -therefore interact with POSIX threads. This is done by creating an on-the-fly
 -POSIX thread ID for the Win32 thread that, once created, allows fully
 -reciprical interaction. This did not extend to thread cancelation (async or
 -deferred). Now it does.
 -
 -Any thread can be canceled by any other thread (Win32 or POSIX) if the former
 -thread's POSIX pthread_t value is known. It's TSD destructors and POSIX
 -cleanup handlers will be run before the thread exits with an exit code of
 -PTHREAD_CANCELED (retrieved with GetExitCodeThread()).
 -
 -This allows a Win32 thread to, for example, call POSIX CV routines in the same way
 -that POSIX threads would/should, with pthread_cond_wait() cancelability and
 -cleanup handlers (pthread_cond_wait() is a POSIX cancelation point).
 -
 -By adding cancelation, Win32 threads should now be able to call all POSIX
 -threads routines that make sense including semaphores, mutexes, condition
 -variables, read/write locks, barriers, spinlocks, tsd, cleanup push/pop,
 -cancelation, pthread_exit, scheduling, etc.
 -
 -Note that these on-the-fly 'implicit' POSIX thread IDs are initialised as detached
 -(not joinable) with deferred cancelation type. The POSIX thread ID will be created
 -automatically by any POSIX routines that need a POSIX handle (unless the routine
 -needs a pthread_t as a parameter of course). A Win32 thread can discover it's own
 -POSIX thread ID by calling pthread_self(), which will create the handle if
 -necessary and return the pthread_t value.
 -
 -New tests
 ----------
 -Test the above new feature.
 -
 -
 -SNAPSHOT 2003-08-19
 --------------------
 -
 -This snapshot fixes some accidental corruption to new test case sources.
 -There are no changes to the library source code.
 -
 -
 -SNAPSHOT 2003-08-15
 --------------------
 -
 -Bug fixes
 ----------
 -
 -* pthread.dsp now uses correct compile flags (/MD).
 -- Viv  <vcotirlea@hotmail.com>
 -
 -* pthread_win32_process_detach_np() fixed memory leak.
 -- Steven Reddie  <Steven.Reddie@ca.com>
 -
 -* pthread_mutex_destroy() fixed incorrect return code.
 -- Nicolas Barry  <boozai@yahoo.com>
 -
 -* pthread_spin_destroy() fixed memory leak.
 -- Piet van Bruggen  <pietvb@newbridges.nl>
 -
 -* Various changes to tighten arg checking, and to work with later versions of
 -MinGW32 and MsysDTK.
 -
 -* pthread_getschedparam() etc, fixed dangerous thread validity checking.
 -- Nicolas Barry  <boozai@yahoo.com>
 -
 -* POSIX thread handles are now reused and their memory is not freed on thread exit.
 -This allows for stronger thread validity checking.
 -
 -New standard routine
 ---------------------
 -
 -* pthread_kill() added to provide thread validity checking to applications.
 -It does not accept any non zero values for the signal arg.
 -
 -New test cases
 ---------------
 -
 -* New test cases to confirm validity checking, pthread_kill(), and thread reuse.
 -
 -
 -SNAPSHOT 2003-05-10
 --------------------
 -
 -Bug fixes
 ----------
 -
 -* pthread_mutex_trylock() now returns correct error values.
 -pthread_mutex_destroy() will no longer destroy a recursively locked mutex.
 -pthread_mutex_lock() is no longer inadvertantly behaving as a cancelation point.
 -- Thomas Pfaff  <tpfaff@gmx.net>
 -
 -* pthread_mutex_timedlock() no longer occasionally sets incorrect mutex
 -ownership, causing deadlocks in some applications.
 -- Robert Strycek <strycek@posam.sk> and Alexander Terekhov  <TEREKHOV@de.ibm.com>
 -
 -
 -SNAPSHOT 2002-11-04
 --------------------
 -
 -Bug fixes
 ----------
 -
 -* sem_getvalue() now returns the correct value under Win NT and WinCE.
 -- Rob Fanner  <rfanner@stonethree.com>
 -
 -* sem_timedwait() now uses tighter checks for unreasonable
 -abstime values - that would result in unexpected timeout values.
 -
 -* ptw32_cond_wait_cleanup() no longer mysteriously consumes
 -CV signals but may produce more spurious wakeups. It is believed
 -that the sem_timedwait() call is consuming a CV signal that it
 -shouldn't.
 -- Alexander Terekhov  <TEREKHOV@de.ibm.com>
 -
 -* Fixed a memory leak in ptw32_threadDestroy() for implicit threads.
 -
 -* Fixed potential for deadlock in pthread_cond_destroy().
 -A deadlock could occur for statically declared CVs (PTHREAD_COND_INITIALIZER),
 -when one thread is attempting to destroy the condition variable while another
 -is attempting to dynamically initialize it.
 -- Michael Johnson  <michaelj@maine.rr.com>
 -
 -
 -SNAPSHOT 2002-03-02
 --------------------
 -
 -Cleanup code default style. (IMPORTANT)
 -----------------------------------------------------------------------
 -Previously, if not defined, the cleanup style was determined automatically
 -from the compiler/language, and one of the following was defined accordingly:
 -
 -        __CLEANUP_SEH   MSVC only
 -        __CLEANUP_CXX   C++, including MSVC++, GNU G++
 -        __CLEANUP_C             C, including GNU GCC, not MSVC
 -
 -These defines determine the style of cleanup (see pthread.h) and,
 -most importantly, the way that cancelation and thread exit (via
 -pthread_exit) is performed (see the routine ptw32_throw() in private.c).
 -
 -In short, the exceptions versions of the library throw an exception
 -when a thread is canceled or exits (via pthread_exit()), which is
 -caught by a handler in the thread startup routine, so that the
 -the correct stack unwinding occurs regardless of where the thread
 -is when it's canceled or exits via pthread_exit().
 -
 -In this and future snapshots, unless the build explicitly defines (e.g.
 -via a compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then
 -the build NOW always defaults to __CLEANUP_C style cleanup. This style
 -uses setjmp/longjmp in the cancelation and pthread_exit implementations,
 -and therefore won't do stack unwinding even when linked to applications
 -that have it (e.g. C++ apps). This is for consistency with most
 -current commercial Unix POSIX threads implementations. Compaq's TRU64
 -may be an exception (no pun intended) and possible future trend.
 -
 -Although it was not clearly documented before, it is still necessary to
 -build your application using the same __CLEANUP_* define as was
 -used for the version of the library that you link with, so that the
 -correct parts of pthread.h are included. That is, the possible
 -defines require the following library versions:
 -
 -        __CLEANUP_SEH   pthreadVSE.dll
 -        __CLEANUP_CXX   pthreadVCE.dll or pthreadGCE.dll
 -        __CLEANUP_C     pthreadVC.dll or pthreadGC.dll
 -
 -E.g. regardless of whether your app is C or C++, if you link with
 -pthreadVC.lib or libpthreadGC.a, then you must define __CLEANUP_C.
 -
 -
 -THE POINT OF ALL THIS IS: if you have not been defining one of these
 -explicitly, then the defaults as described at the top of this
 -section were being used.
 -
 -THIS NOW CHANGES, as has been explained above, but to try to make this
 -clearer here's an example:
 -
 -If you were building your application with MSVC++ i.e. using C++
 -exceptions and not explicitly defining one of __CLEANUP_*, then
 -__CLEANUP_C++ was automatically defined for you in pthread.h.
 -You should have been linking with pthreadVCE.dll, which does
 -stack unwinding.
 -
 -If you now build your application as you had before, pthread.h will now
 -automatically set __CLEANUP_C as the default style, and you will need to
 -link with pthreadVC.dll. Stack unwinding will now NOT occur when a thread
 -is canceled, or the thread calls pthread_exit().
 -
 -Your application will now most likely behave differently to previous
 -versions, and in non-obvious ways. Most likely is that locally
 -instantiated objects may not be destroyed or cleaned up after a thread
 -is canceled.
 -
 -If you want the same behaviour as before, then you must now define
 -__CLEANUP_C++ explicitly using a compiler option and link with
 -pthreadVCE.dll as you did before.
 -
 -
 -WHY ARE WE MAKING THE DEFAULT STYLE LESS EXCEPTION-FRIENDLY?
 -Because no commercial Unix POSIX threads implementation allows you to
 -choose to have stack unwinding. Therefore, providing it in pthread-win32
 -as a default is dangerous. We still provide the choice but unless
 -you consciously choose to do otherwise, your pthreads applications will
 -now run or crash in similar ways irrespective of the threads platform
 -you use. Or at least this is the hope.
 -
 -
 -WHY NOT REMOVE THE EXCEPTIONS VERSIONS OF THE LIBRARY ALTOGETHER?
 -There are a few reasons:
 -- because there are well respected POSIX threads people who believe
 -  that POSIX threads implementations should be exceptions aware and
 -  do the expected thing in that context. (There are equally respected
 -  people who believe it should not be easily accessible, if it's there
 -  at all, for unconditional conformity to other implementations.)
 -- because pthreads-win32 is one of the few implementations that has
 -  the choice, perhaps the only freely available one, and so offers
 -  a laboratory to people who may want to explore the effects;
 -- although the code will always be around somewhere for anyone who
 -  wants it, once it's removed from the current version it will not be
 -  nearly as visible to people who may have a use for it.
 -
 -
 -Source module splitting
 ------------------------
 -In order to enable smaller image sizes to be generated
 -for applications that link statically with the library,
 -most routines have been separated out into individual
 -source code files.
 -
 -This is being done in such a way as to be backward compatible.
 -The old source files are reused to congregate the individual
 -routine files into larger translation units (via a bunch of
 -# includes) so that the compiler can still optimise wherever
 -possible, e.g. through inlining, which can only be done
 -within the same translation unit.
 -
 -It is also possible to build the entire library by compiling
 -the single file named "pthread.c", which just #includes all
 -the secondary congregation source files. The compiler
 -may be able to use this to do more inlining of routines.
 -
 -Although the GNU compiler is able to produce libraries with
 -the necessary separation (the -ffunction-segments switch),
 -AFAIK, the MSVC and other compilers don't have this feature.
 -
 -Finally, since I use makefiles and command-line compilation,
 -I don't know what havoc this reorganisation may wreak amongst
 -IDE project file users. You should be able to continue
 -using your existing project files without modification.
 -
 -
 -New non-portable functions
 ---------------------------
 -pthread_num_processors_np():
 -  Returns the number of processors in the system that are
 -  available to the process, as determined from the processor
 -  affinity mask.
 -
 -pthread_timechange_handler_np():
 -  To improve tolerance against operator or time service initiated
 -  system clock changes.
 -
 -  This routine can be called by an application when it
 -  receives a WM_TIMECHANGE message from the system. At present
 -  it broadcasts all condition variables so that waiting threads
 -  can wake up and re-evaluate their conditions and restart
 -  their timed waits if required.
 -  - Suggested by Alexander Terekhov
 -
 -
 -Platform dependence
 --------------------
 -As Win95 doesn't provide one, the library now contains
 -it's own InterlockedCompareExchange() routine, which is used
 -whenever Windows doesn't provide it. InterlockedCompareExchange()
 -is used to implement spinlocks and barriers, and also in mutexes.
 -This routine relies on the CMPXCHG machine instruction which
 -is not available on i386 CPUs. This library (from snapshot
 -20010712 onwards) is therefore no longer supported on i386
 -processor platforms.
 -
 -
 -New standard routines
 ----------------------
 -For source code portability only - rwlocks cannot be process shared yet.
 -
 -        pthread_rwlockattr_init()
 -        pthread_rwlockattr_destroy()
 -        pthread_rwlockattr_setpshared()
 -        pthread_rwlockattr_getpshared()
 -
 -As defined in the new POSIX standard, and the Single Unix Spec version 3:
 -
 -        sem_timedwait()
 -        pthread_mutex_timedlock()    - Alexander Terekhov and Thomas Pfaff
 -        pthread_rwlock_timedrdlock() - adapted from pthread_rwlock_rdlock()
 -        pthread_rwlock_timedwrlock() - adapted from pthread_rwlock_wrlock()
 -
 -
 -pthread.h no longer includes windows.h
 ---------------------------------------
 -[Not yet for G++]
 -
 -This was done to prevent conflicts.
 -
 -HANDLE, DWORD, and NULL are temporarily defined within pthread.h if
 -they are not already.
 -
 -
 -pthread.h, sched.h and semaphore.h now use dllexport/dllimport
 ---------------------------------------------------------------
 -Not only to avoid the need for the pthread.def file, but to
 -improve performance. Apparently, declaring functions with dllimport
 -generates a direct call to the function and avoids the overhead
 -of a stub function call.
 -
 -Bug fixes
 ----------
 -* Fixed potential NULL pointer dereferences in pthread_mutexattr_init,
 -pthread_mutexattr_getpshared, pthread_barrierattr_init,
 -pthread_barrierattr_getpshared, and pthread_condattr_getpshared.
 -- Scott McCaskill <scott@magruder.org>
 -
 -* Removed potential race condition in pthread_mutex_trylock and
 -pthread_mutex_lock;
 -- Alexander Terekhov <TEREKHOV@de.ibm.com>
 -
 -* The behaviour of pthread_mutex_trylock in relation to
 -recursive mutexes was inconsistent with commercial implementations.
 -Trylock would return EBUSY if the lock was owned already by the
 -calling thread regardless of mutex type. Trylock now increments the
 -recursion count and returns 0 for RECURSIVE mutexes, and will
 -return EDEADLK rather than EBUSY for ERRORCHECK mutexes. This is
 -consistent with Solaris.
 -- Thomas Pfaff <tpfaff@gmx.net>
 -
 -* Found a fix for the library and workaround for applications for
 -the known bug #2, i.e. where __CLEANUP_CXX or __CLEANUP_SEH is defined.
 -See the "Known Bugs in this snapshot" section below.
 -
 -This could be made transparent to applications by replacing the macros that
 -define the current C++ and SEH versions of pthread_cleanup_push/pop
 -with the C version, but AFAIK cleanup handlers would not then run in the
 -correct sequence with destructors and exception cleanup handlers when
 -an exception occurs.
 -
 -* Cancelation once started in a thread cannot now be inadvertantly
 -double canceled. That is, once a thread begins it's cancelation run,
 -cancelation is disabled and a subsequent cancel request will
 -return an error (ESRCH).
 -
 -* errno: An incorrect compiler directive caused a local version
 -of errno to be used instead of the Win32 errno. Both instances are
 -thread-safe but applications checking errno after a pthreads-win32
 -call would be wrong. Fixing this also fixed a bad compiler
 -option in the testsuite (/MT should have been /MD) which is
 -needed to link with the correct library MSVCRT.LIB.
 -
 -
 -SNAPSHOT 2001-07-12
 --------------------
 -
 -To be added
 -
 -
 -SNAPSHOT 2001-07-03
 --------------------
 -
 -To be added
 -
 -
 -SNAPSHOT 2000-08-13
 --------------------
 -
 -New:
 --       Renamed DLL and LIB files:
 -                pthreadVSE.dll  (MS VC++/Structured EH)
 -                pthreadVSE.lib
 -                pthreadVCE.dll  (MS VC++/C++ EH)
 -                pthreadVCE.lib
 -                pthreadGCE.dll  (GNU G++/C++ EH)
 -                libpthreadw32.a
 -
 -        Both your application and the pthread dll should use the
 -        same exception handling scheme.
 -
 -Bugs fixed:
 --       MSVC++ C++ exception handling.
 -
 -Some new tests have been added.
 -
 -
 -SNAPSHOT 2000-08-10
 --------------------
 -
 -New:
 --       asynchronous cancelation on X86 (Jason Nye)
 --       Makefile compatible with MS nmake to replace
 -        buildlib.bat
 --       GNUmakefile for Mingw32
 --       tests/Makefile for MS nmake replaces runall.bat
 --       tests/GNUmakefile for Mingw32
 -
 -Bugs fixed:
 --       kernel32 load/free problem
 --       attempt to hide internel exceptions from application
 -        exception handlers (__try/__except and try/catch blocks)
 --       Win32 thread handle leakage bug
 -        (David Baggett/Paul Redondo/Eyal Lebedinsky)
 -
 -Some new tests have been added.
 -
 -
 -SNAPSHOT 1999-11-02
 --------------------
 -
 -Bugs fixed:
 --       ctime_r macro had an incorrect argument (Erik Hensema),
 --       threads were not being created 
 -        PTHREAD_CANCEL_DEFERRED. This should have
 -        had little effect as deferred is the only
 -        supported type. (Ross Johnson).
 -
 -Some compatibility improvements added, eg.
 --       pthread_setcancelstate accepts NULL pointer
 -        for the previous value argument. Ditto for
 -        pthread_setcanceltype. This is compatible
 -        with Solaris but should not affect
 -        standard applications (Erik Hensema)
 -
 -Some new tests have been added.
 -
 -
 -SNAPSHOT 1999-10-17
 --------------------
 -
 -Bug fix - Cancelation of threads waiting on condition variables
 -now works properly (Lorin Hochstein and Peter Slacik)
 -
 -
 -SNAPSHOT 1999-08-12
 --------------------
 -
 -Fixed exception stack cleanup if calling pthread_exit()
 -- (Lorin Hochstein and John Bossom).
 -
 -Fixed bugs in condition variables - (Peter Slacik):
 -        - additional contention checks
 -        - properly adjust number of waiting threads after timed
 -          condvar timeout.
 -
 -
 -SNAPSHOT 1999-05-30
 --------------------
 -
 -Some minor bugs have been fixed. See the ChangeLog file for details.
 -
 -Some more POSIX 1b functions are now included but ony return an
 -error (ENOSYS) if called. They are:
 -
 -        sem_open
 -        sem_close
 -        sem_unlink
 -        sem_getvalue
 -
 -
 -SNAPSHOT 1999-04-07
 --------------------
 -
 -Some POSIX 1b functions which were internally supported are now
 -available as exported functions:
 -
 -        sem_init
 -        sem_destroy
 -        sem_wait
 -        sem_trywait
 -        sem_post
 -        sched_yield
 -        sched_get_priority_min
 -        sched_get_priority_max
 -
 -Some minor bugs have been fixed. See the ChangeLog file for details.
 -
 -
 -SNAPSHOT 1999-03-16
 --------------------
 -
 -Initial release.
 -
 +RELEASE 2.3.0 +------------- +(2005-04-12) + +General +------- + +Release 1.7.0 is a backport of features and bug fixes new in +this release. See earlier notes under Release 2.0.0/General. + +Bugs fixed +---------- + +* Fixed pthread_once potential for post once_routine cancellation +hanging due to starvation. See comments in pthread_once.c. +Momentary priority boosting is used to ensure that, after a +once_routine is cancelled, the thread that will run the +once_routine is not starved by higher priority waiting threads at +critical times. Priority boosting occurs only AFTER a once_routine  +cancellation, and is applied only to that once_control. The +once_routine is run at the thread's normal base priority. + +New tests +--------- + +* once4.c: Aggressively tests pthread_once() under realtime +conditions using threads with varying priorities. Windows' +random priority boosting does not occur for threads with realtime +priority levels. + + +RELEASE 2.2.0 +------------- +(2005-04-04) + +General +------- + +* Added makefile targets to build static link versions of the library. +Both MinGW and MSVC. Please note that this does not imply any change +to the LGPL licensing, which still imposes psecific conditions on +distributing software that has been statically linked with this library. + +* There is a known bug in pthread_once(). Cancellation of the init_routine +exposes a potential starvation (i.e. deadlock) problem if a waiting thread +has a higher priority than the initting thread. This problem will be fixed +in version 3.0.0 of the library. + +Bugs fixed +---------- + +* Fix integer overrun error in sem_timedwait(). +Kevin Lussier + +* Fix preprocessor directives for static linking. +Dimitar Panayotov + + +RELEASE 2.1.0 +------------- +(2005-03-16) + +Bugs fixed +---------- + +* Reverse change to pthread_setcancelstate() in 2.0.0. + + +RELEASE 2.0.0 +------------- +(2005-03-16) + +General +------- + +This release represents an ABI change and the DLL version naming has +incremented from 1 to 2, e.g. pthreadVC2.dll. + +Version 1.4.0 back-ports the new functionality included in this +release. Please distribute DLLs built from that version with updates +to applications built on pthreads-win32 version 1.x.x. + +The package naming has changed, replacing the snapshot date with  +the version number + descriptive information. E.g. this +release is "pthreads-w32-2-0-0-release". + +Bugs fixed +---------- + +* pthread_setcancelstate() no longer checks for a pending +async cancel event if the library is using alertable async +cancel. See the README file (Prerequisites section) for info +on adding alertable async cancelation. + +New features +------------ + +* pthread_once() now supports init_routine cancellability. + +New tests +--------- + +* Agressively test pthread_once() init_routine cancellability. + + +SNAPSHOT 2005-03-08 +------------------- +Version 1.3.0 + +Bug reports (fixed) +------------------- + +* Implicitly created threads leave Win32 handles behind after exiting. +- Dmitrii Semii + +* pthread_once() starvation problem. +- Gottlob Frege + +New tests +--------- + +* More intense testing of pthread_once(). + + +SNAPSHOT 2005-01-25 +------------------- +Version 1.2.0 + +Bug fixes +--------- + +* Attempted acquisition of a recursive mutex could cause waiting threads +to not be woken when the mutex was released. +- Ralf Kubis  <RKubis at mc.com> + +* Various package omissions have been fixed. + + +SNAPSHOT 2005-01-03 +------------------- +Version 1.1.0 + +Bug fixes +--------- + +* Unlocking recursive or errorcheck mutexes would sometimes +unexpectedly return an EPERM error (bug introduced in +snapshot-2004-11-03). +- Konstantin Voronkov  <beowinkle at yahoo.com> + + +SNAPSHOT 2004-11-22 +------------------- +Version 1.0.0 + +This snapshot primarily fixes the condvar bug introduced in +snapshot-2004-11-03. DLL versioning has also been included to allow +applications to runtime check the Microsoft compatible DLL version +information, and to extend the DLL naming system for ABI and major +(non-backward compatible) API changes. See the README file for details. + +Bug fixes +--------- + +* Condition variables no longer deadlock (bug introduced in +snapshot-2004-11-03). +- Alexander Kotliarov and Nicolas at saintmac + +* DLL naming extended to avoid 'DLL hell' in the future, and to +accommodate the ABI change introduced in snapshot-2004-11-03. Snapshot +2004-11-03 will be removed from FTP sites. + +New features +------------ + +* A Microsoft-style version resource has been added to the DLL for +applications that wish to check DLL compatibility at runtime. + +* Pthreads-win32 DLL naming has been extended to allow incompatible DLL +versions to co-exist in the same filesystem. See the README file for details, +but briefly: while the version information inside the DLL will change with +each release from now on, the DLL version names will only change if the new +DLL is not backward compatible with older applications. + +The versioning scheme has been borrowed from GNU Libtool, and the DLL +naming scheme is from Cygwin. Provided the Libtool-style numbering rules are +honoured, the Cygwin DLL naming scheme automatcally ensures that DLL name +changes are minimal and that applications will not load an incompatible +pthreads-win32 DLL. + +Those who use the pre-built DLLs will find that the DLL/LIB names have a new +suffix (1) in this snapshot. E.g. pthreadVC1.dll etc. + +* The POSIX thread ID reuse uniqueness feature introduced in the last snapshot +has been kept as default, but the behaviour can now be controlled when the DLL +is built to effectively switch it off. This makes the library much more +sensitive to applications that assume that POSIX thread IDs are unique, i.e. +are not strictly compliant with POSIX. See the PTW32_THREAD_ID_REUSE_INCREMENT +macro comments in config.h for details. + +Other changes +------------- +Certain POSIX macros have changed. + +These changes are intended to conform to the Single Unix Specification version 3, +which states that, if set to 0 (zero) or not defined, then applications may use +sysconf() to determine their values at runtime. Pthreads-win32 does not +implement sysconf(). + +The following macros are no longer undefined, but defined and set to -1 +(not implemented): + +      _POSIX_THREAD_ATTR_STACKADDR +      _POSIX_THREAD_PRIO_INHERIT +      _POSIX_THREAD_PRIO_PROTECT +      _POSIX_THREAD_PROCESS_SHARED + +The following macros are defined and set to 200112L (implemented): + +      _POSIX_THREADS +      _POSIX_THREAD_SAFE_FUNCTIONS +      _POSIX_THREAD_ATTR_STACKSIZE +      _POSIX_THREAD_PRIORITY_SCHEDULING +      _POSIX_SEMAPHORES +      _POSIX_READER_WRITER_LOCKS +      _POSIX_SPIN_LOCKS +      _POSIX_BARRIERS + +The following macros are defined and set to appropriate values: + +      _POSIX_THREAD_THREADS_MAX +      _POSIX_SEM_VALUE_MAX +      _POSIX_SEM_NSEMS_MAX +      PTHREAD_DESTRUCTOR_ITERATIONS +      PTHREAD_KEYS_MAX +      PTHREAD_STACK_MIN +      PTHREAD_THREADS_MAX + + +SNAPSHOT 2004-11-03 +------------------- + +DLLs produced from this snapshot cannot be used with older applications without +recompiling the application, due to a change to pthread_t to provide unique POSIX +thread IDs. + +Although this snapshot passes the extended test suite, many of the changes are +fairly major, and some applications may show different behaviour than previously, +so adopt with care. Hopefully, any changed behaviour will be due to the library +being better at it's job, not worse. + +Bug fixes +--------- + +* pthread_create() no longer accepts NULL as the thread reference arg. +A segfault (memory access fault) will result, and no thread will be +created. + +* pthread_barrier_wait() no longer acts as a cancelation point. + +* Fix potential race condition in pthread_once() +- Tristan Savatier  <tristan at mpegtv.com> + +* Changes to pthread_cond_destroy() exposed some coding weaknesses in several +test suite mini-apps because pthread_cond_destroy() now returns EBUSY if the CV +is still in use. + +New features +------------ + +* Added for compatibility: +PTHREAD_RECURSIVE_MUTEX_INITIALIZER, +PTHREAD_ERRORCHECK_MUTEX_INITIALIZER, +PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, +PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP + +* Initial support for Digital Mars compiler +- Anuj Goyal  <anuj.goyal at gmail.com> + +* Faster Mutexes. These have been been rewritten following a model provided by +Alexander Terekhov that reduces kernel space checks, and eliminates some additional +critical sections used to manage a race between timedlock expiration and unlock. +Please be aware that the new mutexes do not enforce strict absolute FIFO scheduling +of mutexes, however any out-of-order lock acquisition should be very rare. + +* Faster semaphores. Following a similar model to mutexes above, these have been +rewritten to use preliminary users space checks. + +* sem_getvalue() now returns the number of waiters. + +* The POSIX thread ID now has much stronger uniqueness characteristics. The library +garrantees not to reuse the same thread ID for at least 2^(wordsize) thread +destruction/creation cycles. + +New tests +--------- + +* semaphore4.c: Tests cancelation of the new sem_wait(). + +* semaphore4t.c: Likewise for sem_timedwait(). + +* rwlock8.c: Tests and times the slow execution paths of r/w locks, and the CVs, +mutexes, and semaphores that they're built on. + + +SNAPSHOT 2004-05-16 +------------------- + +Attempt to add Watcom to the list of compilers that can build the library. +This failed in the end due to it's non-thread-aware errno. The library +builds but the test suite fails. See README.Watcom for more details. + +Bug fixes +--------- +* Bug and memory leak in sem_init() +- Alex Blanco  <Alex.Blanco at motorola.com> + +* ptw32_getprocessors() now returns CPU count of 1 for WinCE. +- James Ewing  <james.ewing at sveasoft.com> + +* pthread_cond_wait() could be canceled at a point where it should not +be cancelable. Fixed. +- Alexander Terekhov  <TEREKHOV at de.ibm.com> + +* sem_timedwait() had an incorrect timeout calculation. +- Philippe Di Cristo  <philipped at voicebox.com> + +* Fix a memory leak left behind after threads are destroyed. +- P. van Bruggen  <pietvb at newbridges.nl> + +New features +------------ +* Ported to AMD64. +- Makoto Kato  <raven at oldskool.jp> + +* True pre-emptive asynchronous cancelation of threads. This is optional +and requires that Panagiotis E. Hadjidoukas's QueueUserAPCEx package be +installed. This package is included in the pthreads-win32 self-unpacking +Zip archive starting from this snapshot. See the README.txt file inside +the package for installation details. + +Note: If you don't use async cancelation in your application, or don't need +to cancel threads that are blocked on system resources such as network I/O, +then the default non-preemptive async cancelation is probably good enough. +However, pthreads-win32 auto-detects the availability of these components +at run-time, so you don't need to rebuild the library from source if you +change your mind later. + +All of the advice available in books and elsewhere on the undesirability +of using async cancelation in any application still stands, but this +feature is a welcome addition with respect to the library's conformance to +the POSIX standard. + +SNAPSHOT 2003-09-18 +------------------- + +Cleanup of thread priority management. In particular, setting of thread +priority now attempts to map invalid Win32 values within the range returned +by sched_get_priority_min/max() to useful values. See README.NONPORTABLE +under "Thread priority". + +Bug fixes +--------- +* pthread_getschedparam() now returns the priority given by the most recent +call to pthread_setschedparam() or established by pthread_create(), as +required by the standard. Previously, pthread_getschedparam() incorrectly +returned the running thread priority at the time of the call, which may have +been adjusted or temporarily promoted/demoted. + +* sched_get_priority_min() and sched_get_priority_max() now return -1 on error +and set errno. Previously, they incorrectly returned the error value directly. + + +SNAPSHOT 2003-09-04 +------------------- + +Bug fixes +--------- +* ptw32_cancelableWait() now allows cancelation of waiting implicit POSIX +threads. + +New test +-------- +* cancel8.c tests cancelation of Win32 threads waiting at a POSIX cancelation +point. + + +SNAPSHOT 2003-09-03 +------------------- + +Bug fixes +--------- +* pthread_self() would free the newly created implicit POSIX thread handle if +DuplicateHandle failed instead of recycle it (very unlikely). + +* pthread_exit() was neither freeing nor recycling the POSIX thread struct +for implicit POSIX threads. + +New feature - Cancelation of/by Win32 (non-POSIX) threads +--------------------------------------------------------- +Since John Bossom's original implementation, the library has allowed non-POSIX +initialised threads (Win32 threads) to call pthreads-win32 routines and +therefore interact with POSIX threads. This is done by creating an on-the-fly +POSIX thread ID for the Win32 thread that, once created, allows fully +reciprical interaction. This did not extend to thread cancelation (async or +deferred). Now it does. + +Any thread can be canceled by any other thread (Win32 or POSIX) if the former +thread's POSIX pthread_t value is known. It's TSD destructors and POSIX +cleanup handlers will be run before the thread exits with an exit code of +PTHREAD_CANCELED (retrieved with GetExitCodeThread()). + +This allows a Win32 thread to, for example, call POSIX CV routines in the same way +that POSIX threads would/should, with pthread_cond_wait() cancelability and +cleanup handlers (pthread_cond_wait() is a POSIX cancelation point). + +By adding cancelation, Win32 threads should now be able to call all POSIX +threads routines that make sense including semaphores, mutexes, condition +variables, read/write locks, barriers, spinlocks, tsd, cleanup push/pop, +cancelation, pthread_exit, scheduling, etc. + +Note that these on-the-fly 'implicit' POSIX thread IDs are initialised as detached +(not joinable) with deferred cancelation type. The POSIX thread ID will be created +automatically by any POSIX routines that need a POSIX handle (unless the routine +needs a pthread_t as a parameter of course). A Win32 thread can discover it's own +POSIX thread ID by calling pthread_self(), which will create the handle if +necessary and return the pthread_t value. + +New tests +--------- +Test the above new feature. + + +SNAPSHOT 2003-08-19 +------------------- + +This snapshot fixes some accidental corruption to new test case sources. +There are no changes to the library source code. + + +SNAPSHOT 2003-08-15 +------------------- + +Bug fixes +--------- + +* pthread.dsp now uses correct compile flags (/MD). +- Viv  <vcotirlea@hotmail.com> + +* pthread_win32_process_detach_np() fixed memory leak. +- Steven Reddie  <Steven.Reddie@ca.com> + +* pthread_mutex_destroy() fixed incorrect return code. +- Nicolas Barry  <boozai@yahoo.com> + +* pthread_spin_destroy() fixed memory leak. +- Piet van Bruggen  <pietvb@newbridges.nl> + +* Various changes to tighten arg checking, and to work with later versions of +MinGW32 and MsysDTK. + +* pthread_getschedparam() etc, fixed dangerous thread validity checking. +- Nicolas Barry  <boozai@yahoo.com> + +* POSIX thread handles are now reused and their memory is not freed on thread exit. +This allows for stronger thread validity checking. + +New standard routine +-------------------- + +* pthread_kill() added to provide thread validity checking to applications. +It does not accept any non zero values for the signal arg. + +New test cases +-------------- + +* New test cases to confirm validity checking, pthread_kill(), and thread reuse. + + +SNAPSHOT 2003-05-10 +------------------- + +Bug fixes +--------- + +* pthread_mutex_trylock() now returns correct error values. +pthread_mutex_destroy() will no longer destroy a recursively locked mutex. +pthread_mutex_lock() is no longer inadvertantly behaving as a cancelation point. +- Thomas Pfaff  <tpfaff@gmx.net> + +* pthread_mutex_timedlock() no longer occasionally sets incorrect mutex +ownership, causing deadlocks in some applications. +- Robert Strycek <strycek@posam.sk> and Alexander Terekhov  <TEREKHOV@de.ibm.com> + + +SNAPSHOT 2002-11-04 +------------------- + +Bug fixes +--------- + +* sem_getvalue() now returns the correct value under Win NT and WinCE. +- Rob Fanner  <rfanner@stonethree.com> + +* sem_timedwait() now uses tighter checks for unreasonable +abstime values - that would result in unexpected timeout values. + +* ptw32_cond_wait_cleanup() no longer mysteriously consumes +CV signals but may produce more spurious wakeups. It is believed +that the sem_timedwait() call is consuming a CV signal that it +shouldn't. +- Alexander Terekhov  <TEREKHOV@de.ibm.com> + +* Fixed a memory leak in ptw32_threadDestroy() for implicit threads. + +* Fixed potential for deadlock in pthread_cond_destroy(). +A deadlock could occur for statically declared CVs (PTHREAD_COND_INITIALIZER), +when one thread is attempting to destroy the condition variable while another +is attempting to dynamically initialize it. +- Michael Johnson  <michaelj@maine.rr.com> + + +SNAPSHOT 2002-03-02 +------------------- + +Cleanup code default style. (IMPORTANT) +---------------------------------------------------------------------- +Previously, if not defined, the cleanup style was determined automatically +from the compiler/language, and one of the following was defined accordingly: + +        __CLEANUP_SEH   MSVC only +        __CLEANUP_CXX   C++, including MSVC++, GNU G++ +        __CLEANUP_C             C, including GNU GCC, not MSVC + +These defines determine the style of cleanup (see pthread.h) and, +most importantly, the way that cancelation and thread exit (via +pthread_exit) is performed (see the routine ptw32_throw() in private.c). + +In short, the exceptions versions of the library throw an exception +when a thread is canceled or exits (via pthread_exit()), which is +caught by a handler in the thread startup routine, so that the +the correct stack unwinding occurs regardless of where the thread +is when it's canceled or exits via pthread_exit(). + +In this and future snapshots, unless the build explicitly defines (e.g. +via a compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then +the build NOW always defaults to __CLEANUP_C style cleanup. This style +uses setjmp/longjmp in the cancelation and pthread_exit implementations, +and therefore won't do stack unwinding even when linked to applications +that have it (e.g. C++ apps). This is for consistency with most +current commercial Unix POSIX threads implementations. Compaq's TRU64 +may be an exception (no pun intended) and possible future trend. + +Although it was not clearly documented before, it is still necessary to +build your application using the same __CLEANUP_* define as was +used for the version of the library that you link with, so that the +correct parts of pthread.h are included. That is, the possible +defines require the following library versions: + +        __CLEANUP_SEH   pthreadVSE.dll +        __CLEANUP_CXX   pthreadVCE.dll or pthreadGCE.dll +        __CLEANUP_C     pthreadVC.dll or pthreadGC.dll + +E.g. regardless of whether your app is C or C++, if you link with +pthreadVC.lib or libpthreadGC.a, then you must define __CLEANUP_C. + + +THE POINT OF ALL THIS IS: if you have not been defining one of these +explicitly, then the defaults as described at the top of this +section were being used. + +THIS NOW CHANGES, as has been explained above, but to try to make this +clearer here's an example: + +If you were building your application with MSVC++ i.e. using C++ +exceptions and not explicitly defining one of __CLEANUP_*, then +__CLEANUP_C++ was automatically defined for you in pthread.h. +You should have been linking with pthreadVCE.dll, which does +stack unwinding. + +If you now build your application as you had before, pthread.h will now +automatically set __CLEANUP_C as the default style, and you will need to +link with pthreadVC.dll. Stack unwinding will now NOT occur when a thread +is canceled, or the thread calls pthread_exit(). + +Your application will now most likely behave differently to previous +versions, and in non-obvious ways. Most likely is that locally +instantiated objects may not be destroyed or cleaned up after a thread +is canceled. + +If you want the same behaviour as before, then you must now define +__CLEANUP_C++ explicitly using a compiler option and link with +pthreadVCE.dll as you did before. + + +WHY ARE WE MAKING THE DEFAULT STYLE LESS EXCEPTION-FRIENDLY? +Because no commercial Unix POSIX threads implementation allows you to +choose to have stack unwinding. Therefore, providing it in pthread-win32 +as a default is dangerous. We still provide the choice but unless +you consciously choose to do otherwise, your pthreads applications will +now run or crash in similar ways irrespective of the threads platform +you use. Or at least this is the hope. + + +WHY NOT REMOVE THE EXCEPTIONS VERSIONS OF THE LIBRARY ALTOGETHER? +There are a few reasons: +- because there are well respected POSIX threads people who believe +  that POSIX threads implementations should be exceptions aware and +  do the expected thing in that context. (There are equally respected +  people who believe it should not be easily accessible, if it's there +  at all, for unconditional conformity to other implementations.) +- because pthreads-win32 is one of the few implementations that has +  the choice, perhaps the only freely available one, and so offers +  a laboratory to people who may want to explore the effects; +- although the code will always be around somewhere for anyone who +  wants it, once it's removed from the current version it will not be +  nearly as visible to people who may have a use for it. + + +Source module splitting +----------------------- +In order to enable smaller image sizes to be generated +for applications that link statically with the library, +most routines have been separated out into individual +source code files. + +This is being done in such a way as to be backward compatible. +The old source files are reused to congregate the individual +routine files into larger translation units (via a bunch of +# includes) so that the compiler can still optimise wherever +possible, e.g. through inlining, which can only be done +within the same translation unit. + +It is also possible to build the entire library by compiling +the single file named "pthread.c", which just #includes all +the secondary congregation source files. The compiler +may be able to use this to do more inlining of routines. + +Although the GNU compiler is able to produce libraries with +the necessary separation (the -ffunction-segments switch), +AFAIK, the MSVC and other compilers don't have this feature. + +Finally, since I use makefiles and command-line compilation, +I don't know what havoc this reorganisation may wreak amongst +IDE project file users. You should be able to continue +using your existing project files without modification. + + +New non-portable functions +-------------------------- +pthread_num_processors_np(): +  Returns the number of processors in the system that are +  available to the process, as determined from the processor +  affinity mask. + +pthread_timechange_handler_np(): +  To improve tolerance against operator or time service initiated +  system clock changes. + +  This routine can be called by an application when it +  receives a WM_TIMECHANGE message from the system. At present +  it broadcasts all condition variables so that waiting threads +  can wake up and re-evaluate their conditions and restart +  their timed waits if required. +  - Suggested by Alexander Terekhov + + +Platform dependence +------------------- +As Win95 doesn't provide one, the library now contains +it's own InterlockedCompareExchange() routine, which is used +whenever Windows doesn't provide it. InterlockedCompareExchange() +is used to implement spinlocks and barriers, and also in mutexes. +This routine relies on the CMPXCHG machine instruction which +is not available on i386 CPUs. This library (from snapshot +20010712 onwards) is therefore no longer supported on i386 +processor platforms. + + +New standard routines +--------------------- +For source code portability only - rwlocks cannot be process shared yet. + +        pthread_rwlockattr_init() +        pthread_rwlockattr_destroy() +        pthread_rwlockattr_setpshared() +        pthread_rwlockattr_getpshared() + +As defined in the new POSIX standard, and the Single Unix Spec version 3: + +        sem_timedwait() +        pthread_mutex_timedlock()    - Alexander Terekhov and Thomas Pfaff +        pthread_rwlock_timedrdlock() - adapted from pthread_rwlock_rdlock() +        pthread_rwlock_timedwrlock() - adapted from pthread_rwlock_wrlock() + + +pthread.h no longer includes windows.h +-------------------------------------- +[Not yet for G++] + +This was done to prevent conflicts. + +HANDLE, DWORD, and NULL are temporarily defined within pthread.h if +they are not already. + + +pthread.h, sched.h and semaphore.h now use dllexport/dllimport +-------------------------------------------------------------- +Not only to avoid the need for the pthread.def file, but to +improve performance. Apparently, declaring functions with dllimport +generates a direct call to the function and avoids the overhead +of a stub function call. + +Bug fixes +--------- +* Fixed potential NULL pointer dereferences in pthread_mutexattr_init, +pthread_mutexattr_getpshared, pthread_barrierattr_init, +pthread_barrierattr_getpshared, and pthread_condattr_getpshared. +- Scott McCaskill <scott@magruder.org> + +* Removed potential race condition in pthread_mutex_trylock and +pthread_mutex_lock; +- Alexander Terekhov <TEREKHOV@de.ibm.com> + +* The behaviour of pthread_mutex_trylock in relation to +recursive mutexes was inconsistent with commercial implementations. +Trylock would return EBUSY if the lock was owned already by the +calling thread regardless of mutex type. Trylock now increments the +recursion count and returns 0 for RECURSIVE mutexes, and will +return EDEADLK rather than EBUSY for ERRORCHECK mutexes. This is +consistent with Solaris. +- Thomas Pfaff <tpfaff@gmx.net> + +* Found a fix for the library and workaround for applications for +the known bug #2, i.e. where __CLEANUP_CXX or __CLEANUP_SEH is defined. +See the "Known Bugs in this snapshot" section below. + +This could be made transparent to applications by replacing the macros that +define the current C++ and SEH versions of pthread_cleanup_push/pop +with the C version, but AFAIK cleanup handlers would not then run in the +correct sequence with destructors and exception cleanup handlers when +an exception occurs. + +* Cancelation once started in a thread cannot now be inadvertantly +double canceled. That is, once a thread begins it's cancelation run, +cancelation is disabled and a subsequent cancel request will +return an error (ESRCH). + +* errno: An incorrect compiler directive caused a local version +of errno to be used instead of the Win32 errno. Both instances are +thread-safe but applications checking errno after a pthreads-win32 +call would be wrong. Fixing this also fixed a bad compiler +option in the testsuite (/MT should have been /MD) which is +needed to link with the correct library MSVCRT.LIB. + + +SNAPSHOT 2001-07-12 +------------------- + +To be added + + +SNAPSHOT 2001-07-03 +------------------- + +To be added + + +SNAPSHOT 2000-08-13 +------------------- + +New: +-       Renamed DLL and LIB files: +                pthreadVSE.dll  (MS VC++/Structured EH) +                pthreadVSE.lib +                pthreadVCE.dll  (MS VC++/C++ EH) +                pthreadVCE.lib +                pthreadGCE.dll  (GNU G++/C++ EH) +                libpthreadw32.a + +        Both your application and the pthread dll should use the +        same exception handling scheme. + +Bugs fixed: +-       MSVC++ C++ exception handling. + +Some new tests have been added. + + +SNAPSHOT 2000-08-10 +------------------- + +New: +-       asynchronous cancelation on X86 (Jason Nye) +-       Makefile compatible with MS nmake to replace +        buildlib.bat +-       GNUmakefile for Mingw32 +-       tests/Makefile for MS nmake replaces runall.bat +-       tests/GNUmakefile for Mingw32 + +Bugs fixed: +-       kernel32 load/free problem +-       attempt to hide internel exceptions from application +        exception handlers (__try/__except and try/catch blocks) +-       Win32 thread handle leakage bug +        (David Baggett/Paul Redondo/Eyal Lebedinsky) + +Some new tests have been added. + + +SNAPSHOT 1999-11-02 +------------------- + +Bugs fixed: +-       ctime_r macro had an incorrect argument (Erik Hensema), +-       threads were not being created  +        PTHREAD_CANCEL_DEFERRED. This should have +        had little effect as deferred is the only +        supported type. (Ross Johnson). + +Some compatibility improvements added, eg. +-       pthread_setcancelstate accepts NULL pointer +        for the previous value argument. Ditto for +        pthread_setcanceltype. This is compatible +        with Solaris but should not affect +        standard applications (Erik Hensema) + +Some new tests have been added. + + +SNAPSHOT 1999-10-17 +------------------- + +Bug fix - Cancelation of threads waiting on condition variables +now works properly (Lorin Hochstein and Peter Slacik) + + +SNAPSHOT 1999-08-12 +------------------- + +Fixed exception stack cleanup if calling pthread_exit() +- (Lorin Hochstein and John Bossom). + +Fixed bugs in condition variables - (Peter Slacik): +        - additional contention checks +        - properly adjust number of waiting threads after timed +          condvar timeout. + + +SNAPSHOT 1999-05-30 +------------------- + +Some minor bugs have been fixed. See the ChangeLog file for details. + +Some more POSIX 1b functions are now included but ony return an +error (ENOSYS) if called. They are: + +        sem_open +        sem_close +        sem_unlink +        sem_getvalue + + +SNAPSHOT 1999-04-07 +------------------- + +Some POSIX 1b functions which were internally supported are now +available as exported functions: + +        sem_init +        sem_destroy +        sem_wait +        sem_trywait +        sem_post +        sched_yield +        sched_get_priority_min +        sched_get_priority_max + +Some minor bugs have been fixed. See the ChangeLog file for details. + + +SNAPSHOT 1999-03-16 +------------------- + +Initial release. + @@ -1,24 +1,24 @@ -/*
 - * nmake file for uwin pthread library
 - */
 -
 -VERSION 		= -
 -CCFLAGS 		= -V -g $(CC.DLL)
 -HAVE_CONFIG_H	== 1
 -_MT			== 1
 -_timeb		== timeb
 -_ftime		== ftime
 -_errno		== _ast_errno
 -
 -$(INCLUDEDIR)	:INSTALLDIR:	pthread.h sched.h
 -
 -pthread $(VERSION) :LIBRARY: attr.c barrier.c cancel.c cleanup.c condvar.c \
 -	create.c dll.c exit.c fork.c global.c misc.c mutex.c private.c \
 -	rwlock.c sched.c semaphore.c spin.c sync.c tsd.c nonportable.c
 -
 -:: ANNOUNCE CONTRIBUTORS COPYING.LIB ChangeLog FAQ GNUmakefile MAINTAINERS \
 -	Makefile Makefile.in Makefile.vc NEWS PROGRESS README README.WinCE \
 -	TODO WinCE-PORT install-sh errno.c tests tests.mk acconfig.h \
 -	config.guess config.h.in config.sub configure configure.in signal.c \
 -	README.CV README.NONPORTABLE pthread.dsp pthread.dsw
 -
 +/* + * nmake file for uwin pthread library + */ + +VERSION 		= - +CCFLAGS 		= -V -g $(CC.DLL) +HAVE_CONFIG_H	== 1 +_MT			== 1 +_timeb		== timeb +_ftime		== ftime +_errno		== _ast_errno + +$(INCLUDEDIR)	:INSTALLDIR:	pthread.h sched.h + +pthread $(VERSION) :LIBRARY: attr.c barrier.c cancel.c cleanup.c condvar.c \ +	create.c dll.c exit.c fork.c global.c misc.c mutex.c private.c \ +	rwlock.c sched.c semaphore.c spin.c sync.c tsd.c nonportable.c + +:: ANNOUNCE CONTRIBUTORS COPYING.LIB ChangeLog FAQ GNUmakefile MAINTAINERS \ +	Makefile Makefile.in Makefile.vc NEWS PROGRESS README README.WinCE \ +	TODO WinCE-PORT install-sh errno.c tests tests.mk acconfig.h \ +	config.guess config.h.in config.sub configure configure.in signal.c \ +	README.CV README.NONPORTABLE pthread.dsp pthread.dsw + diff --git a/Nmakefile.tests b/Nmakefile.tests index 4647273..203560b 100644 --- a/Nmakefile.tests +++ b/Nmakefile.tests @@ -1,260 +1,260 @@ -/* for running tests */
 -CCFLAGS 	= -g 
 -_MT		== 1
 -_timeb	== timeb
 -_ftime	== ftime 
 -
 -.SOURCE:	tests
 -/*
 -:PACKAGE:	pthread
 -*/
 -
 -set keepgoing
 -
 -":test:" : .MAKE .OPERATOR
 -	local I
 -	$(<:D:B:S=.pass) : .IMPLICIT $(>:D:B:S=.pass)
 -	for I $(<) $(>)
 -		$(I:D:B:S=.pass) : .VIRTUAL .FORCE $(I)
 -			$(>)
 -	end
 -sizes::		sizes.c
 -loadfree::	loadfree.c
 -mutex1::	mutex1.c
 -mutex1e::	mutex1e.c
 -mutex1n::	mutex1n.c
 -mutex1r::	mutex1r.c
 -mutex2::	mutex2.c
 -mutex2r::	mutex2r.c
 -mutex2e::	mutex2e.c
 -exit1::	exit1.c
 -condvar1::	condvar1.c
 -condvar1_1::	condvar1_1.c
 -condvar1_2::	condvar1_2.c
 -self1::		self1.c
 -condvar2::	condvar2.c
 -condvar2_1::	condvar2_1.c
 -condvar3_1::	condvar3_1.c
 -condvar3_2::	condvar3_2.c
 -condvar3_3::	condvar3_3.c
 -create1.::	create1.c
 -create2.::	create2.c
 -cancel1::	cancel1.c
 -cancel2::	cancel2.c
 -mutex3::	mutex3.c
 -mutex3r::	mutex3r.c
 -mutex3e::	mutex3e.c
 -mutex4::	mutex4.c
 -mutex5::	mutex5.c
 -mutex6::	mutex6.c
 -mutex6e::	mutex6e.c
 -mutex6n::	mutex6n.c
 -mutex6r::	mutex6r.c
 -mutex7::	mutex7.c
 -mutex6s::	mutex6s.c
 -mutex6rs::	mutex6rs.c
 -mutex6es::	mutex6es.c
 -mutex7e::	mutex7e.c
 -mutex7n::	mutex7n.c
 -mutex7r::	mutex7r.c
 -mutex8::	mutex8.c
 -mutex8e::	mutex8e.c
 -mutex8n::	mutex8n.c
 -mutex8r::	mutex8r.c
 -equal1::	equal1.c
 -exit2::		exit2.c
 -exit3::		exit3.c
 -exit4::		exit4.c
 -exit5::		exit5.c
 -join0::		join0.c
 -join1::		join1.c
 -join2::		join2.c
 -join3::		join3.c
 -kill1::		kill1.c
 -count1::	count1.c
 -once1::		once1.c
 -tsd1::		tsd1.c
 -self2::		self2.c
 -eyal1::		eyal1.c
 -condvar3::	condvar3.c
 -condvar4::	condvar4.c
 -condvar5::	condvar5.c
 -condvar6::	condvar6.c
 -condvar7::	condvar7.c
 -condvar8::	condvar8.c
 -condvar9::	condvar9.c
 -errno1::	errno1.c
 -reuse1.::	reuse1.c
 -reuse2.::	reuse2.c
 -rwlock1::	rwlock1.c
 -rwlock2::	rwlock2.c
 -rwlock3::	rwlock3.c
 -rwlock4::	rwlock4.c
 -rwlock5::	rwlock5.c
 -rwlock6::	rwlock6.c
 -rwlock7::	rwlock7.c
 -rwlock8::	rwlock8.c
 -rwlock2_t::	rwlock2_t.c
 -rwlock3_t::	rwlock3_t.c
 -rwlock4_t::	rwlock4_t.c
 -rwlock5_t::	rwlock5_t.c
 -rwlock6_t::	rwlock6_t.c
 -rwlock6_t2::	rwlock6_t2.c
 -semaphore1::	semaphore1.c
 -semaphore2::	semaphore2.c
 -semaphore3::	semaphore3.c
 -context1::	context1.c
 -cancel3::	cancel3.c
 -cancel4::	cancel4.c
 -cancel5::	cancel5.c
 -cancel6a::	cancel6a.c
 -cancel6d::	cancel6d.c
 -cancel7::	cancel7.c
 -cleanup0::	cleanup0.c
 -cleanup1::	cleanup1.c
 -cleanup2::	cleanup2.c
 -cleanup3::	cleanup3.c
 -priority1::     priority1.c
 -priority2::     priority2.c
 -inherit1::      inherit1.c
 -spin1::         spin1.c
 -spin2::         spin2.c
 -spin3::         spin3.c
 -spin4::         spin4.c
 -barrier1::      barrier1.c
 -barrier2::      barrier2.c
 -barrier3::      barrier3.c
 -barrier4::      barrier4.c
 -barrier5::      barrier5.c
 -exception1::	exception1.c
 -exception2::	exception2.c
 -exception3::	exception3.c
 -benchtest1::    benchtest1.c
 -benchtest2::    benchtest2.c
 -benchtest3::    benchtest3.c
 -benchtest4::    benchtest4.c
 -benchtest5::    benchtest5.c
 -valid1::	valid1.c
 -valid2::	valid2.c
 -cancel9::	cancel9.c
 -
 -sizes:		:test:	sizes
 -loadfree:	:test:
 -mutex5		:test:	loadfree
 -mutex1		:test:	loadfree
 -mutex1n		:test:	loadfree
 -mutex1r		:test:	loadfree
 -mutex1e		:test:	loadfree
 -semaphore1	:test:	loadfree
 -semaphore2	:test:	loadfree
 -semaphore3	:test:	loadfree
 -mutex2		:test:	loadfree
 -mutex2r		:test:	loadfree
 -mutex2e		:test:	loadfree
 -exit1		:test:	loadfree
 -condvar1	:test:	loadfree
 -kill1		:test:	loadfree
 -condvar1_1	:test:	condvar1
 -condvar1_2	:test:	join2
 -self1		:test:	loadfree
 -condvar2	:test:	condvar1
 -condvar2_1	:test:	condvar2
 -create1 	:test:	mutex2
 -create2 	:test:	create1
 -reuse1 		:test:	create2
 -reuse2 		:test:	reuse1
 -cancel1		:test:	create1
 -cancel2		:test:	cancel1
 -mutex3		:test:	create1
 -mutex3r		:test:	create1
 -mutex3e		:test:	create1
 -mutex4		:test:	mutex3
 -mutex6		:test:	mutex4
 -mutex6n		:test:	mutex4
 -mutex6e		:test:	mutex4
 -mutex6r		:test:	mutex4
 -mutex6s		:test:	mutex6
 -mutex6rs	:test:	mutex6r
 -mutex6es	:test:	mutex6e
 -mutex7		:test:	mutex6
 -mutex7n		:test:	mutex6n
 -mutex7e		:test:	mutex6e
 -mutex7r		:test:	mutex6r
 -mutex8		:test:	mutex7
 -mutex8n		:test:	mutex7n
 -mutex8e		:test:	mutex7e
 -mutex8r		:test:	mutex7r
 -equal1		:test:	create1
 -exit2		:test:	create1
 -exit3		:test:	create1
 -exit4		:test:	kill1
 -exit5		:test:	exit4
 -join0		:test:	create1
 -join1		:test:	create1
 -join2		:test:	create1
 -join3		:test:	join2
 -count1		:test:	join1
 -once1		:test:	create1
 -tsd1		:test:	join1
 -self2		:test:	create1
 -eyal1		:test:	tsd1
 -condvar3	:test:	create1
 -condvar3_1	:test:	condvar3
 -condvar3_2	:test:	condvar3_1
 -condvar3_3	:test:	condvar3_2
 -condvar4	:test:	create1
 -condvar5	:test:	condvar4
 -condvar6	:test:	condvar5
 -condvar7	:test:	condvar6	cleanup1
 -condvar8	:test:	condvar7
 -condvar9	:test:	condvar8
 -errno1		:test:	mutex3
 -rwlock1		:test:	condvar6
 -rwlock2		:test:	rwlock1
 -rwlock3		:test:	rwlock2
 -rwlock4		:test:	rwlock3
 -rwlock5		:test:	rwlock4
 -rwlock6		:test:	rwlock5
 -rwlock7		:test:	rwlock6
 -rwlock8		:test:	rwlock7
 -rwlock2_t	:test:	rwlock2
 -rwlock3_t	:test:	rwlock2_t
 -rwlock4_t	:test:	rwlock3_t
 -rwlock5_t	:test:	rwlock4_t
 -rwlock6_t	:test:	rwlock5_t
 -rwlock6_t2	:test:	rwlock6_t
 -context1	:test:	cancel2
 -cancel3		:test:	context1
 -cancel4		:test:	cancel3
 -cancel5		:test:	cancel3
 -cancel6a	:test:	cancel3
 -cancel6d	:test:	cancel3
 -cancel7		:test:	kill1
 -cleanup0	:test:	cancel5
 -cleanup1	:test:	cleanup0
 -cleanup2	:test:	cleanup1
 -cleanup3	:test:	cleanup2
 -priority1       :test:  join1
 -priority2       :test:  priority1
 -inherit1        :test:  join1
 -spin1           :test:
 -spin2           :test:  spin1.c
 -spin3           :test:  spin2.c
 -spin4           :test:  spin3.c
 -barrier1        :test:
 -barrier2        :test:  barrier1.c
 -barrier3        :test:  barrier2.c
 -barrier4        :test:  barrier3.c
 -barrier5        :test:  barrier4.c
 -benchtest1      :test:  mutex3
 -benchtest2      :test:  benchtest1
 -benchtest3      :test:  benchtest2
 -benchtest4      :test:  benchtest3
 -benchtest5      :test:  benchtest4
 -exception1	:test:	cancel4
 -exception2	:test:	exception1
 -exception3	:test:	exception2
 -exit4		:test:	exit3
 -valid1		:test:	join1
 -valid2		:test:	valid1
 -cancel9		:test:	cancel8
 +/* for running tests */ +CCFLAGS 	= -g  +_MT		== 1 +_timeb	== timeb +_ftime	== ftime  + +.SOURCE:	tests +/* +:PACKAGE:	pthread +*/ + +set keepgoing + +":test:" : .MAKE .OPERATOR +	local I +	$(<:D:B:S=.pass) : .IMPLICIT $(>:D:B:S=.pass) +	for I $(<) $(>) +		$(I:D:B:S=.pass) : .VIRTUAL .FORCE $(I) +			$(>) +	end +sizes::		sizes.c +loadfree::	loadfree.c +mutex1::	mutex1.c +mutex1e::	mutex1e.c +mutex1n::	mutex1n.c +mutex1r::	mutex1r.c +mutex2::	mutex2.c +mutex2r::	mutex2r.c +mutex2e::	mutex2e.c +exit1::	exit1.c +condvar1::	condvar1.c +condvar1_1::	condvar1_1.c +condvar1_2::	condvar1_2.c +self1::		self1.c +condvar2::	condvar2.c +condvar2_1::	condvar2_1.c +condvar3_1::	condvar3_1.c +condvar3_2::	condvar3_2.c +condvar3_3::	condvar3_3.c +create1.::	create1.c +create2.::	create2.c +cancel1::	cancel1.c +cancel2::	cancel2.c +mutex3::	mutex3.c +mutex3r::	mutex3r.c +mutex3e::	mutex3e.c +mutex4::	mutex4.c +mutex5::	mutex5.c +mutex6::	mutex6.c +mutex6e::	mutex6e.c +mutex6n::	mutex6n.c +mutex6r::	mutex6r.c +mutex7::	mutex7.c +mutex6s::	mutex6s.c +mutex6rs::	mutex6rs.c +mutex6es::	mutex6es.c +mutex7e::	mutex7e.c +mutex7n::	mutex7n.c +mutex7r::	mutex7r.c +mutex8::	mutex8.c +mutex8e::	mutex8e.c +mutex8n::	mutex8n.c +mutex8r::	mutex8r.c +equal1::	equal1.c +exit2::		exit2.c +exit3::		exit3.c +exit4::		exit4.c +exit5::		exit5.c +join0::		join0.c +join1::		join1.c +join2::		join2.c +join3::		join3.c +kill1::		kill1.c +count1::	count1.c +once1::		once1.c +tsd1::		tsd1.c +self2::		self2.c +eyal1::		eyal1.c +condvar3::	condvar3.c +condvar4::	condvar4.c +condvar5::	condvar5.c +condvar6::	condvar6.c +condvar7::	condvar7.c +condvar8::	condvar8.c +condvar9::	condvar9.c +errno1::	errno1.c +reuse1.::	reuse1.c +reuse2.::	reuse2.c +rwlock1::	rwlock1.c +rwlock2::	rwlock2.c +rwlock3::	rwlock3.c +rwlock4::	rwlock4.c +rwlock5::	rwlock5.c +rwlock6::	rwlock6.c +rwlock7::	rwlock7.c +rwlock8::	rwlock8.c +rwlock2_t::	rwlock2_t.c +rwlock3_t::	rwlock3_t.c +rwlock4_t::	rwlock4_t.c +rwlock5_t::	rwlock5_t.c +rwlock6_t::	rwlock6_t.c +rwlock6_t2::	rwlock6_t2.c +semaphore1::	semaphore1.c +semaphore2::	semaphore2.c +semaphore3::	semaphore3.c +context1::	context1.c +cancel3::	cancel3.c +cancel4::	cancel4.c +cancel5::	cancel5.c +cancel6a::	cancel6a.c +cancel6d::	cancel6d.c +cancel7::	cancel7.c +cleanup0::	cleanup0.c +cleanup1::	cleanup1.c +cleanup2::	cleanup2.c +cleanup3::	cleanup3.c +priority1::     priority1.c +priority2::     priority2.c +inherit1::      inherit1.c +spin1::         spin1.c +spin2::         spin2.c +spin3::         spin3.c +spin4::         spin4.c +barrier1::      barrier1.c +barrier2::      barrier2.c +barrier3::      barrier3.c +barrier4::      barrier4.c +barrier5::      barrier5.c +exception1::	exception1.c +exception2::	exception2.c +exception3::	exception3.c +benchtest1::    benchtest1.c +benchtest2::    benchtest2.c +benchtest3::    benchtest3.c +benchtest4::    benchtest4.c +benchtest5::    benchtest5.c +valid1::	valid1.c +valid2::	valid2.c +cancel9::	cancel9.c + +sizes:		:test:	sizes +loadfree:	:test: +mutex5		:test:	loadfree +mutex1		:test:	loadfree +mutex1n		:test:	loadfree +mutex1r		:test:	loadfree +mutex1e		:test:	loadfree +semaphore1	:test:	loadfree +semaphore2	:test:	loadfree +semaphore3	:test:	loadfree +mutex2		:test:	loadfree +mutex2r		:test:	loadfree +mutex2e		:test:	loadfree +exit1		:test:	loadfree +condvar1	:test:	loadfree +kill1		:test:	loadfree +condvar1_1	:test:	condvar1 +condvar1_2	:test:	join2 +self1		:test:	loadfree +condvar2	:test:	condvar1 +condvar2_1	:test:	condvar2 +create1 	:test:	mutex2 +create2 	:test:	create1 +reuse1 		:test:	create2 +reuse2 		:test:	reuse1 +cancel1		:test:	create1 +cancel2		:test:	cancel1 +mutex3		:test:	create1 +mutex3r		:test:	create1 +mutex3e		:test:	create1 +mutex4		:test:	mutex3 +mutex6		:test:	mutex4 +mutex6n		:test:	mutex4 +mutex6e		:test:	mutex4 +mutex6r		:test:	mutex4 +mutex6s		:test:	mutex6 +mutex6rs	:test:	mutex6r +mutex6es	:test:	mutex6e +mutex7		:test:	mutex6 +mutex7n		:test:	mutex6n +mutex7e		:test:	mutex6e +mutex7r		:test:	mutex6r +mutex8		:test:	mutex7 +mutex8n		:test:	mutex7n +mutex8e		:test:	mutex7e +mutex8r		:test:	mutex7r +equal1		:test:	create1 +exit2		:test:	create1 +exit3		:test:	create1 +exit4		:test:	kill1 +exit5		:test:	exit4 +join0		:test:	create1 +join1		:test:	create1 +join2		:test:	create1 +join3		:test:	join2 +count1		:test:	join1 +once1		:test:	create1 +tsd1		:test:	join1 +self2		:test:	create1 +eyal1		:test:	tsd1 +condvar3	:test:	create1 +condvar3_1	:test:	condvar3 +condvar3_2	:test:	condvar3_1 +condvar3_3	:test:	condvar3_2 +condvar4	:test:	create1 +condvar5	:test:	condvar4 +condvar6	:test:	condvar5 +condvar7	:test:	condvar6	cleanup1 +condvar8	:test:	condvar7 +condvar9	:test:	condvar8 +errno1		:test:	mutex3 +rwlock1		:test:	condvar6 +rwlock2		:test:	rwlock1 +rwlock3		:test:	rwlock2 +rwlock4		:test:	rwlock3 +rwlock5		:test:	rwlock4 +rwlock6		:test:	rwlock5 +rwlock7		:test:	rwlock6 +rwlock8		:test:	rwlock7 +rwlock2_t	:test:	rwlock2 +rwlock3_t	:test:	rwlock2_t +rwlock4_t	:test:	rwlock3_t +rwlock5_t	:test:	rwlock4_t +rwlock6_t	:test:	rwlock5_t +rwlock6_t2	:test:	rwlock6_t +context1	:test:	cancel2 +cancel3		:test:	context1 +cancel4		:test:	cancel3 +cancel5		:test:	cancel3 +cancel6a	:test:	cancel3 +cancel6d	:test:	cancel3 +cancel7		:test:	kill1 +cleanup0	:test:	cancel5 +cleanup1	:test:	cleanup0 +cleanup2	:test:	cleanup1 +cleanup3	:test:	cleanup2 +priority1       :test:  join1 +priority2       :test:  priority1 +inherit1        :test:  join1 +spin1           :test: +spin2           :test:  spin1.c +spin3           :test:  spin2.c +spin4           :test:  spin3.c +barrier1        :test: +barrier2        :test:  barrier1.c +barrier3        :test:  barrier2.c +barrier4        :test:  barrier3.c +barrier5        :test:  barrier4.c +benchtest1      :test:  mutex3 +benchtest2      :test:  benchtest1 +benchtest3      :test:  benchtest2 +benchtest4      :test:  benchtest3 +benchtest5      :test:  benchtest4 +exception1	:test:	cancel4 +exception2	:test:	exception1 +exception3	:test:	exception2 +exit4		:test:	exit3 +valid1		:test:	join1 +valid2		:test:	valid1 +cancel9		:test:	cancel8 @@ -1,568 +1,568 @@ -PTHREADS-WIN32
 -==============
 -
 -Pthreads-win32 is free software, distributed under the GNU Lesser
 -General Public License (LGPL). See the file 'COPYING.LIB' for terms
 -and conditions. Also see the file 'COPYING' for information
 -specific to pthreads-win32, copyrights and the LGPL.
 -
 -
 -What is it?
 ------------
 -
 -Pthreads-win32 is an Open Source Software implementation of the
 -Threads component of the POSIX 1003.1c 1995 Standard (or later)
 -for Microsoft's Win32 environment. Some functions from POSIX
 -1003.1b are also supported including semaphores. Other related
 -functions include the set of read-write lock functions. The
 -library also supports some of the functionality of the Open
 -Group's Single Unix specification, version 2, namely mutex types,
 -plus some common and pthreads-win32 specific non-portable
 -routines (see README.NONPORTABLE).
 -
 -See the file "ANNOUNCE" for more information including standards
 -conformance details and the list of supported and unsupported
 -routines.
 -
 -
 -Prerequisites
 --------------
 -MSVC or GNU C (MinGW32 MSys development kit)
 -	To build from source.
 -
 -QueueUserAPCEx by Panagiotis E. Hadjidoukas
 -	For true async cancelation of threads (including blocked threads).
 -	This is a DLL and Windows driver that provides pre-emptive APC
 -	by forcing threads into an alertable state when the APC is queued.
 -	Both the DLL and driver are provided with the pthreads-win32.exe
 -	self-unpacking ZIP, and on the pthreads-win32 FTP site  (in source
 -	and pre-built forms). Currently this is a separate LGPL package to
 -	pthreads-win32. See the README in the QueueUserAPCEx folder for
 -	installation instructions.
 -
 -	Pthreads-win32 will automatically detect if the QueueUserAPCEx DLL
 -	QuserEx.DLL is available and whether the driver AlertDrv.sys is
 -	loaded. If it is not available, pthreads-win32 will simulate async
 -	cancelation, which means that it can async cancel only threads that
 -	are runnable. The simulated async cancellation cannot cancel blocked
 -	threads.
 -
 -
 -Library naming
 ---------------
 -
 -Because the library is being built using various exception
 -handling schemes and compilers - and because the library
 -may not work reliably if these are mixed in an application,
 -each different version of the library has it's own name.
 -
 -Note 1: the incompatibility is really between EH implementations
 -of the different compilers. It should be possible to use the
 -standard C version from either compiler with C++ applications
 -built with a different compiler. If you use an EH version of
 -the library, then you must use the same compiler for the
 -application. This is another complication and dependency that
 -can be avoided by using only the standard C library version.
 -
 -Note 2: if you use a standard C pthread*.dll with a C++
 -application, then any functions that you define that are
 -intended to be called via pthread_cleanup_push() must be
 -__cdecl.
 -
 -Note 3: the intention was to also name either the VC or GC
 -version (it should be arbitrary) as pthread.dll, including
 -pthread.lib and libpthread.a as appropriate. This is no longer
 -likely to happen.
 -
 -Note 4: the compatibility number was added so that applications
 -can differentiate between binary incompatible versions of the
 -libs and dlls.
 -
 -In general:
 -	pthread[VG]{SE,CE,C}c.dll
 -	pthread[VG]{SE,CE,C}c.lib
 -
 -where:
 -	[VG] indicates the compiler
 -	V	- MS VC, or
 -	G	- GNU C
 -
 -	{SE,CE,C} indicates the exception handling scheme
 -	SE	- Structured EH, or
 -	CE	- C++ EH, or
 -	C	- no exceptions - uses setjmp/longjmp
 -
 -	c	- DLL compatibility number indicating ABI and API
 -		  compatibility with applications built against
 -		  any snapshot with the same compatibility number.
 -		  See 'Version numbering' below.
 -
 -The name may also be suffixed by a 'd' to indicate a debugging version
 -of the library. E.g. pthreadVC2d.lib. Debugging versions contain
 -additional information for debugging (symbols etc) and are often not
 -optimised in any way (compiled with optimisation turned off).
 -
 -For example:
 -	pthreadVSE.dll	(MSVC/SEH)
 -	pthreadGCE.dll	(GNUC/C++ EH)
 -	pthreadGC.dll	(GNUC/not dependent on exceptions)
 -	pthreadVC1.dll	(MSVC/not dependent on exceptions - not binary
 -			compatible with pthreadVC.dll)
 -	pthreadVC2.dll	(MSVC/not dependent on exceptions - not binary
 -			compatible with pthreadVC1.dll or pthreadVC.dll)
 -
 -The GNU library archive file names have correspondingly changed to:
 -
 -	libpthreadGCEc.a
 -	libpthreadGCc.a
 -
 -
 -Versioning numbering
 ---------------------
 -
 -Version numbering is separate from the snapshot dating system, and
 -is the canonical version identification system embedded within the
 -DLL using the Microsoft version resource system. The versioning
 -system chosen follows the GNU Libtool system. See
 -http://www.gnu.org/software/libtool/manual.html section 6.2.
 -
 -See the resource file 'version.rc'.
 -
 -Microsoft version numbers use 4 integers:
 -
 -	0.0.0.0
 -
 -Pthreads-win32 uses the first 3 following the Libtool convention.
 -The fourth is commonly used for the build number, but will be reserved
 -for future use.
 -
 -	current.revision.age.0
 -
 -The numbers are changed as follows:
 -
 -1. If the library source code has changed at all since the last update,
 -   then increment revision (`c:r:a' becomes `c:r+1:a').
 -2. If any interfaces have been added, removed, or changed since the last
 -   update, increment current, and set revision to 0.
 -3. If any interfaces have been added since the last public release, then
 -   increment age.
 -4. If any interfaces have been removed or changed since the last public
 -   release, then set age to 0.
 -
 -
 -DLL compatibility numbering is an attempt to ensure that applications
 -always load a compatible pthreads-win32 DLL by using a DLL naming system
 -that is consistent with the version numbering system. It also allows
 -older and newer DLLs to coexist in the same filesystem so that older
 -applications can continue to be used. For pre .NET Windows systems,
 -this inevitably requires incompatible versions of the same DLLs to have
 -different names.
 -
 -Pthreads-win32 has adopted the Cygwin convention of appending a single
 -integer number to the DLL name. The number used is based on the library
 -version number and is computed as 'current' - 'age'.
 -
 -(See http://home.att.net/~perlspinr/libversioning.html for a nicely
 -detailed explanation.)
 -
 -Using this method, DLL name/s will only change when the DLL's
 -backwards compatibility changes. Note that the addition of new
 -'interfaces' will not of itself change the DLL's compatibility for older
 -applications.
 -
 -
 -Which of the several dll versions to use?
 ------------------------------------------
 -or,
 ----
 -What are all these pthread*.dll and pthread*.lib files?
 --------------------------------------------------------
 -
 -Simple, use either pthreadGCv.* if you use GCC, or pthreadVCv.* if you
 -use MSVC - where 'v' is the DLL versioning (compatibility) number.
 -
 -Otherwise, you need to choose carefully and know WHY.
 -
 -The most important choice you need to make is whether to use a
 -version that uses exceptions internally, or not. There are versions
 -of the library that use exceptions as part of the thread
 -cancelation and exit implementation. The default version uses
 -setjmp/longjmp.
 -
 -There is some contension amongst POSIX threads experts as
 -to how POSIX threads cancelation and exit should work
 -with languages that use exceptions, e.g. C++ and even C
 -(Microsoft's Structured Exceptions).
 -
 -The issue is: should cancelation of a thread in, say,
 -a C++ application cause object destructors and C++ exception
 -handlers to be invoked as the stack unwinds during thread
 -exit, or not?
 -
 -There seems to be more opinion in favour of using the
 -standard C version of the library (no EH) with C++ applications
 -for the reason that this appears to be the assumption commercial
 -pthreads implementations make. Therefore, if you use an EH version
 -of pthreads-win32 then you may be under the illusion that
 -your application will be portable, when in fact it is likely to
 -behave differently when linked with other pthreads libraries.
 -
 -Now you may be asking: then why have you kept the EH versions of
 -the library?
 -
 -There are a couple of reasons:
 -- there is division amongst the experts and so the code may
 -  be needed in the future. Yes, it's in the repository and we
 -  can get it out anytime in the future, but it would be difficult
 -  to find.
 -- pthreads-win32 is one of the few implementations, and possibly
 -  the only freely available one, that has EH versions. It may be
 -  useful to people who want to play with or study application
 -  behaviour under these conditions.
 -
 -Notes:
 -
 -[If you use either pthreadVCE or pthreadGCE]
 -
 -1. [See also the discussion in the FAQ file - Q2, Q4, and Q5]
 -
 -If your application contains catch(...) blocks in your POSIX
 -threads then you will need to replace the "catch(...)" with the macro
 -"PtW32Catch", eg.
 -
 -	#ifdef PtW32Catch
 -		PtW32Catch {
 -			...
 -		}
 -	#else
 -		catch(...) {
 -			...
 -		}
 -	#endif
 -
 -Otherwise neither pthreads cancelation nor pthread_exit() will work
 -reliably when using versions of the library that use C++ exceptions
 -for cancelation and thread exit.
 -
 -This is due to what is believed to be a C++ compliance error in VC++
 -whereby you may not have multiple handlers for the same exception in
 -the same try/catch block. GNU G++ doesn't have this restriction.
 -
 -
 -Other name changes
 -------------------
 -
 -All snapshots prior to and including snapshot 2000-08-13
 -used "_pthread_" as the prefix to library internal
 -functions, and "_PTHREAD_" to many library internal
 -macros. These have now been changed to "ptw32_" and "PTW32_"
 -respectively so as to not conflict with the ANSI standard's
 -reservation of identifiers beginning with "_" and "__" for
 -use by compiler implementations only.
 -
 -If you have written any applications and you are linking
 -statically with the pthreads-win32 library then you may have
 -included a call to _pthread_processInitialize. You will
 -now have to change that to ptw32_processInitialize.
 -
 -
 -Cleanup code default style
 ---------------------------
 -
 -Previously, if not defined, the cleanup style was determined automatically
 -from the compiler used, and one of the following was defined accordingly:
 -
 -	__CLEANUP_SEH	MSVC only
 -	__CLEANUP_CXX	C++, including MSVC++, GNU G++
 -	__CLEANUP_C	C, including GNU GCC, not MSVC
 -
 -These defines determine the style of cleanup (see pthread.h) and,
 -most importantly, the way that cancelation and thread exit (via
 -pthread_exit) is performed (see the routine ptw32_throw()).
 -
 -In short, the exceptions versions of the library throw an exception
 -when a thread is canceled, or exits via pthread_exit(). This exception is
 -caught by a handler in the thread startup routine, so that the
 -the correct stack unwinding occurs regardless of where the thread
 -is when it's canceled or exits via pthread_exit().
 -
 -In this snapshot, unless the build explicitly defines (e.g. via a
 -compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then
 -the build NOW always defaults to __CLEANUP_C style cleanup. This style
 -uses setjmp/longjmp in the cancelation and pthread_exit implementations,
 -and therefore won't do stack unwinding even when linked to applications
 -that have it (e.g. C++ apps). This is for consistency with most/all
 -commercial Unix POSIX threads implementations.
 -
 -Although it was not clearly documented before, it is still necessary to
 -build your application using the same __CLEANUP_* define as was
 -used for the version of the library that you link with, so that the
 -correct parts of pthread.h are included. That is, the possible
 -defines require the following library versions:
 -
 -	__CLEANUP_SEH	pthreadVSE.dll
 -	__CLEANUP_CXX	pthreadVCE.dll or pthreadGCE.dll
 -	__CLEANUP_C	pthreadVC.dll or pthreadGC.dll
 -
 -It is recommended that you let pthread.h use it's default __CLEANUP_C
 -for both library and application builds. That is, don't define any of
 -the above, and then link with pthreadVC.lib (MSVC or MSVC++) and
 -libpthreadGC.a (MinGW GCC or G++). The reason is explained below, but
 -another reason is that the prebuilt pthreadVCE.dll is currently broken.
 -Versions built with MSVC++ later than version 6 may not be broken, but I
 -can't verify this yet.
 -
 -WHY ARE WE MAKING THE DEFAULT STYLE LESS EXCEPTION-FRIENDLY?
 -Because no commercial Unix POSIX threads implementation allows you to
 -choose to have stack unwinding. Therefore, providing it in pthread-win32
 -as a default is dangerous. We still provide the choice but unless
 -you consciously choose to do otherwise, your pthreads applications will
 -now run or crash in similar ways irrespective of the pthreads platform
 -you use. Or at least this is the hope.
 -
 -
 -Building under VC++ using C++ EH, Structured EH, or just C
 -----------------------------------------------------------
 -
 -From the source directory run nmake without any arguments to list
 -help information. E.g.
 -
 -$ nmake
 -
 -Microsoft (R) Program Maintenance Utility   Version 6.00.8168.0
 -Copyright (C) Microsoft Corp 1988-1998. All rights reserved.
 -
 -Run one of the following command lines:
 -nmake clean VCE (to build the MSVC dll with C++ exception handling)
 -nmake clean VSE (to build the MSVC dll with structured exception handling)
 -nmake clean VC (to build the MSVC dll with C cleanup code)
 -nmake clean VCE-inlined (to build the MSVC inlined dll with C++ exception handling)
 -nmake clean VSE-inlined (to build the MSVC inlined dll with structured exception handling)
 -nmake clean VC-inlined (to build the MSVC inlined dll with C cleanup code)
 -nmake clean VC-static (to build the MSVC static lib with C cleanup code)
 -nmake clean VCE-debug (to build the debug MSVC dll with C++ exception handling)
 -nmake clean VSE-debug (to build the debug MSVC dll with structured exception handling)
 -nmake clean VC-debug (to build the debug MSVC dll with C cleanup code)
 -nmake clean VCE-inlined-debug (to build the debug MSVC inlined dll with C++ exception handling)
 -nmake clean VSE-inlined-debug (to build the debug MSVC inlined dll with structured exception handling)
 -nmake clean VC-inlined-debug (to build the debug MSVC inlined dll with C cleanup code)
 -nmake clean VC-static-debug (to build the debug MSVC static lib with C cleanup code)
 -
 -
 -The pre-built dlls are normally built using the *-inlined targets.
 -
 -You can run the testsuite by changing to the "tests" directory and
 -running nmake. E.g.:
 -
 -$ cd tests
 -$ nmake
 -
 -Microsoft (R) Program Maintenance Utility   Version 6.00.8168.0
 -Copyright (C) Microsoft Corp 1988-1998. All rights reserved.
 -
 -Run one of the following command lines:
 -nmake clean VC (to test using VC dll with VC (no EH) applications)
 -nmake clean VCX (to test using VC dll with VC++ (EH) applications)
 -nmake clean VCE (to test using the VCE dll with VC++ EH applications)
 -nmake clean VSE (to test using VSE dll with VC (SEH) applications)
 -nmake clean VC-bench (to benchtest using VC dll with C bench app)
 -nmake clean VCX-bench (to benchtest using VC dll with C++ bench app)
 -nmake clean VCE-bench (to benchtest using VCE dll with C++ bench app)
 -nmake clean VSE-bench (to benchtest using VSE dll with SEH bench app)
 -nmake clean VC-static (to test using VC static lib with VC (no EH) applications)
 -
 -
 -Building under Mingw32
 -----------------------
 -
 -The dll can be built easily with recent versions of Mingw32.
 -(The distributed versions are built using Mingw32 and MsysDTK
 -from www.mingw32.org.)
 -
 -From the source directory, run make for help information. E.g.:
 -
 -$ make
 -Run one of the following command lines:
 -make clean GC            (to build the GNU C dll with C cleanup code)
 -make clean GCE           (to build the GNU C dll with C++ exception handling)
 -make clean GC-inlined    (to build the GNU C inlined dll with C cleanup code)
 -make clean GCE-inlined   (to build the GNU C inlined dll with C++ exception handling)
 -make clean GC-static     (to build the GNU C inlined static lib with C cleanup code)
 -make clean GC-debug      (to build the GNU C debug dll with C cleanup code)
 -make clean GCE-debug     (to build the GNU C debug dll with C++ exception handling)
 -make clean GC-inlined-debug    (to build the GNU C inlined debug dll with C cleanup code)
 -make clean GCE-inlined-debug   (to build the GNU C inlined debug dll with C++ exception handling)
 -make clean GC-static-debug     (to build the GNU C inlined static debug lib with C cleanup code)
 -
 -
 -The pre-built dlls are normally built using the *-inlined targets.
 -
 -You can run the testsuite by changing to the "tests" directory and
 -running make for help information. E.g.:
 -
 -$ cd tests
 -$ make
 -Run one of the following command lines:
 -make clean GC    (to test using GC dll with C (no EH) applications)
 -make clean GCX   (to test using GC dll with C++ (EH) applications)
 -make clean GCE   (to test using GCE dll with C++ (EH) applications)
 -make clean GC-bench       (to benchtest using GNU C dll with C cleanup code)
 -make clean GCE-bench   (to benchtest using GNU C dll with C++ exception handling)
 -make clean GC-static   (to test using GC static lib with C (no EH) applications)
 -
 -
 -Building the library as a statically linkable library
 ------------------------------------------------------
 -
 -General: PTW32_STATIC_LIB must be defined for both the library build and the
 -application build. The following 'make' command lines will define this for the
 -static library builds.
 -
 -MSVC (creates pthreadVCnd.lib as a static link lib):
 -
 -nmake clean VC-static
 -
 -
 -MinGW32 (creates libpthreadGCn.a as a static link lib):
 -
 -make clean GC-static
 -
 -
 -Define PTW32_STATIC_LIB when building your application.
 -
 -The tests makefiles have the same targets but only check that the
 -static library is statically linkable. They don't run the full
 -testsuite. To run the full testsuite, build the dlls and run the
 -dll test targets.
 -
 -
 -Building the library under Cygwin
 ----------------------------------
 -
 -Cygwin is implementing it's own POSIX threads routines and these
 -will be the ones to use if you develop using Cygwin.
 -
 -
 -Ready to run binaries
 ----------------------
 -
 -For convenience, the following ready-to-run files can be downloaded
 -from the FTP site (see under "Availability" below):
 -
 -	pthread.h
 -	semaphore.h
 -	sched.h
 -	pthreadVC.dll	- built with MSVC compiler using C setjmp/longjmp
 -	pthreadVC.lib
 -	pthreadVCE.dll	- built with MSVC++ compiler using C++ EH
 -	pthreadVCE.lib
 -	pthreadVSE.dll	- built with MSVC compiler using SEH
 -	pthreadVSE.lib
 -	pthreadGC.dll	- built with Mingw32 GCC
 -	libpthreadGC.a	- derived from pthreadGC.dll
 -	pthreadGCE.dll	- built with Mingw32 G++
 -	libpthreadGCE.a	- derived from pthreadGCE.dll
 -
 -As of August 2003 pthreads-win32 pthreadG* versions are built and tested
 -using the MinGW + MsysDTK environment current as of that date or later.
 -The following file MAY be needed for older MinGW environments.
 -
 -	gcc.dll 	- needed to build and run applications that use
 -			  pthreadGCE.dll.
 -
 -
 -Building applications with GNU compilers
 -----------------------------------------
 -
 -If you're using pthreadGC.dll:
 -
 -With the three header files, pthreadGC.dll and libpthreadGC.a in the
 -same directory as your application myapp.c, you could compile, link
 -and run myapp.c under Mingw32 as follows:
 -
 -	gcc -o myapp.exe myapp.c -I. -L. -lpthreadGC
 -	myapp
 -
 -Or put pthreadGC.dll in an appropriate directory in your PATH,
 -put libpthreadGC.a in your system lib directory, and
 -put the three header files in your system include directory,
 -then use:
 -
 -	gcc -o myapp.exe myapp.c -lpthreadGC
 -	myapp
 -
 -
 -If you're using pthreadGCE.dll:
 -
 -With the three header files, pthreadGCE.dll, gcc.dll and libpthreadGCE.a
 -in the same directory as your application myapp.c, you could compile,
 -link and run myapp.c under Mingw32 as follows:
 -
 -	gcc -x c++ -o myapp.exe myapp.c -I. -L. -lpthreadGCE
 -	myapp
 -
 -Or put pthreadGCE.dll and gcc.dll in an appropriate directory in
 -your PATH, put libpthreadGCE.a in your system lib directory, and
 -put the three header files in your system include directory,
 -then use:
 -
 -	gcc -x c++ -o myapp.exe myapp.c -lpthreadGCE
 -	myapp
 -
 -
 -Availability
 -------------
 -
 -The complete source code in either unbundled, self-extracting
 -Zip file, or tar/gzipped format can be found at:
 -
 -	ftp://sources.redhat.com/pub/pthreads-win32
 -
 -The pre-built DLL, export libraries and matching pthread.h can
 -be found at:
 -
 -	ftp://sources.redhat.com/pub/pthreads-win32/dll-latest
 -
 -Home page:
 -
 -	http://sources.redhat.com/pthreads-win32/
 -
 -
 -Mailing list
 -------------
 -
 -There is a mailing list for discussing pthreads on Win32.
 -To join, send email to:
 -
 -	pthreads-win32-subscribe@sources.redhat.com
 -
 -Unsubscribe by sending mail to:
 -
 -	pthreads-win32-unsubscribe@sources.redhat.com
 -
 -
 -Acknowledgements
 -----------------
 -
 -See the ANNOUNCE file for acknowledgements.
 -See the 'CONTRIBUTORS' file for the list of contributors.
 -
 -As much as possible, the ChangeLog file attributes
 -contributions and patches that have been incorporated
 -in the library to the individuals responsible.
 -
 -Finally, thanks to all those who work on and contribute to the
 -POSIX and Single Unix Specification standards. The maturity of an
 -industry can be measured by it's open standards.
 -
 -----
 -Ross Johnson
 -<rpj@callisto.canberra.edu.au>
 -
 -
 -
 -
 -
 -
 -
 -
 +PTHREADS-WIN32 +============== + +Pthreads-win32 is free software, distributed under the GNU Lesser +General Public License (LGPL). See the file 'COPYING.LIB' for terms +and conditions. Also see the file 'COPYING' for information +specific to pthreads-win32, copyrights and the LGPL. + + +What is it? +----------- + +Pthreads-win32 is an Open Source Software implementation of the +Threads component of the POSIX 1003.1c 1995 Standard (or later) +for Microsoft's Win32 environment. Some functions from POSIX +1003.1b are also supported including semaphores. Other related +functions include the set of read-write lock functions. The +library also supports some of the functionality of the Open +Group's Single Unix specification, version 2, namely mutex types, +plus some common and pthreads-win32 specific non-portable +routines (see README.NONPORTABLE). + +See the file "ANNOUNCE" for more information including standards +conformance details and the list of supported and unsupported +routines. + + +Prerequisites +------------- +MSVC or GNU C (MinGW32 MSys development kit) +	To build from source. + +QueueUserAPCEx by Panagiotis E. Hadjidoukas +	For true async cancelation of threads (including blocked threads). +	This is a DLL and Windows driver that provides pre-emptive APC +	by forcing threads into an alertable state when the APC is queued. +	Both the DLL and driver are provided with the pthreads-win32.exe +	self-unpacking ZIP, and on the pthreads-win32 FTP site  (in source +	and pre-built forms). Currently this is a separate LGPL package to +	pthreads-win32. See the README in the QueueUserAPCEx folder for +	installation instructions. + +	Pthreads-win32 will automatically detect if the QueueUserAPCEx DLL +	QuserEx.DLL is available and whether the driver AlertDrv.sys is +	loaded. If it is not available, pthreads-win32 will simulate async +	cancelation, which means that it can async cancel only threads that +	are runnable. The simulated async cancellation cannot cancel blocked +	threads. + + +Library naming +-------------- + +Because the library is being built using various exception +handling schemes and compilers - and because the library +may not work reliably if these are mixed in an application, +each different version of the library has it's own name. + +Note 1: the incompatibility is really between EH implementations +of the different compilers. It should be possible to use the +standard C version from either compiler with C++ applications +built with a different compiler. If you use an EH version of +the library, then you must use the same compiler for the +application. This is another complication and dependency that +can be avoided by using only the standard C library version. + +Note 2: if you use a standard C pthread*.dll with a C++ +application, then any functions that you define that are +intended to be called via pthread_cleanup_push() must be +__cdecl. + +Note 3: the intention was to also name either the VC or GC +version (it should be arbitrary) as pthread.dll, including +pthread.lib and libpthread.a as appropriate. This is no longer +likely to happen. + +Note 4: the compatibility number was added so that applications +can differentiate between binary incompatible versions of the +libs and dlls. + +In general: +	pthread[VG]{SE,CE,C}c.dll +	pthread[VG]{SE,CE,C}c.lib + +where: +	[VG] indicates the compiler +	V	- MS VC, or +	G	- GNU C + +	{SE,CE,C} indicates the exception handling scheme +	SE	- Structured EH, or +	CE	- C++ EH, or +	C	- no exceptions - uses setjmp/longjmp + +	c	- DLL compatibility number indicating ABI and API +		  compatibility with applications built against +		  any snapshot with the same compatibility number. +		  See 'Version numbering' below. + +The name may also be suffixed by a 'd' to indicate a debugging version +of the library. E.g. pthreadVC2d.lib. Debugging versions contain +additional information for debugging (symbols etc) and are often not +optimised in any way (compiled with optimisation turned off). + +For example: +	pthreadVSE.dll	(MSVC/SEH) +	pthreadGCE.dll	(GNUC/C++ EH) +	pthreadGC.dll	(GNUC/not dependent on exceptions) +	pthreadVC1.dll	(MSVC/not dependent on exceptions - not binary +			compatible with pthreadVC.dll) +	pthreadVC2.dll	(MSVC/not dependent on exceptions - not binary +			compatible with pthreadVC1.dll or pthreadVC.dll) + +The GNU library archive file names have correspondingly changed to: + +	libpthreadGCEc.a +	libpthreadGCc.a + + +Versioning numbering +-------------------- + +Version numbering is separate from the snapshot dating system, and +is the canonical version identification system embedded within the +DLL using the Microsoft version resource system. The versioning +system chosen follows the GNU Libtool system. See +http://www.gnu.org/software/libtool/manual.html section 6.2. + +See the resource file 'version.rc'. + +Microsoft version numbers use 4 integers: + +	0.0.0.0 + +Pthreads-win32 uses the first 3 following the Libtool convention. +The fourth is commonly used for the build number, but will be reserved +for future use. + +	current.revision.age.0 + +The numbers are changed as follows: + +1. If the library source code has changed at all since the last update, +   then increment revision (`c:r:a' becomes `c:r+1:a'). +2. If any interfaces have been added, removed, or changed since the last +   update, increment current, and set revision to 0. +3. If any interfaces have been added since the last public release, then +   increment age. +4. If any interfaces have been removed or changed since the last public +   release, then set age to 0. + + +DLL compatibility numbering is an attempt to ensure that applications +always load a compatible pthreads-win32 DLL by using a DLL naming system +that is consistent with the version numbering system. It also allows +older and newer DLLs to coexist in the same filesystem so that older +applications can continue to be used. For pre .NET Windows systems, +this inevitably requires incompatible versions of the same DLLs to have +different names. + +Pthreads-win32 has adopted the Cygwin convention of appending a single +integer number to the DLL name. The number used is based on the library +version number and is computed as 'current' - 'age'. + +(See http://home.att.net/~perlspinr/libversioning.html for a nicely +detailed explanation.) + +Using this method, DLL name/s will only change when the DLL's +backwards compatibility changes. Note that the addition of new +'interfaces' will not of itself change the DLL's compatibility for older +applications. + + +Which of the several dll versions to use? +----------------------------------------- +or, +--- +What are all these pthread*.dll and pthread*.lib files? +------------------------------------------------------- + +Simple, use either pthreadGCv.* if you use GCC, or pthreadVCv.* if you +use MSVC - where 'v' is the DLL versioning (compatibility) number. + +Otherwise, you need to choose carefully and know WHY. + +The most important choice you need to make is whether to use a +version that uses exceptions internally, or not. There are versions +of the library that use exceptions as part of the thread +cancelation and exit implementation. The default version uses +setjmp/longjmp. + +There is some contension amongst POSIX threads experts as +to how POSIX threads cancelation and exit should work +with languages that use exceptions, e.g. C++ and even C +(Microsoft's Structured Exceptions). + +The issue is: should cancelation of a thread in, say, +a C++ application cause object destructors and C++ exception +handlers to be invoked as the stack unwinds during thread +exit, or not? + +There seems to be more opinion in favour of using the +standard C version of the library (no EH) with C++ applications +for the reason that this appears to be the assumption commercial +pthreads implementations make. Therefore, if you use an EH version +of pthreads-win32 then you may be under the illusion that +your application will be portable, when in fact it is likely to +behave differently when linked with other pthreads libraries. + +Now you may be asking: then why have you kept the EH versions of +the library? + +There are a couple of reasons: +- there is division amongst the experts and so the code may +  be needed in the future. Yes, it's in the repository and we +  can get it out anytime in the future, but it would be difficult +  to find. +- pthreads-win32 is one of the few implementations, and possibly +  the only freely available one, that has EH versions. It may be +  useful to people who want to play with or study application +  behaviour under these conditions. + +Notes: + +[If you use either pthreadVCE or pthreadGCE] + +1. [See also the discussion in the FAQ file - Q2, Q4, and Q5] + +If your application contains catch(...) blocks in your POSIX +threads then you will need to replace the "catch(...)" with the macro +"PtW32Catch", eg. + +	#ifdef PtW32Catch +		PtW32Catch { +			... +		} +	#else +		catch(...) { +			... +		} +	#endif + +Otherwise neither pthreads cancelation nor pthread_exit() will work +reliably when using versions of the library that use C++ exceptions +for cancelation and thread exit. + +This is due to what is believed to be a C++ compliance error in VC++ +whereby you may not have multiple handlers for the same exception in +the same try/catch block. GNU G++ doesn't have this restriction. + + +Other name changes +------------------ + +All snapshots prior to and including snapshot 2000-08-13 +used "_pthread_" as the prefix to library internal +functions, and "_PTHREAD_" to many library internal +macros. These have now been changed to "ptw32_" and "PTW32_" +respectively so as to not conflict with the ANSI standard's +reservation of identifiers beginning with "_" and "__" for +use by compiler implementations only. + +If you have written any applications and you are linking +statically with the pthreads-win32 library then you may have +included a call to _pthread_processInitialize. You will +now have to change that to ptw32_processInitialize. + + +Cleanup code default style +-------------------------- + +Previously, if not defined, the cleanup style was determined automatically +from the compiler used, and one of the following was defined accordingly: + +	__CLEANUP_SEH	MSVC only +	__CLEANUP_CXX	C++, including MSVC++, GNU G++ +	__CLEANUP_C	C, including GNU GCC, not MSVC + +These defines determine the style of cleanup (see pthread.h) and, +most importantly, the way that cancelation and thread exit (via +pthread_exit) is performed (see the routine ptw32_throw()). + +In short, the exceptions versions of the library throw an exception +when a thread is canceled, or exits via pthread_exit(). This exception is +caught by a handler in the thread startup routine, so that the +the correct stack unwinding occurs regardless of where the thread +is when it's canceled or exits via pthread_exit(). + +In this snapshot, unless the build explicitly defines (e.g. via a +compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then +the build NOW always defaults to __CLEANUP_C style cleanup. This style +uses setjmp/longjmp in the cancelation and pthread_exit implementations, +and therefore won't do stack unwinding even when linked to applications +that have it (e.g. C++ apps). This is for consistency with most/all +commercial Unix POSIX threads implementations. + +Although it was not clearly documented before, it is still necessary to +build your application using the same __CLEANUP_* define as was +used for the version of the library that you link with, so that the +correct parts of pthread.h are included. That is, the possible +defines require the following library versions: + +	__CLEANUP_SEH	pthreadVSE.dll +	__CLEANUP_CXX	pthreadVCE.dll or pthreadGCE.dll +	__CLEANUP_C	pthreadVC.dll or pthreadGC.dll + +It is recommended that you let pthread.h use it's default __CLEANUP_C +for both library and application builds. That is, don't define any of +the above, and then link with pthreadVC.lib (MSVC or MSVC++) and +libpthreadGC.a (MinGW GCC or G++). The reason is explained below, but +another reason is that the prebuilt pthreadVCE.dll is currently broken. +Versions built with MSVC++ later than version 6 may not be broken, but I +can't verify this yet. + +WHY ARE WE MAKING THE DEFAULT STYLE LESS EXCEPTION-FRIENDLY? +Because no commercial Unix POSIX threads implementation allows you to +choose to have stack unwinding. Therefore, providing it in pthread-win32 +as a default is dangerous. We still provide the choice but unless +you consciously choose to do otherwise, your pthreads applications will +now run or crash in similar ways irrespective of the pthreads platform +you use. Or at least this is the hope. + + +Building under VC++ using C++ EH, Structured EH, or just C +---------------------------------------------------------- + +From the source directory run nmake without any arguments to list +help information. E.g. + +$ nmake + +Microsoft (R) Program Maintenance Utility   Version 6.00.8168.0 +Copyright (C) Microsoft Corp 1988-1998. All rights reserved. + +Run one of the following command lines: +nmake clean VCE (to build the MSVC dll with C++ exception handling) +nmake clean VSE (to build the MSVC dll with structured exception handling) +nmake clean VC (to build the MSVC dll with C cleanup code) +nmake clean VCE-inlined (to build the MSVC inlined dll with C++ exception handling) +nmake clean VSE-inlined (to build the MSVC inlined dll with structured exception handling) +nmake clean VC-inlined (to build the MSVC inlined dll with C cleanup code) +nmake clean VC-static (to build the MSVC static lib with C cleanup code) +nmake clean VCE-debug (to build the debug MSVC dll with C++ exception handling) +nmake clean VSE-debug (to build the debug MSVC dll with structured exception handling) +nmake clean VC-debug (to build the debug MSVC dll with C cleanup code) +nmake clean VCE-inlined-debug (to build the debug MSVC inlined dll with C++ exception handling) +nmake clean VSE-inlined-debug (to build the debug MSVC inlined dll with structured exception handling) +nmake clean VC-inlined-debug (to build the debug MSVC inlined dll with C cleanup code) +nmake clean VC-static-debug (to build the debug MSVC static lib with C cleanup code) + + +The pre-built dlls are normally built using the *-inlined targets. + +You can run the testsuite by changing to the "tests" directory and +running nmake. E.g.: + +$ cd tests +$ nmake + +Microsoft (R) Program Maintenance Utility   Version 6.00.8168.0 +Copyright (C) Microsoft Corp 1988-1998. All rights reserved. + +Run one of the following command lines: +nmake clean VC (to test using VC dll with VC (no EH) applications) +nmake clean VCX (to test using VC dll with VC++ (EH) applications) +nmake clean VCE (to test using the VCE dll with VC++ EH applications) +nmake clean VSE (to test using VSE dll with VC (SEH) applications) +nmake clean VC-bench (to benchtest using VC dll with C bench app) +nmake clean VCX-bench (to benchtest using VC dll with C++ bench app) +nmake clean VCE-bench (to benchtest using VCE dll with C++ bench app) +nmake clean VSE-bench (to benchtest using VSE dll with SEH bench app) +nmake clean VC-static (to test using VC static lib with VC (no EH) applications) + + +Building under Mingw32 +---------------------- + +The dll can be built easily with recent versions of Mingw32. +(The distributed versions are built using Mingw32 and MsysDTK +from www.mingw32.org.) + +From the source directory, run make for help information. E.g.: + +$ make +Run one of the following command lines: +make clean GC            (to build the GNU C dll with C cleanup code) +make clean GCE           (to build the GNU C dll with C++ exception handling) +make clean GC-inlined    (to build the GNU C inlined dll with C cleanup code) +make clean GCE-inlined   (to build the GNU C inlined dll with C++ exception handling) +make clean GC-static     (to build the GNU C inlined static lib with C cleanup code) +make clean GC-debug      (to build the GNU C debug dll with C cleanup code) +make clean GCE-debug     (to build the GNU C debug dll with C++ exception handling) +make clean GC-inlined-debug    (to build the GNU C inlined debug dll with C cleanup code) +make clean GCE-inlined-debug   (to build the GNU C inlined debug dll with C++ exception handling) +make clean GC-static-debug     (to build the GNU C inlined static debug lib with C cleanup code) + + +The pre-built dlls are normally built using the *-inlined targets. + +You can run the testsuite by changing to the "tests" directory and +running make for help information. E.g.: + +$ cd tests +$ make +Run one of the following command lines: +make clean GC    (to test using GC dll with C (no EH) applications) +make clean GCX   (to test using GC dll with C++ (EH) applications) +make clean GCE   (to test using GCE dll with C++ (EH) applications) +make clean GC-bench       (to benchtest using GNU C dll with C cleanup code) +make clean GCE-bench   (to benchtest using GNU C dll with C++ exception handling) +make clean GC-static   (to test using GC static lib with C (no EH) applications) + + +Building the library as a statically linkable library +----------------------------------------------------- + +General: PTW32_STATIC_LIB must be defined for both the library build and the +application build. The following 'make' command lines will define this for the +static library builds. + +MSVC (creates pthreadVCnd.lib as a static link lib): + +nmake clean VC-static + + +MinGW32 (creates libpthreadGCn.a as a static link lib): + +make clean GC-static + + +Define PTW32_STATIC_LIB when building your application. + +The tests makefiles have the same targets but only check that the +static library is statically linkable. They don't run the full +testsuite. To run the full testsuite, build the dlls and run the +dll test targets. + + +Building the library under Cygwin +--------------------------------- + +Cygwin is implementing it's own POSIX threads routines and these +will be the ones to use if you develop using Cygwin. + + +Ready to run binaries +--------------------- + +For convenience, the following ready-to-run files can be downloaded +from the FTP site (see under "Availability" below): + +	pthread.h +	semaphore.h +	sched.h +	pthreadVC.dll	- built with MSVC compiler using C setjmp/longjmp +	pthreadVC.lib +	pthreadVCE.dll	- built with MSVC++ compiler using C++ EH +	pthreadVCE.lib +	pthreadVSE.dll	- built with MSVC compiler using SEH +	pthreadVSE.lib +	pthreadGC.dll	- built with Mingw32 GCC +	libpthreadGC.a	- derived from pthreadGC.dll +	pthreadGCE.dll	- built with Mingw32 G++ +	libpthreadGCE.a	- derived from pthreadGCE.dll + +As of August 2003 pthreads-win32 pthreadG* versions are built and tested +using the MinGW + MsysDTK environment current as of that date or later. +The following file MAY be needed for older MinGW environments. + +	gcc.dll 	- needed to build and run applications that use +			  pthreadGCE.dll. + + +Building applications with GNU compilers +---------------------------------------- + +If you're using pthreadGC.dll: + +With the three header files, pthreadGC.dll and libpthreadGC.a in the +same directory as your application myapp.c, you could compile, link +and run myapp.c under Mingw32 as follows: + +	gcc -o myapp.exe myapp.c -I. -L. -lpthreadGC +	myapp + +Or put pthreadGC.dll in an appropriate directory in your PATH, +put libpthreadGC.a in your system lib directory, and +put the three header files in your system include directory, +then use: + +	gcc -o myapp.exe myapp.c -lpthreadGC +	myapp + + +If you're using pthreadGCE.dll: + +With the three header files, pthreadGCE.dll, gcc.dll and libpthreadGCE.a +in the same directory as your application myapp.c, you could compile, +link and run myapp.c under Mingw32 as follows: + +	gcc -x c++ -o myapp.exe myapp.c -I. -L. -lpthreadGCE +	myapp + +Or put pthreadGCE.dll and gcc.dll in an appropriate directory in +your PATH, put libpthreadGCE.a in your system lib directory, and +put the three header files in your system include directory, +then use: + +	gcc -x c++ -o myapp.exe myapp.c -lpthreadGCE +	myapp + + +Availability +------------ + +The complete source code in either unbundled, self-extracting +Zip file, or tar/gzipped format can be found at: + +	ftp://sources.redhat.com/pub/pthreads-win32 + +The pre-built DLL, export libraries and matching pthread.h can +be found at: + +	ftp://sources.redhat.com/pub/pthreads-win32/dll-latest + +Home page: + +	http://sources.redhat.com/pthreads-win32/ + + +Mailing list +------------ + +There is a mailing list for discussing pthreads on Win32. +To join, send email to: + +	pthreads-win32-subscribe@sources.redhat.com + +Unsubscribe by sending mail to: + +	pthreads-win32-unsubscribe@sources.redhat.com + + +Acknowledgements +---------------- + +See the ANNOUNCE file for acknowledgements. +See the 'CONTRIBUTORS' file for the list of contributors. + +As much as possible, the ChangeLog file attributes +contributions and patches that have been incorporated +in the library to the individuals responsible. + +Finally, thanks to all those who work on and contribute to the +POSIX and Single Unix Specification standards. The maturity of an +industry can be measured by it's open standards. + +---- +Ross Johnson +<rpj@callisto.canberra.edu.au> + + + + + + + + diff --git a/README.Borland b/README.Borland index ffb6e8d..1694d55 100644 --- a/README.Borland +++ b/README.Borland @@ -1,47 +1,47 @@ -In ptw32_InterlockedCompareExchange.c, I've added a section for
 -Borland's compiler; it's identical to that for the MS compiler except
 +In ptw32_InterlockedCompareExchange.c, I've added a section for +Borland's compiler; it's identical to that for the MS compiler except  that it uses /* ... */ comments instead of ; comments.  [RPJ: need to define HAVE_TASM32 in config.h to use the above.] -
 - -The other file is a makefile suitable for use with Borland's compiler
 -(run "make -fBmakefile" in the directory).  It builds a single version
 -of the library, pthreadBC.dll and the corresponding pthreadBC.lib
 -import library, which is comparable to the pthreadVC version; I can't
 -personally see any demand for the versions that include structured or
 -C++ exception cancellation handling so I haven't attempted to build
 -those versions of the library.  (I imagine a static version might be
 -of use to some, but we can't legally use that on my commercial
 -projects so I can't try that out, unfortunately.)
 + + +The other file is a makefile suitable for use with Borland's compiler +(run "make -fBmakefile" in the directory).  It builds a single version +of the library, pthreadBC.dll and the corresponding pthreadBC.lib +import library, which is comparable to the pthreadVC version; I can't +personally see any demand for the versions that include structured or +C++ exception cancellation handling so I haven't attempted to build +those versions of the library.  (I imagine a static version might be +of use to some, but we can't legally use that on my commercial +projects so I can't try that out, unfortunately.)  [RPJ: Added tests\Bmakefile as well.] -Borland C++ doesn't define the ENOSYS constant used by pthreads-win32;
 -rather than make more extensive patches to the pthreads-win32 source I
 -have a mostly-arbitrary constant for it in the makefile.  However this
 -doesn't make it visible to the application using the library, so if
 -anyone actually wants to use this constant in their apps (why?)
 -someone might like to make a seperate NEED_BCC_something define to add
 -this stuff.
 +Borland C++ doesn't define the ENOSYS constant used by pthreads-win32; +rather than make more extensive patches to the pthreads-win32 source I +have a mostly-arbitrary constant for it in the makefile.  However this +doesn't make it visible to the application using the library, so if +anyone actually wants to use this constant in their apps (why?) +someone might like to make a seperate NEED_BCC_something define to add +this stuff. -The makefile also #defines EDEADLK as EDEADLOCK, _timeb as timeb, and
 -_ftime as ftime, to deal with the minor differences between the two
 -RTLs' naming conventions, and sets the compiler flags as required to
 -get a normal compile of the library.
 +The makefile also #defines EDEADLK as EDEADLOCK, _timeb as timeb, and +_ftime as ftime, to deal with the minor differences between the two +RTLs' naming conventions, and sets the compiler flags as required to +get a normal compile of the library.  [RPJ: Moved errno values and _timeb etc to pthread.h, so apps will also  use them.] -(While I'm on the subject, the reason Borland users should recompile
 -the library, rather than using the impdef/implib technique suggested
 -previously on the mailing list, is that a) the errno constants are
 -different, so the results returned by the pthread_* functions can be
 -meaningless, and b) the errno variable/pseudo-variable itself is
 -different in the MS & BCC runtimes, so you can't access the
 -pthreadVC's errno from a Borland C++-compiled host application
 -correctly - I imagine there are other potential problems from the RTL
 -mismatch too.)
 +(While I'm on the subject, the reason Borland users should recompile +the library, rather than using the impdef/implib technique suggested +previously on the mailing list, is that a) the errno constants are +different, so the results returned by the pthread_* functions can be +meaningless, and b) the errno variable/pseudo-variable itself is +different in the MS & BCC runtimes, so you can't access the +pthreadVC's errno from a Borland C++-compiled host application +correctly - I imagine there are other potential problems from the RTL +mismatch too.)  [RPJ: There are still problems with errno under Borland and the DLL  will not pass the testsuite yet because of it. Setting and then reading @@ -50,11 +50,11 @@ but DLL and application modules do not seem to be looking at the same  location for errno, even though they are logically running in the same  thread.] -Best regards,
 -Will
 +Best regards, +Will --- 
 -Will Bryant
 -Systems Architect, eCOSM Limited
 -Cell +64 21 655 443, office +64 3 365 4176
 -http://www.ecosm.com/
 +--  +Will Bryant +Systems Architect, eCOSM Limited +Cell +64 21 655 443, office +64 3 365 4176 +http://www.ecosm.com/ diff --git a/implement.h b/implement.h index 919d1cd..f92cc09 100644 --- a/implement.h +++ b/implement.h @@ -1,651 +1,651 @@ -/*
 - * implement.h
 - *
 - * Definitions that don't need to be public.
 - *
 - * Keeps all the internals out of pthread.h
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#ifndef _IMPLEMENT_H
 -#define _IMPLEMENT_H
 -
 -#ifdef _WIN32_WINNT
 -#undef _WIN32_WINNT
 -#endif
 -#define _WIN32_WINNT 0x400
 -
 -#include <windows.h>
 -
 -/*
 - * In case windows.h doesn't define it (e.g. WinCE perhaps)
 - */
 -#ifdef WINCE
 -typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam);
 -#endif
 -
 -/*
 - * note: ETIMEDOUT is correctly defined in winsock.h
 - */
 -#include <winsock.h>
 -
 -/*
 - * In case ETIMEDOUT hasn't been defined above somehow.
 - */
 -#ifndef ETIMEDOUT
 -#  define ETIMEDOUT 10060	/* This is the value in winsock.h. */
 -#endif
 -
 -#if !defined(malloc)
 -#include <malloc.h>
 -#endif
 -
 -#if !defined(INT_MAX)
 -#include <limits.h>
 -#endif
 -
 -/* use local include files during development */
 -#include "semaphore.h"
 -#include "sched.h"
 -
 -#if defined(HAVE_C_INLINE) || defined(__cplusplus)
 -#define INLINE inline
 -#else
 -#define INLINE
 -#endif
 -
 -#if defined (__MINGW32__) || (_MSC_VER >= 1300)
 -#define PTW32_INTERLOCKED_LONG long
 -#define PTW32_INTERLOCKED_LPLONG long*
 -#else
 -#define PTW32_INTERLOCKED_LONG PVOID
 -#define PTW32_INTERLOCKED_LPLONG PVOID*
 -#endif
 -
 -#if defined(__MINGW32__)
 -#include <stdint.h>
 -#else
 -#define int64_t _int64
 -#endif
 -
 -typedef enum
 -{
 -  /*
 -   * This enumeration represents the state of the thread;
 -   * The thread is still "alive" if the numeric value of the
 -   * state is greater or equal "PThreadStateRunning".
 -   */
 -  PThreadStateInitial = 0,	/* Thread not running                   */
 -  PThreadStateRunning,		/* Thread alive & kicking               */
 -  PThreadStateSuspended,	/* Thread alive but suspended           */
 -  PThreadStateCancelPending,	/* Thread alive but is                  */
 -  /* has cancelation pending.        */
 -  PThreadStateCanceling,	/* Thread alive but is                  */
 -  /* in the process of terminating        */
 -  /* due to a cancellation request        */
 -  PThreadStateException,	/* Thread alive but exiting             */
 -  /* due to an exception                  */
 -  PThreadStateLast
 -}
 -PThreadState;
 -
 -
 -typedef struct ptw32_thread_t_ ptw32_thread_t;
 -
 -struct ptw32_thread_t_
 -{
 -#ifdef _UWIN
 -  DWORD dummy[5];
 -#endif
 -  DWORD thread;
 -  HANDLE threadH;		/* Win32 thread handle - POSIX thread is invalid if threadH == 0 */
 -  pthread_t ptHandle;		/* This thread's permanent pthread_t handle */
 -  ptw32_thread_t * prevReuse;	/* Links threads on reuse stack */
 -  volatile PThreadState state;
 -  void *exitStatus;
 -  void *parms;
 -  int ptErrno;
 -  int detachState;
 -  pthread_mutex_t threadLock;	/* Used for serialised access to public thread state */
 -  int sched_priority;		/* As set, not as currently is */
 -  pthread_mutex_t cancelLock;	/* Used for async-cancel safety */
 -  int cancelState;
 -  int cancelType;
 -  HANDLE cancelEvent;
 -#ifdef __CLEANUP_C
 -  jmp_buf start_mark;
 -#endif				/* __CLEANUP_C */
 -#if HAVE_SIGSET_T
 -  sigset_t sigmask;
 -#endif				/* HAVE_SIGSET_T */
 -  int implicit:1;
 -  void *keys;
 -};
 -
 -
 -/* 
 - * Special value to mark attribute objects as valid.
 - */
 -#define PTW32_ATTR_VALID ((unsigned long) 0xC4C0FFEE)
 -
 -struct pthread_attr_t_
 -{
 -  unsigned long valid;
 -  void *stackaddr;
 -  size_t stacksize;
 -  int detachstate;
 -  struct sched_param param;
 -  int inheritsched;
 -  int contentionscope;
 -#if HAVE_SIGSET_T
 -  sigset_t sigmask;
 -#endif				/* HAVE_SIGSET_T */
 -};
 -
 -
 -/*
 - * ====================
 - * ====================
 - * Semaphores, Mutexes and Condition Variables
 - * ====================
 - * ====================
 - */
 -
 -struct sem_t_
 -{
 -  int value;
 -  pthread_mutex_t lock;
 -  HANDLE sem;
 -#ifdef NEED_SEM
 -  int leftToUnblock;
 -#endif
 -};
 -
 -#define PTW32_OBJECT_AUTO_INIT ((void *) -1)
 -#define PTW32_OBJECT_INVALID   NULL
 -
 -struct pthread_mutex_t_
 -{
 -  LONG lock_idx;		/* Provides exclusive access to mutex state
 -				   via the Interlocked* mechanism.
 -				    0: unlocked/free.
 -				    1: locked - no other waiters.
 -				   -1: locked - with possible other waiters.
 -				*/
 -  int recursive_count;		/* Number of unlocks a thread needs to perform
 -				   before the lock is released (recursive
 -				   mutexes only). */
 -  int kind;			/* Mutex type. */
 -  pthread_t ownerThread;
 -  HANDLE event;			/* Mutex release notification to waiting
 -				   threads. */
 -};
 -
 -struct pthread_mutexattr_t_
 -{
 -  int pshared;
 -  int kind;
 -};
 -
 -/*
 - * Possible values, other than PTW32_OBJECT_INVALID,
 - * for the "interlock" element in a spinlock.
 - *
 - * In this implementation, when a spinlock is initialised,
 - * the number of cpus available to the process is checked.
 - * If there is only one cpu then "interlock" is set equal to
 - * PTW32_SPIN_USE_MUTEX and u.mutex is a initialised mutex.
 - * If the number of cpus is greater than 1 then "interlock"
 - * is set equal to PTW32_SPIN_UNLOCKED and the number is
 - * stored in u.cpus. This arrangement allows the spinlock
 - * routines to attempt an InterlockedCompareExchange on "interlock"
 - * immediately and, if that fails, to try the inferior mutex.
 - *
 - * "u.cpus" isn't used for anything yet, but could be used at
 - * some point to optimise spinlock behaviour.
 - */
 -#define PTW32_SPIN_UNLOCKED    (1)
 -#define PTW32_SPIN_LOCKED      (2)
 -#define PTW32_SPIN_USE_MUTEX   (3)
 -
 -struct pthread_spinlock_t_
 -{
 -  long interlock;		/* Locking element for multi-cpus. */
 -  union
 -  {
 -    int cpus;			/* No. of cpus if multi cpus, or   */
 -    pthread_mutex_t mutex;	/* mutex if single cpu.            */
 -  } u;
 -};
 -
 -struct pthread_barrier_t_
 -{
 -  unsigned int nCurrentBarrierHeight;
 -  unsigned int nInitialBarrierHeight;
 -  int iStep;
 -  int pshared;
 -  sem_t semBarrierBreeched[2];
 -};
 -
 -struct pthread_barrierattr_t_
 -{
 -  int pshared;
 -};
 -
 -struct pthread_key_t_
 -{
 -  DWORD key;
 -  void (*destructor) (void *);
 -  pthread_mutex_t threadsLock;
 -  void *threads;
 -};
 -
 -
 -typedef struct ThreadParms ThreadParms;
 -typedef struct ThreadKeyAssoc ThreadKeyAssoc;
 -
 -struct ThreadParms
 -{
 -  pthread_t tid;
 -  void *(*start) (void *);
 -  void *arg;
 -};
 -
 -
 -struct pthread_cond_t_
 -{
 -  long nWaitersBlocked;		/* Number of threads blocked            */
 -  long nWaitersGone;		/* Number of threads timed out          */
 -  long nWaitersToUnblock;	/* Number of threads to unblock         */
 -  sem_t semBlockQueue;		/* Queue up threads waiting for the     */
 -  /*   condition to become signalled      */
 -  sem_t semBlockLock;		/* Semaphore that guards access to      */
 -  /* | waiters blocked count/block queue  */
 -  /* +-> Mandatory Sync.LEVEL-1           */
 -  pthread_mutex_t mtxUnblockLock;	/* Mutex that guards access to          */
 -  /* | waiters (to)unblock(ed) counts     */
 -  /* +-> Optional* Sync.LEVEL-2           */
 -  pthread_cond_t next;		/* Doubly linked list                   */
 -  pthread_cond_t prev;
 -};
 -
 -
 -struct pthread_condattr_t_
 -{
 -  int pshared;
 -};
 -
 -#define PTW32_RWLOCK_MAGIC 0xfacade2
 -
 -struct pthread_rwlock_t_
 -{
 -  pthread_mutex_t mtxExclusiveAccess;
 -  pthread_mutex_t mtxSharedAccessCompleted;
 -  pthread_cond_t cndSharedAccessCompleted;
 -  int nSharedAccessCount;
 -  int nExclusiveAccessCount;
 -  int nCompletedSharedAccessCount;
 -  int nMagic;
 -};
 -
 -struct pthread_rwlockattr_t_
 -{
 -  int pshared;
 -};
 -
 -enum ptw32_once_state {
 -  PTW32_ONCE_CLEAR     = 0x0,
 -  PTW32_ONCE_DONE      = 0x1,
 -  PTW32_ONCE_CANCELLED = 0x2
 -};
 -
 -typedef struct {
 -  pthread_cond_t cond;
 -  pthread_mutex_t mtx;
 -} ptw32_once_control_t;
 -
 -
 -struct ThreadKeyAssoc
 -{
 -  /*
 -   * Purpose:
 -   *      This structure creates an association between a
 -   *      thread and a key.
 -   *      It is used to implement the implicit invocation
 -   *      of a user defined destroy routine for thread
 -   *      specific data registered by a user upon exiting a
 -   *      thread.
 -   *
 -   * Attributes:
 -   *      lock
 -   *              protects access to the rest of the structure
 -   *
 -   *      thread
 -   *              reference to the thread that owns the association.
 -   *              As long as this is not NULL, the association remains
 -   *              referenced by the pthread_t.
 -   *
 -   *      key
 -   *              reference to the key that owns the association.
 -   *              As long as this is not NULL, the association remains
 -   *              referenced by the pthread_key_t.
 -   *
 -   *      nextKey
 -   *              The pthread_t->keys attribute is the head of a
 -   *              chain of associations that runs through the nextKey
 -   *              link. This chain provides the 1 to many relationship
 -   *              between a pthread_t and all pthread_key_t on which
 -   *              it called pthread_setspecific.
 -   *
 -   *      nextThread
 -   *              The pthread_key_t->threads attribute is the head of
 -   *              a chain of assoctiations that runs through the
 -   *              nextThreads link. This chain provides the 1 to many
 -   *              relationship between a pthread_key_t and all the 
 -   *              PThreads that have called pthread_setspecific for
 -   *              this pthread_key_t.
 -   *
 -   *
 -   * Notes:
 -   *      1)      As long as one of the attributes, thread or key, is
 -   *              not NULL, the association is being referenced; once
 -   *              both are NULL, the association must be released.
 -   *
 -   *      2)      Under WIN32, an association is only created by
 -   *              pthread_setspecific if the user provided a
 -   *              destroyRoutine when they created the key.
 -   *
 -   *
 -   */
 -  pthread_mutex_t lock;
 -  pthread_t thread;
 -  pthread_key_t key;
 -  ThreadKeyAssoc *nextKey;
 -  ThreadKeyAssoc *nextThread;
 -};
 -
 -
 -#ifdef __CLEANUP_SEH
 -/*
 - * --------------------------------------------------------------
 - * MAKE_SOFTWARE_EXCEPTION
 - *      This macro constructs a software exception code following
 - *      the same format as the standard Win32 error codes as defined
 - *      in WINERROR.H
 - *  Values are 32 bit values layed out as follows:
 - *
 - *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
 - *  +---+-+-+-----------------------+-------------------------------+
 - *  |Sev|C|R|     Facility          |               Code            |
 - *  +---+-+-+-----------------------+-------------------------------+
 - *
 - * Severity Values:
 - */
 -#define SE_SUCCESS              0x00
 -#define SE_INFORMATION          0x01
 -#define SE_WARNING              0x02
 -#define SE_ERROR                0x03
 -
 -#define MAKE_SOFTWARE_EXCEPTION( _severity, _facility, _exception ) \
 -( (DWORD) ( ( (_severity) << 30 ) |     /* Severity code        */ \
 -            ( 1 << 29 ) |               /* MS=0, User=1         */ \
 -            ( 0 << 28 ) |               /* Reserved             */ \
 -            ( (_facility) << 16 ) |     /* Facility Code        */ \
 -            ( (_exception) <<  0 )      /* Exception Code       */ \
 -            ) )
 -
 -/*
 - * We choose one specific Facility/Error code combination to
 - * identify our software exceptions vs. WIN32 exceptions.
 - * We store our actual component and error code within
 - * the optional information array.
 - */
 -#define EXCEPTION_PTW32_SERVICES        \
 -     MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \
 -                              PTW32_SERVICES_FACILITY, \
 -                              PTW32_SERVICES_ERROR )
 -
 -#define PTW32_SERVICES_FACILITY         0xBAD
 -#define PTW32_SERVICES_ERROR            0xDEED
 -
 -#endif /* __CLEANUP_SEH */
 -
 -/*
 - * Services available through EXCEPTION_PTW32_SERVICES
 - * and also used [as parameters to ptw32_throw()] as
 - * generic exception selectors.
 - */
 -
 -#define PTW32_EPS_EXIT                  (1)
 -#define PTW32_EPS_CANCEL                (2)
 -
 -
 -/* Useful macros */
 -#define PTW32_MAX(a,b)  ((a)<(b)?(b):(a))
 -#define PTW32_MIN(a,b)  ((a)>(b)?(b):(a))
 -
 -
 -/* Declared in global.c */
 -extern PTW32_INTERLOCKED_LONG (WINAPI *
 -			       ptw32_interlocked_compare_exchange)
 -  (PTW32_INTERLOCKED_LPLONG, PTW32_INTERLOCKED_LONG, PTW32_INTERLOCKED_LONG);
 -
 -/* Declared in pthread_cancel.c */
 -extern DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD);
 -
 -/* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */
 -#define PTW32_THREAD_REUSE_EMPTY ((ptw32_thread_t *) 1)
 -
 -extern int ptw32_processInitialized;
 -extern ptw32_thread_t * ptw32_threadReuseTop;
 -extern ptw32_thread_t * ptw32_threadReuseBottom;
 -extern pthread_key_t ptw32_selfThreadKey;
 -extern pthread_key_t ptw32_cleanupKey;
 -extern pthread_cond_t ptw32_cond_list_head;
 -extern pthread_cond_t ptw32_cond_list_tail;
 -
 -extern int ptw32_mutex_default_kind;
 -
 -extern int ptw32_concurrency;
 -
 -extern int ptw32_features;
 -
 -extern BOOL ptw32_smp_system;  /* True: SMP system, False: Uni-processor system */
 -
 -extern CRITICAL_SECTION ptw32_thread_reuse_lock;
 -extern CRITICAL_SECTION ptw32_mutex_test_init_lock;
 -extern CRITICAL_SECTION ptw32_cond_list_lock;
 -extern CRITICAL_SECTION ptw32_cond_test_init_lock;
 -extern CRITICAL_SECTION ptw32_rwlock_test_init_lock;
 -extern CRITICAL_SECTION ptw32_spinlock_test_init_lock;
 -extern CRITICAL_SECTION ptw32_once_event_lock;
 -
 -#ifdef _UWIN
 -extern int pthread_count;
 -#endif
 -
 -#ifdef __cplusplus
 -extern "C"
 -{
 -#endif				/* __cplusplus */
 -
 -/*
 - * =====================
 - * =====================
 - * Forward Declarations
 - * =====================
 - * =====================
 - */
 -
 -  int ptw32_is_attr (const pthread_attr_t * attr);
 -
 -  int ptw32_cond_check_need_init (pthread_cond_t * cond);
 -  int ptw32_mutex_check_need_init (pthread_mutex_t * mutex);
 -  int ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock);
 -
 -  PTW32_INTERLOCKED_LONG WINAPI
 -    ptw32_InterlockedCompareExchange (PTW32_INTERLOCKED_LPLONG location,
 -				      PTW32_INTERLOCKED_LONG value,
 -				      PTW32_INTERLOCKED_LONG comparand);
 -
 -  LONG WINAPI
 -    ptw32_InterlockedExchange (LPLONG location,
 -			       LONG value);
 -
 -  DWORD
 -    ptw32_RegisterCancelation (PAPCFUNC callback,
 -			       HANDLE threadH, DWORD callback_arg);
 -
 -  int ptw32_processInitialize (void);
 -
 -  void ptw32_processTerminate (void);
 -
 -  void ptw32_threadDestroy (pthread_t tid);
 -
 -  void ptw32_pop_cleanup_all (int execute);
 -
 -  pthread_t ptw32_new (void);
 -
 -  pthread_t ptw32_threadReusePop (void);
 -
 -  void ptw32_threadReusePush (pthread_t thread);
 -
 -  int ptw32_getprocessors (int *count);
 -
 -  int ptw32_setthreadpriority (pthread_t thread, int policy, int priority);
 -
 -  void ptw32_rwlock_cancelwrwait (void *arg);
 -
 -#if ! defined (__MINGW32__) || defined (__MSVCRT__)
 -  unsigned __stdcall
 -#else
 -  void
 -#endif
 -    ptw32_threadStart (void *vthreadParms);
 -
 -  void ptw32_callUserDestroyRoutines (pthread_t thread);
 -
 -  int ptw32_tkAssocCreate (ThreadKeyAssoc ** assocP,
 -			   pthread_t thread, pthread_key_t key);
 -
 -  void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc);
 -
 -  int ptw32_semwait (sem_t * sem);
 -
 -  DWORD ptw32_relmillisecs (const struct timespec * abstime);
 -
 -#ifdef NEED_FTIME
 -  void ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft);
 -  void ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts);
 -#endif
 -
 -/* Declared in misc.c */
 -#ifdef NEED_CALLOC
 -#define calloc(n, s) ptw32_calloc(n, s)
 -  void *ptw32_calloc (size_t n, size_t s);
 -#endif
 -
 -/* Declared in private.c */
 -  void ptw32_throw (DWORD exception);
 -
 -#ifdef __cplusplus
 -}
 -#endif				/* __cplusplus */
 -
 -
 -#ifdef _UWIN_
 -#   ifdef       _MT
 -#       ifdef __cplusplus
 -extern "C"
 -{
 -#       endif
 -  _CRTIMP unsigned long __cdecl _beginthread (void (__cdecl *) (void *),
 -					      unsigned, void *);
 -  _CRTIMP void __cdecl _endthread (void);
 -  _CRTIMP unsigned long __cdecl _beginthreadex (void *, unsigned,
 -						unsigned (__stdcall *) (void *),
 -						void *, unsigned, unsigned *);
 -  _CRTIMP void __cdecl _endthreadex (unsigned);
 -#       ifdef __cplusplus
 -}
 -#       endif
 -#   endif
 -#else
 -#   include <process.h>
 -#endif
 -
 -
 -/*
 - * Defaults. Could be overridden when building the inlined version of the dll.
 - * See ptw32_InterlockedCompareExchange.c
 - */
 -#ifndef PTW32_INTERLOCKED_COMPARE_EXCHANGE
 -#define PTW32_INTERLOCKED_COMPARE_EXCHANGE ptw32_interlocked_compare_exchange
 -#endif
 -
 -#ifndef PTW32_INTERLOCKED_EXCHANGE
 -#define PTW32_INTERLOCKED_EXCHANGE InterlockedExchange
 -#endif
 -
 -
 -/*
 - * Check for old and new versions of cygwin. See the FAQ file:
 - *
 - * Question 1 - How do I get pthreads-win32 to link under Cygwin or Mingw32?
 - *
 - * Patch by Anders Norlander <anorland@hem2.passagen.se>
 - */
 -#if defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(NEED_CREATETHREAD)
 -
 -/* 
 - * Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE
 - * in order to avoid warnings because of return type
 - */
 -
 -#define _beginthreadex(security, \
 -                       stack_size, \
 -                       start_proc, \
 -                       arg, \
 -                       flags, \
 -                       pid) \
 -        CreateThread(security, \
 -                     stack_size, \
 -                     (LPTHREAD_START_ROUTINE) start_proc, \
 -                     arg, \
 -                     flags, \
 -                     pid)
 -
 -#define _endthreadex ExitThread
 -
 -#endif				/* __CYGWIN32__ || __CYGWIN__ || NEED_CREATETHREAD */
 -
 -
 -#endif				/* _IMPLEMENT_H */
 +/* + * implement.h + * + * Definitions that don't need to be public. + * + * Keeps all the internals out of pthread.h + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef _IMPLEMENT_H +#define _IMPLEMENT_H + +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x400 + +#include <windows.h> + +/* + * In case windows.h doesn't define it (e.g. WinCE perhaps) + */ +#ifdef WINCE +typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam); +#endif + +/* + * note: ETIMEDOUT is correctly defined in winsock.h + */ +#include <winsock.h> + +/* + * In case ETIMEDOUT hasn't been defined above somehow. + */ +#ifndef ETIMEDOUT +#  define ETIMEDOUT 10060	/* This is the value in winsock.h. */ +#endif + +#if !defined(malloc) +#include <malloc.h> +#endif + +#if !defined(INT_MAX) +#include <limits.h> +#endif + +/* use local include files during development */ +#include "semaphore.h" +#include "sched.h" + +#if defined(HAVE_C_INLINE) || defined(__cplusplus) +#define INLINE inline +#else +#define INLINE +#endif + +#if defined (__MINGW32__) || (_MSC_VER >= 1300) +#define PTW32_INTERLOCKED_LONG long +#define PTW32_INTERLOCKED_LPLONG long* +#else +#define PTW32_INTERLOCKED_LONG PVOID +#define PTW32_INTERLOCKED_LPLONG PVOID* +#endif + +#if defined(__MINGW32__) +#include <stdint.h> +#else +#define int64_t _int64 +#endif + +typedef enum +{ +  /* +   * This enumeration represents the state of the thread; +   * The thread is still "alive" if the numeric value of the +   * state is greater or equal "PThreadStateRunning". +   */ +  PThreadStateInitial = 0,	/* Thread not running                   */ +  PThreadStateRunning,		/* Thread alive & kicking               */ +  PThreadStateSuspended,	/* Thread alive but suspended           */ +  PThreadStateCancelPending,	/* Thread alive but is                  */ +  /* has cancelation pending.        */ +  PThreadStateCanceling,	/* Thread alive but is                  */ +  /* in the process of terminating        */ +  /* due to a cancellation request        */ +  PThreadStateException,	/* Thread alive but exiting             */ +  /* due to an exception                  */ +  PThreadStateLast +} +PThreadState; + + +typedef struct ptw32_thread_t_ ptw32_thread_t; + +struct ptw32_thread_t_ +{ +#ifdef _UWIN +  DWORD dummy[5]; +#endif +  DWORD thread; +  HANDLE threadH;		/* Win32 thread handle - POSIX thread is invalid if threadH == 0 */ +  pthread_t ptHandle;		/* This thread's permanent pthread_t handle */ +  ptw32_thread_t * prevReuse;	/* Links threads on reuse stack */ +  volatile PThreadState state; +  void *exitStatus; +  void *parms; +  int ptErrno; +  int detachState; +  pthread_mutex_t threadLock;	/* Used for serialised access to public thread state */ +  int sched_priority;		/* As set, not as currently is */ +  pthread_mutex_t cancelLock;	/* Used for async-cancel safety */ +  int cancelState; +  int cancelType; +  HANDLE cancelEvent; +#ifdef __CLEANUP_C +  jmp_buf start_mark; +#endif				/* __CLEANUP_C */ +#if HAVE_SIGSET_T +  sigset_t sigmask; +#endif				/* HAVE_SIGSET_T */ +  int implicit:1; +  void *keys; +}; + + +/*  + * Special value to mark attribute objects as valid. + */ +#define PTW32_ATTR_VALID ((unsigned long) 0xC4C0FFEE) + +struct pthread_attr_t_ +{ +  unsigned long valid; +  void *stackaddr; +  size_t stacksize; +  int detachstate; +  struct sched_param param; +  int inheritsched; +  int contentionscope; +#if HAVE_SIGSET_T +  sigset_t sigmask; +#endif				/* HAVE_SIGSET_T */ +}; + + +/* + * ==================== + * ==================== + * Semaphores, Mutexes and Condition Variables + * ==================== + * ==================== + */ + +struct sem_t_ +{ +  int value; +  pthread_mutex_t lock; +  HANDLE sem; +#ifdef NEED_SEM +  int leftToUnblock; +#endif +}; + +#define PTW32_OBJECT_AUTO_INIT ((void *) -1) +#define PTW32_OBJECT_INVALID   NULL + +struct pthread_mutex_t_ +{ +  LONG lock_idx;		/* Provides exclusive access to mutex state +				   via the Interlocked* mechanism. +				    0: unlocked/free. +				    1: locked - no other waiters. +				   -1: locked - with possible other waiters. +				*/ +  int recursive_count;		/* Number of unlocks a thread needs to perform +				   before the lock is released (recursive +				   mutexes only). */ +  int kind;			/* Mutex type. */ +  pthread_t ownerThread; +  HANDLE event;			/* Mutex release notification to waiting +				   threads. */ +}; + +struct pthread_mutexattr_t_ +{ +  int pshared; +  int kind; +}; + +/* + * Possible values, other than PTW32_OBJECT_INVALID, + * for the "interlock" element in a spinlock. + * + * In this implementation, when a spinlock is initialised, + * the number of cpus available to the process is checked. + * If there is only one cpu then "interlock" is set equal to + * PTW32_SPIN_USE_MUTEX and u.mutex is a initialised mutex. + * If the number of cpus is greater than 1 then "interlock" + * is set equal to PTW32_SPIN_UNLOCKED and the number is + * stored in u.cpus. This arrangement allows the spinlock + * routines to attempt an InterlockedCompareExchange on "interlock" + * immediately and, if that fails, to try the inferior mutex. + * + * "u.cpus" isn't used for anything yet, but could be used at + * some point to optimise spinlock behaviour. + */ +#define PTW32_SPIN_UNLOCKED    (1) +#define PTW32_SPIN_LOCKED      (2) +#define PTW32_SPIN_USE_MUTEX   (3) + +struct pthread_spinlock_t_ +{ +  long interlock;		/* Locking element for multi-cpus. */ +  union +  { +    int cpus;			/* No. of cpus if multi cpus, or   */ +    pthread_mutex_t mutex;	/* mutex if single cpu.            */ +  } u; +}; + +struct pthread_barrier_t_ +{ +  unsigned int nCurrentBarrierHeight; +  unsigned int nInitialBarrierHeight; +  int iStep; +  int pshared; +  sem_t semBarrierBreeched[2]; +}; + +struct pthread_barrierattr_t_ +{ +  int pshared; +}; + +struct pthread_key_t_ +{ +  DWORD key; +  void (*destructor) (void *); +  pthread_mutex_t threadsLock; +  void *threads; +}; + + +typedef struct ThreadParms ThreadParms; +typedef struct ThreadKeyAssoc ThreadKeyAssoc; + +struct ThreadParms +{ +  pthread_t tid; +  void *(*start) (void *); +  void *arg; +}; + + +struct pthread_cond_t_ +{ +  long nWaitersBlocked;		/* Number of threads blocked            */ +  long nWaitersGone;		/* Number of threads timed out          */ +  long nWaitersToUnblock;	/* Number of threads to unblock         */ +  sem_t semBlockQueue;		/* Queue up threads waiting for the     */ +  /*   condition to become signalled      */ +  sem_t semBlockLock;		/* Semaphore that guards access to      */ +  /* | waiters blocked count/block queue  */ +  /* +-> Mandatory Sync.LEVEL-1           */ +  pthread_mutex_t mtxUnblockLock;	/* Mutex that guards access to          */ +  /* | waiters (to)unblock(ed) counts     */ +  /* +-> Optional* Sync.LEVEL-2           */ +  pthread_cond_t next;		/* Doubly linked list                   */ +  pthread_cond_t prev; +}; + + +struct pthread_condattr_t_ +{ +  int pshared; +}; + +#define PTW32_RWLOCK_MAGIC 0xfacade2 + +struct pthread_rwlock_t_ +{ +  pthread_mutex_t mtxExclusiveAccess; +  pthread_mutex_t mtxSharedAccessCompleted; +  pthread_cond_t cndSharedAccessCompleted; +  int nSharedAccessCount; +  int nExclusiveAccessCount; +  int nCompletedSharedAccessCount; +  int nMagic; +}; + +struct pthread_rwlockattr_t_ +{ +  int pshared; +}; + +enum ptw32_once_state { +  PTW32_ONCE_CLEAR     = 0x0, +  PTW32_ONCE_DONE      = 0x1, +  PTW32_ONCE_CANCELLED = 0x2 +}; + +typedef struct { +  pthread_cond_t cond; +  pthread_mutex_t mtx; +} ptw32_once_control_t; + + +struct ThreadKeyAssoc +{ +  /* +   * Purpose: +   *      This structure creates an association between a +   *      thread and a key. +   *      It is used to implement the implicit invocation +   *      of a user defined destroy routine for thread +   *      specific data registered by a user upon exiting a +   *      thread. +   * +   * Attributes: +   *      lock +   *              protects access to the rest of the structure +   * +   *      thread +   *              reference to the thread that owns the association. +   *              As long as this is not NULL, the association remains +   *              referenced by the pthread_t. +   * +   *      key +   *              reference to the key that owns the association. +   *              As long as this is not NULL, the association remains +   *              referenced by the pthread_key_t. +   * +   *      nextKey +   *              The pthread_t->keys attribute is the head of a +   *              chain of associations that runs through the nextKey +   *              link. This chain provides the 1 to many relationship +   *              between a pthread_t and all pthread_key_t on which +   *              it called pthread_setspecific. +   * +   *      nextThread +   *              The pthread_key_t->threads attribute is the head of +   *              a chain of assoctiations that runs through the +   *              nextThreads link. This chain provides the 1 to many +   *              relationship between a pthread_key_t and all the  +   *              PThreads that have called pthread_setspecific for +   *              this pthread_key_t. +   * +   * +   * Notes: +   *      1)      As long as one of the attributes, thread or key, is +   *              not NULL, the association is being referenced; once +   *              both are NULL, the association must be released. +   * +   *      2)      Under WIN32, an association is only created by +   *              pthread_setspecific if the user provided a +   *              destroyRoutine when they created the key. +   * +   * +   */ +  pthread_mutex_t lock; +  pthread_t thread; +  pthread_key_t key; +  ThreadKeyAssoc *nextKey; +  ThreadKeyAssoc *nextThread; +}; + + +#ifdef __CLEANUP_SEH +/* + * -------------------------------------------------------------- + * MAKE_SOFTWARE_EXCEPTION + *      This macro constructs a software exception code following + *      the same format as the standard Win32 error codes as defined + *      in WINERROR.H + *  Values are 32 bit values layed out as follows: + * + *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + *  +---+-+-+-----------------------+-------------------------------+ + *  |Sev|C|R|     Facility          |               Code            | + *  +---+-+-+-----------------------+-------------------------------+ + * + * Severity Values: + */ +#define SE_SUCCESS              0x00 +#define SE_INFORMATION          0x01 +#define SE_WARNING              0x02 +#define SE_ERROR                0x03 + +#define MAKE_SOFTWARE_EXCEPTION( _severity, _facility, _exception ) \ +( (DWORD) ( ( (_severity) << 30 ) |     /* Severity code        */ \ +            ( 1 << 29 ) |               /* MS=0, User=1         */ \ +            ( 0 << 28 ) |               /* Reserved             */ \ +            ( (_facility) << 16 ) |     /* Facility Code        */ \ +            ( (_exception) <<  0 )      /* Exception Code       */ \ +            ) ) + +/* + * We choose one specific Facility/Error code combination to + * identify our software exceptions vs. WIN32 exceptions. + * We store our actual component and error code within + * the optional information array. + */ +#define EXCEPTION_PTW32_SERVICES        \ +     MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \ +                              PTW32_SERVICES_FACILITY, \ +                              PTW32_SERVICES_ERROR ) + +#define PTW32_SERVICES_FACILITY         0xBAD +#define PTW32_SERVICES_ERROR            0xDEED + +#endif /* __CLEANUP_SEH */ + +/* + * Services available through EXCEPTION_PTW32_SERVICES + * and also used [as parameters to ptw32_throw()] as + * generic exception selectors. + */ + +#define PTW32_EPS_EXIT                  (1) +#define PTW32_EPS_CANCEL                (2) + + +/* Useful macros */ +#define PTW32_MAX(a,b)  ((a)<(b)?(b):(a)) +#define PTW32_MIN(a,b)  ((a)>(b)?(b):(a)) + + +/* Declared in global.c */ +extern PTW32_INTERLOCKED_LONG (WINAPI * +			       ptw32_interlocked_compare_exchange) +  (PTW32_INTERLOCKED_LPLONG, PTW32_INTERLOCKED_LONG, PTW32_INTERLOCKED_LONG); + +/* Declared in pthread_cancel.c */ +extern DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD); + +/* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */ +#define PTW32_THREAD_REUSE_EMPTY ((ptw32_thread_t *) 1) + +extern int ptw32_processInitialized; +extern ptw32_thread_t * ptw32_threadReuseTop; +extern ptw32_thread_t * ptw32_threadReuseBottom; +extern pthread_key_t ptw32_selfThreadKey; +extern pthread_key_t ptw32_cleanupKey; +extern pthread_cond_t ptw32_cond_list_head; +extern pthread_cond_t ptw32_cond_list_tail; + +extern int ptw32_mutex_default_kind; + +extern int ptw32_concurrency; + +extern int ptw32_features; + +extern BOOL ptw32_smp_system;  /* True: SMP system, False: Uni-processor system */ + +extern CRITICAL_SECTION ptw32_thread_reuse_lock; +extern CRITICAL_SECTION ptw32_mutex_test_init_lock; +extern CRITICAL_SECTION ptw32_cond_list_lock; +extern CRITICAL_SECTION ptw32_cond_test_init_lock; +extern CRITICAL_SECTION ptw32_rwlock_test_init_lock; +extern CRITICAL_SECTION ptw32_spinlock_test_init_lock; +extern CRITICAL_SECTION ptw32_once_event_lock; + +#ifdef _UWIN +extern int pthread_count; +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif				/* __cplusplus */ + +/* + * ===================== + * ===================== + * Forward Declarations + * ===================== + * ===================== + */ + +  int ptw32_is_attr (const pthread_attr_t * attr); + +  int ptw32_cond_check_need_init (pthread_cond_t * cond); +  int ptw32_mutex_check_need_init (pthread_mutex_t * mutex); +  int ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock); + +  PTW32_INTERLOCKED_LONG WINAPI +    ptw32_InterlockedCompareExchange (PTW32_INTERLOCKED_LPLONG location, +				      PTW32_INTERLOCKED_LONG value, +				      PTW32_INTERLOCKED_LONG comparand); + +  LONG WINAPI +    ptw32_InterlockedExchange (LPLONG location, +			       LONG value); + +  DWORD +    ptw32_RegisterCancelation (PAPCFUNC callback, +			       HANDLE threadH, DWORD callback_arg); + +  int ptw32_processInitialize (void); + +  void ptw32_processTerminate (void); + +  void ptw32_threadDestroy (pthread_t tid); + +  void ptw32_pop_cleanup_all (int execute); + +  pthread_t ptw32_new (void); + +  pthread_t ptw32_threadReusePop (void); + +  void ptw32_threadReusePush (pthread_t thread); + +  int ptw32_getprocessors (int *count); + +  int ptw32_setthreadpriority (pthread_t thread, int policy, int priority); + +  void ptw32_rwlock_cancelwrwait (void *arg); + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) +  unsigned __stdcall +#else +  void +#endif +    ptw32_threadStart (void *vthreadParms); + +  void ptw32_callUserDestroyRoutines (pthread_t thread); + +  int ptw32_tkAssocCreate (ThreadKeyAssoc ** assocP, +			   pthread_t thread, pthread_key_t key); + +  void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc); + +  int ptw32_semwait (sem_t * sem); + +  DWORD ptw32_relmillisecs (const struct timespec * abstime); + +#ifdef NEED_FTIME +  void ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft); +  void ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts); +#endif + +/* Declared in misc.c */ +#ifdef NEED_CALLOC +#define calloc(n, s) ptw32_calloc(n, s) +  void *ptw32_calloc (size_t n, size_t s); +#endif + +/* Declared in private.c */ +  void ptw32_throw (DWORD exception); + +#ifdef __cplusplus +} +#endif				/* __cplusplus */ + + +#ifdef _UWIN_ +#   ifdef       _MT +#       ifdef __cplusplus +extern "C" +{ +#       endif +  _CRTIMP unsigned long __cdecl _beginthread (void (__cdecl *) (void *), +					      unsigned, void *); +  _CRTIMP void __cdecl _endthread (void); +  _CRTIMP unsigned long __cdecl _beginthreadex (void *, unsigned, +						unsigned (__stdcall *) (void *), +						void *, unsigned, unsigned *); +  _CRTIMP void __cdecl _endthreadex (unsigned); +#       ifdef __cplusplus +} +#       endif +#   endif +#else +#   include <process.h> +#endif + + +/* + * Defaults. Could be overridden when building the inlined version of the dll. + * See ptw32_InterlockedCompareExchange.c + */ +#ifndef PTW32_INTERLOCKED_COMPARE_EXCHANGE +#define PTW32_INTERLOCKED_COMPARE_EXCHANGE ptw32_interlocked_compare_exchange +#endif + +#ifndef PTW32_INTERLOCKED_EXCHANGE +#define PTW32_INTERLOCKED_EXCHANGE InterlockedExchange +#endif + + +/* + * Check for old and new versions of cygwin. See the FAQ file: + * + * Question 1 - How do I get pthreads-win32 to link under Cygwin or Mingw32? + * + * Patch by Anders Norlander <anorland@hem2.passagen.se> + */ +#if defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(NEED_CREATETHREAD) + +/*  + * Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE + * in order to avoid warnings because of return type + */ + +#define _beginthreadex(security, \ +                       stack_size, \ +                       start_proc, \ +                       arg, \ +                       flags, \ +                       pid) \ +        CreateThread(security, \ +                     stack_size, \ +                     (LPTHREAD_START_ROUTINE) start_proc, \ +                     arg, \ +                     flags, \ +                     pid) + +#define _endthreadex ExitThread + +#endif				/* __CYGWIN32__ || __CYGWIN__ || NEED_CREATETHREAD */ + + +#endif				/* _IMPLEMENT_H */ @@ -1,56 +1,56 @@ -/*
 - * private.c
 - *
 - * Description:
 - * This translation unit implements routines which are private to
 - * the implementation and may be used throughout it.
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#include "pthread.h"
 -#include "implement.h"
 -
 -/* Must be first to define HAVE_INLINABLE_INTERLOCKED_CMPXCHG */
 -#include "ptw32_InterlockedCompareExchange.c"
 -
 -#include "ptw32_is_attr.c"
 -#include "ptw32_processInitialize.c"
 -#include "ptw32_processTerminate.c"
 -#include "ptw32_threadStart.c"
 -#include "ptw32_threadDestroy.c"
 -#include "ptw32_tkAssocCreate.c"
 -#include "ptw32_tkAssocDestroy.c"
 -#include "ptw32_callUserDestroyRoutines.c"
 -#include "ptw32_semwait.c"
 -#include "ptw32_timespec.c"
 -#include "ptw32_relmillisecs.c"
 -#include "ptw32_throw.c"
 -#include "ptw32_getprocessors.c"
 +/* + * private.c + * + * Description: + * This translation unit implements routines which are private to + * the implementation and may be used throughout it. + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + +/* Must be first to define HAVE_INLINABLE_INTERLOCKED_CMPXCHG */ +#include "ptw32_InterlockedCompareExchange.c" + +#include "ptw32_is_attr.c" +#include "ptw32_processInitialize.c" +#include "ptw32_processTerminate.c" +#include "ptw32_threadStart.c" +#include "ptw32_threadDestroy.c" +#include "ptw32_tkAssocCreate.c" +#include "ptw32_tkAssocDestroy.c" +#include "ptw32_callUserDestroyRoutines.c" +#include "ptw32_semwait.c" +#include "ptw32_timespec.c" +#include "ptw32_relmillisecs.c" +#include "ptw32_throw.c" +#include "ptw32_getprocessors.c" diff --git a/pthread.dsp b/pthread.dsp index 5b0228d..6aa87de 100644 --- a/pthread.dsp +++ b/pthread.dsp @@ -1,142 +1,142 @@ -# Microsoft Developer Studio Project File - Name="pthread" - Package Owner=<4>
 -# Microsoft Developer Studio Generated Build File, Format Version 6.00
 -# ** DO NOT EDIT **
 -
 -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
 -
 -CFG=pthread - Win32 Debug
 -!MESSAGE This is not a valid makefile. To build this project using NMAKE,
 -!MESSAGE use the Export Makefile command and run
 -!MESSAGE 
 -!MESSAGE NMAKE /f "pthread.mak".
 -!MESSAGE 
 -!MESSAGE You can specify a configuration when running NMAKE
 -!MESSAGE by defining the macro CFG on the command line. For example:
 -!MESSAGE 
 -!MESSAGE NMAKE /f "pthread.mak" CFG="pthread - Win32 Debug"
 -!MESSAGE 
 -!MESSAGE Possible choices for configuration are:
 -!MESSAGE 
 -!MESSAGE "pthread - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
 -!MESSAGE "pthread - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
 -!MESSAGE 
 -
 -# Begin Project
 -# PROP AllowPerConfigDependencies 0
 -# PROP Scc_ProjName ""
 -# PROP Scc_LocalPath ""
 -CPP=cl.exe
 -MTL=midl.exe
 -RSC=rc.exe
 -
 -!IF  "$(CFG)" == "pthread - Win32 Release"
 -
 -# PROP BASE Use_MFC 0
 -# PROP BASE Use_Debug_Libraries 0
 -# PROP BASE Output_Dir "Release"
 -# PROP BASE Intermediate_Dir "Release"
 -# PROP BASE Target_Dir ""
 -# PROP Use_MFC 0
 -# PROP Use_Debug_Libraries 0
 -# PROP Output_Dir "."
 -# PROP Intermediate_Dir "."
 -# PROP Ignore_Export_Lib 0
 -# PROP Target_Dir ""
 -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /c
 -# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "__CLEANUP_C" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /c
 -# SUBTRACT CPP /u
 -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 -# ADD BASE RSC /l 0x809 /d "NDEBUG"
 -# ADD RSC /l 0x409 /i "." /d "NDEBUG" /d "PTW32_RC_MSC"
 -BSC32=bscmake.exe
 -# ADD BASE BSC32 /nologo
 -# ADD BSC32 /nologo
 -LINK32=link.exe
 -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
 -# ADD LINK32 kernel32.lib user32.lib ws2_32.lib /nologo /dll /pdb:none /machine:I386 /out:".\pthreadVC.dll"
 -
 -!ELSEIF  "$(CFG)" == "pthread - Win32 Debug"
 -
 -# PROP BASE Use_MFC 0
 -# PROP BASE Use_Debug_Libraries 1
 -# PROP BASE Output_Dir "Debug"
 -# PROP BASE Intermediate_Dir "Debug"
 -# PROP BASE Target_Dir ""
 -# PROP Use_MFC 0
 -# PROP Use_Debug_Libraries 1
 -# PROP Output_Dir "."
 -# PROP Intermediate_Dir "."
 -# PROP Ignore_Export_Lib 0
 -# PROP Target_Dir ""
 -# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /GZ /c
 -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "__CLEANUP_C" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /GZ /c
 -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 -# ADD BASE RSC /l 0x809 /d "_DEBUG"
 -# ADD RSC /l 0x409 /i "." /d "_DEBUG" /d "PTW32_RC_MSC"
 -BSC32=bscmake.exe
 -# ADD BASE BSC32 /nologo
 -# ADD BSC32 /nologo
 -LINK32=link.exe
 -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
 -# ADD LINK32 kernel32.lib user32.lib ws2_32.lib /nologo /dll /map /debug /machine:I386 /out:".\pthreadVC.dll" /pdbtype:sept
 -# SUBTRACT LINK32 /pdb:none
 -
 -!ENDIF 
 -
 -# Begin Target
 -
 -# Name "pthread - Win32 Release"
 -# Name "pthread - Win32 Debug"
 -# Begin Group "Source Files"
 -
 -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
 -# Begin Source File
 -
 -SOURCE=.\pthread.c
 -# End Source File
 -# End Group
 -# Begin Group "Header Files"
 -
 -# PROP Default_Filter "h;hpp;hxx;hm;inl"
 -# Begin Source File
 -
 -SOURCE=.\implement.h
 -# End Source File
 -# Begin Source File
 -
 -SOURCE=.\pthread.h
 -# End Source File
 -# Begin Source File
 -
 -SOURCE=.\sched.h
 -# End Source File
 -# Begin Source File
 -
 -SOURCE=.\semaphore.h
 -# End Source File
 -# End Group
 -# Begin Group "Resource Files"
 -
 -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
 -# Begin Source File
 -
 -SOURCE=.\version.rc
 -
 -!IF  "$(CFG)" == "pthread - Win32 Release"
 -
 -# ADD BASE RSC /l 0xc09
 -# ADD RSC /l 0x409 /i "." /d "PTW32_RC_MSC"
 -
 -!ELSEIF  "$(CFG)" == "pthread - Win32 Debug"
 -
 -# ADD BASE RSC /l 0xc09
 -# ADD RSC /l 0x409 /i "." /d "PTW32_RC_MSC"
 -
 -!ENDIF 
 -
 -# End Source File
 -# End Group
 -# End Target
 -# End Project
 +# Microsoft Developer Studio Project File - Name="pthread" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=pthread - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE  +!MESSAGE NMAKE /f "pthread.mak". +!MESSAGE  +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE  +!MESSAGE NMAKE /f "pthread.mak" CFG="pthread - Win32 Debug" +!MESSAGE  +!MESSAGE Possible choices for configuration are: +!MESSAGE  +!MESSAGE "pthread - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "pthread - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE  + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF  "$(CFG)" == "pthread - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "." +# PROP Intermediate_Dir "." +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "__CLEANUP_C" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /c +# SUBTRACT CPP /u +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x409 /i "." /d "NDEBUG" /d "PTW32_RC_MSC" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib ws2_32.lib /nologo /dll /pdb:none /machine:I386 /out:".\pthreadVC.dll" + +!ELSEIF  "$(CFG)" == "pthread - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "." +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "__CLEANUP_C" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x409 /i "." /d "_DEBUG" /d "PTW32_RC_MSC" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib ws2_32.lib /nologo /dll /map /debug /machine:I386 /out:".\pthreadVC.dll" /pdbtype:sept +# SUBTRACT LINK32 /pdb:none + +!ENDIF  + +# Begin Target + +# Name "pthread - Win32 Release" +# Name "pthread - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\pthread.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\implement.h +# End Source File +# Begin Source File + +SOURCE=.\pthread.h +# End Source File +# Begin Source File + +SOURCE=.\sched.h +# End Source File +# Begin Source File + +SOURCE=.\semaphore.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\version.rc + +!IF  "$(CFG)" == "pthread - Win32 Release" + +# ADD BASE RSC /l 0xc09 +# ADD RSC /l 0x409 /i "." /d "PTW32_RC_MSC" + +!ELSEIF  "$(CFG)" == "pthread - Win32 Debug" + +# ADD BASE RSC /l 0xc09 +# ADD RSC /l 0x409 /i "." /d "PTW32_RC_MSC" + +!ENDIF  + +# End Source File +# End Group +# End Target +# End Project diff --git a/pthread.dsw b/pthread.dsw index 9ff68b7..815a678 100644 --- a/pthread.dsw +++ b/pthread.dsw @@ -1,29 +1,29 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00
 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
 -
 -###############################################################################
 -
 -Project: "pthread"=.\pthread.dsp - Package Owner=<4>
 -
 -Package=<5>
 -{{{
 -}}}
 -
 -Package=<4>
 -{{{
 -}}}
 -
 -###############################################################################
 -
 -Global:
 -
 -Package=<5>
 -{{{
 -}}}
 -
 -Package=<3>
 -{{{
 -}}}
 -
 -###############################################################################
 -
 +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "pthread"=.\pthread.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + @@ -1,1391 +1,1391 @@ -/* This is an implementation of the threads API of POSIX 1003.1-2001.
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#if !defined( PTHREAD_H )
 -#define PTHREAD_H
 -
 -/*
 - * See the README file for an explanation of the pthreads-win32 version
 - * numbering scheme and how the DLL is named etc.
 - */
 -#define PTW32_VERSION 2,4,0,0
 -#define PTW32_VERSION_STRING "2, 4, 0, 0\0"
 -
 -/* There are three implementations of cancel cleanup.
 - * Note that pthread.h is included in both application
 - * compilation units and also internally for the library.
 - * The code here and within the library aims to work
 - * for all reasonable combinations of environments.
 - *
 - * The three implementations are:
 - *
 - *   WIN32 SEH
 - *   C
 - *   C++
 - *
 - * Please note that exiting a push/pop block via
 - * "return", "exit", "break", or "continue" will
 - * lead to different behaviour amongst applications
 - * depending upon whether the library was built
 - * using SEH, C++, or C. For example, a library built
 - * with SEH will call the cleanup routine, while both
 - * C++ and C built versions will not.
 - */
 -
 -/*
 - * Define defaults for cleanup code.
 - * Note: Unless the build explicitly defines one of the following, then
 - * we default to standard C style cleanup. This style uses setjmp/longjmp
 - * in the cancelation and thread exit implementations and therefore won't
 - * do stack unwinding if linked to applications that have it (e.g.
 - * C++ apps). This is currently consistent with most/all commercial Unix
 - * POSIX threads implementations.
 - */
 -#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C )
 -# define __CLEANUP_C
 -#endif
 -
 -#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC))
 -#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler.
 -#endif
 -
 -/*
 - * Stop here if we are being included by the resource compiler.
 - */
 -#ifndef RC_INVOKED
 -
 -#undef PTW32_LEVEL
 -
 -#if defined(_POSIX_SOURCE)
 -#define PTW32_LEVEL 0
 -/* Early POSIX */
 -#endif
 -
 -#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
 -#undef PTW32_LEVEL
 -#define PTW32_LEVEL 1
 -/* Include 1b, 1c and 1d */
 -#endif
 -
 -#if defined(INCLUDE_NP)
 -#undef PTW32_LEVEL
 -#define PTW32_LEVEL 2
 -/* Include Non-Portable extensions */
 -#endif
 -
 -#define PTW32_LEVEL_MAX 3
 -
 -#if !defined(PTW32_LEVEL)
 -#define PTW32_LEVEL PTW32_LEVEL_MAX
 -/* Include everything */
 -#endif
 -
 -#ifdef _UWIN
 -#   define HAVE_STRUCT_TIMESPEC 1
 -#   define HAVE_SIGNAL_H        1
 -#   undef HAVE_CONFIG_H
 -#   pragma comment(lib, "pthread")
 -#endif
 -
 -/*
 - * -------------------------------------------------------------
 - *
 - *
 - * Module: pthread.h
 - *
 - * Purpose:
 - *      Provides an implementation of PThreads based upon the
 - *      standard:
 - *
 - *              POSIX 1003.1-2001
 - *  and
 - *    The Single Unix Specification version 3
 - *
 - *    (these two are equivalent)
 - *
 - *      in order to enhance code portability between Windows,
 - *  various commercial Unix implementations, and Linux.
 - *
 - *      See the ANNOUNCE file for a full list of conforming
 - *      routines and defined constants, and a list of missing
 - *      routines and constants not defined in this implementation.
 - *
 - * Authors:
 - *      There have been many contributors to this library.
 - *      The initial implementation was contributed by
 - *      John Bossom, and several others have provided major
 - *      sections or revisions of parts of the implementation.
 - *      Often significant effort has been contributed to
 - *      find and fix important bugs and other problems to
 - *      improve the reliability of the library, which sometimes
 - *      is not reflected in the amount of code which changed as
 - *      result.
 - *      As much as possible, the contributors are acknowledged
 - *      in the ChangeLog file in the source code distribution
 - *      where their changes are noted in detail.
 - *
 - *      Contributors are listed in the CONTRIBUTORS file.
 - *
 - *      As usual, all bouquets go to the contributors, and all
 - *      brickbats go to the project maintainer.
 - *
 - * Maintainer:
 - *      The code base for this project is coordinated and
 - *      eventually pre-tested, packaged, and made available by
 - *
 - *              Ross Johnson <rpj@callisto.canberra.edu.au>
 - *
 - * QA Testers:
 - *      Ultimately, the library is tested in the real world by
 - *      a host of competent and demanding scientists and
 - *      engineers who report bugs and/or provide solutions
 - *      which are then fixed or incorporated into subsequent
 - *      versions of the library. Each time a bug is fixed, a
 - *      test case is written to prove the fix and ensure
 - *      that later changes to the code don't reintroduce the
 - *      same error. The number of test cases is slowly growing
 - *      and therefore so is the code reliability.
 - *
 - * Compliance:
 - *      See the file ANNOUNCE for the list of implemented
 - *      and not-implemented routines and defined options.
 - *      Of course, these are all defined is this file as well.
 - *
 - * Web site:
 - *      The source code and other information about this library
 - *      are available from
 - *
 - *              http://sources.redhat.com/pthreads-win32/
 - *
 - * -------------------------------------------------------------
 - */
 -
 -/* Try to avoid including windows.h */
 -#if defined(__MINGW32__) && defined(__cplusplus)
 -/*
 - * FIXME: The pthreadGCE.dll build gets linker unresolved errors
 - * on pthread_key_create() unless windows.h is included here.
 - * It appears to have something to do with an argument type mismatch.
 - * Looking at tsd.o with 'nm' shows this line:
 - * 00000000 T _pthread_key_create__FPP14pthread_key_t_PFPv_v
 - * instead of
 - * 00000000 T _pthread_key_create
 - */
 -#define PTW32_INCLUDE_WINDOWS_H
 -#endif
 -
 -#ifdef PTW32_INCLUDE_WINDOWS_H
 -#include <windows.h>
 -#endif
 -
 -#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__)
 -/*
 - * VC++6.0 or early compiler's header has no DWORD_PTR type.
 - */
 -typedef unsigned long DWORD_PTR;
 -#endif
 -/*
 - * -----------------
 - * autoconf switches
 - * -----------------
 - */
 -
 -#if HAVE_CONFIG_H
 -#include "config.h"
 -#endif /* HAVE_CONFIG_H */
 -
 -#if PTW32_LEVEL >= PTW32_LEVEL_MAX
 -
 -/* Try to avoid including windows.h */
 -#if defined(__MINGW32__) && defined(__cplusplus)
 -/*
 - * FIXME: The pthreadGCE.dll build gets linker unresolved errors
 - * on pthread_key_create() unless windows.h is included here.
 - * It appears to have something to do with an argument type mismatch.
 - * Looking at tsd.o with 'nm' shows this line:
 - * 00000000 T _pthread_key_create__FPP14pthread_key_t_PFPv_v
 - * instead of
 - * 00000000 T _pthread_key_create
 - */
 -#define PTW32_INCLUDE_WINDOWS_H
 -#endif
 -
 -#ifdef PTW32_INCLUDE_WINDOWS_H
 -#include <windows.h>
 -#endif
 -
 -#ifndef NEED_FTIME
 -#include <time.h>
 -#else /* NEED_FTIME */
 -/* use native WIN32 time API */
 -#endif /* NEED_FTIME */
 -
 -#if HAVE_SIGNAL_H
 -#include <signal.h>
 -#endif /* HAVE_SIGNAL_H */
 -
 -#include <setjmp.h>
 -#include <limits.h>
 -
 -/*
 - * Boolean values to make us independent of system includes.
 - */
 -enum {
 -  PTW32_FALSE = 0,
 -  PTW32_TRUE = (! PTW32_FALSE)
 -};
 -
 -/*
 - * This is a duplicate of what is in the autoconf config.h,
 - * which is only used when building the pthread-win32 libraries.
 - */
 -
 -#ifndef PTW32_CONFIG_H
 -#  if defined(WINCE)
 -#    define NEED_ERRNO
 -#    define NEED_SEM
 -#  endif
 -#  if defined(_UWIN) || defined(__MINGW32__)
 -#    define HAVE_MODE_T
 -#  endif
 -#endif
 -
 -/*
 - *
 - */
 -
 -#if PTW32_LEVEL >= PTW32_LEVEL_MAX
 -#ifdef NEED_ERRNO
 -#include "need_errno.h"
 -#else
 -#include <errno.h>
 -#endif
 -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
 -
 -/*
 - * Several systems don't define some error numbers.
 - */
 -#ifndef ENOTSUP
 -#  define ENOTSUP 48   /* This is the value in Solaris. */
 -#endif
 -
 -#ifndef ETIMEDOUT
 -#  define ETIMEDOUT 10060     /* This is the value in winsock.h. */
 -#endif
 -
 -#ifndef ENOSYS
 -#  define ENOSYS 140     /* Semi-arbitrary value */
 -#endif
 -
 -#ifndef EDEADLK
 -#  ifdef EDEADLOCK
 -#    define EDEADLK EDEADLOCK
 -#  else
 -#    define EDEADLK 36     /* This is the value in MSVC. */
 -#  endif
 -#endif
 -
 -#include <sched.h>
 -
 -/*
 - * To avoid including windows.h we define only those things that we
 - * actually need from it. I don't like the potential incompatibility that
 - * this creates with future versions of windows.
 - */
 -#ifndef PTW32_INCLUDE_WINDOWS_H
 -#ifndef HANDLE
 -# define PTW32__HANDLE_DEF
 -# define HANDLE void *
 -#endif
 -#ifndef DWORD
 -# define PTW32__DWORD_DEF
 -# define DWORD unsigned long
 -#endif
 -#endif
 -
 -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
 -
 -#ifndef HAVE_STRUCT_TIMESPEC
 -#define HAVE_STRUCT_TIMESPEC 1
 -struct timespec {
 -        long tv_sec;
 -        long tv_nsec;
 -};
 -#endif /* HAVE_STRUCT_TIMESPEC */
 -
 -#ifndef SIG_BLOCK
 -#define SIG_BLOCK 0
 -#endif /* SIG_BLOCK */
 -
 -#ifndef SIG_UNBLOCK 
 -#define SIG_UNBLOCK 1
 -#endif /* SIG_UNBLOCK */
 -
 -#ifndef SIG_SETMASK
 -#define SIG_SETMASK 2
 -#endif /* SIG_SETMASK */
 -
 -#ifdef __cplusplus
 -extern "C"
 -{
 -#endif                          /* __cplusplus */
 -
 -/*
 - * -------------------------------------------------------------
 - *
 - * POSIX 1003.1-2001 Options
 - * =========================
 - *
 - * Options are normally set in <unistd.h>, which is not provided
 - * with pthreads-win32.
 - *
 - * For conformance with the Single Unix Specification (version 3), all of the
 - * options below are defined, and have a value of either -1 (not supported)
 - * or 200112L (supported).
 - *
 - * These options can neither be left undefined nor have a value of 0, because
 - * either indicates that sysconf(), which is not implemented, may be used at
 - * runtime to check the status of the option.
 - *
 - * _POSIX_THREADS (== 200112L)
 - *                      If == 200112L, you can use threads
 - *
 - * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L)
 - *                      If == 200112L, you can control the size of a thread's
 - *                      stack
 - *                              pthread_attr_getstacksize
 - *                              pthread_attr_setstacksize
 - *
 - * _POSIX_THREAD_ATTR_STACKADDR (== -1)
 - *                      If == 200112L, you can allocate and control a thread's
 - *                      stack. If not supported, the following functions
 - *                      will return ENOSYS, indicating they are not
 - *                      supported:
 - *                              pthread_attr_getstackaddr
 - *                              pthread_attr_setstackaddr
 - *
 - * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1)
 - *                      If == 200112L, you can use realtime scheduling.
 - *                      This option indicates that the behaviour of some
 - *                      implemented functions conforms to the additional TPS
 - *                      requirements in the standard. E.g. rwlocks favour
 - *                      writers over readers when threads have equal priority.
 - *
 - * _POSIX_THREAD_PRIO_INHERIT (== -1)
 - *                      If == 200112L, you can create priority inheritance
 - *                      mutexes.
 - *                              pthread_mutexattr_getprotocol +
 - *                              pthread_mutexattr_setprotocol +
 - *
 - * _POSIX_THREAD_PRIO_PROTECT (== -1)
 - *                      If == 200112L, you can create priority ceiling mutexes
 - *                      Indicates the availability of:
 - *                              pthread_mutex_getprioceiling
 - *                              pthread_mutex_setprioceiling
 - *                              pthread_mutexattr_getprioceiling
 - *                              pthread_mutexattr_getprotocol     +
 - *                              pthread_mutexattr_setprioceiling
 - *                              pthread_mutexattr_setprotocol     +
 - *
 - * _POSIX_THREAD_PROCESS_SHARED (== -1)
 - *                      If set, you can create mutexes and condition
 - *                      variables that can be shared with another
 - *                      process.If set, indicates the availability
 - *                      of:
 - *                              pthread_mutexattr_getpshared
 - *                              pthread_mutexattr_setpshared
 - *                              pthread_condattr_getpshared
 - *                              pthread_condattr_setpshared
 - *
 - * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L)
 - *                      If == 200112L you can use the special *_r library
 - *                      functions that provide thread-safe behaviour
 - *
 - * _POSIX_READER_WRITER_LOCKS (== 200112L)
 - *                      If == 200112L, you can use read/write locks
 - *
 - * _POSIX_SPIN_LOCKS (== 200112L)
 - *                      If == 200112L, you can use spin locks
 - *
 - * _POSIX_BARRIERS (== 200112L)
 - *                      If == 200112L, you can use barriers
 - *
 - *      + These functions provide both 'inherit' and/or
 - *        'protect' protocol, based upon these macro
 - *        settings.
 - *
 - * -------------------------------------------------------------
 - */
 -
 -/*
 - * POSIX Options
 - */
 -#undef _POSIX_THREADS
 -#define _POSIX_THREADS 200112L
 -
 -#undef _POSIX_READER_WRITER_LOCKS
 -#define _POSIX_READER_WRITER_LOCKS 200112L
 -
 -#undef _POSIX_SPIN_LOCKS
 -#define _POSIX_SPIN_LOCKS 200112L
 -
 -#undef _POSIX_BARRIERS
 -#define _POSIX_BARRIERS 200112L
 -
 -#undef _POSIX_THREAD_SAFE_FUNCTIONS
 -#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L
 -
 -#undef _POSIX_THREAD_ATTR_STACKSIZE
 -#define _POSIX_THREAD_ATTR_STACKSIZE 200112L
 -
 -/*
 - * The following options are not supported
 - */
 -#undef _POSIX_THREAD_ATTR_STACKADDR
 -#define _POSIX_THREAD_ATTR_STACKADDR -1
 -
 -#undef _POSIX_THREAD_PRIO_INHERIT
 -#define _POSIX_THREAD_PRIO_INHERIT -1
 -
 -#undef _POSIX_THREAD_PRIO_PROTECT
 -#define _POSIX_THREAD_PRIO_PROTECT -1
 -
 -/* TPS is not fully supported.  */
 -#undef _POSIX_THREAD_PRIORITY_SCHEDULING
 -#define _POSIX_THREAD_PRIORITY_SCHEDULING -1
 -
 -#undef _POSIX_THREAD_PROCESS_SHARED
 -#define _POSIX_THREAD_PROCESS_SHARED -1
 -
 -
 -/*
 - * POSIX 1003.1-2001 Limits
 - * ===========================
 - *
 - * These limits are normally set in <limits.h>, which is not provided with
 - * pthreads-win32.
 - *
 - * PTHREAD_DESTRUCTOR_ITERATIONS
 - *                      Maximum number of attempts to destroy
 - *                      a thread's thread-specific data on
 - *                      termination (must be at least 4)
 - *
 - * PTHREAD_KEYS_MAX
 - *                      Maximum number of thread-specific data keys
 - *                      available per process (must be at least 128)
 - *
 - * PTHREAD_STACK_MIN
 - *                      Minimum supported stack size for a thread
 - *
 - * PTHREAD_THREADS_MAX
 - *                      Maximum number of threads supported per
 - *                      process (must be at least 64).
 - *
 - * _POSIX_SEM_NSEMS_MAX
 - *      The maximum number of semaphores a process can have.
 - *      (only defined if not already defined)
 - *
 - * _POSIX_SEM_VALUE_MAX
 - *      The maximum value a semaphore can have.
 - *      (only defined if not already defined)
 - *
 - */
 -#undef PTHREAD_DESTRUCTOR_ITERATIONS
 -#define PTHREAD_DESTRUCTOR_ITERATIONS                          4
 -
 -#undef PTHREAD_KEYS_MAX
 -#define PTHREAD_KEYS_MAX                        64
 -
 -#undef PTHREAD_STACK_MIN
 -#define PTHREAD_STACK_MIN                        0
 -
 -#if PTW32_LEVEL < 2
 -  /* Arbitrary value */
 -#  undef PTHREAD_THREADS_MAX
 -#  define PTHREAD_THREADS_MAX                   2019
 -#endif
 -
 -  /* Arbitrary value */
 -#undef _POSIX_THREAD_THREADS_MAX
 -#define _POSIX_THREAD_THREADS_MAX               2019
 -
 -  /* Arbitrary value */
 -#undef _POSIX_SEM_NSEMS_MAX
 -#define _POSIX_SEM_NSEMS_MAX                    1024
 -
 -#undef _POSIX_SEM_VALUE_MAX
 -#define _POSIX_SEM_VALUE_MAX                    (INT_MAX/2)
 -
 -
 -#if __GNUC__ && ! defined (__declspec)
 -# error Please upgrade your GNU compiler to one that supports __declspec.
 -#endif
 -
 -/*
 - * When building the DLL code, you should define PTW32_BUILD so that
 - * the variables/functions are exported correctly. When using the DLL,
 - * do NOT define PTW32_BUILD, and then the variables/functions will
 - * be imported correctly.
 - */
 -#ifndef PTW32_STATIC_LIB
 -#  ifdef PTW32_BUILD
 -#    define PTW32_DLLPORT __declspec (dllexport)
 -#  else
 -#    define PTW32_DLLPORT __declspec (dllimport)
 -#  endif
 -#else
 -#  define PTW32_DLLPORT
 -#endif
 -
 -/*
 - * The Open Watcom C/C++ compiler uses a non-standard calling convention
 - * that passes function args in registers unless __cdecl is explicitly specified
 - * in exposed function prototypes.
 - *
 - * We force all calls to cdecl even though this could slow Watcom code down
 - * slightly. If you know that the Watcom compiler will be used to build both
 - * the DLL and application, then you can probably define this as a null string.
 - * Remember that pthread.h (this file) is used for both the DLL and application builds.
 - */
 -#define PTW32_CDECL __cdecl
 -
 -#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX
 -#   include     <sys/types.h>
 -#else
 -/*
 - * Generic handle type - intended to extend uniqueness beyond
 - * that available with a simple pointer. It should scale for either
 - * IA-32 or IA-64.
 - */
 -typedef struct {
 -    void * p;                   /* Pointer to actual object */
 -    unsigned int x;             /* Extra information - reuse count etc */
 -} ptw32_handle_t;
 -
 -typedef ptw32_handle_t pthread_t;
 -typedef struct pthread_attr_t_ * pthread_attr_t;
 -typedef struct pthread_once_t_ pthread_once_t;
 -typedef struct pthread_key_t_ * pthread_key_t;
 -typedef struct pthread_mutex_t_ * pthread_mutex_t;
 -typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t;
 -typedef struct pthread_cond_t_ * pthread_cond_t;
 -typedef struct pthread_condattr_t_ * pthread_condattr_t;
 -#endif
 -typedef struct pthread_rwlock_t_ * pthread_rwlock_t;
 -typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t;
 -typedef struct pthread_spinlock_t_ * pthread_spinlock_t;
 -typedef struct pthread_barrier_t_ * pthread_barrier_t;
 -typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t;
 -
 -/*
 - * ====================
 - * ====================
 - * POSIX Threads
 - * ====================
 - * ====================
 - */
 -
 -enum {
 -/*
 - * pthread_attr_{get,set}detachstate
 - */
 -  PTHREAD_CREATE_JOINABLE       = 0,  /* Default */
 -  PTHREAD_CREATE_DETACHED       = 1,
 -
 -/*
 - * pthread_attr_{get,set}inheritsched
 - */
 -  PTHREAD_INHERIT_SCHED         = 0,
 -  PTHREAD_EXPLICIT_SCHED        = 1,  /* Default */
 -
 -/*
 - * pthread_{get,set}scope
 - */
 -  PTHREAD_SCOPE_PROCESS         = 0,
 -  PTHREAD_SCOPE_SYSTEM          = 1,  /* Default */
 -
 -/*
 - * pthread_setcancelstate paramters
 - */
 -  PTHREAD_CANCEL_ENABLE         = 0,  /* Default */
 -  PTHREAD_CANCEL_DISABLE        = 1,
 -
 -/*
 - * pthread_setcanceltype parameters
 - */
 -  PTHREAD_CANCEL_ASYNCHRONOUS   = 0,
 -  PTHREAD_CANCEL_DEFERRED       = 1,  /* Default */
 -
 -/*
 - * pthread_mutexattr_{get,set}pshared
 - * pthread_condattr_{get,set}pshared
 - */
 -  PTHREAD_PROCESS_PRIVATE       = 0,
 -  PTHREAD_PROCESS_SHARED        = 1,
 -
 -/*
 - * pthread_barrier_wait
 - */
 -  PTHREAD_BARRIER_SERIAL_THREAD = -1
 -};
 -
 -/*
 - * ====================
 - * ====================
 - * Cancelation
 - * ====================
 - * ====================
 - */
 -#define PTHREAD_CANCELED       ((void *) -1)
 -
 -
 -/*
 - * ====================
 - * ====================
 - * Once Key
 - * ====================
 - * ====================
 - */
 -#define PTHREAD_ONCE_INIT       { 0, PTW32_FALSE, 0, 0}
 -
 -struct pthread_once_t_
 -{
 -  int          state;        /* indicates if user function has been executed, or cancelled  */
 -  int          started;
 -  int          eventUsers;
 -  HANDLE       event;
 -};
 -
 -
 -/*
 - * ====================
 - * ====================
 - * Object initialisers
 - * ====================
 - * ====================
 - */
 -#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1)
 -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2)
 -#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3)
 -
 -/*
 - * Compatibility with LinuxThreads
 - */
 -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
 -#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
 -
 -#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1)
 -
 -#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1)
 -
 -#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1)
 -
 -
 -/*
 - * Mutex types.
 - */
 -enum
 -{
 -  /* Compatibility with LinuxThreads */
 -  PTHREAD_MUTEX_FAST_NP,
 -  PTHREAD_MUTEX_RECURSIVE_NP,
 -  PTHREAD_MUTEX_ERRORCHECK_NP,
 -  PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP,
 -  PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP,
 -  /* For compatibility with POSIX */
 -  PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP,
 -  PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
 -  PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
 -  PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
 -};
 -
 -
 -typedef struct ptw32_cleanup_t ptw32_cleanup_t;
 -
 -#if defined(_MSC_VER)
 -/* Disable MSVC 'anachronism used' warning */
 -#pragma warning( disable : 4229 )
 -#endif
 -
 -typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *);
 -
 -#if defined(_MSC_VER)
 -#pragma warning( default : 4229 )
 -#endif
 -
 -struct ptw32_cleanup_t
 -{
 -  ptw32_cleanup_callback_t routine;
 -  void *arg;
 -  struct ptw32_cleanup_t *prev;
 -};
 -
 -#ifdef __CLEANUP_SEH
 -        /*
 -         * WIN32 SEH version of cancel cleanup.
 -         */
 -
 -#define pthread_cleanup_push( _rout, _arg ) \
 -        { \
 -            ptw32_cleanup_t     _cleanup; \
 -            \
 -        _cleanup.routine        = (ptw32_cleanup_callback_t)(_rout); \
 -            _cleanup.arg        = (_arg); \
 -            __try \
 -              { \
 -
 -#define pthread_cleanup_pop( _execute ) \
 -              } \
 -            __finally \
 -                { \
 -                    if( _execute || AbnormalTermination()) \
 -                      { \
 -                          (*(_cleanup.routine))( _cleanup.arg ); \
 -                      } \
 -                } \
 -        }
 -
 -#else /* __CLEANUP_SEH */
 -
 -#ifdef __CLEANUP_C
 -
 -        /*
 -         * C implementation of PThreads cancel cleanup
 -         */
 -
 -#define pthread_cleanup_push( _rout, _arg ) \
 -        { \
 -            ptw32_cleanup_t     _cleanup; \
 -            \
 -            ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \
 -
 -#define pthread_cleanup_pop( _execute ) \
 -            (void) ptw32_pop_cleanup( _execute ); \
 -        }
 -
 -#else /* __CLEANUP_C */
 -
 -#ifdef __CLEANUP_CXX
 -
 -        /*
 -         * C++ version of cancel cleanup.
 -         * - John E. Bossom.
 -         */
 -
 -        class PThreadCleanup {
 -          /*
 -           * PThreadCleanup
 -           *
 -           * Purpose
 -           *      This class is a C++ helper class that is
 -           *      used to implement pthread_cleanup_push/
 -           *      pthread_cleanup_pop.
 -           *      The destructor of this class automatically
 -           *      pops the pushed cleanup routine regardless
 -           *      of how the code exits the scope
 -           *      (i.e. such as by an exception)
 -           */
 -      ptw32_cleanup_callback_t cleanUpRout;
 -          void    *       obj;
 -          int             executeIt;
 -
 -        public:
 -          PThreadCleanup() :
 -            cleanUpRout( 0 ),
 -            obj( 0 ),
 -            executeIt( 0 )
 -            /*
 -             * No cleanup performed
 -             */
 -            {
 -            }
 -
 -          PThreadCleanup(
 -             ptw32_cleanup_callback_t routine,
 -                         void    *       arg ) :
 -            cleanUpRout( routine ),
 -            obj( arg ),
 -            executeIt( 1 )
 -            /*
 -             * Registers a cleanup routine for 'arg'
 -             */
 -            {
 -            }
 -
 -          ~PThreadCleanup()
 -            {
 -              if ( executeIt && ((void *) cleanUpRout != (void *) 0) )
 -                {
 -                  (void) (*cleanUpRout)( obj );
 -                }
 -            }
 -
 -          void execute( int exec )
 -            {
 -              executeIt = exec;
 -            }
 -        };
 -
 -        /*
 -         * C++ implementation of PThreads cancel cleanup;
 -         * This implementation takes advantage of a helper
 -         * class who's destructor automatically calls the
 -         * cleanup routine if we exit our scope weirdly
 -         */
 -#define pthread_cleanup_push( _rout, _arg ) \
 -        { \
 -            PThreadCleanup  cleanup((ptw32_cleanup_callback_t)(_rout), \
 -                                    (void *) (_arg) );
 -
 -#define pthread_cleanup_pop( _execute ) \
 -            cleanup.execute( _execute ); \
 -        }
 -
 -#else
 -
 -#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
 -
 -#endif /* __CLEANUP_CXX */
 -
 -#endif /* __CLEANUP_C */
 -
 -#endif /* __CLEANUP_SEH */
 -
 -/*
 - * ===============
 - * ===============
 - * Methods
 - * ===============
 - * ===============
 - */
 -
 -/*
 - * PThread Attribute Functions
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr,
 -                                         int *detachstate);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr,
 -                                       void **stackaddr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr,
 -                                       size_t * stacksize);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr,
 -                                         int detachstate);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr,
 -                                       void *stackaddr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr,
 -                                       size_t stacksize);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr,
 -                                        struct sched_param *param);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr,
 -                                        const struct sched_param *param);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *,
 -                                         int);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (pthread_attr_t *,
 -                                         int *);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr,
 -                                         int inheritsched);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(pthread_attr_t * attr,
 -                                         int * inheritsched);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *,
 -                                   int);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *,
 -                                   int *);
 -
 -/*
 - * PThread Functions
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,
 -                            const pthread_attr_t * attr,
 -                            void *(*start) (void *),
 -                            void *arg);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1,
 -                           pthread_t t2);
 -
 -PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread,
 -                          void **value_ptr);
 -
 -PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state,
 -                                    int *oldstate);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type,
 -                                   int *oldtype);
 -
 -PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control,
 -                          void (*init_routine) (void));
 -
 -#if PTW32_LEVEL >= PTW32_LEVEL_MAX
 -PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute);
 -
 -PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup,
 -                                 void (*routine) (void *),
 -                                 void *arg);
 -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
 -
 -/*
 - * Thread Specific Data Functions
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key,
 -                                void (*destructor) (void *));
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key,
 -                                 const void *value);
 -
 -PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key);
 -
 -
 -/*
 - * Mutex Attribute Functions
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t
 -                                          * attr,
 -                                          int *pshared);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,
 -                                          int pshared);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind);
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind);
 -
 -/*
 - * Barrier Attribute Functions
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t
 -                                            * attr,
 -                                            int *pshared);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr,
 -                                            int pshared);
 -
 -/*
 - * Mutex Functions
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex,
 -                                const pthread_mutexattr_t * attr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t *mutex,
 -                                    const struct timespec *abstime);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex);
 -
 -/*
 - * Spinlock Functions
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock);
 -
 -/*
 - * Barrier Functions
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier,
 -                                  const pthread_barrierattr_t * attr,
 -                                  unsigned int count);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier);
 -
 -/*
 - * Condition Variable Attribute Functions
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr,
 -                                         int *pshared);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr,
 -                                         int pshared);
 -
 -/*
 - * Condition Variable Functions
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond,
 -                               const pthread_condattr_t * attr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond,
 -                               pthread_mutex_t * mutex);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond,
 -                                    pthread_mutex_t * mutex,
 -                                    const struct timespec *abstime);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond);
 -
 -/*
 - * Scheduling
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread,
 -                                   int policy,
 -                                   const struct sched_param *param);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread,
 -                                   int *policy,
 -                                   struct sched_param *param);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int);
 - 
 -PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void);
 -
 -/*
 - * Read-Write Lock Functions
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock,
 -                                const pthread_rwlockattr_t *attr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock,
 -                                       const struct timespec *abstime);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock,
 -                                       const struct timespec *abstime);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
 -                                           int *pshared);
 -
 -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr,
 -                                           int pshared);
 -
 -#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1
 -
 -/*
 - * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32
 - * already have signal.h that don't define these.
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig);
 -
 -/*
 - * Non-portable functions
 - */
 -
 -/*
 - * Compatibility with Linux.
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr,
 -                                         int kind);
 -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr,
 -                                         int *kind);
 -
 -/*
 - * Possibly supported by other POSIX threads implementations
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval);
 -PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void);
 -
 -/*
 - * Useful if an application wants to statically link
 - * the lib rather than load the DLL at run-time.
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void);
 -PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void);
 -PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void);
 -PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void);
 -
 -/*
 - * Features that are auto-detected at load/run time.
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int);
 -enum ptw32_features {
 -  PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */
 -  PTW32_ALERTABLE_ASYNC_CANCEL              = 0x0002  /* Can cancel blocked threads. */
 -};
 -
 -/*
 - * Register a system time change with the library.
 - * Causes the library to perform various functions
 - * in response to the change. Should be called whenever
 - * the application's top level window receives a
 - * WM_TIMECHANGE message. It can be passed directly to
 - * pthread_create() as a new thread if desired.
 - */
 -PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *);
 -
 -#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */
 -
 -#if PTW32_LEVEL >= PTW32_LEVEL_MAX
 -
 -/*
 - * Returns the Win32 HANDLE for the POSIX thread.
 - */
 -PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread);
 -
 -
 -/*
 - * Protected Methods
 - *
 - * This function blocks until the given WIN32 handle
 - * is signaled or pthread_cancel had been called.
 - * This function allows the caller to hook into the
 - * PThreads cancel mechanism. It is implemented using
 - *
 - *              WaitForMultipleObjects
 - *
 - * on 'waitHandle' and a manually reset WIN32 Event
 - * used to implement pthread_cancel. The 'timeout'
 - * argument to TimedWait is simply passed to
 - * WaitForMultipleObjects.
 - */
 -PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle);
 -PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle,
 -                                        DWORD timeout);
 -
 -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
 -
 -/*
 - * Thread-Safe C Runtime Library Mappings.
 - */
 -#ifndef _UWIN
 -#  if defined(NEED_ERRNO)
 -     PTW32_DLLPORT int * PTW32_CDECL _errno( void );
 -#  else
 -#    ifndef errno
 -#      if (defined(_MT) || defined(_DLL))
 -         __declspec(dllimport) extern int * __cdecl _errno(void);
 -#        define errno   (*_errno())
 -#      endif
 -#    endif
 -#  endif
 -#endif
 -
 -/*
 - * WIN32 C runtime library had been made thread-safe
 - * without affecting the user interface. Provide
 - * mappings from the UNIX thread-safe versions to
 - * the standard C runtime library calls.
 - * Only provide function mappings for functions that
 - * actually exist on WIN32.
 - */
 -
 -#if !defined(__MINGW32__)
 -#define strtok_r( _s, _sep, _lasts ) \
 -        ( *(_lasts) = strtok( (_s), (_sep) ) )
 -#endif /* !__MINGW32__ */
 -
 -#define asctime_r( _tm, _buf ) \
 -        ( strcpy( (_buf), asctime( (_tm) ) ), \
 -          (_buf) )
 -
 -#define ctime_r( _clock, _buf ) \
 -        ( strcpy( (_buf), ctime( (_clock) ) ),  \
 -          (_buf) )
 -
 -#define gmtime_r( _clock, _result ) \
 -        ( *(_result) = *gmtime( (_clock) ), \
 -          (_result) )
 -
 -#define localtime_r( _clock, _result ) \
 -        ( *(_result) = *localtime( (_clock) ), \
 -          (_result) )
 -
 -#define rand_r( _seed ) \
 -        ( _seed == _seed? rand() : rand() )
 -
 -
 -/*
 - * Some compiler environments don't define some things.
 - */
 -#if defined(__BORLANDC__)
 -#  define _ftime ftime
 -#  define _timeb timeb
 -#endif
 -
 -#ifdef __cplusplus
 -
 -/*
 - * Internal exceptions
 - */
 -class ptw32_exception {};
 -class ptw32_exception_cancel : public ptw32_exception {};
 -class ptw32_exception_exit   : public ptw32_exception {};
 -
 -#endif
 -
 -#if PTW32_LEVEL >= PTW32_LEVEL_MAX
 -
 -/* FIXME: This is only required if the library was built using SEH */
 -/*
 - * Get internal SEH tag
 - */
 -PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void);
 -
 -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
 -
 -#ifndef PTW32_BUILD
 -
 -#ifdef __CLEANUP_SEH
 -
 -/*
 - * Redefine the SEH __except keyword to ensure that applications
 - * propagate our internal exceptions up to the library's internal handlers.
 - */
 -#define __except( E ) \
 -        __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \
 -                 ? EXCEPTION_CONTINUE_SEARCH : ( E ) )
 -
 -#endif /* __CLEANUP_SEH */
 -
 -#ifdef __CLEANUP_CXX
 -
 -/*
 - * Redefine the C++ catch keyword to ensure that applications
 - * propagate our internal exceptions up to the library's internal handlers.
 - */
 -#ifdef _MSC_VER
 -        /*
 -         * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'
 -         * if you want Pthread-Win32 cancelation and pthread_exit to work.
 -         */
 -
 -#ifndef PtW32NoCatchWarn
 -
 -#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.")
 -#pragma message("------------------------------------------------------------------")
 -#pragma message("When compiling applications with MSVC++ and C++ exception handling:")
 -#pragma message("  Replace any 'catch( ... )' in routines called from POSIX threads")
 -#pragma message("  with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread")
 -#pragma message("  cancelation and pthread_exit to work. For example:")
 -#pragma message("")
 -#pragma message("    #ifdef PtW32CatchAll")
 -#pragma message("      PtW32CatchAll")
 -#pragma message("    #else")
 -#pragma message("      catch(...)")
 -#pragma message("    #endif")
 -#pragma message("        {")
 -#pragma message("          /* Catchall block processing */")
 -#pragma message("        }")
 -#pragma message("------------------------------------------------------------------")
 -
 -#endif
 -
 -#define PtW32CatchAll \
 -        catch( ptw32_exception & ) { throw; } \
 -        catch( ... )
 -
 -#else /* _MSC_VER */
 -
 -#define catch( E ) \
 -        catch( ptw32_exception & ) { throw; } \
 -        catch( E )
 -
 -#endif /* _MSC_VER */
 -
 -#endif /* __CLEANUP_CXX */
 -
 -#endif /* ! PTW32_BUILD */
 -
 -#ifdef __cplusplus
 -}                               /* End of extern "C" */
 -#endif                          /* __cplusplus */
 -
 -#ifdef PTW32__HANDLE_DEF
 -# undef HANDLE
 -#endif
 -#ifdef PTW32__DWORD_DEF
 -# undef DWORD
 -#endif
 -
 -#undef PTW32_LEVEL
 -#undef PTW32_LEVEL_MAX
 -
 -#endif /* ! RC_INVOKED */
 -
 -#endif /* PTHREAD_H */
 +/* This is an implementation of the threads API of POSIX 1003.1-2001. + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#if !defined( PTHREAD_H ) +#define PTHREAD_H + +/* + * See the README file for an explanation of the pthreads-win32 version + * numbering scheme and how the DLL is named etc. + */ +#define PTW32_VERSION 2,4,0,0 +#define PTW32_VERSION_STRING "2, 4, 0, 0\0" + +/* There are three implementations of cancel cleanup. + * Note that pthread.h is included in both application + * compilation units and also internally for the library. + * The code here and within the library aims to work + * for all reasonable combinations of environments. + * + * The three implementations are: + * + *   WIN32 SEH + *   C + *   C++ + * + * Please note that exiting a push/pop block via + * "return", "exit", "break", or "continue" will + * lead to different behaviour amongst applications + * depending upon whether the library was built + * using SEH, C++, or C. For example, a library built + * with SEH will call the cleanup routine, while both + * C++ and C built versions will not. + */ + +/* + * Define defaults for cleanup code. + * Note: Unless the build explicitly defines one of the following, then + * we default to standard C style cleanup. This style uses setjmp/longjmp + * in the cancelation and thread exit implementations and therefore won't + * do stack unwinding if linked to applications that have it (e.g. + * C++ apps). This is currently consistent with most/all commercial Unix + * POSIX threads implementations. + */ +#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C ) +# define __CLEANUP_C +#endif + +#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC)) +#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler. +#endif + +/* + * Stop here if we are being included by the resource compiler. + */ +#ifndef RC_INVOKED + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + +#ifdef _UWIN +#   define HAVE_STRUCT_TIMESPEC 1 +#   define HAVE_SIGNAL_H        1 +#   undef HAVE_CONFIG_H +#   pragma comment(lib, "pthread") +#endif + +/* + * ------------------------------------------------------------- + * + * + * Module: pthread.h + * + * Purpose: + *      Provides an implementation of PThreads based upon the + *      standard: + * + *              POSIX 1003.1-2001 + *  and + *    The Single Unix Specification version 3 + * + *    (these two are equivalent) + * + *      in order to enhance code portability between Windows, + *  various commercial Unix implementations, and Linux. + * + *      See the ANNOUNCE file for a full list of conforming + *      routines and defined constants, and a list of missing + *      routines and constants not defined in this implementation. + * + * Authors: + *      There have been many contributors to this library. + *      The initial implementation was contributed by + *      John Bossom, and several others have provided major + *      sections or revisions of parts of the implementation. + *      Often significant effort has been contributed to + *      find and fix important bugs and other problems to + *      improve the reliability of the library, which sometimes + *      is not reflected in the amount of code which changed as + *      result. + *      As much as possible, the contributors are acknowledged + *      in the ChangeLog file in the source code distribution + *      where their changes are noted in detail. + * + *      Contributors are listed in the CONTRIBUTORS file. + * + *      As usual, all bouquets go to the contributors, and all + *      brickbats go to the project maintainer. + * + * Maintainer: + *      The code base for this project is coordinated and + *      eventually pre-tested, packaged, and made available by + * + *              Ross Johnson <rpj@callisto.canberra.edu.au> + * + * QA Testers: + *      Ultimately, the library is tested in the real world by + *      a host of competent and demanding scientists and + *      engineers who report bugs and/or provide solutions + *      which are then fixed or incorporated into subsequent + *      versions of the library. Each time a bug is fixed, a + *      test case is written to prove the fix and ensure + *      that later changes to the code don't reintroduce the + *      same error. The number of test cases is slowly growing + *      and therefore so is the code reliability. + * + * Compliance: + *      See the file ANNOUNCE for the list of implemented + *      and not-implemented routines and defined options. + *      Of course, these are all defined is this file as well. + * + * Web site: + *      The source code and other information about this library + *      are available from + * + *              http://sources.redhat.com/pthreads-win32/ + * + * ------------------------------------------------------------- + */ + +/* Try to avoid including windows.h */ +#if defined(__MINGW32__) && defined(__cplusplus) +/* + * FIXME: The pthreadGCE.dll build gets linker unresolved errors + * on pthread_key_create() unless windows.h is included here. + * It appears to have something to do with an argument type mismatch. + * Looking at tsd.o with 'nm' shows this line: + * 00000000 T _pthread_key_create__FPP14pthread_key_t_PFPv_v + * instead of + * 00000000 T _pthread_key_create + */ +#define PTW32_INCLUDE_WINDOWS_H +#endif + +#ifdef PTW32_INCLUDE_WINDOWS_H +#include <windows.h> +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__) +/* + * VC++6.0 or early compiler's header has no DWORD_PTR type. + */ +typedef unsigned long DWORD_PTR; +#endif +/* + * ----------------- + * autoconf switches + * ----------------- + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* Try to avoid including windows.h */ +#if defined(__MINGW32__) && defined(__cplusplus) +/* + * FIXME: The pthreadGCE.dll build gets linker unresolved errors + * on pthread_key_create() unless windows.h is included here. + * It appears to have something to do with an argument type mismatch. + * Looking at tsd.o with 'nm' shows this line: + * 00000000 T _pthread_key_create__FPP14pthread_key_t_PFPv_v + * instead of + * 00000000 T _pthread_key_create + */ +#define PTW32_INCLUDE_WINDOWS_H +#endif + +#ifdef PTW32_INCLUDE_WINDOWS_H +#include <windows.h> +#endif + +#ifndef NEED_FTIME +#include <time.h> +#else /* NEED_FTIME */ +/* use native WIN32 time API */ +#endif /* NEED_FTIME */ + +#if HAVE_SIGNAL_H +#include <signal.h> +#endif /* HAVE_SIGNAL_H */ + +#include <setjmp.h> +#include <limits.h> + +/* + * Boolean values to make us independent of system includes. + */ +enum { +  PTW32_FALSE = 0, +  PTW32_TRUE = (! PTW32_FALSE) +}; + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#ifndef PTW32_CONFIG_H +#  if defined(WINCE) +#    define NEED_ERRNO +#    define NEED_SEM +#  endif +#  if defined(_UWIN) || defined(__MINGW32__) +#    define HAVE_MODE_T +#  endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#ifdef NEED_ERRNO +#include "need_errno.h" +#else +#include <errno.h> +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Several systems don't define some error numbers. + */ +#ifndef ENOTSUP +#  define ENOTSUP 48   /* This is the value in Solaris. */ +#endif + +#ifndef ETIMEDOUT +#  define ETIMEDOUT 10060     /* This is the value in winsock.h. */ +#endif + +#ifndef ENOSYS +#  define ENOSYS 140     /* Semi-arbitrary value */ +#endif + +#ifndef EDEADLK +#  ifdef EDEADLOCK +#    define EDEADLK EDEADLOCK +#  else +#    define EDEADLK 36     /* This is the value in MSVC. */ +#  endif +#endif + +#include <sched.h> + +/* + * To avoid including windows.h we define only those things that we + * actually need from it. I don't like the potential incompatibility that + * this creates with future versions of windows. + */ +#ifndef PTW32_INCLUDE_WINDOWS_H +#ifndef HANDLE +# define PTW32__HANDLE_DEF +# define HANDLE void * +#endif +#ifndef DWORD +# define PTW32__DWORD_DEF +# define DWORD unsigned long +#endif +#endif + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#ifndef HAVE_STRUCT_TIMESPEC +#define HAVE_STRUCT_TIMESPEC 1 +struct timespec { +        long tv_sec; +        long tv_nsec; +}; +#endif /* HAVE_STRUCT_TIMESPEC */ + +#ifndef SIG_BLOCK +#define SIG_BLOCK 0 +#endif /* SIG_BLOCK */ + +#ifndef SIG_UNBLOCK  +#define SIG_UNBLOCK 1 +#endif /* SIG_UNBLOCK */ + +#ifndef SIG_SETMASK +#define SIG_SETMASK 2 +#endif /* SIG_SETMASK */ + +#ifdef __cplusplus +extern "C" +{ +#endif                          /* __cplusplus */ + +/* + * ------------------------------------------------------------- + * + * POSIX 1003.1-2001 Options + * ========================= + * + * Options are normally set in <unistd.h>, which is not provided + * with pthreads-win32. + * + * For conformance with the Single Unix Specification (version 3), all of the + * options below are defined, and have a value of either -1 (not supported) + * or 200112L (supported). + * + * These options can neither be left undefined nor have a value of 0, because + * either indicates that sysconf(), which is not implemented, may be used at + * runtime to check the status of the option. + * + * _POSIX_THREADS (== 200112L) + *                      If == 200112L, you can use threads + * + * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) + *                      If == 200112L, you can control the size of a thread's + *                      stack + *                              pthread_attr_getstacksize + *                              pthread_attr_setstacksize + * + * _POSIX_THREAD_ATTR_STACKADDR (== -1) + *                      If == 200112L, you can allocate and control a thread's + *                      stack. If not supported, the following functions + *                      will return ENOSYS, indicating they are not + *                      supported: + *                              pthread_attr_getstackaddr + *                              pthread_attr_setstackaddr + * + * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) + *                      If == 200112L, you can use realtime scheduling. + *                      This option indicates that the behaviour of some + *                      implemented functions conforms to the additional TPS + *                      requirements in the standard. E.g. rwlocks favour + *                      writers over readers when threads have equal priority. + * + * _POSIX_THREAD_PRIO_INHERIT (== -1) + *                      If == 200112L, you can create priority inheritance + *                      mutexes. + *                              pthread_mutexattr_getprotocol + + *                              pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PRIO_PROTECT (== -1) + *                      If == 200112L, you can create priority ceiling mutexes + *                      Indicates the availability of: + *                              pthread_mutex_getprioceiling + *                              pthread_mutex_setprioceiling + *                              pthread_mutexattr_getprioceiling + *                              pthread_mutexattr_getprotocol     + + *                              pthread_mutexattr_setprioceiling + *                              pthread_mutexattr_setprotocol     + + * + * _POSIX_THREAD_PROCESS_SHARED (== -1) + *                      If set, you can create mutexes and condition + *                      variables that can be shared with another + *                      process.If set, indicates the availability + *                      of: + *                              pthread_mutexattr_getpshared + *                              pthread_mutexattr_setpshared + *                              pthread_condattr_getpshared + *                              pthread_condattr_setpshared + * + * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) + *                      If == 200112L you can use the special *_r library + *                      functions that provide thread-safe behaviour + * + * _POSIX_READER_WRITER_LOCKS (== 200112L) + *                      If == 200112L, you can use read/write locks + * + * _POSIX_SPIN_LOCKS (== 200112L) + *                      If == 200112L, you can use spin locks + * + * _POSIX_BARRIERS (== 200112L) + *                      If == 200112L, you can use barriers + * + *      + These functions provide both 'inherit' and/or + *        'protect' protocol, based upon these macro + *        settings. + * + * ------------------------------------------------------------- + */ + +/* + * POSIX Options + */ +#undef _POSIX_THREADS +#define _POSIX_THREADS 200112L + +#undef _POSIX_READER_WRITER_LOCKS +#define _POSIX_READER_WRITER_LOCKS 200112L + +#undef _POSIX_SPIN_LOCKS +#define _POSIX_SPIN_LOCKS 200112L + +#undef _POSIX_BARRIERS +#define _POSIX_BARRIERS 200112L + +#undef _POSIX_THREAD_SAFE_FUNCTIONS +#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L + +#undef _POSIX_THREAD_ATTR_STACKSIZE +#define _POSIX_THREAD_ATTR_STACKSIZE 200112L + +/* + * The following options are not supported + */ +#undef _POSIX_THREAD_ATTR_STACKADDR +#define _POSIX_THREAD_ATTR_STACKADDR -1 + +#undef _POSIX_THREAD_PRIO_INHERIT +#define _POSIX_THREAD_PRIO_INHERIT -1 + +#undef _POSIX_THREAD_PRIO_PROTECT +#define _POSIX_THREAD_PRIO_PROTECT -1 + +/* TPS is not fully supported.  */ +#undef _POSIX_THREAD_PRIORITY_SCHEDULING +#define _POSIX_THREAD_PRIORITY_SCHEDULING -1 + +#undef _POSIX_THREAD_PROCESS_SHARED +#define _POSIX_THREAD_PROCESS_SHARED -1 + + +/* + * POSIX 1003.1-2001 Limits + * =========================== + * + * These limits are normally set in <limits.h>, which is not provided with + * pthreads-win32. + * + * PTHREAD_DESTRUCTOR_ITERATIONS + *                      Maximum number of attempts to destroy + *                      a thread's thread-specific data on + *                      termination (must be at least 4) + * + * PTHREAD_KEYS_MAX + *                      Maximum number of thread-specific data keys + *                      available per process (must be at least 128) + * + * PTHREAD_STACK_MIN + *                      Minimum supported stack size for a thread + * + * PTHREAD_THREADS_MAX + *                      Maximum number of threads supported per + *                      process (must be at least 64). + * + * _POSIX_SEM_NSEMS_MAX + *      The maximum number of semaphores a process can have. + *      (only defined if not already defined) + * + * _POSIX_SEM_VALUE_MAX + *      The maximum value a semaphore can have. + *      (only defined if not already defined) + * + */ +#undef PTHREAD_DESTRUCTOR_ITERATIONS +#define PTHREAD_DESTRUCTOR_ITERATIONS                          4 + +#undef PTHREAD_KEYS_MAX +#define PTHREAD_KEYS_MAX                        64 + +#undef PTHREAD_STACK_MIN +#define PTHREAD_STACK_MIN                        0 + +#if PTW32_LEVEL < 2 +  /* Arbitrary value */ +#  undef PTHREAD_THREADS_MAX +#  define PTHREAD_THREADS_MAX                   2019 +#endif + +  /* Arbitrary value */ +#undef _POSIX_THREAD_THREADS_MAX +#define _POSIX_THREAD_THREADS_MAX               2019 + +  /* Arbitrary value */ +#undef _POSIX_SEM_NSEMS_MAX +#define _POSIX_SEM_NSEMS_MAX                    1024 + +#undef _POSIX_SEM_VALUE_MAX +#define _POSIX_SEM_VALUE_MAX                    (INT_MAX/2) + + +#if __GNUC__ && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the DLL code, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the DLL, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#ifndef PTW32_STATIC_LIB +#  ifdef PTW32_BUILD +#    define PTW32_DLLPORT __declspec (dllexport) +#  else +#    define PTW32_DLLPORT __declspec (dllimport) +#  endif +#else +#  define PTW32_DLLPORT +#endif + +/* + * The Open Watcom C/C++ compiler uses a non-standard calling convention + * that passes function args in registers unless __cdecl is explicitly specified + * in exposed function prototypes. + * + * We force all calls to cdecl even though this could slow Watcom code down + * slightly. If you know that the Watcom compiler will be used to build both + * the DLL and application, then you can probably define this as a null string. + * Remember that pthread.h (this file) is used for both the DLL and application builds. + */ +#define PTW32_CDECL __cdecl + +#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX +#   include     <sys/types.h> +#else +/* + * Generic handle type - intended to extend uniqueness beyond + * that available with a simple pointer. It should scale for either + * IA-32 or IA-64. + */ +typedef struct { +    void * p;                   /* Pointer to actual object */ +    unsigned int x;             /* Extra information - reuse count etc */ +} ptw32_handle_t; + +typedef ptw32_handle_t pthread_t; +typedef struct pthread_attr_t_ * pthread_attr_t; +typedef struct pthread_once_t_ pthread_once_t; +typedef struct pthread_key_t_ * pthread_key_t; +typedef struct pthread_mutex_t_ * pthread_mutex_t; +typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; +typedef struct pthread_cond_t_ * pthread_cond_t; +typedef struct pthread_condattr_t_ * pthread_condattr_t; +#endif +typedef struct pthread_rwlock_t_ * pthread_rwlock_t; +typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; +typedef struct pthread_spinlock_t_ * pthread_spinlock_t; +typedef struct pthread_barrier_t_ * pthread_barrier_t; +typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; + +/* + * ==================== + * ==================== + * POSIX Threads + * ==================== + * ==================== + */ + +enum { +/* + * pthread_attr_{get,set}detachstate + */ +  PTHREAD_CREATE_JOINABLE       = 0,  /* Default */ +  PTHREAD_CREATE_DETACHED       = 1, + +/* + * pthread_attr_{get,set}inheritsched + */ +  PTHREAD_INHERIT_SCHED         = 0, +  PTHREAD_EXPLICIT_SCHED        = 1,  /* Default */ + +/* + * pthread_{get,set}scope + */ +  PTHREAD_SCOPE_PROCESS         = 0, +  PTHREAD_SCOPE_SYSTEM          = 1,  /* Default */ + +/* + * pthread_setcancelstate paramters + */ +  PTHREAD_CANCEL_ENABLE         = 0,  /* Default */ +  PTHREAD_CANCEL_DISABLE        = 1, + +/* + * pthread_setcanceltype parameters + */ +  PTHREAD_CANCEL_ASYNCHRONOUS   = 0, +  PTHREAD_CANCEL_DEFERRED       = 1,  /* Default */ + +/* + * pthread_mutexattr_{get,set}pshared + * pthread_condattr_{get,set}pshared + */ +  PTHREAD_PROCESS_PRIVATE       = 0, +  PTHREAD_PROCESS_SHARED        = 1, + +/* + * pthread_barrier_wait + */ +  PTHREAD_BARRIER_SERIAL_THREAD = -1 +}; + +/* + * ==================== + * ==================== + * Cancelation + * ==================== + * ==================== + */ +#define PTHREAD_CANCELED       ((void *) -1) + + +/* + * ==================== + * ==================== + * Once Key + * ==================== + * ==================== + */ +#define PTHREAD_ONCE_INIT       { 0, PTW32_FALSE, 0, 0} + +struct pthread_once_t_ +{ +  int          state;        /* indicates if user function has been executed, or cancelled  */ +  int          started; +  int          eventUsers; +  HANDLE       event; +}; + + +/* + * ==================== + * ==================== + * Object initialisers + * ==================== + * ==================== + */ +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1) +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2) +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3) + +/* + * Compatibility with LinuxThreads + */ +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1) + +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1) + +#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1) + + +/* + * Mutex types. + */ +enum +{ +  /* Compatibility with LinuxThreads */ +  PTHREAD_MUTEX_FAST_NP, +  PTHREAD_MUTEX_RECURSIVE_NP, +  PTHREAD_MUTEX_ERRORCHECK_NP, +  PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, +  PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, +  /* For compatibility with POSIX */ +  PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, +  PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, +  PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, +  PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL +}; + + +typedef struct ptw32_cleanup_t ptw32_cleanup_t; + +#if defined(_MSC_VER) +/* Disable MSVC 'anachronism used' warning */ +#pragma warning( disable : 4229 ) +#endif + +typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *); + +#if defined(_MSC_VER) +#pragma warning( default : 4229 ) +#endif + +struct ptw32_cleanup_t +{ +  ptw32_cleanup_callback_t routine; +  void *arg; +  struct ptw32_cleanup_t *prev; +}; + +#ifdef __CLEANUP_SEH +        /* +         * WIN32 SEH version of cancel cleanup. +         */ + +#define pthread_cleanup_push( _rout, _arg ) \ +        { \ +            ptw32_cleanup_t     _cleanup; \ +            \ +        _cleanup.routine        = (ptw32_cleanup_callback_t)(_rout); \ +            _cleanup.arg        = (_arg); \ +            __try \ +              { \ + +#define pthread_cleanup_pop( _execute ) \ +              } \ +            __finally \ +                { \ +                    if( _execute || AbnormalTermination()) \ +                      { \ +                          (*(_cleanup.routine))( _cleanup.arg ); \ +                      } \ +                } \ +        } + +#else /* __CLEANUP_SEH */ + +#ifdef __CLEANUP_C + +        /* +         * C implementation of PThreads cancel cleanup +         */ + +#define pthread_cleanup_push( _rout, _arg ) \ +        { \ +            ptw32_cleanup_t     _cleanup; \ +            \ +            ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ + +#define pthread_cleanup_pop( _execute ) \ +            (void) ptw32_pop_cleanup( _execute ); \ +        } + +#else /* __CLEANUP_C */ + +#ifdef __CLEANUP_CXX + +        /* +         * C++ version of cancel cleanup. +         * - John E. Bossom. +         */ + +        class PThreadCleanup { +          /* +           * PThreadCleanup +           * +           * Purpose +           *      This class is a C++ helper class that is +           *      used to implement pthread_cleanup_push/ +           *      pthread_cleanup_pop. +           *      The destructor of this class automatically +           *      pops the pushed cleanup routine regardless +           *      of how the code exits the scope +           *      (i.e. such as by an exception) +           */ +      ptw32_cleanup_callback_t cleanUpRout; +          void    *       obj; +          int             executeIt; + +        public: +          PThreadCleanup() : +            cleanUpRout( 0 ), +            obj( 0 ), +            executeIt( 0 ) +            /* +             * No cleanup performed +             */ +            { +            } + +          PThreadCleanup( +             ptw32_cleanup_callback_t routine, +                         void    *       arg ) : +            cleanUpRout( routine ), +            obj( arg ), +            executeIt( 1 ) +            /* +             * Registers a cleanup routine for 'arg' +             */ +            { +            } + +          ~PThreadCleanup() +            { +              if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) +                { +                  (void) (*cleanUpRout)( obj ); +                } +            } + +          void execute( int exec ) +            { +              executeIt = exec; +            } +        }; + +        /* +         * C++ implementation of PThreads cancel cleanup; +         * This implementation takes advantage of a helper +         * class who's destructor automatically calls the +         * cleanup routine if we exit our scope weirdly +         */ +#define pthread_cleanup_push( _rout, _arg ) \ +        { \ +            PThreadCleanup  cleanup((ptw32_cleanup_callback_t)(_rout), \ +                                    (void *) (_arg) ); + +#define pthread_cleanup_pop( _execute ) \ +            cleanup.execute( _execute ); \ +        } + +#else + +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* __CLEANUP_CXX */ + +#endif /* __CLEANUP_C */ + +#endif /* __CLEANUP_SEH */ + +/* + * =============== + * =============== + * Methods + * =============== + * =============== + */ + +/* + * PThread Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr, +                                         int *detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr, +                                       void **stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr, +                                       size_t * stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr, +                                         int detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr, +                                       void *stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr, +                                       size_t stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr, +                                        struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr, +                                        const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *, +                                         int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (pthread_attr_t *, +                                         int *); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr, +                                         int inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(pthread_attr_t * attr, +                                         int * inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *, +                                   int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *, +                                   int *); + +/* + * PThread Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid, +                            const pthread_attr_t * attr, +                            void *(*start) (void *), +                            void *arg); + +PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid); + +PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1, +                           pthread_t t2); + +PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr); + +PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread, +                          void **value_ptr); + +PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state, +                                    int *oldstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type, +                                   int *oldtype); + +PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control, +                          void (*init_routine) (void)); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute); + +PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup, +                                 void (*routine) (void *), +                                 void *arg); +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread Specific Data Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key, +                                void (*destructor) (void *)); + +PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key); + +PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key, +                                 const void *value); + +PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key); + + +/* + * Mutex Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t +                                          * attr, +                                          int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, +                                          int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind); + +/* + * Barrier Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t +                                            * attr, +                                            int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, +                                            int pshared); + +/* + * Mutex Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex, +                                const pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t *mutex, +                                    const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex); + +/* + * Spinlock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock); + +/* + * Barrier Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier, +                                  const pthread_barrierattr_t * attr, +                                  unsigned int count); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier); + +/* + * Condition Variable Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr, +                                         int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr, +                                         int pshared); + +/* + * Condition Variable Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, +                               const pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond, +                               pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, +                                    pthread_mutex_t * mutex, +                                    const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); + +/* + * Scheduling + */ +PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread, +                                   int policy, +                                   const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread, +                                   int *policy, +                                   struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int); +  +PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void); + +/* + * Read-Write Lock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock, +                                const pthread_rwlockattr_t *attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, +                                       const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, +                                       const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, +                                           int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, +                                           int pshared); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 + +/* + * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32 + * already have signal.h that don't define these. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig); + +/* + * Non-portable functions + */ + +/* + * Compatibility with Linux. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, +                                         int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, +                                         int *kind); + +/* + * Possibly supported by other POSIX threads implementations + */ +PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval); +PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); + +/* + * Useful if an application wants to statically link + * the lib rather than load the DLL at run-time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void); + +/* + * Features that are auto-detected at load/run time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int); +enum ptw32_features { +  PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */ +  PTW32_ALERTABLE_ASYNC_CANCEL              = 0x0002  /* Can cancel blocked threads. */ +}; + +/* + * Register a system time change with the library. + * Causes the library to perform various functions + * in response to the change. Should be called whenever + * the application's top level window receives a + * WM_TIMECHANGE message. It can be passed directly to + * pthread_create() as a new thread if desired. + */ +PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *); + +#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* + * Returns the Win32 HANDLE for the POSIX thread. + */ +PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread); + + +/* + * Protected Methods + * + * This function blocks until the given WIN32 handle + * is signaled or pthread_cancel had been called. + * This function allows the caller to hook into the + * PThreads cancel mechanism. It is implemented using + * + *              WaitForMultipleObjects + * + * on 'waitHandle' and a manually reset WIN32 Event + * used to implement pthread_cancel. The 'timeout' + * argument to TimedWait is simply passed to + * WaitForMultipleObjects. + */ +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle); +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle, +                                        DWORD timeout); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread-Safe C Runtime Library Mappings. + */ +#ifndef _UWIN +#  if defined(NEED_ERRNO) +     PTW32_DLLPORT int * PTW32_CDECL _errno( void ); +#  else +#    ifndef errno +#      if (defined(_MT) || defined(_DLL)) +         __declspec(dllimport) extern int * __cdecl _errno(void); +#        define errno   (*_errno()) +#      endif +#    endif +#  endif +#endif + +/* + * WIN32 C runtime library had been made thread-safe + * without affecting the user interface. Provide + * mappings from the UNIX thread-safe versions to + * the standard C runtime library calls. + * Only provide function mappings for functions that + * actually exist on WIN32. + */ + +#if !defined(__MINGW32__) +#define strtok_r( _s, _sep, _lasts ) \ +        ( *(_lasts) = strtok( (_s), (_sep) ) ) +#endif /* !__MINGW32__ */ + +#define asctime_r( _tm, _buf ) \ +        ( strcpy( (_buf), asctime( (_tm) ) ), \ +          (_buf) ) + +#define ctime_r( _clock, _buf ) \ +        ( strcpy( (_buf), ctime( (_clock) ) ),  \ +          (_buf) ) + +#define gmtime_r( _clock, _result ) \ +        ( *(_result) = *gmtime( (_clock) ), \ +          (_result) ) + +#define localtime_r( _clock, _result ) \ +        ( *(_result) = *localtime( (_clock) ), \ +          (_result) ) + +#define rand_r( _seed ) \ +        ( _seed == _seed? rand() : rand() ) + + +/* + * Some compiler environments don't define some things. + */ +#if defined(__BORLANDC__) +#  define _ftime ftime +#  define _timeb timeb +#endif + +#ifdef __cplusplus + +/* + * Internal exceptions + */ +class ptw32_exception {}; +class ptw32_exception_cancel : public ptw32_exception {}; +class ptw32_exception_exit   : public ptw32_exception {}; + +#endif + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* FIXME: This is only required if the library was built using SEH */ +/* + * Get internal SEH tag + */ +PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#ifndef PTW32_BUILD + +#ifdef __CLEANUP_SEH + +/* + * Redefine the SEH __except keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#define __except( E ) \ +        __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ +                 ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) + +#endif /* __CLEANUP_SEH */ + +#ifdef __CLEANUP_CXX + +/* + * Redefine the C++ catch keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#ifdef _MSC_VER +        /* +         * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' +         * if you want Pthread-Win32 cancelation and pthread_exit to work. +         */ + +#ifndef PtW32NoCatchWarn + +#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") +#pragma message("------------------------------------------------------------------") +#pragma message("When compiling applications with MSVC++ and C++ exception handling:") +#pragma message("  Replace any 'catch( ... )' in routines called from POSIX threads") +#pragma message("  with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") +#pragma message("  cancelation and pthread_exit to work. For example:") +#pragma message("") +#pragma message("    #ifdef PtW32CatchAll") +#pragma message("      PtW32CatchAll") +#pragma message("    #else") +#pragma message("      catch(...)") +#pragma message("    #endif") +#pragma message("        {") +#pragma message("          /* Catchall block processing */") +#pragma message("        }") +#pragma message("------------------------------------------------------------------") + +#endif + +#define PtW32CatchAll \ +        catch( ptw32_exception & ) { throw; } \ +        catch( ... ) + +#else /* _MSC_VER */ + +#define catch( E ) \ +        catch( ptw32_exception & ) { throw; } \ +        catch( E ) + +#endif /* _MSC_VER */ + +#endif /* __CLEANUP_CXX */ + +#endif /* ! PTW32_BUILD */ + +#ifdef __cplusplus +}                               /* End of extern "C" */ +#endif                          /* __cplusplus */ + +#ifdef PTW32__HANDLE_DEF +# undef HANDLE +#endif +#ifdef PTW32__DWORD_DEF +# undef DWORD +#endif + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* ! RC_INVOKED */ + +#endif /* PTHREAD_H */ diff --git a/pthread_mutex_timedlock.c b/pthread_mutex_timedlock.c index ad373ba..a238552 100644 --- a/pthread_mutex_timedlock.c +++ b/pthread_mutex_timedlock.c @@ -1,196 +1,196 @@ -/*
 - * pthread_mutex_timedlock.c
 - *
 - * Description:
 - * This translation unit implements mutual exclusion (mutex) primitives.
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#include "pthread.h"
 -#include "implement.h"
 -
 -
 -static INLINE int
 -ptw32_timed_eventwait (HANDLE event, const struct timespec *abstime)
 -     /*
 -      * ------------------------------------------------------
 -      * DESCRIPTION
 -      *      This function waits on an event until signaled or until
 -      *      abstime passes.
 -      *      If abstime has passed when this routine is called then
 -      *      it returns a result to indicate this.
 -      *
 -      *      If 'abstime' is a NULL pointer then this function will
 -      *      block until it can successfully decrease the value or
 -      *      until interrupted by a signal.
 -      *
 -      *      This routine is not a cancelation point.
 -      *
 -      * RESULTS
 -      *              0               successfully signaled,
 -      *              ETIMEDOUT       abstime passed
 -      *              EINVAL          'event' is not a valid event,
 -      *
 -      * ------------------------------------------------------
 -      */
 -{
 -
 -  DWORD milliseconds;
 -  DWORD status;
 -
 -  if (event == NULL)
 -    {
 -      return EINVAL;
 -    }
 -  else
 -    {
 -      if (abstime == NULL)
 -	{
 -	  milliseconds = INFINITE;
 -	}
 -      else
 -	{
 -	  /* 
 -	   * Calculate timeout as milliseconds from current system time. 
 -	   */
 -	  milliseconds = ptw32_relmillisecs (abstime);
 -	}
 -
 -      status = WaitForSingleObject (event, milliseconds);
 -
 -      if (status == WAIT_OBJECT_0)
 -	{
 -	  return 0;
 -	}
 -      else if (status == WAIT_TIMEOUT)
 -	{
 -	  return ETIMEDOUT;
 -	}
 -      else
 -	{
 -	  return EINVAL;
 -	}
 -    }
 -
 -  return 0;
 -
 -}				/* ptw32_timed_semwait */
 -
 -
 -int
 -pthread_mutex_timedlock (pthread_mutex_t * mutex,
 -			 const struct timespec *abstime)
 -{
 -  int result;
 -  pthread_mutex_t mx;
 -
 -  /*
 -   * Let the system deal with invalid pointers.
 -   */
 -
 -  /*
 -   * We do a quick check to see if we need to do more work
 -   * to initialise a static mutex. We check
 -   * again inside the guarded section of ptw32_mutex_check_need_init()
 -   * to avoid race conditions.
 -   */
 -  if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
 -    {
 -      if ((result = ptw32_mutex_check_need_init (mutex)) != 0)
 -	{
 -	  return (result);
 -	}
 -    }
 -
 -  mx = *mutex;
 -
 -  if (mx->kind == PTHREAD_MUTEX_NORMAL)
 -    {
 -      if ((LONG) PTW32_INTERLOCKED_EXCHANGE(
 -		   (LPLONG) &mx->lock_idx,
 -		   (LONG) 1) != 0)
 -	{
 -          while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
 -                          (LPLONG) &mx->lock_idx,
 -			  (LONG) -1) != 0)
 -            {
 -	      if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
 -		{
 -		  return result;
 -		}
 -	    }
 -	}
 -    }
 -  else
 -    {
 -      pthread_t self = pthread_self();
 -
 -      if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE(
 -                   (PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
 -		   (PTW32_INTERLOCKED_LONG) 1,
 -		   (PTW32_INTERLOCKED_LONG) 0) == 0)
 -	{
 -	  mx->recursive_count = 1;
 -	  mx->ownerThread = self;
 -	}
 -      else
 -	{
 -	  if (pthread_equal (mx->ownerThread, self))
 -	    {
 -	      if (mx->kind == PTHREAD_MUTEX_RECURSIVE)
 -		{
 -		  mx->recursive_count++;
 -		}
 -	      else
 -		{
 -		  return EDEADLK;
 -		}
 -	    }
 -	  else
 -	    {
 -              while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
 -                              (LPLONG) &mx->lock_idx,
 -			      (LONG) -1) != 0)
 -                {
 -		  if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
 -		    {
 -		      return result;
 -		    }
 -		}
 -
 -	      mx->recursive_count = 1;
 -	      mx->ownerThread = self;
 -	    }
 -	}
 -    }
 -
 -  return 0;
 -}
 +/* + * pthread_mutex_timedlock.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "implement.h" + + +static INLINE int +ptw32_timed_eventwait (HANDLE event, const struct timespec *abstime) +     /* +      * ------------------------------------------------------ +      * DESCRIPTION +      *      This function waits on an event until signaled or until +      *      abstime passes. +      *      If abstime has passed when this routine is called then +      *      it returns a result to indicate this. +      * +      *      If 'abstime' is a NULL pointer then this function will +      *      block until it can successfully decrease the value or +      *      until interrupted by a signal. +      * +      *      This routine is not a cancelation point. +      * +      * RESULTS +      *              0               successfully signaled, +      *              ETIMEDOUT       abstime passed +      *              EINVAL          'event' is not a valid event, +      * +      * ------------------------------------------------------ +      */ +{ + +  DWORD milliseconds; +  DWORD status; + +  if (event == NULL) +    { +      return EINVAL; +    } +  else +    { +      if (abstime == NULL) +	{ +	  milliseconds = INFINITE; +	} +      else +	{ +	  /*  +	   * Calculate timeout as milliseconds from current system time.  +	   */ +	  milliseconds = ptw32_relmillisecs (abstime); +	} + +      status = WaitForSingleObject (event, milliseconds); + +      if (status == WAIT_OBJECT_0) +	{ +	  return 0; +	} +      else if (status == WAIT_TIMEOUT) +	{ +	  return ETIMEDOUT; +	} +      else +	{ +	  return EINVAL; +	} +    } + +  return 0; + +}				/* ptw32_timed_semwait */ + + +int +pthread_mutex_timedlock (pthread_mutex_t * mutex, +			 const struct timespec *abstime) +{ +  int result; +  pthread_mutex_t mx; + +  /* +   * Let the system deal with invalid pointers. +   */ + +  /* +   * We do a quick check to see if we need to do more work +   * to initialise a static mutex. We check +   * again inside the guarded section of ptw32_mutex_check_need_init() +   * to avoid race conditions. +   */ +  if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER) +    { +      if ((result = ptw32_mutex_check_need_init (mutex)) != 0) +	{ +	  return (result); +	} +    } + +  mx = *mutex; + +  if (mx->kind == PTHREAD_MUTEX_NORMAL) +    { +      if ((LONG) PTW32_INTERLOCKED_EXCHANGE( +		   (LPLONG) &mx->lock_idx, +		   (LONG) 1) != 0) +	{ +          while ((LONG) PTW32_INTERLOCKED_EXCHANGE( +                          (LPLONG) &mx->lock_idx, +			  (LONG) -1) != 0) +            { +	      if (0 != (result = ptw32_timed_eventwait (mx->event, abstime))) +		{ +		  return result; +		} +	    } +	} +    } +  else +    { +      pthread_t self = pthread_self(); + +      if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE( +                   (PTW32_INTERLOCKED_LPLONG) &mx->lock_idx, +		   (PTW32_INTERLOCKED_LONG) 1, +		   (PTW32_INTERLOCKED_LONG) 0) == 0) +	{ +	  mx->recursive_count = 1; +	  mx->ownerThread = self; +	} +      else +	{ +	  if (pthread_equal (mx->ownerThread, self)) +	    { +	      if (mx->kind == PTHREAD_MUTEX_RECURSIVE) +		{ +		  mx->recursive_count++; +		} +	      else +		{ +		  return EDEADLK; +		} +	    } +	  else +	    { +              while ((LONG) PTW32_INTERLOCKED_EXCHANGE( +                              (LPLONG) &mx->lock_idx, +			      (LONG) -1) != 0) +                { +		  if (0 != (result = ptw32_timed_eventwait (mx->event, abstime))) +		    { +		      return result; +		    } +		} + +	      mx->recursive_count = 1; +	      mx->ownerThread = self; +	    } +	} +    } + +  return 0; +} diff --git a/pthread_once.c b/pthread_once.c index fad9dcc..eb355dd 100644 --- a/pthread_once.c +++ b/pthread_once.c @@ -1,403 +1,403 @@ -/*
 - * pthread_once.c
 - *
 - * Description:
 - * This translation unit implements miscellaneous thread functions.
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -/*
 - * NOTES:
 - * pthread_once() performs a very simple task. So why is this implementation
 - * so complicated?
 - *
 - * The original implementation WAS very simple, but it relied on Windows random
 - * priority boosting to resolve starvation problems. Windows priority boosting
 - * does not occur for realtime priority classes (levels 16 to 31).
 - *
 - * You can check back to previous versions of code in the CVS repository or
 - * search the mailing list archives for discussion.
 - *
 - * Version A
 - * ---------
 - * Waiting threads would resume and suspend again using Sleep(0) until the
 - * init_routine had completed, but a higher priority waiter could hog the CPU and
 - * starve the initter thread until Windows randomly boosted it's priority, or forever
 - * for realtime applications.
 - *
 - * Version B
 - * ---------
 - * This was fixed by introducing a per once_control manual-reset event that is
 - * created and destroyed dynamically only if there are waiters. The design did not
 - * need global critical sections. Each once_control remained independent. A waiter
 - * could be confident that if the event was not null then it did not need to create
 - * the event.
 - *
 - * Version C
 - * ---------
 - * Since a change in ABI would result from version B, it was decided to take
 - * the opportunity and make pthread_once() fully compliant with the Single Unix
 - * Specification (version 3 at the time). This required allowing the init_routine
 - * to be a cancelation point. A cancelation meant that at least some waiting threads
 - * if any had to be woken so that one might become the new initter thread.
 - * Waiters could no longer simply assume that, if the event was not null, it did
 - * not need to create an event. Some real critical sections were needed, and in the
 - * current library, a global CRITICAL_SECTION is probably more efficient than a per
 - * once_control PTHREAD_MUTEX_INITIALIZER that should be somehow destroyed on exit from
 - * pthread_once(). Also, the cancelled init thread needed to set the event, and the
 - * new init thread (the winner of the race between any newly arriving threads and
 - * waking waiters) would need to reset it again. In the meantime, threads could be
 - * happily looping around until they either suspended on the reset event, or exited
 - * because the init thread had completed. It was also once again possible for a higher
 - * priority waiter to starve the init thread.
 - * 
 - * Version D
 - * ---------
 - * There were now two options considered:
 - * - use an auto-reset event; OR
 - * - add our own priority boosting.
 - *
 - * An auto-reset event would stop threads from looping ok, but it makes threads
 - * dependent on earlier threads to successfully set the event in turn when it's time
 - * to wake up, and this serialises threads unecessarily on MP systems. It also adds
 - * an extra kernel call for each waking thread. If one waiter wakes and dies (async
 - * cancelled or killed) before it can set the event, then all remaining waiters are
 - * stranded.
 - *
 - * Priority boosting is a standard method for solving priority inversion and
 - * starvation problems. Furthermore, all of the priority boost logic can
 - * be restricted to the post cancellation tracks. That is, it need not slow
 - * the normal cancel-free behaviour. Threads remain independent of other threads.
 - *
 - * The implementation below adds only a few local (to the thread) integer comparisons
 - * to the normal track through the routine and additional bus locking/cache line
 - * syncing operations have been avoided altogether in the uncontended track.
 - */
 -
 -#include "pthread.h"
 -#include "implement.h"
 -
 -
 -static void PTW32_CDECL
 -ptw32_once_init_routine_cleanup(void * arg)
 -{
 -  pthread_once_t * once_control = (pthread_once_t *) arg;
 -
 -  (void) PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->state, (LONG)PTW32_ONCE_CANCELLED);
 -  (void) PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->started, (LONG)PTW32_FALSE);
 -
 -//  EnterCriticalSection(&ptw32_once_event_lock);
 -  if (InterlockedExchangeAdd((LPLONG)&once_control->event, 0L)) /* MBR fence */
 -    {
 -      int lasterror = GetLastError ();
 -      int lastWSAerror = WSAGetLastError ();
 -
 -      /*
 -       * There are waiters, wake some up.
 -       */
 -      if (!SetEvent(once_control->event))
 -	{
 -	  SetLastError (lasterror);
 -	  WSASetLastError (lastWSAerror);
 -	}
 -    }
 -//  LeaveCriticalSection(&ptw32_once_event_lock);
 -}
 -
 -
 -int
 -pthread_once (pthread_once_t * once_control, void (*init_routine) (void))
 -	/*
 -	 * ------------------------------------------------------
 -	 * DOCPUBLIC
 -	 *      If any thread in a process  with  a  once_control  parameter
 -	 *      makes  a  call to pthread_once(), the first call will summon
 -	 *      the init_routine(), but  subsequent  calls  will  not. The
 -	 *      once_control  parameter  determines  whether  the associated
 -	 *      initialization routine has been called.  The  init_routine()
 -	 *      is complete upon return of pthread_once().
 -	 *      This function guarantees that one and only one thread
 -	 *      executes the initialization routine, init_routine when
 -	 *      access is controlled by the pthread_once_t control
 -	 *      key.
 -	 *
 -	 *      pthread_once() is not a cancelation point, but the init_routine
 -	 *      can be. If it's cancelled then the effect on the once_control is
 -	 *      as if pthread_once had never been entered.
 -	 *
 -	 *
 -	 * PARAMETERS
 -	 *      once_control
 -	 *              pointer to an instance of pthread_once_t
 -	 *
 -	 *      init_routine
 -	 *              pointer to an initialization routine
 -	 *
 -	 *
 -	 * DESCRIPTION
 -	 *      See above.
 -	 *
 -	 * RESULTS
 -	 *              0               success,
 -	 *              EINVAL          once_control or init_routine is NULL
 -	 *
 -	 * ------------------------------------------------------
 -	 */
 -{
 -  int result;
 -  int lasterror;
 -  int lastWSAerror;
 -  int restoreLastError;
 -  LONG state;
 -  pthread_t self;
 -  HANDLE w32Thread = 0;
 -
 -  if (once_control == NULL || init_routine == NULL)
 -    {
 -      result = EINVAL;
 -      goto FAIL0;
 -    }
 -  else
 -    {
 -      result = 0;
 -    }
 -
 -  /*
 -   * We want to be invisible to GetLastError() outside of this routine.
 -   */
 -  lasterror = GetLastError ();
 -  lastWSAerror = WSAGetLastError ();
 -  restoreLastError = PTW32_FALSE;
 -
 -  while (!((state = InterlockedExchangeAdd((LPLONG)&once_control->state, 0L)) /* Atomic Read */
 -	   & (LONG)PTW32_ONCE_DONE))
 -    {
 -      LONG cancelled = (state & PTW32_ONCE_CANCELLED);
 -
 -      if (cancelled)
 -	{
 -	  /* Boost priority momentarily */
 -	  if (!w32Thread)
 -	    {
 -	      self = pthread_self();
 -	      w32Thread = ((ptw32_thread_t *)self.p)->threadH;
 -	    }
 -	  /*
 -	   * Prevent pthread_setschedparam() from changing our priority while we're boosted.
 -	   */
 -	  pthread_mutex_lock(&((ptw32_thread_t *)self.p)->threadLock);
 -	  SetThreadPriority(w32Thread, THREAD_PRIORITY_HIGHEST);
 -	}
 -
 -      if (!PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->started, (LONG)PTW32_TRUE))
 -	{
 -	  if (cancelled)
 -	    {
 -	      /*
 -	       * The previous initter was cancelled.
 -	       * We now have a new initter (us) and we need to make the rest wait again.
 -	       * Furthermore, we're running at max priority until after we've reset the event
 -	       * so we will not be starved by any other threads that may now be looping
 -	       * around.
 -	       */
 -//	      EnterCriticalSection(&ptw32_once_event_lock);
 -	      if (InterlockedExchangeAdd((LPLONG)&once_control->event, 0L)) /* MBR fence */
 -		{
 -		  if (!ResetEvent(once_control->event))
 -		    {
 -		      restoreLastError = PTW32_TRUE;
 -		    }
 -		}
 -//	      LeaveCriticalSection(&ptw32_once_event_lock);
 -
 -	      /*
 -	       * Any threads entering the wait section and getting out again before
 -	       * the event is reset and the CANCELLED state is cleared will, at worst,
 -	       * just go around again or, if they suspend and we (the initter) completes before
 -	       * they resume, they will see state == DONE and leave immediately.
 -	       */
 -	      PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->state, (LONG)PTW32_ONCE_CLEAR);
 -
 -	      /*
 -	       * Restore priority. We catch any changes to this thread's priority
 -	       * only if they were done through the POSIX API (i.e. pthread_setschedparam)
 -	       */
 -	      SetThreadPriority(w32Thread, ((ptw32_thread_t *)self.p)->sched_priority);
 -	      pthread_mutex_unlock(&((ptw32_thread_t *)self.p)->threadLock);
 -	    }
 -
 -#ifdef _MSC_VER
 -#pragma inline_depth(0)
 -#endif
 -
 -	  pthread_cleanup_push(ptw32_once_init_routine_cleanup, (void *) once_control);
 -	  (*init_routine)();
 -	  pthread_cleanup_pop(0);
 -
 -#ifdef _MSC_VER
 -#pragma inline_depth()
 -#endif
 -
 -	  (void) PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->state, (LONG)PTW32_ONCE_DONE);
 -
 -	  /*
 -	   * we didn't create the event.
 -	   * it is only there if there is someone waiting.
 -	   * Avoid using the global event_lock but still prevent SetEvent
 -	   * from overwriting any 'lasterror' if the event is closed before we
 -	   * are done with it.
 -	   */
 -	  if (InterlockedExchangeAdd((LPLONG)&once_control->event, 0L)) /* MBR fence */
 -	    {
 -	      if (!SetEvent(once_control->event))
 -		{
 -		  restoreLastError = PTW32_TRUE;
 -		}
 -	    }
 -	}
 -      else
 -	{
 -	  HANDLE tmpEvent;
 -
 -	  if (cancelled)
 -	    {
 -	      /*
 -	       * Restore priority. We catch any changes to this thread's priority
 -	       * only if they were done through the POSIX API (i.e. pthread_setschedparam.
 -	       */
 -	      SetThreadPriority(w32Thread, ((ptw32_thread_t *)self.p)->sched_priority);
 -	      pthread_mutex_unlock(&((ptw32_thread_t *)self.p)->threadLock);
 -	    }
 -
 -	  /*
 -	   * wait for init.
 -	   * while waiting, create an event to wait on
 -	   */
 -
 -//	  EnterCriticalSection(&ptw32_once_event_lock);
 -	  if (1 == InterlockedIncrement((LPLONG)&once_control->eventUsers))
 -	    {
 -	      /*
 -	       * RE CANCELLATION:
 -	       * If we are the first thread after the initter thread, and the init_routine is cancelled
 -	       * while we're suspended at this point in the code:-
 -	       * - state will not get set to PTW32_ONCE_DONE;
 -	       * - cleanup will not see an event and cannot set it;
 -	       * - therefore, we will eventually resume, create an event and wait on it;
 -	       * cleanup will set state == CANCELLED before checking for an event, so that
 -	       * we will see it and avoid waiting (as for state == DONE). We will go around again and
 -	       * we may then become the initter.
 -	       * If we are still the only other thread when we get to the end of this block, we will
 -	       * have closed the event (good). If another thread beats us to be initter, then we will
 -	       * re-enter here (good). In case the old event is reused, the event is always reset by
 -	       * the new initter before clearing the CANCELLED state, causing any threads that are
 -	       * cycling around the loop to wait again.
 -	       * The initter thread is guaranteed to be at equal or higher priority than any waiters
 -	       * so no waiters will starve the initter, which might otherwise cause us to loop
 -	       * forever.
 -	       */
 -	      tmpEvent = CreateEvent(NULL, PTW32_TRUE, PTW32_FALSE, NULL);
 -	      if (PTW32_INTERLOCKED_COMPARE_EXCHANGE((PTW32_INTERLOCKED_LPLONG)&once_control->event,
 -						     (PTW32_INTERLOCKED_LONG)tmpEvent,
 -						     (PTW32_INTERLOCKED_LONG)0))
 -		{
 -		  CloseHandle(tmpEvent);
 -		}
 -	    }
 -//	  LeaveCriticalSection(&ptw32_once_event_lock);
 -
 -	  /*
 -	   * Check 'state' again in case the initting thread has finished or cancelled
 -	   * and left before seeing that there was an event to trigger.
 -	   */
 -
 -	  switch (InterlockedExchangeAdd((LPLONG)&once_control->state, 0L))
 -	    {
 -	    case PTW32_ONCE_CLEAR:
 -	      {
 -		/* Neither DONE nor CANCELLED */
 -		if (WAIT_FAILED == WaitForSingleObject(once_control->event, INFINITE))
 -		  {
 -		    restoreLastError = PTW32_TRUE;
 -		    /*
 -		     * If the wait failed it's probably because the event is invalid.
 -		     * That's possible after a cancellation (but rare) if we got through the
 -		     * event create block above while a woken thread was suspended between
 -		     * the decrement and exchange below and then resumed before we could wait.
 -		     * So we'll yield.
 -		     */
 -		    Sleep(0);
 -		  }
 -		break;
 -	      }
 -	    case PTW32_ONCE_CANCELLED:
 -	      {
 -		if (once_control->started)
 -		  {
 -		    /* The new initter hasn't cleared the cancellation yet, so give the
 -		     * processor to a more productive thread. */
 -		    Sleep(0);
 -		  }
 -		break;
 -	      }
 -	    }
 -
 -	  /* last one out shut off the lights */
 -//	  EnterCriticalSection(&ptw32_once_event_lock);
 -	  if (0 == InterlockedDecrement((LPLONG)&once_control->eventUsers))
 -	    {
 -	      /* we were last */
 -	      if ((tmpEvent = (HANDLE)
 -		   PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->event,
 -					      (LONG)0)))
 -		{
 -		  CloseHandle(tmpEvent);
 -		}
 -	    }
 -//	  LeaveCriticalSection(&ptw32_once_event_lock);
 -	}
 -    }
 -
 -  if (restoreLastError)
 -    {
 -      SetLastError (lasterror);
 -      WSASetLastError (lastWSAerror);
 -    }
 -
 -  /*
 -   * ------------
 -   * Failure Code
 -   * ------------
 -   */
 -FAIL0:
 -  return (result);
 -
 -}				/* pthread_once */
 +/* + * pthread_once.c + * + * Description: + * This translation unit implements miscellaneous thread functions. + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/* + * NOTES: + * pthread_once() performs a very simple task. So why is this implementation + * so complicated? + * + * The original implementation WAS very simple, but it relied on Windows random + * priority boosting to resolve starvation problems. Windows priority boosting + * does not occur for realtime priority classes (levels 16 to 31). + * + * You can check back to previous versions of code in the CVS repository or + * search the mailing list archives for discussion. + * + * Version A + * --------- + * Waiting threads would resume and suspend again using Sleep(0) until the + * init_routine had completed, but a higher priority waiter could hog the CPU and + * starve the initter thread until Windows randomly boosted it's priority, or forever + * for realtime applications. + * + * Version B + * --------- + * This was fixed by introducing a per once_control manual-reset event that is + * created and destroyed dynamically only if there are waiters. The design did not + * need global critical sections. Each once_control remained independent. A waiter + * could be confident that if the event was not null then it did not need to create + * the event. + * + * Version C + * --------- + * Since a change in ABI would result from version B, it was decided to take + * the opportunity and make pthread_once() fully compliant with the Single Unix + * Specification (version 3 at the time). This required allowing the init_routine + * to be a cancelation point. A cancelation meant that at least some waiting threads + * if any had to be woken so that one might become the new initter thread. + * Waiters could no longer simply assume that, if the event was not null, it did + * not need to create an event. Some real critical sections were needed, and in the + * current library, a global CRITICAL_SECTION is probably more efficient than a per + * once_control PTHREAD_MUTEX_INITIALIZER that should be somehow destroyed on exit from + * pthread_once(). Also, the cancelled init thread needed to set the event, and the + * new init thread (the winner of the race between any newly arriving threads and + * waking waiters) would need to reset it again. In the meantime, threads could be + * happily looping around until they either suspended on the reset event, or exited + * because the init thread had completed. It was also once again possible for a higher + * priority waiter to starve the init thread. + *  + * Version D + * --------- + * There were now two options considered: + * - use an auto-reset event; OR + * - add our own priority boosting. + * + * An auto-reset event would stop threads from looping ok, but it makes threads + * dependent on earlier threads to successfully set the event in turn when it's time + * to wake up, and this serialises threads unecessarily on MP systems. It also adds + * an extra kernel call for each waking thread. If one waiter wakes and dies (async + * cancelled or killed) before it can set the event, then all remaining waiters are + * stranded. + * + * Priority boosting is a standard method for solving priority inversion and + * starvation problems. Furthermore, all of the priority boost logic can + * be restricted to the post cancellation tracks. That is, it need not slow + * the normal cancel-free behaviour. Threads remain independent of other threads. + * + * The implementation below adds only a few local (to the thread) integer comparisons + * to the normal track through the routine and additional bus locking/cache line + * syncing operations have been avoided altogether in the uncontended track. + */ + +#include "pthread.h" +#include "implement.h" + + +static void PTW32_CDECL +ptw32_once_init_routine_cleanup(void * arg) +{ +  pthread_once_t * once_control = (pthread_once_t *) arg; + +  (void) PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->state, (LONG)PTW32_ONCE_CANCELLED); +  (void) PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->started, (LONG)PTW32_FALSE); + +//  EnterCriticalSection(&ptw32_once_event_lock); +  if (InterlockedExchangeAdd((LPLONG)&once_control->event, 0L)) /* MBR fence */ +    { +      int lasterror = GetLastError (); +      int lastWSAerror = WSAGetLastError (); + +      /* +       * There are waiters, wake some up. +       */ +      if (!SetEvent(once_control->event)) +	{ +	  SetLastError (lasterror); +	  WSASetLastError (lastWSAerror); +	} +    } +//  LeaveCriticalSection(&ptw32_once_event_lock); +} + + +int +pthread_once (pthread_once_t * once_control, void (*init_routine) (void)) +	/* +	 * ------------------------------------------------------ +	 * DOCPUBLIC +	 *      If any thread in a process  with  a  once_control  parameter +	 *      makes  a  call to pthread_once(), the first call will summon +	 *      the init_routine(), but  subsequent  calls  will  not. The +	 *      once_control  parameter  determines  whether  the associated +	 *      initialization routine has been called.  The  init_routine() +	 *      is complete upon return of pthread_once(). +	 *      This function guarantees that one and only one thread +	 *      executes the initialization routine, init_routine when +	 *      access is controlled by the pthread_once_t control +	 *      key. +	 * +	 *      pthread_once() is not a cancelation point, but the init_routine +	 *      can be. If it's cancelled then the effect on the once_control is +	 *      as if pthread_once had never been entered. +	 * +	 * +	 * PARAMETERS +	 *      once_control +	 *              pointer to an instance of pthread_once_t +	 * +	 *      init_routine +	 *              pointer to an initialization routine +	 * +	 * +	 * DESCRIPTION +	 *      See above. +	 * +	 * RESULTS +	 *              0               success, +	 *              EINVAL          once_control or init_routine is NULL +	 * +	 * ------------------------------------------------------ +	 */ +{ +  int result; +  int lasterror; +  int lastWSAerror; +  int restoreLastError; +  LONG state; +  pthread_t self; +  HANDLE w32Thread = 0; + +  if (once_control == NULL || init_routine == NULL) +    { +      result = EINVAL; +      goto FAIL0; +    } +  else +    { +      result = 0; +    } + +  /* +   * We want to be invisible to GetLastError() outside of this routine. +   */ +  lasterror = GetLastError (); +  lastWSAerror = WSAGetLastError (); +  restoreLastError = PTW32_FALSE; + +  while (!((state = InterlockedExchangeAdd((LPLONG)&once_control->state, 0L)) /* Atomic Read */ +	   & (LONG)PTW32_ONCE_DONE)) +    { +      LONG cancelled = (state & PTW32_ONCE_CANCELLED); + +      if (cancelled) +	{ +	  /* Boost priority momentarily */ +	  if (!w32Thread) +	    { +	      self = pthread_self(); +	      w32Thread = ((ptw32_thread_t *)self.p)->threadH; +	    } +	  /* +	   * Prevent pthread_setschedparam() from changing our priority while we're boosted. +	   */ +	  pthread_mutex_lock(&((ptw32_thread_t *)self.p)->threadLock); +	  SetThreadPriority(w32Thread, THREAD_PRIORITY_HIGHEST); +	} + +      if (!PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->started, (LONG)PTW32_TRUE)) +	{ +	  if (cancelled) +	    { +	      /* +	       * The previous initter was cancelled. +	       * We now have a new initter (us) and we need to make the rest wait again. +	       * Furthermore, we're running at max priority until after we've reset the event +	       * so we will not be starved by any other threads that may now be looping +	       * around. +	       */ +//	      EnterCriticalSection(&ptw32_once_event_lock); +	      if (InterlockedExchangeAdd((LPLONG)&once_control->event, 0L)) /* MBR fence */ +		{ +		  if (!ResetEvent(once_control->event)) +		    { +		      restoreLastError = PTW32_TRUE; +		    } +		} +//	      LeaveCriticalSection(&ptw32_once_event_lock); + +	      /* +	       * Any threads entering the wait section and getting out again before +	       * the event is reset and the CANCELLED state is cleared will, at worst, +	       * just go around again or, if they suspend and we (the initter) completes before +	       * they resume, they will see state == DONE and leave immediately. +	       */ +	      PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->state, (LONG)PTW32_ONCE_CLEAR); + +	      /* +	       * Restore priority. We catch any changes to this thread's priority +	       * only if they were done through the POSIX API (i.e. pthread_setschedparam) +	       */ +	      SetThreadPriority(w32Thread, ((ptw32_thread_t *)self.p)->sched_priority); +	      pthread_mutex_unlock(&((ptw32_thread_t *)self.p)->threadLock); +	    } + +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif + +	  pthread_cleanup_push(ptw32_once_init_routine_cleanup, (void *) once_control); +	  (*init_routine)(); +	  pthread_cleanup_pop(0); + +#ifdef _MSC_VER +#pragma inline_depth() +#endif + +	  (void) PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->state, (LONG)PTW32_ONCE_DONE); + +	  /* +	   * we didn't create the event. +	   * it is only there if there is someone waiting. +	   * Avoid using the global event_lock but still prevent SetEvent +	   * from overwriting any 'lasterror' if the event is closed before we +	   * are done with it. +	   */ +	  if (InterlockedExchangeAdd((LPLONG)&once_control->event, 0L)) /* MBR fence */ +	    { +	      if (!SetEvent(once_control->event)) +		{ +		  restoreLastError = PTW32_TRUE; +		} +	    } +	} +      else +	{ +	  HANDLE tmpEvent; + +	  if (cancelled) +	    { +	      /* +	       * Restore priority. We catch any changes to this thread's priority +	       * only if they were done through the POSIX API (i.e. pthread_setschedparam. +	       */ +	      SetThreadPriority(w32Thread, ((ptw32_thread_t *)self.p)->sched_priority); +	      pthread_mutex_unlock(&((ptw32_thread_t *)self.p)->threadLock); +	    } + +	  /* +	   * wait for init. +	   * while waiting, create an event to wait on +	   */ + +//	  EnterCriticalSection(&ptw32_once_event_lock); +	  if (1 == InterlockedIncrement((LPLONG)&once_control->eventUsers)) +	    { +	      /* +	       * RE CANCELLATION: +	       * If we are the first thread after the initter thread, and the init_routine is cancelled +	       * while we're suspended at this point in the code:- +	       * - state will not get set to PTW32_ONCE_DONE; +	       * - cleanup will not see an event and cannot set it; +	       * - therefore, we will eventually resume, create an event and wait on it; +	       * cleanup will set state == CANCELLED before checking for an event, so that +	       * we will see it and avoid waiting (as for state == DONE). We will go around again and +	       * we may then become the initter. +	       * If we are still the only other thread when we get to the end of this block, we will +	       * have closed the event (good). If another thread beats us to be initter, then we will +	       * re-enter here (good). In case the old event is reused, the event is always reset by +	       * the new initter before clearing the CANCELLED state, causing any threads that are +	       * cycling around the loop to wait again. +	       * The initter thread is guaranteed to be at equal or higher priority than any waiters +	       * so no waiters will starve the initter, which might otherwise cause us to loop +	       * forever. +	       */ +	      tmpEvent = CreateEvent(NULL, PTW32_TRUE, PTW32_FALSE, NULL); +	      if (PTW32_INTERLOCKED_COMPARE_EXCHANGE((PTW32_INTERLOCKED_LPLONG)&once_control->event, +						     (PTW32_INTERLOCKED_LONG)tmpEvent, +						     (PTW32_INTERLOCKED_LONG)0)) +		{ +		  CloseHandle(tmpEvent); +		} +	    } +//	  LeaveCriticalSection(&ptw32_once_event_lock); + +	  /* +	   * Check 'state' again in case the initting thread has finished or cancelled +	   * and left before seeing that there was an event to trigger. +	   */ + +	  switch (InterlockedExchangeAdd((LPLONG)&once_control->state, 0L)) +	    { +	    case PTW32_ONCE_CLEAR: +	      { +		/* Neither DONE nor CANCELLED */ +		if (WAIT_FAILED == WaitForSingleObject(once_control->event, INFINITE)) +		  { +		    restoreLastError = PTW32_TRUE; +		    /* +		     * If the wait failed it's probably because the event is invalid. +		     * That's possible after a cancellation (but rare) if we got through the +		     * event create block above while a woken thread was suspended between +		     * the decrement and exchange below and then resumed before we could wait. +		     * So we'll yield. +		     */ +		    Sleep(0); +		  } +		break; +	      } +	    case PTW32_ONCE_CANCELLED: +	      { +		if (once_control->started) +		  { +		    /* The new initter hasn't cleared the cancellation yet, so give the +		     * processor to a more productive thread. */ +		    Sleep(0); +		  } +		break; +	      } +	    } + +	  /* last one out shut off the lights */ +//	  EnterCriticalSection(&ptw32_once_event_lock); +	  if (0 == InterlockedDecrement((LPLONG)&once_control->eventUsers)) +	    { +	      /* we were last */ +	      if ((tmpEvent = (HANDLE) +		   PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->event, +					      (LONG)0))) +		{ +		  CloseHandle(tmpEvent); +		} +	    } +//	  LeaveCriticalSection(&ptw32_once_event_lock); +	} +    } + +  if (restoreLastError) +    { +      SetLastError (lasterror); +      WSASetLastError (lastWSAerror); +    } + +  /* +   * ------------ +   * Failure Code +   * ------------ +   */ +FAIL0: +  return (result); + +}				/* pthread_once */ diff --git a/ptw32_increase_semaphore.c b/ptw32_increase_semaphore.c index c1ede3f..ecfc1da 100644 --- a/ptw32_increase_semaphore.c +++ b/ptw32_increase_semaphore.c @@ -1,73 +1,73 @@ -/*
 - * -------------------------------------------------------------
 - *
 - * Module: ptw32_increase_semaphore.c
 - *
 - * Purpose:
 - *	Semaphores aren't actually part of the PThreads standard.
 - *	They are defined by the POSIX Standard:
 - *
 - *		POSIX 1003.1b-1993	(POSIX.1b)
 - *
 - * -------------------------------------------------------------
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#include "pthread.h"
 -#include "semaphore.h"
 -#include "implement.h"
 -
 -#ifdef NEED_SEM
 -
 -INLINE BOOL
 -ptw32_increase_semaphore (sem_t * sem, int n)
 -{
 -  BOOL result;
 -  register sem_t s = *sem;
 -
 -  EnterCriticalSection (&s->sem_lock_cs);
 -
 -  if (s->value + n > s->value)
 -    {
 -      s->value += n;
 -      SetEvent (s->event);
 -      result = PTW32_TRUE;
 -    }
 -  else
 -    {
 -      result = PTW32_FALSE;
 -    }
 -
 -  LeaveCriticalSection (&s->sem_lock_cs);
 -  return result;
 -}
 -
 -#endif /* NEED_SEM */
 +/* + * ------------------------------------------------------------- + * + * Module: ptw32_increase_semaphore.c + * + * Purpose: + *	Semaphores aren't actually part of the PThreads standard. + *	They are defined by the POSIX Standard: + * + *		POSIX 1003.1b-1993	(POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + +#ifdef NEED_SEM + +INLINE BOOL +ptw32_increase_semaphore (sem_t * sem, int n) +{ +  BOOL result; +  register sem_t s = *sem; + +  EnterCriticalSection (&s->sem_lock_cs); + +  if (s->value + n > s->value) +    { +      s->value += n; +      SetEvent (s->event); +      result = PTW32_TRUE; +    } +  else +    { +      result = PTW32_FALSE; +    } + +  LeaveCriticalSection (&s->sem_lock_cs); +  return result; +} + +#endif /* NEED_SEM */ diff --git a/ptw32_relmillisecs.c b/ptw32_relmillisecs.c index 2e6bc4d..11ff593 100644 --- a/ptw32_relmillisecs.c +++ b/ptw32_relmillisecs.c @@ -1,120 +1,120 @@ -/*
 - * ptw32_relmillisecs.c
 - *
 - * Description:
 - * This translation unit implements miscellaneous thread functions.
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#ifndef _UWIN
 -//#include <process.h>
 -#endif
 -#include "pthread.h"
 -#include "implement.h"
 -#ifndef NEED_FTIME
 -#include <sys/timeb.h>
 -#endif
 -
 -
 -INLINE DWORD 
 -ptw32_relmillisecs (const struct timespec * abstime)
 -{
 -  const int64_t NANOSEC_PER_MILLISEC = 1000000;
 -  const int64_t MILLISEC_PER_SEC = 1000;
 -  DWORD milliseconds;
 -  int64_t tmpAbsMilliseconds;
 -  int64_t tmpCurrMilliseconds;
 -#ifdef NEED_FTIME
 -  struct timespec currSysTime;
 -  FILETIME ft;
 -  SYSTEMTIME st;
 -#else /* ! NEED_FTIME */
 -  struct _timeb currSysTime;
 -#endif /* NEED_FTIME */
 -
 -
 -  /* 
 -   * Calculate timeout as milliseconds from current system time. 
 -   */
 -
 -  /*
 -   * subtract current system time from abstime in a way that checks
 -   * that abstime is never in the past, or is never equivalent to the
 -   * defined INFINITE value (0xFFFFFFFF).
 -   *
 -   * Assume all integers are unsigned, i.e. cannot test if less than 0.
 -   */
 -  tmpAbsMilliseconds =  (int64_t)abstime->tv_sec * MILLISEC_PER_SEC;
 -  tmpAbsMilliseconds += ((int64_t)abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC;
 -
 -  /* get current system time */
 -
 -#ifdef NEED_FTIME
 -
 -  GetSystemTime(&st);
 -  SystemTimeToFileTime(&st, &ft);
 -  /*
 -   * GetSystemTimeAsFileTime(&ft); would be faster,
 -   * but it does not exist on WinCE
 -   */
 -
 -  ptw32_filetime_to_timespec(&ft, &currSysTime);
 -
 -  tmpCurrMilliseconds = (int64_t)currSysTime.tv_sec * MILLISEC_PER_SEC;
 -  tmpCurrMilliseconds += ((int64_t)currSysTime.tv_nsec + (NANOSEC_PER_MILLISEC/2))
 -			   / NANOSEC_PER_MILLISEC;
 -
 -#else /* ! NEED_FTIME */
 -
 -  _ftime(&currSysTime);
 -
 -  tmpCurrMilliseconds = (int64_t) currSysTime.time * MILLISEC_PER_SEC;
 -  tmpCurrMilliseconds += (int64_t) currSysTime.millitm;
 -
 -#endif /* NEED_FTIME */
 -
 -  if (tmpAbsMilliseconds > tmpCurrMilliseconds)
 -    {
 -      milliseconds = (DWORD) (tmpAbsMilliseconds - tmpCurrMilliseconds);
 -      if (milliseconds == INFINITE)
 -        {
 -          /* Timeouts must be finite */
 -          milliseconds--;
 -        }
 -    }
 -  else
 -    {
 -      /* The abstime given is in the past */
 -      milliseconds = 0;
 -    }
 -
 -  return milliseconds;
 -}
 +/* + * ptw32_relmillisecs.c + * + * Description: + * This translation unit implements miscellaneous thread functions. + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef _UWIN +//#include <process.h> +#endif +#include "pthread.h" +#include "implement.h" +#ifndef NEED_FTIME +#include <sys/timeb.h> +#endif + + +INLINE DWORD  +ptw32_relmillisecs (const struct timespec * abstime) +{ +  const int64_t NANOSEC_PER_MILLISEC = 1000000; +  const int64_t MILLISEC_PER_SEC = 1000; +  DWORD milliseconds; +  int64_t tmpAbsMilliseconds; +  int64_t tmpCurrMilliseconds; +#ifdef NEED_FTIME +  struct timespec currSysTime; +  FILETIME ft; +  SYSTEMTIME st; +#else /* ! NEED_FTIME */ +  struct _timeb currSysTime; +#endif /* NEED_FTIME */ + + +  /*  +   * Calculate timeout as milliseconds from current system time.  +   */ + +  /* +   * subtract current system time from abstime in a way that checks +   * that abstime is never in the past, or is never equivalent to the +   * defined INFINITE value (0xFFFFFFFF). +   * +   * Assume all integers are unsigned, i.e. cannot test if less than 0. +   */ +  tmpAbsMilliseconds =  (int64_t)abstime->tv_sec * MILLISEC_PER_SEC; +  tmpAbsMilliseconds += ((int64_t)abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC; + +  /* get current system time */ + +#ifdef NEED_FTIME + +  GetSystemTime(&st); +  SystemTimeToFileTime(&st, &ft); +  /* +   * GetSystemTimeAsFileTime(&ft); would be faster, +   * but it does not exist on WinCE +   */ + +  ptw32_filetime_to_timespec(&ft, &currSysTime); + +  tmpCurrMilliseconds = (int64_t)currSysTime.tv_sec * MILLISEC_PER_SEC; +  tmpCurrMilliseconds += ((int64_t)currSysTime.tv_nsec + (NANOSEC_PER_MILLISEC/2)) +			   / NANOSEC_PER_MILLISEC; + +#else /* ! NEED_FTIME */ + +  _ftime(&currSysTime); + +  tmpCurrMilliseconds = (int64_t) currSysTime.time * MILLISEC_PER_SEC; +  tmpCurrMilliseconds += (int64_t) currSysTime.millitm; + +#endif /* NEED_FTIME */ + +  if (tmpAbsMilliseconds > tmpCurrMilliseconds) +    { +      milliseconds = (DWORD) (tmpAbsMilliseconds - tmpCurrMilliseconds); +      if (milliseconds == INFINITE) +        { +          /* Timeouts must be finite */ +          milliseconds--; +        } +    } +  else +    { +      /* The abstime given is in the past */ +      milliseconds = 0; +    } + +  return milliseconds; +} diff --git a/ptw32_semwait.c b/ptw32_semwait.c index 209c8a6..8b23d11 100644 --- a/ptw32_semwait.c +++ b/ptw32_semwait.c @@ -1,118 +1,118 @@ -/*
 - * ptw32_semwait.c
 - *
 - * Description:
 - * This translation unit implements mutual exclusion (mutex) primitives.
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#ifndef _UWIN
 -//#   include <process.h>
 -#endif
 -#include "pthread.h"
 -#include "implement.h"
 -
 -
 -int
 -ptw32_semwait (sem_t * sem)
 -     /*
 -      * ------------------------------------------------------
 -      * DESCRIPTION
 -      *      This function waits on a POSIX semaphore. If the
 -      *      semaphore value is greater than zero, it decreases
 -      *      its value by one. If the semaphore value is zero, then
 -      *      the calling thread (or process) is blocked until it can
 -      *      successfully decrease the value.
 -      *
 -      *      Unlike sem_wait(), this routine is non-cancelable.
 -      *
 -      * RESULTS
 -      *              0               successfully decreased semaphore,
 -      *              -1              failed, error in errno.
 -      * ERRNO
 -      *              EINVAL          'sem' is not a valid semaphore,
 -      *              ENOSYS          semaphores are not supported,
 -      *              EINTR           the function was interrupted by a signal,
 -      *              EDEADLK         a deadlock condition was detected.
 -      *
 -      * ------------------------------------------------------
 -      */
 -{
 -  int result = 0;
 -  sem_t s = *sem;
 -
 -  if (s == NULL)
 -    {
 -      result = EINVAL;
 -    }
 -  else
 -    {
 -      if ((result = pthread_mutex_lock (&s->lock)) == 0)
 -        {
 -          int v = --s->value;
 -
 -          (void) pthread_mutex_unlock (&s->lock);
 -
 -          if (v < 0)
 -            {
 -              /* Must wait */
 -              if (WaitForSingleObject (s->sem, INFINITE) == WAIT_OBJECT_0)
 -		{
 -#ifdef NEED_SEM
 -		  if (pthread_mutex_lock (&s->lock) == 0)
 -		    {
 -		      if (s->leftToUnblock > 0)
 -			{
 -			  --s->leftToUnblock;
 -			  SetEvent(s->sem);
 -			}
 -		      (void) pthread_mutex_unlock (&s->lock);
 -		    }
 -#endif
 -		  return 0;
 -		}
 -            }
 -          else
 -	    {
 -	      return 0;
 -	    }
 -        }
 -    }
 -
 -  if (result != 0)
 -    {
 -      errno = result;
 -      return -1;
 -    }
 -
 -  return 0;
 -
 -}				/* ptw32_semwait */
 +/* + * ptw32_semwait.c + * + * Description: + * This translation unit implements mutual exclusion (mutex) primitives. + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef _UWIN +//#   include <process.h> +#endif +#include "pthread.h" +#include "implement.h" + + +int +ptw32_semwait (sem_t * sem) +     /* +      * ------------------------------------------------------ +      * DESCRIPTION +      *      This function waits on a POSIX semaphore. If the +      *      semaphore value is greater than zero, it decreases +      *      its value by one. If the semaphore value is zero, then +      *      the calling thread (or process) is blocked until it can +      *      successfully decrease the value. +      * +      *      Unlike sem_wait(), this routine is non-cancelable. +      * +      * RESULTS +      *              0               successfully decreased semaphore, +      *              -1              failed, error in errno. +      * ERRNO +      *              EINVAL          'sem' is not a valid semaphore, +      *              ENOSYS          semaphores are not supported, +      *              EINTR           the function was interrupted by a signal, +      *              EDEADLK         a deadlock condition was detected. +      * +      * ------------------------------------------------------ +      */ +{ +  int result = 0; +  sem_t s = *sem; + +  if (s == NULL) +    { +      result = EINVAL; +    } +  else +    { +      if ((result = pthread_mutex_lock (&s->lock)) == 0) +        { +          int v = --s->value; + +          (void) pthread_mutex_unlock (&s->lock); + +          if (v < 0) +            { +              /* Must wait */ +              if (WaitForSingleObject (s->sem, INFINITE) == WAIT_OBJECT_0) +		{ +#ifdef NEED_SEM +		  if (pthread_mutex_lock (&s->lock) == 0) +		    { +		      if (s->leftToUnblock > 0) +			{ +			  --s->leftToUnblock; +			  SetEvent(s->sem); +			} +		      (void) pthread_mutex_unlock (&s->lock); +		    } +#endif +		  return 0; +		} +            } +          else +	    { +	      return 0; +	    } +        } +    } + +  if (result != 0) +    { +      errno = result; +      return -1; +    } + +  return 0; + +}				/* ptw32_semwait */ diff --git a/sem_destroy.c b/sem_destroy.c index c260d41..96734d1 100644 --- a/sem_destroy.c +++ b/sem_destroy.c @@ -1,146 +1,146 @@ -/*
 - * -------------------------------------------------------------
 - *
 - * Module: sem_destroy.c
 - *
 - * Purpose:
 - *	Semaphores aren't actually part of the PThreads standard.
 - *	They are defined by the POSIX Standard:
 - *
 - *		POSIX 1003.1b-1993	(POSIX.1b)
 - *
 - * -------------------------------------------------------------
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#include "pthread.h"
 -#include "semaphore.h"
 -#include "implement.h"
 -
 -
 -int
 -sem_destroy (sem_t * sem)
 -     /*
 -      * ------------------------------------------------------
 -      * DOCPUBLIC
 -      *      This function destroys an unnamed semaphore.
 -      *
 -      * PARAMETERS
 -      *      sem
 -      *              pointer to an instance of sem_t
 -      *
 -      * DESCRIPTION
 -      *      This function destroys an unnamed semaphore.
 -      *
 -      * RESULTS
 -      *              0               successfully destroyed semaphore,
 -      *              -1              failed, error in errno
 -      * ERRNO
 -      *              EINVAL          'sem' is not a valid semaphore,
 -      *              ENOSYS          semaphores are not supported,
 -      *              EBUSY           threads (or processes) are currently
 -      *                                      blocked on 'sem'
 -      *
 -      * ------------------------------------------------------
 -      */
 -{
 -  int result = 0;
 -  sem_t s = NULL;
 -
 -  if (sem == NULL || *sem == NULL)
 -    {
 -      result = EINVAL;
 -    }
 -  else
 -    {
 -      s = *sem;
 -      *sem = NULL;
 -
 -      if ((result = pthread_mutex_trylock (&s->lock)) == 0)
 -        {
 -          if (s->value >= 0)
 -            {
 -              (void) pthread_mutex_unlock (&s->lock);
 -
 -              if (!CloseHandle (s->sem))
 -	        {
 -	          *sem = s;
 -	          result = EINVAL;
 -	        }
 -              else if ((result = pthread_mutex_destroy (&s->lock)) != 0)
 -                {
 -
 -#ifdef NEED_SEM
 -		  s->sem = CreateEvent (NULL,
 -					PTW32_FALSE,    /* manual reset is false */
 -					PTW32_FALSE,    /* initial state is unset */
 -					NULL);
 -#else
 -                  s->sem = CreateSemaphore (NULL,      /* Always NULL */
 -                                            (long) 0,  /* Force threads to wait */
 -                                            (long) _POSIX_SEM_VALUE_MAX,       /* Maximum value */
 -                                            NULL);     /* Name */
 -#endif
 -
 -                  if (s->sem == 0)
 -                    {
 -                      /* We just have to pretend that we've destroyed the semaphore
 -                       * even though we're leaving a mutex around.
 -                       */
 -                      result = 0;
 -                    }
 -                  else
 -                    {
 -                      *sem = s;
 -                      if (result != EBUSY)
 -                        result = EINVAL;
 -                    }
 -                }
 -            }
 -          else
 -            {
 -              (void) pthread_mutex_unlock (&s->lock);
 -              result = EBUSY;
 -            }
 -        }
 -    }
 -
 -  if (result != 0)
 -    {
 -      errno = result;
 -      return -1;
 -    }
 -
 -  free (s);
 -
 -  return 0;
 -
 -}				/* sem_destroy */
 +/* + * ------------------------------------------------------------- + * + * Module: sem_destroy.c + * + * Purpose: + *	Semaphores aren't actually part of the PThreads standard. + *	They are defined by the POSIX Standard: + * + *		POSIX 1003.1b-1993	(POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_destroy (sem_t * sem) +     /* +      * ------------------------------------------------------ +      * DOCPUBLIC +      *      This function destroys an unnamed semaphore. +      * +      * PARAMETERS +      *      sem +      *              pointer to an instance of sem_t +      * +      * DESCRIPTION +      *      This function destroys an unnamed semaphore. +      * +      * RESULTS +      *              0               successfully destroyed semaphore, +      *              -1              failed, error in errno +      * ERRNO +      *              EINVAL          'sem' is not a valid semaphore, +      *              ENOSYS          semaphores are not supported, +      *              EBUSY           threads (or processes) are currently +      *                                      blocked on 'sem' +      * +      * ------------------------------------------------------ +      */ +{ +  int result = 0; +  sem_t s = NULL; + +  if (sem == NULL || *sem == NULL) +    { +      result = EINVAL; +    } +  else +    { +      s = *sem; +      *sem = NULL; + +      if ((result = pthread_mutex_trylock (&s->lock)) == 0) +        { +          if (s->value >= 0) +            { +              (void) pthread_mutex_unlock (&s->lock); + +              if (!CloseHandle (s->sem)) +	        { +	          *sem = s; +	          result = EINVAL; +	        } +              else if ((result = pthread_mutex_destroy (&s->lock)) != 0) +                { + +#ifdef NEED_SEM +		  s->sem = CreateEvent (NULL, +					PTW32_FALSE,    /* manual reset is false */ +					PTW32_FALSE,    /* initial state is unset */ +					NULL); +#else +                  s->sem = CreateSemaphore (NULL,      /* Always NULL */ +                                            (long) 0,  /* Force threads to wait */ +                                            (long) _POSIX_SEM_VALUE_MAX,       /* Maximum value */ +                                            NULL);     /* Name */ +#endif + +                  if (s->sem == 0) +                    { +                      /* We just have to pretend that we've destroyed the semaphore +                       * even though we're leaving a mutex around. +                       */ +                      result = 0; +                    } +                  else +                    { +                      *sem = s; +                      if (result != EBUSY) +                        result = EINVAL; +                    } +                } +            } +          else +            { +              (void) pthread_mutex_unlock (&s->lock); +              result = EBUSY; +            } +        } +    } + +  if (result != 0) +    { +      errno = result; +      return -1; +    } + +  free (s); + +  return 0; + +}				/* sem_destroy */ diff --git a/sem_getvalue.c b/sem_getvalue.c index f1a7e4b..ae13ef9 100644 --- a/sem_getvalue.c +++ b/sem_getvalue.c @@ -1,101 +1,101 @@ -/*
 - * -------------------------------------------------------------
 - *
 - * Module: sem_getvalue.c
 - *
 - * Purpose:
 - *	Semaphores aren't actually part of PThreads.
 - *	They are defined by the POSIX Standard:
 - *
 - *		POSIX 1003.1-2001
 - *
 - * -------------------------------------------------------------
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#include "pthread.h"
 -#include "semaphore.h"
 -#include "implement.h"
 -
 -
 -int
 -sem_getvalue (sem_t * sem, int *sval)
 -     /*
 -      * ------------------------------------------------------
 -      * DOCPUBLIC
 -      *      This function stores the current count value of the
 -      *      semaphore.
 -      * RESULTS
 -      *
 -      * Return value
 -      *
 -      *       0                  sval has been set.
 -      *      -1                  failed, error in errno
 -      *
 -      *  in global errno
 -      *
 -      *      EINVAL              'sem' is not a valid semaphore,
 -      *      ENOSYS              this function is not supported,
 -      *
 -      *
 -      * PARAMETERS
 -      *
 -      *      sem                 pointer to an instance of sem_t
 -      *
 -      *      sval                pointer to int.
 -      *
 -      * DESCRIPTION
 -      *      This function stores the current count value of the semaphore
 -      *      pointed to by sem in the int pointed to by sval.
 -      */
 -{
 -  if (sem == NULL || *sem == NULL || sval == NULL)
 -    {
 -      errno = EINVAL;
 -      return -1;
 -    }
 -  else
 -    {
 -      long value;
 -      register sem_t s = *sem;
 -      int result = 0;
 -
 -      if ((result = pthread_mutex_lock(&s->lock)) == 0)
 -        {
 -          value = s->value;
 -          (void) pthread_mutex_unlock(&s->lock);
 -          *sval = value;
 -        }
 -
 -      return result;
 -    }
 -
 -}				/* sem_getvalue */
 +/* + * ------------------------------------------------------------- + * + * Module: sem_getvalue.c + * + * Purpose: + *	Semaphores aren't actually part of PThreads. + *	They are defined by the POSIX Standard: + * + *		POSIX 1003.1-2001 + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_getvalue (sem_t * sem, int *sval) +     /* +      * ------------------------------------------------------ +      * DOCPUBLIC +      *      This function stores the current count value of the +      *      semaphore. +      * RESULTS +      * +      * Return value +      * +      *       0                  sval has been set. +      *      -1                  failed, error in errno +      * +      *  in global errno +      * +      *      EINVAL              'sem' is not a valid semaphore, +      *      ENOSYS              this function is not supported, +      * +      * +      * PARAMETERS +      * +      *      sem                 pointer to an instance of sem_t +      * +      *      sval                pointer to int. +      * +      * DESCRIPTION +      *      This function stores the current count value of the semaphore +      *      pointed to by sem in the int pointed to by sval. +      */ +{ +  if (sem == NULL || *sem == NULL || sval == NULL) +    { +      errno = EINVAL; +      return -1; +    } +  else +    { +      long value; +      register sem_t s = *sem; +      int result = 0; + +      if ((result = pthread_mutex_lock(&s->lock)) == 0) +        { +          value = s->value; +          (void) pthread_mutex_unlock(&s->lock); +          *sval = value; +        } + +      return result; +    } + +}				/* sem_getvalue */ @@ -1,164 +1,164 @@ -/*
 - * -------------------------------------------------------------
 - *
 - * Module: sem_init.c
 - *
 - * Purpose:
 - *	Semaphores aren't actually part of PThreads.
 - *	They are defined by the POSIX Standard:
 - *
 - *		POSIX 1003.1-2001
 - *
 - * -------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#include "pthread.h"
 -#include "semaphore.h"
 -#include "implement.h"
 -
 -int
 -sem_init (sem_t * sem, int pshared, unsigned int value)
 -     /*
 -      * ------------------------------------------------------
 -      * DOCPUBLIC
 -      *      This function initializes a semaphore. The
 -      *      initial value of the semaphore is 'value'
 -      *
 -      * PARAMETERS
 -      *      sem
 -      *              pointer to an instance of sem_t
 -      *
 -      *      pshared
 -      *              if zero, this semaphore may only be shared between
 -      *              threads in the same process.
 -      *              if nonzero, the semaphore can be shared between
 -      *              processes
 -      *
 -      *      value
 -      *              initial value of the semaphore counter
 -      *
 -      * DESCRIPTION
 -      *      This function initializes a semaphore. The
 -      *      initial value of the semaphore is set to 'value'.
 -      *
 -      * RESULTS
 -      *              0               successfully created semaphore,
 -      *              -1              failed, error in errno
 -      * ERRNO
 -      *              EINVAL          'sem' is not a valid semaphore,
 -      *              ENOMEM          out of memory,
 -      *              ENOSPC          a required resource has been exhausted,
 -      *              ENOSYS          semaphores are not supported,
 -      *              EPERM           the process lacks appropriate privilege
 -      *
 -      * ------------------------------------------------------
 -      */
 -{
 -  int result = 0;
 -  sem_t s = NULL;
 -
 -  if (pshared != 0)
 -    {
 -      /*
 -       * Creating a semaphore that can be shared between
 -       * processes
 -       */
 -      result = EPERM;
 -    }
 -  else
 -    {
 -      s = (sem_t) calloc (1, sizeof (*s));
 -
 -      if (NULL == s)
 -	{
 -	  result = ENOMEM;
 -	}
 -      else
 -	{
 -
 -	  s->value = value;
 -	  if (pthread_mutex_init(&s->lock, NULL) == 0)
 -	    {
 -
 -#ifdef NEED_SEM
 -
 -	  s->sem = CreateEvent (NULL,
 -				PTW32_FALSE,	/* auto (not manual) reset */
 -				PTW32_FALSE,	/* initial state is unset */
 -				NULL);
 -
 -	  if (0 == s->sem)
 -	    {
 -	      free (s);
 -	      (void) pthread_mutex_destroy(&s->lock);
 -	      result = ENOSPC;
 -	    }
 -	  else
 -	    {
 -	      s->leftToUnblock = 0;
 -	    }
 -
 -#else /* NEED_SEM */
 -
 -	      if ((s->sem = CreateSemaphore (NULL,	/* Always NULL */
 -					     (long) 0,	/* Force threads to wait */
 -					     (long) _POSIX_SEM_VALUE_MAX,	/* Maximum value */
 -					     NULL)) == 0)	/* Name */
 -		{
 -		  (void) pthread_mutex_destroy(&s->lock);
 -		  result = ENOSPC;
 -		}
 -
 -#endif /* NEED_SEM */
 -
 -	    }
 -	  else
 -	    {
 -	      result = ENOSPC;
 -	    }
 -
 -	  if (result != 0)
 -	    {
 -	      free(s);
 -	    }
 -	}
 -    }
 -
 -  if (result != 0)
 -    {
 -      errno = result;
 -      return -1;
 -    }
 -
 -  *sem = s;
 -
 -  return 0;
 -
 -}				/* sem_init */
 +/* + * ------------------------------------------------------------- + * + * Module: sem_init.c + * + * Purpose: + *	Semaphores aren't actually part of PThreads. + *	They are defined by the POSIX Standard: + * + *		POSIX 1003.1-2001 + * + * ------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + +int +sem_init (sem_t * sem, int pshared, unsigned int value) +     /* +      * ------------------------------------------------------ +      * DOCPUBLIC +      *      This function initializes a semaphore. The +      *      initial value of the semaphore is 'value' +      * +      * PARAMETERS +      *      sem +      *              pointer to an instance of sem_t +      * +      *      pshared +      *              if zero, this semaphore may only be shared between +      *              threads in the same process. +      *              if nonzero, the semaphore can be shared between +      *              processes +      * +      *      value +      *              initial value of the semaphore counter +      * +      * DESCRIPTION +      *      This function initializes a semaphore. The +      *      initial value of the semaphore is set to 'value'. +      * +      * RESULTS +      *              0               successfully created semaphore, +      *              -1              failed, error in errno +      * ERRNO +      *              EINVAL          'sem' is not a valid semaphore, +      *              ENOMEM          out of memory, +      *              ENOSPC          a required resource has been exhausted, +      *              ENOSYS          semaphores are not supported, +      *              EPERM           the process lacks appropriate privilege +      * +      * ------------------------------------------------------ +      */ +{ +  int result = 0; +  sem_t s = NULL; + +  if (pshared != 0) +    { +      /* +       * Creating a semaphore that can be shared between +       * processes +       */ +      result = EPERM; +    } +  else +    { +      s = (sem_t) calloc (1, sizeof (*s)); + +      if (NULL == s) +	{ +	  result = ENOMEM; +	} +      else +	{ + +	  s->value = value; +	  if (pthread_mutex_init(&s->lock, NULL) == 0) +	    { + +#ifdef NEED_SEM + +	  s->sem = CreateEvent (NULL, +				PTW32_FALSE,	/* auto (not manual) reset */ +				PTW32_FALSE,	/* initial state is unset */ +				NULL); + +	  if (0 == s->sem) +	    { +	      free (s); +	      (void) pthread_mutex_destroy(&s->lock); +	      result = ENOSPC; +	    } +	  else +	    { +	      s->leftToUnblock = 0; +	    } + +#else /* NEED_SEM */ + +	      if ((s->sem = CreateSemaphore (NULL,	/* Always NULL */ +					     (long) 0,	/* Force threads to wait */ +					     (long) _POSIX_SEM_VALUE_MAX,	/* Maximum value */ +					     NULL)) == 0)	/* Name */ +		{ +		  (void) pthread_mutex_destroy(&s->lock); +		  result = ENOSPC; +		} + +#endif /* NEED_SEM */ + +	    } +	  else +	    { +	      result = ENOSPC; +	    } + +	  if (result != 0) +	    { +	      free(s); +	    } +	} +    } + +  if (result != 0) +    { +      errno = result; +      return -1; +    } + +  *sem = s; + +  return 0; + +}				/* sem_init */ @@ -1,112 +1,112 @@ -/*
 - * -------------------------------------------------------------
 - *
 - * Module: sem_post.c
 - *
 - * Purpose:
 - *	Semaphores aren't actually part of the PThreads standard.
 - *	They are defined by the POSIX Standard:
 - *
 - *		POSIX 1003.1b-1993	(POSIX.1b)
 - *
 - * -------------------------------------------------------------
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#include "pthread.h"
 -#include "semaphore.h"
 -#include "implement.h"
 -
 -
 -int
 -sem_post (sem_t * sem)
 -     /*
 -      * ------------------------------------------------------
 -      * DOCPUBLIC
 -      *      This function posts a wakeup to a semaphore.
 -      *
 -      * PARAMETERS
 -      *      sem
 -      *              pointer to an instance of sem_t
 -      *
 -      * DESCRIPTION
 -      *      This function posts a wakeup to a semaphore. If there
 -      *      are waiting threads (or processes), one is awakened;
 -      *      otherwise, the semaphore value is incremented by one.
 -      *
 -      * RESULTS
 -      *              0               successfully posted semaphore,
 -      *              -1              failed, error in errno
 -      * ERRNO
 -      *              EINVAL          'sem' is not a valid semaphore,
 -      *              ENOSYS          semaphores are not supported,
 -      *
 -      * ------------------------------------------------------
 -      */
 -{
 -  int result = 0;
 -  sem_t s = *sem;
 -
 -  if (s == NULL)
 -    {
 -      result = EINVAL;
 -    }
 -  else if ((result = pthread_mutex_lock (&s->lock)) == 0)
 -    {
 -#ifdef NEED_SEM
 -
 -      if (++s->value <= 0)
 -	{
 -	  if (!SetEvent(s->sem))
 -	    {
 -	      result = EINVAL;
 -	    }
 -	}
 -#else
 -      if (++s->value <= 0
 -	  && !ReleaseSemaphore (s->sem, 1, NULL))
 -	{
 -	  result = EINVAL;
 -	}
 -#endif /* NEED_SEM */
 -      
 -      (void) pthread_mutex_unlock (&s->lock);
 -    }
 -
 -  if (result != 0)
 -    {
 -      errno = result;
 -      return -1;
 -    }
 -
 -  return 0;
 -
 -}				/* sem_post */
 +/* + * ------------------------------------------------------------- + * + * Module: sem_post.c + * + * Purpose: + *	Semaphores aren't actually part of the PThreads standard. + *	They are defined by the POSIX Standard: + * + *		POSIX 1003.1b-1993	(POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_post (sem_t * sem) +     /* +      * ------------------------------------------------------ +      * DOCPUBLIC +      *      This function posts a wakeup to a semaphore. +      * +      * PARAMETERS +      *      sem +      *              pointer to an instance of sem_t +      * +      * DESCRIPTION +      *      This function posts a wakeup to a semaphore. If there +      *      are waiting threads (or processes), one is awakened; +      *      otherwise, the semaphore value is incremented by one. +      * +      * RESULTS +      *              0               successfully posted semaphore, +      *              -1              failed, error in errno +      * ERRNO +      *              EINVAL          'sem' is not a valid semaphore, +      *              ENOSYS          semaphores are not supported, +      * +      * ------------------------------------------------------ +      */ +{ +  int result = 0; +  sem_t s = *sem; + +  if (s == NULL) +    { +      result = EINVAL; +    } +  else if ((result = pthread_mutex_lock (&s->lock)) == 0) +    { +#ifdef NEED_SEM + +      if (++s->value <= 0) +	{ +	  if (!SetEvent(s->sem)) +	    { +	      result = EINVAL; +	    } +	} +#else +      if (++s->value <= 0 +	  && !ReleaseSemaphore (s->sem, 1, NULL)) +	{ +	  result = EINVAL; +	} +#endif /* NEED_SEM */ +       +      (void) pthread_mutex_unlock (&s->lock); +    } + +  if (result != 0) +    { +      errno = result; +      return -1; +    } + +  return 0; + +}				/* sem_post */ diff --git a/sem_post_multiple.c b/sem_post_multiple.c index 6c582e2..9dab861 100644 --- a/sem_post_multiple.c +++ b/sem_post_multiple.c @@ -1,121 +1,121 @@ -/*
 - * -------------------------------------------------------------
 - *
 - * Module: sem_post_multiple.c
 - *
 - * Purpose:
 - *	Semaphores aren't actually part of the PThreads standard.
 - *	They are defined by the POSIX Standard:
 - *
 - *		POSIX 1003.1b-1993	(POSIX.1b)
 - *
 - * -------------------------------------------------------------
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#include "pthread.h"
 -#include "semaphore.h"
 -#include "implement.h"
 -
 -
 -int
 -sem_post_multiple (sem_t * sem, int count)
 -     /*
 -      * ------------------------------------------------------
 -      * DOCPUBLIC
 -      *      This function posts multiple wakeups to a semaphore.
 -      *
 -      * PARAMETERS
 -      *      sem
 -      *              pointer to an instance of sem_t
 -      *
 -      *      count
 -      *              counter, must be greater than zero.
 -      *
 -      * DESCRIPTION
 -      *      This function posts multiple wakeups to a semaphore. If there
 -      *      are waiting threads (or processes), n <= count are awakened;
 -      *      the semaphore value is incremented by count - n.
 -      *
 -      * RESULTS
 -      *              0               successfully posted semaphore,
 -      *              -1              failed, error in errno
 -      * ERRNO
 -      *              EINVAL          'sem' is not a valid semaphore
 -      *                              or count is less than or equal to zero.
 -      *
 -      * ------------------------------------------------------
 -      */
 -{
 -  int result = 0;
 -  long waiters;
 -  sem_t s = *sem;
 -
 -  if (s == NULL || count <= 0)
 -    {
 -      result = EINVAL;
 -    }
 -  else if ((result = pthread_mutex_lock (&s->lock)) == 0)
 -    {
 -      waiters = -s->value;
 -      s->value += count;
 -      if (waiters > 0)
 -        {
 -#ifdef NEED_SEM
 -	  if (SetEvent(s->sem))
 -	    {
 -	      waiters--;
 -	      s->leftToUnblock += count - 1;
 -	      if (s->leftToUnblock > waiters)
 -		{
 -		  s->leftToUnblock = waiters;
 -		}
 -	    }
 -	  else
 -#else
 -          if (!ReleaseSemaphore (s->sem,  (waiters<=count)?waiters:count, 0))
 -#endif
 -            {
 -              result = EINVAL;
 -            }
 -        }
 -      (void) pthread_mutex_unlock (&s->lock);
 -    }
 -
 -  if (result != 0)
 -    {
 -      errno = result;
 -      return -1;
 -    }
 -
 -  return 0;
 -
 -}				/* sem_post_multiple */
 +/* + * ------------------------------------------------------------- + * + * Module: sem_post_multiple.c + * + * Purpose: + *	Semaphores aren't actually part of the PThreads standard. + *	They are defined by the POSIX Standard: + * + *		POSIX 1003.1b-1993	(POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_post_multiple (sem_t * sem, int count) +     /* +      * ------------------------------------------------------ +      * DOCPUBLIC +      *      This function posts multiple wakeups to a semaphore. +      * +      * PARAMETERS +      *      sem +      *              pointer to an instance of sem_t +      * +      *      count +      *              counter, must be greater than zero. +      * +      * DESCRIPTION +      *      This function posts multiple wakeups to a semaphore. If there +      *      are waiting threads (or processes), n <= count are awakened; +      *      the semaphore value is incremented by count - n. +      * +      * RESULTS +      *              0               successfully posted semaphore, +      *              -1              failed, error in errno +      * ERRNO +      *              EINVAL          'sem' is not a valid semaphore +      *                              or count is less than or equal to zero. +      * +      * ------------------------------------------------------ +      */ +{ +  int result = 0; +  long waiters; +  sem_t s = *sem; + +  if (s == NULL || count <= 0) +    { +      result = EINVAL; +    } +  else if ((result = pthread_mutex_lock (&s->lock)) == 0) +    { +      waiters = -s->value; +      s->value += count; +      if (waiters > 0) +        { +#ifdef NEED_SEM +	  if (SetEvent(s->sem)) +	    { +	      waiters--; +	      s->leftToUnblock += count - 1; +	      if (s->leftToUnblock > waiters) +		{ +		  s->leftToUnblock = waiters; +		} +	    } +	  else +#else +          if (!ReleaseSemaphore (s->sem,  (waiters<=count)?waiters:count, 0)) +#endif +            { +              result = EINVAL; +            } +        } +      (void) pthread_mutex_unlock (&s->lock); +    } + +  if (result != 0) +    { +      errno = result; +      return -1; +    } + +  return 0; + +}				/* sem_post_multiple */ diff --git a/sem_timedwait.c b/sem_timedwait.c index 01bab42..186c123 100644 --- a/sem_timedwait.c +++ b/sem_timedwait.c @@ -1,220 +1,220 @@ -/*
 - * -------------------------------------------------------------
 - *
 - * Module: sem_timedwait.c
 - *
 - * Purpose:
 - *	Semaphores aren't actually part of the PThreads standard.
 - *	They are defined by the POSIX Standard:
 - *
 - *		POSIX 1003.1b-1993	(POSIX.1b)
 - *
 - * -------------------------------------------------------------
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#include "pthread.h"
 -#include "semaphore.h"
 -#include "implement.h"
 -
 -
 -typedef struct {
 -  sem_t sem;
 -  int * resultPtr;
 -} sem_timedwait_cleanup_args_t;
 -
 -
 -static void PTW32_CDECL
 -ptw32_sem_timedwait_cleanup (void * args)
 -{
 -  sem_timedwait_cleanup_args_t * a = (sem_timedwait_cleanup_args_t *)args;
 -  sem_t s = a->sem;
 -
 -  if (pthread_mutex_lock (&s->lock) == 0)
 -    {
 -      /*
 -       * We either timed out or were cancelled.
 -       * If someone posted since then we try to take the semaphore.
 -       * Otherwise the semaphore count may be wrong after we
 -       * return. In the case of a cancellation, it is as if we
 -       * were cancelled just before we return (after taking the semaphore)
 -       * which is ok.
 -       */
 -      if (WaitForSingleObject(s->sem, 0) == WAIT_OBJECT_0)
 -	{
 -	  /* We got the semaphore on the second attempt */
 -	  *(a->resultPtr) = 0;
 -	}
 -      else
 -	{
 -	  /* Indicate we're no longer waiting */
 -	  s->value++;
 -#ifdef NEED_SEM
 -	  if (s->value > 0)
 -	    {
 -	      s->leftToUnblock = 0;
 -	    }
 -#else
 -          /*
 -           * Don't release the W32 sema, it doesn't need adjustment
 -           * because it doesn't record the number of waiters.
 -           */
 -#endif
 -	}
 -      (void) pthread_mutex_unlock (&s->lock);
 -    }
 -}
 -
 -
 -int
 -sem_timedwait (sem_t * sem, const struct timespec *abstime)
 -     /*
 -      * ------------------------------------------------------
 -      * DOCPUBLIC
 -      *      This function waits on a semaphore possibly until
 -      *      'abstime' time.
 -      *
 -      * PARAMETERS
 -      *      sem
 -      *              pointer to an instance of sem_t
 -      *
 -      *      abstime
 -      *              pointer to an instance of struct timespec
 -      *
 -      * DESCRIPTION
 -      *      This function waits on a semaphore. If the
 -      *      semaphore value is greater than zero, it decreases
 -      *      its value by one. If the semaphore value is zero, then
 -      *      the calling thread (or process) is blocked until it can
 -      *      successfully decrease the value or until interrupted by
 -      *      a signal.
 -      *
 -      *      If 'abstime' is a NULL pointer then this function will
 -      *      block until it can successfully decrease the value or
 -      *      until interrupted by a signal.
 -      *
 -      * RESULTS
 -      *              0               successfully decreased semaphore,
 -      *              -1              failed, error in errno
 -      * ERRNO
 -      *              EINVAL          'sem' is not a valid semaphore,
 -      *              ENOSYS          semaphores are not supported,
 -      *              EINTR           the function was interrupted by a signal,
 -      *              EDEADLK         a deadlock condition was detected.
 -      *              ETIMEDOUT       abstime elapsed before success.
 -      *
 -      * ------------------------------------------------------
 -      */
 -{
 -  int result = 0;
 -  sem_t s = *sem;
 -
 -  if (sem == NULL)
 -    {
 -      result = EINVAL;
 -    }
 -  else
 -    {
 -      DWORD milliseconds;
 -
 -      if (abstime == NULL)
 -	{
 -	  milliseconds = INFINITE;
 -	}
 -      else
 -	{
 -	  /* 
 -	   * Calculate timeout as milliseconds from current system time. 
 -	   */
 -	  milliseconds = ptw32_relmillisecs (abstime);
 -	}
 -
 -      pthread_testcancel();
 -
 -      if ((result = pthread_mutex_lock (&s->lock)) == 0)
 -	{
 -	  int v = --s->value;
 -	  (void) pthread_mutex_unlock (&s->lock);
 -
 -	  if (v < 0)
 -	    {
 -#ifdef NEED_SEM
 -	      int timedout;
 -#endif
 -	      sem_timedwait_cleanup_args_t cleanup_args;
 -
 -	      cleanup_args.sem = s;
 -	      cleanup_args.resultPtr = &result;
 -
 -#ifdef _MSC_VER
 -#pragma inline_depth(0)
 -#endif
 -	      /* Must wait */
 -              pthread_cleanup_push(ptw32_sem_timedwait_cleanup, (void *) &cleanup_args);
 -#ifdef NEED_SEM
 -	      timedout =
 -#endif
 -	      result = pthreadCancelableTimedWait (s->sem, milliseconds);
 -	      pthread_cleanup_pop(result);
 -#ifdef _MSC_VER
 -#pragma inline_depth()
 -#endif
 -
 -#ifdef NEED_SEM
 -
 -	      if (!timedout && pthread_mutex_lock (&s->lock) == 0)
 -	        {
 -	          if (s->leftToUnblock > 0)
 -	            {
 -		      --s->leftToUnblock;
 -		      SetEvent(s->sem);
 -		    }
 -	          (void) pthread_mutex_unlock (&s->lock);
 -	        }
 -
 -#endif /* NEED_SEM */
 -
 -	    }
 -	}
 -
 -    }
 -
 -  if (result != 0)
 -    {
 -
 -      errno = result;
 -      return -1;
 -
 -    }
 -
 -  return 0;
 -
 -}				/* sem_timedwait */
 +/* + * ------------------------------------------------------------- + * + * Module: sem_timedwait.c + * + * Purpose: + *	Semaphores aren't actually part of the PThreads standard. + *	They are defined by the POSIX Standard: + * + *		POSIX 1003.1b-1993	(POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +typedef struct { +  sem_t sem; +  int * resultPtr; +} sem_timedwait_cleanup_args_t; + + +static void PTW32_CDECL +ptw32_sem_timedwait_cleanup (void * args) +{ +  sem_timedwait_cleanup_args_t * a = (sem_timedwait_cleanup_args_t *)args; +  sem_t s = a->sem; + +  if (pthread_mutex_lock (&s->lock) == 0) +    { +      /* +       * We either timed out or were cancelled. +       * If someone posted since then we try to take the semaphore. +       * Otherwise the semaphore count may be wrong after we +       * return. In the case of a cancellation, it is as if we +       * were cancelled just before we return (after taking the semaphore) +       * which is ok. +       */ +      if (WaitForSingleObject(s->sem, 0) == WAIT_OBJECT_0) +	{ +	  /* We got the semaphore on the second attempt */ +	  *(a->resultPtr) = 0; +	} +      else +	{ +	  /* Indicate we're no longer waiting */ +	  s->value++; +#ifdef NEED_SEM +	  if (s->value > 0) +	    { +	      s->leftToUnblock = 0; +	    } +#else +          /* +           * Don't release the W32 sema, it doesn't need adjustment +           * because it doesn't record the number of waiters. +           */ +#endif +	} +      (void) pthread_mutex_unlock (&s->lock); +    } +} + + +int +sem_timedwait (sem_t * sem, const struct timespec *abstime) +     /* +      * ------------------------------------------------------ +      * DOCPUBLIC +      *      This function waits on a semaphore possibly until +      *      'abstime' time. +      * +      * PARAMETERS +      *      sem +      *              pointer to an instance of sem_t +      * +      *      abstime +      *              pointer to an instance of struct timespec +      * +      * DESCRIPTION +      *      This function waits on a semaphore. If the +      *      semaphore value is greater than zero, it decreases +      *      its value by one. If the semaphore value is zero, then +      *      the calling thread (or process) is blocked until it can +      *      successfully decrease the value or until interrupted by +      *      a signal. +      * +      *      If 'abstime' is a NULL pointer then this function will +      *      block until it can successfully decrease the value or +      *      until interrupted by a signal. +      * +      * RESULTS +      *              0               successfully decreased semaphore, +      *              -1              failed, error in errno +      * ERRNO +      *              EINVAL          'sem' is not a valid semaphore, +      *              ENOSYS          semaphores are not supported, +      *              EINTR           the function was interrupted by a signal, +      *              EDEADLK         a deadlock condition was detected. +      *              ETIMEDOUT       abstime elapsed before success. +      * +      * ------------------------------------------------------ +      */ +{ +  int result = 0; +  sem_t s = *sem; + +  if (sem == NULL) +    { +      result = EINVAL; +    } +  else +    { +      DWORD milliseconds; + +      if (abstime == NULL) +	{ +	  milliseconds = INFINITE; +	} +      else +	{ +	  /*  +	   * Calculate timeout as milliseconds from current system time.  +	   */ +	  milliseconds = ptw32_relmillisecs (abstime); +	} + +      pthread_testcancel(); + +      if ((result = pthread_mutex_lock (&s->lock)) == 0) +	{ +	  int v = --s->value; +	  (void) pthread_mutex_unlock (&s->lock); + +	  if (v < 0) +	    { +#ifdef NEED_SEM +	      int timedout; +#endif +	      sem_timedwait_cleanup_args_t cleanup_args; + +	      cleanup_args.sem = s; +	      cleanup_args.resultPtr = &result; + +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif +	      /* Must wait */ +              pthread_cleanup_push(ptw32_sem_timedwait_cleanup, (void *) &cleanup_args); +#ifdef NEED_SEM +	      timedout = +#endif +	      result = pthreadCancelableTimedWait (s->sem, milliseconds); +	      pthread_cleanup_pop(result); +#ifdef _MSC_VER +#pragma inline_depth() +#endif + +#ifdef NEED_SEM + +	      if (!timedout && pthread_mutex_lock (&s->lock) == 0) +	        { +	          if (s->leftToUnblock > 0) +	            { +		      --s->leftToUnblock; +		      SetEvent(s->sem); +		    } +	          (void) pthread_mutex_unlock (&s->lock); +	        } + +#endif /* NEED_SEM */ + +	    } +	} + +    } + +  if (result != 0) +    { + +      errno = result; +      return -1; + +    } + +  return 0; + +}				/* sem_timedwait */ diff --git a/sem_trywait.c b/sem_trywait.c index 2116222..4d1451d 100644 --- a/sem_trywait.c +++ b/sem_trywait.c @@ -1,108 +1,108 @@ -/*
 - * -------------------------------------------------------------
 - *
 - * Module: sem_trywait.c
 - *
 - * Purpose:
 - *	Semaphores aren't actually part of the PThreads standard.
 - *	They are defined by the POSIX Standard:
 - *
 - *		POSIX 1003.1b-1993	(POSIX.1b)
 - *
 - * -------------------------------------------------------------
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#include "pthread.h"
 -#include "semaphore.h"
 -#include "implement.h"
 -
 -
 -int
 -sem_trywait (sem_t * sem)
 -     /*
 -      * ------------------------------------------------------
 -      * DOCPUBLIC
 -      *      This function tries to wait on a semaphore.
 -      *
 -      * PARAMETERS
 -      *      sem
 -      *              pointer to an instance of sem_t
 -      *
 -      * DESCRIPTION
 -      *      This function tries to wait on a semaphore. If the
 -      *      semaphore value is greater than zero, it decreases
 -      *      its value by one. If the semaphore value is zero, then
 -      *      this function returns immediately with the error EAGAIN
 -      *
 -      * RESULTS
 -      *              0               successfully decreased semaphore,
 -      *              -1              failed, error in errno
 -      * ERRNO
 -      *              EAGAIN          the semaphore was already locked,
 -      *              EINVAL          'sem' is not a valid semaphore,
 -      *              ENOTSUP         sem_trywait is not supported,
 -      *              EINTR           the function was interrupted by a signal,
 -      *              EDEADLK         a deadlock condition was detected.
 -      *
 -      * ------------------------------------------------------
 -      */
 -{
 -  int result = 0;
 -  sem_t s = *sem;
 -
 -  if (s == NULL)
 -    {
 -      result = EINVAL;
 -    }
 -  else if ((result = pthread_mutex_lock (&s->lock)) == 0)
 -    {
 -      if (s->value > 0)
 -	{
 -	  s->value--;
 -	}
 -      else
 -	{
 -	  result = EAGAIN;
 -	}
 -
 -      (void) pthread_mutex_unlock (&s->lock);
 -    }
 -
 -  if (result != 0)
 -    {
 -      errno = result;
 -      return -1;
 -    }
 -
 -  return 0;
 -
 -}				/* sem_trywait */
 +/* + * ------------------------------------------------------------- + * + * Module: sem_trywait.c + * + * Purpose: + *	Semaphores aren't actually part of the PThreads standard. + *	They are defined by the POSIX Standard: + * + *		POSIX 1003.1b-1993	(POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_trywait (sem_t * sem) +     /* +      * ------------------------------------------------------ +      * DOCPUBLIC +      *      This function tries to wait on a semaphore. +      * +      * PARAMETERS +      *      sem +      *              pointer to an instance of sem_t +      * +      * DESCRIPTION +      *      This function tries to wait on a semaphore. If the +      *      semaphore value is greater than zero, it decreases +      *      its value by one. If the semaphore value is zero, then +      *      this function returns immediately with the error EAGAIN +      * +      * RESULTS +      *              0               successfully decreased semaphore, +      *              -1              failed, error in errno +      * ERRNO +      *              EAGAIN          the semaphore was already locked, +      *              EINVAL          'sem' is not a valid semaphore, +      *              ENOTSUP         sem_trywait is not supported, +      *              EINTR           the function was interrupted by a signal, +      *              EDEADLK         a deadlock condition was detected. +      * +      * ------------------------------------------------------ +      */ +{ +  int result = 0; +  sem_t s = *sem; + +  if (s == NULL) +    { +      result = EINVAL; +    } +  else if ((result = pthread_mutex_lock (&s->lock)) == 0) +    { +      if (s->value > 0) +	{ +	  s->value--; +	} +      else +	{ +	  result = EAGAIN; +	} + +      (void) pthread_mutex_unlock (&s->lock); +    } + +  if (result != 0) +    { +      errno = result; +      return -1; +    } + +  return 0; + +}				/* sem_trywait */ @@ -1,162 +1,162 @@ -/*
 - * -------------------------------------------------------------
 - *
 - * Module: sem_wait.c
 - *
 - * Purpose:
 - *	Semaphores aren't actually part of the PThreads standard.
 - *	They are defined by the POSIX Standard:
 - *
 - *		POSIX 1003.1b-1993	(POSIX.1b)
 - *
 - * -------------------------------------------------------------
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#include "pthread.h"
 -#include "semaphore.h"
 -#include "implement.h"
 -
 -
 -static void PTW32_CDECL
 -ptw32_sem_wait_cleanup(void * sem)
 -{
 -  sem_t s = (sem_t) sem;
 -
 -  if (pthread_mutex_lock (&s->lock) == 0)
 -    {
 -      ++s->value;
 -#ifdef NEED_SEM
 -          
 -      if (s->value > 0)
 -	{
 -	  s->leftToUnblock = 0;
 -	}   
 -#else 
 -      /*
 -       * Don't release the W32 sema, it doesn't need adjustment
 -       * because it doesn't record the number of waiters.
 -       */
 -#endif /* NEED_SEM */
 -      (void) pthread_mutex_unlock (&s->lock);
 -    }
 -}
 -
 -int
 -sem_wait (sem_t * sem)
 -     /*
 -      * ------------------------------------------------------
 -      * DOCPUBLIC
 -      *      This function  waits on a semaphore.
 -      *
 -      * PARAMETERS
 -      *      sem
 -      *              pointer to an instance of sem_t
 -      *
 -      * DESCRIPTION
 -      *      This function waits on a semaphore. If the
 -      *      semaphore value is greater than zero, it decreases
 -      *      its value by one. If the semaphore value is zero, then
 -      *      the calling thread (or process) is blocked until it can
 -      *      successfully decrease the value or until interrupted by
 -      *      a signal.
 -      *
 -      * RESULTS
 -      *              0               successfully decreased semaphore,
 -      *              -1              failed, error in errno
 -      * ERRNO
 -      *              EINVAL          'sem' is not a valid semaphore,
 -      *              ENOSYS          semaphores are not supported,
 -      *              EINTR           the function was interrupted by a signal,
 -      *              EDEADLK         a deadlock condition was detected.
 -      *
 -      * ------------------------------------------------------
 -      */
 -{
 -  int result = 0;
 -  sem_t s = *sem;
 -
 -  if (s == NULL)
 -    {
 -      result = EINVAL;
 -    }
 -  else
 -    {
 -
 -      /* Faster to test before adjusting the count */
 -      pthread_testcancel();
 -
 -      if ((result = pthread_mutex_lock (&s->lock)) == 0)
 -	{
 -	  int v = --s->value;
 -
 -	  (void) pthread_mutex_unlock (&s->lock);
 -
 -	  if (v < 0)
 -	    {
 -#ifdef _MSC_VER
 -#pragma inline_depth(0)
 -#endif
 -	      /* Must wait */
 -	      pthread_cleanup_push(ptw32_sem_wait_cleanup, (void *) s);
 -	      result = pthreadCancelableWait (s->sem);
 -	      pthread_cleanup_pop(result);
 -#ifdef _MSC_VER
 -#pragma inline_depth()
 -#endif
 -	    }
 -#ifdef NEED_SEM
 -
 -	  if (!result && pthread_mutex_lock (&s->lock) == 0)
 -	    {
 -	      if (s->leftToUnblock > 0)
 -		{
 -		  --s->leftToUnblock;
 -		  SetEvent(s->sem);
 -		}
 -	      (void) pthread_mutex_unlock (&s->lock);
 -	    }
 -
 -#endif /* NEED_SEM */
 -
 -	}
 -
 -    }
 -
 -  if (result != 0)
 -    {
 -      errno = result;
 -      return -1;
 -    }
 -
 -  return 0;
 -
 -}				/* sem_wait */
 +/* + * ------------------------------------------------------------- + * + * Module: sem_wait.c + * + * Purpose: + *	Semaphores aren't actually part of the PThreads standard. + *	They are defined by the POSIX Standard: + * + *		POSIX 1003.1b-1993	(POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +static void PTW32_CDECL +ptw32_sem_wait_cleanup(void * sem) +{ +  sem_t s = (sem_t) sem; + +  if (pthread_mutex_lock (&s->lock) == 0) +    { +      ++s->value; +#ifdef NEED_SEM +           +      if (s->value > 0) +	{ +	  s->leftToUnblock = 0; +	}    +#else  +      /* +       * Don't release the W32 sema, it doesn't need adjustment +       * because it doesn't record the number of waiters. +       */ +#endif /* NEED_SEM */ +      (void) pthread_mutex_unlock (&s->lock); +    } +} + +int +sem_wait (sem_t * sem) +     /* +      * ------------------------------------------------------ +      * DOCPUBLIC +      *      This function  waits on a semaphore. +      * +      * PARAMETERS +      *      sem +      *              pointer to an instance of sem_t +      * +      * DESCRIPTION +      *      This function waits on a semaphore. If the +      *      semaphore value is greater than zero, it decreases +      *      its value by one. If the semaphore value is zero, then +      *      the calling thread (or process) is blocked until it can +      *      successfully decrease the value or until interrupted by +      *      a signal. +      * +      * RESULTS +      *              0               successfully decreased semaphore, +      *              -1              failed, error in errno +      * ERRNO +      *              EINVAL          'sem' is not a valid semaphore, +      *              ENOSYS          semaphores are not supported, +      *              EINTR           the function was interrupted by a signal, +      *              EDEADLK         a deadlock condition was detected. +      * +      * ------------------------------------------------------ +      */ +{ +  int result = 0; +  sem_t s = *sem; + +  if (s == NULL) +    { +      result = EINVAL; +    } +  else +    { + +      /* Faster to test before adjusting the count */ +      pthread_testcancel(); + +      if ((result = pthread_mutex_lock (&s->lock)) == 0) +	{ +	  int v = --s->value; + +	  (void) pthread_mutex_unlock (&s->lock); + +	  if (v < 0) +	    { +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif +	      /* Must wait */ +	      pthread_cleanup_push(ptw32_sem_wait_cleanup, (void *) s); +	      result = pthreadCancelableWait (s->sem); +	      pthread_cleanup_pop(result); +#ifdef _MSC_VER +#pragma inline_depth() +#endif +	    } +#ifdef NEED_SEM + +	  if (!result && pthread_mutex_lock (&s->lock) == 0) +	    { +	      if (s->leftToUnblock > 0) +		{ +		  --s->leftToUnblock; +		  SetEvent(s->sem); +		} +	      (void) pthread_mutex_unlock (&s->lock); +	    } + +#endif /* NEED_SEM */ + +	} + +    } + +  if (result != 0) +    { +      errno = result; +      return -1; +    } + +  return 0; + +}				/* sem_wait */ diff --git a/semaphore.c b/semaphore.c index 0a5131f..6b2b10e 100644 --- a/semaphore.c +++ b/semaphore.c @@ -1,69 +1,69 @@ -/*
 - * -------------------------------------------------------------
 - *
 - * Module: semaphore.c
 - *
 - * Purpose:
 - *	Concatenated version of separate modules to allow
 - *	inlining optimisation, which it is assumed can only
 - *	be effective within a single module.
 - *
 - *	Semaphores aren't actually part of the PThreads standard.
 - *	They are defined by the POSIX Standard:
 - *
 - *		POSIX 1003.1b-1993	(POSIX.1b)
 - *
 - * -------------------------------------------------------------
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - */
 -
 -#ifndef NEED_FTIME
 -#  include <sys/timeb.h>
 -#endif
 -
 -#include <limits.h>
 -
 -#include "pthread.h"
 -#include "semaphore.h"
 -#include "implement.h"
 -
 -
 -#include "sem_init.c"
 -#include "sem_destroy.c"
 -#include "sem_trywait.c"
 -#include "sem_wait.c"
 -#include "sem_timedwait.c"
 -#include "sem_post.c"
 -#include "sem_post_multiple.c"
 -#include "sem_getvalue.c"
 -#include "sem_open.c"
 -#include "sem_close.c"
 -#include "sem_unlink.c"
 +/* + * ------------------------------------------------------------- + * + * Module: semaphore.c + * + * Purpose: + *	Concatenated version of separate modules to allow + *	inlining optimisation, which it is assumed can only + *	be effective within a single module. + * + *	Semaphores aren't actually part of the PThreads standard. + *	They are defined by the POSIX Standard: + * + *		POSIX 1003.1b-1993	(POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef NEED_FTIME +#  include <sys/timeb.h> +#endif + +#include <limits.h> + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +#include "sem_init.c" +#include "sem_destroy.c" +#include "sem_trywait.c" +#include "sem_wait.c" +#include "sem_timedwait.c" +#include "sem_post.c" +#include "sem_post_multiple.c" +#include "sem_getvalue.c" +#include "sem_open.c" +#include "sem_close.c" +#include "sem_unlink.c" diff --git a/tests/Bmakefile b/tests/Bmakefile index 6263866..6ab5a34 100644 --- a/tests/Bmakefile +++ b/tests/Bmakefile @@ -1,345 +1,345 @@ -# Makefile for the pthreads test suite.
 -# If all of the .pass files can be created, the test suite has passed.
 -#
 -# --------------------------------------------------------------------------
 -#
 -#      Pthreads-win32 - POSIX Threads Library for Win32
 -#      Copyright(C) 1998 John E. Bossom
 -#      Copyright(C) 1999,2005 Pthreads-win32 contributors
 -# 
 -#      Contact Email: rpj@callisto.canberra.edu.au
 -# 
 -#      The current list of contributors is contained
 -#      in the file CONTRIBUTORS included with the source
 -#      code distribution. The list can also be seen at the
 -#      following World Wide Web location:
 -#      http://sources.redhat.com/pthreads-win32/contributors.html
 -# 
 -#      This library is free software; you can redistribute it and/or
 -#      modify it under the terms of the GNU Lesser General Public
 -#      License as published by the Free Software Foundation; either
 -#      version 2 of the License, or (at your option) any later version.
 -# 
 -#      This library is distributed in the hope that it will be useful,
 -#      but WITHOUT ANY WARRANTY; without even the implied warranty of
 -#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 -#      Lesser General Public License for more details.
 -# 
 -#      You should have received a copy of the GNU Lesser General Public
 -#      License along with this library in the file COPYING.LIB;
 -#      if not, write to the Free Software Foundation, Inc.,
 -#      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 -#
 -
 -DLL_VER	= 2
 -
 -CP	= copy
 -RM	= erase
 -CAT	= type
 -MKDIR	= mkdir
 -TOUCH	= echo Passed >
 -ECHO	= @echo
 -
 -QAPC	= ..\QueueUserAPCEx\User\quserex.dll
 -
 -CPHDR	= pthread.h semaphore.h sched.h
 -
 -OPTIM	= -O2
 -
 -XXLIBS	= ws2_32.lib
 -
 -# C++ Exceptions
 -BCEFLAGS	= -P -DPtW32NoCatchWarn -D__CLEANUP_CXX
 -BCELIB	= pthreadBCE$(DLL_VER).lib
 -BCEDLL	= pthreadBCE$(DLL_VER).dll
 -# C cleanup code
 -BCFLAGS	= -D__CLEANUP_C
 -BCLIB	= pthreadBC$(DLL_VER).lib
 -BCDLL	= pthreadBC$(DLL_VER).dll
 -# C++ Exceptions in application - using VC version of pthreads dll
 -BCXFLAGS	= -D__CLEANUP_C
 -
 -# Defaults
 -CPLIB	= $(BCLIB)
 -CPDLL	= $(BCDLL)
 -
 -CFLAGS= -q $(OPTIM) -w -tWC -tWM -w-aus -w-asc -w-par
 -LFLAGS= 
 -INCLUDES=-I.
 -BUILD_DIR=..
 -
 -COPYFILES	= $(CPHDR) $(CPLIB) $(CPDLL) $(QAPC)
 -
 -EHFLAGS	=
 -
 -# If a test case returns a non-zero exit code to the shell, make will
 -# stop.
 -
 -PASSES=   loadfree.pass \
 -	  errno1.pass  \
 -	  self1.pass  mutex5.pass  \
 -	  mutex1.pass  mutex1n.pass  mutex1e.pass  mutex1r.pass  \
 -	  semaphore1.pass  semaphore2.pass  semaphore3.pass  \
 -	  mutex2.pass  mutex3.pass  \
 -	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  \
 -	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  \
 -	  exit1.pass  create1.pass  create2.pass  reuse1.pass  reuse2.pass  equal1.pass  \
 -	  kill1.pass  valid1.pass  valid2.pass  \
 -	  exit2.pass  exit3.pass  exit4  exit5  \
 -	  join0.pass  join1.pass  join2.pass join3.pass  \
 -	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  \
 -	  mutex6s.pass  mutex6es.pass  mutex6rs.pass  \
 -	  mutex7.pass  mutex7n.pass  mutex7e.pass  mutex7r.pass  \
 -	  mutex8.pass  mutex8n.pass  mutex8e.pass  mutex8r.pass  \
 -	  count1.pass  once1.pass  once2.pass  once3.pass  once4.pass  tsd1.pass  \
 -	  self2.pass  \
 -	  cancel1.pass  cancel2.pass  \
 -	  semaphore4.pass  semaphore4t.pass  \
 -	  delay1.pass  delay2.pass  eyal1.pass  \
 -	  condvar3.pass  condvar3_1.pass  condvar3_2.pass  condvar3_3.pass  \
 -	  condvar4.pass  condvar5.pass  condvar6.pass  \
 -	  condvar7.pass  condvar8.pass  condvar9.pass  \
 -	  rwlock1.pass  rwlock2.pass  rwlock3.pass  rwlock4.pass  \
 -	  rwlock5.pass  rwlock6.pass  rwlock7.pass  rwlock8.pass  \
 -	  rwlock2_t.pass  rwlock3_t.pass  rwlock4_t.pass  rwlock5_t.pass  rwlock6_t.pass  rwlock6_t2.pass  \
 -	  context1.pass  \
 -	  cancel3.pass  cancel4.pass  cancel5.pass  cancel6a.pass  cancel6d.pass  \
 -	  cancel7  cancel8  \
 -	  cleanup0.pass  cleanup1.pass  cleanup2.pass  cleanup3.pass  \
 -	  priority1.pass priority2.pass inherit1.pass  \
 -	  spin1.pass  spin2.pass  spin3.pass  spin4.pass  \
 -	  barrier1.pass  barrier2.pass  barrier3.pass  barrier4.pass  barrier5.pass  \
 -	  exception1.pass  exception2.pass  exception3.pass  \
 -	  cancel9 create3
 -
 -BENCHRESULTS = \
 -	  benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench
 -
 -help:
 -	@ $(ECHO) Run one of the following command lines:
 -	@ $(ECHO) make clean BC    (to test using BC dll with VC (no EH) applications)
 -	@ $(ECHO) make clean BCX   (to test using BC dll with VC++ (EH) applications)
 -	@ $(ECHO) make clean BCE   (to test using the BCE dll with VC++ EH applications)
 -	@ $(ECHO) make clean BC-bench    (to benchtest using BC dll with C bench app)
 -	@ $(ECHO) make clean BCX-bench   (to benchtest using BC dll with C++ bench app)
 -	@ $(ECHO) make clean BCE-bench   (to benchtest using BCE dll with C++ bench app)
 -
 -all:
 -	@ make clean BC
 -	@ make clean BCX
 -	@ make clean BCE
 -	@ make clean BC-bench
 -
 -# This allows an individual test application to be made using the default lib.
 -# e.g. make clean test cancel3.exe
 -test: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC)
 -
 -tests: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC) sizes.pass $(PASSES)
 -	@ $(ECHO) ALL TESTS PASSED! Congratulations!
 -
 -benchtests: $(CPLIB) $(CPDLL) $(CPHDR) $(BENCHRESULTS)
 -	@ $(ECHO) ALL BENCH TESTS DONE.
 -
 -sizes.pass: sizes.exe
 -	@ $(ECHO) ... Running $(TEST) test: $*.exe
 -	@ .\$*.exe > SIZES.$(TEST)
 -	@ $(CAT) SIZES.$(TEST)
 -	@ $(ECHO) ...... Passed
 -	@ $(TOUCH) $*.pass
 -
 -BCE:
 -	@ make -f Bmakefile TEST="$@" CPLIB="$(BCELIB)" CPDLL="$(BCEDLL)" EHFLAGS="$(BCEFLAGS)" tests
 -
 -BC:
 -	@ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCFLAGS)" tests
 -
 -BCX:
 -	@ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCXFLAGS)" tests
 -
 -BCE-bench:
 -	@ make -f Bmakefile TEST="$@" CPLIB="$(BCELIB)" CPDLL="$(BCEDLL)" EHFLAGS="$(BCEFLAGS)" XXLIBS="benchlib.o" benchtests
 -
 -BC-bench:
 -	@ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCFLAGS)" XXLIBS="benchlib.o" benchtests
 -
 -BCX-bench:
 -	@ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCXFLAGS)" XXLIBS="benchlib.o" benchtests
 -
 -.exe.pass:
 -	@ $(ECHO) ... Running $(TEST) test: $<
 -	@ .\$<
 -	@ $(ECHO) ...... Passed
 -	@ $(TOUCH) $@
 -
 -.exe.bench:
 -	@ $(ECHO) ... Running $(TEST) benchtest: $<
 -	@ .\$<
 -	@ $(ECHO) ...... Done
 -	@ $(TOUCH) $@
 -
 -.c.exe:
 -	@ $(ECHO) $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< -e$@ $(LFLAGS) $(CPLIB) $(XXLIBS)
 -	@ $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< -e$@ $(LFLAGS) $(CPLIB) $(XXLIBS)
 -
 -.c.o:
 -	@ $(ECHO) $(CC) $(EHFLAGS) -c $(CFLAGS) $(INCLUDES) $< -o$@
 -	@ $(CC) $(EHFLAGS) $(CFLAGS) -c $(INCLUDES) $< -o$@
 -
 -
 -.c.i:
 -	@ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $<
 -
 -$(COPYFILES):
 -	@ $(ECHO) Copying $@
 -	@ $(CP) $(BUILD_DIR)\$@ .
 -
 -pthread.dll: $(CPDLL)
 -	@ $(CP) $(CPDLL) pthread.dll
 -	@ $(CP) $(CPLIB) pthread.lib
 -
 -clean:
 -	- $(RM) *.dll
 -	- $(RM) *.lib
 -	- $(RM) pthread.h
 -	- $(RM) semaphore.h
 -	- $(RM) sched.h
 -	- $(RM) *.e
 -	- $(RM) *.i
 -	- $(RM) *.obj
 -	- $(RM) *.tds
 -	- $(RM) *.pdb
 -	- $(RM) *.o
 -	- $(RM) *.asm
 -	- $(RM) *.exe
 -	- $(RM) *.pass
 -	- $(RM) *.bench
 -	- $(RM) *.log
 -
 -benchtest1.bench:
 -benchtest2.bench:
 -benchtest3.bench:
 -benchtest4.bench:
 -benchtest5.bench:
 -barrier1.pass:
 -barrier2.pass: barrier1.pass
 -barrier3.pass: barrier2.pass
 -barrier4.pass: barrier3.pass
 -barrier5.pass: barrier4.pass
 -cancel1.pass: create1.pass
 -cancel2.pass: cancel1.pass
 -cancel3.pass: context1.pass
 -cancel4.pass: cancel3.pass
 -cancel5.pass: cancel3.pass
 -cancel6a.pass: cancel3.pass
 -cancel6d.pass: cancel3.pass
 -cancel7.pass: kill1.pass
 -cancel8.pass: cancel7.pass
 -cleanup0.pass: cancel5.pass
 -cleanup1.pass: cleanup0.pass
 -cleanup2.pass: cleanup1.pass
 -cleanup3.pass: cleanup2.pass
 -condvar1.pass:
 -condvar1_1.pass: condvar1.pass
 -condvar1_2.pass: join2.pass
 -condvar2.pass: condvar1.pass
 -condvar2_1.pass: condvar2.pass join2.pass
 -condvar3.pass: create1.pass condvar2.pass
 -condvar3_1.pass: condvar3.pass join2.pass
 -condvar3_2.pass: condvar3_1.pass
 -condvar3_3.pass: condvar3_2.pass
 -condvar4.pass: create1.pass
 -condvar5.pass: condvar4.pass
 -condvar6.pass: condvar5.pass
 -condvar7.pass: condvar6.pass cleanup1.pass
 -condvar8.pass: condvar7.pass
 -condvar9.pass: condvar8.pass
 -context1.pass: cancel2.pass
 -count1.pass: join1.pass
 -create1.pass: mutex2.pass
 -create2.pass: create1.pass
 -create3.pass:
 -delay1.pass:
 -delay2.pass: delay1.pass
 -equal1.pass: create1.pass
 -errno1.pass: mutex3.pass
 -exception1.pass: cancel4.pass
 -exception2.pass: exception1.pass
 -exception3.pass: exception2.pass
 -exit1.pass:
 -exit2.pass: create1.pass
 -exit3.pass: create1.pass
 -exit4.pass:
 -exit5.pass: kill1.pass
 -eyal1.pass: tsd1.pass
 -inherit1.pass: join1.pass priority1.pass
 -join0.pass: create1.pass
 -join1.pass: create1.pass
 -join2.pass: create1.pass
 -join3.pass: join2.pass
 -kill1.pass: 
 -loadfree.pass: pthread.dll
 -mutex1.pass: self1.pass
 -mutex1n.pass: mutex1.pass
 -mutex1e.pass: mutex1.pass
 -mutex1r.pass: mutex1.pass
 -mutex2.pass: mutex1.pass
 -mutex2r.pass: mutex2.pass
 -mutex2e.pass: mutex2.pass
 -mutex3.pass: create1.pass
 -mutex3r.pass: mutex3.pass
 -mutex3e.pass: mutex3.pass
 -mutex4.pass: mutex3.pass
 -mutex5.pass:
 -mutex6.pass: mutex4.pass
 -mutex6n.pass: mutex4.pass
 -mutex6e.pass: mutex4.pass
 -mutex6r.pass: mutex4.pass
 -mutex6s.pass: mutex6.pass
 -mutex6rs.pass: mutex6r.pass
 -mutex6es.pass: mutex6e.pass
 -mutex7.pass: mutex6.pass
 -mutex7n.pass: mutex6n.pass
 -mutex7e.pass: mutex6e.pass
 -mutex7r.pass: mutex6r.pass
 -mutex8.pass: mutex7.pass
 -mutex8n.pass: mutex7n.pass
 -mutex8e.pass: mutex7e.pass
 -mutex8r.pass: mutex7r.pass
 -once1.pass: create1.pass
 -once2.pass: once1.pass
 -once3.pass: once2.pass
 -once4.pass: once3.pass
 -priority1.pass: join1.pass
 -priority2.pass: priority1.pass barrier3.pass
 -reuse1.pass: create2.pass
 -reuse2.pass: reuse1.pass
 -rwlock1.pass: condvar6.pass
 -rwlock2.pass: rwlock1.pass
 -rwlock3.pass: rwlock2.pass
 -rwlock4.pass: rwlock3.pass
 -rwlock5.pass: rwlock4.pass
 -rwlock6.pass: rwlock5.pass
 -rwlock7.pass: rwlock6.pass
 -rwlock8.pass: rwlock7.pass
 -rwlock2_t.pass: rwlock2.pass
 -rwlock3_t.pass: rwlock2_t.pass
 -rwlock4_t.pass: rwlock3_t.pass
 -rwlock5_t.pass: rwlock4_t.pass
 -rwlock6_t.pass: rwlock5_t.pass
 -rwlock6_t2.pass: rwlock6_t.pass
 -self1.pass:
 -self2.pass: create1.pass
 -semaphore1.pass:
 -semaphore2.pass:
 -semaphore3.pass: semaphore2.pass
 -semaphore4.pass: semaphore3.pass cancel1.pass
 -semaphore4t.pass: semaphore4.pass
 -sizes.pass:
 -spin1.pass:
 -spin2.pass: spin1.pass
 -spin3.pass: spin2.pass
 -spin4.pass: spin3.pass
 -tsd1.pass: join1.pass
 -valid1.pass: join1.pass
 -valid2.pass: valid1.pass
 -cancel9.pass: cancel8.pass
 +# Makefile for the pthreads test suite. +# If all of the .pass files can be created, the test suite has passed. +# +# -------------------------------------------------------------------------- +# +#      Pthreads-win32 - POSIX Threads Library for Win32 +#      Copyright(C) 1998 John E. Bossom +#      Copyright(C) 1999,2005 Pthreads-win32 contributors +#  +#      Contact Email: rpj@callisto.canberra.edu.au +#  +#      The current list of contributors is contained +#      in the file CONTRIBUTORS included with the source +#      code distribution. The list can also be seen at the +#      following World Wide Web location: +#      http://sources.redhat.com/pthreads-win32/contributors.html +#  +#      This library is free software; you can redistribute it and/or +#      modify it under the terms of the GNU Lesser General Public +#      License as published by the Free Software Foundation; either +#      version 2 of the License, or (at your option) any later version. +#  +#      This library is distributed in the hope that it will be useful, +#      but WITHOUT ANY WARRANTY; without even the implied warranty of +#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +#      Lesser General Public License for more details. +#  +#      You should have received a copy of the GNU Lesser General Public +#      License along with this library in the file COPYING.LIB; +#      if not, write to the Free Software Foundation, Inc., +#      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# + +DLL_VER	= 2 + +CP	= copy +RM	= erase +CAT	= type +MKDIR	= mkdir +TOUCH	= echo Passed > +ECHO	= @echo + +QAPC	= ..\QueueUserAPCEx\User\quserex.dll + +CPHDR	= pthread.h semaphore.h sched.h + +OPTIM	= -O2 + +XXLIBS	= ws2_32.lib + +# C++ Exceptions +BCEFLAGS	= -P -DPtW32NoCatchWarn -D__CLEANUP_CXX +BCELIB	= pthreadBCE$(DLL_VER).lib +BCEDLL	= pthreadBCE$(DLL_VER).dll +# C cleanup code +BCFLAGS	= -D__CLEANUP_C +BCLIB	= pthreadBC$(DLL_VER).lib +BCDLL	= pthreadBC$(DLL_VER).dll +# C++ Exceptions in application - using VC version of pthreads dll +BCXFLAGS	= -D__CLEANUP_C + +# Defaults +CPLIB	= $(BCLIB) +CPDLL	= $(BCDLL) + +CFLAGS= -q $(OPTIM) -w -tWC -tWM -w-aus -w-asc -w-par +LFLAGS=  +INCLUDES=-I. +BUILD_DIR=.. + +COPYFILES	= $(CPHDR) $(CPLIB) $(CPDLL) $(QAPC) + +EHFLAGS	= + +# If a test case returns a non-zero exit code to the shell, make will +# stop. + +PASSES=   loadfree.pass \ +	  errno1.pass  \ +	  self1.pass  mutex5.pass  \ +	  mutex1.pass  mutex1n.pass  mutex1e.pass  mutex1r.pass  \ +	  semaphore1.pass  semaphore2.pass  semaphore3.pass  \ +	  mutex2.pass  mutex3.pass  \ +	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  \ +	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  \ +	  exit1.pass  create1.pass  create2.pass  reuse1.pass  reuse2.pass  equal1.pass  \ +	  kill1.pass  valid1.pass  valid2.pass  \ +	  exit2.pass  exit3.pass  exit4  exit5  \ +	  join0.pass  join1.pass  join2.pass join3.pass  \ +	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  \ +	  mutex6s.pass  mutex6es.pass  mutex6rs.pass  \ +	  mutex7.pass  mutex7n.pass  mutex7e.pass  mutex7r.pass  \ +	  mutex8.pass  mutex8n.pass  mutex8e.pass  mutex8r.pass  \ +	  count1.pass  once1.pass  once2.pass  once3.pass  once4.pass  tsd1.pass  \ +	  self2.pass  \ +	  cancel1.pass  cancel2.pass  \ +	  semaphore4.pass  semaphore4t.pass  \ +	  delay1.pass  delay2.pass  eyal1.pass  \ +	  condvar3.pass  condvar3_1.pass  condvar3_2.pass  condvar3_3.pass  \ +	  condvar4.pass  condvar5.pass  condvar6.pass  \ +	  condvar7.pass  condvar8.pass  condvar9.pass  \ +	  rwlock1.pass  rwlock2.pass  rwlock3.pass  rwlock4.pass  \ +	  rwlock5.pass  rwlock6.pass  rwlock7.pass  rwlock8.pass  \ +	  rwlock2_t.pass  rwlock3_t.pass  rwlock4_t.pass  rwlock5_t.pass  rwlock6_t.pass  rwlock6_t2.pass  \ +	  context1.pass  \ +	  cancel3.pass  cancel4.pass  cancel5.pass  cancel6a.pass  cancel6d.pass  \ +	  cancel7  cancel8  \ +	  cleanup0.pass  cleanup1.pass  cleanup2.pass  cleanup3.pass  \ +	  priority1.pass priority2.pass inherit1.pass  \ +	  spin1.pass  spin2.pass  spin3.pass  spin4.pass  \ +	  barrier1.pass  barrier2.pass  barrier3.pass  barrier4.pass  barrier5.pass  \ +	  exception1.pass  exception2.pass  exception3.pass  \ +	  cancel9 create3 + +BENCHRESULTS = \ +	  benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench + +help: +	@ $(ECHO) Run one of the following command lines: +	@ $(ECHO) make clean BC    (to test using BC dll with VC (no EH) applications) +	@ $(ECHO) make clean BCX   (to test using BC dll with VC++ (EH) applications) +	@ $(ECHO) make clean BCE   (to test using the BCE dll with VC++ EH applications) +	@ $(ECHO) make clean BC-bench    (to benchtest using BC dll with C bench app) +	@ $(ECHO) make clean BCX-bench   (to benchtest using BC dll with C++ bench app) +	@ $(ECHO) make clean BCE-bench   (to benchtest using BCE dll with C++ bench app) + +all: +	@ make clean BC +	@ make clean BCX +	@ make clean BCE +	@ make clean BC-bench + +# This allows an individual test application to be made using the default lib. +# e.g. make clean test cancel3.exe +test: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC) + +tests: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC) sizes.pass $(PASSES) +	@ $(ECHO) ALL TESTS PASSED! Congratulations! + +benchtests: $(CPLIB) $(CPDLL) $(CPHDR) $(BENCHRESULTS) +	@ $(ECHO) ALL BENCH TESTS DONE. + +sizes.pass: sizes.exe +	@ $(ECHO) ... Running $(TEST) test: $*.exe +	@ .\$*.exe > SIZES.$(TEST) +	@ $(CAT) SIZES.$(TEST) +	@ $(ECHO) ...... Passed +	@ $(TOUCH) $*.pass + +BCE: +	@ make -f Bmakefile TEST="$@" CPLIB="$(BCELIB)" CPDLL="$(BCEDLL)" EHFLAGS="$(BCEFLAGS)" tests + +BC: +	@ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCFLAGS)" tests + +BCX: +	@ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCXFLAGS)" tests + +BCE-bench: +	@ make -f Bmakefile TEST="$@" CPLIB="$(BCELIB)" CPDLL="$(BCEDLL)" EHFLAGS="$(BCEFLAGS)" XXLIBS="benchlib.o" benchtests + +BC-bench: +	@ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCFLAGS)" XXLIBS="benchlib.o" benchtests + +BCX-bench: +	@ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCXFLAGS)" XXLIBS="benchlib.o" benchtests + +.exe.pass: +	@ $(ECHO) ... Running $(TEST) test: $< +	@ .\$< +	@ $(ECHO) ...... Passed +	@ $(TOUCH) $@ + +.exe.bench: +	@ $(ECHO) ... Running $(TEST) benchtest: $< +	@ .\$< +	@ $(ECHO) ...... Done +	@ $(TOUCH) $@ + +.c.exe: +	@ $(ECHO) $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< -e$@ $(LFLAGS) $(CPLIB) $(XXLIBS) +	@ $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< -e$@ $(LFLAGS) $(CPLIB) $(XXLIBS) + +.c.o: +	@ $(ECHO) $(CC) $(EHFLAGS) -c $(CFLAGS) $(INCLUDES) $< -o$@ +	@ $(CC) $(EHFLAGS) $(CFLAGS) -c $(INCLUDES) $< -o$@ + + +.c.i: +	@ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< + +$(COPYFILES): +	@ $(ECHO) Copying $@ +	@ $(CP) $(BUILD_DIR)\$@ . + +pthread.dll: $(CPDLL) +	@ $(CP) $(CPDLL) pthread.dll +	@ $(CP) $(CPLIB) pthread.lib + +clean: +	- $(RM) *.dll +	- $(RM) *.lib +	- $(RM) pthread.h +	- $(RM) semaphore.h +	- $(RM) sched.h +	- $(RM) *.e +	- $(RM) *.i +	- $(RM) *.obj +	- $(RM) *.tds +	- $(RM) *.pdb +	- $(RM) *.o +	- $(RM) *.asm +	- $(RM) *.exe +	- $(RM) *.pass +	- $(RM) *.bench +	- $(RM) *.log + +benchtest1.bench: +benchtest2.bench: +benchtest3.bench: +benchtest4.bench: +benchtest5.bench: +barrier1.pass: +barrier2.pass: barrier1.pass +barrier3.pass: barrier2.pass +barrier4.pass: barrier3.pass +barrier5.pass: barrier4.pass +cancel1.pass: create1.pass +cancel2.pass: cancel1.pass +cancel3.pass: context1.pass +cancel4.pass: cancel3.pass +cancel5.pass: cancel3.pass +cancel6a.pass: cancel3.pass +cancel6d.pass: cancel3.pass +cancel7.pass: kill1.pass +cancel8.pass: cancel7.pass +cleanup0.pass: cancel5.pass +cleanup1.pass: cleanup0.pass +cleanup2.pass: cleanup1.pass +cleanup3.pass: cleanup2.pass +condvar1.pass: +condvar1_1.pass: condvar1.pass +condvar1_2.pass: join2.pass +condvar2.pass: condvar1.pass +condvar2_1.pass: condvar2.pass join2.pass +condvar3.pass: create1.pass condvar2.pass +condvar3_1.pass: condvar3.pass join2.pass +condvar3_2.pass: condvar3_1.pass +condvar3_3.pass: condvar3_2.pass +condvar4.pass: create1.pass +condvar5.pass: condvar4.pass +condvar6.pass: condvar5.pass +condvar7.pass: condvar6.pass cleanup1.pass +condvar8.pass: condvar7.pass +condvar9.pass: condvar8.pass +context1.pass: cancel2.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +create2.pass: create1.pass +create3.pass: +delay1.pass: +delay2.pass: delay1.pass +equal1.pass: create1.pass +errno1.pass: mutex3.pass +exception1.pass: cancel4.pass +exception2.pass: exception1.pass +exception3.pass: exception2.pass +exit1.pass: +exit2.pass: create1.pass +exit3.pass: create1.pass +exit4.pass: +exit5.pass: kill1.pass +eyal1.pass: tsd1.pass +inherit1.pass: join1.pass priority1.pass +join0.pass: create1.pass +join1.pass: create1.pass +join2.pass: create1.pass +join3.pass: join2.pass +kill1.pass:  +loadfree.pass: pthread.dll +mutex1.pass: self1.pass +mutex1n.pass: mutex1.pass +mutex1e.pass: mutex1.pass +mutex1r.pass: mutex1.pass +mutex2.pass: mutex1.pass +mutex2r.pass: mutex2.pass +mutex2e.pass: mutex2.pass +mutex3.pass: create1.pass +mutex3r.pass: mutex3.pass +mutex3e.pass: mutex3.pass +mutex4.pass: mutex3.pass +mutex5.pass: +mutex6.pass: mutex4.pass +mutex6n.pass: mutex4.pass +mutex6e.pass: mutex4.pass +mutex6r.pass: mutex4.pass +mutex6s.pass: mutex6.pass +mutex6rs.pass: mutex6r.pass +mutex6es.pass: mutex6e.pass +mutex7.pass: mutex6.pass +mutex7n.pass: mutex6n.pass +mutex7e.pass: mutex6e.pass +mutex7r.pass: mutex6r.pass +mutex8.pass: mutex7.pass +mutex8n.pass: mutex7n.pass +mutex8e.pass: mutex7e.pass +mutex8r.pass: mutex7r.pass +once1.pass: create1.pass +once2.pass: once1.pass +once3.pass: once2.pass +once4.pass: once3.pass +priority1.pass: join1.pass +priority2.pass: priority1.pass barrier3.pass +reuse1.pass: create2.pass +reuse2.pass: reuse1.pass +rwlock1.pass: condvar6.pass +rwlock2.pass: rwlock1.pass +rwlock3.pass: rwlock2.pass +rwlock4.pass: rwlock3.pass +rwlock5.pass: rwlock4.pass +rwlock6.pass: rwlock5.pass +rwlock7.pass: rwlock6.pass +rwlock8.pass: rwlock7.pass +rwlock2_t.pass: rwlock2.pass +rwlock3_t.pass: rwlock2_t.pass +rwlock4_t.pass: rwlock3_t.pass +rwlock5_t.pass: rwlock4_t.pass +rwlock6_t.pass: rwlock5_t.pass +rwlock6_t2.pass: rwlock6_t.pass +self1.pass: +self2.pass: create1.pass +semaphore1.pass: +semaphore2.pass: +semaphore3.pass: semaphore2.pass +semaphore4.pass: semaphore3.pass cancel1.pass +semaphore4t.pass: semaphore4.pass +sizes.pass: +spin1.pass: +spin2.pass: spin1.pass +spin3.pass: spin2.pass +spin4.pass: spin3.pass +tsd1.pass: join1.pass +valid1.pass: join1.pass +valid2.pass: valid1.pass +cancel9.pass: cancel8.pass diff --git a/tests/ChangeLog b/tests/ChangeLog index d02bce0..3cd189f 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,873 +1,873 @@ -2005-04-18  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* condvar3.c: Remove locks from around signalling calls - should not
 -	be required for normal operation and only serve to mask deficiencies;
 -	ensure that CV destruction is not premature after removing guards.
 -	* condvar3_1.c: Likewise.
 -	* condvar3_2.c: Likewise.
 -	* condvar3_3.c: Likewise.
 -	* condvar4.c: Likewise.
 -	* condvar5.c: Likewise.
 -	* condvar6.c: Likewise.
 -	* condvar7.c: Likewise.
 -	* condvar8.c: Likewise.
 -	* condvar9.c: Likewise.
 -
 -2005-04-11  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -        * once4.c: New test; tries to test priority adjustments
 -        in pthread_once(); set priority class to realtime so that
 -        any failures can be seen.
 -
 -2005-04-06  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* cleanup0.c: Fix unguarded global variable accesses.
 -	* cleanup1.c: Likewise.
 -	* cleanup2.c: Likewise.
 -	* cleanup3.c: Likewise.
 -	* once2.c: Likewise.
 -	* once3.c: Likewise.
 -
 -2005-04-01  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* GNUmakefile: Add target to test linking static link library.
 -	* Makefile: Likewise.
 -	* self1.c: Run process attach/detach routines when static linked.
 -
 -2005-03-16  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* mutex5.c: Prevent optimiser from removing asserts.
 -
 -2005-03-12  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* once3.c: New test.
 -
 -2005-03-08  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -        * once2.c: New test.
 -
 -2004-11-19  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* Bmakefile: New makefile for Borland.
 -	* Makefile (DLL_VER): Added.
 -	* GNUmakefile (DLL_VER): Added.
 -	* Wmakefile (DLL_VER): Added.
 -
 -2004-10-29  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* semaphore4.c: New test.
 -	* semaphore4t.c: New test.
 -	* Debug.dsp (et al): Created MSVC Workspace project to aid debugging.
 -	* All: Many tests have been modified to work with the new pthread
 -	ID type; some other corrections were made after some library
 -	functions were semantically strengthened. For example,
 -	pthread_cond_destroy() no longer destroys a busy CV, which
 -	required minor redesigns of some tests, including some where
 -	the mutex associated with the CV was not locked during
 -	signaling and broadcasting.
 -
 -2004-10-23  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* condvar3.c: Fixed mutex operations that were incorrectly
 -	placed in relation to their condition variable operations.
 -	The error became evident after sem_destroy() was rewritten
 -	and conditions for destroing the semaphore were tightened.
 -	As a result, pthread_cond_destroy() was not able to
 -	destroy the cv queueing sempahore.
 -	* condvar3_1.c: Likewise.
 -	* condvar3_2.c: Likewise.
 -	* condvar4.c: Likewise.
 -	* condvar5.c: Likewise.
 -	* condvar6.c: Likewise.
 -	* condvar7.c: Likewise.
 -	* condvar8.c: Likewise.
 -	* condvar9.c: Likewise.
 -
 -2004-10-19  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* semaphore3.c: New test.
 -
 -2004-10-14  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* rwlock7.c (main): Tidy up statistics reporting; randomise
 -	update accesses.
 -	* rwlock8.c: New test.
 -
 -2004-09-08  Alexandre Girao  <alexgirao@gmail.com>
 -
 -	* cancel7.c (main): Win98 wants a valid (non-NULL) location
 -	for the last arg of _beginthreadex().
 -	* cancel8.c (main): Likewise.
 -	* exit4.c (main): Likewise.
 -	* exit5.c (main): Likewise.
 -
 -2004-08-26  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* create3.c: New test.
 -
 -2004-06-21  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* mutex2r.c: New test.
 -	* mutex2e.c: New test.
 -	* mutex3r.c: New test.
 -	* mutex3e.c: New test.
 -	* mutex6s.c: New test.
 -	* mutex6rs.c: New test.
 -	* mutex6es.c: New test.
 -
 -2004-05-21  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* join3.c: New test.
 -
 -2004-05-16  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* condvar2.c (WIN32_WINNT): Define to avoid redefinition warning
 -	from inclusion of implement.h.
 -	* convar2_1.c: Likewise.
 -	* condvar3_1.c: Likewise.
 -	* condvar3_2.c: Likewise.
 -	* context1.c: Likewise.
 -	* sizes.c: Likewise.
 -	* Makefile: Don't define _WIN32_WINNT on compiler command line.
 -	* GNUmakefile: Likewise.
 -	* priority1.c (main): Add column to output for actual win32
 -	priority.
 -
 -2004-05-16  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* cancel9.c: New test.
 -	* cancel3.c: Remove inappropriate conditional compilation;
 -	GNU C version of test suite no longer quietly skips this test.
 -	* cancel5.c: Likewise.
 -	* GNUmakefile: Can now build individual test app using default
 -	C version of library using 'make clean testname.c'.
 -	* Makefile: Likewise for VC using 'nmake clean test testname.c'.
 -
 -2003-10-14  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* Wmakefile: New makefile for Watcom testing.
 -
 -2003-09-18  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* benchtest.h: Move old mutex code into benchlib.c.
 -	* benchlib.c: New statically linked module to ensure that
 -	bench apps don't inline the code and therefore have an unfair
 -	advantage over the pthreads lib routines. Made little or no
 -	difference.
 -	* benchtest1.c: Minor change to avoid compiler warnings.
 -	* benchtest5.c: Likewise.
 -	* benchtest2.c: Fix misinformation in output report.
 -	* README.BENCH: Add comments on results.
 -
 -2003-09-14  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* priority1.c: Reworked to comply with modified priority
 -	management and provide additional output.
 -	* priority2.c: Likewise.
 -	* inherit1.c: Likewise.
 -
 -2003-09-03  Ross Johnson  <rpj@callisto.canberra.edu.au>
 -
 -	* exit4.c: New test.
 -	* exit5.c: New test.
 -	* cancel7.c: New test.
 -	* cancel8.c: New test.
 -
 -2003-08-13  Ross Johnson  <rpj@ise.canberra.edu.au>
 -
 -	* reuse1.c: New test.
 -	* reuse1.c: New test.
 -	* valid1.c: New test.
 -	* valid2.c: New test.
 -	* kill1.c: New test.
 - 	* create2.c: Now included in test regime.
 -
 -2003-07-19  Ross Johnson  <rpj@ise.canberra.edu.au>
 -
 -	* eyal1.c (waste_time): Make threads do more work to ensure that
 -	all threads get to do some work.
 -	* semaphore1.c: Make it clear that certain errors are expected.
 -	* exception2.c (non_MSVC code sections): Change to include
 -	C++ standard include file, i.e. change <new.h> to <exception>.
 -	* exception3.c (non_MSVC code sections): Likewise; qualify std::
 -	namespace entities where necessary.
 -	* GNUmakefile: modified to work in the MsysDTK (newer MinGW)
 -	environment; define CC as gcc or g++ as appropriate because
 -	using gcc -x c++ doesn't link with required c++ libs by default,
 -	but g++ does.
 -
 -2002-12-11  Ross Johnson  <ross@special.ise.canberra.edu.au>
 -
 -	* mutex7e.c: Assert EBUSY return instead of EDEADLK.
 -
 -2002-06-03  Ross Johnson  <rpj@digit.ise.canberra.edu.au>
 -
 -	* semaphore2.c: New test.
 -
 -2002-03-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 -
 -	* Makefile (CFLAGS): Changed /MT to /MD to link with
 -	the correct library MSVCRT.LIB. Otherwise errno doesn't
 -	work.
 -
 -2002-02-28  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 -
 -	* exception3.c: Correct recent change.
 -
 -	* semaphore1.c: New test.
 -
 -	* Makefile: Add rule to generate pre-processor output.
 -
 -2002-02-28  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 -
 -	* exception3.c (terminateFunction): For MSVC++, call
 -	exit() rather than pthread_exit(). Add comments to explain
 -	why.
 -	   * Notes from the MSVC++ manual:
 -	   *       1) A term_func() should call exit(), otherwise
 -	   *          abort() will be called on return to the caller.
 -	   *          abort() raises SIGABRT. The default signal handler
 -	   *          for all signals terminates the calling program with
 -	   *          exit code 3.
 -	   *       2) A term_func() must not throw an exception. Therefore
 -	   *          term_func() should not call pthread_exit() if an
 -	   *          an exception-using version of pthreads-win32 library
 -	   *          is being used (i.e. either pthreadVCE or pthreadVSE).
 -
 -
 -2002-02-23  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 -
 -	* rwlock2_t.c: New test.
 -	* rwlock3_t.c: New test.
 -	* rwlock4_t.c: New test.
 -	* rwlock5_t.c: New test.
 -	* rwlock6_t.c: New test.
 -	* rwlock6_t2.c: New test.
 -	* rwlock6.c (main): Swap thread and result variables
 -	to correspond to actual thread functions.
 -	* rwlock1.c: Change test description comment to correspond
 -	to the actual test.
 -
 -	* condvar1_2.c: Loop over the test many times in the hope
 -	of detecting any intermittent deadlocks. This is to
 -	test a fixed problem in pthread_cond_destroy.c.
 -
 -	* spin4.c: Remove unused variable.
 -
 -2002-02-17  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 -
 -	* condvar1_1.c: New test.
 -	* condvar1_2.c: New test.
 -
 -2002-02-07  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 -
 -	* delay1.c: New test.
 -	* delay2.c: New test.
 -	* exit4.c: New test.
 -
 -2002-02-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 -
 -	* mutex8: New test.
 -	* mutex8n: New test.
 -	* mutex8e: New test.
 -	* mutex8r: New test.
 -	* cancel6a: New test.
 -	* cancel6d: New test.
 -	* cleanup0.c: Add pragmas for inline optimisation control.
 -	* cleanup1.c: Add pragmas for inline optimisation control.
 -	* cleanup2.c: Add pragmas for inline optimisation control.
 -	* cleanup3.c: Add pragmas for inline optimisation control.
 -	* condvar7.c: Add pragmas for inline optimisation control.
 -	* condvar8.c: Add pragmas for inline optimisation control.
 -	* condvar9.c: Add pragmas for inline optimisation control.
 -
 -2002-01-30  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 -
 -	* cleanup1.c (): Must be declared __cdecl when compiled
 -	as C++ AND testing the standard C library version.
 -
 -2002-01-16  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 -
 -	* spin4.c (main): Fix renamed function call.
 -
 -2002-01-14  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 -
 -	* exception3.c (main): Shorten wait time.
 -
 -2002-01-09  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 -
 -	* mutex7.c: New test.
 -	* mutex7n.c: New test.
 -	* mutex7e.c: New test.
 -	* mutex7r.c: New test.
 -	* mutex6.c: Modified to avoid leaving the locked mutex
 -	around on exit.
 -
 -2001-10-25  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 -
 -	* condvar2.c: Remove reference to cv->nWaitersUnblocked.
 -	* condvar2_1.c: Likewise; lower NUMTHREADS from 60 to 30.
 -	* condvar3_1.c: Likewise.
 -	* condvar3_2.c: Likewise.
 -	* count1.c: lower NUMTHREADS from 60 to 30.
 -	* inherit1.c: Determine valid priority values and then
 -	assert values returned by POSIX routines are the same.
 -	* priority1.c: Likewise.
 -	* priority2.c: Likewise.
 -	
 -2001-07-12  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 -
 -	* barrier5.c: Assert that precisely one thread receives
 -	PTHREAD_BARRIER_SERIAL_THREAD at each barrier.
 -
 -2001-07-09  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 -
 -	* barrier3.c: Fixed.
 -	* barrier4.c: Fixed.
 -	* barrier5.c: New; proves that all threads in the group
 -	reaching the barrier wait and then resume together. Repeats the test
 -	using groups of 1 to 16 threads. Each group of threads must negotiate
 -	a large number of barriers (10000).
 -	* spin4.c: Fixed.
 -	* test.h (error_string): Modified the success (0) value.
 -
 -2001-07-07  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 -
 -	* spin3.c: Changed test and fixed.
 -	* spin4.c: Fixed.
 -	* barrier3.c: Fixed.
 -	* barrier4.c: Fixed.
 -
 -2001-07-05  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 -
 -	* spin1.c: New; testing spinlocks.
 -	* spin2.c: New; testing spinlocks.
 -	* spin3.c: New; testing spinlocks.
 -	* spin4.c: New; testing spinlocks.
 -	* barrier1.c: New; testing barriers.
 -	* barrier2.c: New; testing barriers.
 -	* barrier3.c: New; testing barriers.
 -	* barrier4.c: New; testing barriers.
 -	* GNUmakefile: Add new tests.
 -	* Makefile: Add new tests.
 -
 -2001-07-01  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 -
 -	* benchtest3.c: New; timing mutexes.
 -	* benchtest4.c: New; time mutexes.
 -	* condvar3_1.c: Fixed bug - Alexander Terekhov
 -	* condvar3_3.c: New test.
 -
 -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().
 +2005-04-18  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* condvar3.c: Remove locks from around signalling calls - should not +	be required for normal operation and only serve to mask deficiencies; +	ensure that CV destruction is not premature after removing guards. +	* condvar3_1.c: Likewise. +	* condvar3_2.c: Likewise. +	* condvar3_3.c: Likewise. +	* condvar4.c: Likewise. +	* condvar5.c: Likewise. +	* condvar6.c: Likewise. +	* condvar7.c: Likewise. +	* condvar8.c: Likewise. +	* condvar9.c: Likewise. + +2005-04-11  Ross Johnson  <rpj@callisto.canberra.edu.au> + +        * once4.c: New test; tries to test priority adjustments +        in pthread_once(); set priority class to realtime so that +        any failures can be seen. + +2005-04-06  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* cleanup0.c: Fix unguarded global variable accesses. +	* cleanup1.c: Likewise. +	* cleanup2.c: Likewise. +	* cleanup3.c: Likewise. +	* once2.c: Likewise. +	* once3.c: Likewise. + +2005-04-01  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* GNUmakefile: Add target to test linking static link library. +	* Makefile: Likewise. +	* self1.c: Run process attach/detach routines when static linked. + +2005-03-16  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* mutex5.c: Prevent optimiser from removing asserts. + +2005-03-12  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* once3.c: New test. + +2005-03-08  Ross Johnson  <rpj@callisto.canberra.edu.au> + +        * once2.c: New test. + +2004-11-19  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* Bmakefile: New makefile for Borland. +	* Makefile (DLL_VER): Added. +	* GNUmakefile (DLL_VER): Added. +	* Wmakefile (DLL_VER): Added. + +2004-10-29  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* semaphore4.c: New test. +	* semaphore4t.c: New test. +	* Debug.dsp (et al): Created MSVC Workspace project to aid debugging. +	* All: Many tests have been modified to work with the new pthread +	ID type; some other corrections were made after some library +	functions were semantically strengthened. For example, +	pthread_cond_destroy() no longer destroys a busy CV, which +	required minor redesigns of some tests, including some where +	the mutex associated with the CV was not locked during +	signaling and broadcasting. + +2004-10-23  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* condvar3.c: Fixed mutex operations that were incorrectly +	placed in relation to their condition variable operations. +	The error became evident after sem_destroy() was rewritten +	and conditions for destroing the semaphore were tightened. +	As a result, pthread_cond_destroy() was not able to +	destroy the cv queueing sempahore. +	* condvar3_1.c: Likewise. +	* condvar3_2.c: Likewise. +	* condvar4.c: Likewise. +	* condvar5.c: Likewise. +	* condvar6.c: Likewise. +	* condvar7.c: Likewise. +	* condvar8.c: Likewise. +	* condvar9.c: Likewise. + +2004-10-19  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* semaphore3.c: New test. + +2004-10-14  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* rwlock7.c (main): Tidy up statistics reporting; randomise +	update accesses. +	* rwlock8.c: New test. + +2004-09-08  Alexandre Girao  <alexgirao@gmail.com> + +	* cancel7.c (main): Win98 wants a valid (non-NULL) location +	for the last arg of _beginthreadex(). +	* cancel8.c (main): Likewise. +	* exit4.c (main): Likewise. +	* exit5.c (main): Likewise. + +2004-08-26  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* create3.c: New test. + +2004-06-21  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* mutex2r.c: New test. +	* mutex2e.c: New test. +	* mutex3r.c: New test. +	* mutex3e.c: New test. +	* mutex6s.c: New test. +	* mutex6rs.c: New test. +	* mutex6es.c: New test. + +2004-05-21  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* join3.c: New test. + +2004-05-16  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* condvar2.c (WIN32_WINNT): Define to avoid redefinition warning +	from inclusion of implement.h. +	* convar2_1.c: Likewise. +	* condvar3_1.c: Likewise. +	* condvar3_2.c: Likewise. +	* context1.c: Likewise. +	* sizes.c: Likewise. +	* Makefile: Don't define _WIN32_WINNT on compiler command line. +	* GNUmakefile: Likewise. +	* priority1.c (main): Add column to output for actual win32 +	priority. + +2004-05-16  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* cancel9.c: New test. +	* cancel3.c: Remove inappropriate conditional compilation; +	GNU C version of test suite no longer quietly skips this test. +	* cancel5.c: Likewise. +	* GNUmakefile: Can now build individual test app using default +	C version of library using 'make clean testname.c'. +	* Makefile: Likewise for VC using 'nmake clean test testname.c'. + +2003-10-14  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* Wmakefile: New makefile for Watcom testing. + +2003-09-18  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* benchtest.h: Move old mutex code into benchlib.c. +	* benchlib.c: New statically linked module to ensure that +	bench apps don't inline the code and therefore have an unfair +	advantage over the pthreads lib routines. Made little or no +	difference. +	* benchtest1.c: Minor change to avoid compiler warnings. +	* benchtest5.c: Likewise. +	* benchtest2.c: Fix misinformation in output report. +	* README.BENCH: Add comments on results. + +2003-09-14  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* priority1.c: Reworked to comply with modified priority +	management and provide additional output. +	* priority2.c: Likewise. +	* inherit1.c: Likewise. + +2003-09-03  Ross Johnson  <rpj@callisto.canberra.edu.au> + +	* exit4.c: New test. +	* exit5.c: New test. +	* cancel7.c: New test. +	* cancel8.c: New test. + +2003-08-13  Ross Johnson  <rpj@ise.canberra.edu.au> + +	* reuse1.c: New test. +	* reuse1.c: New test. +	* valid1.c: New test. +	* valid2.c: New test. +	* kill1.c: New test. + 	* create2.c: Now included in test regime. + +2003-07-19  Ross Johnson  <rpj@ise.canberra.edu.au> + +	* eyal1.c (waste_time): Make threads do more work to ensure that +	all threads get to do some work. +	* semaphore1.c: Make it clear that certain errors are expected. +	* exception2.c (non_MSVC code sections): Change to include +	C++ standard include file, i.e. change <new.h> to <exception>. +	* exception3.c (non_MSVC code sections): Likewise; qualify std:: +	namespace entities where necessary. +	* GNUmakefile: modified to work in the MsysDTK (newer MinGW) +	environment; define CC as gcc or g++ as appropriate because +	using gcc -x c++ doesn't link with required c++ libs by default, +	but g++ does. + +2002-12-11  Ross Johnson  <ross@special.ise.canberra.edu.au> + +	* mutex7e.c: Assert EBUSY return instead of EDEADLK. + +2002-06-03  Ross Johnson  <rpj@digit.ise.canberra.edu.au> + +	* semaphore2.c: New test. + +2002-03-02  Ross Johnson  <rpj@special.ise.canberra.edu.au> + +	* Makefile (CFLAGS): Changed /MT to /MD to link with +	the correct library MSVCRT.LIB. Otherwise errno doesn't +	work. + +2002-02-28  Ross Johnson  <rpj@special.ise.canberra.edu.au> + +	* exception3.c: Correct recent change. + +	* semaphore1.c: New test. + +	* Makefile: Add rule to generate pre-processor output. + +2002-02-28  Ross Johnson  <rpj@special.ise.canberra.edu.au> + +	* exception3.c (terminateFunction): For MSVC++, call +	exit() rather than pthread_exit(). Add comments to explain +	why. +	   * Notes from the MSVC++ manual: +	   *       1) A term_func() should call exit(), otherwise +	   *          abort() will be called on return to the caller. +	   *          abort() raises SIGABRT. The default signal handler +	   *          for all signals terminates the calling program with +	   *          exit code 3. +	   *       2) A term_func() must not throw an exception. Therefore +	   *          term_func() should not call pthread_exit() if an +	   *          an exception-using version of pthreads-win32 library +	   *          is being used (i.e. either pthreadVCE or pthreadVSE). + + +2002-02-23  Ross Johnson  <rpj@special.ise.canberra.edu.au> + +	* rwlock2_t.c: New test. +	* rwlock3_t.c: New test. +	* rwlock4_t.c: New test. +	* rwlock5_t.c: New test. +	* rwlock6_t.c: New test. +	* rwlock6_t2.c: New test. +	* rwlock6.c (main): Swap thread and result variables +	to correspond to actual thread functions. +	* rwlock1.c: Change test description comment to correspond +	to the actual test. + +	* condvar1_2.c: Loop over the test many times in the hope +	of detecting any intermittent deadlocks. This is to +	test a fixed problem in pthread_cond_destroy.c. + +	* spin4.c: Remove unused variable. + +2002-02-17  Ross Johnson  <rpj@special.ise.canberra.edu.au> + +	* condvar1_1.c: New test. +	* condvar1_2.c: New test. + +2002-02-07  Ross Johnson  <rpj@special.ise.canberra.edu.au> + +	* delay1.c: New test. +	* delay2.c: New test. +	* exit4.c: New test. + +2002-02-02  Ross Johnson  <rpj@special.ise.canberra.edu.au> + +	* mutex8: New test. +	* mutex8n: New test. +	* mutex8e: New test. +	* mutex8r: New test. +	* cancel6a: New test. +	* cancel6d: New test. +	* cleanup0.c: Add pragmas for inline optimisation control. +	* cleanup1.c: Add pragmas for inline optimisation control. +	* cleanup2.c: Add pragmas for inline optimisation control. +	* cleanup3.c: Add pragmas for inline optimisation control. +	* condvar7.c: Add pragmas for inline optimisation control. +	* condvar8.c: Add pragmas for inline optimisation control. +	* condvar9.c: Add pragmas for inline optimisation control. + +2002-01-30  Ross Johnson  <rpj@special.ise.canberra.edu.au> + +	* cleanup1.c (): Must be declared __cdecl when compiled +	as C++ AND testing the standard C library version. + +2002-01-16  Ross Johnson  <rpj@special.ise.canberra.edu.au> + +	* spin4.c (main): Fix renamed function call. + +2002-01-14  Ross Johnson  <rpj@special.ise.canberra.edu.au> + +	* exception3.c (main): Shorten wait time. + +2002-01-09  Ross Johnson  <rpj@special.ise.canberra.edu.au> + +	* mutex7.c: New test. +	* mutex7n.c: New test. +	* mutex7e.c: New test. +	* mutex7r.c: New test. +	* mutex6.c: Modified to avoid leaving the locked mutex +	around on exit. + +2001-10-25  Ross Johnson  <rpj@setup1.ise.canberra.edu.au> + +	* condvar2.c: Remove reference to cv->nWaitersUnblocked. +	* condvar2_1.c: Likewise; lower NUMTHREADS from 60 to 30. +	* condvar3_1.c: Likewise. +	* condvar3_2.c: Likewise. +	* count1.c: lower NUMTHREADS from 60 to 30. +	* inherit1.c: Determine valid priority values and then +	assert values returned by POSIX routines are the same. +	* priority1.c: Likewise. +	* priority2.c: Likewise. +	 +2001-07-12  Ross Johnson  <rpj@setup1.ise.canberra.edu.au> + +	* barrier5.c: Assert that precisely one thread receives +	PTHREAD_BARRIER_SERIAL_THREAD at each barrier. + +2001-07-09  Ross Johnson  <rpj@setup1.ise.canberra.edu.au> + +	* barrier3.c: Fixed. +	* barrier4.c: Fixed. +	* barrier5.c: New; proves that all threads in the group +	reaching the barrier wait and then resume together. Repeats the test +	using groups of 1 to 16 threads. Each group of threads must negotiate +	a large number of barriers (10000). +	* spin4.c: Fixed. +	* test.h (error_string): Modified the success (0) value. + +2001-07-07  Ross Johnson  <rpj@setup1.ise.canberra.edu.au> + +	* spin3.c: Changed test and fixed. +	* spin4.c: Fixed. +	* barrier3.c: Fixed. +	* barrier4.c: Fixed. + +2001-07-05  Ross Johnson  <rpj@special.ise.canberra.edu.au> + +	* spin1.c: New; testing spinlocks. +	* spin2.c: New; testing spinlocks. +	* spin3.c: New; testing spinlocks. +	* spin4.c: New; testing spinlocks. +	* barrier1.c: New; testing barriers. +	* barrier2.c: New; testing barriers. +	* barrier3.c: New; testing barriers. +	* barrier4.c: New; testing barriers. +	* GNUmakefile: Add new tests. +	* Makefile: Add new tests. + +2001-07-01  Ross Johnson  <rpj@special.ise.canberra.edu.au> + +	* benchtest3.c: New; timing mutexes. +	* benchtest4.c: New; time mutexes. +	* condvar3_1.c: Fixed bug - Alexander Terekhov +	* condvar3_3.c: New test. + +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 c031cd1..8700572 100644 --- a/tests/GNUmakefile +++ b/tests/GNUmakefile @@ -1,349 +1,349 @@ -# Makefile for the pthreads test suite.
 -# If all of the .pass files can be created, the test suite has passed.
 -#
 -# --------------------------------------------------------------------------
 -#
 -#      Pthreads-win32 - POSIX Threads Library for Win32
 -#      Copyright(C) 1998 John E. Bossom
 -#      Copyright(C) 1999,2005 Pthreads-win32 contributors
 -# 
 -#      Contact Email: rpj@callisto.canberra.edu.au
 -# 
 -#      The current list of contributors is contained
 -#      in the file CONTRIBUTORS included with the source
 -#      code distribution. The list can also be seen at the
 -#      following World Wide Web location:
 -#      http://sources.redhat.com/pthreads-win32/contributors.html
 -# 
 -#      This library is free software; you can redistribute it and/or
 -#      modify it under the terms of the GNU Lesser General Public
 -#      License as published by the Free Software Foundation; either
 -#      version 2 of the License, or (at your option) any later version.
 -# 
 -#      This library is distributed in the hope that it will be useful,
 -#      but WITHOUT ANY WARRANTY; without even the implied warranty of
 -#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 -#      Lesser General Public License for more details.
 -# 
 -#      You should have received a copy of the GNU Lesser General Public
 -#      License along with this library in the file COPYING.LIB;
 -#      if not, write to the Free Software Foundation, Inc.,
 -#      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 -#
 -
 -DLL_VER	= 2
 -
 -CP	= cp -f
 -MV	= mv -f
 -RM	= rm -f
 -CAT	= cat
 -#CP	= copy
 -#MV	= rename
 -#RM	= erase
 -#CAT	= type
 -MKDIR	= mkdir
 -TOUCH	= echo Passed >
 -ECHO	= @echo
 -MAKE	= make
 -
 -#
 -# Mingw32
 -#
 -XXCFLAGS	= 
 -XXLIBS	= -lws2_32
 -#CFLAGS	= -O3 -UNDEBUG -Wall $(XXCFLAGS)
 -CFLAGS	= -g -UNDEBUG -Wall $(XXCFLAGS)
 -BUILD_DIR	= ..
 -INCLUDES	= -I.
 -
 -
 -TEST	= GC
 -
 -# Default lib version
 -GCX	= $(TEST)$(DLL_VER)
 -
 -# Files we need to run the tests
 -# - paths are relative to pthreads build dir.
 -HDR	= pthread.h semaphore.h sched.h
 -LIB	= libpthread$(GCX).a
 -DLL	= pthread$(GCX).dll
 -QAPC	= ../QueueUserAPCEx/User/quserex.dll
 -
 -COPYFILES	= $(HDR) $(LIB) $(DLL) $(QAPC)
 -
 -# If a test case returns a non-zero exit code to the shell, make will
 -# stop.
 -
 -TESTS	= sizes loadfree \
 -	  self1 mutex5 mutex1 mutex1e mutex1n mutex1r \
 -	  semaphore1 semaphore2 semaphore3 \
 -	  condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 \
 -	  create1 create2 reuse1 reuse2 equal1 \
 -	  kill1 valid1 valid2 \
 -	  exit2 exit3 exit4 exit5 \
 -	  join0 join1 join2 join3 \
 -	  mutex2 mutex2r mutex2e mutex3 mutex3r mutex3e \
 -	  mutex4 mutex6 mutex6n mutex6e mutex6r \
 -	  mutex6s mutex6es mutex6rs \
 -	  mutex7 mutex7n mutex7e mutex7r mutex8 mutex8n mutex8e mutex8r \
 -	  count1 once1 once2 once3 once4 tsd1 self2 \
 -	  cancel1 cancel2 \
 -	  semaphore4 semaphore4t \
 -	  delay1 delay2 eyal1 \
 -	  condvar3 condvar3_1 condvar3_2 condvar3_3 \
 -	  condvar4 condvar5 condvar6 condvar7 condvar8 condvar9 \
 -	  errno1 \
 -	  rwlock1 rwlock2 rwlock3 rwlock4 rwlock5 rwlock6 rwlock7 rwlock8 \
 -	  rwlock2_t rwlock3_t rwlock4_t rwlock5_t rwlock6_t rwlock6_t2 \
 -	  context1 cancel3 cancel4 cancel5 cancel6a cancel6d \
 -	  cancel7 cancel8 \
 -	  cleanup0 cleanup1 cleanup2 cleanup3 \
 -	  priority1 priority2 inherit1 \
 -	  spin1 spin2 spin3 spin4 \
 -	  barrier1 barrier2 barrier3 barrier4 barrier5 \
 -	  exception1 exception2 exception3 \
 -	  cancel9 create3
 -
 -BENCHTESTS = \
 -	benchtest1 benchtest2 benchtest3 benchtest4 benchtest5
 -
 -STATICTESTS = \
 -	self1
 -
 -PASSES		= $(TESTS:%=%.pass)
 -BENCHRESULTS	= $(BENCHTESTS:%=%.bench)
 -STATICRESULTS	= $(STATICTESTS:%=%.pass)
 -
 -help:
 -	@ $(ECHO) "Run one of the following command lines:"
 -	@ $(ECHO) "make clean GC    (to test using GC dll with C (no EH) applications)"
 -	@ $(ECHO) "make clean GCX   (to test using GC dll with C++ (EH) applications)"
 -	@ $(ECHO) "make clean GCE   (to test using GCE dll with C++ (EH) applications)"
 -	@ $(ECHO) "make clean GC-bench	  (to benchtest using GNU C dll with C cleanup code)"
 -	@ $(ECHO) "make clean GCE-bench   (to benchtest using GNU C dll with C++ exception handling)"
 -	@ $(ECHO) "make clean GC-static   (to test using GC static lib with C (no EH) applications)"
 -
 -all:
 -	@ $(MAKE) clean GC
 -	@ $(MAKE) clean GCX
 -	@ $(MAKE) clean GCE
 -
 -GC:
 -	$(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" all-pass
 -
 -GCE:
 -	$(MAKE) TEST=GCE CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" all-pass
 -
 -GCX:
 -	$(MAKE) TEST=GC CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_C" all-pass
 -
 -GC-bench:
 -	$(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" XXLIBS="benchlib.o" all-bench
 -
 -GCE-bench:
 -	$(MAKE) TEST=GCE  CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" XXLIBS="benchlib." all-bench
 -
 -GC-static:
 -	$(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C -DPTW32_STATIC_LIB" DLL="" all-static
 -
 -all-pass: $(PASSES)
 -	@ $(ECHO) ALL TESTS PASSED! Congratulations!
 -
 -all-bench: $(BENCHRESULTS)
 -	@ $(ECHO) BENCH TESTS COMPLETED.
 -
 -all-static: $(STATICRESULTS)
 -	@ $(ECHO) ALL STATIC TESTS PASSED! Congratulations!
 -	@ $(ECHO) Build and test the DLL to run all tests.
 -	@ $(ECHO) This test only confirms that the static lib links correctly.
 -
 -benchtest1.bench:
 -benchtest2.bench:
 -benchtest3.bench:
 -benchtest4.bench:
 -benchtest5.bench:
 -
 -barrier1.pass:
 -barrier2.pass: barrier1.pass
 -barrier3.pass: barrier2.pass
 -barrier4.pass: barrier3.pass
 -barrier5.pass: barrier4.pass
 -cancel1.pass: create1.pass
 -cancel2.pass: cancel1.pass
 -cancel2_1.pass: cancel2.pass
 -cancel3.pass: context1.pass
 -cancel4.pass: cancel3.pass
 -cancel5.pass: cancel3.pass
 -cancel6a.pass: cancel3.pass
 -cancel6d.pass: cancel3.pass
 -cancel7.pass: kill1.pass
 -cancel8.pass: cancel7.pass
 -cleanup0.pass: cancel5.pass
 -cleanup1.pass: cleanup0.pass
 -cleanup2.pass: cleanup1.pass
 -cleanup3.pass: cleanup2.pass
 -condvar1.pass:
 -condvar1_1.pass: condvar1.pass
 -condvar1_2.pass: join2.pass
 -condvar2.pass: condvar1.pass
 -condvar2_1.pass: condvar2.pass join2.pass
 -condvar3.pass: create1.pass condvar2.pass
 -condvar3_1.pass: condvar3.pass join2.pass
 -condvar3_2.pass: condvar3_1.pass
 -condvar3_3.pass: condvar3_2.pass
 -condvar4.pass: create1.pass
 -condvar5.pass: condvar4.pass
 -condvar6.pass: condvar5.pass
 -condvar7.pass: condvar6.pass cleanup1.pass
 -condvar8.pass: condvar7.pass
 -condvar9.pass: condvar8.pass
 -context1.pass: cancel2.pass
 -count1.pass: join1.pass
 -create1.pass: mutex2.pass
 -create2.pass: create1.pass
 -create3.pass:
 -delay1.pass: cancel2.pass
 -delay2.pass: delay1.pass
 -equal1.pass: create1.pass
 -errno1.pass: mutex3.pass
 -exception1.pass: cancel4.pass
 -exception2.pass: exception1.pass
 -exception3.pass: exception2.pass
 -exit1.pass:
 -exit2.pass: create1.pass
 -exit3.pass: create1.pass
 -exit4.pass:
 -exit5.pass: exit4.pass kill1.pass
 -eyal1.pass: tsd1.pass
 -inherit1.pass: join1.pass priority1.pass
 -join0.pass: create1.pass
 -join1.pass: create1.pass
 -join2.pass: create1.pass
 -join3.pass: join2.pass
 -kill1.pass:
 -loadfree.pass: pthread.dll
 -mutex1.pass: self1.pass
 -mutex1n.pass: mutex1.pass
 -mutex1e.pass: mutex1.pass
 -mutex1r.pass: mutex1.pass
 -mutex2.pass: mutex1.pass
 -mutex2r.pass: mutex2.pass
 -mutex2e.pass: mutex2.pass
 -mutex3.pass: create1.pass
 -mutex3r.pass: mutex3.pass
 -mutex3e.pass: mutex3.pass
 -mutex4.pass: mutex3.pass
 -mutex5.pass:
 -mutex6.pass: mutex4.pass
 -mutex6n.pass: mutex4.pass
 -mutex6e.pass: mutex4.pass
 -mutex6r.pass: mutex4.pass
 -mutex6s.pass: mutex6.pass
 -mutex6rs.pass: mutex6r.pass
 -mutex6es.pass: mutex6e.pass
 -mutex7.pass: mutex6.pass
 -mutex7n.pass: mutex6n.pass
 -mutex7e.pass: mutex6e.pass
 -mutex7r.pass: mutex6r.pass
 -mutex8.pass: mutex7.pass
 -mutex8n.pass: mutex7n.pass
 -mutex8e.pass: mutex7e.pass
 -mutex8r.pass: mutex7r.pass
 -once1.pass: create1.pass
 -once2.pass: once1.pass
 -once3.pass: once2.pass
 -once4.pass: once3.pass
 -priority1.pass: join1.pass
 -priority2.pass: priority1.pass barrier3.pass
 -reuse1.pass: create2.pass
 -reuse2.pass: reuse1.pass
 -rwlock1.pass: condvar6.pass
 -rwlock2.pass: rwlock1.pass
 -rwlock3.pass: rwlock2.pass
 -rwlock4.pass: rwlock3.pass
 -rwlock5.pass: rwlock4.pass
 -rwlock6.pass: rwlock5.pass
 -rwlock7.pass: rwlock6.pass
 -rwlock8.pass: rwlock7.pass
 -rwlock2_t.pass: rwlock2.pass
 -rwlock3_t.pass: rwlock2_t.pass
 -rwlock4_t.pass: rwlock3_t.pass
 -rwlock5_t.pass: rwlock4_t.pass
 -rwlock6_t.pass: rwlock5_t.pass
 -rwlock6_t2.pass: rwlock6_t.pass
 -self1.pass:
 -self2.pass: create1.pass
 -semaphore1.pass:
 -semaphore2.pass:
 -semaphore3.pass: semaphore2.pass
 -semaphore4.pass: semaphore3.pass cancel1.pass
 -semaphore4t.pass: semaphore4.pass
 -sizes.pass:
 -spin1.pass:
 -spin2.pass: spin1.pass
 -spin3.pass: spin2.pass
 -spin4.pass: spin3.pass
 -tsd1.pass: join1.pass
 -valid1.pass: join1.pass
 -valid2.pass: valid1.pass
 -cancel9.pass: cancel8.pass
 -
 -sizes.pass: sizes.exe
 -	@ $(ECHO) Running $*
 -	$< > SIZES.$(TEST)
 -	@ $(CAT) SIZES.$(TEST)
 -	@ $(ECHO) Passed
 -	@ $(TOUCH) $@
 -
 -%.pass: %.exe
 -	@ $(ECHO) Running $*
 -	$*
 -	@ $(ECHO) Passed
 -	@ $(TOUCH) $@
 -
 -%.bench: $(LIB) $(DLL) $(HDR) $(QAPC) $(XXLIBS) %.exe
 -	@ $(ECHO) Running $*
 -	$*
 -	@ $(ECHO) Done
 -	@ $(TOUCH) $@
 -
 -%.exe: %.c $(LIB) $(DLL) $(HDR) $(QAPC)
 -	@ $(ECHO) Compiling $@
 -	@ $(ECHO) $(CC) $(CFLAGS) -o $@ $< $(INCLUDES) -L. -lpthread$(GCX) -lsupc++ $(XXLIBS)
 -	@ $(CC) $(CFLAGS) -o $@ $< $(INCLUDES) -L. -lpthread$(GCX) -lsupc++ $(XXLIBS)
 -
 -%.pre: %.c $(HDR)
 -	@ $(CC) -E $(CFLAGS) -o $@ $< $(INCLUDES)
 -
 -%.s: %.c $(HDR)
 -	@ $(CC) -S $(CFLAGS) -o $@ $< $(INCLUDES)
 -
 -$(COPYFILES):
 -	@ $(ECHO) Copying $@
 -	@ $(CP) $(BUILD_DIR)/$@ .
 -
 -benchlib.o: benchlib.c
 -	@ $(ECHO) Compiling $@
 -	@ $(ECHO) $(CC) -c $(CFLAGS) $< $(INCLUDES)
 -	@ $(CC) -c $(CFLAGS) $< $(INCLUDES)
 -
 -pthread.dll: $(DLL)
 -	@ $(CP) $(DLL) $@
 -
 -clean:
 -	- $(RM) *.dll
 -	- $(RM) *.lib
 -	- $(RM) pthread.h
 -	- $(RM) semaphore.h
 -	- $(RM) sched.h
 -	- $(RM) *.a
 -	- $(RM) *.e
 -	- $(RM) *.i
 -	- $(RM) *.o
 -	- $(RM) *.obj
 -	- $(RM) *.pdb
 -	- $(RM) *.exe
 -	- $(RM) *.pass
 -	- $(RM) *.bench
 -	- $(RM) *.static
 -	- $(RM) *.log
 +# Makefile for the pthreads test suite. +# If all of the .pass files can be created, the test suite has passed. +# +# -------------------------------------------------------------------------- +# +#      Pthreads-win32 - POSIX Threads Library for Win32 +#      Copyright(C) 1998 John E. Bossom +#      Copyright(C) 1999,2005 Pthreads-win32 contributors +#  +#      Contact Email: rpj@callisto.canberra.edu.au +#  +#      The current list of contributors is contained +#      in the file CONTRIBUTORS included with the source +#      code distribution. The list can also be seen at the +#      following World Wide Web location: +#      http://sources.redhat.com/pthreads-win32/contributors.html +#  +#      This library is free software; you can redistribute it and/or +#      modify it under the terms of the GNU Lesser General Public +#      License as published by the Free Software Foundation; either +#      version 2 of the License, or (at your option) any later version. +#  +#      This library is distributed in the hope that it will be useful, +#      but WITHOUT ANY WARRANTY; without even the implied warranty of +#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +#      Lesser General Public License for more details. +#  +#      You should have received a copy of the GNU Lesser General Public +#      License along with this library in the file COPYING.LIB; +#      if not, write to the Free Software Foundation, Inc., +#      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# + +DLL_VER	= 2 + +CP	= cp -f +MV	= mv -f +RM	= rm -f +CAT	= cat +#CP	= copy +#MV	= rename +#RM	= erase +#CAT	= type +MKDIR	= mkdir +TOUCH	= echo Passed > +ECHO	= @echo +MAKE	= make + +# +# Mingw32 +# +XXCFLAGS	=  +XXLIBS	= -lws2_32 +#CFLAGS	= -O3 -UNDEBUG -Wall $(XXCFLAGS) +CFLAGS	= -g -UNDEBUG -Wall $(XXCFLAGS) +BUILD_DIR	= .. +INCLUDES	= -I. + + +TEST	= GC + +# Default lib version +GCX	= $(TEST)$(DLL_VER) + +# Files we need to run the tests +# - paths are relative to pthreads build dir. +HDR	= pthread.h semaphore.h sched.h +LIB	= libpthread$(GCX).a +DLL	= pthread$(GCX).dll +QAPC	= ../QueueUserAPCEx/User/quserex.dll + +COPYFILES	= $(HDR) $(LIB) $(DLL) $(QAPC) + +# If a test case returns a non-zero exit code to the shell, make will +# stop. + +TESTS	= sizes loadfree \ +	  self1 mutex5 mutex1 mutex1e mutex1n mutex1r \ +	  semaphore1 semaphore2 semaphore3 \ +	  condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 \ +	  create1 create2 reuse1 reuse2 equal1 \ +	  kill1 valid1 valid2 \ +	  exit2 exit3 exit4 exit5 \ +	  join0 join1 join2 join3 \ +	  mutex2 mutex2r mutex2e mutex3 mutex3r mutex3e \ +	  mutex4 mutex6 mutex6n mutex6e mutex6r \ +	  mutex6s mutex6es mutex6rs \ +	  mutex7 mutex7n mutex7e mutex7r mutex8 mutex8n mutex8e mutex8r \ +	  count1 once1 once2 once3 once4 tsd1 self2 \ +	  cancel1 cancel2 \ +	  semaphore4 semaphore4t \ +	  delay1 delay2 eyal1 \ +	  condvar3 condvar3_1 condvar3_2 condvar3_3 \ +	  condvar4 condvar5 condvar6 condvar7 condvar8 condvar9 \ +	  errno1 \ +	  rwlock1 rwlock2 rwlock3 rwlock4 rwlock5 rwlock6 rwlock7 rwlock8 \ +	  rwlock2_t rwlock3_t rwlock4_t rwlock5_t rwlock6_t rwlock6_t2 \ +	  context1 cancel3 cancel4 cancel5 cancel6a cancel6d \ +	  cancel7 cancel8 \ +	  cleanup0 cleanup1 cleanup2 cleanup3 \ +	  priority1 priority2 inherit1 \ +	  spin1 spin2 spin3 spin4 \ +	  barrier1 barrier2 barrier3 barrier4 barrier5 \ +	  exception1 exception2 exception3 \ +	  cancel9 create3 + +BENCHTESTS = \ +	benchtest1 benchtest2 benchtest3 benchtest4 benchtest5 + +STATICTESTS = \ +	self1 + +PASSES		= $(TESTS:%=%.pass) +BENCHRESULTS	= $(BENCHTESTS:%=%.bench) +STATICRESULTS	= $(STATICTESTS:%=%.pass) + +help: +	@ $(ECHO) "Run one of the following command lines:" +	@ $(ECHO) "make clean GC    (to test using GC dll with C (no EH) applications)" +	@ $(ECHO) "make clean GCX   (to test using GC dll with C++ (EH) applications)" +	@ $(ECHO) "make clean GCE   (to test using GCE dll with C++ (EH) applications)" +	@ $(ECHO) "make clean GC-bench	  (to benchtest using GNU C dll with C cleanup code)" +	@ $(ECHO) "make clean GCE-bench   (to benchtest using GNU C dll with C++ exception handling)" +	@ $(ECHO) "make clean GC-static   (to test using GC static lib with C (no EH) applications)" + +all: +	@ $(MAKE) clean GC +	@ $(MAKE) clean GCX +	@ $(MAKE) clean GCE + +GC: +	$(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" all-pass + +GCE: +	$(MAKE) TEST=GCE CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" all-pass + +GCX: +	$(MAKE) TEST=GC CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_C" all-pass + +GC-bench: +	$(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" XXLIBS="benchlib.o" all-bench + +GCE-bench: +	$(MAKE) TEST=GCE  CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" XXLIBS="benchlib." all-bench + +GC-static: +	$(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C -DPTW32_STATIC_LIB" DLL="" all-static + +all-pass: $(PASSES) +	@ $(ECHO) ALL TESTS PASSED! Congratulations! + +all-bench: $(BENCHRESULTS) +	@ $(ECHO) BENCH TESTS COMPLETED. + +all-static: $(STATICRESULTS) +	@ $(ECHO) ALL STATIC TESTS PASSED! Congratulations! +	@ $(ECHO) Build and test the DLL to run all tests. +	@ $(ECHO) This test only confirms that the static lib links correctly. + +benchtest1.bench: +benchtest2.bench: +benchtest3.bench: +benchtest4.bench: +benchtest5.bench: + +barrier1.pass: +barrier2.pass: barrier1.pass +barrier3.pass: barrier2.pass +barrier4.pass: barrier3.pass +barrier5.pass: barrier4.pass +cancel1.pass: create1.pass +cancel2.pass: cancel1.pass +cancel2_1.pass: cancel2.pass +cancel3.pass: context1.pass +cancel4.pass: cancel3.pass +cancel5.pass: cancel3.pass +cancel6a.pass: cancel3.pass +cancel6d.pass: cancel3.pass +cancel7.pass: kill1.pass +cancel8.pass: cancel7.pass +cleanup0.pass: cancel5.pass +cleanup1.pass: cleanup0.pass +cleanup2.pass: cleanup1.pass +cleanup3.pass: cleanup2.pass +condvar1.pass: +condvar1_1.pass: condvar1.pass +condvar1_2.pass: join2.pass +condvar2.pass: condvar1.pass +condvar2_1.pass: condvar2.pass join2.pass +condvar3.pass: create1.pass condvar2.pass +condvar3_1.pass: condvar3.pass join2.pass +condvar3_2.pass: condvar3_1.pass +condvar3_3.pass: condvar3_2.pass +condvar4.pass: create1.pass +condvar5.pass: condvar4.pass +condvar6.pass: condvar5.pass +condvar7.pass: condvar6.pass cleanup1.pass +condvar8.pass: condvar7.pass +condvar9.pass: condvar8.pass +context1.pass: cancel2.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +create2.pass: create1.pass +create3.pass: +delay1.pass: cancel2.pass +delay2.pass: delay1.pass +equal1.pass: create1.pass +errno1.pass: mutex3.pass +exception1.pass: cancel4.pass +exception2.pass: exception1.pass +exception3.pass: exception2.pass +exit1.pass: +exit2.pass: create1.pass +exit3.pass: create1.pass +exit4.pass: +exit5.pass: exit4.pass kill1.pass +eyal1.pass: tsd1.pass +inherit1.pass: join1.pass priority1.pass +join0.pass: create1.pass +join1.pass: create1.pass +join2.pass: create1.pass +join3.pass: join2.pass +kill1.pass: +loadfree.pass: pthread.dll +mutex1.pass: self1.pass +mutex1n.pass: mutex1.pass +mutex1e.pass: mutex1.pass +mutex1r.pass: mutex1.pass +mutex2.pass: mutex1.pass +mutex2r.pass: mutex2.pass +mutex2e.pass: mutex2.pass +mutex3.pass: create1.pass +mutex3r.pass: mutex3.pass +mutex3e.pass: mutex3.pass +mutex4.pass: mutex3.pass +mutex5.pass: +mutex6.pass: mutex4.pass +mutex6n.pass: mutex4.pass +mutex6e.pass: mutex4.pass +mutex6r.pass: mutex4.pass +mutex6s.pass: mutex6.pass +mutex6rs.pass: mutex6r.pass +mutex6es.pass: mutex6e.pass +mutex7.pass: mutex6.pass +mutex7n.pass: mutex6n.pass +mutex7e.pass: mutex6e.pass +mutex7r.pass: mutex6r.pass +mutex8.pass: mutex7.pass +mutex8n.pass: mutex7n.pass +mutex8e.pass: mutex7e.pass +mutex8r.pass: mutex7r.pass +once1.pass: create1.pass +once2.pass: once1.pass +once3.pass: once2.pass +once4.pass: once3.pass +priority1.pass: join1.pass +priority2.pass: priority1.pass barrier3.pass +reuse1.pass: create2.pass +reuse2.pass: reuse1.pass +rwlock1.pass: condvar6.pass +rwlock2.pass: rwlock1.pass +rwlock3.pass: rwlock2.pass +rwlock4.pass: rwlock3.pass +rwlock5.pass: rwlock4.pass +rwlock6.pass: rwlock5.pass +rwlock7.pass: rwlock6.pass +rwlock8.pass: rwlock7.pass +rwlock2_t.pass: rwlock2.pass +rwlock3_t.pass: rwlock2_t.pass +rwlock4_t.pass: rwlock3_t.pass +rwlock5_t.pass: rwlock4_t.pass +rwlock6_t.pass: rwlock5_t.pass +rwlock6_t2.pass: rwlock6_t.pass +self1.pass: +self2.pass: create1.pass +semaphore1.pass: +semaphore2.pass: +semaphore3.pass: semaphore2.pass +semaphore4.pass: semaphore3.pass cancel1.pass +semaphore4t.pass: semaphore4.pass +sizes.pass: +spin1.pass: +spin2.pass: spin1.pass +spin3.pass: spin2.pass +spin4.pass: spin3.pass +tsd1.pass: join1.pass +valid1.pass: join1.pass +valid2.pass: valid1.pass +cancel9.pass: cancel8.pass + +sizes.pass: sizes.exe +	@ $(ECHO) Running $* +	$< > SIZES.$(TEST) +	@ $(CAT) SIZES.$(TEST) +	@ $(ECHO) Passed +	@ $(TOUCH) $@ + +%.pass: %.exe +	@ $(ECHO) Running $* +	$* +	@ $(ECHO) Passed +	@ $(TOUCH) $@ + +%.bench: $(LIB) $(DLL) $(HDR) $(QAPC) $(XXLIBS) %.exe +	@ $(ECHO) Running $* +	$* +	@ $(ECHO) Done +	@ $(TOUCH) $@ + +%.exe: %.c $(LIB) $(DLL) $(HDR) $(QAPC) +	@ $(ECHO) Compiling $@ +	@ $(ECHO) $(CC) $(CFLAGS) -o $@ $< $(INCLUDES) -L. -lpthread$(GCX) -lsupc++ $(XXLIBS) +	@ $(CC) $(CFLAGS) -o $@ $< $(INCLUDES) -L. -lpthread$(GCX) -lsupc++ $(XXLIBS) + +%.pre: %.c $(HDR) +	@ $(CC) -E $(CFLAGS) -o $@ $< $(INCLUDES) + +%.s: %.c $(HDR) +	@ $(CC) -S $(CFLAGS) -o $@ $< $(INCLUDES) + +$(COPYFILES): +	@ $(ECHO) Copying $@ +	@ $(CP) $(BUILD_DIR)/$@ . + +benchlib.o: benchlib.c +	@ $(ECHO) Compiling $@ +	@ $(ECHO) $(CC) -c $(CFLAGS) $< $(INCLUDES) +	@ $(CC) -c $(CFLAGS) $< $(INCLUDES) + +pthread.dll: $(DLL) +	@ $(CP) $(DLL) $@ + +clean: +	- $(RM) *.dll +	- $(RM) *.lib +	- $(RM) pthread.h +	- $(RM) semaphore.h +	- $(RM) sched.h +	- $(RM) *.a +	- $(RM) *.e +	- $(RM) *.i +	- $(RM) *.o +	- $(RM) *.obj +	- $(RM) *.pdb +	- $(RM) *.exe +	- $(RM) *.pass +	- $(RM) *.bench +	- $(RM) *.static +	- $(RM) *.log diff --git a/tests/Makefile b/tests/Makefile index 786d85e..6a82a58 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,369 +1,369 @@ -# Makefile for the pthreads test suite.
 -# If all of the .pass files can be created, the test suite has passed.
 -#
 -# --------------------------------------------------------------------------
 -#
 -#      Pthreads-win32 - POSIX Threads Library for Win32
 -#      Copyright(C) 1998 John E. Bossom
 -#      Copyright(C) 1999,2005 Pthreads-win32 contributors
 -# 
 -#      Contact Email: rpj@callisto.canberra.edu.au
 -# 
 -#      The current list of contributors is contained
 -#      in the file CONTRIBUTORS included with the source
 -#      code distribution. The list can also be seen at the
 -#      following World Wide Web location:
 -#      http://sources.redhat.com/pthreads-win32/contributors.html
 -# 
 -#      This library is free software; you can redistribute it and/or
 -#      modify it under the terms of the GNU Lesser General Public
 -#      License as published by the Free Software Foundation; either
 -#      version 2 of the License, or (at your option) any later version.
 -# 
 -#      This library is distributed in the hope that it will be useful,
 -#      but WITHOUT ANY WARRANTY; without even the implied warranty of
 -#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 -#      Lesser General Public License for more details.
 -# 
 -#      You should have received a copy of the GNU Lesser General Public
 -#      License along with this library in the file COPYING.LIB;
 -#      if not, write to the Free Software Foundation, Inc.,
 -#      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 -#
 -
 -DLL_VER	= 2
 -
 -CP	= copy
 -RM	= erase
 -CAT	= type
 -MKDIR	= mkdir
 -TOUCH	= echo Passed >
 -ECHO	= @echo
 -
 -QAPC	= ..\QueueUserAPCEx\User\quserex.dll
 -
 -CPHDR	= pthread.h semaphore.h sched.h
 -
 -OPTIM	= /O2 /Ob0
 -
 -XXLIBS	= ws2_32.lib
 -
 -# C++ Exceptions
 -VCEFLAGS	= /GX /TP /DPtW32NoCatchWarn /D__CLEANUP_CXX
 -VCELIB	= pthreadVCE$(DLL_VER).lib
 -VCEDLL	= pthreadVCE$(DLL_VER).dll
 -# Structured Exceptions
 -VSEFLAGS	= /D__CLEANUP_SEH
 -VSELIB	= pthreadVSE$(DLL_VER).lib
 -VSEDLL	= pthreadVSE$(DLL_VER).dll
 -# C cleanup code
 -VCFLAGS	= /D__CLEANUP_C
 -VCLIB	= pthreadVC$(DLL_VER).lib
 -VCDLL	= pthreadVC$(DLL_VER).dll
 -# C++ Exceptions in application - using VC version of pthreads dll
 -VCXFLAGS	= /GX /TP /D__CLEANUP_C
 -
 -# Defaults
 -CPLIB	= $(VCLIB)
 -CPDLL	= $(VCDLL)
 -
 -CFLAGS= $(OPTIM) /W3 /WX /MD /nologo /Yd /Zi
 -LFLAGS= /INCREMENTAL:NO
 -INCLUDES=-I.
 -BUILD_DIR=..
 -
 -COPYFILES	= $(CPHDR) $(CPLIB) $(CPDLL) $(QAPC)
 -
 -TEST		=
 -EHFLAGS	=
 -
 -# If a test case returns a non-zero exit code to the shell, make will
 -# stop.
 -
 -PASSES= sizes.pass  loadfree.pass \
 -	  self1.pass  mutex5.pass  \
 -	  mutex1.pass  mutex1n.pass  mutex1e.pass  mutex1r.pass  \
 -	  semaphore1.pass  semaphore2.pass  semaphore3.pass  \
 -	  mutex2.pass  mutex3.pass  \
 -	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  \
 -	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  \
 -	  exit1.pass  create1.pass  create2.pass  reuse1.pass  reuse2.pass  equal1.pass  \
 -	  kill1.pass  valid1.pass  valid2.pass  \
 -	  exit2.pass  exit3.pass  exit4.pass  exit5.pass  \
 -	  join0.pass  join1.pass  join2.pass join3.pass  \
 -	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  \
 -	  mutex6s.pass  mutex6es.pass  mutex6rs.pass  \
 -	  mutex7.pass  mutex7n.pass  mutex7e.pass  mutex7r.pass  \
 -	  mutex8.pass  mutex8n.pass  mutex8e.pass  mutex8r.pass  \
 -	  count1.pass  once1.pass  once2.pass  once3.pass  once4.pass  tsd1.pass  \
 -	  self2.pass  \
 -	  cancel1.pass  cancel2.pass  \
 -	  semaphore4.pass  semaphore4t.pass  \
 -	  delay1.pass  delay2.pass  eyal1.pass  \
 -	  condvar3.pass  condvar3_1.pass  condvar3_2.pass  condvar3_3.pass  \
 -	  condvar4.pass  condvar5.pass  condvar6.pass  \
 -	  condvar7.pass  condvar8.pass  condvar9.pass  \
 -	  errno1.pass  \
 -	  rwlock1.pass  rwlock2.pass  rwlock3.pass  rwlock4.pass  \
 -	  rwlock5.pass  rwlock6.pass  rwlock7.pass  rwlock8.pass  \
 -	  rwlock2_t.pass  rwlock3_t.pass  rwlock4_t.pass  rwlock5_t.pass  rwlock6_t.pass  rwlock6_t2.pass  \
 -	  context1.pass  \
 -	  cancel3.pass  cancel4.pass  cancel5.pass  cancel6a.pass  cancel6d.pass  \
 -	  cancel7.pass  cancel8.pass  \
 -	  cleanup0.pass  cleanup1.pass  cleanup2.pass  cleanup3.pass  \
 -	  priority1.pass priority2.pass inherit1.pass  \
 -	  spin1.pass  spin2.pass  spin3.pass  spin4.pass  \
 -	  barrier1.pass  barrier2.pass  barrier3.pass  barrier4.pass  barrier5.pass  \
 -	  exception1.pass  exception2.pass  exception3.pass  \
 -	  cancel9.pass create3.pass
 -
 -BENCHRESULTS = \
 -	  benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench
 -
 -STATICRESULTS = \
 -	  self1.pass
 -
 -help:
 -	@ $(ECHO) Run one of the following command lines:
 -	@ $(ECHO) nmake clean VC    (to test using VC dll with VC (no EH) applications)
 -	@ $(ECHO) nmake clean VCX   (to test using VC dll with VC++ (EH) applications)
 -	@ $(ECHO) nmake clean VCE   (to test using the VCE dll with VC++ EH applications)
 -	@ $(ECHO) nmake clean VSE   (to test using VSE dll with VC (SEH) applications)
 -	@ $(ECHO) nmake clean VC-bench    (to benchtest using VC dll with C bench app)
 -	@ $(ECHO) nmake clean VCX-bench   (to benchtest using VC dll with C++ bench app)
 -	@ $(ECHO) nmake clean VCE-bench   (to benchtest using VCE dll with C++ bench app)
 -	@ $(ECHO) nmake clean VSE-bench   (to benchtest using VSE dll with SEH bench app)
 -	@ $(ECHO) nmake clean VC-static   (to test using VC static lib with VC (no EH) applications)
 -
 -all:
 -	@ nmake clean VC
 -	@ nmake clean VCX
 -	@ nmake clean VCE
 -	@ nmake clean VSE
 -	@ nmake clean VC-bench
 -
 -# This allows an individual test application to be made using the default lib.
 -# e.g. nmake clean test cancel3.exe
 -test: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC)
 -
 -tests: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC) $(PASSES)
 -	@ $(ECHO) ALL TESTS PASSED! Congratulations!
 -
 -benchtests: $(CPLIB) $(CPDLL) $(CPHDR) $(XXLIBS) $(BENCHRESULTS)
 -	@ $(ECHO) ALL BENCH TESTS DONE.
 -
 -statictests: $(CPLIB) $(CPDLL) $(CPHDR) $(STATICRESULTS)
 -	@ $(ECHO) ALL STATIC TESTS DONE.
 -	@ $(ECHO) Build and test the DLL to run all tests.
 -	@ $(ECHO) The static test only confirms that the .lib links correctly.
 -
 -sizes.pass: sizes.exe
 -	@ $(ECHO) ... Running $(TEST)$(DLL_VER) test: $*.exe
 -	@ .\$*.exe > SIZES.$(TEST)
 -	@ $(CAT) SIZES.$(TEST)
 -	@ $(ECHO) ...... Passed
 -	@ $(TOUCH) $*.pass
 -
 -$(PASSES): $*.exe
 -	@ $(ECHO) ... Running $(TEST) test: $*.exe
 -	@ .\$*.exe
 -	@ $(ECHO) ...... Passed
 -	@ $(TOUCH) $*.pass
 -
 -$(BENCHRESULTS): $*.exe
 -	@ $(ECHO) ... Running $(TEST) benchtest: $*.exe
 -	@ .\$*.exe
 -	@ $(ECHO) ...... Done
 -	@ $(TOUCH) $*.bench
 -
 -VCE:
 -	@ nmake TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" tests
 -
 -VSE:	
 -	@ nmake TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" tests
 -
 -VC:
 -	@ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" tests
 -
 -VCX:
 -	@ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" tests
 -
 -VCE-bench:
 -	@ nmake TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" XXLIBS="benchlib.o" benchtests
 -
 -VSE-bench:
 -	@ nmake TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" XXLIBS="benchlib.o" benchtests
 -
 -VC-bench:
 -	@ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" XXLIBS="benchlib.o" benchtests
 -
 -VCX-bench:
 -	@ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" XXLIBS="benchlib.o" benchtests
 -
 -VC-static:
 -	@ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="" EHFLAGS="$(VCFLAGS) /DPTW32_STATIC_LIB" statictests
 -
 -.c.exe:
 -	@ $(ECHO) $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< /Fe$@ /link $(LFLAGS) $(CPLIB) $(XXLIBS)
 -	@ $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< /Fe$@ /link $(LFLAGS) $(CPLIB) $(XXLIBS)
 -
 -.c.o:
 -	@ $(ECHO) $(CC) $(EHFLAGS) /c $(CFLAGS) $(INCLUDES) $< /Fo$@
 -	@ $(CC) $(EHFLAGS) $(CFLAGS) /c $(INCLUDES) $< /Fo$@
 -
 -.c.i:
 -	@ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $<
 -
 -$(COPYFILES):
 -	@ $(ECHO) Copying $@
 -	@ $(CP) $(BUILD_DIR)\$@ .
 -
 -pthread.dll: $(CPDLL)
 -	@ $(CP) $(CPDLL) pthread.dll
 -	@ $(CP) $(CPLIB) pthread.lib
 -
 -clean:
 -	- $(RM) *.dll
 -	- $(RM) *.lib
 -	- $(RM) pthread.h
 -	- $(RM) semaphore.h
 -	- $(RM) sched.h
 -	- $(RM) *.e
 -	- $(RM) *.i
 -	- $(RM) *.obj
 -	- $(RM) *.pdb
 -	- $(RM) *.o
 -	- $(RM) *.asm
 -	- $(RM) *.exe
 -	- $(RM) *.pass
 -	- $(RM) *.bench
 -	- $(RM) *.log
 -
 -benchtest1.bench:
 -benchtest2.bench:
 -benchtest3.bench:
 -benchtest4.bench:
 -benchtest5.bench:
 -barrier1.pass:
 -barrier2.pass: barrier1.pass
 -barrier3.pass: barrier2.pass
 -barrier4.pass: barrier3.pass
 -barrier5.pass: barrier4.pass
 -cancel1.pass: create1.pass
 -cancel2.pass: cancel1.pass
 -cancel3.pass: context1.pass
 -cancel4.pass: cancel3.pass
 -cancel5.pass: cancel3.pass
 -cancel6a.pass: cancel3.pass
 -cancel6d.pass: cancel3.pass
 -cancel7.pass: kill1.pass
 -cancel8.pass: cancel7.pass
 -cleanup0.pass: cancel5.pass
 -cleanup1.pass: cleanup0.pass
 -cleanup2.pass: cleanup1.pass
 -cleanup3.pass: cleanup2.pass
 -condvar1.pass:
 -condvar1_1.pass: condvar1.pass
 -condvar1_2.pass: join2.pass
 -condvar2.pass: condvar1.pass
 -condvar2_1.pass: condvar2.pass join2.pass
 -condvar3.pass: create1.pass condvar2.pass
 -condvar3_1.pass: condvar3.pass join2.pass
 -condvar3_2.pass: condvar3_1.pass
 -condvar3_3.pass: condvar3_2.pass
 -condvar4.pass: create1.pass
 -condvar5.pass: condvar4.pass
 -condvar6.pass: condvar5.pass
 -condvar7.pass: condvar6.pass cleanup1.pass
 -condvar8.pass: condvar7.pass
 -condvar9.pass: condvar8.pass
 -context1.pass: cancel2.pass
 -count1.pass: join1.pass
 -create1.pass: mutex2.pass
 -create2.pass: create1.pass
 -create3.pass:
 -delay1.pass:
 -delay2.pass: delay1.pass
 -equal1.pass: create1.pass
 -errno1.pass: mutex3.pass
 -exception1.pass: cancel4.pass
 -exception2.pass: exception1.pass
 -exception3.pass: exception2.pass
 -exit1.pass:
 -exit2.pass: create1.pass
 -exit3.pass: create1.pass
 -exit4.pass:
 -exit5.pass: kill1.pass
 -eyal1.pass: tsd1.pass
 -inherit1.pass: join1.pass priority1.pass
 -join0.pass: create1.pass
 -join1.pass: create1.pass
 -join2.pass: create1.pass
 -join3.pass: join2.pass
 -kill1.pass: 
 -loadfree.pass: pthread.dll
 -mutex1.pass: self1.pass
 -mutex1n.pass: mutex1.pass
 -mutex1e.pass: mutex1.pass
 -mutex1r.pass: mutex1.pass
 -mutex2.pass: mutex1.pass
 -mutex2r.pass: mutex2.pass
 -mutex2e.pass: mutex2.pass
 -mutex3.pass: create1.pass
 -mutex3r.pass: mutex3.pass
 -mutex3e.pass: mutex3.pass
 -mutex4.pass: mutex3.pass
 -mutex5.pass:
 -mutex6.pass: mutex4.pass
 -mutex6n.pass: mutex4.pass
 -mutex6e.pass: mutex4.pass
 -mutex6r.pass: mutex4.pass
 -mutex6s.pass: mutex6.pass
 -mutex6rs.pass: mutex6r.pass
 -mutex6es.pass: mutex6e.pass
 -mutex7.pass: mutex6.pass
 -mutex7n.pass: mutex6n.pass
 -mutex7e.pass: mutex6e.pass
 -mutex7r.pass: mutex6r.pass
 -mutex8.pass: mutex7.pass
 -mutex8n.pass: mutex7n.pass
 -mutex8e.pass: mutex7e.pass
 -mutex8r.pass: mutex7r.pass
 -once1.pass: create1.pass
 -once2.pass: once1.pass
 -once3.pass: once2.pass
 -once4.pass: once3.pass
 -priority1.pass: join1.pass
 -priority2.pass: priority1.pass barrier3.pass
 -reuse1.pass: create2.pass
 -reuse2.pass: reuse1.pass
 -rwlock1.pass: condvar6.pass
 -rwlock2.pass: rwlock1.pass
 -rwlock3.pass: rwlock2.pass
 -rwlock4.pass: rwlock3.pass
 -rwlock5.pass: rwlock4.pass
 -rwlock6.pass: rwlock5.pass
 -rwlock7.pass: rwlock6.pass
 -rwlock8.pass: rwlock7.pass
 -rwlock2_t.pass: rwlock2.pass
 -rwlock3_t.pass: rwlock2_t.pass
 -rwlock4_t.pass: rwlock3_t.pass
 -rwlock5_t.pass: rwlock4_t.pass
 -rwlock6_t.pass: rwlock5_t.pass
 -rwlock6_t2.pass: rwlock6_t.pass
 -self1.pass:
 -self2.pass: create1.pass
 -semaphore1.pass:
 -semaphore2.pass:
 -semaphore3.pass: semaphore2.pass
 -semaphore4.pass: semaphore3.pass cancel1.pass
 -semaphore4t.pass: semaphore4.pass
 -sizes.pass:
 -spin1.pass:
 -spin2.pass: spin1.pass
 -spin3.pass: spin2.pass
 -spin4.pass: spin3.pass
 -tsd1.pass: join1.pass
 -valid1.pass: join1.pass
 -valid2.pass: valid1.pass
 -cancel9.pass: cancel8.pass
 +# Makefile for the pthreads test suite. +# If all of the .pass files can be created, the test suite has passed. +# +# -------------------------------------------------------------------------- +# +#      Pthreads-win32 - POSIX Threads Library for Win32 +#      Copyright(C) 1998 John E. Bossom +#      Copyright(C) 1999,2005 Pthreads-win32 contributors +#  +#      Contact Email: rpj@callisto.canberra.edu.au +#  +#      The current list of contributors is contained +#      in the file CONTRIBUTORS included with the source +#      code distribution. The list can also be seen at the +#      following World Wide Web location: +#      http://sources.redhat.com/pthreads-win32/contributors.html +#  +#      This library is free software; you can redistribute it and/or +#      modify it under the terms of the GNU Lesser General Public +#      License as published by the Free Software Foundation; either +#      version 2 of the License, or (at your option) any later version. +#  +#      This library is distributed in the hope that it will be useful, +#      but WITHOUT ANY WARRANTY; without even the implied warranty of +#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +#      Lesser General Public License for more details. +#  +#      You should have received a copy of the GNU Lesser General Public +#      License along with this library in the file COPYING.LIB; +#      if not, write to the Free Software Foundation, Inc., +#      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# + +DLL_VER	= 2 + +CP	= copy +RM	= erase +CAT	= type +MKDIR	= mkdir +TOUCH	= echo Passed > +ECHO	= @echo + +QAPC	= ..\QueueUserAPCEx\User\quserex.dll + +CPHDR	= pthread.h semaphore.h sched.h + +OPTIM	= /O2 /Ob0 + +XXLIBS	= ws2_32.lib + +# C++ Exceptions +VCEFLAGS	= /GX /TP /DPtW32NoCatchWarn /D__CLEANUP_CXX +VCELIB	= pthreadVCE$(DLL_VER).lib +VCEDLL	= pthreadVCE$(DLL_VER).dll +# Structured Exceptions +VSEFLAGS	= /D__CLEANUP_SEH +VSELIB	= pthreadVSE$(DLL_VER).lib +VSEDLL	= pthreadVSE$(DLL_VER).dll +# C cleanup code +VCFLAGS	= /D__CLEANUP_C +VCLIB	= pthreadVC$(DLL_VER).lib +VCDLL	= pthreadVC$(DLL_VER).dll +# C++ Exceptions in application - using VC version of pthreads dll +VCXFLAGS	= /GX /TP /D__CLEANUP_C + +# Defaults +CPLIB	= $(VCLIB) +CPDLL	= $(VCDLL) + +CFLAGS= $(OPTIM) /W3 /WX /MD /nologo /Yd /Zi +LFLAGS= /INCREMENTAL:NO +INCLUDES=-I. +BUILD_DIR=.. + +COPYFILES	= $(CPHDR) $(CPLIB) $(CPDLL) $(QAPC) + +TEST		= +EHFLAGS	= + +# If a test case returns a non-zero exit code to the shell, make will +# stop. + +PASSES= sizes.pass  loadfree.pass \ +	  self1.pass  mutex5.pass  \ +	  mutex1.pass  mutex1n.pass  mutex1e.pass  mutex1r.pass  \ +	  semaphore1.pass  semaphore2.pass  semaphore3.pass  \ +	  mutex2.pass  mutex3.pass  \ +	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  \ +	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  \ +	  exit1.pass  create1.pass  create2.pass  reuse1.pass  reuse2.pass  equal1.pass  \ +	  kill1.pass  valid1.pass  valid2.pass  \ +	  exit2.pass  exit3.pass  exit4.pass  exit5.pass  \ +	  join0.pass  join1.pass  join2.pass join3.pass  \ +	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  \ +	  mutex6s.pass  mutex6es.pass  mutex6rs.pass  \ +	  mutex7.pass  mutex7n.pass  mutex7e.pass  mutex7r.pass  \ +	  mutex8.pass  mutex8n.pass  mutex8e.pass  mutex8r.pass  \ +	  count1.pass  once1.pass  once2.pass  once3.pass  once4.pass  tsd1.pass  \ +	  self2.pass  \ +	  cancel1.pass  cancel2.pass  \ +	  semaphore4.pass  semaphore4t.pass  \ +	  delay1.pass  delay2.pass  eyal1.pass  \ +	  condvar3.pass  condvar3_1.pass  condvar3_2.pass  condvar3_3.pass  \ +	  condvar4.pass  condvar5.pass  condvar6.pass  \ +	  condvar7.pass  condvar8.pass  condvar9.pass  \ +	  errno1.pass  \ +	  rwlock1.pass  rwlock2.pass  rwlock3.pass  rwlock4.pass  \ +	  rwlock5.pass  rwlock6.pass  rwlock7.pass  rwlock8.pass  \ +	  rwlock2_t.pass  rwlock3_t.pass  rwlock4_t.pass  rwlock5_t.pass  rwlock6_t.pass  rwlock6_t2.pass  \ +	  context1.pass  \ +	  cancel3.pass  cancel4.pass  cancel5.pass  cancel6a.pass  cancel6d.pass  \ +	  cancel7.pass  cancel8.pass  \ +	  cleanup0.pass  cleanup1.pass  cleanup2.pass  cleanup3.pass  \ +	  priority1.pass priority2.pass inherit1.pass  \ +	  spin1.pass  spin2.pass  spin3.pass  spin4.pass  \ +	  barrier1.pass  barrier2.pass  barrier3.pass  barrier4.pass  barrier5.pass  \ +	  exception1.pass  exception2.pass  exception3.pass  \ +	  cancel9.pass create3.pass + +BENCHRESULTS = \ +	  benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench + +STATICRESULTS = \ +	  self1.pass + +help: +	@ $(ECHO) Run one of the following command lines: +	@ $(ECHO) nmake clean VC    (to test using VC dll with VC (no EH) applications) +	@ $(ECHO) nmake clean VCX   (to test using VC dll with VC++ (EH) applications) +	@ $(ECHO) nmake clean VCE   (to test using the VCE dll with VC++ EH applications) +	@ $(ECHO) nmake clean VSE   (to test using VSE dll with VC (SEH) applications) +	@ $(ECHO) nmake clean VC-bench    (to benchtest using VC dll with C bench app) +	@ $(ECHO) nmake clean VCX-bench   (to benchtest using VC dll with C++ bench app) +	@ $(ECHO) nmake clean VCE-bench   (to benchtest using VCE dll with C++ bench app) +	@ $(ECHO) nmake clean VSE-bench   (to benchtest using VSE dll with SEH bench app) +	@ $(ECHO) nmake clean VC-static   (to test using VC static lib with VC (no EH) applications) + +all: +	@ nmake clean VC +	@ nmake clean VCX +	@ nmake clean VCE +	@ nmake clean VSE +	@ nmake clean VC-bench + +# This allows an individual test application to be made using the default lib. +# e.g. nmake clean test cancel3.exe +test: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC) + +tests: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC) $(PASSES) +	@ $(ECHO) ALL TESTS PASSED! Congratulations! + +benchtests: $(CPLIB) $(CPDLL) $(CPHDR) $(XXLIBS) $(BENCHRESULTS) +	@ $(ECHO) ALL BENCH TESTS DONE. + +statictests: $(CPLIB) $(CPDLL) $(CPHDR) $(STATICRESULTS) +	@ $(ECHO) ALL STATIC TESTS DONE. +	@ $(ECHO) Build and test the DLL to run all tests. +	@ $(ECHO) The static test only confirms that the .lib links correctly. + +sizes.pass: sizes.exe +	@ $(ECHO) ... Running $(TEST)$(DLL_VER) test: $*.exe +	@ .\$*.exe > SIZES.$(TEST) +	@ $(CAT) SIZES.$(TEST) +	@ $(ECHO) ...... Passed +	@ $(TOUCH) $*.pass + +$(PASSES): $*.exe +	@ $(ECHO) ... Running $(TEST) test: $*.exe +	@ .\$*.exe +	@ $(ECHO) ...... Passed +	@ $(TOUCH) $*.pass + +$(BENCHRESULTS): $*.exe +	@ $(ECHO) ... Running $(TEST) benchtest: $*.exe +	@ .\$*.exe +	@ $(ECHO) ...... Done +	@ $(TOUCH) $*.bench + +VCE: +	@ nmake TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" tests + +VSE:	 +	@ nmake TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" tests + +VC: +	@ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" tests + +VCX: +	@ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" tests + +VCE-bench: +	@ nmake TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" XXLIBS="benchlib.o" benchtests + +VSE-bench: +	@ nmake TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" XXLIBS="benchlib.o" benchtests + +VC-bench: +	@ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" XXLIBS="benchlib.o" benchtests + +VCX-bench: +	@ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" XXLIBS="benchlib.o" benchtests + +VC-static: +	@ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="" EHFLAGS="$(VCFLAGS) /DPTW32_STATIC_LIB" statictests + +.c.exe: +	@ $(ECHO) $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< /Fe$@ /link $(LFLAGS) $(CPLIB) $(XXLIBS) +	@ $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< /Fe$@ /link $(LFLAGS) $(CPLIB) $(XXLIBS) + +.c.o: +	@ $(ECHO) $(CC) $(EHFLAGS) /c $(CFLAGS) $(INCLUDES) $< /Fo$@ +	@ $(CC) $(EHFLAGS) $(CFLAGS) /c $(INCLUDES) $< /Fo$@ + +.c.i: +	@ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< + +$(COPYFILES): +	@ $(ECHO) Copying $@ +	@ $(CP) $(BUILD_DIR)\$@ . + +pthread.dll: $(CPDLL) +	@ $(CP) $(CPDLL) pthread.dll +	@ $(CP) $(CPLIB) pthread.lib + +clean: +	- $(RM) *.dll +	- $(RM) *.lib +	- $(RM) pthread.h +	- $(RM) semaphore.h +	- $(RM) sched.h +	- $(RM) *.e +	- $(RM) *.i +	- $(RM) *.obj +	- $(RM) *.pdb +	- $(RM) *.o +	- $(RM) *.asm +	- $(RM) *.exe +	- $(RM) *.pass +	- $(RM) *.bench +	- $(RM) *.log + +benchtest1.bench: +benchtest2.bench: +benchtest3.bench: +benchtest4.bench: +benchtest5.bench: +barrier1.pass: +barrier2.pass: barrier1.pass +barrier3.pass: barrier2.pass +barrier4.pass: barrier3.pass +barrier5.pass: barrier4.pass +cancel1.pass: create1.pass +cancel2.pass: cancel1.pass +cancel3.pass: context1.pass +cancel4.pass: cancel3.pass +cancel5.pass: cancel3.pass +cancel6a.pass: cancel3.pass +cancel6d.pass: cancel3.pass +cancel7.pass: kill1.pass +cancel8.pass: cancel7.pass +cleanup0.pass: cancel5.pass +cleanup1.pass: cleanup0.pass +cleanup2.pass: cleanup1.pass +cleanup3.pass: cleanup2.pass +condvar1.pass: +condvar1_1.pass: condvar1.pass +condvar1_2.pass: join2.pass +condvar2.pass: condvar1.pass +condvar2_1.pass: condvar2.pass join2.pass +condvar3.pass: create1.pass condvar2.pass +condvar3_1.pass: condvar3.pass join2.pass +condvar3_2.pass: condvar3_1.pass +condvar3_3.pass: condvar3_2.pass +condvar4.pass: create1.pass +condvar5.pass: condvar4.pass +condvar6.pass: condvar5.pass +condvar7.pass: condvar6.pass cleanup1.pass +condvar8.pass: condvar7.pass +condvar9.pass: condvar8.pass +context1.pass: cancel2.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +create2.pass: create1.pass +create3.pass: +delay1.pass: +delay2.pass: delay1.pass +equal1.pass: create1.pass +errno1.pass: mutex3.pass +exception1.pass: cancel4.pass +exception2.pass: exception1.pass +exception3.pass: exception2.pass +exit1.pass: +exit2.pass: create1.pass +exit3.pass: create1.pass +exit4.pass: +exit5.pass: kill1.pass +eyal1.pass: tsd1.pass +inherit1.pass: join1.pass priority1.pass +join0.pass: create1.pass +join1.pass: create1.pass +join2.pass: create1.pass +join3.pass: join2.pass +kill1.pass:  +loadfree.pass: pthread.dll +mutex1.pass: self1.pass +mutex1n.pass: mutex1.pass +mutex1e.pass: mutex1.pass +mutex1r.pass: mutex1.pass +mutex2.pass: mutex1.pass +mutex2r.pass: mutex2.pass +mutex2e.pass: mutex2.pass +mutex3.pass: create1.pass +mutex3r.pass: mutex3.pass +mutex3e.pass: mutex3.pass +mutex4.pass: mutex3.pass +mutex5.pass: +mutex6.pass: mutex4.pass +mutex6n.pass: mutex4.pass +mutex6e.pass: mutex4.pass +mutex6r.pass: mutex4.pass +mutex6s.pass: mutex6.pass +mutex6rs.pass: mutex6r.pass +mutex6es.pass: mutex6e.pass +mutex7.pass: mutex6.pass +mutex7n.pass: mutex6n.pass +mutex7e.pass: mutex6e.pass +mutex7r.pass: mutex6r.pass +mutex8.pass: mutex7.pass +mutex8n.pass: mutex7n.pass +mutex8e.pass: mutex7e.pass +mutex8r.pass: mutex7r.pass +once1.pass: create1.pass +once2.pass: once1.pass +once3.pass: once2.pass +once4.pass: once3.pass +priority1.pass: join1.pass +priority2.pass: priority1.pass barrier3.pass +reuse1.pass: create2.pass +reuse2.pass: reuse1.pass +rwlock1.pass: condvar6.pass +rwlock2.pass: rwlock1.pass +rwlock3.pass: rwlock2.pass +rwlock4.pass: rwlock3.pass +rwlock5.pass: rwlock4.pass +rwlock6.pass: rwlock5.pass +rwlock7.pass: rwlock6.pass +rwlock8.pass: rwlock7.pass +rwlock2_t.pass: rwlock2.pass +rwlock3_t.pass: rwlock2_t.pass +rwlock4_t.pass: rwlock3_t.pass +rwlock5_t.pass: rwlock4_t.pass +rwlock6_t.pass: rwlock5_t.pass +rwlock6_t2.pass: rwlock6_t.pass +self1.pass: +self2.pass: create1.pass +semaphore1.pass: +semaphore2.pass: +semaphore3.pass: semaphore2.pass +semaphore4.pass: semaphore3.pass cancel1.pass +semaphore4t.pass: semaphore4.pass +sizes.pass: +spin1.pass: +spin2.pass: spin1.pass +spin3.pass: spin2.pass +spin4.pass: spin3.pass +tsd1.pass: join1.pass +valid1.pass: join1.pass +valid2.pass: valid1.pass +cancel9.pass: cancel8.pass diff --git a/tests/README.benchtests b/tests/README.benchtests index 01051a2..e02cb3e 100644 --- a/tests/README.benchtests +++ b/tests/README.benchtests @@ -1,97 +1,97 @@ -
 -------------
 -Benchmarking
 -------------
 -There is a new but growing set a benchmarking programs in the
 -"tests" directory. These should be runnable using the
 -following command-lines corresponding to each of the possible
 -library builds:
 -
 -MSVC:
 -nmake clean VC-bench
 -nmake clean VCE-bench
 -nmake clean VSE-bench
 -
 -Mingw32:
 -make clean GC-bench
 -make clean GCE-bench
 -
 -UWIN:
 -The benchtests are run as part of the testsuite.
 -
 -
 -Mutex benchtests
 -----------------
 -
 -benchtest1 - Lock plus unlock on an unlocked mutex.
 -benchtest2 - Lock plus unlock on a locked mutex.
 -benchtest3 - Trylock on a locked mutex.
 -benchtest4 - Trylock plus unlock on an unlocked mutex.
 -
 -
 -Each test times up to three alternate synchronisation
 -implementations as a reference, and then times each of
 -the four mutex types provided by the library. Each is
 -described below:
 -
 -Simple Critical Section
 -- uses a simple Win32 critical section. There is no
 -additional overhead for this case as there is in the
 -remaining cases.
 -
 -POSIX mutex implemented using a Critical Section
 -- The old implementation which uses runtime adaptation
 -depending on the Windows variant being run on. When
 -the pthreads DLL was run on WinNT or higher then
 -POSIX mutexes would use Win32 Critical Sections.
 -
 -POSIX mutex implemented using a Win32 Mutex
 -- The old implementation which uses runtime adaptation
 -depending on the Windows variant being run on. When
 -the pthreads DLL was run on Win9x then POSIX mutexes
 -would use Win32 Mutexes (because TryEnterCriticalSection
 -is not implemented on Win9x).
 -
 -PTHREAD_MUTEX_DEFAULT
 -PTHREAD_MUTEX_NORMAL
 -PTHREAD_MUTEX_ERRORCHECK
 -PTHREAD_MUTEX_RECURSIVE
 -- The current implementation supports these mutex types.
 -The underlying basis of POSIX mutexes is now the same
 -irrespective of the Windows variant, and should therefore
 -have consistent performance.
 -
 -
 -In all benchtests, the operation is repeated a large
 -number of times and an average is calculated. Loop
 -overhead is measured and subtracted from all test times.
 -
 -Comment on the results
 -----------------------
 -The gain in performance for Win9x systems is enormous - up to
 -40 times faster for unlocked mutexes (2 times faster for locked
 -mutexes).
 -
 -Pthread_mutex_trylock also appears to be faster for locked mutexes.
 -
 -The price for the new consistency between WinNT and Win9x is
 -slower performance (up to twice as long) across a lock/unlock
 -sequence. It is difficult to get a good split timing for lock
 -and unlock operations, but by code inspection, it is the unlock
 -operation that is slowing the pair down in comparison with the
 -old-style CS mutexes, even for the fast PTHREAD_MUTEX_NORMAL mutex
 -type with no other waiting threads. However, comparitive
 -performance for operations on already locked mutexes is very close.
 -
 -When this is translated to real-world applications, the overall
 -camparitive performance should be almost identical on NT class
 -systems. That is, applications with heavy mutex contention should
 -have almost equal performance, while applications with only light
 -mutex contention should also have almost equal performance because
 -the most critical operation in this case is the lock operation.
 -
 -Overall, the newer pthreads-win32 mutex routines are only slower
 -(on NT class systems) where and when it is least critical.
 -
 -Thanks go to Thomas Pfaff for the current implementation of mutex
 -routines.
 + +------------ +Benchmarking +------------ +There is a new but growing set a benchmarking programs in the +"tests" directory. These should be runnable using the +following command-lines corresponding to each of the possible +library builds: + +MSVC: +nmake clean VC-bench +nmake clean VCE-bench +nmake clean VSE-bench + +Mingw32: +make clean GC-bench +make clean GCE-bench + +UWIN: +The benchtests are run as part of the testsuite. + + +Mutex benchtests +---------------- + +benchtest1 - Lock plus unlock on an unlocked mutex. +benchtest2 - Lock plus unlock on a locked mutex. +benchtest3 - Trylock on a locked mutex. +benchtest4 - Trylock plus unlock on an unlocked mutex. + + +Each test times up to three alternate synchronisation +implementations as a reference, and then times each of +the four mutex types provided by the library. Each is +described below: + +Simple Critical Section +- uses a simple Win32 critical section. There is no +additional overhead for this case as there is in the +remaining cases. + +POSIX mutex implemented using a Critical Section +- The old implementation which uses runtime adaptation +depending on the Windows variant being run on. When +the pthreads DLL was run on WinNT or higher then +POSIX mutexes would use Win32 Critical Sections. + +POSIX mutex implemented using a Win32 Mutex +- The old implementation which uses runtime adaptation +depending on the Windows variant being run on. When +the pthreads DLL was run on Win9x then POSIX mutexes +would use Win32 Mutexes (because TryEnterCriticalSection +is not implemented on Win9x). + +PTHREAD_MUTEX_DEFAULT +PTHREAD_MUTEX_NORMAL +PTHREAD_MUTEX_ERRORCHECK +PTHREAD_MUTEX_RECURSIVE +- The current implementation supports these mutex types. +The underlying basis of POSIX mutexes is now the same +irrespective of the Windows variant, and should therefore +have consistent performance. + + +In all benchtests, the operation is repeated a large +number of times and an average is calculated. Loop +overhead is measured and subtracted from all test times. + +Comment on the results +---------------------- +The gain in performance for Win9x systems is enormous - up to +40 times faster for unlocked mutexes (2 times faster for locked +mutexes). + +Pthread_mutex_trylock also appears to be faster for locked mutexes. + +The price for the new consistency between WinNT and Win9x is +slower performance (up to twice as long) across a lock/unlock +sequence. It is difficult to get a good split timing for lock +and unlock operations, but by code inspection, it is the unlock +operation that is slowing the pair down in comparison with the +old-style CS mutexes, even for the fast PTHREAD_MUTEX_NORMAL mutex +type with no other waiting threads. However, comparitive +performance for operations on already locked mutexes is very close. + +When this is translated to real-world applications, the overall +camparitive performance should be almost identical on NT class +systems. That is, applications with heavy mutex contention should +have almost equal performance, while applications with only light +mutex contention should also have almost equal performance because +the most critical operation in this case is the lock operation. + +Overall, the newer pthreads-win32 mutex routines are only slower +(on NT class systems) where and when it is least critical. + +Thanks go to Thomas Pfaff for the current implementation of mutex +routines. diff --git a/tests/Wmakefile b/tests/Wmakefile index 512b2ce..4f003df 100644 --- a/tests/Wmakefile +++ b/tests/Wmakefile @@ -1,341 +1,341 @@ -# Watcom makefile for the pthreads test suite.
 -# If all of the .pass files can be created, the test suite has passed.
 -#
 -# --------------------------------------------------------------------------
 -#
 -#      Pthreads-win32 - POSIX Threads Library for Win32
 -#      Copyright(C) 1998 John E. Bossom
 -#      Copyright(C) 1999,2005 Pthreads-win32 contributors
 -# 
 -#      Contact Email: rpj@callisto.canberra.edu.au
 -# 
 -#      The current list of contributors is contained
 -#      in the file CONTRIBUTORS included with the source
 -#      code distribution. The list can also be seen at the
 -#     following World Wide Web location:
 -#      http://sources.redhat.com/pthreads-win32/contributors.html
 -# 
 -#      This library is free software; you can redistribute it and/or
 -#      modify it under the terms of the GNU Lesser General Public
 -#      License as published by the Free Software Foundation; either
 -#      version 2 of the License, or (at your option) any later version.
 -# 
 -#      This library is distributed in the hope that it will be useful,
 -#      but WITHOUT ANY WARRANTY; without even the implied warranty of
 -#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 -#      Lesser General Public License for more details.
 -# 
 -#      You should have received a copy of the GNU Lesser General Public
 -#      License along with this library in the file COPYING.LIB;
 -#      if not, write to the Free Software Foundation, Inc.,
 -#      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 -#
 -
 -
 -DLL_VER	= 2
 -
 -.EXTENSIONS:
 -
 -.EXTENSIONS: .pass .exe .obj .i .c
 -
 -CP	= copy
 -RM	= erase
 -CAT	= type
 -MKDIR	= mkdir
 -TOUCH	= echo Passed >
 -ECHO	= @echo
 -
 -CPHDR	= pthread.h semaphore.h sched.h
 -
 -OPTIM	= -od
 -
 -XXLIBS	=
 -
 -# C++ Exceptions
 -WCEFLAGS	= -xs -dPtW32NoCatchWarn -d__CLEANUP_CXX
 -WCELIB	= pthreadWCE$(DLL_VER).lib
 -WCEDLL	= pthreadWCE$(DLL_VER).dll
 -# C cleanup code
 -WCFLAGS	= -d__CLEANUP_C
 -WCLIB	= pthreadWC$(DLL_VER).lib
 -WCDLL	= pthreadWC$(DLL_VER).dll
 -# C++ Exceptions in application - using WC version of pthreads dll
 -WCXFLAGS	= -xs -d__CLEANUP_C
 -
 -CFLAGS= -w4 -e25 -d_WIN32_WINNT=0x400 -d_REENTRANT -zq -bm $(OPTIM) -5r -bt=nt -mf -d2
 -
 -LFLAGS= 
 -INCLUDES= -i=.
 -BUILD_DIR=..
 -
 -COPYFILES	= $(CPHDR) $(CPLIB) $(CPDLL)
 -
 -TEST		=
 -EHFLAGS	=
 -
 -# If a test case returns a non-zero exit code to the shell, make will
 -# stop.
 -
 -PASSES	= sizes.pass  loadfree.pass &
 -	  self1.pass  mutex5.pass  &
 -	  mutex1.pass  mutex1n.pass  mutex1e.pass  mutex1r.pass &
 -	  semaphore1.pass  semaphore2.pass semaphore3.pass &
 -	  mutex2.pass  mutex3.pass  &
 -	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  &
 -	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  &
 -	  exit1.pass  create1.pass  create2.pass  reuse1.pass  reuse2.pass  equal1.pass  &
 -	  kill1.pass  valid1.pass  valid2.pass  &
 -	  exit2.pass  exit3.pass  exit4  exit5  &
 -	  join0.pass  join1.pass  join2.pass join3.pass  &
 -	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  &
 -	  mutex6s.pass  mutex6es.pass  mutex6rs.pass  &
 -	  mutex7.pass  mutex7n.pass  mutex7e.pass  mutex7r.pass  &
 -	  mutex8.pass  mutex8n.pass  mutex8e.pass  mutex8r.pass  &
 -	  count1.pass  once1.pass  once2.pass  once3.pass  once4.pass  tsd1.pass  &
 -	  self2.pass  &
 -	  cancel1.pass  cancel2.pass  &
 -	  semaphore4.pass semaphore4t.pass  &
 -	  delay1.pass  delay2.pass  eyal1.pass  &
 -	  condvar3.pass  condvar3_1.pass  condvar3_2.pass  condvar3_3.pass  &
 -	  condvar4.pass  condvar5.pass  condvar6.pass  &
 -	  condvar7.pass  condvar8.pass  condvar9.pass  &
 -	  errno1.pass  &
 -	  rwlock1.pass  rwlock2.pass  rwlock3.pass  rwlock4.pass  rwlock5.pass  &
 -	  rwlock6.pass  rwlock7.pass  rwlock8.pass  &
 -	  rwlock2_t.pass  rwlock3_t.pass  rwlock4_t.pass  rwlock5_t.pass  rwlock6_t.pass  rwlock6_t2.pass  &
 -	  context1.pass  &
 -	  cancel3.pass  cancel4.pass  cancel5.pass  cancel6a.pass  cancel6d.pass  &
 -	  cancel7  cancel8  &
 -	  cleanup0.pass  cleanup1.pass  cleanup2.pass  cleanup3.pass  &
 -	  priority1.pass priority2.pass inherit1.pass  &
 -	  spin1.pass  spin2.pass  spin3.pass  spin4.pass  &
 -	  barrier1.pass  barrier2.pass  barrier3.pass  barrier4.pass  barrier5.pass  &
 -	  exception1.pass  exception2.pass  exception3.pass  &
 -	  cancel9.pass
 -
 -BENCHRESULTS = &
 -	  benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench
 -
 -help: .SYMBOLIC
 -	@ $(ECHO) Run one of the following command lines:
 -	@ $(ECHO) wmake /f Wmakefile clean WC    (to test using WC dll with wcc386 (no EH) applications)
 -	@ $(ECHO) wmake /f Wmakefile clean WCX   (to test using WC dll with wpp386 (EH) applications)
 -	@ $(ECHO) wmake /f Wmakefile clean WCE   (to test using the WCE dll with wpp386 EH applications)
 -	@ $(ECHO) wmake /f Wmakefile clean WC-bench    (to benchtest using WC dll with C bench app)
 -	@ $(ECHO) wmake /f Wmakefile clean WCX-bench   (to benchtest using WC dll with C++ bench app)
 -	@ $(ECHO) wmake /f Wmakefile clean WCE-bench   (to benchtest using WCE dll with C++ bench app)
 -
 -all: .SYMBOLIC
 -	@ wmake /f Wmakefile clean WC
 -	@ wmake /f Wmakefile clean WCX
 -	@ wmake /f Wmakefile clean WCE
 -	@ wmake /f Wmakefile clean WSE
 -	@ wmake /f Wmakefile clean WC-bench
 -
 -tests: $(CPLIB) $(CPDLL) $(CPHDR) $(PASSES) .SYMBOLIC
 -	@ $(ECHO) ALL TESTS PASSED! Congratulations!
 -
 -benchtests: $(CPLIB) $(CPDLL) $(CPHDR) $(XXLIBS) $(BENCHRESULTS) .SYMBOLIC
 -	@ $(ECHO) ALL BENCH TESTS DONE.
 -
 -$(BENCHRESULTS): ($[*).exe
 -	@ $(ECHO) ... Running $(TEST) benchtest: ($[*).exe
 -	@ .\($[*).exe
 -	@ $(ECHO) ...... Done
 -	@ $(TOUCH) ($[*).bench
 -
 -WCE: .SYMBOLIC
 -	@ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCELIB)" CPDLL="$(WCEDLL)" EHFLAGS="$(WCEFLAGS)" tests
 -
 -WC: .SYMBOLIC
 -	@ wmake /f Wmakefile CC=wcc386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCFLAGS)" tests
 -
 -WCX: .SYMBOLIC
 -	@ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCXFLAGS)" tests
 -
 -WCE-bench: .SYMBOLIC
 -	@ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCELIB)" CPDLL="$(WCEDLL)" EHFLAGS="$(WCEFLAGS)" XXLIBS="benchlib.o" benchtests
 -
 -WC-bench: .SYMBOLIC
 -	@ wmake /f Wmakefile CC=wcc386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCFLAGS)" XXLIBS="benchlib.o" benchtests
 -
 -WCX-bench: .SYMBOLIC
 -	@ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCXFLAGS)" XXLIBS="benchlib.o" benchtests
 -
 -sizes.pass: sizes.exe
 -	@ $(ECHO) ... Running $(TEST) test: $^*
 -	@ $[@ > SIZES.$(TEST)
 -	@ $(CAT) SIZES.$(TEST)
 -	@ $(ECHO) ...... Passed
 -	@ $(TOUCH) $^@
 -
 -.exe.pass:
 -	@ $(ECHO) ... Running $(TEST) test: $^*
 -	@ $[@
 -	@ $(ECHO) ...... Passed
 -	@ $(TOUCH) $^@
 -
 -.obj.exe:
 -	@ $(ECHO) wlink NAME $^@ FILE $[@ LIBRARY $(CPLIB) OPTION quiet
 -	@ wlink NAME $^@ FILE $[@ LIBRARY $(CPLIB) OPTION quiet
 -
 -.c.obj:
 -	@ $(ECHO) $(CC) $^* $(EHFLAGS) $(CFLAGS) $(INCLUDES)
 -	@ $(CC) $^* $(EHFLAGS) $(CFLAGS) $(INCLUDES)
 -
 -.c.i:
 -	@ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $<
 -
 -$(COPYFILES): .SYMBOLIC
 -	@ $(ECHO) Copying $@
 -	@ $(CP) $(BUILD_DIR)\$@ .
 -
 -pthread.dll:
 -	@ $(CP) $(CPDLL) $*.dll
 -	@ $(CP) $(CPLIB) $*.lib
 -
 -clean: .SYMBOLIC
 -	@ if exist *.dll $(RM) *.dll
 -	@ if exist *.lib $(RM) *.lib
 -	@ if exist *.err $(RM) *.err
 -	@ if exist pthread.h $(RM) pthread.h
 -	@ if exist semaphore.h $(RM) semaphore.h
 -	@ if exist sched.h $(RM) sched.h
 -	@ if exist *.e $(RM) *.e
 -	@ if exist *.i $(RM) *.i
 -	@ if exist *.obj $(RM) *.obj
 -	@ if exist *.pdb $(RM) *.pdb
 -	@ if exist *.o $(RM) *.o
 -	@ if exist *.asm $(RM) *.asm
 -	@ if exist *.exe $(RM) *.exe
 -	@ if exist *.pass $(RM) *.pass
 -	@ if exist *.bench $(RM) *.bench
 -	@ if exist *.log $(RM) *.log
 -	@ $(ECHO) Clean completed.
 -
 -benchtest1.bench:
 -benchtest2.bench:
 -benchtest3.bench:
 -benchtest4.bench:
 -benchtest5.bench:
 -barrier1.pass:
 -barrier2.pass: barrier1.pass
 -barrier3.pass: barrier2.pass
 -barrier4.pass: barrier3.pass
 -barrier5.pass: barrier4.pass
 -cancel1.pass: create1.pass
 -cancel2.pass: cancel1.pass
 -cancel3.pass: context1.pass
 -cancel4.pass: cancel3.pass
 -cancel5.pass: cancel3.pass
 -cancel6a.pass: cancel3.pass
 -cancel6d.pass: cancel3.pass
 -cancel7.pass: kill1.pass
 -cancel8.pass: cancel7.pass
 -cleanup0.pass: cancel5.pass
 -cleanup1.pass: cleanup0.pass
 -cleanup2.pass: cleanup1.pass
 -cleanup3.pass: cleanup2.pass
 -condvar1.pass:
 -condvar1_1.pass: condvar1.pass
 -condvar1_2.pass: join2.pass
 -condvar2.pass: condvar1.pass
 -condvar2_1.pass: condvar2.pass join2.pass
 -condvar3.pass: create1.pass condvar2.pass
 -condvar3_1.pass: condvar3.pass join2.pass
 -condvar3_2.pass: condvar3_1.pass
 -condvar3_3.pass: condvar3_2.pass
 -condvar4.pass: create1.pass
 -condvar5.pass: condvar4.pass
 -condvar6.pass: condvar5.pass
 -condvar7.pass: condvar6.pass cleanup1.pass
 -condvar8.pass: condvar7.pass
 -condvar9.pass: condvar8.pass
 -context1.pass: cancel2.pass
 -count1.pass: join1.pass
 -create1.pass: mutex2.pass
 -create2.pass: create1.pass
 -delay1.pass:
 -delay2.pass: delay1.pass
 -equal1.pass: create1.pass
 -errno1.pass: mutex3.pass
 -exception1.pass: cancel4.pass
 -exception2.pass: exception1.pass
 -exception3.pass: exception2.pass
 -exit1.pass:
 -exit2.pass: create1.pass
 -exit3.pass: create1.pass
 -exit4.pass:
 -exit5.pass: kill1.pass
 -eyal1.pass: tsd1.pass
 -inherit1.pass: join1.pass priority1.pass
 -join0.pass: create1.pass
 -join1.pass: create1.pass
 -join2.pass: create1.pass
 -join3.pass: join2.pass
 -kill1.pass: 
 -loadfree.pass: pthread.dll
 -mutex1.pass: self1.pass
 -mutex1n.pass: mutex1.pass
 -mutex1e.pass: mutex1.pass
 -mutex1r.pass: mutex1.pass
 -mutex2.pass: mutex1.pass
 -mutex2r.pass: mutex2.pass
 -mutex2e.pass: mutex2.pass
 -mutex3.pass: create1.pass
 -mutex3r.pass: mutex3.pass
 -mutex3e.pass: mutex3.pass
 -mutex4.pass: mutex3.pass
 -mutex5.pass:
 -mutex6.pass: mutex4.pass
 -mutex6n.pass: mutex4.pass
 -mutex6e.pass: mutex4.pass
 -mutex6r.pass: mutex4.pass
 -mutex6s.pass: mutex6.pass
 -mutex6rs.pass: mutex6r.pass
 -mutex6es.pass: mutex6e.pass
 -mutex7.pass: mutex6.pass
 -mutex7n.pass: mutex6n.pass
 -mutex7e.pass: mutex6e.pass
 -mutex7r.pass: mutex6r.pass
 -mutex8.pass: mutex7.pass
 -mutex8n.pass: mutex7n.pass
 -mutex8e.pass: mutex7e.pass
 -mutex8r.pass: mutex7r.pass
 -once1.pass: create1.pass
 -once2.pass: once1.pass
 -once3.pass: once2.pass
 -once4.pass: once3.pass
 -priority1.pass: join1.pass
 -priority2.pass: priority1.pass barrier3.pass
 -reuse1.pass: create2.pass
 -reuse2.pass: reuse1.pass
 -rwlock1.pass: condvar6.pass
 -rwlock2.pass: rwlock1.pass
 -rwlock3.pass: rwlock2.pass
 -rwlock4.pass: rwlock3.pass
 -rwlock5.pass: rwlock4.pass
 -rwlock6.pass: rwlock5.pass
 -rwlock7.pass: rwlock6.pass
 -rwlock2_t.pass: rwlock2.pass
 -rwlock3_t.pass: rwlock2_t.pass
 -rwlock4_t.pass: rwlock3_t.pass
 -rwlock5_t.pass: rwlock4_t.pass
 -rwlock6_t.pass: rwlock5_t.pass
 -rwlock6_t2.pass: rwlock6_t.pass
 -self1.pass:
 -self2.pass: create1.pass
 -semaphore1.pass:
 -semaphore2.pass:
 -semaphore3.pass: semaphore2.pass
 -semaphore4.pass: semaphore3.pass cancel1.pass
 -semaphore4t.pass: semaphore4.pass
 -sizes.pass:
 -spin1.pass:
 -spin2.pass: spin1.pass
 -spin3.pass: spin2.pass
 -spin4.pass: spin3.pass
 -tsd1.pass: join1.pass
 -valid1.pass: join1.pass
 -valid2.pass: valid1.pass
 -cancel9.pass: cancel8.pass
 +# Watcom makefile for the pthreads test suite. +# If all of the .pass files can be created, the test suite has passed. +# +# -------------------------------------------------------------------------- +# +#      Pthreads-win32 - POSIX Threads Library for Win32 +#      Copyright(C) 1998 John E. Bossom +#      Copyright(C) 1999,2005 Pthreads-win32 contributors +#  +#      Contact Email: rpj@callisto.canberra.edu.au +#  +#      The current list of contributors is contained +#      in the file CONTRIBUTORS included with the source +#      code distribution. The list can also be seen at the +#     following World Wide Web location: +#      http://sources.redhat.com/pthreads-win32/contributors.html +#  +#      This library is free software; you can redistribute it and/or +#      modify it under the terms of the GNU Lesser General Public +#      License as published by the Free Software Foundation; either +#      version 2 of the License, or (at your option) any later version. +#  +#      This library is distributed in the hope that it will be useful, +#      but WITHOUT ANY WARRANTY; without even the implied warranty of +#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +#      Lesser General Public License for more details. +#  +#      You should have received a copy of the GNU Lesser General Public +#      License along with this library in the file COPYING.LIB; +#      if not, write to the Free Software Foundation, Inc., +#      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# + + +DLL_VER	= 2 + +.EXTENSIONS: + +.EXTENSIONS: .pass .exe .obj .i .c + +CP	= copy +RM	= erase +CAT	= type +MKDIR	= mkdir +TOUCH	= echo Passed > +ECHO	= @echo + +CPHDR	= pthread.h semaphore.h sched.h + +OPTIM	= -od + +XXLIBS	= + +# C++ Exceptions +WCEFLAGS	= -xs -dPtW32NoCatchWarn -d__CLEANUP_CXX +WCELIB	= pthreadWCE$(DLL_VER).lib +WCEDLL	= pthreadWCE$(DLL_VER).dll +# C cleanup code +WCFLAGS	= -d__CLEANUP_C +WCLIB	= pthreadWC$(DLL_VER).lib +WCDLL	= pthreadWC$(DLL_VER).dll +# C++ Exceptions in application - using WC version of pthreads dll +WCXFLAGS	= -xs -d__CLEANUP_C + +CFLAGS= -w4 -e25 -d_WIN32_WINNT=0x400 -d_REENTRANT -zq -bm $(OPTIM) -5r -bt=nt -mf -d2 + +LFLAGS=  +INCLUDES= -i=. +BUILD_DIR=.. + +COPYFILES	= $(CPHDR) $(CPLIB) $(CPDLL) + +TEST		= +EHFLAGS	= + +# If a test case returns a non-zero exit code to the shell, make will +# stop. + +PASSES	= sizes.pass  loadfree.pass & +	  self1.pass  mutex5.pass  & +	  mutex1.pass  mutex1n.pass  mutex1e.pass  mutex1r.pass & +	  semaphore1.pass  semaphore2.pass semaphore3.pass & +	  mutex2.pass  mutex3.pass  & +	  mutex2r.pass  mutex2e.pass  mutex3r.pass  mutex3e.pass  & +	  condvar1.pass  condvar1_1.pass  condvar1_2.pass  condvar2.pass  condvar2_1.pass  & +	  exit1.pass  create1.pass  create2.pass  reuse1.pass  reuse2.pass  equal1.pass  & +	  kill1.pass  valid1.pass  valid2.pass  & +	  exit2.pass  exit3.pass  exit4  exit5  & +	  join0.pass  join1.pass  join2.pass join3.pass  & +	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  & +	  mutex6s.pass  mutex6es.pass  mutex6rs.pass  & +	  mutex7.pass  mutex7n.pass  mutex7e.pass  mutex7r.pass  & +	  mutex8.pass  mutex8n.pass  mutex8e.pass  mutex8r.pass  & +	  count1.pass  once1.pass  once2.pass  once3.pass  once4.pass  tsd1.pass  & +	  self2.pass  & +	  cancel1.pass  cancel2.pass  & +	  semaphore4.pass semaphore4t.pass  & +	  delay1.pass  delay2.pass  eyal1.pass  & +	  condvar3.pass  condvar3_1.pass  condvar3_2.pass  condvar3_3.pass  & +	  condvar4.pass  condvar5.pass  condvar6.pass  & +	  condvar7.pass  condvar8.pass  condvar9.pass  & +	  errno1.pass  & +	  rwlock1.pass  rwlock2.pass  rwlock3.pass  rwlock4.pass  rwlock5.pass  & +	  rwlock6.pass  rwlock7.pass  rwlock8.pass  & +	  rwlock2_t.pass  rwlock3_t.pass  rwlock4_t.pass  rwlock5_t.pass  rwlock6_t.pass  rwlock6_t2.pass  & +	  context1.pass  & +	  cancel3.pass  cancel4.pass  cancel5.pass  cancel6a.pass  cancel6d.pass  & +	  cancel7  cancel8  & +	  cleanup0.pass  cleanup1.pass  cleanup2.pass  cleanup3.pass  & +	  priority1.pass priority2.pass inherit1.pass  & +	  spin1.pass  spin2.pass  spin3.pass  spin4.pass  & +	  barrier1.pass  barrier2.pass  barrier3.pass  barrier4.pass  barrier5.pass  & +	  exception1.pass  exception2.pass  exception3.pass  & +	  cancel9.pass + +BENCHRESULTS = & +	  benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench + +help: .SYMBOLIC +	@ $(ECHO) Run one of the following command lines: +	@ $(ECHO) wmake /f Wmakefile clean WC    (to test using WC dll with wcc386 (no EH) applications) +	@ $(ECHO) wmake /f Wmakefile clean WCX   (to test using WC dll with wpp386 (EH) applications) +	@ $(ECHO) wmake /f Wmakefile clean WCE   (to test using the WCE dll with wpp386 EH applications) +	@ $(ECHO) wmake /f Wmakefile clean WC-bench    (to benchtest using WC dll with C bench app) +	@ $(ECHO) wmake /f Wmakefile clean WCX-bench   (to benchtest using WC dll with C++ bench app) +	@ $(ECHO) wmake /f Wmakefile clean WCE-bench   (to benchtest using WCE dll with C++ bench app) + +all: .SYMBOLIC +	@ wmake /f Wmakefile clean WC +	@ wmake /f Wmakefile clean WCX +	@ wmake /f Wmakefile clean WCE +	@ wmake /f Wmakefile clean WSE +	@ wmake /f Wmakefile clean WC-bench + +tests: $(CPLIB) $(CPDLL) $(CPHDR) $(PASSES) .SYMBOLIC +	@ $(ECHO) ALL TESTS PASSED! Congratulations! + +benchtests: $(CPLIB) $(CPDLL) $(CPHDR) $(XXLIBS) $(BENCHRESULTS) .SYMBOLIC +	@ $(ECHO) ALL BENCH TESTS DONE. + +$(BENCHRESULTS): ($[*).exe +	@ $(ECHO) ... Running $(TEST) benchtest: ($[*).exe +	@ .\($[*).exe +	@ $(ECHO) ...... Done +	@ $(TOUCH) ($[*).bench + +WCE: .SYMBOLIC +	@ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCELIB)" CPDLL="$(WCEDLL)" EHFLAGS="$(WCEFLAGS)" tests + +WC: .SYMBOLIC +	@ wmake /f Wmakefile CC=wcc386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCFLAGS)" tests + +WCX: .SYMBOLIC +	@ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCXFLAGS)" tests + +WCE-bench: .SYMBOLIC +	@ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCELIB)" CPDLL="$(WCEDLL)" EHFLAGS="$(WCEFLAGS)" XXLIBS="benchlib.o" benchtests + +WC-bench: .SYMBOLIC +	@ wmake /f Wmakefile CC=wcc386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCFLAGS)" XXLIBS="benchlib.o" benchtests + +WCX-bench: .SYMBOLIC +	@ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCXFLAGS)" XXLIBS="benchlib.o" benchtests + +sizes.pass: sizes.exe +	@ $(ECHO) ... Running $(TEST) test: $^* +	@ $[@ > SIZES.$(TEST) +	@ $(CAT) SIZES.$(TEST) +	@ $(ECHO) ...... Passed +	@ $(TOUCH) $^@ + +.exe.pass: +	@ $(ECHO) ... Running $(TEST) test: $^* +	@ $[@ +	@ $(ECHO) ...... Passed +	@ $(TOUCH) $^@ + +.obj.exe: +	@ $(ECHO) wlink NAME $^@ FILE $[@ LIBRARY $(CPLIB) OPTION quiet +	@ wlink NAME $^@ FILE $[@ LIBRARY $(CPLIB) OPTION quiet + +.c.obj: +	@ $(ECHO) $(CC) $^* $(EHFLAGS) $(CFLAGS) $(INCLUDES) +	@ $(CC) $^* $(EHFLAGS) $(CFLAGS) $(INCLUDES) + +.c.i: +	@ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< + +$(COPYFILES): .SYMBOLIC +	@ $(ECHO) Copying $@ +	@ $(CP) $(BUILD_DIR)\$@ . + +pthread.dll: +	@ $(CP) $(CPDLL) $*.dll +	@ $(CP) $(CPLIB) $*.lib + +clean: .SYMBOLIC +	@ if exist *.dll $(RM) *.dll +	@ if exist *.lib $(RM) *.lib +	@ if exist *.err $(RM) *.err +	@ if exist pthread.h $(RM) pthread.h +	@ if exist semaphore.h $(RM) semaphore.h +	@ if exist sched.h $(RM) sched.h +	@ if exist *.e $(RM) *.e +	@ if exist *.i $(RM) *.i +	@ if exist *.obj $(RM) *.obj +	@ if exist *.pdb $(RM) *.pdb +	@ if exist *.o $(RM) *.o +	@ if exist *.asm $(RM) *.asm +	@ if exist *.exe $(RM) *.exe +	@ if exist *.pass $(RM) *.pass +	@ if exist *.bench $(RM) *.bench +	@ if exist *.log $(RM) *.log +	@ $(ECHO) Clean completed. + +benchtest1.bench: +benchtest2.bench: +benchtest3.bench: +benchtest4.bench: +benchtest5.bench: +barrier1.pass: +barrier2.pass: barrier1.pass +barrier3.pass: barrier2.pass +barrier4.pass: barrier3.pass +barrier5.pass: barrier4.pass +cancel1.pass: create1.pass +cancel2.pass: cancel1.pass +cancel3.pass: context1.pass +cancel4.pass: cancel3.pass +cancel5.pass: cancel3.pass +cancel6a.pass: cancel3.pass +cancel6d.pass: cancel3.pass +cancel7.pass: kill1.pass +cancel8.pass: cancel7.pass +cleanup0.pass: cancel5.pass +cleanup1.pass: cleanup0.pass +cleanup2.pass: cleanup1.pass +cleanup3.pass: cleanup2.pass +condvar1.pass: +condvar1_1.pass: condvar1.pass +condvar1_2.pass: join2.pass +condvar2.pass: condvar1.pass +condvar2_1.pass: condvar2.pass join2.pass +condvar3.pass: create1.pass condvar2.pass +condvar3_1.pass: condvar3.pass join2.pass +condvar3_2.pass: condvar3_1.pass +condvar3_3.pass: condvar3_2.pass +condvar4.pass: create1.pass +condvar5.pass: condvar4.pass +condvar6.pass: condvar5.pass +condvar7.pass: condvar6.pass cleanup1.pass +condvar8.pass: condvar7.pass +condvar9.pass: condvar8.pass +context1.pass: cancel2.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +create2.pass: create1.pass +delay1.pass: +delay2.pass: delay1.pass +equal1.pass: create1.pass +errno1.pass: mutex3.pass +exception1.pass: cancel4.pass +exception2.pass: exception1.pass +exception3.pass: exception2.pass +exit1.pass: +exit2.pass: create1.pass +exit3.pass: create1.pass +exit4.pass: +exit5.pass: kill1.pass +eyal1.pass: tsd1.pass +inherit1.pass: join1.pass priority1.pass +join0.pass: create1.pass +join1.pass: create1.pass +join2.pass: create1.pass +join3.pass: join2.pass +kill1.pass:  +loadfree.pass: pthread.dll +mutex1.pass: self1.pass +mutex1n.pass: mutex1.pass +mutex1e.pass: mutex1.pass +mutex1r.pass: mutex1.pass +mutex2.pass: mutex1.pass +mutex2r.pass: mutex2.pass +mutex2e.pass: mutex2.pass +mutex3.pass: create1.pass +mutex3r.pass: mutex3.pass +mutex3e.pass: mutex3.pass +mutex4.pass: mutex3.pass +mutex5.pass: +mutex6.pass: mutex4.pass +mutex6n.pass: mutex4.pass +mutex6e.pass: mutex4.pass +mutex6r.pass: mutex4.pass +mutex6s.pass: mutex6.pass +mutex6rs.pass: mutex6r.pass +mutex6es.pass: mutex6e.pass +mutex7.pass: mutex6.pass +mutex7n.pass: mutex6n.pass +mutex7e.pass: mutex6e.pass +mutex7r.pass: mutex6r.pass +mutex8.pass: mutex7.pass +mutex8n.pass: mutex7n.pass +mutex8e.pass: mutex7e.pass +mutex8r.pass: mutex7r.pass +once1.pass: create1.pass +once2.pass: once1.pass +once3.pass: once2.pass +once4.pass: once3.pass +priority1.pass: join1.pass +priority2.pass: priority1.pass barrier3.pass +reuse1.pass: create2.pass +reuse2.pass: reuse1.pass +rwlock1.pass: condvar6.pass +rwlock2.pass: rwlock1.pass +rwlock3.pass: rwlock2.pass +rwlock4.pass: rwlock3.pass +rwlock5.pass: rwlock4.pass +rwlock6.pass: rwlock5.pass +rwlock7.pass: rwlock6.pass +rwlock2_t.pass: rwlock2.pass +rwlock3_t.pass: rwlock2_t.pass +rwlock4_t.pass: rwlock3_t.pass +rwlock5_t.pass: rwlock4_t.pass +rwlock6_t.pass: rwlock5_t.pass +rwlock6_t2.pass: rwlock6_t.pass +self1.pass: +self2.pass: create1.pass +semaphore1.pass: +semaphore2.pass: +semaphore3.pass: semaphore2.pass +semaphore4.pass: semaphore3.pass cancel1.pass +semaphore4t.pass: semaphore4.pass +sizes.pass: +spin1.pass: +spin2.pass: spin1.pass +spin3.pass: spin2.pass +spin4.pass: spin3.pass +tsd1.pass: join1.pass +valid1.pass: join1.pass +valid2.pass: valid1.pass +cancel9.pass: cancel8.pass diff --git a/tests/benchtest1.c b/tests/benchtest1.c index da0380e..116dad0 100644 --- a/tests/benchtest1.c +++ b/tests/benchtest1.c @@ -1,249 +1,249 @@ -/*
 - * benchtest1.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * 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
 -
 -#include "benchtest.h"
 -
 -#define PTW32_MUTEX_TYPES
 -#define ITERATIONS      10000000L
 -
 -pthread_mutex_t mx;
 -pthread_mutexattr_t ma;
 -struct _timeb currSysTimeStart;
 -struct _timeb currSysTimeStop;
 -long durationMilliSecs;
 -long overHeadMilliSecs = 0;
 -int one = 1;
 -int zero = 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 PTW32_MUTEX_TYPES
 -  assert(pthread_mutexattr_settype(&ma, mType) == 0);
 -#endif
 -  assert(pthread_mutex_init(&mx, &ma) == 0);
 -
 -  TESTSTART
 -  assert(pthread_mutex_lock(&mx) == zero);
 -  assert(pthread_mutex_unlock(&mx) == zero);
 -  TESTSTOP
 -
 -  assert(pthread_mutex_destroy(&mx) == 0);
 -
 -  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
 -
 -  printf( "%-45s %15ld %15.3f\n",
 -	    testNameString,
 -          durationMilliSecs,
 -          (float) durationMilliSecs * 1E3 / ITERATIONS);
 -}
 -
 -
 -int
 -main (int argc, char *argv[])
 -{
 -  int i = 0;
 -  CRITICAL_SECTION cs;
 -  old_mutex_t ox;
 -  pthread_mutexattr_init(&ma);
 -
 -  printf( "=============================================================================\n");
 -  printf( "\nLock plus unlock on an unlocked mutex.\n%ld iterations\n\n",
 -          ITERATIONS);
 -  printf( "%-45s %15s %15s\n",
 -	    "Test",
 -	    "Total(msec)",
 -	    "average(usec)");
 -  printf( "-----------------------------------------------------------------------------\n");
 -
 -  /*
 -   * Time the loop overhead so we can subtract it from the actual test times.
 -   */
 -
 -  TESTSTART
 -  assert(1 == one);
 -  assert(1 == one);
 -  TESTSTOP
 -
 -  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
 -  overHeadMilliSecs = durationMilliSecs;
 -
 -
 -  TESTSTART
 -  assert((dummy_call(&i), 1) == one);
 -  assert((dummy_call(&i), 1) == one);
 -  TESTSTOP
 -
 -  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
 -
 -  printf( "%-45s %15ld %15.3f\n",
 -	    "Dummy call x 2",
 -          durationMilliSecs,
 -          (float) durationMilliSecs * 1E3 / ITERATIONS);
 -
 -
 -  TESTSTART
 -  assert((interlocked_inc_with_conditionals(&i), 1) == one);
 -  assert((interlocked_dec_with_conditionals(&i), 1) == one);
 -  TESTSTOP
 -
 -  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
 -
 -  printf( "%-45s %15ld %15.3f\n",
 -	    "Dummy call -> Interlocked with cond x 2",
 -          durationMilliSecs,
 -          (float) durationMilliSecs * 1E3 / ITERATIONS);
 -
 -
 -  TESTSTART
 -  assert((InterlockedIncrement((LPLONG)&i), 1) == (LONG)one);
 -  assert((InterlockedDecrement((LPLONG)&i), 1) == (LONG)one);
 -  TESTSTOP
 -
 -  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
 -
 -  printf( "%-45s %15ld %15.3f\n",
 -	    "InterlockedOp x 2",
 -          durationMilliSecs,
 -          (float) durationMilliSecs * 1E3 / ITERATIONS);
 -
 -
 -  InitializeCriticalSection(&cs);
 -
 -  TESTSTART
 -  assert((EnterCriticalSection(&cs), 1) == one);
 -  assert((LeaveCriticalSection(&cs), 1) == one);
 -  TESTSTOP
 -
 -  DeleteCriticalSection(&cs);
 -
 -  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
 -
 -  printf( "%-45s %15ld %15.3f\n",
 -	    "Simple Critical Section",
 -          durationMilliSecs,
 -          (float) durationMilliSecs * 1E3 / ITERATIONS);
 -
 -
 -  old_mutex_use = OLD_WIN32CS;
 -  assert(old_mutex_init(&ox, NULL) == 0);
 -
 -  TESTSTART
 -  assert(old_mutex_lock(&ox) == zero);
 -  assert(old_mutex_unlock(&ox) == zero);
 -  TESTSTOP
 -
 -  assert(old_mutex_destroy(&ox) == 0);
 -
 -  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
 -
 -  printf( "%-45s %15ld %15.3f\n",
 -	    "Old PT Mutex using a Critical Section (WNT)",
 -          durationMilliSecs,
 -          (float) durationMilliSecs * 1E3 / ITERATIONS);
 -
 -
 -  old_mutex_use = OLD_WIN32MUTEX;
 -  assert(old_mutex_init(&ox, NULL) == 0);
 -
 -  TESTSTART
 -  assert(old_mutex_lock(&ox) == zero);
 -  assert(old_mutex_unlock(&ox) == zero);
 -  TESTSTOP
 -
 -  assert(old_mutex_destroy(&ox) == 0);
 -
 -  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
 -
 -  printf( "%-45s %15ld %15.3f\n",
 -	    "Old PT Mutex using a Win32 Mutex (W9x)",
 -          durationMilliSecs,
 -          (float) durationMilliSecs * 1E3 / ITERATIONS);
 -
 -  printf( ".............................................................................\n");
 -
 -  /*
 -   * Now we can start the actual tests
 -   */
 -#ifdef PTW32_MUTEX_TYPES
 -  runTest("PTHREAD_MUTEX_DEFAULT (W9x,WNT)", PTHREAD_MUTEX_DEFAULT);
 -
 -  runTest("PTHREAD_MUTEX_NORMAL (W9x,WNT)", PTHREAD_MUTEX_NORMAL);
 -
 -  runTest("PTHREAD_MUTEX_ERRORCHECK (W9x,WNT)", PTHREAD_MUTEX_ERRORCHECK);
 -
 -  runTest("PTHREAD_MUTEX_RECURSIVE (W9x,WNT)", PTHREAD_MUTEX_RECURSIVE);
 -#else
 -  runTest("Non-blocking lock", 0);
 -#endif
 -
 -  printf( "=============================================================================\n");
 -
 -  /*
 -   * End of tests.
 -   */
 -
 -  pthread_mutexattr_destroy(&ma);
 -
 -  one = i; /* Dummy assignment to avoid 'variable unused' warning */
 -  return 0;
 -}
 +/* + * benchtest1.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * 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 + +#include "benchtest.h" + +#define PTW32_MUTEX_TYPES +#define ITERATIONS      10000000L + +pthread_mutex_t mx; +pthread_mutexattr_t ma; +struct _timeb currSysTimeStart; +struct _timeb currSysTimeStop; +long durationMilliSecs; +long overHeadMilliSecs = 0; +int one = 1; +int zero = 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 PTW32_MUTEX_TYPES +  assert(pthread_mutexattr_settype(&ma, mType) == 0); +#endif +  assert(pthread_mutex_init(&mx, &ma) == 0); + +  TESTSTART +  assert(pthread_mutex_lock(&mx) == zero); +  assert(pthread_mutex_unlock(&mx) == zero); +  TESTSTOP + +  assert(pthread_mutex_destroy(&mx) == 0); + +  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + +  printf( "%-45s %15ld %15.3f\n", +	    testNameString, +          durationMilliSecs, +          (float) durationMilliSecs * 1E3 / ITERATIONS); +} + + +int +main (int argc, char *argv[]) +{ +  int i = 0; +  CRITICAL_SECTION cs; +  old_mutex_t ox; +  pthread_mutexattr_init(&ma); + +  printf( "=============================================================================\n"); +  printf( "\nLock plus unlock on an unlocked mutex.\n%ld iterations\n\n", +          ITERATIONS); +  printf( "%-45s %15s %15s\n", +	    "Test", +	    "Total(msec)", +	    "average(usec)"); +  printf( "-----------------------------------------------------------------------------\n"); + +  /* +   * Time the loop overhead so we can subtract it from the actual test times. +   */ + +  TESTSTART +  assert(1 == one); +  assert(1 == one); +  TESTSTOP + +  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; +  overHeadMilliSecs = durationMilliSecs; + + +  TESTSTART +  assert((dummy_call(&i), 1) == one); +  assert((dummy_call(&i), 1) == one); +  TESTSTOP + +  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + +  printf( "%-45s %15ld %15.3f\n", +	    "Dummy call x 2", +          durationMilliSecs, +          (float) durationMilliSecs * 1E3 / ITERATIONS); + + +  TESTSTART +  assert((interlocked_inc_with_conditionals(&i), 1) == one); +  assert((interlocked_dec_with_conditionals(&i), 1) == one); +  TESTSTOP + +  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + +  printf( "%-45s %15ld %15.3f\n", +	    "Dummy call -> Interlocked with cond x 2", +          durationMilliSecs, +          (float) durationMilliSecs * 1E3 / ITERATIONS); + + +  TESTSTART +  assert((InterlockedIncrement((LPLONG)&i), 1) == (LONG)one); +  assert((InterlockedDecrement((LPLONG)&i), 1) == (LONG)one); +  TESTSTOP + +  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + +  printf( "%-45s %15ld %15.3f\n", +	    "InterlockedOp x 2", +          durationMilliSecs, +          (float) durationMilliSecs * 1E3 / ITERATIONS); + + +  InitializeCriticalSection(&cs); + +  TESTSTART +  assert((EnterCriticalSection(&cs), 1) == one); +  assert((LeaveCriticalSection(&cs), 1) == one); +  TESTSTOP + +  DeleteCriticalSection(&cs); + +  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + +  printf( "%-45s %15ld %15.3f\n", +	    "Simple Critical Section", +          durationMilliSecs, +          (float) durationMilliSecs * 1E3 / ITERATIONS); + + +  old_mutex_use = OLD_WIN32CS; +  assert(old_mutex_init(&ox, NULL) == 0); + +  TESTSTART +  assert(old_mutex_lock(&ox) == zero); +  assert(old_mutex_unlock(&ox) == zero); +  TESTSTOP + +  assert(old_mutex_destroy(&ox) == 0); + +  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + +  printf( "%-45s %15ld %15.3f\n", +	    "Old PT Mutex using a Critical Section (WNT)", +          durationMilliSecs, +          (float) durationMilliSecs * 1E3 / ITERATIONS); + + +  old_mutex_use = OLD_WIN32MUTEX; +  assert(old_mutex_init(&ox, NULL) == 0); + +  TESTSTART +  assert(old_mutex_lock(&ox) == zero); +  assert(old_mutex_unlock(&ox) == zero); +  TESTSTOP + +  assert(old_mutex_destroy(&ox) == 0); + +  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + +  printf( "%-45s %15ld %15.3f\n", +	    "Old PT Mutex using a Win32 Mutex (W9x)", +          durationMilliSecs, +          (float) durationMilliSecs * 1E3 / ITERATIONS); + +  printf( ".............................................................................\n"); + +  /* +   * Now we can start the actual tests +   */ +#ifdef PTW32_MUTEX_TYPES +  runTest("PTHREAD_MUTEX_DEFAULT (W9x,WNT)", PTHREAD_MUTEX_DEFAULT); + +  runTest("PTHREAD_MUTEX_NORMAL (W9x,WNT)", PTHREAD_MUTEX_NORMAL); + +  runTest("PTHREAD_MUTEX_ERRORCHECK (W9x,WNT)", PTHREAD_MUTEX_ERRORCHECK); + +  runTest("PTHREAD_MUTEX_RECURSIVE (W9x,WNT)", PTHREAD_MUTEX_RECURSIVE); +#else +  runTest("Non-blocking lock", 0); +#endif + +  printf( "=============================================================================\n"); + +  /* +   * End of tests. +   */ + +  pthread_mutexattr_destroy(&ma); + +  one = i; /* Dummy assignment to avoid 'variable unused' warning */ +  return 0; +} diff --git a/tests/benchtest5.c b/tests/benchtest5.c index 2fba9e3..7700fde 100644 --- a/tests/benchtest5.c +++ b/tests/benchtest5.c @@ -1,159 +1,159 @@ -/*
 - * benchtest5.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * Measure time taken to complete an elementary operation.
 - *
 - * - Semaphore
 - *   Single thread iteration over post/wait for a semaphore.
 - */
 -
 -#include "test.h"
 -#include <sys/timeb.h>
 -
 -#ifdef __GNUC__
 -#include <stdlib.h>
 -#endif
 -
 -#include "benchtest.h"
 -
 -#define ITERATIONS      1000000L
 -
 -sem_t sema;
 -HANDLE w32sema;
 -
 -struct _timeb currSysTimeStart;
 -struct _timeb currSysTimeStop;
 -long durationMilliSecs;
 -long overHeadMilliSecs = 0;
 -int one = 1;
 -int zero = 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
 -reportTest (char * testNameString)
 -{
 -  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
 -
 -  printf( "%-45s %15ld %15.3f\n",
 -	    testNameString,
 -          durationMilliSecs,
 -          (float) durationMilliSecs * 1E3 / ITERATIONS);
 -}
 -
 -
 -int
 -main (int argc, char *argv[])
 -{
 -  printf( "=============================================================================\n");
 -  printf( "\nOperations on a semaphore.\n%ld iterations\n\n",
 -          ITERATIONS);
 -  printf( "%-45s %15s %15s\n",
 -	    "Test",
 -	    "Total(msec)",
 -	    "average(usec)");
 -  printf( "-----------------------------------------------------------------------------\n");
 -
 -  /*
 -   * Time the loop overhead so we can subtract it from the actual test times.
 -   */
 -
 -  TESTSTART
 -  assert(1 == one);
 -  TESTSTOP
 -
 -  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
 -  overHeadMilliSecs = durationMilliSecs;
 -
 -
 -  /*
 -   * Now we can start the actual tests
 -   */
 -  assert((w32sema = CreateSemaphore(NULL, (long) 0, (long) ITERATIONS, NULL)) != 0);
 -  TESTSTART
 -  assert(ReleaseSemaphore(w32sema, 1, NULL) != zero);
 -  TESTSTOP
 -  assert(CloseHandle(w32sema) != 0);
 -
 -  reportTest("W32 Post with no waiters");
 -
 -
 -  assert((w32sema = CreateSemaphore(NULL, (long) ITERATIONS, (long) ITERATIONS, NULL)) != 0);
 -  TESTSTART
 -  assert(WaitForSingleObject(w32sema, INFINITE) == WAIT_OBJECT_0);
 -  TESTSTOP
 -  assert(CloseHandle(w32sema) != 0);
 -
 -  reportTest("W32 Wait without blocking");
 -
 -
 -  assert(sem_init(&sema, 0, 0) == 0);
 -  TESTSTART
 -  assert(sem_post(&sema) == zero);
 -  TESTSTOP
 -  assert(sem_destroy(&sema) == 0);
 -
 -  reportTest("POSIX Post with no waiters");
 -
 -
 -  assert(sem_init(&sema, 0, ITERATIONS) == 0);
 -  TESTSTART
 -  assert(sem_wait(&sema) == zero);
 -  TESTSTOP
 -  assert(sem_destroy(&sema) == 0);
 -
 -  reportTest("POSIX Wait without blocking");
 -
 -
 -  printf( "=============================================================================\n");
 -
 -  /*
 -   * End of tests.
 -   */
 -
 -  return 0;
 -}
 +/* + * benchtest5.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Measure time taken to complete an elementary operation. + * + * - Semaphore + *   Single thread iteration over post/wait for a semaphore. + */ + +#include "test.h" +#include <sys/timeb.h> + +#ifdef __GNUC__ +#include <stdlib.h> +#endif + +#include "benchtest.h" + +#define ITERATIONS      1000000L + +sem_t sema; +HANDLE w32sema; + +struct _timeb currSysTimeStart; +struct _timeb currSysTimeStop; +long durationMilliSecs; +long overHeadMilliSecs = 0; +int one = 1; +int zero = 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 +reportTest (char * testNameString) +{ +  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + +  printf( "%-45s %15ld %15.3f\n", +	    testNameString, +          durationMilliSecs, +          (float) durationMilliSecs * 1E3 / ITERATIONS); +} + + +int +main (int argc, char *argv[]) +{ +  printf( "=============================================================================\n"); +  printf( "\nOperations on a semaphore.\n%ld iterations\n\n", +          ITERATIONS); +  printf( "%-45s %15s %15s\n", +	    "Test", +	    "Total(msec)", +	    "average(usec)"); +  printf( "-----------------------------------------------------------------------------\n"); + +  /* +   * Time the loop overhead so we can subtract it from the actual test times. +   */ + +  TESTSTART +  assert(1 == one); +  TESTSTOP + +  durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; +  overHeadMilliSecs = durationMilliSecs; + + +  /* +   * Now we can start the actual tests +   */ +  assert((w32sema = CreateSemaphore(NULL, (long) 0, (long) ITERATIONS, NULL)) != 0); +  TESTSTART +  assert(ReleaseSemaphore(w32sema, 1, NULL) != zero); +  TESTSTOP +  assert(CloseHandle(w32sema) != 0); + +  reportTest("W32 Post with no waiters"); + + +  assert((w32sema = CreateSemaphore(NULL, (long) ITERATIONS, (long) ITERATIONS, NULL)) != 0); +  TESTSTART +  assert(WaitForSingleObject(w32sema, INFINITE) == WAIT_OBJECT_0); +  TESTSTOP +  assert(CloseHandle(w32sema) != 0); + +  reportTest("W32 Wait without blocking"); + + +  assert(sem_init(&sema, 0, 0) == 0); +  TESTSTART +  assert(sem_post(&sema) == zero); +  TESTSTOP +  assert(sem_destroy(&sema) == 0); + +  reportTest("POSIX Post with no waiters"); + + +  assert(sem_init(&sema, 0, ITERATIONS) == 0); +  TESTSTART +  assert(sem_wait(&sema) == zero); +  TESTSTOP +  assert(sem_destroy(&sema) == 0); + +  reportTest("POSIX Wait without blocking"); + + +  printf( "=============================================================================\n"); + +  /* +   * End of tests. +   */ + +  return 0; +} diff --git a/tests/condvar3.c b/tests/condvar3.c index 60cd0e7..e3a23f5 100644 --- a/tests/condvar3.c +++ b/tests/condvar3.c @@ -1,148 +1,148 @@ -/*
 - * File: condvar3.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * Test Synopsis:
 - * - Test basic function of a CV
 - *
 - * Test Method (Validation or Falsification):
 - * - Validation
 - *
 - * Requirements Tested:
 - * - 
 - *
 - * Features Tested:
 - * - 
 - *
 - * Cases Tested:
 - * - 
 - *
 - * Description:
 - * - The primary thread takes the lock before creating any threads.
 - *   The secondary thread blocks on the lock allowing the primary
 - *   thread to enter the cv wait state which releases the lock.
 - *   The secondary thread then takes the lock and signals the waiting
 - *   primary thread.
 - *
 - * Environment:
 - * - 
 - *
 - * Input:
 - * - None.
 - *
 - * Output:
 - * - File name, Line number, and failed expression on failure.
 - * - No output on success.
 - *
 - * Assumptions:
 - * - 
 - *
 - * Pass Criteria:
 - * - pthread_cond_timedwait returns 0.
 - * - Process returns zero exit status.
 - *
 - * Fail Criteria:
 - * - pthread_cond_timedwait returns ETIMEDOUT.
 - * - Process returns non-zero exit status.
 - */
 -
 -#include "test.h"
 -#include <sys/timeb.h>
 -
 -static pthread_cond_t cv;
 -static pthread_mutex_t mutex;
 -static int shared = 0;
 -
 -enum {
 -  NUMTHREADS = 2         /* Including the primary thread. */
 -};
 -
 -void *
 -mythread(void * arg)
 -{
 -  int result = 0;
 -
 -  assert(pthread_mutex_lock(&mutex) == 0);
 -  shared++;
 -  assert(pthread_mutex_unlock(&mutex) == 0);
 -
 -  if ((result = pthread_cond_signal(&cv)) != 0)
 -    {
 -      printf("Error = %s\n", error_string[result]);
 -    }
 -  assert(result == 0);
 -
 -
 -  return (void *) 0;
 -}
 -
 -int
 -main()
 -{
 -  pthread_t t[NUMTHREADS];
 -  struct timespec abstime = { 0, 0 };
 -  struct _timeb currSysTime;
 -  const DWORD NANOSEC_PER_MILLISEC = 1000000;
 -
 -  assert((t[0] = pthread_self()).p != NULL);
 -
 -  assert(pthread_cond_init(&cv, NULL) == 0);
 -
 -  assert(pthread_mutex_init(&mutex, NULL) == 0);
 -
 -  assert(pthread_mutex_lock(&mutex) == 0);
 -
 -  /* get current system time */
 -  _ftime(&currSysTime);
 -
 -  abstime.tv_sec = currSysTime.time;
 -  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
 -
 -  assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0);
 -
 -  abstime.tv_sec += 5;
 -
 -  while (! (shared > 0))
 -    assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == 0);
 -
 -  assert(shared > 0);
 -
 -  assert(pthread_mutex_unlock(&mutex) == 0);
 -
 -  assert(pthread_join(t[1], NULL) == 0);
 -
 -  assert(pthread_cond_destroy(&cv) == 0);
 -
 -  return 0;
 -}
 +/* + * File: condvar3.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test basic function of a CV + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * -  + * + * Features Tested: + * -  + * + * Cases Tested: + * -  + * + * Description: + * - The primary thread takes the lock before creating any threads. + *   The secondary thread blocks on the lock allowing the primary + *   thread to enter the cv wait state which releases the lock. + *   The secondary thread then takes the lock and signals the waiting + *   primary thread. + * + * Environment: + * -  + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * -  + * + * Pass Criteria: + * - pthread_cond_timedwait returns 0. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#include "test.h" +#include <sys/timeb.h> + +static pthread_cond_t cv; +static pthread_mutex_t mutex; +static int shared = 0; + +enum { +  NUMTHREADS = 2         /* Including the primary thread. */ +}; + +void * +mythread(void * arg) +{ +  int result = 0; + +  assert(pthread_mutex_lock(&mutex) == 0); +  shared++; +  assert(pthread_mutex_unlock(&mutex) == 0); + +  if ((result = pthread_cond_signal(&cv)) != 0) +    { +      printf("Error = %s\n", error_string[result]); +    } +  assert(result == 0); + + +  return (void *) 0; +} + +int +main() +{ +  pthread_t t[NUMTHREADS]; +  struct timespec abstime = { 0, 0 }; +  struct _timeb currSysTime; +  const DWORD NANOSEC_PER_MILLISEC = 1000000; + +  assert((t[0] = pthread_self()).p != NULL); + +  assert(pthread_cond_init(&cv, NULL) == 0); + +  assert(pthread_mutex_init(&mutex, NULL) == 0); + +  assert(pthread_mutex_lock(&mutex) == 0); + +  /* get current system time */ +  _ftime(&currSysTime); + +  abstime.tv_sec = currSysTime.time; +  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + +  assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); + +  abstime.tv_sec += 5; + +  while (! (shared > 0)) +    assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == 0); + +  assert(shared > 0); + +  assert(pthread_mutex_unlock(&mutex) == 0); + +  assert(pthread_join(t[1], NULL) == 0); + +  assert(pthread_cond_destroy(&cv) == 0); + +  return 0; +} diff --git a/tests/condvar3_1.c b/tests/condvar3_1.c index 369c07c..25a50e4 100644 --- a/tests/condvar3_1.c +++ b/tests/condvar3_1.c @@ -1,201 +1,201 @@ -/*
 - * File: condvar3_1.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * Test Synopsis:
 - * - Test timeout of multiple waits on a CV with some signaled.
 - *
 - * Test Method (Validation or Falsification):
 - * - Validation
 - *
 - * Requirements Tested:
 - * - 
 - *
 - * Features Tested:
 - * - 
 - *
 - * Cases Tested:
 - * - 
 - *
 - * Description:
 - * - Because some CVs are never signaled, we expect their waits to time out.
 - *   Some are signaled, the rest time out. Pthread_cond_destroy() will fail
 - *   unless all are accounted for, either signaled or timedout.
 - *
 - * Environment:
 - * -
 - *
 - * Input:
 - * - None.
 - *
 - * Output:
 - * - File name, Line number, and failed expression on failure.
 - * - No output on success.
 - *
 - * Assumptions:
 - * - 
 - *
 - * Pass Criteria:
 - * - pthread_cond_timedwait returns ETIMEDOUT.
 - * - Process returns zero exit status.
 - *
 - * Fail Criteria:
 - * - pthread_cond_timedwait does not return ETIMEDOUT.
 - * - Process returns non-zero exit status.
 - */
 -
 -#define _WIN32_WINNT 0x400
 -
 -#include "test.h"
 -#include <sys/timeb.h>
 -
 -static pthread_cond_t cv;
 -static pthread_cond_t cv1;
 -static pthread_mutex_t mutex;
 -static pthread_mutex_t mutex1;
 -static struct timespec abstime = { 0, 0 };
 -static int timedout = 0;
 -static int signaled = 0;
 -static int awoken = 0;
 -static int waiting = 0;
 -
 -enum {
 -  NUMTHREADS = 30
 -};
 -
 -void *
 -mythread(void * arg)
 -{
 -  int result;
 -
 -  assert(pthread_mutex_lock(&mutex1) == 0);
 -  ++waiting;
 -  assert(pthread_mutex_unlock(&mutex1) == 0);
 -  assert(pthread_cond_signal(&cv1) == 0);
 -
 -  assert(pthread_mutex_lock(&mutex) == 0);
 -  result = pthread_cond_timedwait(&cv, &mutex, &abstime);
 -  if (result == ETIMEDOUT)
 -    {
 -      timedout++;
 -    }
 -  else
 -    {
 -      awoken++;
 -    }
 -  assert(pthread_mutex_unlock(&mutex) == 0);
 -
 -  return arg;
 -}
 -
 -#include "../implement.h"
 -
 -int
 -main()
 -{
 -  int i;
 -  pthread_t t[NUMTHREADS + 1];
 -  int result = 0;
 -  struct _timeb currSysTime;
 -  const DWORD NANOSEC_PER_MILLISEC = 1000000;
 -
 -  assert(pthread_cond_init(&cv, NULL) == 0);
 -  assert(pthread_cond_init(&cv1, NULL) == 0);
 -
 -  assert(pthread_mutex_init(&mutex, NULL) == 0);
 -  assert(pthread_mutex_init(&mutex1, NULL) == 0);
 -
 -  /* get current system time */
 -  _ftime(&currSysTime);
 -
 -  abstime.tv_sec = currSysTime.time;
 -  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
 -
 -  abstime.tv_sec += 5;
 -
 -  assert(pthread_mutex_lock(&mutex1) == 0);
 -
 -  for (i = 1; i <= NUMTHREADS; i++)
 -    {
 -      assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0);
 -    }
 -
 -  do {
 -    assert(pthread_cond_wait(&cv1,&mutex1) == 0);
 -  } while ( NUMTHREADS > waiting );
 -
 -  assert(pthread_mutex_unlock(&mutex1) == 0);
 -
 -  for (i = NUMTHREADS/3; i <= 2*NUMTHREADS/3; i++)
 -    {
 -//      assert(pthread_mutex_lock(&mutex) == 0);
 -      assert(pthread_cond_signal(&cv) == 0);
 -//      assert(pthread_mutex_unlock(&mutex) == 0);
 -
 -      signaled++;
 -    }
 -
 -  for (i = 1; i <= NUMTHREADS; i++)
 -    {
 -      assert(pthread_join(t[i], (void **) &result) == 0);
 -        assert(result == i);
 -    }
 -
 -      fprintf(stderr, "awk = %d\n", awoken);
 -      fprintf(stderr, "sig = %d\n", signaled);
 -      fprintf(stderr, "tot = %d\n", timedout);
 -
 -  assert(signaled == awoken);
 -  assert(timedout == NUMTHREADS - signaled);
 -
 -  assert(pthread_cond_destroy(&cv1) == 0);
 -
 -  {
 -  int result = pthread_cond_destroy(&cv);
 -  if (result != 0)
 -    {
 -      fprintf(stderr, "Result = %s\n", error_string[result]);
 -        fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked);
 -        fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone);
 -        fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock);
 -        fflush(stderr);
 -    }
 -  assert(result == 0);
 -  }
 -
 -  assert(pthread_mutex_destroy(&mutex1) == 0);
 -  assert(pthread_mutex_destroy(&mutex) == 0);
 -
 -  return 0;
 -}
 +/* + * File: condvar3_1.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test timeout of multiple waits on a CV with some signaled. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * -  + * + * Features Tested: + * -  + * + * Cases Tested: + * -  + * + * Description: + * - Because some CVs are never signaled, we expect their waits to time out. + *   Some are signaled, the rest time out. Pthread_cond_destroy() will fail + *   unless all are accounted for, either signaled or timedout. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * -  + * + * Pass Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait does not return ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#define _WIN32_WINNT 0x400 + +#include "test.h" +#include <sys/timeb.h> + +static pthread_cond_t cv; +static pthread_cond_t cv1; +static pthread_mutex_t mutex; +static pthread_mutex_t mutex1; +static struct timespec abstime = { 0, 0 }; +static int timedout = 0; +static int signaled = 0; +static int awoken = 0; +static int waiting = 0; + +enum { +  NUMTHREADS = 30 +}; + +void * +mythread(void * arg) +{ +  int result; + +  assert(pthread_mutex_lock(&mutex1) == 0); +  ++waiting; +  assert(pthread_mutex_unlock(&mutex1) == 0); +  assert(pthread_cond_signal(&cv1) == 0); + +  assert(pthread_mutex_lock(&mutex) == 0); +  result = pthread_cond_timedwait(&cv, &mutex, &abstime); +  if (result == ETIMEDOUT) +    { +      timedout++; +    } +  else +    { +      awoken++; +    } +  assert(pthread_mutex_unlock(&mutex) == 0); + +  return arg; +} + +#include "../implement.h" + +int +main() +{ +  int i; +  pthread_t t[NUMTHREADS + 1]; +  int result = 0; +  struct _timeb currSysTime; +  const DWORD NANOSEC_PER_MILLISEC = 1000000; + +  assert(pthread_cond_init(&cv, NULL) == 0); +  assert(pthread_cond_init(&cv1, NULL) == 0); + +  assert(pthread_mutex_init(&mutex, NULL) == 0); +  assert(pthread_mutex_init(&mutex1, NULL) == 0); + +  /* get current system time */ +  _ftime(&currSysTime); + +  abstime.tv_sec = currSysTime.time; +  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + +  abstime.tv_sec += 5; + +  assert(pthread_mutex_lock(&mutex1) == 0); + +  for (i = 1; i <= NUMTHREADS; i++) +    { +      assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0); +    } + +  do { +    assert(pthread_cond_wait(&cv1,&mutex1) == 0); +  } while ( NUMTHREADS > waiting ); + +  assert(pthread_mutex_unlock(&mutex1) == 0); + +  for (i = NUMTHREADS/3; i <= 2*NUMTHREADS/3; i++) +    { +//      assert(pthread_mutex_lock(&mutex) == 0); +      assert(pthread_cond_signal(&cv) == 0); +//      assert(pthread_mutex_unlock(&mutex) == 0); + +      signaled++; +    } + +  for (i = 1; i <= NUMTHREADS; i++) +    { +      assert(pthread_join(t[i], (void **) &result) == 0); +        assert(result == i); +    } + +      fprintf(stderr, "awk = %d\n", awoken); +      fprintf(stderr, "sig = %d\n", signaled); +      fprintf(stderr, "tot = %d\n", timedout); + +  assert(signaled == awoken); +  assert(timedout == NUMTHREADS - signaled); + +  assert(pthread_cond_destroy(&cv1) == 0); + +  { +  int result = pthread_cond_destroy(&cv); +  if (result != 0) +    { +      fprintf(stderr, "Result = %s\n", error_string[result]); +        fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); +        fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); +        fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); +        fflush(stderr); +    } +  assert(result == 0); +  } + +  assert(pthread_mutex_destroy(&mutex1) == 0); +  assert(pthread_mutex_destroy(&mutex) == 0); + +  return 0; +} diff --git a/tests/condvar3_2.c b/tests/condvar3_2.c index c9d58ad..5ddcf57 100644 --- a/tests/condvar3_2.c +++ b/tests/condvar3_2.c @@ -1,193 +1,193 @@ -/*
 - * File: condvar3_2.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * Test Synopsis:
 - * - Test timeout of multiple waits on a CV with remainder broadcast awoken.
 - *
 - * Test Method (Validation or Falsification):
 - * - Validation
 - *
 - * Requirements Tested:
 - * - 
 - *
 - * Features Tested:
 - * - 
 - *
 - * Cases Tested:
 - * - 
 - *
 - * Description:
 - * - Because some CVs are never signaled, we expect their waits to time out.
 - *   Some time out, the rest are broadcast signaled. Pthread_cond_destroy() will fail
 - *   unless all are accounted for, either signaled or timedout.
 - *
 - * Environment:
 - * -
 - *
 - * Input:
 - * - None.
 - *
 - * Output:
 - * - File name, Line number, and failed expression on failure.
 - * - No output on success.
 - *
 - * Assumptions:
 - * - 
 - *
 - * Pass Criteria:
 - * - pthread_cond_timedwait returns ETIMEDOUT.
 - * - Process returns zero exit status.
 - *
 - * Fail Criteria:
 - * - pthread_cond_timedwait does not return ETIMEDOUT.
 - * - Process returns non-zero exit status.
 - */
 -
 -#define _WIN32_WINNT 0x400
 -
 -#include "test.h"
 -#include <sys/timeb.h>
 -
 -static pthread_cond_t cv;
 -static pthread_mutex_t mutex;
 -static struct timespec abstime = { 0, 0 };
 -static struct timespec abstime2 = { 0, 0 };
 -static int timedout = 0;
 -static int awoken = 0;
 -
 -enum {
 -  NUMTHREADS = 30
 -};
 -
 -void *
 -mythread(void * arg)
 -{
 -  int result;
 -
 -  assert(pthread_mutex_lock(&mutex) == 0);
 -
 -  abstime2.tv_sec = abstime.tv_sec;
 -
 -  if ((int) arg % 3 == 0)
 -    {
 -      abstime2.tv_sec += 2;
 -    }
 -
 -  result = pthread_cond_timedwait(&cv, &mutex, &abstime2);
 -  assert(pthread_mutex_unlock(&mutex) == 0);
 -  if (result == ETIMEDOUT)
 -    {
 -      InterlockedIncrement((LPLONG)&timedout);
 -    }
 -  else
 -    {
 -      InterlockedIncrement((LPLONG)&awoken);
 -    }
 -
 -
 -  return arg;
 -}
 -
 -#include "../implement.h"
 -
 -int
 -main()
 -{
 -  int i;
 -  pthread_t t[NUMTHREADS + 1];
 -  int result = 0;
 -  struct _timeb currSysTime;
 -  const DWORD NANOSEC_PER_MILLISEC = 1000000;
 -
 -  assert(pthread_cond_init(&cv, NULL) == 0);
 -
 -  assert(pthread_mutex_init(&mutex, NULL) == 0);
 -
 -  /* get current system time */
 -  _ftime(&currSysTime);
 -
 -  abstime.tv_sec = abstime.tv_sec = currSysTime.time + 5;
 -  abstime.tv_nsec = abstime2.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
 -
 -  assert(pthread_mutex_lock(&mutex) == 0);
 -
 -  for (i = 1; i <= NUMTHREADS; i++)
 -    {
 -      assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0);
 -    }
 -
 -  assert(pthread_mutex_unlock(&mutex) == 0);
 -
 -  for (i = 1; i <= NUMTHREADS; i++)
 -    {
 -      assert(pthread_join(t[i], (void **) &result) == 0);
 -	assert(result == i);
 -      /*
 -       * Approximately 2/3rds of the threads are expected to time out.
 -       * Signal the remainder after some threads have woken up and exited
 -       * and while some are still waking up after timeout.
 -       * Also tests that redundant broadcasts don't return errors.
 -       */
 -
 -//      assert(pthread_mutex_lock(&mutex) == 0);
 -
 -      if (InterlockedExchangeAdd((LPLONG)&awoken, 0L) > NUMTHREADS/3)
 -        {
 -          assert(pthread_cond_broadcast(&cv) == 0);
 -        }
 -
 -//      assert(pthread_mutex_unlock(&mutex) == 0);
 -
 -    }
 -
 -  assert(awoken == NUMTHREADS - timedout);
 -
 -  {
 -  int result = pthread_cond_destroy(&cv);
 -  if (result != 0)
 -    {
 -      fprintf(stderr, "Result = %s\n", error_string[result]);
 -	fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked);
 -	fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone);
 -	fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock);
 -	fflush(stderr);
 -    }
 -  assert(result == 0);
 -  }
 -
 -  assert(pthread_mutex_destroy(&mutex) == 0);
 -
 -  return 0;
 -}
 +/* + * File: condvar3_2.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test timeout of multiple waits on a CV with remainder broadcast awoken. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * -  + * + * Features Tested: + * -  + * + * Cases Tested: + * -  + * + * Description: + * - Because some CVs are never signaled, we expect their waits to time out. + *   Some time out, the rest are broadcast signaled. Pthread_cond_destroy() will fail + *   unless all are accounted for, either signaled or timedout. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * -  + * + * Pass Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait does not return ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#define _WIN32_WINNT 0x400 + +#include "test.h" +#include <sys/timeb.h> + +static pthread_cond_t cv; +static pthread_mutex_t mutex; +static struct timespec abstime = { 0, 0 }; +static struct timespec abstime2 = { 0, 0 }; +static int timedout = 0; +static int awoken = 0; + +enum { +  NUMTHREADS = 30 +}; + +void * +mythread(void * arg) +{ +  int result; + +  assert(pthread_mutex_lock(&mutex) == 0); + +  abstime2.tv_sec = abstime.tv_sec; + +  if ((int) arg % 3 == 0) +    { +      abstime2.tv_sec += 2; +    } + +  result = pthread_cond_timedwait(&cv, &mutex, &abstime2); +  assert(pthread_mutex_unlock(&mutex) == 0); +  if (result == ETIMEDOUT) +    { +      InterlockedIncrement((LPLONG)&timedout); +    } +  else +    { +      InterlockedIncrement((LPLONG)&awoken); +    } + + +  return arg; +} + +#include "../implement.h" + +int +main() +{ +  int i; +  pthread_t t[NUMTHREADS + 1]; +  int result = 0; +  struct _timeb currSysTime; +  const DWORD NANOSEC_PER_MILLISEC = 1000000; + +  assert(pthread_cond_init(&cv, NULL) == 0); + +  assert(pthread_mutex_init(&mutex, NULL) == 0); + +  /* get current system time */ +  _ftime(&currSysTime); + +  abstime.tv_sec = abstime.tv_sec = currSysTime.time + 5; +  abstime.tv_nsec = abstime2.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + +  assert(pthread_mutex_lock(&mutex) == 0); + +  for (i = 1; i <= NUMTHREADS; i++) +    { +      assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0); +    } + +  assert(pthread_mutex_unlock(&mutex) == 0); + +  for (i = 1; i <= NUMTHREADS; i++) +    { +      assert(pthread_join(t[i], (void **) &result) == 0); +	assert(result == i); +      /* +       * Approximately 2/3rds of the threads are expected to time out. +       * Signal the remainder after some threads have woken up and exited +       * and while some are still waking up after timeout. +       * Also tests that redundant broadcasts don't return errors. +       */ + +//      assert(pthread_mutex_lock(&mutex) == 0); + +      if (InterlockedExchangeAdd((LPLONG)&awoken, 0L) > NUMTHREADS/3) +        { +          assert(pthread_cond_broadcast(&cv) == 0); +        } + +//      assert(pthread_mutex_unlock(&mutex) == 0); + +    } + +  assert(awoken == NUMTHREADS - timedout); + +  { +  int result = pthread_cond_destroy(&cv); +  if (result != 0) +    { +      fprintf(stderr, "Result = %s\n", error_string[result]); +	fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); +	fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); +	fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); +	fflush(stderr); +    } +  assert(result == 0); +  } + +  assert(pthread_mutex_destroy(&mutex) == 0); + +  return 0; +} diff --git a/tests/condvar3_3.c b/tests/condvar3_3.c index 840a83b..fe67632 100644 --- a/tests/condvar3_3.c +++ b/tests/condvar3_3.c @@ -1,132 +1,132 @@ -/*
 - * File: condvar3_3.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * Test Synopsis:
 - * - Test timeouts and lost signals on a CV.
 - *
 - * Test Method (Validation or Falsification):
 - * - Validation
 - *
 - * 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:
 - * - pthread_cond_timedwait returns ETIMEDOUT.
 - * - Process returns zero exit status.
 - *
 - * Fail Criteria:
 - * - pthread_cond_timedwait does not return ETIMEDOUT.
 - * - Process returns non-zero exit status.
 - */
 -
 -/* Timur Aydin (taydin@snet.net) */
 -
 -#include "test.h"
 -
 -#include <sys/timeb.h>
 -
 -pthread_cond_t cnd;
 -pthread_mutex_t mtx;
 -
 -int main()
 -{
 -   int rc;
 -
 -   struct timespec abstime = { 0, 0 };
 -   struct _timeb currSysTime;
 -   const DWORD NANOSEC_PER_MILLISEC = 1000000;
 -
 -   assert(pthread_cond_init(&cnd, 0) == 0);
 -   assert(pthread_mutex_init(&mtx, 0) == 0);
 -
 -   /* get current system time */
 -   _ftime(&currSysTime);
 -
 -   abstime.tv_sec = currSysTime.time;
 -   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
 -   abstime.tv_sec += 1;
 -
 -   /* Here pthread_cond_timedwait should time out after one second. */
 -
 -   assert(pthread_mutex_lock(&mtx) == 0);
 -
 -   assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT);
 -
 -   assert(pthread_mutex_unlock(&mtx) == 0);
 -
 -   /* Here, the condition variable is signaled, but there are no
 -      threads waiting on it. The signal should be lost and
 -      the next pthread_cond_timedwait should time out too. */
 -
 -//   assert(pthread_mutex_lock(&mtx) == 0);
 -
 -   assert((rc = pthread_cond_signal(&cnd)) == 0);
 -
 -//   assert(pthread_mutex_unlock(&mtx) == 0);
 -
 -   assert(pthread_mutex_lock(&mtx) == 0);
 -
 -   abstime.tv_sec = currSysTime.time;
 -   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
 -   abstime.tv_sec += 1;
 -
 -   assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT);
 -
 -   assert(pthread_mutex_unlock(&mtx) == 0);
 -
 -   return 0;
 -}
 +/* + * File: condvar3_3.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test timeouts and lost signals on a CV. + * + * Test Method (Validation or Falsification): + * - Validation + * + * 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: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait does not return ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +/* Timur Aydin (taydin@snet.net) */ + +#include "test.h" + +#include <sys/timeb.h> + +pthread_cond_t cnd; +pthread_mutex_t mtx; + +int main() +{ +   int rc; + +   struct timespec abstime = { 0, 0 }; +   struct _timeb currSysTime; +   const DWORD NANOSEC_PER_MILLISEC = 1000000; + +   assert(pthread_cond_init(&cnd, 0) == 0); +   assert(pthread_mutex_init(&mtx, 0) == 0); + +   /* get current system time */ +   _ftime(&currSysTime); + +   abstime.tv_sec = currSysTime.time; +   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; +   abstime.tv_sec += 1; + +   /* Here pthread_cond_timedwait should time out after one second. */ + +   assert(pthread_mutex_lock(&mtx) == 0); + +   assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT); + +   assert(pthread_mutex_unlock(&mtx) == 0); + +   /* Here, the condition variable is signaled, but there are no +      threads waiting on it. The signal should be lost and +      the next pthread_cond_timedwait should time out too. */ + +//   assert(pthread_mutex_lock(&mtx) == 0); + +   assert((rc = pthread_cond_signal(&cnd)) == 0); + +//   assert(pthread_mutex_unlock(&mtx) == 0); + +   assert(pthread_mutex_lock(&mtx) == 0); + +   abstime.tv_sec = currSysTime.time; +   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; +   abstime.tv_sec += 1; + +   assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT); + +   assert(pthread_mutex_unlock(&mtx) == 0); + +   return 0; +} diff --git a/tests/condvar4.c b/tests/condvar4.c index 89fa855..3babeea 100644 --- a/tests/condvar4.c +++ b/tests/condvar4.c @@ -1,169 +1,169 @@ -/*
 - * File: condvar4.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * Test Synopsis:
 - * - Test PTHREAD_COND_INITIALIZER.
 - *
 - * Test Method (Validation or Falsification):
 - * - Validation
 - *
 - * Requirements Tested:
 - * - 
 - *
 - * Features Tested:
 - * - 
 - *
 - * Cases Tested:
 - * - 
 - *
 - * Description:
 - * - Test basic CV function but starting with a static initialised
 - *   CV.
 - *
 - * Environment:
 - * - 
 - *
 - * Input:
 - * - None.
 - *
 - * Output:
 - * - File name, Line number, and failed expression on failure.
 - * - No output on success.
 - *
 - * Assumptions:
 - * - 
 - *
 - * Pass Criteria:
 - * - pthread_cond_timedwait returns 0.
 - * - Process returns zero exit status.
 - *
 - * Fail Criteria:
 - * - pthread_cond_timedwait returns ETIMEDOUT.
 - * - Process returns non-zero exit status.
 - */
 -
 -#include "test.h"
 -#include <sys/timeb.h>
 -
 -typedef struct cvthing_t_ cvthing_t;
 -
 -struct cvthing_t_ {
 -  pthread_cond_t notbusy;
 -  pthread_mutex_t lock;
 -  int shared;
 -};
 -
 -static cvthing_t cvthing = {
 -  PTHREAD_COND_INITIALIZER,
 -  PTHREAD_MUTEX_INITIALIZER,
 -  0
 -};
 -
 -enum {
 -  NUMTHREADS = 2
 -};
 -
 -void *
 -mythread(void * arg)
 -{
 -  assert(pthread_mutex_lock(&cvthing.lock) == 0);
 -  cvthing.shared++;
 -  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
 -
 -  assert(pthread_cond_signal(&cvthing.notbusy) == 0);
 -
 -  return (void *) 0;
 -}
 -
 -int
 -main()
 -{
 -  pthread_t t[NUMTHREADS];
 -  struct timespec abstime = { 0, 0 };
 -  struct _timeb currSysTime;
 -  const DWORD NANOSEC_PER_MILLISEC = 1000000;
 -
 -  cvthing.shared = 0;
 -
 -  assert((t[0] = pthread_self()).p != NULL);
 -
 -  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
 -
 -  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
 -
 -  assert(pthread_mutex_lock(&cvthing.lock) == 0);
 -
 -  assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER);
 -
 -  /* get current system time */
 -  _ftime(&currSysTime);
 -
 -  abstime.tv_sec = currSysTime.time;
 -  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
 -
 -  abstime.tv_sec += 5;
 -
 -  assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT);
 -  
 -  assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER);
 -
 -  assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0);
 -
 -  _ftime(&currSysTime);
 -
 -  abstime.tv_sec = currSysTime.time;
 -  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
 -
 -  abstime.tv_sec += 5;
 -
 -  while (! (cvthing.shared > 0))
 -    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
 -
 -  assert(cvthing.shared > 0);
 -
 -  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
 -
 -  assert(pthread_join(t[1], NULL) == 0);
 -
 -  assert(pthread_mutex_destroy(&cvthing.lock) == 0);
 -
 -  assert(cvthing.lock == NULL);
 -
 -  assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
 -
 -  assert(cvthing.notbusy == NULL);
 -
 -  return 0;
 -}
 +/* + * File: condvar4.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test PTHREAD_COND_INITIALIZER. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * -  + * + * Features Tested: + * -  + * + * Cases Tested: + * -  + * + * Description: + * - Test basic CV function but starting with a static initialised + *   CV. + * + * Environment: + * -  + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * -  + * + * Pass Criteria: + * - pthread_cond_timedwait returns 0. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#include "test.h" +#include <sys/timeb.h> + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ { +  pthread_cond_t notbusy; +  pthread_mutex_t lock; +  int shared; +}; + +static cvthing_t cvthing = { +  PTHREAD_COND_INITIALIZER, +  PTHREAD_MUTEX_INITIALIZER, +  0 +}; + +enum { +  NUMTHREADS = 2 +}; + +void * +mythread(void * arg) +{ +  assert(pthread_mutex_lock(&cvthing.lock) == 0); +  cvthing.shared++; +  assert(pthread_mutex_unlock(&cvthing.lock) == 0); + +  assert(pthread_cond_signal(&cvthing.notbusy) == 0); + +  return (void *) 0; +} + +int +main() +{ +  pthread_t t[NUMTHREADS]; +  struct timespec abstime = { 0, 0 }; +  struct _timeb currSysTime; +  const DWORD NANOSEC_PER_MILLISEC = 1000000; + +  cvthing.shared = 0; + +  assert((t[0] = pthread_self()).p != NULL); + +  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + +  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + +  assert(pthread_mutex_lock(&cvthing.lock) == 0); + +  assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER); + +  /* get current system time */ +  _ftime(&currSysTime); + +  abstime.tv_sec = currSysTime.time; +  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + +  abstime.tv_sec += 5; + +  assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT); +   +  assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER); + +  assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); + +  _ftime(&currSysTime); + +  abstime.tv_sec = currSysTime.time; +  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + +  abstime.tv_sec += 5; + +  while (! (cvthing.shared > 0)) +    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + +  assert(cvthing.shared > 0); + +  assert(pthread_mutex_unlock(&cvthing.lock) == 0); + +  assert(pthread_join(t[1], NULL) == 0); + +  assert(pthread_mutex_destroy(&cvthing.lock) == 0); + +  assert(cvthing.lock == NULL); + +  assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + +  assert(cvthing.notbusy == NULL); + +  return 0; +} diff --git a/tests/condvar5.c b/tests/condvar5.c index 4836676..4d51f39 100644 --- a/tests/condvar5.c +++ b/tests/condvar5.c @@ -1,168 +1,168 @@ -/*
 - * File: condvar5.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * Test Synopsis:
 - * - Test pthread_cond_broadcast.
 - *
 - * Test Method (Validation or Falsification):
 - * - Validation
 - *
 - * Requirements Tested:
 - * - 
 - *
 - * Features Tested:
 - * - 
 - *
 - * Cases Tested:
 - * - 
 - *
 - * Description:
 - * - Test broadcast with one waiting CV.
 - *
 - * Environment:
 - * - 
 - *
 - * Input:
 - * - None.
 - *
 - * Output:
 - * - File name, Line number, and failed expression on failure.
 - * - No output on success.
 - *
 - * Assumptions:
 - * - 
 - *
 - * Pass Criteria:
 - * - pthread_cond_timedwait returns 0.
 - * - Process returns zero exit status.
 - *
 - * Fail Criteria:
 - * - pthread_cond_timedwait returns ETIMEDOUT.
 - * - Process returns non-zero exit status.
 - */
 -
 -#include "test.h"
 -#include <sys/timeb.h>
 -
 -typedef struct cvthing_t_ cvthing_t;
 -
 -struct cvthing_t_ {
 -  pthread_cond_t notbusy;
 -  pthread_mutex_t lock;
 -  int shared;
 -};
 -
 -static cvthing_t cvthing = {
 -  PTHREAD_COND_INITIALIZER,
 -  PTHREAD_MUTEX_INITIALIZER,
 -  0
 -};
 -
 -enum {
 -  NUMTHREADS = 2
 -};
 -
 -void *
 -mythread(void * arg)
 -{
 -  assert(pthread_mutex_lock(&cvthing.lock) == 0);
 -  cvthing.shared++;
 -  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
 -
 -  assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
 -
 -  return (void *) 0;
 -}
 -
 -int
 -main()
 -{
 -  pthread_t t[NUMTHREADS];
 -  struct timespec abstime = { 0, 0 };
 -  struct _timeb currSysTime;
 -  const DWORD NANOSEC_PER_MILLISEC = 1000000;
 -
 -  cvthing.shared = 0;
 -
 -  assert((t[0] = pthread_self()).p != NULL);
 -
 -  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
 -
 -  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
 -
 -  assert(pthread_mutex_lock(&cvthing.lock) == 0);
 -
 -  assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER);
 -
 -  /* get current system time */
 -  _ftime(&currSysTime);
 -
 -  abstime.tv_sec = currSysTime.time;
 -  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
 -
 -  abstime.tv_sec += 5;
 -
 -  assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT);
 -  
 -  assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER);
 -
 -  assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0);
 -
 -  _ftime(&currSysTime);
 -
 -  abstime.tv_sec = currSysTime.time;
 -  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
 -
 -  abstime.tv_sec += 5;
 -
 -  while (! (cvthing.shared > 0))
 -    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
 -
 -  assert(cvthing.shared > 0);
 -
 -  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
 -
 -  assert(pthread_join(t[1], NULL) == 0);
 -
 -  assert(pthread_mutex_destroy(&cvthing.lock) == 0);
 -
 -  assert(cvthing.lock == NULL);
 -
 -  assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
 -
 -  assert(cvthing.notbusy == NULL);
 -
 -  return 0;
 -}
 +/* + * File: condvar5.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test pthread_cond_broadcast. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * -  + * + * Features Tested: + * -  + * + * Cases Tested: + * -  + * + * Description: + * - Test broadcast with one waiting CV. + * + * Environment: + * -  + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * -  + * + * Pass Criteria: + * - pthread_cond_timedwait returns 0. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#include "test.h" +#include <sys/timeb.h> + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ { +  pthread_cond_t notbusy; +  pthread_mutex_t lock; +  int shared; +}; + +static cvthing_t cvthing = { +  PTHREAD_COND_INITIALIZER, +  PTHREAD_MUTEX_INITIALIZER, +  0 +}; + +enum { +  NUMTHREADS = 2 +}; + +void * +mythread(void * arg) +{ +  assert(pthread_mutex_lock(&cvthing.lock) == 0); +  cvthing.shared++; +  assert(pthread_mutex_unlock(&cvthing.lock) == 0); + +  assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + +  return (void *) 0; +} + +int +main() +{ +  pthread_t t[NUMTHREADS]; +  struct timespec abstime = { 0, 0 }; +  struct _timeb currSysTime; +  const DWORD NANOSEC_PER_MILLISEC = 1000000; + +  cvthing.shared = 0; + +  assert((t[0] = pthread_self()).p != NULL); + +  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + +  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + +  assert(pthread_mutex_lock(&cvthing.lock) == 0); + +  assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER); + +  /* get current system time */ +  _ftime(&currSysTime); + +  abstime.tv_sec = currSysTime.time; +  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + +  abstime.tv_sec += 5; + +  assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT); +   +  assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER); + +  assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); + +  _ftime(&currSysTime); + +  abstime.tv_sec = currSysTime.time; +  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + +  abstime.tv_sec += 5; + +  while (! (cvthing.shared > 0)) +    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + +  assert(cvthing.shared > 0); + +  assert(pthread_mutex_unlock(&cvthing.lock) == 0); + +  assert(pthread_join(t[1], NULL) == 0); + +  assert(pthread_mutex_destroy(&cvthing.lock) == 0); + +  assert(cvthing.lock == NULL); + +  assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + +  assert(cvthing.notbusy == NULL); + +  return 0; +} diff --git a/tests/condvar6.c b/tests/condvar6.c index 1cb1d9e..e63132c 100644 --- a/tests/condvar6.c +++ b/tests/condvar6.c @@ -1,242 +1,242 @@ -/*
 - * File: condvar6.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * Test Synopsis:
 - * - Test pthread_cond_broadcast.
 - *
 - * Test Method (Validation or Falsification):
 - * - Validation
 - *
 - * Requirements Tested:
 - * - 
 - *
 - * Features Tested:
 - * - 
 - *
 - * Cases Tested:
 - * - 
 - *
 - * Description:
 - * - Test broadcast with NUMTHREADS (=5) waiting CVs.
 - *
 - * 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"
 -#include <sys/timeb.h>
 -
 -/*
 - * Create NUMTHREADS threads in addition to the Main thread.
 - */
 -enum {
 -  NUMTHREADS = 5
 -};
 -
 -typedef struct bag_t_ bag_t;
 -struct bag_t_ {
 -  int threadnum;
 -  int started;
 -  /* Add more per-thread state variables here */
 -};
 -
 -static bag_t threadbag[NUMTHREADS + 1];
 -
 -typedef struct cvthing_t_ cvthing_t;
 -
 -struct cvthing_t_ {
 -  pthread_cond_t notbusy;
 -  pthread_mutex_t lock;
 -  int shared;
 -};
 -
 -static cvthing_t cvthing = {
 -  PTHREAD_COND_INITIALIZER,
 -  PTHREAD_MUTEX_INITIALIZER,
 -  0
 -};
 -
 -static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER;
 -
 -static struct timespec abstime = { 0, 0 };
 -
 -static int awoken;
 -
 -void *
 -mythread(void * arg)
 -{
 -  bag_t * bag = (bag_t *) arg;
 -
 -  assert(bag == &threadbag[bag->threadnum]);
 -  assert(bag->started == 0);
 -  bag->started = 1;
 -
 -  /* Wait for the start gun */
 -  assert(pthread_mutex_lock(&start_flag) == 0);
 -  assert(pthread_mutex_unlock(&start_flag) == 0);
 -
 -  assert(pthread_mutex_lock(&cvthing.lock) == 0);
 -
 -  while (! (cvthing.shared > 0))
 -    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
 -
 -  assert(cvthing.shared > 0);
 -
 -  awoken++;
 -
 -  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
 -
 -  return (void *) 0;
 -}
 -
 -int
 -main()
 -{
 -  int failed = 0;
 -  int i;
 -  pthread_t t[NUMTHREADS + 1];
 -
 -  struct _timeb currSysTime;
 -  const DWORD NANOSEC_PER_MILLISEC = 1000000;
 -
 -  cvthing.shared = 0;
 -
 -  assert((t[0] = pthread_self()).p != NULL);
 -
 -  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
 -
 -  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
 -
 -  assert(pthread_mutex_lock(&start_flag) == 0);
 -
 -  _ftime(&currSysTime);
 -
 -  abstime.tv_sec = currSysTime.time;
 -  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
 -
 -  abstime.tv_sec += 5;
 -
 -  assert((t[0] = pthread_self()).p != NULL);
 -
 -  awoken = 0;
 -
 -  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.
 -   */
 -
 -  assert(pthread_mutex_unlock(&start_flag) == 0);
 -
 -  /*
 -   * Give threads time to start.
 -   */
 -  Sleep(1000);
 -
 -  assert(pthread_mutex_lock(&cvthing.lock) == 0);
 -  cvthing.shared++;
 -  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
 -
 -  assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
 -
 -  /*
 -   * Give threads time to complete.
 -   */
 -  for (i = 1; i <= NUMTHREADS; i++)
 -    {
 -      assert(pthread_join(t[i], NULL) == 0);
 -    }
 -
 -  /* 
 -   * Cleanup the CV.
 -   */
 -  
 -  assert(pthread_mutex_destroy(&cvthing.lock) == 0);
 -
 -  assert(cvthing.lock == NULL);
 -
 -  assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
 -
 -  assert(cvthing.notbusy == NULL);
 -
 -  /*
 -   * Standard check that all threads started.
 -   */
 -  for (i = 1; i <= NUMTHREADS; i++)
 -    { 
 -      failed = !threadbag[i].started;
 -
 -      if (failed)
 -	{
 -	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
 -	}
 -    }
 -
 -  assert(!failed);
 -
 -  /*
 -   * Check any results here.
 -   */
 -
 -  assert(awoken == NUMTHREADS);
 -
 -  /*
 -   * Success.
 -   */
 -  return 0;
 -}
 -
 -
 +/* + * File: condvar6.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test pthread_cond_broadcast. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * -  + * + * Features Tested: + * -  + * + * Cases Tested: + * -  + * + * Description: + * - Test broadcast with NUMTHREADS (=5) waiting CVs. + * + * 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" +#include <sys/timeb.h> + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { +  NUMTHREADS = 5 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { +  int threadnum; +  int started; +  /* Add more per-thread state variables here */ +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ { +  pthread_cond_t notbusy; +  pthread_mutex_t lock; +  int shared; +}; + +static cvthing_t cvthing = { +  PTHREAD_COND_INITIALIZER, +  PTHREAD_MUTEX_INITIALIZER, +  0 +}; + +static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; + +static struct timespec abstime = { 0, 0 }; + +static int awoken; + +void * +mythread(void * arg) +{ +  bag_t * bag = (bag_t *) arg; + +  assert(bag == &threadbag[bag->threadnum]); +  assert(bag->started == 0); +  bag->started = 1; + +  /* Wait for the start gun */ +  assert(pthread_mutex_lock(&start_flag) == 0); +  assert(pthread_mutex_unlock(&start_flag) == 0); + +  assert(pthread_mutex_lock(&cvthing.lock) == 0); + +  while (! (cvthing.shared > 0)) +    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + +  assert(cvthing.shared > 0); + +  awoken++; + +  assert(pthread_mutex_unlock(&cvthing.lock) == 0); + +  return (void *) 0; +} + +int +main() +{ +  int failed = 0; +  int i; +  pthread_t t[NUMTHREADS + 1]; + +  struct _timeb currSysTime; +  const DWORD NANOSEC_PER_MILLISEC = 1000000; + +  cvthing.shared = 0; + +  assert((t[0] = pthread_self()).p != NULL); + +  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + +  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + +  assert(pthread_mutex_lock(&start_flag) == 0); + +  _ftime(&currSysTime); + +  abstime.tv_sec = currSysTime.time; +  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + +  abstime.tv_sec += 5; + +  assert((t[0] = pthread_self()).p != NULL); + +  awoken = 0; + +  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. +   */ + +  assert(pthread_mutex_unlock(&start_flag) == 0); + +  /* +   * Give threads time to start. +   */ +  Sleep(1000); + +  assert(pthread_mutex_lock(&cvthing.lock) == 0); +  cvthing.shared++; +  assert(pthread_mutex_unlock(&cvthing.lock) == 0); + +  assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + +  /* +   * Give threads time to complete. +   */ +  for (i = 1; i <= NUMTHREADS; i++) +    { +      assert(pthread_join(t[i], NULL) == 0); +    } + +  /*  +   * Cleanup the CV. +   */ +   +  assert(pthread_mutex_destroy(&cvthing.lock) == 0); + +  assert(cvthing.lock == NULL); + +  assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + +  assert(cvthing.notbusy == NULL); + +  /* +   * Standard check that all threads started. +   */ +  for (i = 1; i <= NUMTHREADS; i++) +    {  +      failed = !threadbag[i].started; + +      if (failed) +	{ +	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); +	} +    } + +  assert(!failed); + +  /* +   * Check any results here. +   */ + +  assert(awoken == NUMTHREADS); + +  /* +   * Success. +   */ +  return 0; +} + + diff --git a/tests/condvar7.c b/tests/condvar7.c index 696a18e..6d89f2e 100644 --- a/tests/condvar7.c +++ b/tests/condvar7.c @@ -1,257 +1,257 @@ -/*
 - * File: condvar7.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * Test Synopsis:
 - * - Test pthread_cond_broadcast with thread cancelation.
 - *
 - * Test Method (Validation or Falsification):
 - * - Validation
 - *
 - * Requirements Tested:
 - * - 
 - *
 - * Features Tested:
 - * - 
 - *
 - * Cases Tested:
 - * - 
 - *
 - * Description:
 - * - Test broadcast with NUMTHREADS (=5) waiting CVs, one is canceled while waiting.
 - *
 - * 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"
 -#include <sys/timeb.h>
 -
 -/*
 - * Create NUMTHREADS threads in addition to the Main thread.
 - */
 -enum {
 -  NUMTHREADS = 5
 -};
 -
 -typedef struct bag_t_ bag_t;
 -struct bag_t_ {
 -  int threadnum;
 -  int started;
 -  /* Add more per-thread state variables here */
 -};
 -
 -static bag_t threadbag[NUMTHREADS + 1];
 -
 -typedef struct cvthing_t_ cvthing_t;
 -
 -struct cvthing_t_ {
 -  pthread_cond_t notbusy;
 -  pthread_mutex_t lock;
 -  int shared;
 -};
 -
 -static cvthing_t cvthing = {
 -  PTHREAD_COND_INITIALIZER,
 -  PTHREAD_MUTEX_INITIALIZER,
 -  0
 -};
 -
 -static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER;
 -
 -static struct timespec abstime = { 0, 0 };
 -
 -static int awoken;
 -
 -void *
 -mythread(void * arg)
 -{
 -  bag_t * bag = (bag_t *) arg;
 -
 -  assert(bag == &threadbag[bag->threadnum]);
 -  assert(bag->started == 0);
 -  bag->started = 1;
 -
 -  /* Wait for the start gun */
 -  assert(pthread_mutex_lock(&start_flag) == 0);
 -  assert(pthread_mutex_unlock(&start_flag) == 0);
 -
 -  assert(pthread_mutex_lock(&cvthing.lock) == 0);
 -
 -#ifdef _MSC_VER
 -#pragma inline_depth(0)
 -#endif
 -  pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock);
 -
 -  while (! (cvthing.shared > 0))
 -    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
 -
 -  pthread_cleanup_pop(0);
 -#ifdef _MSC_VER
 -#pragma inline_depth()
 -#endif
 -
 -  assert(cvthing.shared > 0);
 -
 -  awoken++;
 -
 -  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
 -
 -  return (void *) 0;
 -}
 -
 -int
 -main()
 -{
 -  int failed = 0;
 -  int i;
 -  pthread_t t[NUMTHREADS + 1];
 -
 -  struct _timeb currSysTime;
 -  const DWORD NANOSEC_PER_MILLISEC = 1000000;
 -
 -  cvthing.shared = 0;
 -
 -  assert((t[0] = pthread_self()).p != NULL);
 -
 -  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
 -
 -  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
 -
 -  assert(pthread_mutex_lock(&start_flag) == 0);
 -
 -  _ftime(&currSysTime);
 -
 -  abstime.tv_sec = currSysTime.time;
 -  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
 -
 -  abstime.tv_sec += 10;
 -
 -  assert((t[0] = pthread_self()).p != NULL);
 -
 -  awoken = 0;
 -
 -  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.
 -   */
 -
 -  assert(pthread_mutex_unlock(&start_flag) == 0);
 -
 -  /*
 -   * Give threads time to start.
 -   */
 -  Sleep(1000);
 -
 -  /*
 -   * Cancel one of the threads.
 -   */
 -  assert(pthread_cancel(t[1]) == 0);
 -  assert(pthread_join(t[1], NULL) == 0);
 -
 -  assert(pthread_mutex_lock(&cvthing.lock) == 0);
 -  cvthing.shared++;
 -  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
 -
 -  /*
 -   * Signal all remaining waiting threads.
 -   */
 -  assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
 -
 -  /*
 -   * Wait for all threads to complete.
 -   */
 -  for (i = 2; i <= NUMTHREADS; i++)
 -    assert(pthread_join(t[i], NULL) == 0);
 -
 -  /* 
 -   * Cleanup the CV.
 -   */
 -  
 -  assert(pthread_mutex_destroy(&cvthing.lock) == 0);
 -
 -  assert(cvthing.lock == NULL);
 -
 -  assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
 -
 -  assert(cvthing.notbusy == NULL);
 -
 -  /*
 -   * Standard check that all threads started.
 -   */
 -  for (i = 1; i <= NUMTHREADS; i++)
 -    { 
 -      failed = !threadbag[i].started;
 -
 -      if (failed)
 -	{
 -	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
 -	}
 -    }
 -
 -  assert(!failed);
 -
 -  /*
 -   * Check any results here.
 -   */
 -
 -  assert(awoken == (NUMTHREADS - 1));
 -
 -  /*
 -   * Success.
 -   */
 -  return 0;
 -}
 +/* + * File: condvar7.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test pthread_cond_broadcast with thread cancelation. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * -  + * + * Features Tested: + * -  + * + * Cases Tested: + * -  + * + * Description: + * - Test broadcast with NUMTHREADS (=5) waiting CVs, one is canceled while waiting. + * + * 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" +#include <sys/timeb.h> + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { +  NUMTHREADS = 5 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { +  int threadnum; +  int started; +  /* Add more per-thread state variables here */ +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ { +  pthread_cond_t notbusy; +  pthread_mutex_t lock; +  int shared; +}; + +static cvthing_t cvthing = { +  PTHREAD_COND_INITIALIZER, +  PTHREAD_MUTEX_INITIALIZER, +  0 +}; + +static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; + +static struct timespec abstime = { 0, 0 }; + +static int awoken; + +void * +mythread(void * arg) +{ +  bag_t * bag = (bag_t *) arg; + +  assert(bag == &threadbag[bag->threadnum]); +  assert(bag->started == 0); +  bag->started = 1; + +  /* Wait for the start gun */ +  assert(pthread_mutex_lock(&start_flag) == 0); +  assert(pthread_mutex_unlock(&start_flag) == 0); + +  assert(pthread_mutex_lock(&cvthing.lock) == 0); + +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif +  pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock); + +  while (! (cvthing.shared > 0)) +    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + +  pthread_cleanup_pop(0); +#ifdef _MSC_VER +#pragma inline_depth() +#endif + +  assert(cvthing.shared > 0); + +  awoken++; + +  assert(pthread_mutex_unlock(&cvthing.lock) == 0); + +  return (void *) 0; +} + +int +main() +{ +  int failed = 0; +  int i; +  pthread_t t[NUMTHREADS + 1]; + +  struct _timeb currSysTime; +  const DWORD NANOSEC_PER_MILLISEC = 1000000; + +  cvthing.shared = 0; + +  assert((t[0] = pthread_self()).p != NULL); + +  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + +  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + +  assert(pthread_mutex_lock(&start_flag) == 0); + +  _ftime(&currSysTime); + +  abstime.tv_sec = currSysTime.time; +  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + +  abstime.tv_sec += 10; + +  assert((t[0] = pthread_self()).p != NULL); + +  awoken = 0; + +  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. +   */ + +  assert(pthread_mutex_unlock(&start_flag) == 0); + +  /* +   * Give threads time to start. +   */ +  Sleep(1000); + +  /* +   * Cancel one of the threads. +   */ +  assert(pthread_cancel(t[1]) == 0); +  assert(pthread_join(t[1], NULL) == 0); + +  assert(pthread_mutex_lock(&cvthing.lock) == 0); +  cvthing.shared++; +  assert(pthread_mutex_unlock(&cvthing.lock) == 0); + +  /* +   * Signal all remaining waiting threads. +   */ +  assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + +  /* +   * Wait for all threads to complete. +   */ +  for (i = 2; i <= NUMTHREADS; i++) +    assert(pthread_join(t[i], NULL) == 0); + +  /*  +   * Cleanup the CV. +   */ +   +  assert(pthread_mutex_destroy(&cvthing.lock) == 0); + +  assert(cvthing.lock == NULL); + +  assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + +  assert(cvthing.notbusy == NULL); + +  /* +   * Standard check that all threads started. +   */ +  for (i = 1; i <= NUMTHREADS; i++) +    {  +      failed = !threadbag[i].started; + +      if (failed) +	{ +	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); +	} +    } + +  assert(!failed); + +  /* +   * Check any results here. +   */ + +  assert(awoken == (NUMTHREADS - 1)); + +  /* +   * Success. +   */ +  return 0; +} diff --git a/tests/condvar8.c b/tests/condvar8.c index 890970e..e384a1c 100644 --- a/tests/condvar8.c +++ b/tests/condvar8.c @@ -1,258 +1,258 @@ -/*
 - * File: condvar8.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * Test Synopsis:
 - * - Test multiple pthread_cond_broadcasts.
 - *
 - * Test Method (Validation or Falsification):
 - * - Validation
 - *
 - * Requirements Tested:
 - * - 
 - *
 - * Features Tested:
 - * - 
 - *
 - * Cases Tested:
 - * - 
 - *
 - * Description:
 - * - Make NUMTHREADS threads wait on CV, broadcast signal them, and then repeat.
 - *
 - * 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"
 -#include <sys/timeb.h>
 -
 -/*
 - * Create NUMTHREADS threads in addition to the Main thread.
 - */
 -enum {
 -  NUMTHREADS = 5
 -};
 -
 -typedef struct bag_t_ bag_t;
 -struct bag_t_ {
 -  int threadnum;
 -  int started;
 -  /* Add more per-thread state variables here */
 -};
 -
 -static bag_t threadbag[NUMTHREADS + 1];
 -
 -typedef struct cvthing_t_ cvthing_t;
 -
 -struct cvthing_t_ {
 -  pthread_cond_t notbusy;
 -  pthread_mutex_t lock;
 -  int shared;
 -};
 -
 -static cvthing_t cvthing = {
 -  PTHREAD_COND_INITIALIZER,
 -  PTHREAD_MUTEX_INITIALIZER,
 -  0
 -};
 -
 -static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER;
 -
 -static struct timespec abstime = { 0, 0 };
 -
 -static int awoken;
 -
 -static void *
 -mythread(void * arg)
 -{
 -  bag_t * bag = (bag_t *) arg;
 -
 -  assert(bag == &threadbag[bag->threadnum]);
 -  assert(bag->started == 0);
 -  bag->started = 1;
 -
 -  /* Wait for the start gun */
 -  assert(pthread_mutex_lock(&start_flag) == 0);
 -  assert(pthread_mutex_unlock(&start_flag) == 0);
 -
 -  assert(pthread_mutex_lock(&cvthing.lock) == 0);
 -
 -#ifdef _MSC_VER
 -#pragma inline_depth(0)
 -#endif
 -  pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock);
 -
 -  while (! (cvthing.shared > 0))
 -    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
 -
 -  pthread_cleanup_pop(0);
 -#ifdef _MSC_VER
 -#pragma inline_depth()
 -#endif
 -
 -  assert(cvthing.shared > 0);
 -
 -  awoken++;
 -
 -  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
 -
 -  return (void *) 0;
 -}
 -
 -int
 -main()
 -{
 -  int failed = 0;
 -  int i;
 -  int first, last;
 -  pthread_t t[NUMTHREADS + 1];
 -
 -  struct _timeb currSysTime;
 -  const DWORD NANOSEC_PER_MILLISEC = 1000000;
 -
 -  assert((t[0] = pthread_self()).p != NULL);
 -
 -  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
 -
 -  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
 -
 -  _ftime(&currSysTime);
 -
 -  abstime.tv_sec = currSysTime.time;
 -  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
 -
 -  abstime.tv_sec += 10;
 -
 -  assert((t[0] = pthread_self()).p != NULL);
 -
 -  awoken = 0;
 -
 -  for (first = 1, last = NUMTHREADS / 2;
 -       first < NUMTHREADS;
 -       first = last + 1, last = NUMTHREADS)
 -    {
 -      assert(pthread_mutex_lock(&start_flag) == 0);
 -
 -      for (i = first; i <= last; 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.
 -       */
 -      cvthing.shared = 0;
 -
 -      assert(pthread_mutex_unlock(&start_flag) == 0);
 -
 -      /*
 -       * Give threads time to start.
 -       */
 -      Sleep(100);
 -
 -      assert(pthread_mutex_lock(&cvthing.lock) == 0);
 -      cvthing.shared++;
 -      assert(pthread_mutex_unlock(&cvthing.lock) == 0);
 -
 -      assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
 -
 -      /*
 -       * Give threads time to complete.
 -       */
 -      for (i = first; i <= last; i++)
 -	{
 -	  assert(pthread_join(t[i], NULL) == 0);
 -	}
 -
 -      assert(awoken == (i - 1));
 -    }
 -
 -
 -  /*
 -   * Standard check that all threads started.
 -   */
 -  for (i = 1; i <= NUMTHREADS; i++)
 -    { 
 -      failed = !threadbag[i].started;
 -
 -      if (failed)
 -	{
 -	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
 -	}
 -    }
 -
 -  /* 
 -   * Cleanup the CV.
 -   */
 -  
 -  assert(pthread_mutex_destroy(&cvthing.lock) == 0);
 -
 -  assert(cvthing.lock == NULL);
 -
 -  assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
 -
 -  assert(cvthing.notbusy == NULL);
 -
 -  assert(!failed);
 -
 -  /*
 -   * Check any results here.
 -   */
 -
 -  assert(awoken == NUMTHREADS);
 -
 -  /*
 -   * Success.
 -   */
 -  return 0;
 -}
 +/* + * File: condvar8.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test multiple pthread_cond_broadcasts. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * -  + * + * Features Tested: + * -  + * + * Cases Tested: + * -  + * + * Description: + * - Make NUMTHREADS threads wait on CV, broadcast signal them, and then repeat. + * + * 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" +#include <sys/timeb.h> + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { +  NUMTHREADS = 5 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { +  int threadnum; +  int started; +  /* Add more per-thread state variables here */ +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ { +  pthread_cond_t notbusy; +  pthread_mutex_t lock; +  int shared; +}; + +static cvthing_t cvthing = { +  PTHREAD_COND_INITIALIZER, +  PTHREAD_MUTEX_INITIALIZER, +  0 +}; + +static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; + +static struct timespec abstime = { 0, 0 }; + +static int awoken; + +static void * +mythread(void * arg) +{ +  bag_t * bag = (bag_t *) arg; + +  assert(bag == &threadbag[bag->threadnum]); +  assert(bag->started == 0); +  bag->started = 1; + +  /* Wait for the start gun */ +  assert(pthread_mutex_lock(&start_flag) == 0); +  assert(pthread_mutex_unlock(&start_flag) == 0); + +  assert(pthread_mutex_lock(&cvthing.lock) == 0); + +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif +  pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock); + +  while (! (cvthing.shared > 0)) +    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + +  pthread_cleanup_pop(0); +#ifdef _MSC_VER +#pragma inline_depth() +#endif + +  assert(cvthing.shared > 0); + +  awoken++; + +  assert(pthread_mutex_unlock(&cvthing.lock) == 0); + +  return (void *) 0; +} + +int +main() +{ +  int failed = 0; +  int i; +  int first, last; +  pthread_t t[NUMTHREADS + 1]; + +  struct _timeb currSysTime; +  const DWORD NANOSEC_PER_MILLISEC = 1000000; + +  assert((t[0] = pthread_self()).p != NULL); + +  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + +  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + +  _ftime(&currSysTime); + +  abstime.tv_sec = currSysTime.time; +  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + +  abstime.tv_sec += 10; + +  assert((t[0] = pthread_self()).p != NULL); + +  awoken = 0; + +  for (first = 1, last = NUMTHREADS / 2; +       first < NUMTHREADS; +       first = last + 1, last = NUMTHREADS) +    { +      assert(pthread_mutex_lock(&start_flag) == 0); + +      for (i = first; i <= last; 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. +       */ +      cvthing.shared = 0; + +      assert(pthread_mutex_unlock(&start_flag) == 0); + +      /* +       * Give threads time to start. +       */ +      Sleep(100); + +      assert(pthread_mutex_lock(&cvthing.lock) == 0); +      cvthing.shared++; +      assert(pthread_mutex_unlock(&cvthing.lock) == 0); + +      assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + +      /* +       * Give threads time to complete. +       */ +      for (i = first; i <= last; i++) +	{ +	  assert(pthread_join(t[i], NULL) == 0); +	} + +      assert(awoken == (i - 1)); +    } + + +  /* +   * Standard check that all threads started. +   */ +  for (i = 1; i <= NUMTHREADS; i++) +    {  +      failed = !threadbag[i].started; + +      if (failed) +	{ +	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); +	} +    } + +  /*  +   * Cleanup the CV. +   */ +   +  assert(pthread_mutex_destroy(&cvthing.lock) == 0); + +  assert(cvthing.lock == NULL); + +  assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + +  assert(cvthing.notbusy == NULL); + +  assert(!failed); + +  /* +   * Check any results here. +   */ + +  assert(awoken == NUMTHREADS); + +  /* +   * Success. +   */ +  return 0; +} diff --git a/tests/condvar9.c b/tests/condvar9.c index 6610af7..c751271 100644 --- a/tests/condvar9.c +++ b/tests/condvar9.c @@ -1,267 +1,267 @@ -/*
 - * File: condvar9.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * Test Synopsis:
 - * - Test multiple pthread_cond_broadcasts with thread cancelation.
 - *
 - * Test Method (Validation or Falsification):
 - * - Validation
 - *
 - * Requirements Tested:
 - * - 
 - *
 - * Features Tested:
 - * - 
 - *
 - * Cases Tested:
 - * - 
 - *
 - * Description:
 - * - Make NUMTHREADS threads wait on CV, cancel one, broadcast signal them,
 - *   and then repeat.
 - *
 - * 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"
 -#include <sys/timeb.h>
 -
 -/*
 - * Create NUMTHREADS threads in addition to the Main thread.
 - */
 -enum {
 -  NUMTHREADS = 9
 -};
 -
 -typedef struct bag_t_ bag_t;
 -struct bag_t_ {
 -  int threadnum;
 -  int started;
 -  int finished;
 -  /* Add more per-thread state variables here */
 -};
 -
 -static bag_t threadbag[NUMTHREADS + 1];
 -
 -typedef struct cvthing_t_ cvthing_t;
 -
 -struct cvthing_t_ {
 -  pthread_cond_t notbusy;
 -  pthread_mutex_t lock;
 -  int shared;
 -};
 -
 -static cvthing_t cvthing = {
 -  PTHREAD_COND_INITIALIZER,
 -  PTHREAD_MUTEX_INITIALIZER,
 -  0
 -};
 -
 -static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER;
 -
 -static struct timespec abstime = { 0, 0 };
 -
 -static int awoken;
 -
 -static void *
 -mythread(void * arg)
 -{
 -  bag_t * bag = (bag_t *) arg;
 -
 -  assert(bag == &threadbag[bag->threadnum]);
 -  assert(bag->started == 0);
 -  bag->started = 1;
 -
 -  /* Wait for the start gun */
 -  assert(pthread_mutex_lock(&start_flag) == 0);
 -  assert(pthread_mutex_unlock(&start_flag) == 0);
 -
 -  assert(pthread_mutex_lock(&cvthing.lock) == 0);
 -
 -  /*
 -   * pthread_cond_timedwait is a cancelation point and we're
 -   * going to cancel some threads deliberately.
 -   */
 -#ifdef _MSC_VER
 -#pragma inline_depth(0)
 -#endif
 -  pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock);
 -
 -  while (! (cvthing.shared > 0))
 -    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
 -
 -  pthread_cleanup_pop(0);
 -#ifdef _MSC_VER
 -#pragma inline_depth()
 -#endif
 -
 -  assert(cvthing.shared > 0);
 -
 -  awoken++;
 -  bag->finished = 1;
 -
 -  assert(pthread_mutex_unlock(&cvthing.lock) == 0);
 -
 -  return (void *) 0;
 -}
 -
 -int
 -main()
 -{
 -  int failed = 0;
 -  int i;
 -  int first, last;
 -  int canceledThreads = 0;
 -  pthread_t t[NUMTHREADS + 1];
 -
 -  struct _timeb currSysTime;
 -  const DWORD NANOSEC_PER_MILLISEC = 1000000;
 -
 -  assert((t[0] = pthread_self()).p != NULL);
 -
 -  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
 -
 -  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
 -
 -  _ftime(&currSysTime);
 -
 -  abstime.tv_sec = currSysTime.time;
 -  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
 -
 -  abstime.tv_sec += 5;
 -
 -  assert((t[0] = pthread_self()).p != NULL);
 -
 -  awoken = 0;
 -
 -  for (first = 1, last = NUMTHREADS / 2;
 -       first < NUMTHREADS;
 -       first = last + 1, last = NUMTHREADS)
 -    {
 -      int ct;
 -
 -      assert(pthread_mutex_lock(&start_flag) == 0);
 -
 -      for (i = first; i <= last; i++)
 -	{
 -	  threadbag[i].started = threadbag[i].finished = 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.
 -       */
 -      cvthing.shared = 0;
 -
 -      assert(pthread_mutex_unlock(&start_flag) == 0);
 -
 -      /*
 -       * Give threads time to start.
 -       */
 -      Sleep(1000);
 -
 -      ct = (first + last) / 2;
 -      assert(pthread_cancel(t[ct]) == 0);
 -      canceledThreads++;
 -      assert(pthread_join(t[ct], NULL) == 0);
 -
 -      assert(pthread_mutex_lock(&cvthing.lock) == 0);
 -      cvthing.shared++;
 -      assert(pthread_mutex_unlock(&cvthing.lock) == 0);
 -
 -      assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
 -
 -      /*
 -       * Standard check that all threads started - and wait for them to finish.
 -       */
 -      for (i = first; i <= last; i++)
 -	{ 
 -	  failed = !threadbag[i].started;
 -
 -          if (failed)
 -	    {
 -	      fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
 -	    }
 -	  else
 -	    {
 -	      assert(pthread_join(t[i], NULL) == 0 || threadbag[i].finished == 0);
 -//	      fprintf(stderr, "Thread %d: finished %d\n", i, threadbag[i].finished);
 -	    }
 -	}
 -    }
 -
 -  /* 
 -   * Cleanup the CV.
 -   */
 -
 -  assert(pthread_mutex_destroy(&cvthing.lock) == 0);
 -
 -  assert(cvthing.lock == NULL);
 -
 -  assert_e(pthread_cond_destroy(&cvthing.notbusy), ==, 0);
 -
 -  assert(cvthing.notbusy == NULL);
 -
 -  assert(!failed);
 -
 -  /*
 -   * Check any results here.
 -   */
 -
 -  assert(awoken == NUMTHREADS - canceledThreads);
 -
 -  /*
 -   * Success.
 -   */
 -  return 0;
 -}
 +/* + * File: condvar9.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test multiple pthread_cond_broadcasts with thread cancelation. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * -  + * + * Features Tested: + * -  + * + * Cases Tested: + * -  + * + * Description: + * - Make NUMTHREADS threads wait on CV, cancel one, broadcast signal them, + *   and then repeat. + * + * 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" +#include <sys/timeb.h> + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { +  NUMTHREADS = 9 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { +  int threadnum; +  int started; +  int finished; +  /* Add more per-thread state variables here */ +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ { +  pthread_cond_t notbusy; +  pthread_mutex_t lock; +  int shared; +}; + +static cvthing_t cvthing = { +  PTHREAD_COND_INITIALIZER, +  PTHREAD_MUTEX_INITIALIZER, +  0 +}; + +static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; + +static struct timespec abstime = { 0, 0 }; + +static int awoken; + +static void * +mythread(void * arg) +{ +  bag_t * bag = (bag_t *) arg; + +  assert(bag == &threadbag[bag->threadnum]); +  assert(bag->started == 0); +  bag->started = 1; + +  /* Wait for the start gun */ +  assert(pthread_mutex_lock(&start_flag) == 0); +  assert(pthread_mutex_unlock(&start_flag) == 0); + +  assert(pthread_mutex_lock(&cvthing.lock) == 0); + +  /* +   * pthread_cond_timedwait is a cancelation point and we're +   * going to cancel some threads deliberately. +   */ +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif +  pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock); + +  while (! (cvthing.shared > 0)) +    assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + +  pthread_cleanup_pop(0); +#ifdef _MSC_VER +#pragma inline_depth() +#endif + +  assert(cvthing.shared > 0); + +  awoken++; +  bag->finished = 1; + +  assert(pthread_mutex_unlock(&cvthing.lock) == 0); + +  return (void *) 0; +} + +int +main() +{ +  int failed = 0; +  int i; +  int first, last; +  int canceledThreads = 0; +  pthread_t t[NUMTHREADS + 1]; + +  struct _timeb currSysTime; +  const DWORD NANOSEC_PER_MILLISEC = 1000000; + +  assert((t[0] = pthread_self()).p != NULL); + +  assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + +  assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + +  _ftime(&currSysTime); + +  abstime.tv_sec = currSysTime.time; +  abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + +  abstime.tv_sec += 5; + +  assert((t[0] = pthread_self()).p != NULL); + +  awoken = 0; + +  for (first = 1, last = NUMTHREADS / 2; +       first < NUMTHREADS; +       first = last + 1, last = NUMTHREADS) +    { +      int ct; + +      assert(pthread_mutex_lock(&start_flag) == 0); + +      for (i = first; i <= last; i++) +	{ +	  threadbag[i].started = threadbag[i].finished = 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. +       */ +      cvthing.shared = 0; + +      assert(pthread_mutex_unlock(&start_flag) == 0); + +      /* +       * Give threads time to start. +       */ +      Sleep(1000); + +      ct = (first + last) / 2; +      assert(pthread_cancel(t[ct]) == 0); +      canceledThreads++; +      assert(pthread_join(t[ct], NULL) == 0); + +      assert(pthread_mutex_lock(&cvthing.lock) == 0); +      cvthing.shared++; +      assert(pthread_mutex_unlock(&cvthing.lock) == 0); + +      assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + +      /* +       * Standard check that all threads started - and wait for them to finish. +       */ +      for (i = first; i <= last; i++) +	{  +	  failed = !threadbag[i].started; + +          if (failed) +	    { +	      fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); +	    } +	  else +	    { +	      assert(pthread_join(t[i], NULL) == 0 || threadbag[i].finished == 0); +//	      fprintf(stderr, "Thread %d: finished %d\n", i, threadbag[i].finished); +	    } +	} +    } + +  /*  +   * Cleanup the CV. +   */ + +  assert(pthread_mutex_destroy(&cvthing.lock) == 0); + +  assert(cvthing.lock == NULL); + +  assert_e(pthread_cond_destroy(&cvthing.notbusy), ==, 0); + +  assert(cvthing.notbusy == NULL); + +  assert(!failed); + +  /* +   * Check any results here. +   */ + +  assert(awoken == NUMTHREADS - canceledThreads); + +  /* +   * Success. +   */ +  return 0; +} diff --git a/tests/once4.c b/tests/once4.c index 69e9384..f5be644 100644 --- a/tests/once4.c +++ b/tests/once4.c @@ -1,191 +1,191 @@ -/*
 - * once4.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * Create several pthread_once objects and channel several threads
 - * through each. Make the init_routine cancelable and cancel them
 - * waiters waiting. Vary the priorities.
 - *
 - * Depends on API functions:
 - *	pthread_once()
 - *	pthread_create()
 - *      pthread_testcancel()
 - *      pthread_cancel()
 - *      pthread_once()
 - */
 -
 -#include "test.h"
 -
 -#define NUM_THREADS 100 /* Targeting each once control */
 -#define NUM_ONCE    10
 -
 -pthread_once_t o = PTHREAD_ONCE_INIT;
 -pthread_once_t once[NUM_ONCE];
 -
 -typedef struct {
 -  int i;
 -  CRITICAL_SECTION cs;
 -} sharedInt_t;
 -
 -static sharedInt_t numOnce = {0, {0}};
 -static sharedInt_t numThreads = {0, {0}};
 -
 -typedef struct {
 -  int threadnum;
 -  int oncenum;
 -  int myPrio;
 -  HANDLE w32Thread;
 -} bag_t;
 -
 -static bag_t threadbag[NUM_THREADS][NUM_ONCE];
 -
 -CRITICAL_SECTION print_lock;
 -
 -void
 -mycleanupfunc(void * arg)
 -{
 -  bag_t * bag = (bag_t *) arg;
 -  EnterCriticalSection(&print_lock);
 -  /*      once thrd  prio error */
 -  printf("%4d %4d %4d %4d\n",
 -	 bag->oncenum,
 -	 bag->threadnum,
 -	 bag->myPrio,
 -	 bag->myPrio - GetThreadPriority(bag->w32Thread));
 -  LeaveCriticalSection(&print_lock);
 -}
 -
 -void
 -myinitfunc(void)
 -{
 -  EnterCriticalSection(&numOnce.cs);
 -  numOnce.i++;
 -  LeaveCriticalSection(&numOnce.cs);
 -  /* Simulate slow once routine so that following threads pile up behind it */
 -  Sleep(10);
 -  /* test for cancelation late so we're sure to have waiters. */
 -  pthread_testcancel();
 -}
 -
 -void *
 -mythread(void * arg)
 -{
 -  bag_t * bag = (bag_t *) arg;
 -  struct sched_param param;
 -
 -  /*
 -   * Cancel every thread. These threads are deferred cancelable only, so
 -   * only the thread performing the init_routine will see it (there are
 -   * no other cancelation points here). The result will be that every thread
 -   * eventually cancels only when it becomes the new initter.
 -   */
 -  pthread_t self = pthread_self();
 -  bag->w32Thread = pthread_getw32threadhandle_np(self);
 -  /*
 -   * Set priority between -2 and 2 inclusive.
 -   */
 -  bag->myPrio = (bag->threadnum % 5) - 2;
 -  param.sched_priority = bag->myPrio;
 -  pthread_setschedparam(self, SCHED_OTHER, ¶m);
 -
 -  /* Trigger a cancellation at the next cancellation point in this thread */
 -  pthread_cancel(self);
 -#if 0
 -  pthread_cleanup_push(mycleanupfunc, arg);
 -  assert(pthread_once(&once[bag->oncenum], myinitfunc) == 0);
 -  pthread_cleanup_pop(1);
 -#else
 -  assert(pthread_once(&once[bag->oncenum], myinitfunc) == 0);
 -#endif
 -  EnterCriticalSection(&numThreads.cs);
 -  numThreads.i++;
 -  LeaveCriticalSection(&numThreads.cs);
 -  return 0;
 -}
 -
 -int
 -main()
 -{
 -  pthread_t t[NUM_THREADS][NUM_ONCE];
 -  int i, j;
 -  
 -  InitializeCriticalSection(&print_lock);
 -  InitializeCriticalSection(&numThreads.cs);
 -  InitializeCriticalSection(&numOnce.cs);
 -
 -#if 0
 -  /*       once thrd  prio change */
 -  printf("once thrd  prio  error\n");
 -#endif
 -
 -  /*
 -   * Set the priority class to realtime - otherwise normal
 -   * Windows random priority boosting will obscure any problems.
 -   */
 -  SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
 -  /* Set main thread to lower prio than threads */
 -  SetThreadPriority(GetCurrentThread(), -2);
 -
 -  for (j = 0; j < NUM_ONCE; j++)
 -    {
 -      once[j] = o;
 -
 -      for (i = 0; i < NUM_THREADS; i++)
 -        {
 -	  bag_t * bag = &threadbag[i][j];
 -	  bag->threadnum = i;
 -	  bag->oncenum = j;
 -          assert(pthread_create(&t[i][j], NULL, mythread, (void *) bag) == 0);
 -        }
 -    }
 -
 -  for (j = 0; j < NUM_ONCE; j++)
 -    for (i = 0; i < NUM_THREADS; i++)
 -      if (pthread_join(t[i][j], NULL) != 0)
 -        printf("Join failed for [thread,once] = [%d,%d]\n", i, j);
 -
 -  /*
 -   * All threads will cancel, none will return normally from
 -   * pthread_once and so numThreads should never be incremented. However,
 -   * numOnce should be incremented by every thread (NUM_THREADS*NUM_ONCE).
 -   */
 -  assert(numOnce.i == NUM_ONCE * NUM_THREADS);
 -  assert(numThreads.i == 0);
 -
 -  DeleteCriticalSection(&numOnce.cs);
 -  DeleteCriticalSection(&numThreads.cs);
 -  DeleteCriticalSection(&print_lock);
 -
 -  return 0;
 -}
 +/* + * once4.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Create several pthread_once objects and channel several threads + * through each. Make the init_routine cancelable and cancel them + * waiters waiting. Vary the priorities. + * + * Depends on API functions: + *	pthread_once() + *	pthread_create() + *      pthread_testcancel() + *      pthread_cancel() + *      pthread_once() + */ + +#include "test.h" + +#define NUM_THREADS 100 /* Targeting each once control */ +#define NUM_ONCE    10 + +pthread_once_t o = PTHREAD_ONCE_INIT; +pthread_once_t once[NUM_ONCE]; + +typedef struct { +  int i; +  CRITICAL_SECTION cs; +} sharedInt_t; + +static sharedInt_t numOnce = {0, {0}}; +static sharedInt_t numThreads = {0, {0}}; + +typedef struct { +  int threadnum; +  int oncenum; +  int myPrio; +  HANDLE w32Thread; +} bag_t; + +static bag_t threadbag[NUM_THREADS][NUM_ONCE]; + +CRITICAL_SECTION print_lock; + +void +mycleanupfunc(void * arg) +{ +  bag_t * bag = (bag_t *) arg; +  EnterCriticalSection(&print_lock); +  /*      once thrd  prio error */ +  printf("%4d %4d %4d %4d\n", +	 bag->oncenum, +	 bag->threadnum, +	 bag->myPrio, +	 bag->myPrio - GetThreadPriority(bag->w32Thread)); +  LeaveCriticalSection(&print_lock); +} + +void +myinitfunc(void) +{ +  EnterCriticalSection(&numOnce.cs); +  numOnce.i++; +  LeaveCriticalSection(&numOnce.cs); +  /* Simulate slow once routine so that following threads pile up behind it */ +  Sleep(10); +  /* test for cancelation late so we're sure to have waiters. */ +  pthread_testcancel(); +} + +void * +mythread(void * arg) +{ +  bag_t * bag = (bag_t *) arg; +  struct sched_param param; + +  /* +   * Cancel every thread. These threads are deferred cancelable only, so +   * only the thread performing the init_routine will see it (there are +   * no other cancelation points here). The result will be that every thread +   * eventually cancels only when it becomes the new initter. +   */ +  pthread_t self = pthread_self(); +  bag->w32Thread = pthread_getw32threadhandle_np(self); +  /* +   * Set priority between -2 and 2 inclusive. +   */ +  bag->myPrio = (bag->threadnum % 5) - 2; +  param.sched_priority = bag->myPrio; +  pthread_setschedparam(self, SCHED_OTHER, ¶m); + +  /* Trigger a cancellation at the next cancellation point in this thread */ +  pthread_cancel(self); +#if 0 +  pthread_cleanup_push(mycleanupfunc, arg); +  assert(pthread_once(&once[bag->oncenum], myinitfunc) == 0); +  pthread_cleanup_pop(1); +#else +  assert(pthread_once(&once[bag->oncenum], myinitfunc) == 0); +#endif +  EnterCriticalSection(&numThreads.cs); +  numThreads.i++; +  LeaveCriticalSection(&numThreads.cs); +  return 0; +} + +int +main() +{ +  pthread_t t[NUM_THREADS][NUM_ONCE]; +  int i, j; +   +  InitializeCriticalSection(&print_lock); +  InitializeCriticalSection(&numThreads.cs); +  InitializeCriticalSection(&numOnce.cs); + +#if 0 +  /*       once thrd  prio change */ +  printf("once thrd  prio  error\n"); +#endif + +  /* +   * Set the priority class to realtime - otherwise normal +   * Windows random priority boosting will obscure any problems. +   */ +  SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); +  /* Set main thread to lower prio than threads */ +  SetThreadPriority(GetCurrentThread(), -2); + +  for (j = 0; j < NUM_ONCE; j++) +    { +      once[j] = o; + +      for (i = 0; i < NUM_THREADS; i++) +        { +	  bag_t * bag = &threadbag[i][j]; +	  bag->threadnum = i; +	  bag->oncenum = j; +          assert(pthread_create(&t[i][j], NULL, mythread, (void *) bag) == 0); +        } +    } + +  for (j = 0; j < NUM_ONCE; j++) +    for (i = 0; i < NUM_THREADS; i++) +      if (pthread_join(t[i][j], NULL) != 0) +        printf("Join failed for [thread,once] = [%d,%d]\n", i, j); + +  /* +   * All threads will cancel, none will return normally from +   * pthread_once and so numThreads should never be incremented. However, +   * numOnce should be incremented by every thread (NUM_THREADS*NUM_ONCE). +   */ +  assert(numOnce.i == NUM_ONCE * NUM_THREADS); +  assert(numThreads.i == 0); + +  DeleteCriticalSection(&numOnce.cs); +  DeleteCriticalSection(&numThreads.cs); +  DeleteCriticalSection(&print_lock); + +  return 0; +} diff --git a/tests/semaphore1.c b/tests/semaphore1.c index 8ebf365..b5b2050 100644 --- a/tests/semaphore1.c +++ b/tests/semaphore1.c @@ -1,159 +1,159 @@ -/*
 - * File: semaphore1.c
 - *
 - *
 - * --------------------------------------------------------------------------
 - *
 - *      Pthreads-win32 - POSIX Threads Library for Win32
 - *      Copyright(C) 1998 John E. Bossom
 - *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 - * 
 - *      Contact Email: rpj@callisto.canberra.edu.au
 - * 
 - *      The current list of contributors is contained
 - *      in the file CONTRIBUTORS included with the source
 - *      code distribution. The list can also be seen at the
 - *      following World Wide Web location:
 - *      http://sources.redhat.com/pthreads-win32/contributors.html
 - * 
 - *      This library is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU Lesser General Public
 - *      License as published by the Free Software Foundation; either
 - *      version 2 of the License, or (at your option) any later version.
 - * 
 - *      This library is distributed in the hope that it will be useful,
 - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *      Lesser General Public License for more details.
 - * 
 - *      You should have received a copy of the GNU Lesser General Public
 - *      License along with this library in the file COPYING.LIB;
 - *      if not, write to the Free Software Foundation, Inc.,
 - *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 - *
 - * --------------------------------------------------------------------------
 - *
 - * Test Synopsis: Verify trywait() returns -1 and sets EAGAIN.
 - * - 
 - *
 - * Test Method (Validation or Falsification):
 - * - Validation
 - *
 - * 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 *
 -thr(void * arg)
 -{
 -  sem_t s;
 -  int result;
 -
 -  assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0);
 -
 -  assert((result = sem_trywait(&s)) == -1);
 -
 -  if ( result == -1 )
 -  {
 -    int err = errno;
 -    perror("thread: sem_trywait 1: expected error"); // No error
 -    assert(err == EAGAIN);
 -  }
 -  else
 -  {
 -    printf("thread: ok 1\n");
 -  }
 -
 -  assert((result = sem_post(&s)) == 0);
 -
 -  assert((result = sem_trywait(&s)) == 0);
 -
 -  if ( result == -1 )
 -  {
 -    perror("thread: sem_trywait 2");
 -  }
 -  else
 -  {
 -    printf("thread: ok 2\n");
 -  }
 -
 -  assert(sem_post(&s) == 0);
 -
 -  return 0;
 -}
 -
 -
 -int
 -main()
 -{
 -  pthread_t t;
 -  sem_t s;
 -  int result;
 -
 -  assert(pthread_create(&t, NULL, thr, NULL) == 0);
 -  assert(pthread_join(t, (void **)&result) == 0);
 -  assert(result == 0);
 -
 -  assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0);
 -
 -  assert((result = sem_trywait(&s)) == -1);
 -
 -  if ( result == -1 )
 -  {
 -    int err = errno;
 -    perror("main: sem_trywait 1: expected error"); // No error
 -    assert(err == EAGAIN);
 -  }
 -  else
 -  {
 -    printf("main: ok 1\n");
 -  }
 -
 -  assert((result = sem_post(&s)) == 0);
 -
 -  assert((result = sem_trywait(&s)) == 0);
 -
 -  if ( result == -1 )
 -  {
 -    perror("main: sem_trywait 2");
 -  }
 -  else
 -  {
 -    printf("main: ok 2\n");
 -  }
 -
 -  assert(sem_post(&s) == 0);
 -
 -  return 0;
 -}
 -
 +/* + * File: semaphore1.c + * + * + * -------------------------------------------------------------------------- + * + *      Pthreads-win32 - POSIX Threads Library for Win32 + *      Copyright(C) 1998 John E. Bossom + *      Copyright(C) 1999,2005 Pthreads-win32 contributors + *  + *      Contact Email: rpj@callisto.canberra.edu.au + *  + *      The current list of contributors is contained + *      in the file CONTRIBUTORS included with the source + *      code distribution. The list can also be seen at the + *      following World Wide Web location: + *      http://sources.redhat.com/pthreads-win32/contributors.html + *  + *      This library is free software; you can redistribute it and/or + *      modify it under the terms of the GNU Lesser General Public + *      License as published by the Free Software Foundation; either + *      version 2 of the License, or (at your option) any later version. + *  + *      This library is distributed in the hope that it will be useful, + *      but WITHOUT ANY WARRANTY; without even the implied warranty of + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *      Lesser General Public License for more details. + *  + *      You should have received a copy of the GNU Lesser General Public + *      License along with this library in the file COPYING.LIB; + *      if not, write to the Free Software Foundation, Inc., + *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Verify trywait() returns -1 and sets EAGAIN. + * -  + * + * Test Method (Validation or Falsification): + * - Validation + * + * 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 * +thr(void * arg) +{ +  sem_t s; +  int result; + +  assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + +  assert((result = sem_trywait(&s)) == -1); + +  if ( result == -1 ) +  { +    int err = errno; +    perror("thread: sem_trywait 1: expected error"); // No error +    assert(err == EAGAIN); +  } +  else +  { +    printf("thread: ok 1\n"); +  } + +  assert((result = sem_post(&s)) == 0); + +  assert((result = sem_trywait(&s)) == 0); + +  if ( result == -1 ) +  { +    perror("thread: sem_trywait 2"); +  } +  else +  { +    printf("thread: ok 2\n"); +  } + +  assert(sem_post(&s) == 0); + +  return 0; +} + + +int +main() +{ +  pthread_t t; +  sem_t s; +  int result; + +  assert(pthread_create(&t, NULL, thr, NULL) == 0); +  assert(pthread_join(t, (void **)&result) == 0); +  assert(result == 0); + +  assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + +  assert((result = sem_trywait(&s)) == -1); + +  if ( result == -1 ) +  { +    int err = errno; +    perror("main: sem_trywait 1: expected error"); // No error +    assert(err == EAGAIN); +  } +  else +  { +    printf("main: ok 1\n"); +  } + +  assert((result = sem_post(&s)) == 0); + +  assert((result = sem_trywait(&s)) == 0); + +  if ( result == -1 ) +  { +    perror("main: sem_trywait 2"); +  } +  else +  { +    printf("main: ok 2\n"); +  } + +  assert(sem_post(&s) == 0); + +  return 0; +} +  | 
