From 88101146f2ec7d53ffb793e365f05097ffd35fd3 Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 18 Jul 2011 10:33:05 +0200 Subject: cvs version of pthreads --- pthreads/ANNOUNCE | 958 +-- pthreads/BUGS | 10 +- pthreads/Bmakefile | 8 +- pthreads/CONTRIBUTORS | 274 +- pthreads/ChangeLog | 10167 +++++++++++++------------- pthreads/GNUmakefile | 1180 +-- pthreads/Makefile | 1020 +-- pthreads/NEWS | 2432 +++--- pthreads/Nmakefile | 2 +- pthreads/README | 16 +- pthreads/README.NONPORTABLE | 487 +- pthreads/autostatic.c | 138 +- pthreads/builddmc.bat | 4 +- pthreads/config.h | 295 +- pthreads/context.h | 148 +- pthreads/create.c | 613 +- pthreads/dll.c | 6 +- pthreads/global.c | 30 +- pthreads/implement.h | 1658 +++-- pthreads/manual/ChangeLog | 140 +- pthreads/manual/index.html | 278 +- pthreads/manual/pthread_getunique_np.html | 76 + pthreads/manual/pthread_mutex_init.html | 225 +- pthreads/manual/pthread_mutexattr_init.html | 172 +- pthreads/mutex.c | 121 +- pthreads/need_errno.h | 286 +- pthreads/nonportable.c | 1 + pthreads/private.c | 3 - pthreads/pthread.h | 2746 ++++--- pthreads/pthread_attr_getscope.c | 4 +- pthreads/pthread_attr_getstackaddr.c | 2 +- pthreads/pthread_attr_getstacksize.c | 4 +- pthreads/pthread_attr_init.c | 6 +- pthreads/pthread_attr_setscope.c | 4 +- pthreads/pthread_attr_setstackaddr.c | 4 +- pthreads/pthread_attr_setstacksize.c | 2 +- pthreads/pthread_barrier_destroy.c | 206 +- pthreads/pthread_barrier_wait.c | 208 +- pthreads/pthread_cancel.c | 377 +- pthreads/pthread_cond_destroy.c | 504 +- pthreads/pthread_cond_init.c | 6 +- pthreads/pthread_cond_wait.c | 4 +- pthreads/pthread_delay_np.c | 9 +- pthreads/pthread_detach.c | 277 +- pthreads/pthread_equal.c | 2 +- pthreads/pthread_exit.c | 212 +- pthreads/pthread_getunique_np.c | 47 + pthreads/pthread_join.c | 313 +- pthreads/pthread_key_create.c | 216 +- pthreads/pthread_key_delete.c | 258 +- pthreads/pthread_kill.c | 209 +- pthreads/pthread_mutex_consistent.c | 190 + pthreads/pthread_mutex_destroy.c | 22 +- pthreads/pthread_mutex_init.c | 52 +- pthreads/pthread_mutex_lock.c | 408 +- pthreads/pthread_mutex_timedlock.c | 228 +- pthreads/pthread_mutex_trylock.c | 98 +- pthreads/pthread_mutex_unlock.c | 144 +- pthreads/pthread_mutexattr_getrobust.c | 113 + pthreads/pthread_mutexattr_setrobust.c | 119 + pthreads/pthread_once.c | 165 +- pthreads/pthread_rwlock_destroy.c | 285 +- pthreads/pthread_rwlock_timedwrlock.c | 278 +- pthreads/pthread_rwlock_wrlock.c | 266 +- pthreads/pthread_self.c | 11 +- pthreads/pthread_setcancelstate.c | 7 +- pthreads/pthread_setcanceltype.c | 7 +- pthreads/pthread_setschedparam.c | 34 +- pthreads/pthread_setspecific.c | 335 +- pthreads/pthread_spin_destroy.c | 15 +- pthreads/pthread_spin_lock.c | 9 +- pthreads/pthread_spin_trylock.c | 9 +- pthreads/pthread_spin_unlock.c | 12 +- pthreads/pthread_testcancel.c | 205 +- pthreads/pthread_timechange_handler_np.c | 7 +- pthreads/pthread_win32_attach_detach_np.c | 570 +- pthreads/ptw32_InterlockedCompareExchange.c | 307 - pthreads/ptw32_MCS_lock.c | 541 +- pthreads/ptw32_callUserDestroyRoutines.c | 44 +- pthreads/ptw32_calloc.c | 2 +- pthreads/ptw32_cond_check_need_init.c | 22 +- pthreads/ptw32_mutex_check_need_init.c | 26 +- pthreads/ptw32_new.c | 7 +- pthreads/ptw32_processInitialize.c | 10 - pthreads/ptw32_processTerminate.c | 15 +- pthreads/ptw32_relmillisecs.c | 252 +- pthreads/ptw32_reuse.c | 14 +- pthreads/ptw32_rwlock_check_need_init.c | 22 +- pthreads/ptw32_semwait.c | 270 +- pthreads/ptw32_spinlock_check_need_init.c | 9 +- pthreads/ptw32_threadDestroy.c | 5 +- pthreads/ptw32_threadStart.c | 69 +- pthreads/ptw32_throw.c | 361 +- pthreads/ptw32_timespec.c | 12 +- pthreads/ptw32_tkAssocCreate.c | 2 +- pthreads/ptw32_tkAssocDestroy.c | 2 +- pthreads/sched.h | 363 +- pthreads/sched_getscheduler.c | 2 + pthreads/sched_setscheduler.c | 2 + pthreads/sem_close.c | 2 +- pthreads/sem_init.c | 2 +- pthreads/sem_open.c | 2 +- pthreads/sem_post.c | 2 +- pthreads/sem_post_multiple.c | 2 +- pthreads/sem_timedwait.c | 12 +- pthreads/sem_unlink.c | 2 +- pthreads/sem_wait.c | 8 +- pthreads/semaphore.c | 2 +- pthreads/semaphore.h | 335 +- pthreads/signal.c | 2 +- pthreads/tests/Bmakefile | 712 +- pthreads/tests/ChangeLog | 1918 ++--- pthreads/tests/GNUmakefile | 850 +-- pthreads/tests/Makefile | 891 +-- pthreads/tests/SIZES.GC | 42 +- pthreads/tests/SIZES.GCE | 16 +- pthreads/tests/SIZES.VC | 41 +- pthreads/tests/SIZES.VCE | 40 +- pthreads/tests/SIZES.VSE | 40 +- pthreads/tests/Wmakefile | 704 +- pthreads/tests/barrier3.c | 8 +- pthreads/tests/barrier5.c | 236 +- pthreads/tests/benchtest1.c | 55 +- pthreads/tests/benchtest2.c | 38 +- pthreads/tests/benchtest3.c | 36 +- pthreads/tests/benchtest4.c | 36 +- pthreads/tests/benchtest5.c | 20 +- pthreads/tests/cancel1.c | 2 +- pthreads/tests/cancel2.c | 31 +- pthreads/tests/cancel3.c | 402 +- pthreads/tests/cancel4.c | 10 +- pthreads/tests/cancel5.c | 10 +- pthreads/tests/cancel6a.c | 10 +- pthreads/tests/cancel6d.c | 17 +- pthreads/tests/cancel7.c | 8 +- pthreads/tests/cancel8.c | 8 +- pthreads/tests/cleanup0.c | 10 +- pthreads/tests/cleanup1.c | 10 +- pthreads/tests/cleanup2.c | 10 +- pthreads/tests/cleanup3.c | 10 +- pthreads/tests/condvar1_2.c | 6 +- pthreads/tests/condvar2.c | 6 +- pthreads/tests/condvar2_1.c | 14 +- pthreads/tests/condvar3.c | 6 +- pthreads/tests/condvar3_1.c | 14 +- pthreads/tests/condvar3_2.c | 16 +- pthreads/tests/condvar3_3.c | 8 +- pthreads/tests/condvar4.c | 10 +- pthreads/tests/condvar5.c | 10 +- pthreads/tests/condvar6.c | 6 +- pthreads/tests/condvar7.c | 6 +- pthreads/tests/condvar8.c | 6 +- pthreads/tests/condvar9.c | 6 +- pthreads/tests/create2.c | 3 +- pthreads/tests/create3.c | 122 - pthreads/tests/delay2.c | 8 +- pthreads/tests/detach1.c | 4 +- pthreads/tests/exception1.c | 28 +- pthreads/tests/exception2.c | 4 +- pthreads/tests/exception3.c | 23 +- pthreads/tests/exit2.c | 2 +- pthreads/tests/exit3.c | 4 +- pthreads/tests/exit4.c | 4 +- pthreads/tests/exit5.c | 4 +- pthreads/tests/inherit1.c | 4 +- pthreads/tests/join0.c | 6 +- pthreads/tests/join1.c | 10 +- pthreads/tests/join2.c | 8 +- pthreads/tests/join3.c | 8 +- pthreads/tests/mutex1e.c | 4 + pthreads/tests/mutex1n.c | 4 + pthreads/tests/mutex1r.c | 4 + pthreads/tests/mutex4.c | 24 +- pthreads/tests/mutex6e.c | 15 +- pthreads/tests/mutex6es.c | 6 +- pthreads/tests/mutex6n.c | 21 +- pthreads/tests/mutex6r.c | 15 +- pthreads/tests/mutex6rs.c | 6 +- pthreads/tests/mutex7.c | 2 +- pthreads/tests/mutex7e.c | 16 +- pthreads/tests/mutex7n.c | 13 +- pthreads/tests/mutex7r.c | 15 +- pthreads/tests/mutex8.c | 6 +- pthreads/tests/mutex8e.c | 14 +- pthreads/tests/mutex8n.c | 14 +- pthreads/tests/mutex8r.c | 14 +- pthreads/tests/once2.c | 6 +- pthreads/tests/once3.c | 264 +- pthreads/tests/openmp1.c | 140 + pthreads/tests/priority1.c | 6 +- pthreads/tests/priority2.c | 4 +- pthreads/tests/reuse1.c | 6 +- pthreads/tests/reuse2.c | 3 +- pthreads/tests/robust1.c | 141 + pthreads/tests/robust2.c | 143 + pthreads/tests/robust3.c | 149 + pthreads/tests/robust4.c | 199 + pthreads/tests/robust5.c | 120 + pthreads/tests/rwlock2_t.c | 6 +- pthreads/tests/rwlock3.c | 4 +- pthreads/tests/rwlock3_t.c | 6 +- pthreads/tests/rwlock4.c | 4 +- pthreads/tests/rwlock4_t.c | 6 +- pthreads/tests/rwlock5.c | 4 +- pthreads/tests/rwlock5_t.c | 6 +- pthreads/tests/rwlock6.c | 28 +- pthreads/tests/rwlock6_t.c | 42 +- pthreads/tests/rwlock6_t2.c | 38 +- pthreads/tests/rwlock7.c | 18 +- pthreads/tests/rwlock8.c | 18 +- pthreads/tests/semaphore1.c | 49 +- pthreads/tests/semaphore4.c | 10 +- pthreads/tests/semaphore4t.c | 3 - pthreads/tests/sequence1.c | 142 + pthreads/tests/sizes.c | 36 +- pthreads/tests/spin3.c | 10 +- pthreads/tests/spin4.c | 20 +- pthreads/tests/stress1.c | 556 +- pthreads/tests/test.h | 322 +- pthreads/tests/tsd1.c | 4 +- pthreads/tests/tsd2.c | 4 +- pthreads/tests/valid1.c | 2 +- pthreads/version.rc | 36 +- pthreads/w32_CancelableWait.c | 7 +- 224 files changed, 22487 insertions(+), 19532 deletions(-) create mode 100644 pthreads/manual/pthread_getunique_np.html create mode 100644 pthreads/pthread_getunique_np.c create mode 100644 pthreads/pthread_mutex_consistent.c create mode 100644 pthreads/pthread_mutexattr_getrobust.c create mode 100644 pthreads/pthread_mutexattr_setrobust.c delete mode 100644 pthreads/ptw32_InterlockedCompareExchange.c delete mode 100644 pthreads/tests/create3.c create mode 100644 pthreads/tests/openmp1.c create mode 100644 pthreads/tests/robust1.c create mode 100644 pthreads/tests/robust2.c create mode 100644 pthreads/tests/robust3.c create mode 100644 pthreads/tests/robust4.c create mode 100644 pthreads/tests/robust5.c create mode 100644 pthreads/tests/sequence1.c (limited to 'pthreads') diff --git a/pthreads/ANNOUNCE b/pthreads/ANNOUNCE index 703070d1a..3fa6232c1 100644 --- a/pthreads/ANNOUNCE +++ b/pthreads/ANNOUNCE @@ -1,476 +1,482 @@ - PTHREADS-WIN32 RELEASE 2.9.0 (2007-??-??) - ----------------------------------------- - Web Site: http://sources.redhat.com/pthreads-win32/ - FTP Site: ftp://sources.redhat.com/pub/pthreads-win32 - Maintainer: Ross Johnson - - -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 . - -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. - -Thanks to Xavier Leroy for granting permission to use and modify his -LinuxThreads manual pages. - -Thanks to The Open Group for making the Single Unix Specification -publicly available - many of the manual pages included in the package -were extracted from it. - -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 limits are defined and set: - - _POSIX_THREAD_THREADS_MAX - _POSIX_SEM_VALUE_MAX - _POSIX_SEM_NSEMS_MAX - _POSIX_THREAD_KEYS_MAX - _POSIX_THREAD_DESTRUCTOR_ITERATIONS - PTHREAD_STACK_MIN - PTHREAD_THREADS_MAX - SEM_VALUE_MAX - SEM_NSEMS_MAX - PTHREAD_KEYS_MAX - PTHREAD_DESTRUCTOR_ITERATIONS - - -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_getvalue (# free if +ve, # of waiters if -ve) - sem_open (returns an error ENOSYS) - sem_close (returns an error ENOSYS) - sem_unlink (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.9.0 (2007-??-??) + ----------------------------------------- + Web Site: http://sources.redhat.com/pthreads-win32/ + FTP Site: ftp://sources.redhat.com/pub/pthreads-win32 + Maintainer: Ross Johnson + + +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 . + +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. + +Thanks to Xavier Leroy for granting permission to use and modify his +LinuxThreads manual pages. + +Thanks to The Open Group for making the Single Unix Specification +publicly available - many of the manual pages included in the package +were extracted from it. + +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 limits are defined and set: + + _POSIX_THREAD_THREADS_MAX + _POSIX_SEM_VALUE_MAX + _POSIX_SEM_NSEMS_MAX + _POSIX_THREAD_KEYS_MAX + _POSIX_THREAD_DESTRUCTOR_ITERATIONS + PTHREAD_STACK_MIN + PTHREAD_THREADS_MAX + SEM_VALUE_MAX + SEM_NSEMS_MAX + PTHREAD_KEYS_MAX + PTHREAD_DESTRUCTOR_ITERATIONS + + +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_mutexattr_getrobust + pthread_mutexattr_setrobust (values: PTHREAD_MUTEX_STALLED + PTHREAD_MUTEX_ROBUST) + pthread_mutex_init + pthread_mutex_destroy + pthread_mutex_lock + pthread_mutex_trylock + pthread_mutex_timedlock + pthread_mutex_unlock + pthread_mutex_consistent + + --------------------------- + 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_getvalue (# free if +ve, # of waiters if -ve) + sem_open (returns an error ENOSYS) + sem_close (returns an error ENOSYS) + sem_unlink (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_getunique_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 + + +The library includes two non-API functions for creating cancellation +points in applications and libraries: + + pthreadCancelableWait + pthreadCancelableTimedWait + + +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 + + --------------------------- + Thread-Safe C Runtime Library (macros) + --------------------------- + strtok_r + asctime_r + ctime_r + gmtime_r + localtime_r + rand_r + + +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 do 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 threads + semaphore.h - for POSIX semaphores + sched.h - for POSIX 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 diff --git a/pthreads/BUGS b/pthreads/BUGS index 29cee0033..285ba4eb9 100644 --- a/pthreads/BUGS +++ b/pthreads/BUGS @@ -22,9 +22,17 @@ Known bugs 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 +2. Cancellation problems in C++ builds - Milan Gardian + [Note: It's not clear if this problem isn't simply due to the context + switch in pthread_cancel() which occurs unless the QueueUserAPCEx + library and driver are installed and used. Just like setjmp/longjmp, + this is probably not going to work well in C++. In any case, unless for + some very unusual reason you really must use the C++ build then please + use the C build pthreadVC2.dll or pthreadGC2.dll, i.e. for C++ + applications.] + 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 diff --git a/pthreads/Bmakefile b/pthreads/Bmakefile index 66707bf4c..ea25dec4f 100644 --- a/pthreads/Bmakefile +++ b/pthreads/Bmakefile @@ -21,7 +21,7 @@ OPTIM = /O2 RC = brcc32 RCFLAGS = -i. -CFLAGS = /q /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H=1 /4 /tWD /tWM \ +CFLAGS = /q /I. /D_WIN32_WINNT=0x400 /DHAVE_PTW32_CONFIG_H=1 /4 /tWD /tWM \ /w-aus /w-asc /w-par #C cleanup code @@ -116,10 +116,13 @@ MUTEX_SRCS = \ pthread_mutexattr_setpshared.c \ pthread_mutexattr_settype.c \ pthread_mutexattr_gettype.c \ + pthread_mutexattr_setrobust.c \ + pthread_mutexattr_getrobust.c \ pthread_mutex_lock.c \ pthread_mutex_timedlock.c \ pthread_mutex_unlock.c \ - pthread_mutex_trylock.c + pthread_mutex_trylock.c \ + pthread_mutex_consistent.c NONPORTABLE_SRCS = \ pthread_mutexattr_setkind_np.c \ @@ -142,7 +145,6 @@ PRIVATE_SRCS = \ ptw32_timespec.c \ ptw32_relmillisecs.c \ ptw32_throw.c \ - ptw32_InterlockedCompareExchange.c \ ptw32_getprocessors.c RWLOCK_SRCS = \ diff --git a/pthreads/CONTRIBUTORS b/pthreads/CONTRIBUTORS index edde3c8b9..da31ff266 100644 --- a/pthreads/CONTRIBUTORS +++ b/pthreads/CONTRIBUTORS @@ -1,134 +1,140 @@ -Contributors (in approximate order of appearance) - -[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; - suggested a robust implementation of pthread_once - similar to that implemented by V.Kliathcko; - 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 - phadjido at cs dot uoi 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). -Vladimir Kliatchko vladimir at kliatchko dot com - reimplemented pthread_once with the same form - as described by A.Terekhov (later version 2); - implementation of MCS (Mellor-Crummey/Scott) locks. -Ramiro Polla ramiro.polla at gmail.com - static library auto init/cleanup on application - start/exit via RT hooks (MSC and GCC compilers only). - \ No newline at end of file +Contributors (in approximate order of appearance) + +[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 Ross dot Johnson at dot homemail dot com 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; + suggested a robust implementation of pthread_once + similar to that implemented by V.Kliathcko; + 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 + phadjido at cs dot uoi 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). +Vladimir Kliatchko vladimir at kliatchko dot com + reimplemented pthread_once with the same form + as described by A.Terekhov (later version 2); + implementation of MCS (Mellor-Crummey/Scott) locks. +Ramiro Polla ramiro.polla at gmail dot com + static library auto init/cleanup on application + start/exit via RT hooks (MSC and GCC compilers only). +Daniel Richard G. skunk at iSKUNK dot org + Patches and cleanups for x86 and x64, particularly + across a range of MS build environments. +John Kamp john dot kamp at globalgraphics dot com + Patches to fix various problems on x64; brutal testing + particularly using high memory run environments. + diff --git a/pthreads/ChangeLog b/pthreads/ChangeLog index 32e7a06a4..b2396ebf4 100644 --- a/pthreads/ChangeLog +++ b/pthreads/ChangeLog @@ -1,4973 +1,5194 @@ -2010-11-16 Ross Johnson - - * ChangeLog: Add this entry ;-) - Restore entries from 2007 through 2009 that went missing - at the last update. - -2010-06-19 Ross Johnson - - * ptw32_MCS_lock.c (ptw32_mcs_node_substitute): Fix variable - names to avoid using C++ keyword ("new"). - * implement.h (ptw32_mcs_node_substitute): Likewise. - * pthread_barrier_wait.c: Fix signed/unsigned comparison warning. - -2010-06-18 Ramiro Polla - - * autostatic.c: New file; call pthread_win32_process_*() - libary init/cleanup routines automatically on application start - when statically linked. - * pthread.c (autostatic.c): Included. - * pthread.h (declspec): Remove import/export defines if compiler - is MINGW. - * sched.h (declspec): Likewise. - * semaphore.h (declspec): Likewise. - * need_errno.h (declspec): Likewise. - * Makefile (autostatic.obj): Add for small static builds. - * GNUmakefile (autostatic.o): Likewise. - * NEWS (Version 2.9.0): Add changes. - * README.NONPORTABLE (pthread_win32_process_*): Update - description. - -2010-06-15 Ramiro Polla - - * Makefile: Remove linkage with the winsock library by default. - * GNUmakefile: Likewise. - * pthread_getspecific.c: Likewise by removing calls to WSA - functions. - * config.h (RETAIN_WSALASTERROR): Can be defined if necessary. - -2010-01-26 Ross Johnson - - * ptw32_MCS_lock.c (ptw32_mcs_node_substitute): New routine - to allow relocating the lock owners thread-local node to somewhere - else, e.g. to global space so that another thread can release the - lock. Used in pthread_barrier_wait. - (ptw32_mcs_lock_try_acquire): New routine. - * pthread_barrier_init: Only one semaphore is used now. - * pthread_barrier_wait: Added an MCS guard lock with the last thread - to leave the barrier releasing the lock. This removes a deadlock bug - observed when there are greater than barrier-count threads - attempting to cross. - * pthread_barrier_destroy: Added an MCS guard lock. - -2009-03-03 Stephan O'Farrill - - * pthread_attr_getschedpolicy.c: Add "const" to function parameter - in accordance with SUSv3 (POSIX). - * pthread_attr_getinheritsched.c: Likewise. - * pthread_mutexattr_gettype.c: Likewise. - -2008-06-06 Robert Kindred - - * ptw32_throw.c (ptw32_throw): Remove possible reference to NULL - pointer. (At the same time made the switch block conditionally - included only if exitCode is needed - RPJ.) - * pthread_testcancel.c (pthread_testcancel): Remove duplicate and - misplaced pthread_mutex_unlock(). - -2008-02-21 Sebastian Gottschalk - - * pthread_attr_getdetachstate.c (pthread_attr_getdetachstate): - Remove potential and superfluous null pointer assignment. - -2007-11-22 Ivan Pizhenko - - * pthread.h (gmtime_r): gmtime returns 0 if tm represents a time - prior to 1/1/1970. Notice this to prevent raising an exception. - * pthread.h (localtime_r): Likewise for localtime. - -2007-07-14 Marcel Ruff - - * errno.c (_errno): Fix test for pthread_self() success. - * need_errno.h: Remove unintentional line wrap from #if line. - -2007-07-14 Mike Romanchuk - - * pthread.h (timespec): Fix tv_sec type. - -2007-01-07 Sinan Kaya - - * need_errno.h: Fix declaration of _errno - the local version of - _errno() is used, e.g. by WinCE. - -2007-01-06 Ross Johnson - - * ptw32_semwait.c: Add check for invalid sem_t after acquiring the - sem_t state guard mutex and before affecting changes to sema state. - -2007-01-06 Marcel Ruff - - * error.c: Fix reference to pthread handle exitStatus member for - builds that use NEED_ERRNO (i.e. WINCE). - * context.h: Add support for ARM processor (WinCE). - * mutex.c (process.h): Exclude for WINCE. - * create.c: Likewise. - * exit.c: Likewise. - * implement.h: Likewise. - * pthread_detach.c (signal.h): Exclude for WINCE. - * pthread_join.c: Likewise. - * pthread_kill.c: Likewise. - * pthread_rwlock_init.c (errno.h): Remove - included by pthread.h. - * pthread_rwlock_destroy.c: Likewise. - * pthread_rwlock_rdlock.c: Likewise. - * pthread_rwlock_timedrdlock.c: Likewise. - * pthread_rwlock_timedwrlock.c: Likewise. - * pthread_rwlock_tryrdlock.c: Likewise. - * pthread_rwlock_trywrlock.c: likewise. - * pthread_rwlock_unlock.c: Likewise. - * pthread_rwlock_wrlock.c: Likewise. - * pthread_rwlockattr_destroy.c: Likewise. - * pthread_rwlockattr_getpshared.c: Likewise. - * pthread_rwlockattr_init.c: Likewise. - * pthread_rwlockattr_setpshared.c: Likewise. - -2007-01-06 Romano Paolo Tenca - - * pthread_cond_destroy.c: Replace sem_wait() with non-cancelable - ptw32_semwait() since pthread_cond_destroy() is not a cancelation - point. - * implement.h (ptw32_spinlock_check_need_init): Add prototype. - * ptw32_MCS_lock.c: Reverse order of includes. - -2007-01-06 Eric Berge - - * pthread_cond_destroy.c: Add LeaveCriticalSection before returning - after errors. - -2007-01-04 Ross Johnson - - * ptw32_InterlockedCompareExchange.c: Conditionally skip for - Win64 as not required. - * pthread_win32_attach_detach_np.c (pthread_win32_process_attach_np): - Test for InterlockedCompareExchange is not required for Win64. - * context.h: New file. Included by pthread_cancel.h and any tests - that need it (e.g. context1.c). - * pthread_cancel.c: Architecture-dependent context macros moved - to context.h. - -2007-01-04 Kip Streithorst - - * implement.h (PTW32_INTERLOCKED_COMPARE_EXCHANGE): Add Win64 - support. - -2006-12-20 Ross Johnson - - * sem_destroy.c: Fix the race involving invalidation of the sema; - fix incorrect return of EBUSY resulting from the mutex trylock - on the private mutex guard. - * sem_wait.c: Add check for invalid sem_t after acquiring the - sem_t state guard mutex and before affecting changes to sema state. - * sem_trywait.c: Likewise. - * sem_timedwait.c: Likewise. - * sem_getvalue.c: Likewise. - * sem_post.c: Similar. - * sem_post_multiple.c: Likewise. - * sem_init.c: Set max Win32 semaphore count to SEM_VALUE_MAX (was - _POSIX_SEM_VALUE_MAX, which is a lower value - the minimum). - - * pthread_win32_attach_detach_np.c (pthread_win32_process_attach_np): - Load COREDLL.DLL under WINCE to check existence of - InterlockedCompareExchange() routine. This used to be done to test - for TryEnterCriticalSection() but was removed when this was no - longer needed. - -2006-01-25 Prashant Thakre - - * pthread_cancel.c: Added _M_IA64 register context support. - -2005-05-13 Ross Johnson - - * pthread_kill.c (pthread_kill): Remove check for Win32 thread - priority (to confirm HANDLE validity). Useless since thread HANDLEs - a not recycle-unique. - -2005-05-30 Vladimir Kliatchko - - * pthread_once.c: Re-implement using an MCS queue-based lock. The form - of pthread_once is as proposed by Alexander Terekhov (see entry of - 2005-03-13). The MCS lock implementation does not require a unique - 'name' to identify the lock between threads. Attempts to get the Event - or Semaphore based versions of pthread_once to a satisfactory level - of robustness have thus far failed. The last problem (avoiding races - involving non recycle-unique Win32 HANDLEs) was giving everyone - grey hair trying to solve it. - - * ptw32_MCS_lock.c: New MCS queue-based lock implementation. These - locks are efficient: they have very low overhead in the uncontended case; - are efficient in contention and minimise cache-coherence updates in - managing the user level FIFO queue; do not require an ABI change in the - library. - -2005-05-27 Alexander Gottwald - - * pthread.h: Some things, like HANDLE, were only defined if - PTW32_LEVEL was >= 3. They should always be defined. - -2005-05-25 Vladimir Kliatchko - - * pthread_once.c: Eliminate all priority operations and other - complexity by replacing the event with a semaphore. The advantage - of the change is the ability to release just one waiter if the - init_routine thread is cancelled yet still release all waiters when - done. Simplify once_control state checks to improve efficiency - further. - -2005-05-24 Mikael Magnusson - - * GNUmakefile: Patched to allow cross-compile with mingw32 on Linux. - It uses macros instead of referencing dlltool, gcc and g++ directly; - added a call to ranlib. For example the GC static library can be - built with: - make CC=i586-mingw32msvc-gcc RC=i586-mingw32msvc-windres \ - RANLIB=i586-mingw32msvc-ranlib clean GC-static - -2005-05-13 Ross Johnson - - * pthread_win32_attach_detach_np.c (pthread_win32_thread_detach_np): - Move on-exit-only stuff from ptw32_threadDestroy() to here. - * ptw32_threadDestroy.c: It's purpose is now only to reclaim thread - resources for detached threads, or via pthread_join() or - pthread_detach() on joinable threads. - * ptw32_threadStart.c: Calling user destruct routines has moved to - pthread_win32_thread_detach_np(); call pthread_win32_thread_detach_np() - directly if statically linking, otherwise do so via dllMain; store - thread return value in thread struct for all cases, including - cancellation and exception exits; thread abnormal exits go via - pthread_win32_thread_detach_np. - * pthread_join.c (pthread_join): Don't try to get return code from - Win32 thread - always get it from he thread struct. - * pthread_detach.c (pthread_detach): reduce extent of the thread - existence check since we now don't care if the Win32 thread HANDLE has - been closed; reclaim thread resources if the thread has exited already. - * ptw32_throw.c (ptw32_throw): For Win32 threads that are not implicit, - only Call thread cleanup if statically linking, otherwise leave it to - dllMain. - * sem_post.c (_POSIX_SEM_VALUE_MAX): Change to SEM_VALUE_MAX. - * sem_post_multiple.c: Likewise. - * sem_init.c: Likewise. - -2005-05-10 Ross Johnson - - * pthread_join.c (pthread_join): Add missing check for thread ID - reference count in thread existence test; reduce extent of the - existence test since we don't care if the Win32 thread HANDLE has - been closed. - -2005-05-09 Ross Johnson - - * ptw32_callUserDestroyRoutines.c: Run destructor process (i.e. - loop over all keys calling destructors) up to - PTHREAD_DESTRUCTOR_ITERATIONS times if TSD value isn't NULL yet; - modify assoc management. - * pthread_key_delete.c: Modify assoc management. - * ptw32_tkAssocDestroy.c: Fix error in assoc removal from chains. - * pthread.h - (_POSIX_THREAD_DESTRUCTOR_ITERATIONS): Define to value specified by - POSIX. - (_POSIX_THREAD_KEYS_MAX): Define to value specified by POSIX. - (PTHREAD_KEYS_MAX): Redefine [upward] to minimum required by POSIX. - (SEM_NSEMS_MAX): Define to implementation value. - (SEM_VALUE_MAX): Define to implementation value. - (_POSIX_SEM_NSEMS_MAX): Redefine to value specified by POSIX. - (_POSIX_SEM_VALUE_MAX): Redefine to value specified by POSIX. - -2005-05-06 Ross Johnson - - * signal.c (sigwait): Add a cancellation point to this otherwise - no-op. - * sem_init.c (sem_init): Check for and return ERANGE error. - * sem_post.c (sem_post): Likewise. - * sem_post_multiple.c (sem_post_multiple): Likewise. - * manual (directory): Added; see ChangeLog inside. - -2005-05-02 Ross Johnson - - * implement.h (struct pthread_key_t_): Change threadsLock to keyLock - so as not to be confused with the per thread lock 'threadlock'; - change all references to it. - * implement.h (struct ThreadKeyAssoc): Remove lock; add prevKey - and prevThread pointers; re-implemented all routines that use this - struct. The effect of this is to save one handle per association, - which could potentially equal the number of keys multiplied by the - number of threads, accumulating over time - and to free the - association memory as soon as it is no longer referenced by either - the key or the thread. Previously, the handle and memory were - released only after BOTH key and thread no longer referenced the - association. That is, often no association resources were released - until the process itself exited. In addition, at least one race - condition has been removed - where two threads could attempt to - release the association resources simultaneously - one via - ptw32_callUserDestroyRoutines and the other via - pthread_key_delete. - - thanks to Richard Hughes at Aculab for discovering the problem. - * pthread_key_create.c: See above. - * pthread_key_delete.c: See above. - * pthread_setspecific.c: See above. - * ptw32_callUserDestroyRoutines.c: See above. - * ptw32_tkAssocCreate.c: See above. - * ptw32_tkAssocDestroy.c: See above. - -2005-04-27 Ross Johnson - - * sem_wait.c (ptw32_sem_wait_cleanup): after cancellation re-attempt - to acquire the semaphore to avoid a race with a late sem_post. - * sem_timedwait.c: Modify comments. - -2005-04-25 Ross Johnson - - * ptw32_relmillisecs.c: New module; converts future abstime to - milliseconds relative to 'now'. - * pthread_mutex_timedlock.c: Use new ptw32_relmillisecs routine in - place of internal code; remove the NEED_SEM code - this routine is now - implemented for builds that define NEED_SEM (WinCE etc) - * sem_timedwait.c: Likewise; after timeout or cancellation, - re-attempt to acquire the semaphore in case one has been posted since - the timeout/cancel occurred. Thanks to Stefan Mueller. - * Makefile: Add ptw32_relmillisecs.c module; remove - ptw32_{in,de}crease_semaphore.c modules. - * GNUmakefile: Likewise. - * Bmakefile: Likewise. - - * sem_init.c: Re-write the NEED_SEM code to be consistent with the - non-NEED_SEM code, but retaining use of an event in place of the w32 sema - for w32 systems that don't include semaphores (WinCE); - the NEED_SEM versions of semaphores has been broken for a long time but is - now fixed and supports all of the same routines as the non-NEED_SEM case. - * sem_destroy.c: Likewise. - * sem_wait.c: Likewise. - * sem_post.c: Likewise. - * sem_post_multple.c: Likewise. - * implement.h: Likewise. - * sem_timedwait.c: Likewise; this routine is now - implemented for builds that define NEED_SEM (WinCE etc). - * sem_trywait.c: Likewise. - * sem_getvalue.c: Likewise. - - * pthread_once.c: Yet more changes, reverting closer to Gottlob Frege's - first design, but retaining cancellation, priority boosting, and adding - preservation of W32 error codes to make pthread_once transparent to - GetLastError. - -2005-04-11 Ross Johnson - - * pthread_once.c (pthread_once): Added priority boosting to - solve starvation problem after once_routine cancellation. - See notes in file. - -2005-04-06 Kevin Lussier - - * Makefile: Added debug targets for all versions of the library. - -2005-04-01 Ross Johnson - - * GNUmakefile: Add target to build libpthreadGC1.a as a static link - library. - * Makefile: Likewise for pthreadGC1.lib. - -2005-04-01 Kevin Lussier - - * sem_timedwait.c (sem_timedwait): Increase size of temp variables to - avoid int overflows for large timeout values. - * implement.h (int64_t): Include or define. - -2005-03-31 Dimitar Panayotov ^M - - * pthread.h: Fix conditional defines for static linking. - * sched.h: Liekwise. - * semaphore.h: Likewise. - * dll.c (PTW32_STATIC_LIB): Module is conditionally included - in the build. - -2005-03-16 Ross Johnson ^M - - * pthread_setcancelstate.c: Undo the last change. - -2005-03-16 Ross Johnson ^M - - * pthread_setcancelstate.c: Don't check for an async cancel event - if the library is using alertable async cancel.. - -2005-03-14 Ross Johnson - - * 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 - - * 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) { - - 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 - - * pthread_once.c (pthread_once): Redesigned to elliminate potential - starvation problem. - - reported by Gottlob Frege - - * ptw32_threadDestroy.c (ptw32_threadDestroy): Implicit threads were - not closing their Win32 thread duplicate handle. - - reported by Dmitrii Semii - -2005-01-25 Ralf Kubis - - * 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 - - * 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 - - * 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 - - * pthread_getspecific.c (pthread_getspecific): Check for - invalid (NULL) key argument. - -2004-11-19 Ross Johnson - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - * 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 - - * pthread.h: Declare additional types as volatile. - -2004-08-27 Ross Johnson - - * 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 - - * 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 - - * 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 - - * 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 - - * pthread.h (__DMC__): Initial support for Digital Mars compiler. - -2004-06-29 Will Bryant - - * 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 - - * pthread.h (HAVE_STRUCT_TIMESPEC): If undefined, define it - to avoid timespec struct redefined errors elsewhere in an - application. - -2004-06-21 Ross Johnson - - * 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 - - * README.NONPORTABLE: Document pthread_win32_test_features_np(). - * FAQ: Update various answers. - -2004-05-19 Ross Johnson - - * Makefile: Don't define _WIN32_WINNT on compiler command line. - * GNUmakefile: Likewise. - -2004-05-16 Ross Johnson - - * 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 - - * 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 - - * 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 - - * ptw32_threadDestroy.c: Destroy threadLock mutex to - close a memory leak. - -2004-02-13 Gustav Hallberg - - * pthread_equal.c: Remove redundant equality logic. - -2003-12-10 Philippe Di Cristo - - * sem_timedwait.c (sem_timedwait): Fix timeout calculations. - -2003-10-20 Alexander Terekhov - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * w32_cancelableWait.c (ptw32_cancelable_wait): Allow cancelation - of implicit POSIX threads as well. - -2003-09-02 Ross Johnson - - * 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 - - * 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 - - * 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 - - * 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 rather - than old-style ; 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 - - * pthread_spin_destroy.c (pthread_spin_destroy): Was not freeing the - spinlock struct. - -2003-06-22 Nicolas Barry - - * 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 - - * 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 - - * pthread.dsp: Change /MT compile flag to /MD. - -2003-03-04 Alexander Terekhov - - * 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 - -2002-12-17 Thomas Pfaff - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * pthread_cond_destroy.c (pthread_cond_destroy): - Enter the time change critical section earlier. - -2002-02-17 Ross Johnson - - * nonportable.c (pthread_delay_np): Make a true - cancelation point. Deferred cancels will interrupt the - wait. - -2002-02-07 Ross Johnson - - 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 - 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 . - (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 - - 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * attr.c (pthread_attr_setscope): Fix struct pointer - indirection error introduced 2002-01-04. - (pthread_attr_getscope): Likewise. - -2002-01-12 Ross Johnson - - * pthread.dsp (SOURCE): Add missing source files. - -2002-01-08 Ross Johnson - - * 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 , Alexander Terekhov - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * spin.c (pthread_spin_unlock): Was not returning - EPERM if the spinlock was not locked, for multi CPU - machines. - -2001-10-08 Ross Johnson - - * spin.c (pthread_spin_trylock): Was not returning - EBUSY for multi CPU machines. - -2001-08-24 Ross Johnson - - * condvar.c (pthread_cond_destroy): Remove cv element - that is no longer used. - * implement.h: Likewise. - -2001-08-23 Alexander Terekhov - - * 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. - - * tsd.c (pthread_getspecific): Preserve the last - winsock error [from WSAGetLastError()]. - -2001-07-18 Scott McCaskill - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * pthread.h (_POSIX_READER_WRITER_LOCKS): Define it - if not already defined. - -2001-07-01 Alexander Terekhov - - * 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 - - * 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 - - *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 - - * create.c (pthread_create): Set thread priority from - thread attributes. - -2001-06-18 Ross Johnson - - * 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 - - * 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 - - * 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 - - * 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 - - * mutex.c (pthread_mutexattr_init): Remove - ptw32_mutex_default_kind. - -2001-06-05 Ross Johnson - - * 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 - - * condvar.c: Add original description of the algorithm as - developed by Terekhov and Thomas, plus reference to - README.CV. - -2001-06-03 Alexander Terekhov , Louis Thomas - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * FAQ: Update Answer 6 re getting a fully working - Mingw32 built library. - -2000-10-10 Steven Reddie - - * misc.c (pthread_self): Restore Win32 "last error" - cleared by TlsGetValue() call in - pthread_getspecific() - -2000-09-20 Arthur Kantor - - * 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 - - * 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 - - * pthread.h (ctime_r): Fix arg. - -2000-09-08 Ross Johnson - - * 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 - (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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 ; we - use our own local semaphore.h. - -2000-08-10 Ross Johnson - - * 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 - - * pthread.h: Remove #warning - VC++ doesn't accept it. - -2000-08-05 Ross Johnson - - * 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 - - * 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 - - * 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 - - * sched.c (sched_get_priority_max): Handle different WinCE and - Win32 priority values together. - (sched_get_priority_min): Ditto. - -2000-07-25 Ross Johnson - - * 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 - - * 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 - - * FAQ: Added Q5 and Q6. - -2000-07-21 David Baggett - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * Makefile: Remove inconsistencies in 'cl' args - -2000-01-04 Ross Johnson - - * 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 - - * 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 - - * 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 , Erik Hensema - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * pthread.h (ctime_r): Fix incorrect argument "_tm" - -1999-10-21 Aurelio Medina - - * 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 - - * 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 , Peter Slacik - - * 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 - - * condvar.c (cond_wait_cleanup): the last waiter will now reset the CV's - wasBroadcast flag - -Thu Sep 16 1999 Ross Johnson - - * 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 - - * 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 - - * mutex.c (pthread_mutex_destroy): Free mutex memory. - -1999-08-22 Ross Johnson - - * exit.c (pthread_exit): Fix reference to potentially - uninitialised pointer. - -1999-08-21 Ross Johnson - - * 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 - - * private.c (ptw32_threadStart): Return exit status from - the application thread startup routine. - - Milan Gardian - -1999-08-18 John Bossom - - * 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 - - * 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 - - * 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 - - * exit.c (pthread_exit): Don't call pthread_self() but - get thread handle directly from TSD for efficiency. - -1999-08-12 Ross Johnson - - * 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 - - * 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 , John Bossom - - 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 - - * 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 - - * semaphore.h (mode_t): Conditionally typedef it. - -Fri May 28 13:33:05 1999 Mark E. Armstrong - - * condvar.c (pthread_cond_broadcast): Fix possible memory fault - -Thu May 27 13:08:46 1999 Peter Slacik - - * condvar.c (pthread_cond_broadcast): Fix logic bug - -Thu May 27 13:08:46 1999 Bossom, John - - * condvar.c (pthread_cond_broadcast): optimise sem_post loop - -Fri May 14 12:13:18 1999 Mike Russo - - * attr.c (pthread_attr_setdetachstate): Fix logic bug - -Sat May 8 09:42:30 1999 Ross Johnson - - * 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 - - * 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 - - * errno.c (_REENTRANT || _MT): Invert condition. - - * pthread.h (_errno): Conditionally include prototype. - -Wed Apr 7 09:37:00 1999 Ross Johnson - - * *.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 - - * 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 - - * Makefile.in (OBJS): Add errno.o. - -Fri Apr 2 11:08:50 1999 Ross Johnson - - * 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 - - * 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 - - * semaphore.c (ptw32_sem_timedwait): Check for negative - milliseconds. - -Wed Mar 24 11:32:07 1999 John Bossom - - * 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 - - * cancel.c (comments): Update and cleanup. - -Fri Mar 19 09:12:59 1999 Ross Johnson - - * private.c (ptw32_threadStart): status returns PTHREAD_CANCELED. - - * pthread.h (PTHREAD_CANCELED): defined. - -Tue Mar 16 1999 Ross Johnson - - * all: Add GNU LGPL and Copyright and Warranty. - -Mon Mar 15 00:20:13 1999 Ross Johnson - - * condvar.c (pthread_cond_init): fix possible uninitialised use - of cv. - -Sun Mar 14 21:01:59 1999 Ross Johnson - - * 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 - - * 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 - - * misc.c (CancelableWait): Undo changes from Mar 8 and 7. - -Mon Mar 8 11:18:59 1999 Ross Johnson - - * 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 - - * 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 - - * implement.h: Undate comments. - -Sun Feb 21 1999 Ross Johnson - - * pthread.h (PTHREAD_MUTEX_INITIALIZER): missing braces around - cs element initialiser. - -1999-02-21 Ben Elliston - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * configure: Various temporary changes. - - Kevin Ruland - - * README: Update. - - * pthread.def (pthread_attr_getstackaddr): uncomment - (pthread_attr_setstackaddr): uncomment - -Fri Feb 5 13:42:30 1999 Ross Johnson - - * semaphore.c: Comment format changes. - -Thu Feb 4 10:07:28 1999 Ross Johnson - - * 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 - - * 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 - - * sync.c (pthread_join): Check for NULL value_ptr arg; - check for detached threads. - -Tue Feb 2 18:07:43 1999 Ross Johnson - - * implement.h: Add #include . - Change sem_t to ptw32_sem_t. - -Tue Feb 2 18:07:43 1999 Kevin Ruland - - * signal.c (pthread_sigmask): Add and modify casts. - Reverse LHS/RHS bitwise assignments. - - * pthread.h: Remove #include . - (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 - - * 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 - - * pthread.def: Cleanup CVS merge conflicts. - - * global.c: Ditto. - - * ChangeLog: Ditto. - - * cleanup.c: Ditto. - -Sun Jan 24 01:34:52 1999 Ross Johnson - - * semaphore.c (sem_wait): Remove second arg to - pthreadCancelableWait() call. - -Sat Jan 23 17:36:40 1999 Ross Johnson - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * condvar.c (cond_timedwait): Remove comment. - -Fri Jan 15 15:41:28 1999 Ross Johnson - - * 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 - - * 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 - - * build.bat: Delete old binaries before compiling/linking. - -Tue Jan 12 09:58:38 1999 Tor Lillqvist - - * 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 - - * 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 - - * 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 - - * condvar.c (pthread_cond_init): Invert logic when testing the - return value from calloc(). - -Sat Jan 9 14:32:08 1999 Ross Johnson - - * implement.h: Compile-time switch for CYGWIN derived environments - to use CreateThread instead of _beginthreadex. Ditto for ExitThread. - Patch provided by Anders Norlander . - -Tue Jan 5 16:33:04 1999 Ross Johnson - - * 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 which is included by pthread.h. - -1998-12-11 Ben Elliston - - * README: Update info about subscribing to the mailing list. - -Mon Jan 4 11:23:40 1999 Ross Johnson - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * README: Correct cygwin32 compatibility statement. - -Sun Nov 15 21:24:06 1998 Ross Johnson - - * cleanup.c (ptw32_destructor_run_all): Declare missing void * arg. - Fixup CVS merge conflicts. - -1998-10-30 Ben Elliston - - * condvar.c (cond_wait): Fix semantic error. Test for equality - instead of making an assignment. - -Fri Oct 30 15:15:50 1998 Ross Johnson - - * cleanup.c (ptw32_handler_push): Fixed bug appending new - handler to list reported by Peter Slacik - . - (new_thread): Rename poorly named local variable to - "new_handler". - -Sat Oct 24 18:34:59 1998 Ross Johnson - - * global.c: Add TSD key management array and index declarations. - - * implement.h: Ditto for externs. - -Fri Oct 23 00:08:09 1998 Ross Johnson - - * 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 - - * 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 - - * cleanup.c (ptw32_destructor_run_all): Fix and improve - stepping through the key table. - -Thu Oct 15 14:05:01 1998 Ross Johnson - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * condvar.c (cond_wait): Use POSIX, not Win32 mutex calls. - (pthread_cond_broadcast): Likewise. - (pthread_cond_signal): Likewise. - -1998-10-05 Ben Elliston - - * pthread.def: Update. Some functions aren't available yet, others - are macros in . - - * tests/join.c: Remove; useless. - -Mon Oct 5 14:25:08 1998 Ross Johnson - - * pthread.def: New file for building the DLL. - -1998-10-05 Ben Elliston - - * 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 - - * 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 - - * 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 . 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 - - * COPYING: Remove. - - * COPYING.LIB: Add. This library is under the LGPL. - -1998-09-13 Ben Elliston - - * 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 - - * windows.h: No longer needed; remove. - - * windows.c: Likewise. - -Sat Sep 12 20:09:24 1998 Ross Johnson - - * windows.h: Remove error number definitions. These are in - - * tsd.c: Add comment explaining rationale for not building - POSIX TSD on top of Win32 TLS. - -1998-09-12 Ben Elliston - - * {most}.c: Include 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * fork.c (fork): Autoconfiscate. - -Sat Jul 25 00:00:13 1998 Ross Johnson - - * 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 - - * 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 - - * pthread.h (pthread_condattr_t): Rename dummy structure member. - (pthread_mutexattr_t): Likewise. - -Fri Jul 24 21:13:55 1998 Ross Johnson - - * 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 - - * 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 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 - - * 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 - - * sync.c (pthread_detach): Close the Win32 thread handle to - emulate detached (or daemon) threads. - -Fri Jul 24 03:00:25 1998 Ross Johnson - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * implement.h: Preliminary implementation specific defines. - - * create.c (pthread_create): Preliminary implementation. - -1998-07-11 Ben Elliston - - * 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 - - * 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 - - * create.c (pthread_create): A dummy stub right now. - - * pthread.h (pthread_create): Add function prototype. +2011-07-06 Ross Johnson + + * pthread_cond_wait.c (pragma inline_depth): this is almost redundant + now nevertheless fixed thei controlling MSC_VER from "< 800" to + "< 1400" (i.e. any prior to VC++ 8.0). + * pthread_once.ci (pragma inline_depth): Likewise. + * pthread_rwlock_timedwrlock.ci (pragma inline_depth): Likewise. + * pthread_rwlock_wrlock.ci (pragma inline_depth): Likewise. + * sem_timedwait.ci (pragma inline_depth): Likewise. + * sem_wait.ci (pragma inline_depth): Likewise. + +2011-07-05 Ross Johnson + + * pthread_win32_attach_detach_np.c: Use strncat_s if available + to removei a compile warning; MingW supports this routine but we + continue to use strncat anyway there because it is secure if + given the correct parameters; fix strncat param 3 to avoid + buffer overrun exploitation potential. + +2011-07-03 Ross Johnson + + * pthread_spin_unlock.c (EPERM): Return success if unlocking a lock + that is not locked, because single CPU machines wrap a + PTHREAD_MUTEX_NORMAL mutex, which returns success in this case. + * pthread_win32_attach_detach_np.c (QUSEREX.DLL): Load from an + absolute path only which must be the Windows System folder. + +2011-07-03 Daniel Richard G. + + * Makefile (_WIN32_WINNT): Removed; duplicate definition in + implement.h; more cleanup and enhancements. + +2011-07-02 Daniel Richard G. + + * Makefile: Cleanups and implovements. + * ptw32_MCS_locks.c: Casting fixes. + * implement.h: Interlocked call and argument casting macro fixes + to support older and newer build environments. + +2011-07-01 Ross Johnson + + * *.[ch] (PTW32_INTERLOCKED_*): Redo 23 and 64 bit versions of these + macros and re-apply in code to undo the incorrect changes from + 2011-06-29; remove some size_t casts which should not be required + and may be problematic.a + There are now two sets of macros: + PTW32_INTERLOCKED_*_LONG which work only on 32 bit integer variables; + PTW32_INTERLOCKED_*_SIZE which work on size_t integer variables, i.e. + LONG for 32 bit systems and LONGLONG for 64 bit systems. + * implement.h (MCS locks): nextFlag and waitFlag are now HANDLE type. + * ptw32_MCS_locks.c: Likewise. + * pthread.h (#include ): Removed. + * ptw32_throw.c (#include ): Added. + * ptw32_threadStart.c (#include ): Added. + * implement.h (#include ): Added. + +2011-06-30 Ross Johnson + + * pthread_once.c: Tighten 'if' statement casting; fix interlocked + pointer cast for 64 bit compatibility (missed yesterday); remove + the superfluous static cleanup routine and call the release routine + directly if popped. + * create.c (stackSize): Now type size_t. + * pthread.h (struct ptw32_thread_t_): Rearrange to fix element alignments. + +2011-06-29 Daniel Richard G. + + * ptw32_relmillisecs.c (ftime): + _ftime64_s() is only available in MSVC 2005 or later; + _ftime64() is available in MinGW or MSVC 2002 or later; + _ftime() is always available. + * pthread.h (long long): Not defined in older MSVC 6. + * implement.h (long long): Likewise. + * pthread_getunique_np.c (long long): Likewise. + +2011-06-29 Ross Johnson + + * *.[ch] (PTW32_INTERLOCKED_*): These macros should now work for + both 32 and 64 bit builds. The MingW versions are all inlined asm + while the MSVC versions expand to their Interlocked* or Interlocked*64 + counterparts appropriately. The argument type have also been changed + to cast to the appropriate value or pointer size for the architecture. + +2011-05-29 Ross Johnson + + * *.[ch] (#ifdef): Extended cleanup to whole project. + +2011-05-29 Daniel Richard G. + + * Makefile (CC): Define CC to allow use of other compatible + compilers such as the Intel compilter icl. + * implement.h (#if): Fix forms like #if HAVE_SOMETHING. + * pthread.h: Likewise. + * sched.h: Likewise; PTW32_LEVEL_* becomes PTW32_SCHED_LEVEL_*. + * semaphore.h: Likewise. + +2011-05-11 Ross Johnson + + * ptw32_callUserDestroyRoutines.c (terminate): Altered includes + to match ptw32_threadStart.c. + * GNUmakefile (GCE-inlined-debug, DOPT): Fixed. + +2011-04-31 Ross Johnson + + * (robust mutexes): Added this API. The API is not + mandatory for implementations that don't support PROCESS_SHARED + mutexes, nevertheless it was considered useful both functionally + and for source-level compatibility. + +2011-03-26 Ross Johnson + + * pthread_getunique_np.c: New non-POSIX interface for compatibility + with some other implementations; returns a 64 bit sequence number + that is unique to each thread in the process. + * pthread.h (pthread_getunique_np): Added. + * global.c: Add global sequence counter for above. + * implement.h: Likewise. + +2011-03-25 Ross Johnson + + * (cancelLock): Convert to an MCS lock and rename to stateLock. + * (threadLock): Likewise. + * (keyLock): Likewise. + * pthread_mutex*.c: First working robust mutexes. + +2011-03-11 Ross Johnson + + * implement.h (PTW32_INTERLOCKED_*CREMENT macros): increment/decrement + using ++/-- instead of add/subtract 1. + * ptw32_MCS_lock.c: Make casts consistent. + +2011-03-09 Ross Johnson + + * implement.h (ptw32_thread_t_): Add process unique sequence number. + * global.c: Replace global Critical Section objects with MCS + queue locks. + * implement.h: Likewise. + * pthread_cond_destroy.c: Likewise. + * pthread_cond_init.c: Likewise. + * pthread_detach.c: Likewise. + * pthread_join.c: Likewise. + * pthread_kill.c: Likewise. + * pthread_mutex_destroy.c: Likewise. + * pthread_rwlock_destroy.c: Likewise. + * pthread_spin_destroy.c: Likewise. + * pthread_timechange_handler_np.c: Likewise. + * ptw32_cond_check_need_init.c: Likewise. + * ptw32_mutex_check_need_init.c: Likewise. + * ptw32_processInitialize.c: Likewise. + * ptw32_processTerminate.c: Likewise. + * ptw32_reuse.c: Likewise. + * ptw32_rwlock_check_need_init.c: Likewise. + * ptw32_spinlock_check_need_init.c: Likewise. + +2011-03-06 Ross Johnson + + * several (MINGW64): Cast and call fixups for 64 bit compatibility; + clean build via x86_64-w64-mingw32 cross toolchain on Linux i686 + targeting x86_64 win64. + * ptw32_threadStart.c (ptw32_threadStart): Routine no longer attempts + to pass [unexpected C++] exceptions out of scope but ends the thread + normally setting EINTR as the exit status. + * ptw32_throw.c: Fix C++ exception throwing warnings; ignore + informational warning. + * implement.h: Likewise with the corresponding header definition. + +2011-03-04 Ross Johnson + + * implement.h (PTW32_INTERLOCKED_*): Mingw32 does not provide + the __sync_* intrinsics so implemented them here as macro + assembler routines. MSVS Interlocked* are emmitted as intrinsics + wherever possible, so we want mingw to match it; Extended to + include all interlocked routines used by the library; implemented + x86_64 versions also. + * ptw32_InterlockedCompareExchange.c: No code remaining here. + * ptw32_MCS_lock.c: Converted interlocked calls to use new macros. + * pthread_barrier_wait.c: Likewise. + * pthread_once.c: Likewise. + * ptw32_MCS_lock.c (ptw32_mcs_node_substitute): Name changed to + ptw32_mcs_node_transfer. + +2011-02-28 Ross Johnson + + * ptw32_relmillisecs.c: If possible, use _ftime64_s or _ftime64 + before resorting to _ftime. + +2011-02-27 Ross Johnson + + * sched_setscheduler.c: Ensure the handle is closed after use. + * sched_getscheduler.c: Likewise. + * pthread.h: Remove POSIX compatibility macros; don't define + timespec if already defined. + * context.h: Changes for 64 bit. + * pthread_cancel.c: Likewise. + * pthread_exit.c: Likewise. + * pthread_spin_destroy.c: Likewise. + * pthread_timechange_handler_np.c: Likewise. + * ptw32_MCS_lock.c: Likewise; some of these changes may + not be compatible with pre Windows 2000 systems; reverse the order of + the includes. + * ptw32_threadStart.c: Likewise. + * ptw32_throw.c: Likewise. + +2011-02-13 Ross Johnson + + * pthread_self: Add comment re returning 'nil' value to + indicate failure only to win32 threads that call us. + * pthread_attr_setstackaddr: Fix comments; note this + function and it's compliment are now removed from SUSv4. + +2011-02-12 Ross Johnson + + README.NONPORTABLE: Record a description of an obvious + method for nulling/comparing/hashing pthread_t using a + union; plus and investigation of a change of type for + pthread_t (to a union) to neutralise any padding bits and + bytes if they occur in pthread_t (the current pthread_t struct + does not contain padding AFAIK, but porting the library to a + future architecture may introduce them). Padding affects + byte-by-byte copies and compare operations. + +2010-11-16 Ross Johnson + + * ChangeLog: Add this entry ;-) + Restore entries from 2007 through 2009 that went missing + at the last update. + +2010-06-19 Ross Johnson + + * ptw32_MCS_lock.c (ptw32_mcs_node_substitute): Fix variable + names to avoid using C++ keyword ("new"). + * implement.h (ptw32_mcs_node_substitute): Likewise. + * pthread_barrier_wait.c: Fix signed/unsigned comparison warning. + +2010-06-18 Ramiro Polla + + * autostatic.c: New file; call pthread_win32_process_*() + libary init/cleanup routines automatically on application start + when statically linked. + * pthread.c (autostatic.c): Included. + * pthread.h (declspec): Remove import/export defines if compiler + is MINGW. + * sched.h (declspec): Likewise. + * semaphore.h (declspec): Likewise. + * need_errno.h (declspec): Likewise. + * Makefile (autostatic.obj): Add for small static builds. + * GNUmakefile (autostatic.o): Likewise. + * NEWS (Version 2.9.0): Add changes. + * README.NONPORTABLE (pthread_win32_process_*): Update + description. + +2010-06-15 Ramiro Polla + + * Makefile: Remove linkage with the winsock library by default. + * GNUmakefile: Likewise. + * pthread_getspecific.c: Likewise by removing calls to WSA + functions. + * config.h (RETAIN_WSALASTERROR): Can be defined if necessary. + +2010-01-26 Ross Johnson + + * ptw32_MCS_lock.c (ptw32_mcs_node_substitute): New routine + to allow relocating the lock owners thread-local node to somewhere + else, e.g. to global space so that another thread can release the + lock. Used in pthread_barrier_wait. + (ptw32_mcs_lock_try_acquire): New routine. + * pthread_barrier_init: Only one semaphore is used now. + * pthread_barrier_wait: Added an MCS guard lock with the last thread + to leave the barrier releasing the lock. This removes a deadlock bug + observed when there are greater than barrier-count threads + attempting to cross. + * pthread_barrier_destroy: Added an MCS guard lock. + +2009-03-03 Stephan O'Farrill + + * pthread_attr_getschedpolicy.c: Add "const" to function parameter + in accordance with SUSv3 (POSIX). + * pthread_attr_getinheritsched.c: Likewise. + * pthread_mutexattr_gettype.c: Likewise. + +2008-06-06 Robert Kindred + + * ptw32_throw.c (ptw32_throw): Remove possible reference to NULL + pointer. (At the same time made the switch block conditionally + included only if exitCode is needed - RPJ.) + * pthread_testcancel.c (pthread_testcancel): Remove duplicate and + misplaced pthread_mutex_unlock(). + +2008-02-21 Sebastian Gottschalk + + * pthread_attr_getdetachstate.c (pthread_attr_getdetachstate): + Remove potential and superfluous null pointer assignment. + +2007-11-22 Ivan Pizhenko + + * pthread.h (gmtime_r): gmtime returns 0 if tm represents a time + prior to 1/1/1970. Notice this to prevent raising an exception. + * pthread.h (localtime_r): Likewise for localtime. + +2007-07-14 Marcel Ruff + + * errno.c (_errno): Fix test for pthread_self() success. + * need_errno.h: Remove unintentional line wrap from #if line. + +2007-07-14 Mike Romanchuk + + * pthread.h (timespec): Fix tv_sec type. + +2007-01-07 Sinan Kaya + + * need_errno.h: Fix declaration of _errno - the local version of + _errno() is used, e.g. by WinCE. + +2007-01-06 Ross Johnson + + * ptw32_semwait.c: Add check for invalid sem_t after acquiring the + sem_t state guard mutex and before affecting changes to sema state. + +2007-01-06 Marcel Ruff + + * error.c: Fix reference to pthread handle exitStatus member for + builds that use NEED_ERRNO (i.e. WINCE). + * context.h: Add support for ARM processor (WinCE). + * mutex.c (process.h): Exclude for WINCE. + * create.c: Likewise. + * exit.c: Likewise. + * implement.h: Likewise. + * pthread_detach.c (signal.h): Exclude for WINCE. + * pthread_join.c: Likewise. + * pthread_kill.c: Likewise. + * pthread_rwlock_init.c (errno.h): Remove - included by pthread.h. + * pthread_rwlock_destroy.c: Likewise. + * pthread_rwlock_rdlock.c: Likewise. + * pthread_rwlock_timedrdlock.c: Likewise. + * pthread_rwlock_timedwrlock.c: Likewise. + * pthread_rwlock_tryrdlock.c: Likewise. + * pthread_rwlock_trywrlock.c: likewise. + * pthread_rwlock_unlock.c: Likewise. + * pthread_rwlock_wrlock.c: Likewise. + * pthread_rwlockattr_destroy.c: Likewise. + * pthread_rwlockattr_getpshared.c: Likewise. + * pthread_rwlockattr_init.c: Likewise. + * pthread_rwlockattr_setpshared.c: Likewise. + +2007-01-06 Romano Paolo Tenca + + * pthread_cond_destroy.c: Replace sem_wait() with non-cancelable + ptw32_semwait() since pthread_cond_destroy() is not a cancelation + point. + * implement.h (ptw32_spinlock_check_need_init): Add prototype. + * ptw32_MCS_lock.c: Reverse order of includes. + +2007-01-06 Eric Berge + + * pthread_cond_destroy.c: Add LeaveCriticalSection before returning + after errors. + +2007-01-04 Ross Johnson + + * ptw32_InterlockedCompareExchange.c: Conditionally skip for + Win64 as not required. + * pthread_win32_attach_detach_np.c (pthread_win32_process_attach_np): + Test for InterlockedCompareExchange is not required for Win64. + * context.h: New file. Included by pthread_cancel.h and any tests + that need it (e.g. context1.c). + * pthread_cancel.c: Architecture-dependent context macros moved + to context.h. + +2007-01-04 Kip Streithorst + + * implement.h (PTW32_INTERLOCKED_COMPARE_EXCHANGE): Add Win64 + support. + +2006-12-20 Ross Johnson + + * sem_destroy.c: Fix the race involving invalidation of the sema; + fix incorrect return of EBUSY resulting from the mutex trylock + on the private mutex guard. + * sem_wait.c: Add check for invalid sem_t after acquiring the + sem_t state guard mutex and before affecting changes to sema state. + * sem_trywait.c: Likewise. + * sem_timedwait.c: Likewise. + * sem_getvalue.c: Likewise. + * sem_post.c: Similar. + * sem_post_multiple.c: Likewise. + * sem_init.c: Set max Win32 semaphore count to SEM_VALUE_MAX (was + _POSIX_SEM_VALUE_MAX, which is a lower value - the minimum). + + * pthread_win32_attach_detach_np.c (pthread_win32_process_attach_np): + Load COREDLL.DLL under WINCE to check existence of + InterlockedCompareExchange() routine. This used to be done to test + for TryEnterCriticalSection() but was removed when this was no + longer needed. + +2006-01-25 Prashant Thakre + + * pthread_cancel.c: Added _M_IA64 register context support. + +2005-05-13 Ross Johnson + + * pthread_kill.c (pthread_kill): Remove check for Win32 thread + priority (to confirm HANDLE validity). Useless since thread HANDLEs + a not recycle-unique. + +2005-05-30 Vladimir Kliatchko + + * pthread_once.c: Re-implement using an MCS queue-based lock. The form + of pthread_once is as proposed by Alexander Terekhov (see entry of + 2005-03-13). The MCS lock implementation does not require a unique + 'name' to identify the lock between threads. Attempts to get the Event + or Semaphore based versions of pthread_once to a satisfactory level + of robustness have thus far failed. The last problem (avoiding races + involving non recycle-unique Win32 HANDLEs) was giving everyone + grey hair trying to solve it. + + * ptw32_MCS_lock.c: New MCS queue-based lock implementation. These + locks are efficient: they have very low overhead in the uncontended case; + are efficient in contention and minimise cache-coherence updates in + managing the user level FIFO queue; do not require an ABI change in the + library. + +2005-05-27 Alexander Gottwald + + * pthread.h: Some things, like HANDLE, were only defined if + PTW32_LEVEL was >= 3. They should always be defined. + +2005-05-25 Vladimir Kliatchko + + * pthread_once.c: Eliminate all priority operations and other + complexity by replacing the event with a semaphore. The advantage + of the change is the ability to release just one waiter if the + init_routine thread is cancelled yet still release all waiters when + done. Simplify once_control state checks to improve efficiency + further. + +2005-05-24 Mikael Magnusson + + * GNUmakefile: Patched to allow cross-compile with mingw32 on Linux. + It uses macros instead of referencing dlltool, gcc and g++ directly; + added a call to ranlib. For example the GC static library can be + built with: + make CC=i586-mingw32msvc-gcc RC=i586-mingw32msvc-windres \ + RANLIB=i586-mingw32msvc-ranlib clean GC-static + +2005-05-13 Ross Johnson + + * pthread_win32_attach_detach_np.c (pthread_win32_thread_detach_np): + Move on-exit-only stuff from ptw32_threadDestroy() to here. + * ptw32_threadDestroy.c: It's purpose is now only to reclaim thread + resources for detached threads, or via pthread_join() or + pthread_detach() on joinable threads. + * ptw32_threadStart.c: Calling user destruct routines has moved to + pthread_win32_thread_detach_np(); call pthread_win32_thread_detach_np() + directly if statically linking, otherwise do so via dllMain; store + thread return value in thread struct for all cases, including + cancellation and exception exits; thread abnormal exits go via + pthread_win32_thread_detach_np. + * pthread_join.c (pthread_join): Don't try to get return code from + Win32 thread - always get it from he thread struct. + * pthread_detach.c (pthread_detach): reduce extent of the thread + existence check since we now don't care if the Win32 thread HANDLE has + been closed; reclaim thread resources if the thread has exited already. + * ptw32_throw.c (ptw32_throw): For Win32 threads that are not implicit, + only Call thread cleanup if statically linking, otherwise leave it to + dllMain. + * sem_post.c (_POSIX_SEM_VALUE_MAX): Change to SEM_VALUE_MAX. + * sem_post_multiple.c: Likewise. + * sem_init.c: Likewise. + +2005-05-10 Ross Johnson + + * pthread_join.c (pthread_join): Add missing check for thread ID + reference count in thread existence test; reduce extent of the + existence test since we don't care if the Win32 thread HANDLE has + been closed. + +2005-05-09 Ross Johnson + + * ptw32_callUserDestroyRoutines.c: Run destructor process (i.e. + loop over all keys calling destructors) up to + PTHREAD_DESTRUCTOR_ITERATIONS times if TSD value isn't NULL yet; + modify assoc management. + * pthread_key_delete.c: Modify assoc management. + * ptw32_tkAssocDestroy.c: Fix error in assoc removal from chains. + * pthread.h + (_POSIX_THREAD_DESTRUCTOR_ITERATIONS): Define to value specified by + POSIX. + (_POSIX_THREAD_KEYS_MAX): Define to value specified by POSIX. + (PTHREAD_KEYS_MAX): Redefine [upward] to minimum required by POSIX. + (SEM_NSEMS_MAX): Define to implementation value. + (SEM_VALUE_MAX): Define to implementation value. + (_POSIX_SEM_NSEMS_MAX): Redefine to value specified by POSIX. + (_POSIX_SEM_VALUE_MAX): Redefine to value specified by POSIX. + +2005-05-06 Ross Johnson + + * signal.c (sigwait): Add a cancellation point to this otherwise + no-op. + * sem_init.c (sem_init): Check for and return ERANGE error. + * sem_post.c (sem_post): Likewise. + * sem_post_multiple.c (sem_post_multiple): Likewise. + * manual (directory): Added; see ChangeLog inside. + +2005-05-02 Ross Johnson + + * implement.h (struct pthread_key_t_): Change threadsLock to keyLock + so as not to be confused with the per thread lock 'threadlock'; + change all references to it. + * implement.h (struct ThreadKeyAssoc): Remove lock; add prevKey + and prevThread pointers; re-implemented all routines that use this + struct. The effect of this is to save one handle per association, + which could potentially equal the number of keys multiplied by the + number of threads, accumulating over time - and to free the + association memory as soon as it is no longer referenced by either + the key or the thread. Previously, the handle and memory were + released only after BOTH key and thread no longer referenced the + association. That is, often no association resources were released + until the process itself exited. In addition, at least one race + condition has been removed - where two threads could attempt to + release the association resources simultaneously - one via + ptw32_callUserDestroyRoutines and the other via + pthread_key_delete. + - thanks to Richard Hughes at Aculab for discovering the problem. + * pthread_key_create.c: See above. + * pthread_key_delete.c: See above. + * pthread_setspecific.c: See above. + * ptw32_callUserDestroyRoutines.c: See above. + * ptw32_tkAssocCreate.c: See above. + * ptw32_tkAssocDestroy.c: See above. + +2005-04-27 Ross Johnson + + * sem_wait.c (ptw32_sem_wait_cleanup): after cancellation re-attempt + to acquire the semaphore to avoid a race with a late sem_post. + * sem_timedwait.c: Modify comments. + +2005-04-25 Ross Johnson + + * ptw32_relmillisecs.c: New module; converts future abstime to + milliseconds relative to 'now'. + * pthread_mutex_timedlock.c: Use new ptw32_relmillisecs routine in + place of internal code; remove the NEED_SEM code - this routine is now + implemented for builds that define NEED_SEM (WinCE etc) + * sem_timedwait.c: Likewise; after timeout or cancellation, + re-attempt to acquire the semaphore in case one has been posted since + the timeout/cancel occurred. Thanks to Stefan Mueller. + * Makefile: Add ptw32_relmillisecs.c module; remove + ptw32_{in,de}crease_semaphore.c modules. + * GNUmakefile: Likewise. + * Bmakefile: Likewise. + + * sem_init.c: Re-write the NEED_SEM code to be consistent with the + non-NEED_SEM code, but retaining use of an event in place of the w32 sema + for w32 systems that don't include semaphores (WinCE); + the NEED_SEM versions of semaphores has been broken for a long time but is + now fixed and supports all of the same routines as the non-NEED_SEM case. + * sem_destroy.c: Likewise. + * sem_wait.c: Likewise. + * sem_post.c: Likewise. + * sem_post_multple.c: Likewise. + * implement.h: Likewise. + * sem_timedwait.c: Likewise; this routine is now + implemented for builds that define NEED_SEM (WinCE etc). + * sem_trywait.c: Likewise. + * sem_getvalue.c: Likewise. + + * pthread_once.c: Yet more changes, reverting closer to Gottlob Frege's + first design, but retaining cancellation, priority boosting, and adding + preservation of W32 error codes to make pthread_once transparent to + GetLastError. + +2005-04-11 Ross Johnson + + * pthread_once.c (pthread_once): Added priority boosting to + solve starvation problem after once_routine cancellation. + See notes in file. + +2005-04-06 Kevin Lussier + + * Makefile: Added debug targets for all versions of the library. + +2005-04-01 Ross Johnson + + * GNUmakefile: Add target to build libpthreadGC1.a as a static link + library. + * Makefile: Likewise for pthreadGC1.lib. + +2005-04-01 Kevin Lussier + + * sem_timedwait.c (sem_timedwait): Increase size of temp variables to + avoid int overflows for large timeout values. + * implement.h (int64_t): Include or define. + +2005-03-31 Dimitar Panayotov ^M + + * pthread.h: Fix conditional defines for static linking. + * sched.h: Liekwise. + * semaphore.h: Likewise. + * dll.c (PTW32_STATIC_LIB): Module is conditionally included + in the build. + +2005-03-16 Ross Johnson ^M + + * pthread_setcancelstate.c: Undo the last change. + +2005-03-16 Ross Johnson ^M + + * pthread_setcancelstate.c: Don't check for an async cancel event + if the library is using alertable async cancel.. + +2005-03-14 Ross Johnson + + * 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 + + * 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) { + + 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 + + * pthread_once.c (pthread_once): Redesigned to elliminate potential + starvation problem. + - reported by Gottlob Frege + + * ptw32_threadDestroy.c (ptw32_threadDestroy): Implicit threads were + not closing their Win32 thread duplicate handle. + - reported by Dmitrii Semii + +2005-01-25 Ralf Kubis + + * 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 + + * 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 + + * 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 + + * pthread_getspecific.c (pthread_getspecific): Check for + invalid (NULL) key argument. + +2004-11-19 Ross Johnson + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + * 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 + + * pthread.h: Declare additional types as volatile. + +2004-08-27 Ross Johnson + + * 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 + + * 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 + + * 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 + + * 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 + + * pthread.h (__DMC__): Initial support for Digital Mars compiler. + +2004-06-29 Will Bryant + + * 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 + + * pthread.h (HAVE_STRUCT_TIMESPEC): If undefined, define it + to avoid timespec struct redefined errors elsewhere in an + application. + +2004-06-21 Ross Johnson + + * 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 + + * README.NONPORTABLE: Document pthread_win32_test_features_np(). + * FAQ: Update various answers. + +2004-05-19 Ross Johnson + + * Makefile: Don't define _WIN32_WINNT on compiler command line. + * GNUmakefile: Likewise. + +2004-05-16 Ross Johnson + + * 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 + + * 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 + + * 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 + + * ptw32_threadDestroy.c: Destroy threadLock mutex to + close a memory leak. + +2004-02-13 Gustav Hallberg + + * pthread_equal.c: Remove redundant equality logic. + +2003-12-10 Philippe Di Cristo + + * sem_timedwait.c (sem_timedwait): Fix timeout calculations. + +2003-10-20 Alexander Terekhov + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * w32_cancelableWait.c (ptw32_cancelable_wait): Allow cancelation + of implicit POSIX threads as well. + +2003-09-02 Ross Johnson + + * 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 + + * 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 + + * 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 + + * 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 rather + than old-style ; 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 + + * pthread_spin_destroy.c (pthread_spin_destroy): Was not freeing the + spinlock struct. + +2003-06-22 Nicolas Barry + + * 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 + + * 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 + + * pthread.dsp: Change /MT compile flag to /MD. + +2003-03-04 Alexander Terekhov + + * 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 + +2002-12-17 Thomas Pfaff + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * pthread_cond_destroy.c (pthread_cond_destroy): + Enter the time change critical section earlier. + +2002-02-17 Ross Johnson + + * nonportable.c (pthread_delay_np): Make a true + cancelation point. Deferred cancels will interrupt the + wait. + +2002-02-07 Ross Johnson + + 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 + 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 . + (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 + + 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * attr.c (pthread_attr_setscope): Fix struct pointer + indirection error introduced 2002-01-04. + (pthread_attr_getscope): Likewise. + +2002-01-12 Ross Johnson + + * pthread.dsp (SOURCE): Add missing source files. + +2002-01-08 Ross Johnson + + * 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 , Alexander Terekhov + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * spin.c (pthread_spin_unlock): Was not returning + EPERM if the spinlock was not locked, for multi CPU + machines. + +2001-10-08 Ross Johnson + + * spin.c (pthread_spin_trylock): Was not returning + EBUSY for multi CPU machines. + +2001-08-24 Ross Johnson + + * condvar.c (pthread_cond_destroy): Remove cv element + that is no longer used. + * implement.h: Likewise. + +2001-08-23 Alexander Terekhov + + * 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. + + * tsd.c (pthread_getspecific): Preserve the last + winsock error [from WSAGetLastError()]. + +2001-07-18 Scott McCaskill + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * pthread.h (_POSIX_READER_WRITER_LOCKS): Define it + if not already defined. + +2001-07-01 Alexander Terekhov + + * 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 + + * 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 + + *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 + + * create.c (pthread_create): Set thread priority from + thread attributes. + +2001-06-18 Ross Johnson + + * 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 + + * 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 + + * 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 + + * 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 + + * mutex.c (pthread_mutexattr_init): Remove + ptw32_mutex_default_kind. + +2001-06-05 Ross Johnson + + * 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 + + * condvar.c: Add original description of the algorithm as + developed by Terekhov and Thomas, plus reference to + README.CV. + +2001-06-03 Alexander Terekhov , Louis Thomas + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * FAQ: Update Answer 6 re getting a fully working + Mingw32 built library. + +2000-10-10 Steven Reddie + + * misc.c (pthread_self): Restore Win32 "last error" + cleared by TlsGetValue() call in + pthread_getspecific() + +2000-09-20 Arthur Kantor + + * 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 + + * 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 + + * pthread.h (ctime_r): Fix arg. + +2000-09-08 Ross Johnson + + * 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 + (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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 ; we + use our own local semaphore.h. + +2000-08-10 Ross Johnson + + * 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 + + * pthread.h: Remove #warning - VC++ doesn't accept it. + +2000-08-05 Ross Johnson + + * 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 + + * 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 + + * 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 + + * sched.c (sched_get_priority_max): Handle different WinCE and + Win32 priority values together. + (sched_get_priority_min): Ditto. + +2000-07-25 Ross Johnson + + * 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 + + * 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 + + * FAQ: Added Q5 and Q6. + +2000-07-21 David Baggett + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Makefile: Remove inconsistencies in 'cl' args + +2000-01-04 Ross Johnson + + * 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 + + * 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 + + * 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 , Erik Hensema + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * pthread.h (ctime_r): Fix incorrect argument "_tm" + +1999-10-21 Aurelio Medina + + * 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 + + * 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 , Peter Slacik + + * 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 + + * condvar.c (cond_wait_cleanup): the last waiter will now reset the CV's + wasBroadcast flag + +Thu Sep 16 1999 Ross Johnson + + * 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 + + * 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 + + * mutex.c (pthread_mutex_destroy): Free mutex memory. + +1999-08-22 Ross Johnson + + * exit.c (pthread_exit): Fix reference to potentially + uninitialised pointer. + +1999-08-21 Ross Johnson + + * 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 + + * private.c (ptw32_threadStart): Return exit status from + the application thread startup routine. + - Milan Gardian + +1999-08-18 John Bossom + + * 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 + + * 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 + + * 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 + + * exit.c (pthread_exit): Don't call pthread_self() but + get thread handle directly from TSD for efficiency. + +1999-08-12 Ross Johnson + + * 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 + + * 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 , John Bossom + + 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 + + * 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 + + * semaphore.h (mode_t): Conditionally typedef it. + +Fri May 28 13:33:05 1999 Mark E. Armstrong + + * condvar.c (pthread_cond_broadcast): Fix possible memory fault + +Thu May 27 13:08:46 1999 Peter Slacik + + * condvar.c (pthread_cond_broadcast): Fix logic bug + +Thu May 27 13:08:46 1999 Bossom, John + + * condvar.c (pthread_cond_broadcast): optimise sem_post loop + +Fri May 14 12:13:18 1999 Mike Russo + + * attr.c (pthread_attr_setdetachstate): Fix logic bug + +Sat May 8 09:42:30 1999 Ross Johnson + + * 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 + + * 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 + + * errno.c (_REENTRANT || _MT): Invert condition. + + * pthread.h (_errno): Conditionally include prototype. + +Wed Apr 7 09:37:00 1999 Ross Johnson + + * *.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 + + * 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 + + * Makefile.in (OBJS): Add errno.o. + +Fri Apr 2 11:08:50 1999 Ross Johnson + + * 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 + + * 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 + + * semaphore.c (ptw32_sem_timedwait): Check for negative + milliseconds. + +Wed Mar 24 11:32:07 1999 John Bossom + + * 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 + + * cancel.c (comments): Update and cleanup. + +Fri Mar 19 09:12:59 1999 Ross Johnson + + * private.c (ptw32_threadStart): status returns PTHREAD_CANCELED. + + * pthread.h (PTHREAD_CANCELED): defined. + +Tue Mar 16 1999 Ross Johnson + + * all: Add GNU LGPL and Copyright and Warranty. + +Mon Mar 15 00:20:13 1999 Ross Johnson + + * condvar.c (pthread_cond_init): fix possible uninitialised use + of cv. + +Sun Mar 14 21:01:59 1999 Ross Johnson + + * 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 + + * 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 + + * misc.c (CancelableWait): Undo changes from Mar 8 and 7. + +Mon Mar 8 11:18:59 1999 Ross Johnson + + * 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 + + * 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 + + * implement.h: Undate comments. + +Sun Feb 21 1999 Ross Johnson + + * pthread.h (PTHREAD_MUTEX_INITIALIZER): missing braces around + cs element initialiser. + +1999-02-21 Ben Elliston + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * configure: Various temporary changes. + - Kevin Ruland + + * README: Update. + + * pthread.def (pthread_attr_getstackaddr): uncomment + (pthread_attr_setstackaddr): uncomment + +Fri Feb 5 13:42:30 1999 Ross Johnson + + * semaphore.c: Comment format changes. + +Thu Feb 4 10:07:28 1999 Ross Johnson + + * 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 + + * 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 + + * sync.c (pthread_join): Check for NULL value_ptr arg; + check for detached threads. + +Tue Feb 2 18:07:43 1999 Ross Johnson + + * implement.h: Add #include . + Change sem_t to ptw32_sem_t. + +Tue Feb 2 18:07:43 1999 Kevin Ruland + + * signal.c (pthread_sigmask): Add and modify casts. + Reverse LHS/RHS bitwise assignments. + + * pthread.h: Remove #include . + (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 + + * 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 + + * pthread.def: Cleanup CVS merge conflicts. + + * global.c: Ditto. + + * ChangeLog: Ditto. + + * cleanup.c: Ditto. + +Sun Jan 24 01:34:52 1999 Ross Johnson + + * semaphore.c (sem_wait): Remove second arg to + pthreadCancelableWait() call. + +Sat Jan 23 17:36:40 1999 Ross Johnson + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * condvar.c (cond_timedwait): Remove comment. + +Fri Jan 15 15:41:28 1999 Ross Johnson + + * 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 + + * 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 + + * build.bat: Delete old binaries before compiling/linking. + +Tue Jan 12 09:58:38 1999 Tor Lillqvist + + * 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 + + * 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 + + * 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 + + * condvar.c (pthread_cond_init): Invert logic when testing the + return value from calloc(). + +Sat Jan 9 14:32:08 1999 Ross Johnson + + * implement.h: Compile-time switch for CYGWIN derived environments + to use CreateThread instead of _beginthreadex. Ditto for ExitThread. + Patch provided by Anders Norlander . + +Tue Jan 5 16:33:04 1999 Ross Johnson + + * 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 which is included by pthread.h. + +1998-12-11 Ben Elliston + + * README: Update info about subscribing to the mailing list. + +Mon Jan 4 11:23:40 1999 Ross Johnson + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * README: Correct cygwin32 compatibility statement. + +Sun Nov 15 21:24:06 1998 Ross Johnson + + * cleanup.c (ptw32_destructor_run_all): Declare missing void * arg. + Fixup CVS merge conflicts. + +1998-10-30 Ben Elliston + + * condvar.c (cond_wait): Fix semantic error. Test for equality + instead of making an assignment. + +Fri Oct 30 15:15:50 1998 Ross Johnson + + * cleanup.c (ptw32_handler_push): Fixed bug appending new + handler to list reported by Peter Slacik + . + (new_thread): Rename poorly named local variable to + "new_handler". + +Sat Oct 24 18:34:59 1998 Ross Johnson + + * global.c: Add TSD key management array and index declarations. + + * implement.h: Ditto for externs. + +Fri Oct 23 00:08:09 1998 Ross Johnson + + * 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 + + * 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 + + * cleanup.c (ptw32_destructor_run_all): Fix and improve + stepping through the key table. + +Thu Oct 15 14:05:01 1998 Ross Johnson + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * condvar.c (cond_wait): Use POSIX, not Win32 mutex calls. + (pthread_cond_broadcast): Likewise. + (pthread_cond_signal): Likewise. + +1998-10-05 Ben Elliston + + * pthread.def: Update. Some functions aren't available yet, others + are macros in . + + * tests/join.c: Remove; useless. + +Mon Oct 5 14:25:08 1998 Ross Johnson + + * pthread.def: New file for building the DLL. + +1998-10-05 Ben Elliston + + * 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 + + * 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 + + * 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 . 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 + + * COPYING: Remove. + + * COPYING.LIB: Add. This library is under the LGPL. + +1998-09-13 Ben Elliston + + * 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 + + * windows.h: No longer needed; remove. + + * windows.c: Likewise. + +Sat Sep 12 20:09:24 1998 Ross Johnson + + * windows.h: Remove error number definitions. These are in + + * tsd.c: Add comment explaining rationale for not building + POSIX TSD on top of Win32 TLS. + +1998-09-12 Ben Elliston + + * {most}.c: Include 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * fork.c (fork): Autoconfiscate. + +Sat Jul 25 00:00:13 1998 Ross Johnson + + * 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 + + * 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 + + * pthread.h (pthread_condattr_t): Rename dummy structure member. + (pthread_mutexattr_t): Likewise. + +Fri Jul 24 21:13:55 1998 Ross Johnson + + * 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 + + * 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 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 + + * 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 + + * sync.c (pthread_detach): Close the Win32 thread handle to + emulate detached (or daemon) threads. + +Fri Jul 24 03:00:25 1998 Ross Johnson + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * implement.h: Preliminary implementation specific defines. + + * create.c (pthread_create): Preliminary implementation. + +1998-07-11 Ben Elliston + + * 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 + + * 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 + + * create.c (pthread_create): A dummy stub right now. + + * pthread.h (pthread_create): Add function prototype. diff --git a/pthreads/GNUmakefile b/pthreads/GNUmakefile index 66d70da4e..a117dfe51 100644 --- a/pthreads/GNUmakefile +++ b/pthreads/GNUmakefile @@ -1,587 +1,593 @@ -# -# -------------------------------------------------------------------------- -# -# 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 - -# If not. -#RM = erase -#MV = rename -#CP = copy - -# For cross compiling use e.g. -# make CROSS=i386-mingw32msvc- clean GC-inlined -CROSS = - -AR = $(CROSS)ar -DLLTOOL = $(CROSS)dlltool -CC = $(CROSS)gcc -CXX = $(CROSS)g++ -RANLIB = $(CROSS)ranlib -RC = $(CROSS)windres - -OPT = $(CLEANUP) -O3 -finline-functions -DOPT = $(CLEANUP) -g -O0 -XOPT = - -RCFLAGS = --include-dir=. -# Uncomment this if config.h defines RETAIN_WSALASTERROR -#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. -# Pthreads-win32 provides pseudo-unique IDs when the default increment -# (1) is used, but pthread_t is not a scalar type like Solaris's. -# -# 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 (this is the default). -# Set to some other +ve value to emulate smaller word size types -# (i.e. will wrap sooner). -# -#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 \ - autostatic.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_MCS_lock.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_MCS_lock.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 -GCE_STATIC_STAMP = libpthreadGCE$(DLL_VER).stamp -GCED_STATIC_STAMP = libpthreadGCE$(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) CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" $(GC_DLL) - -GC-debug: - $(MAKE) CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="$(DOPT)" $(GCD_DLL) - -GCE: - $(MAKE) CC=$(CXX) CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" $(GCE_DLL) - -GCE-debug: - $(MAKE) CC=$(CXX) CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="$(DOPT)" $(GCED_DLL) - -GC-inlined: - $(MAKE) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_INLINED_STAMP) - -GC-inlined-debug: - $(MAKE) 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=$(CXX) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GCE_INLINED_STAMP) - -GCE-inlined-debug: - $(MAKE) CC=$(CXX) 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) 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) 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) -DPTW32_BUILD_INLINED -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) - $(RANLIB) $(GC_LIB) - 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 + +# If not. +#RM = erase +#MV = rename +#CP = copy + +# For cross compiling use e.g. +# make CROSS=x86_64-w64-mingw32- clean GC-inlined +CROSS = + +AR = $(CROSS)ar +DLLTOOL = $(CROSS)dlltool +CC = $(CROSS)gcc +CXX = $(CROSS)g++ +RANLIB = $(CROSS)ranlib +RC = $(CROSS)windres + +OPT = $(CLEANUP) -O3 # -finline-functions -findirect-inlining +XOPT = + +RCFLAGS = --include-dir=. +# Uncomment this if config.h defines RETAIN_WSALASTERROR +#LFLAGS = -lws2_32 + +# ---------------------------------------------------------------------- +# 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. +# Pthreads-win32 provides pseudo-unique IDs when the default increment +# (1) is used, but pthread_t is not a scalar type like Solaris's. +# +# 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 (this is the default). +# Set to some other +ve value to emulate smaller word size types +# (i.e. will wrap sooner). +# +#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_PTW32_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 \ + autostatic.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_mutexattr_setrobust.o \ + pthread_mutexattr_getrobust.o \ + pthread_mutex_lock.o \ + pthread_mutex_timedlock.o \ + pthread_mutex_unlock.o \ + pthread_mutex_trylock.o \ + pthread_mutex_consistent.o \ + pthread_mutexattr_setkind_np.o \ + pthread_mutexattr_getkind_np.o \ + pthread_getw32threadhandle_np.o \ + pthread_getunique_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_MCS_lock.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_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_MCS_lock.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_mutexattr_setrobust.c \ + pthread_mutexattr_getrobust.c \ + pthread_mutex_lock.c \ + pthread_mutex_timedlock.c \ + pthread_mutex_unlock.c \ + pthread_mutex_trylock.c \ + pthread_mutex_consistent.c + +NONPORTABLE_SRCS = \ + pthread_mutexattr_setkind_np.c \ + pthread_mutexattr_getkind_np.c \ + pthread_getw32threadhandle_np.c \ + pthread_getunique_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_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 +GCE_STATIC_STAMP = libpthreadGCE$(DLL_VER).stamp +GCED_STATIC_STAMP = libpthreadGCE$(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) CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" $(GC_DLL) + +GC-debug: + $(MAKE) CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_C -g -O0" $(GCD_DLL) + +GCE: + $(MAKE) CC=$(CXX) CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" $(GCE_DLL) + +GCE-debug: + $(MAKE) CC=$(CXX) CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_CXX -g -O0" $(GCED_DLL) + +GC-inlined: + $(MAKE) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GC_INLINED_STAMP) + +GC-inlined-debug: + $(MAKE) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_C -g -O0" $(GCD_INLINED_STAMP) + +GCE-inlined: + $(MAKE) CC=$(CXX) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" $(GCE_INLINED_STAMP) + +GCE-inlined-debug: + $(MAKE) CC=$(CXX) XOPT="-DPTW32_BUILD_INLINED" CLEANUP=-D__CLEANUP_CXX XC_FLAGS="$(GCE_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_CXX -g -O0" $(GCED_INLINED_STAMP) + +GC-static: + $(MAKE) 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) XOPT="-DPTW32_BUILD_INLINED -DPTW32_STATIC_LIB" CLEANUP=-D__CLEANUP_C XC_FLAGS="$(GC_CFLAGS)" OBJ="$(DLL_INLINED_OBJS)" DLL_VER=$(DLL_VERD) OPT="-D__CLEANUP_C -g -O0" $(GCD_STATIC_STAMP) + +tests: + @ cd tests + @ $(MAKE) auto + +%.pre: %.c + $(CC) -E -o $@ $(CFLAGS) $^ + +%.s: %.c + $(CC) -c $(CFLAGS) -DPTW32_BUILD_INLINED -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) + $(RANLIB) $(GC_LIB) + echo touched > $(GC_STATIC_STAMP) + +clean: + -$(RM) *~ + -$(RM) *.i + -$(RM) *.s + -$(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) diff --git a/pthreads/Makefile b/pthreads/Makefile index 2dc9d8d40..f1789976f 100644 --- a/pthreads/Makefile +++ b/pthreads/Makefile @@ -1,508 +1,512 @@ -# 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 /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H -CFLAGSD = /Zi $(CFLAGS) - -# Uncomment this if config.h defines RETAIN_WSALASTERROR -#XLIBS = wsock32.lib - -# 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 \ - autostatic.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 \ - autostatic.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 \ - ptw32_MCS_lock.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_MCS_lock.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 $(XLIBS) /out:$@ - -$(INLINED_STAMPS): $(DLL_INLINED_OBJS) - cl /LDd /Zi /nologo $(DLL_INLINED_OBJS) \ - /link /nodefaultlib:libcmt /implib:$*.lib \ - msvcrt.lib $(XLIBS) /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 + +CC = cl +CPPFLAGS = /I. /DHAVE_PTW32_CONFIG_H +XCFLAGS = /W3 /MD /nologo +CFLAGS = /O2 /Ob2 $(XCFLAGS) +CFLAGSD = /Z7 $(XCFLAGS) + +# Uncomment this if config.h defines RETAIN_WSALASTERROR +#XLIBS = wsock32.lib + +# Default cleanup style +CLEANUP = __CLEANUP_C + +# C++ Exceptions +VCEFLAGS = /EHsc /TP $(CPPFLAGS) $(CFLAGS) +VCEFLAGSD = /EHsc /TP $(CPPFLAGS) $(CFLAGSD) +#Structured Exceptions +VSEFLAGS = $(CPPFLAGS) $(CFLAGS) +VSEFLAGSD = $(CPPFLAGS) $(CFLAGSD) +#C cleanup code +VCFLAGS = $(CPPFLAGS) $(CFLAGS) +VCFLAGSD = $(CPPFLAGS) $(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 \ + autostatic.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 \ + autostatic.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_mutexattr_setrobust.obj \ + pthread_mutexattr_getrobust.obj \ + pthread_mutex_lock.obj \ + pthread_mutex_timedlock.obj \ + pthread_mutex_unlock.obj \ + pthread_mutex_trylock.obj \ + pthread_mutex_consistent.obj \ + pthread_mutexattr_setkind_np.obj \ + pthread_mutexattr_getkind_np.obj \ + pthread_getw32threadhandle_np.obj \ + pthread_getunique_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_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 \ + ptw32_MCS_lock.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_MCS_lock.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_mutexattr_setrobust.c \ + pthread_mutexattr_getrobust.c \ + pthread_mutex_lock.c \ + pthread_mutex_timedlock.c \ + pthread_mutex_unlock.c \ + pthread_mutex_trylock.c \ + pthread_mutex_consistent.c + +NONPORTABLE_SRCS = \ + pthread_mutexattr_setkind_np.c \ + pthread_mutexattr_getkind_np.c \ + pthread_getw32threadhandle_np.c \ + pthread_getunique_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_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: + @ $(MAKE) /E clean VCE-inlined + @ $(MAKE) /E clean VSE-inlined + @ $(MAKE) /E clean VC-inlined + @ $(MAKE) /E clean VCE-inlined-debug + @ $(MAKE) /E clean VSE-inlined-debug + @ $(MAKE) /E clean VC-inlined-debug + +VCE: + @ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGS)" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VER).dll + +VCE-debug: + @ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGSD)" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VERD).dll + +VSE: + @ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGS)" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VER).dll + +VSE-debug: + @ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGSD)" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VERD).dll + +VC: + @ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGS)" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).dll + +VC-debug: + @ $(MAKE) /E /nologo EHFLAGS="$(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: + @ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VER).stamp + +VCE-inlined-debug: + @ $(MAKE) /E /nologo EHFLAGS="$(VCEFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_CXX pthreadVCE$(DLL_VERD).stamp + +VSE-inlined: + @ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VER).stamp + +VSE-inlined-debug: + @ $(MAKE) /E /nologo EHFLAGS="$(VSEFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_SEH pthreadVSE$(DLL_VERD).stamp + +VC-inlined: + @ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGS) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).stamp + +VC-inlined-debug: + @ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGSD) /DPTW32_BUILD_INLINED" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VERD).stamp + +VC-static: + @ $(MAKE) /E /nologo EHFLAGS="$(VCFLAGS) /DPTW32_BUILD_INLINED /DPTW32_STATIC_LIB" CLEANUP=__CLEANUP_C pthreadVC$(DLL_VER).static + +VC-static-debug: + @ $(MAKE) /E /nologo EHFLAGS="$(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 *.manifest del *.manifest + if exist *.stamp del *.stamp + +clean: + if exist *.obj del *.obj + if exist *.def del *.def + 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: + copy pthread*.dll $(DLLDEST) + copy pthread*.lib $(LIBDEST) + copy pthread.h $(HDRDEST) + copy sched.h $(HDRDEST) + copy semaphore.h $(HDRDEST) + +$(DLLS): $(DLL_OBJS) + $(CC) /LDd /Zi /nologo $(DLL_OBJS) /link /implib:$*.lib $(XLIBS) /out:$@ + +$(INLINED_STAMPS): $(DLL_INLINED_OBJS) + $(CC) /LDd /Zi /nologo $(DLL_INLINED_OBJS) /link /implib:$*.lib $(XLIBS) /out:$*.dll + +$(STATIC_STAMPS): $(DLL_INLINED_OBJS) + if exist $*.lib del $*.lib + lib $(DLL_INLINED_OBJS) /out:$*.lib + +.c.obj: + $(CC) $(EHFLAGS) /D$(CLEANUP) -c $< + +.rc.res: + rc /dPTW32_RC_MSC /d$(CLEANUP) $< + +.c.i: + $(CC) /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) diff --git a/pthreads/NEWS b/pthreads/NEWS index f713955fe..219fe4e23 100644 --- a/pthreads/NEWS +++ b/pthreads/NEWS @@ -1,1187 +1,1245 @@ -CURRENT CVS HEAD Version -RELEASE 2.9.0 pending -------------- -(2010-??-??) - -General -------- -New bug fixes in this release since 2.8.0 have NOT been applied to the -1.x.x series. - -Version 1 no longer maintained ------------------------------- -The 1.x.x series is no longer maintained. However, if you really need a -version 1, the differences between 1.11.0 and 2.7.0 are very small, mainly -revolving around the pthread_once_t_ struct. Those differences applied -as a patch to the current 2.x.x should work. Don't forget to change -the version numbering in pthread.h before building. If you distribute -such a version 1.x.x please bear in mind that your numbers may clash -with those of others doing the same thing. Please consider also making -identifying changes in version.rc to differentiate your build. - -Testing and verification ------------------------- -The current CVS head version has been tested on an SMP architecture -(AMD Phenom 9750 Quad Core) by running the MinGW32 (GCC) builds against -the full test suite, stress tests and benchmarks. - -New Features ------------- -Dependence on the winsock library is now discretionary via -#define RETAIN_WSALASTERROR in config.h. It is undefined by default unless -WINCE is defined (because I (RJ) am unsure of the dependency there). -- Ramiro Polla - -(MSC and GNU builds) The statically linked library now automatically -initialises and cleans up on program start/exit, i.e. statically linked -applications need not call the routines pthread_win32_process_attach_np() -and pthread_win32_process_detach_np() explicitly. The per-thread routine -pthread_win32_thread_detach_np() is also called at program exit to cleanup -POSIX resources acquired by the primary Windows native thread (if I (RJ) -understand the process correctly). Other Windows native threads that call -POSIX API routines may need to call the thread detach routine on thread -exit if the application depends on reclaimed POSIX resources or running -POSIX TSD (TLS) destructors. -See README.NONPORTABLE for descriptions of these routines. -- Ramiro Polla - -Bug fixes ---------- -Various modifications and fixes to build and test for WinCE. -- Marcel Ruff, Sinan Kaya - -Fix pthread_cond_destroy() - should not be a cancellation point. Other -minor build problems fixed. -- Romano Paolo Tenca - -Remove potential deadlock condition from pthread_cond_destroy(). -- Eric Berge - -Various modifications to build and test for Win64. -- Kip Streithorst - -Various fixes to the QueueUserAPCEx async cancellation helper DLL -(this is a separate download) and pthreads code cleanups. -- Sebastian Gottschalk - -Removed potential NULL pointer reference. -- Robert Kindred - -Removed the requirement that applications restrict the number of threads -calling pthread_barrier_wait() [on the same barrier] to just the barrier -count in order to avoid contention and dead lock. Also reduced the -contention between barrier_wait and barrier_destroy. This change will -have slowed barriers down slightly but halves the number of semaphores -consumed per barrier to one. -- Ross Johnson - -RELEASE 2.8.0 -------------- -(2006-12-22) - -General -------- -New bug fixes in this release since 2.7.0 have not been applied to the -version 1.x.x series. It is probably time to drop version 1. - -Testing and verification ------------------------- -This release has not yet been tested on SMP architechtures. All tests pass -on a uni-processor system. - -Bug fixes ---------- -Sem_destroy could return EBUSY even though no threads were waiting on the -semaphore. Other races around invalidating semaphore structs (internally) -have been removed as well. - -New tests ---------- -semaphore5.c - tests the bug fix referred to above. - - -RELEASE 2.7.0 -------------- -(2005-06-04) - -General -------- -All new features in this release have been back-ported in release 1.11.0, -including the incorporation of MCS locks in pthread_once, however, versions -1 and 2 remain incompatible even though they are now identical in -performance and functionality. - -Testing and verification ------------------------- -This release has been tested (passed the test suite) on both uni-processor -and multi-processor systems. -- Tim Theisen - -Bug fixes ---------- -Pthread_once has been re-implemented to remove priority boosting and other -complexity to improve robustness. Races for Win32 handles that are not -recycle-unique have been removed. The general form of pthread_once is now -the same as that suggested earlier by Alexander Terekhov, but instead of the -'named mutex', a queue-based lock has been implemented which has the required -properties of dynamic self initialisation and destruction. This lock is also -efficient. The ABI is unaffected in as much as the size of pthread_once_t has -not changed and PTHREAD_ONCE_INIT has not changed, however, applications that -peek inside pthread_once_t, which is supposed to be opaque, will break. -- Vladimir Kliatchko - -New features ------------- -* Support for Mingw cross development tools added to GNUmakefile. -Mingw cross tools allow building the libraries on Linux. -- Mikael Magnusson - - -RELEASE 2.6.0 -------------- -(2005-05-19) - -General -------- -All of the bug fixes and new features in this release have been -back-ported in release 1.10.0. - -Testing and verification ------------------------- -This release has been tested (passed the test suite) on both uni-processor -and multi-processor systems. Thanks to Tim Theisen at TomoTherapy for -exhaustively running the MP tests and for providing crutial observations -and data when faults are detected. - -Bugs fixed ----------- - -* pthread_detach() now reclaims remaining thread resources if called after -the target thread has terminated. Previously, this routine did nothing in -this case. - -New tests ---------- - -* detach1.c - tests that pthread_detach properly invalidates the target -thread, which indicates that the thread resources have been reclaimed. - - -RELEASE 2.5.0 -------------- -(2005-05-09) - -General -------- - -The package now includes a reference documentation set consisting of -HTML formatted Unix-style manual pages that have been edited for -consistency with Pthreads-w32. The set can also be read online at: -http://sources.redhat.com/pthreads-win32/manual/index.html - -Thanks again to Tim Theisen for running the test suite pre-release -on an MP system. - -All of the bug fixes and new features in this release have been -back-ported in release 1.9.0. - -Bugs fixed ----------- - -* Thread Specific Data (TSD) key management has been ammended to -eliminate a source of (what was effectively) resource leakage (a HANDLE -plus memory for each key destruct routine/thread association). This was -not a true leak because these resources were eventually reclaimed when -pthread_key_delete was run AND each thread referencing the key had exited. -The problem was that these two conditions are often not met until very -late, and often not until the process is about to exit. - -The ammended implementation avoids the need for the problematic HANDLE -and reclaims the memory as soon as either the key is deleted OR the -thread exits, whichever is first. - -Thanks to Richard Hughes at Aculab for identifying and locating the leak. - -* TSD key destructors are now processed up to PTHREAD_DESTRUCTOR_ITERATIONS -times instead of just once. PTHREAD_DESTRUCTOR_ITERATIONS has been -defined in pthread.h for some time but not used. - -* Fix a semaphore accounting race between sem_post/sem_post_multiple -and sem_wait cancellation. This is the same issue as with -sem_timedwait that was fixed in the last release. - -* sem_init, sem_post, and sem_post_multiple now check that the -semaphore count never exceeds _POSIX_SEM_VALUE_MAX. - -* Although sigwait() is nothing more than a no-op, it should at least -be a cancellation point to be consistent with the standard. - -New tests ---------- - -* stress1.c - attempts to expose problems in condition variable -and semaphore timed wait logic. This test was inspired by Stephan -Mueller's sample test code used to identify the sem_timedwait bug -from the last release. It's not a part of the regular test suite -because it can take awhile to run. To run it: -nmake clean VC-stress - -* tsd2.c - tests that key destructors are re-run if the tsd key value is -not NULL after the destructor routine has run. Also tests that -pthread_setspecific() and pthread_getspecific() are callable from -destructors. - - -RELEASE 2.4.0 -------------- -(2005-04-26) - -General -------- - -There is now no plan to release a version 3.0.0 to fix problems in -pthread_once(). Other possible implementations of pthread_once -will still be investigated for a possible future release in an attempt -to reduce the current implementation's complexity. - -All of the bug fixes and new features in this release have been -back-ported for release 1.8.0. - -Bugs fixed ----------- - -* Fixed pthread_once race (failures on an MP system). Thanks to -Tim Theisen for running exhaustive pre-release testing on his MP system -using a range of compilers: - VC++ 6 - VC++ 7.1 - Intel C++ version 8.0 -All tests passed. -Some minor speed improvements were also done. - -* Fix integer overrun error in pthread_mutex_timedlock() - missed when -sem_timedwait() was fixed in release 2.2.0. This routine no longer returns -ENOTSUP when NEED_SEM is defined - it is supported (NEED_SEM is only -required for WinCE versions prior to 3.0). - -* Fix timeout bug in sem_timedwait(). -- Thanks to Stephan Mueller for reporting, providing diagnostic output -and test code. - -* Fix several problems in the NEED_SEM conditionally included code. -NEED_SEM included code is provided for systems that don't implement W32 -semaphores, such as WinCE prior to version 3.0. An alternate implementation -of POSIX semaphores is built using W32 events for these systems when -NEED_SEM is defined. This code has been completely rewritten in this -release to reuse most of the default POSIX semaphore code, and particularly, -to implement all of the sem_* routines supported by pthreads-win32. Tim -Theisen also run the test suite over the NEED_SEM code on his MP system. All -tests passed. - -* The library now builds without errors for the Borland Builder 5.5 compiler. - -New features ------------- - -* pthread_mutex_timedlock() and all sem_* routines provided by -pthreads-win32 are now implemented for WinCE versions prior to 3.0. Those -versions did not implement W32 semaphores. Define NEED_SEM in config.h when -building the library for these systems. - -Known issues in this release ----------------------------- - -* pthread_once is too complicated - but it works as far as testing can -determine.. - -* The Borland version of the dll fails some of the tests with a memory read -exception. The cause is not yet known but a compiler bug has not been ruled -out. - - -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 - -* 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 - - -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 - -* 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 - -* 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 - -* ptw32_getprocessors() now returns CPU count of 1 for WinCE. -- James Ewing - -* pthread_cond_wait() could be canceled at a point where it should not -be cancelable. Fixed. -- Alexander Terekhov - -* sem_timedwait() had an incorrect timeout calculation. -- Philippe Di Cristo - -* Fix a memory leak left behind after threads are destroyed. -- P. van Bruggen - -New features ------------- -* Ported to AMD64. -- Makoto Kato - -* 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 - -* pthread_win32_process_detach_np() fixed memory leak. -- Steven Reddie - -* pthread_mutex_destroy() fixed incorrect return code. -- Nicolas Barry - -* pthread_spin_destroy() fixed memory leak. -- Piet van Bruggen - -* 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 - -* 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 - -* pthread_mutex_timedlock() no longer occasionally sets incorrect mutex -ownership, causing deadlocks in some applications. -- Robert Strycek and Alexander Terekhov - - -SNAPSHOT 2002-11-04 -------------------- - -Bug fixes ---------- - -* sem_getvalue() now returns the correct value under Win NT and WinCE. -- Rob Fanner - -* 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 - -* 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 - - -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 - -* Removed potential race condition in pthread_mutex_trylock and -pthread_mutex_lock; -- Alexander Terekhov - -* 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 - -* 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. - +CURRENT CVS HEAD Version +RELEASE 2.9.0 pending +------------- +(2011-??-??) + +General +------- +New bug fixes in this release since 2.8.0 have NOT been applied to the +1.x.x series. + +Version 2.8.0 may be the last release for some older Windows systems. +Some changes post 2011-02-26 in CVS may not be compatible with pre +Windows 2000 systems. + +Version 1 no longer maintained +------------------------------ +The 1.x.x series is no longer maintained. However, if you really need a +version 1, the differences between 1.11.0 and 2.7.0 are very small, mainly +revolving around the pthread_once_t_ struct. Those differences applied +as a patch to the current 2.x.x should work. Don't forget to change +the version numbering in pthread.h before building. If you distribute +such a version 1.x.x please bear in mind that your numbers may clash +with those of others doing the same thing. Please consider also making +identifying changes in version.rc to differentiate your build. + +Testing and verification +------------------------ +The current CVS head version has been tested on an SMP architecture +(AMD Phenom 9750 Quad Core) by running the MinGW32 (GCC) builds against +the full test suite, stress tests and benchmarks. + +New Features +------------ +(MSC and GNU builds) The statically linked library now automatically +initialises and cleans up on program start/exit, i.e. statically linked +applications need not call the routines pthread_win32_process_attach_np() +and pthread_win32_process_detach_np() explicitly. The per-thread routine +pthread_win32_thread_detach_np() is also called at program exit to cleanup +POSIX resources acquired by the primary Windows native thread (if I (RJ) +understand the process correctly). Other Windows native threads that call +POSIX API routines may need to call the thread detach routine on thread +exit if the application depends on reclaimed POSIX resources or running +POSIX TSD (TLS) destructors. +See README.NONPORTABLE for descriptions of these routines. +- Ramiro Polla + +Robust mutexes are implemented within the PROCESS_PRIVATE scope. NOTE that +pthread_mutex_* functions may return different error codes for robust +mutexes than they otherwise do in normal usage, e.g. pthread_mutex_unlock +is required to check ownership for all mutex types when the mutex is +robust, whereas this does not occur for the "normal" non-robust mutex type. +- Ross Johnson + +pthread_getunique_np is implemented for source level compatibility +with some other implementations. This routine returns a 64 bit +sequence number that is uniquely associated with a thread. It can be +used by applications to order or hash POSIX thread handles. +- Ross Johnson + +Bug fixes +--------- +Many more changes for 64 bit systems. +- Kai Tietz + +Various modifications and fixes to build and test for WinCE. +- Marcel Ruff, Sinan Kaya + +Fix pthread_cond_destroy() - should not be a cancellation point. Other +minor build problems fixed. +- Romano Paolo Tenca + +Remove potential deadlock condition from pthread_cond_destroy(). +- Eric Berge + +Various modifications to build and test for Win64. +- Kip Streithorst + +Various fixes to the QueueUserAPCEx async cancellation helper DLL +(this is a separate download) and pthreads code cleanups. +- Sebastian Gottschalk + +Removed potential NULL pointer reference. +- Robert Kindred + +Removed the requirement that applications restrict the number of threads +calling pthread_barrier_wait to just the barrier count. Also reduced the +contention between barrier_wait and barrier_destroy. This change will have +slowed barriers down slightly but halves the number of semaphores consumed +per barrier to one. +- Ross Johnson + +Fixed a handle leak in sched_[gs]etscheduler. +- Mark Pizzolato + +Removed all of the POSIX re-entrant function compatibility macros from pthread.h. +Some were simply not semanticly correct. +- Igor Lubashev + +Threads no longer attempt to pass uncaught exceptions out of thread scope (C++ +and SEH builds only). Uncaught exceptions now cause the thread to exit with +the return code PTHREAD_CANCELED. +- Ross Johnson + +Lots of casting fixes particularly for x64, Interlocked fixes and reworking +for x64. +- Daniel Richard G., John Kamp + +Other changes +------------- +Dependence on the winsock library is now discretionary via +#define RETAIN_WSALASTERROR in config.h. It is undefined by default unless +WINCE is defined (because RJ is unsure of the dependency there). +- Ramiro Polla + +Several static POSIX mutexes used for internal management were replaced by +MCS queue-based locks to reduce resource consumption, in particular use of Win32 +objects. +- Ross Johnson + +For security, the QuserEx.dll if used must now be installed in the Windows System +folder. +- Ross Johnson + +New tests +--------- +robust[1-5].c - Robust mutexes +sequence1.c - per-thread unique sequence numbers + +Modified tests and benchtests +----------------------------- +All mutex*.c tests wherever appropriate have been modified to also test +robust mutexes under the same conditions. +Added robust mutex benchtests to benchtest*.c wherever appropriate. + + +RELEASE 2.8.0 +------------- +(2006-12-22) + +General +------- +New bug fixes in this release since 2.7.0 have not been applied to the +version 1.x.x series. It is probably time to drop version 1. + +Testing and verification +------------------------ +This release has not yet been tested on SMP architechtures. All tests pass +on a uni-processor system. + +Bug fixes +--------- +Sem_destroy could return EBUSY even though no threads were waiting on the +semaphore. Other races around invalidating semaphore structs (internally) +have been removed as well. + +New tests +--------- +semaphore5.c - tests the bug fix referred to above. + + +RELEASE 2.7.0 +------------- +(2005-06-04) + +General +------- +All new features in this release have been back-ported in release 1.11.0, +including the incorporation of MCS locks in pthread_once, however, versions +1 and 2 remain incompatible even though they are now identical in +performance and functionality. + +Testing and verification +------------------------ +This release has been tested (passed the test suite) on both uni-processor +and multi-processor systems. +- Tim Theisen + +Bug fixes +--------- +Pthread_once has been re-implemented to remove priority boosting and other +complexity to improve robustness. Races for Win32 handles that are not +recycle-unique have been removed. The general form of pthread_once is now +the same as that suggested earlier by Alexander Terekhov, but instead of the +'named mutex', a queue-based lock has been implemented which has the required +properties of dynamic self initialisation and destruction. This lock is also +efficient. The ABI is unaffected in as much as the size of pthread_once_t has +not changed and PTHREAD_ONCE_INIT has not changed, however, applications that +peek inside pthread_once_t, which is supposed to be opaque, will break. +- Vladimir Kliatchko + +New features +------------ +* Support for Mingw cross development tools added to GNUmakefile. +Mingw cross tools allow building the libraries on Linux. +- Mikael Magnusson + + +RELEASE 2.6.0 +------------- +(2005-05-19) + +General +------- +All of the bug fixes and new features in this release have been +back-ported in release 1.10.0. + +Testing and verification +------------------------ +This release has been tested (passed the test suite) on both uni-processor +and multi-processor systems. Thanks to Tim Theisen at TomoTherapy for +exhaustively running the MP tests and for providing crutial observations +and data when faults are detected. + +Bugs fixed +---------- + +* pthread_detach() now reclaims remaining thread resources if called after +the target thread has terminated. Previously, this routine did nothing in +this case. + +New tests +--------- + +* detach1.c - tests that pthread_detach properly invalidates the target +thread, which indicates that the thread resources have been reclaimed. + + +RELEASE 2.5.0 +------------- +(2005-05-09) + +General +------- + +The package now includes a reference documentation set consisting of +HTML formatted Unix-style manual pages that have been edited for +consistency with Pthreads-w32. The set can also be read online at: +http://sources.redhat.com/pthreads-win32/manual/index.html + +Thanks again to Tim Theisen for running the test suite pre-release +on an MP system. + +All of the bug fixes and new features in this release have been +back-ported in release 1.9.0. + +Bugs fixed +---------- + +* Thread Specific Data (TSD) key management has been ammended to +eliminate a source of (what was effectively) resource leakage (a HANDLE +plus memory for each key destruct routine/thread association). This was +not a true leak because these resources were eventually reclaimed when +pthread_key_delete was run AND each thread referencing the key had exited. +The problem was that these two conditions are often not met until very +late, and often not until the process is about to exit. + +The ammended implementation avoids the need for the problematic HANDLE +and reclaims the memory as soon as either the key is deleted OR the +thread exits, whichever is first. + +Thanks to Richard Hughes at Aculab for identifying and locating the leak. + +* TSD key destructors are now processed up to PTHREAD_DESTRUCTOR_ITERATIONS +times instead of just once. PTHREAD_DESTRUCTOR_ITERATIONS has been +defined in pthread.h for some time but not used. + +* Fix a semaphore accounting race between sem_post/sem_post_multiple +and sem_wait cancellation. This is the same issue as with +sem_timedwait that was fixed in the last release. + +* sem_init, sem_post, and sem_post_multiple now check that the +semaphore count never exceeds _POSIX_SEM_VALUE_MAX. + +* Although sigwait() is nothing more than a no-op, it should at least +be a cancellation point to be consistent with the standard. + +New tests +--------- + +* stress1.c - attempts to expose problems in condition variable +and semaphore timed wait logic. This test was inspired by Stephan +Mueller's sample test code used to identify the sem_timedwait bug +from the last release. It's not a part of the regular test suite +because it can take awhile to run. To run it: +nmake clean VC-stress + +* tsd2.c - tests that key destructors are re-run if the tsd key value is +not NULL after the destructor routine has run. Also tests that +pthread_setspecific() and pthread_getspecific() are callable from +destructors. + + +RELEASE 2.4.0 +------------- +(2005-04-26) + +General +------- + +There is now no plan to release a version 3.0.0 to fix problems in +pthread_once(). Other possible implementations of pthread_once +will still be investigated for a possible future release in an attempt +to reduce the current implementation's complexity. + +All of the bug fixes and new features in this release have been +back-ported for release 1.8.0. + +Bugs fixed +---------- + +* Fixed pthread_once race (failures on an MP system). Thanks to +Tim Theisen for running exhaustive pre-release testing on his MP system +using a range of compilers: + VC++ 6 + VC++ 7.1 + Intel C++ version 8.0 +All tests passed. +Some minor speed improvements were also done. + +* Fix integer overrun error in pthread_mutex_timedlock() - missed when +sem_timedwait() was fixed in release 2.2.0. This routine no longer returns +ENOTSUP when NEED_SEM is defined - it is supported (NEED_SEM is only +required for WinCE versions prior to 3.0). + +* Fix timeout bug in sem_timedwait(). +- Thanks to Stephan Mueller for reporting, providing diagnostic output +and test code. + +* Fix several problems in the NEED_SEM conditionally included code. +NEED_SEM included code is provided for systems that don't implement W32 +semaphores, such as WinCE prior to version 3.0. An alternate implementation +of POSIX semaphores is built using W32 events for these systems when +NEED_SEM is defined. This code has been completely rewritten in this +release to reuse most of the default POSIX semaphore code, and particularly, +to implement all of the sem_* routines supported by pthreads-win32. Tim +Theisen also run the test suite over the NEED_SEM code on his MP system. All +tests passed. + +* The library now builds without errors for the Borland Builder 5.5 compiler. + +New features +------------ + +* pthread_mutex_timedlock() and all sem_* routines provided by +pthreads-win32 are now implemented for WinCE versions prior to 3.0. Those +versions did not implement W32 semaphores. Define NEED_SEM in config.h when +building the library for these systems. + +Known issues in this release +---------------------------- + +* pthread_once is too complicated - but it works as far as testing can +determine.. + +* The Borland version of the dll fails some of the tests with a memory read +exception. The cause is not yet known but a compiler bug has not been ruled +out. + + +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 + +* 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 + + +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 + +* 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 + +* 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 + +* ptw32_getprocessors() now returns CPU count of 1 for WinCE. +- James Ewing + +* pthread_cond_wait() could be canceled at a point where it should not +be cancelable. Fixed. +- Alexander Terekhov + +* sem_timedwait() had an incorrect timeout calculation. +- Philippe Di Cristo + +* Fix a memory leak left behind after threads are destroyed. +- P. van Bruggen + +New features +------------ +* Ported to AMD64. +- Makoto Kato + +* 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 + +* pthread_win32_process_detach_np() fixed memory leak. +- Steven Reddie + +* pthread_mutex_destroy() fixed incorrect return code. +- Nicolas Barry + +* pthread_spin_destroy() fixed memory leak. +- Piet van Bruggen + +* 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 + +* 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 + +* pthread_mutex_timedlock() no longer occasionally sets incorrect mutex +ownership, causing deadlocks in some applications. +- Robert Strycek and Alexander Terekhov + + +SNAPSHOT 2002-11-04 +------------------- + +Bug fixes +--------- + +* sem_getvalue() now returns the correct value under Win NT and WinCE. +- Rob Fanner + +* 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 + +* 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 + + +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 + +* Removed potential race condition in pthread_mutex_trylock and +pthread_mutex_lock; +- Alexander Terekhov + +* 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 + +* 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. + diff --git a/pthreads/Nmakefile b/pthreads/Nmakefile index e6c74dd71..d9e5bf1bc 100644 --- a/pthreads/Nmakefile +++ b/pthreads/Nmakefile @@ -4,7 +4,7 @@ VERSION = - CCFLAGS = -V -g $(CC.DLL) -HAVE_CONFIG_H == 1 +HAVE_PTW32_CONFIG_H == 1 _MT == 1 _timeb == timeb _ftime == ftime diff --git a/pthreads/README b/pthreads/README index 564933302..545360bfa 100644 --- a/pthreads/README +++ b/pthreads/README @@ -31,6 +31,10 @@ MSVC or GNU C (MinGW32 MSys development kit) To build from source. QueueUserAPCEx by Panagiotis E. Hadjidoukas + To support any thread cancelation in C++ library builds or + to support cancelation of blocked threads in any build. + This library is not required otherwise. + 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. @@ -47,6 +51,10 @@ QueueUserAPCEx by Panagiotis E. Hadjidoukas are runnable. The simulated async cancellation cannot cancel blocked threads. + [FOR SECURITY] To be found Quserex.dll MUST be installed in the + Windows System Folder. This is not an unreasonable constraint given a + driver must also be installed and loaded at system startup. + Library naming -------------- @@ -79,8 +87,8 @@ 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 + pthread[VG]{SE,CE,C}[c].dll + pthread[VG]{SE,CE,C}[c].lib where: [VG] indicates the compiler @@ -94,7 +102,7 @@ where: c - DLL compatibility number indicating ABI and API compatibility with applications built against - any snapshot with the same compatibility number. + a snapshot with the same compatibility number. See 'Version numbering' below. The name may also be suffixed by a 'd' to indicate a debugging version @@ -102,7 +110,7 @@ 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: +Examples: pthreadVSE.dll (MSVC/SEH) pthreadGCE.dll (GNUC/C++ EH) pthreadGC.dll (GNUC/not dependent on exceptions) diff --git a/pthreads/README.NONPORTABLE b/pthreads/README.NONPORTABLE index e2d69a72b..0821104d8 100644 --- a/pthreads/README.NONPORTABLE +++ b/pthreads/README.NONPORTABLE @@ -15,6 +15,11 @@ pthread_win32_test_features_np(int mask) PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE Return TRUE if the native version of InterlockedCompareExchange() is being used. + This feature is not meaningful in recent + library versions as MSVC builds only support + system implemented ICE. Note that all Mingw + builds use inlined asm versions of all the + Interlocked routines. PTW32_ALERTABLE_ASYNC_CANCEL Return TRUE is the QueueUserAPCEx package QUSEREX.DLL is available and the AlertDrv.sys @@ -75,11 +80,11 @@ pthread_getw32threadhandle_np(pthread_t thread); DWORD pthread_getw32threadid_np (pthread_t thread) - Returns the win32 thread ID that the POSIX + Returns the Windows native thread ID that the POSIX thread "thread" is running as. Only valid when the library is built where - ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) + ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) and otherwise returns 0. @@ -298,3 +303,481 @@ Thread priority If it wishes, a Win32 application using pthreads-win32 can use the Win32 defined priority macros THREAD_PRIORITY_IDLE through THREAD_PRIORITY_TIME_CRITICAL. + + +The opacity of the pthread_t datatype +------------------------------------- +and possible solutions for portable null/compare/hash, etc +---------------------------------------------------------- + +Because pthread_t is an opague datatype an implementation is permitted to define +pthread_t in any way it wishes. That includes defining some bits, if it is +scalar, or members, if it is an aggregate, to store information that may be +extra to the unique identifying value of the ID. As a result, pthread_t values +may not be directly comparable. + +If you want your code to be portable you must adhere to the following contraints: + +1) Don't assume it is a scalar data type, e.g. an integer or pointer value. There +are several other implementations where pthread_t is also a struct. See our FAQ +Question 11 for our reasons for defining pthread_t as a struct. + +2) You must not compare them using relational or equality operators. You must use +the API function pthread_equal() to test for equality. + +3) Never attempt to reference individual members. + + +The problem + +Certain applications would like to be able to access only the 'pure' pthread_t +id values, primarily to use as keys into data structures to manage threads or +thread-related data, but this is not possible in a maximally portable and +standards compliant way for current POSIX threads implementations. + +For implementations that define pthread_t as a scalar, programmers often employ +direct relational and equality operators on pthread_t. This code will break when +ported to an implementation that defines pthread_t as an aggregate type. + +For implementations that define pthread_t as an aggregate, e.g. a struct, +programmers can use memcmp etc., but then face the prospect that the struct may +include alignment padding bytes or bits as well as extra implementation-specific +members that are not part of the unique identifying value. + +[While this is not currently the case for pthreads-win32, opacity also +means that an implementation is free to change the definition, which should +generally only require that applications be recompiled and relinked, not +rewritten.] + + +Doesn't the compiler take care of padding? + +The C89 and later standards only effectively guarrantee element-by-element +equivalence following an assignment or pass by value of a struct or union, +therefore undefined areas of any two otherwise equivalent pthread_t instances +can still compare differently, e.g. attempting to compare two such pthread_t +variables byte-by-byte, e.g. memcmp(&t1, &t2, sizeof(pthread_t) may give an +incorrect result. In practice I'm reasonably confident that compilers routinely +also copy the padding bytes, mainly because assignment of unions would be far +too complicated otherwise. But it just isn't guarranteed by the standard. + +Illustration: + +We have two thread IDs t1 and t2 + +pthread_t t1, t2; + +In an application we create the threads and intend to store the thread IDs in an +ordered data structure (linked list, tree, etc) so we need to be able to compare +them in order to insert them initially and also to traverse. + +Suppose pthread_t contains undefined padding bits and our compiler copies our +pthread_t [struct] element-by-element, then for the assignment: + +pthread_t temp = t1; + +temp and t1 will be equivalent and correct but a byte-for-byte comparison such as +memcmp(&temp, &t1, sizeof(pthread_t)) == 0 may not return true as we expect because +the undefined bits may not have the same values in the two variable instances. + +Similarly if passing by value under the same conditions. + +If, on the other hand, the undefined bits are at least constant through every +assignment and pass-by-value then the byte-for-byte comparison +memcmp(&temp, &t1, sizeof(pthread_t)) == 0 will always return the expected result. +How can we force the behaviour we need? + + +Solutions + +Adding new functions to the standard API or as non-portable extentions is +the only reliable and portable way to provide the necessary operations. +Remember also that POSIX is not tied to the C language. The most common +functions that have been suggested are: + +pthread_null() +pthread_compare() +pthread_hash() + +A single more general purpose function could also be defined as a +basis for at least the last two of the above functions. + +First we need to list the freedoms and constraints with restpect +to pthread_t so that we can be sure our solution is compatible with the +standard. + +What is known or may be deduced from the standard: +1) pthread_t must be able to be passed by value, so it must be a single object. +2) from (1) it must be copyable so cannot embed thread-state information, locks +or other volatile objects required to manage the thread it associates with. +3) pthread_t may carry additional information, e.g. for debugging or to manage +itself. +4) there is an implicit requirement that the size of pthread_t is determinable +at compile-time and size-invariant, because it must be able to copy the object +(i.e. through assignment and pass-by-value). Such copies must be genuine +duplicates, not merely a copy of a pointer to a common instance such as +would be the case if pthread_t were defined as an array. + + +Suppose we define the following function: + +/* This function shall return it's argument */ +pthread_t* pthread_normalize(pthread_t* thread); + +For scalar or aggregate pthread_t types this function would simply zero any bits +within the pthread_t that don't uniquely identify the thread, including padding, +such that client code can return consistent results from operations done on the +result. If the additional bits are a pointer to an associate structure then +this function would ensure that the memory used to store that associate +structure does not leak. After normalization the following compare would be +valid and repeatable: + +memcmp(pthread_normalize(&t1),pthread_normalize(&t2),sizeof(pthread_t)) + +Note 1: such comparisons are intended merely to order and sort pthread_t values +and allow them to index various data structures. They are not intended to reveal +anything about the relationships between threads, like startup order. + +Note 2: the normalized pthread_t is also a valid pthread_t that uniquely +identifies the same thread. + +Advantages: +1) In most existing implementations this function would reduce to a no-op that +emits no additional instructions, i.e after in-lining or optimisation, or if +defined as a macro: +#define pthread_normalise(tptr) (tptr) + +2) This single function allows an application to portably derive +application-level versions of any of the other required functions. + +3) It is a generic function that could enable unanticipated uses. + +Disadvantages: +1) Less efficient than dedicated compare or hash functions for implementations +that include significant extra non-id elements in pthread_t. + +2) Still need to be concerned about padding if copying normalized pthread_t. +See the later section on defining pthread_t to neutralise padding issues. + +Generally a pthread_t may need to be normalized every time it is used, +which could have a significant impact. However, this is a design decision +for the implementor in a competitive environment. An implementation is free +to define a pthread_t in a way that minimises or eliminates padding or +renders this function a no-op. + +Hazards: +1) Pass-by-reference directly modifies 'thread' so the application must +synchronise access or ensure that the pointer refers to a copy. The alternative +of pass-by-value/return-by-value was considered but then this requires two copy +operations, disadvantaging implementations where this function is not a no-op +in terms of speed of execution. This function is intended to be used in high +frequency situations and needs to be efficient, or at least not unnecessarily +inefficient. The alternative also sits awkwardly with functions like memcmp. + +2) [Non-compliant] code that uses relational and equality operators on +arithmetic or pointer style pthread_t types would need to be rewritten, but it +should be rewritten anyway. + + +C implementation of null/compare/hash functions using pthread_normalize(): + +/* In pthread.h */ +pthread_t* pthread_normalize(pthread_t* thread); + +/* In user code */ +/* User-level bitclear function - clear bits in loc corresponding to mask */ +void* bitclear (void* loc, void* mask, size_t count); + +typedef unsigned int hash_t; + +/* User-level hash function */ +hash_t hash(void* ptr, size_t count); + +/* + * User-level pthr_null function - modifies the origin thread handle. + * The concept of a null pthread_t is highly implementation dependent + * and this design may be far from the mark. For example, in an + * implementation "null" may mean setting a special value inside one + * element of pthread_t to mean "INVALID". However, if that value was zero and + * formed part of the id component then we may get away with this design. + */ +pthread_t* pthr_null(pthread_t* tp) +{ + /* + * This should have the same effect as memset(tp, 0, sizeof(pthread_t)) + * We're just showing that we can do it. + */ + void* p = (void*) pthread_normalize(tp); + return (pthread_t*) bitclear(p, p, sizeof(pthread_t)); +} + +/* + * Safe user-level pthr_compare function - modifies temporary thread handle copies + */ +int pthr_compare_safe(pthread_t thread1, pthread_t thread2) +{ + return memcmp(pthread_normalize(&thread1), pthread_normalize(&thread2), sizeof(pthread_t)); +} + +/* + * Fast user-level pthr_compare function - modifies origin thread handles + */ +int pthr_compare_fast(pthread_t* thread1, pthread_t* thread2) +{ + return memcmp(pthread_normalize(&thread1), pthread_normalize(&thread2), sizeof(pthread_t)); +} + +/* + * Safe user-level pthr_hash function - modifies temporary thread handle copy + */ +hash_t pthr_hash_safe(pthread_t thread) +{ + return hash((void *) pthread_normalize(&thread), sizeof(pthread_t)); +} + +/* + * Fast user-level pthr_hash function - modifies origin thread handle + */ +hash_t pthr_hash_fast(pthread_t thread) +{ + return hash((void *) pthread_normalize(&thread), sizeof(pthread_t)); +} + +/* User-level bitclear function - modifies the origin array */ +void* bitclear(void* loc, void* mask, size_t count) +{ + int i; + for (i=0; i < count; i++) { + (unsigned char) *loc++ &= ~((unsigned char) *mask++); + } +} + +/* Donald Knuth hash */ +hash_t hash(void* str, size_t count) +{ + hash_t hash = (hash_t) count; + unsigned int i = 0; + + for(i = 0; i < len; str++, i++) + { + hash = ((hash << 5) ^ (hash >> 27)) ^ (*str); + } + return hash; +} + +/* Example of advantage point (3) - split a thread handle into its id and non-id values */ +pthread_t id = thread, non-id = thread; +bitclear((void*) &non-id, (void*) pthread_normalize(&id), sizeof(pthread_t)); + + +A pthread_t type change proposal to neutralise the effects of padding + +Even if pthread_nornalize() is available, padding is still a problem because +the standard only garrantees element-by-element equivalence through +copy operations (assignment and pass-by-value). So padding bit values can +still change randomly after calls to pthread_normalize(). + +[I suspect that most compilers take the easy path and always byte-copy anyway, +partly because it becomes too complex to do (e.g. unions that contain sub-aggregates) +but also because programmers can easily design their aggregates to minimise and +often eliminate padding]. + +How can we eliminate the problem of padding bytes in structs? Could +defining pthread_t as a union rather than a struct provide a solution? + +In fact, the Linux pthread.h defines most of it's pthread_*_t objects (but not +pthread_t itself) as unions, possibly for this and/or other reasons. We'll +borrow some element naming from there but the ideas themselves are well known +- the __align element used to force alignment of the union comes from K&R's +storage allocator example. + +/* Essentially our current pthread_t renamed */ +typedef struct { + struct thread_state_t * __p; + long __x; /* sequence counter */ +} thread_id_t; + +Ensuring that the last element in the above struct is a long ensures that the +overall struct size is a multiple of sizeof(long), so there should be no trailing +padding in this struct or the union we define below. +(Later we'll see that we can handle internal but not trailing padding.) + +/* New pthread_t */ +typedef union { + char __size[sizeof(thread_id_t)]; /* array as the first element */ + thread_id_t __tid; + long __align; /* Ensure that the union starts on long boundary */ +} pthread_t; + +This guarrantees that, during an assignment or pass-by-value, the compiler copies +every byte in our thread_id_t because the compiler guarrantees that the __size +array, which we have ensured is the equal-largest element in the union, retains +equivalence. + +This means that pthread_t values stored, assigned and passed by value will at least +carry the value of any undefined padding bytes along and therefore ensure that +those values remain consistent. Our comparisons will return consistent results and +our hashes of [zero initialised] pthread_t values will also return consistent +results. + +We have also removed the need for a pthread_null() function; we can initialise +at declaration time or easily create our own const pthread_t to use in assignments +later: + +const pthread_t null_tid = {0}; /* braces are required */ + +pthread_t t; +... +t = null_tid; + + +Note that we don't have to explicitly make use of the __size array at all. It's +there just to force the compiler behaviour we want. + + +Partial solutions without a pthread_normalize function + + +An application-level pthread_null and pthread_compare proposal +(and pthread_hash proposal by extention) + +In order to deal with the problem of scalar/aggregate pthread_t type disparity in +portable code I suggest using an old-fashioned union, e.g.: + +Contraints: +- there is no padding, or padding values are preserved through assignment and + pass-by-value (see above); +- there are no extra non-id values in the pthread_t. + + +Example 1: A null initialiser for pthread_t variables... + +typedef union { + unsigned char b[sizeof(pthread_t)]; + pthread_t t; +} init_t; + +const init_t initial = {0}; + +pthread_t tid = initial.t; /* init tid to all zeroes */ + + +Example 2: A comparison function for pthread_t values + +typedef union { + unsigned char b[sizeof(pthread_t)]; + pthread_t t; +} pthcmp_t; + +int pthcmp(pthread_t left, pthread_t right) +{ + /* + * Compare two pthread handles in a way that imposes a repeatable but arbitrary + * ordering on them. + * I.e. given the same set of pthread_t handles the ordering should be the same + * each time but the order has no particular meaning other than that. E.g. + * the ordering does not imply the thread start sequence, or any other + * relationship between threads. + * + * Return values are: + * 1 : left is greater than right + * 0 : left is equal to right + * -1 : left is less than right + */ + int i; + pthcmp_t L, R; + L.t = left; + R.t = right; + for (i = 0; i < sizeof(pthread_t); i++) + { + if (L.b[i] > R.b[i]) + return 1; + else if (L.b[i] < R.b[i]) + return -1; + } + return 0; +} + +It has been pointed out that the C99 standard allows for the possibility that +integer types also may include padding bits, which could invalidate the above +method. This addition to C99 was specifically included after it was pointed +out that there was one, presumably not particularly well known, architecture +that included a padding bit in it's 32 bit integer type. See section 6.2.6.2 +of both the standard and the rationale, specifically the paragraph starting at +line 16 on page 43 of the rationale. + + +An aside + +Certain compilers, e.g. gcc and one of the IBM compilers, include a feature +extention: provided the union contains a member of the same type as the +object then the object may be cast to the union itself. + +We could use this feature to speed up the pthrcmp() function from example 2 +above by casting rather than assigning the pthread_t arguments to the union, e.g.: + +int pthcmp(pthread_t left, pthread_t right) +{ + /* + * Compare two pthread handles in a way that imposes a repeatable but arbitrary + * ordering on them. + * I.e. given the same set of pthread_t handles the ordering should be the same + * each time but the order has no particular meaning other than that. E.g. + * the ordering does not imply the thread start sequence, or any other + * relationship between threads. + * + * Return values are: + * 1 : left is greater than right + * 0 : left is equal to right + * -1 : left is less than right + */ + int i; + for (i = 0; i < sizeof(pthread_t); i++) + { + if (((pthcmp_t)left).b[i] > ((pthcmp_t)right).b[i]) + return 1; + else if (((pthcmp_t)left).b[i] < ((pthcmp_t)right).b[i]) + return -1; + } + return 0; +} + + +Result thus far + +We can't remove undefined bits if they are there in pthread_t already, but we have +attempted to render them inert for comparison and hashing functions by making them +consistent through assignment, copy and pass-by-value. + +Note: Hashing pthread_t values requires that all pthread_t variables be initialised +to the same value (usually all zeros) before being assigned a proper thread ID, i.e. +to ensure that any padding bits are zero, or at least the same value for all +pthread_t. Since all pthread_t values are generated by the library in the first +instance this need not be an application-level operation. + + +Conclusion + +I've attempted to resolve the multiple issues of type opacity and the possible +presence of undefined bits and bytes in pthread_t values, which prevent +applications from comparing or hashing pthread handles. + +Two complimentary partial solutions have been proposed, one an application-level +scheme to handle both scalar and aggregate pthread_t types equally, plus a +definition of pthread_t itself that neutralises padding bits and bytes by +coercing semantics out of the compiler to eliminate variations in the values of +padding bits. + +I have not provided any solution to the problem of handling extra values embedded +in pthread_t, e.g. debugging or trap information that an implementation is entitled +to include. Therefore none of this replaces the portability and flexibility of API +functions but what functions are needed? The threads standard is unlikely to +include that can be implemented by a combination of existing features and more +generic functions (several references in the threads rationale suggest this. +Therefore I propose that the following function could replace the several functions +that have been suggested in conversations: + +pthread_t * pthread_normalize(pthread_t * handle); + +For most existing pthreads implementations this function, or macro, would reduce to +a no-op with zero call overhead. diff --git a/pthreads/autostatic.c b/pthreads/autostatic.c index 12137a6cd..092aff2ae 100644 --- a/pthreads/autostatic.c +++ b/pthreads/autostatic.c @@ -1,69 +1,69 @@ -/* - * pthread_barrier_wait.c - * - * Description: - * This translation unit implements barrier 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 - */ - -#ifdef PTW32_STATIC_LIB - -#if defined(__MINGW32__) || defined(_MSC_VER) - -#include "pthread.h" -#include "implement.h" - -static void on_process_init(void) -{ - pthread_win32_process_attach_np (); -} - -static void on_process_exit(void) -{ - pthread_win32_thread_detach_np (); - pthread_win32_process_detach_np (); -} - -#if defined(__MINGW32__) -# define attribute_section(a) __attribute__((section(a))) -#elif defined(_MSC_VER) -# define attribute_section(a) __pragma(section(a,long,read)); __declspec(allocate(a)) -#endif - -attribute_section(".ctors") void *gcc_ctor = on_process_init; -attribute_section(".dtors") void *gcc_dtor = on_process_exit; - -attribute_section(".CRT$XCU") void *msc_ctor = on_process_init; -attribute_section(".CRT$XPU") void *msc_dtor = on_process_exit; - -#endif /* defined(__MINGW32__) || defined(_MSC_VER) */ - -#endif /* PTW32_STATIC_LIB */ +/* + * autostatic.c + * + * Description: + * This translation unit implements static auto-init and auto-exit logic. + * + * -------------------------------------------------------------------------- + * + * 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(PTW32_STATIC_LIB) + +#if defined(__MINGW64__) || defined(__MINGW32__) || defined(_MSC_VER) + +#include "pthread.h" +#include "implement.h" + +static void on_process_init(void) +{ + pthread_win32_process_attach_np (); +} + +static void on_process_exit(void) +{ + pthread_win32_thread_detach_np (); + pthread_win32_process_detach_np (); +} + +#if defined(__MINGW64__) || defined(__MINGW32__) +# define attribute_section(a) __attribute__((section(a))) +#elif defined(_MSC_VER) +# define attribute_section(a) __pragma(section(a,long,read)); __declspec(allocate(a)) +#endif + +attribute_section(".ctors") void *gcc_ctor = on_process_init; +attribute_section(".dtors") void *gcc_dtor = on_process_exit; + +attribute_section(".CRT$XCU") void *msc_ctor = on_process_init; +attribute_section(".CRT$XPU") void *msc_dtor = on_process_exit; + +#endif /* defined(__MINGW64__) || defined(__MINGW32__) || defined(_MSC_VER) */ + +#endif /* PTW32_STATIC_LIB */ diff --git a/pthreads/builddmc.bat b/pthreads/builddmc.bat index 3edbaebb3..bf813d816 100644 --- a/pthreads/builddmc.bat +++ b/pthreads/builddmc.bat @@ -3,7 +3,7 @@ set DMCDIR=c:\dm ; RELEASE -%DMCDIR%\bin\dmc -D_WIN32_WINNT -D_MT -DHAVE_CONFIG_H -I.;c:\dm\include -o+all -WD pthread.c user32.lib+kernel32.lib+wsock32.lib -L/impl -L/NODEBUG -L/SU:WINDOWS +%DMCDIR%\bin\dmc -D_WIN32_WINNT -D_MT -DHAVE_PTW32_CONFIG_H -I.;c:\dm\include -o+all -WD pthread.c user32.lib+kernel32.lib+wsock32.lib -L/impl -L/NODEBUG -L/SU:WINDOWS ; DEBUG -%DMCDIR%\bin\dmc -g -D_WIN32_WINNT -D_MT -DHAVE_CONFIG_H -I.;c:\dm\include -o+all -WD pthread.c user32.lib+kernel32.lib+wsock32.lib -L/impl -L/SU:WINDOWS +%DMCDIR%\bin\dmc -g -D_WIN32_WINNT -D_MT -DHAVE_PTW32_CONFIG_H -I.;c:\dm\include -o+all -WD pthread.c user32.lib+kernel32.lib+wsock32.lib -L/impl -L/SU:WINDOWS diff --git a/pthreads/config.h b/pthreads/config.h index 343d63049..e231724e3 100644 --- a/pthreads/config.h +++ b/pthreads/config.h @@ -1,142 +1,153 @@ -/* config.h */ - -#ifndef PTW32_CONFIG_H -#define PTW32_CONFIG_H - -/********************************************************************* - * Defaults: see target specific redefinitions below. - *********************************************************************/ - -/* We're building the pthreads-win32 library */ -#define PTW32_BUILD - -/* Do we know about the C type sigset_t? */ -#undef HAVE_SIGSET_T - -/* Define if you have the header file. */ -#undef HAVE_SIGNAL_H - -/* Define if you have the Borland TASM32 or compatible assembler. */ -#undef HAVE_TASM32 - -/* Define if you don't have Win32 DuplicateHandle. (eg. WinCE) */ -#undef NEED_DUPLICATEHANDLE - -/* Define if you don't have Win32 _beginthreadex. (eg. WinCE) */ -#undef NEED_CREATETHREAD - -/* Define if you don't have Win32 errno. (eg. WinCE) */ -#undef NEED_ERRNO - -/* Define if you don't have Win32 calloc. (eg. WinCE) */ -#undef NEED_CALLOC - -/* Define if you don't have Win32 ftime. (eg. WinCE) */ -#undef NEED_FTIME - -/* Define if you don't have Win32 semaphores. (eg. WinCE 2.1 or earlier) */ -#undef NEED_SEM - -/* Define if you need to convert string parameters to unicode. (eg. WinCE) */ -#undef NEED_UNICODE_CONSTS - -/* Define if your C (not C++) compiler supports "inline" functions. */ -#undef HAVE_C_INLINE - -/* Do we know about type mode_t? */ -#undef HAVE_MODE_T - -/* Define if you have the timespec struct */ -#undef HAVE_STRUCT_TIMESPEC - -/* Define if you don't have the GetProcessAffinityMask() */ -#undef NEED_PROCESS_AFFINITY_MASK - -/* Define if your version of Windows TLSGetValue() clears WSALastError - * and calling SetLastError() isn't enough restore it. You'll also need to - * link against wsock32.lib (or libwsock32.a for MinGW). - */ -#undef RETAIN_WSALASTERROR - -/* -# ---------------------------------------------------------------------- -# The library can be built with some alternative behaviour to better -# facilitate development of applications on Win32 that will be ported -# to other POSIX systems. -# -# Nothing described here will make the library non-compliant and strictly -# compliant applications will not be affected in any way, but -# applications that make assumptions that POSIX does not guarantee are -# not strictly compliant and may fail or misbehave with 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. -# This provides a very high but finite level of safety for applications -# that are not meticulous in tracking thread lifecycles e.g. applications -# that call functions which target detached threads without some form of -# thread exit synchronisation. -# -# Usage: -# Set to any value in the range: 0 <= value < 2^wordsize. -# Set to 0 to emulate reusable thread ID behaviour like Linux or *BSD. -# Set to 1 for unique thread IDs like Solaris (this is the default). -# Set to some factor of 2^wordsize to emulate smaller word size types -# (i.e. will wrap sooner). This might be useful to emulate some embedded -# systems. -# -# define PTW32_THREAD_ID_REUSE_INCREMENT 0 -# -# ---------------------------------------------------------------------- - */ -#undef PTW32_THREAD_ID_REUSE_INCREMENT - - -/********************************************************************* - * Target specific groups - * - * If you find that these are incorrect or incomplete please report it - * to the pthreads-win32 maintainer. Thanks. - *********************************************************************/ -#ifdef WINCE -#define NEED_DUPLICATEHANDLE -#define NEED_CREATETHREAD -#define NEED_ERRNO -#define NEED_CALLOC -#define NEED_FTIME -/* #define NEED_SEM */ -#define NEED_UNICODE_CONSTS -#define NEED_PROCESS_AFFINITY_MASK -/* This may not be needed */ -#define RETAIN_WSALASTERROR -#endif - -#ifdef _UWIN -#define HAVE_MODE_T -#define HAVE_STRUCT_TIMESPEC -#endif - -#ifdef __GNUC__ -#define HAVE_C_INLINE -#endif - -#ifdef __MINGW32__ -#define HAVE_MODE_T -#endif - -#ifdef __BORLANDC__ -#endif - -#ifdef __WATCOMC__ -#endif - -#ifdef __DMC__ -#define HAVE_SIGNAL_H -#define HAVE_C_INLINE -#endif - - - -#endif +/* config.h */ + +#ifndef PTW32_CONFIG_H +#define PTW32_CONFIG_H + +/********************************************************************* + * Defaults: see target specific redefinitions below. + *********************************************************************/ + +/* We're building the pthreads-win32 library */ +#define PTW32_BUILD + +/* Do we know about the C type sigset_t? */ +#undef HAVE_SIGSET_T + +/* Define if you have the header file. */ +#undef HAVE_SIGNAL_H + +/* Define if you have the Borland TASM32 or compatible assembler. */ +#undef HAVE_TASM32 + +/* Define if you don't have Win32 DuplicateHandle. (eg. WinCE) */ +#undef NEED_DUPLICATEHANDLE + +/* Define if you don't have Win32 _beginthreadex. (eg. WinCE) */ +#undef NEED_CREATETHREAD + +/* Define if you don't have Win32 errno. (eg. WinCE) */ +#undef NEED_ERRNO + +/* Define if you don't have Win32 calloc. (eg. WinCE) */ +#undef NEED_CALLOC + +/* Define if you don't have Win32 ftime. (eg. WinCE) */ +#undef NEED_FTIME + +/* Define if you don't have Win32 semaphores. (eg. WinCE 2.1 or earlier) */ +#undef NEED_SEM + +/* Define if you need to convert string parameters to unicode. (eg. WinCE) */ +#undef NEED_UNICODE_CONSTS + +/* Define if your C (not C++) compiler supports "inline" functions. */ +#undef HAVE_C_INLINE + +/* Do we know about type mode_t? */ +#undef HAVE_MODE_T + +/* + * Define if GCC has atomic builtins, i.e. __sync_* intrinsics + * __sync_lock_* is implemented in mingw32 gcc 4.5.2 at least + * so this define does not turn those on or off. If you get an + * error from __sync_lock* then consider upgrading your gcc. + */ +#undef HAVE_GCC_ATOMIC_BUILTINS + +/* Define if you have the timespec struct */ +#undef HAVE_STRUCT_TIMESPEC + +/* Define if you don't have the GetProcessAffinityMask() */ +#undef NEED_PROCESS_AFFINITY_MASK + +/* Define if your version of Windows TLSGetValue() clears WSALastError + * and calling SetLastError() isn't enough restore it. You'll also need to + * link against wsock32.lib (or libwsock32.a for MinGW). + */ +#undef RETAIN_WSALASTERROR + +/* +# ---------------------------------------------------------------------- +# The library can be built with some alternative behaviour to better +# facilitate development of applications on Win32 that will be ported +# to other POSIX systems. +# +# Nothing described here will make the library non-compliant and strictly +# compliant applications will not be affected in any way, but +# applications that make assumptions that POSIX does not guarantee are +# not strictly compliant and may fail or misbehave with 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. +# This provides a very high but finite level of safety for applications +# that are not meticulous in tracking thread lifecycles e.g. applications +# that call functions which target detached threads without some form of +# thread exit synchronisation. +# +# Usage: +# Set to any value in the range: 0 <= value < 2^wordsize. +# Set to 0 to emulate reusable thread ID behaviour like Linux or *BSD. +# Set to 1 for unique thread IDs like Solaris (this is the default). +# Set to some factor of 2^wordsize to emulate smaller word size types +# (i.e. will wrap sooner). This might be useful to emulate some embedded +# systems. +# +# define PTW32_THREAD_ID_REUSE_INCREMENT 0 +# +# ---------------------------------------------------------------------- + */ +#undef PTW32_THREAD_ID_REUSE_INCREMENT + + +/********************************************************************* + * Target specific groups + * + * If you find that these are incorrect or incomplete please report it + * to the pthreads-win32 maintainer. Thanks. + *********************************************************************/ +#if defined(WINCE) +#define NEED_DUPLICATEHANDLE +#define NEED_CREATETHREAD +#define NEED_ERRNO +#define NEED_CALLOC +#define NEED_FTIME +/* #define NEED_SEM */ +#define NEED_UNICODE_CONSTS +#define NEED_PROCESS_AFFINITY_MASK +/* This may not be needed */ +#define RETAIN_WSALASTERROR +#endif + +#if defined(_UWIN) +#define HAVE_MODE_T +#define HAVE_STRUCT_TIMESPEC +#endif + +#if defined(__GNUC__) +#define HAVE_C_INLINE +#endif + +#if defined(__MINGW64__) +#define HAVE_MODE_T +#define HAVE_STRUCT_TIMESPEC +#elif defined(__MINGW32__) +#define HAVE_MODE_T +#endif + +#if defined(__BORLANDC__) +#endif + +#if defined(__WATCOMC__) +#endif + +#if defined(__DMC__) +#define HAVE_SIGNAL_H +#define HAVE_C_INLINE +#endif + + + +#endif diff --git a/pthreads/context.h b/pthreads/context.h index 65e050bd5..3d4511f5b 100644 --- a/pthreads/context.h +++ b/pthreads/context.h @@ -1,74 +1,74 @@ -/* - * context.h - * - * Description: - * POSIX thread macros related to thread cancellation. - * - * -------------------------------------------------------------------------- - * - * 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 PTW32_CONTEXT_H -#define PTW32_CONTEXT_H - -#undef PTW32_PROGCTR - -#if defined(_M_IX86) || defined(_X86_) -#define PTW32_PROGCTR(Context) ((Context).Eip) -#endif - -#if defined (_M_IA64) || defined(_IA64) -#define PTW32_PROGCTR(Context) ((Context).StIIP) -#endif - -#if defined(_MIPS_) || defined(MIPS) -#define PTW32_PROGCTR(Context) ((Context).Fir) -#endif - -#if defined(_ALPHA_) -#define PTW32_PROGCTR(Context) ((Context).Fir) -#endif - -#if defined(_PPC_) -#define PTW32_PROGCTR(Context) ((Context).Iar) -#endif - -#if defined(_AMD64_) || defined(__amd64__) -#define PTW32_PROGCTR(Context) ((Context).Rip) -#endif - -#if defined(_ARM_) || defined(ARM) -#define PTW32_PROGCTR(Context) ((Context).Pc) -#endif - -#if !defined(PTW32_PROGCTR) -#error Module contains CPU-specific code; modify and recompile. -#endif - -#endif +/* + * context.h + * + * Description: + * POSIX thread macros related to thread cancellation. + * + * -------------------------------------------------------------------------- + * + * 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 PTW32_CONTEXT_H +#define PTW32_CONTEXT_H + +#undef PTW32_PROGCTR + +#if defined(_M_IX86) || (defined(_X86_) && !defined(__amd64__)) +#define PTW32_PROGCTR(Context) ((Context).Eip) +#endif + +#if defined (_M_IA64) || defined(_IA64) +#define PTW32_PROGCTR(Context) ((Context).StIIP) +#endif + +#if defined(_MIPS_) || defined(MIPS) +#define PTW32_PROGCTR(Context) ((Context).Fir) +#endif + +#if defined(_ALPHA_) +#define PTW32_PROGCTR(Context) ((Context).Fir) +#endif + +#if defined(_PPC_) +#define PTW32_PROGCTR(Context) ((Context).Iar) +#endif + +#if defined(_AMD64_) || defined(__amd64__) +#define PTW32_PROGCTR(Context) ((Context).Rip) +#endif + +#if defined(_ARM_) || defined(ARM) +#define PTW32_PROGCTR(Context) ((Context).Pc) +#endif + +#if !defined(PTW32_PROGCTR) +#error Module contains CPU-specific code; modify and recompile. +#endif + +#endif diff --git a/pthreads/create.c b/pthreads/create.c index 3c97db082..e15418588 100644 --- a/pthreads/create.c +++ b/pthreads/create.c @@ -1,305 +1,308 @@ -/* - * create.c - * - * Description: - * This translation unit implements routines associated with spawning a new - * thread. - * - * -------------------------------------------------------------------------- - * - * 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" -#if ! defined(_UWIN) && ! defined(WINCE) -#include -#endif - -int -pthread_create (pthread_t * tid, - const pthread_attr_t * attr, - void *(*start) (void *), void *arg) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function creates a thread running the start function, - * passing it the parameter value, 'arg'. The 'attr' - * argument specifies optional creation attributes. - * The identity of the new thread is returned - * via 'tid', which should not be NULL. - * - * PARAMETERS - * tid - * pointer to an instance of pthread_t - * - * attr - * optional pointer to an instance of pthread_attr_t - * - * start - * pointer to the starting routine for the new thread - * - * arg - * optional parameter passed to 'start' - * - * - * DESCRIPTION - * This function creates a thread running the start function, - * passing it the parameter value, 'arg'. The 'attr' - * argument specifies optional creation attributes. - * The identity of the new thread is returned - * via 'tid', which should not be the NULL pointer. - * - * RESULTS - * 0 successfully created thread, - * EINVAL attr invalid, - * EAGAIN insufficient resources. - * - * ------------------------------------------------------ - */ -{ - pthread_t thread; - ptw32_thread_t * tp; - register pthread_attr_t a; - HANDLE threadH = 0; - int result = EAGAIN; - int run = PTW32_TRUE; - ThreadParms *parms = NULL; - long stackSize; - int priority; - pthread_t self; - - /* - * Before doing anything, check that tid can be stored through - * without invoking a memory protection error (segfault). - * Make sure that the assignment below can't be optimised out by the compiler. - * This is assured by conditionally assigning *tid again at the end. - */ - tid->x = 0; - - if (attr != NULL) - { - a = *attr; - } - else - { - a = NULL; - } - - if ((thread = ptw32_new ()).p == NULL) - { - goto FAIL0; - } - - tp = (ptw32_thread_t *) thread.p; - - priority = tp->sched_priority; - - if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == NULL) - { - goto FAIL0; - } - - parms->tid = thread; - parms->start = start; - parms->arg = arg; - -#if defined(HAVE_SIGSET_T) - - /* - * Threads inherit their initial sigmask from their creator thread. - */ - self = pthread_self(); - tp->sigmask = ((ptw32_thread_t *)self.p)->sigmask; - -#endif /* HAVE_SIGSET_T */ - - - if (a != NULL) - { - stackSize = a->stacksize; - tp->detachState = a->detachstate; - priority = a->param.sched_priority; - -#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL) - /* WinCE */ -#else - /* Everything else */ - - /* - * Thread priority must be set to a valid system level - * without altering the value set by pthread_attr_setschedparam(). - */ - - /* - * PTHREAD_EXPLICIT_SCHED is the default because Win32 threads - * don't inherit their creator's priority. They are started with - * THREAD_PRIORITY_NORMAL (win32 value). The result of not supplying - * an 'attr' arg to pthread_create() is equivalent to defaulting to - * PTHREAD_EXPLICIT_SCHED and priority THREAD_PRIORITY_NORMAL. - */ - if (PTHREAD_INHERIT_SCHED == a->inheritsched) - { - /* - * If the thread that called pthread_create() is a Win32 thread - * then the inherited priority could be the result of a temporary - * system adjustment. This is not the case for POSIX threads. - */ -#if ! defined(HAVE_SIGSET_T) - self = pthread_self (); -#endif - priority = ((ptw32_thread_t *) self.p)->sched_priority; - } - -#endif - - } - else - { - /* - * Default stackSize - */ - stackSize = PTHREAD_STACK_MIN; - } - - tp->state = run ? PThreadStateInitial : PThreadStateSuspended; - - tp->keys = NULL; - - /* - * Threads must be started in suspended mode and resumed if necessary - * after _beginthreadex returns us the handle. Otherwise we set up a - * race condition between the creating and the created threads. - * Note that we also retain a local copy of the handle for use - * by us in case thread.p->threadH gets NULLed later but before we've - * finished with it here. - */ - -#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) - - tp->threadH = - threadH = - (HANDLE) _beginthreadex ((void *) NULL, /* No security info */ - (unsigned) stackSize, /* default stack size */ - ptw32_threadStart, - parms, - (unsigned) - CREATE_SUSPENDED, - (unsigned *) &(tp->thread)); - - if (threadH != 0) - { - if (a != NULL) - { - (void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority); - } - - if (run) - { - ResumeThread (threadH); - } - } - -#else /* __MINGW32__ && ! __MSVCRT__ */ - - /* - * This lock will force pthread_threadStart() to wait until we have - * the thread handle and have set the priority. - */ - (void) pthread_mutex_lock (&tp->cancelLock); - - tp->threadH = - threadH = - (HANDLE) _beginthread (ptw32_threadStart, (unsigned) stackSize, /* default stack size */ - parms); - - /* - * Make the return code match _beginthreadex's. - */ - if (threadH == (HANDLE) - 1L) - { - tp->threadH = threadH = 0; - } - else - { - if (!run) - { - /* - * beginthread does not allow for create flags, so we do it now. - * Note that beginthread itself creates the thread in SUSPENDED - * mode, and then calls ResumeThread to start it. - */ - SuspendThread (threadH); - } - - if (a != NULL) - { - (void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority); - } - } - - (void) pthread_mutex_unlock (&tp->cancelLock); - -#endif /* __MINGW32__ && ! __MSVCRT__ */ - - result = (threadH != 0) ? 0 : EAGAIN; - - /* - * Fall Through Intentionally - */ - - /* - * ------------ - * Failure Code - * ------------ - */ - -FAIL0: - if (result != 0) - { - - ptw32_threadDestroy (thread); - tp = NULL; - - if (parms != NULL) - { - free (parms); - } - } - else - { - *tid = thread; - } - -#ifdef _UWIN - if (result == 0) - pthread_count++; -#endif - return (result); - -} /* pthread_create */ +/* + * create.c + * + * Description: + * This translation unit implements routines associated with spawning a new + * thread. + * + * -------------------------------------------------------------------------- + * + * 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" +#if ! defined(_UWIN) && ! defined(WINCE) +#include +#endif + +int +pthread_create (pthread_t * tid, + const pthread_attr_t * attr, + void *(*start) (void *), void *arg) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function creates a thread running the start function, + * passing it the parameter value, 'arg'. The 'attr' + * argument specifies optional creation attributes. + * The identity of the new thread is returned + * via 'tid', which should not be NULL. + * + * PARAMETERS + * tid + * pointer to an instance of pthread_t + * + * attr + * optional pointer to an instance of pthread_attr_t + * + * start + * pointer to the starting routine for the new thread + * + * arg + * optional parameter passed to 'start' + * + * + * DESCRIPTION + * This function creates a thread running the start function, + * passing it the parameter value, 'arg'. The 'attr' + * argument specifies optional creation attributes. + * The identity of the new thread is returned + * via 'tid', which should not be the NULL pointer. + * + * RESULTS + * 0 successfully created thread, + * EINVAL attr invalid, + * EAGAIN insufficient resources. + * + * ------------------------------------------------------ + */ +{ + pthread_t thread; + ptw32_thread_t * tp; + register pthread_attr_t a; + HANDLE threadH = 0; + int result = EAGAIN; + int run = PTW32_TRUE; + ThreadParms *parms = NULL; + unsigned int stackSize; + int priority; + pthread_t self; + + /* + * Before doing anything, check that tid can be stored through + * without invoking a memory protection error (segfault). + * Make sure that the assignment below can't be optimised out by the compiler. + * This is assured by conditionally assigning *tid again at the end. + */ + tid->x = 0; + + if (attr != NULL) + { + a = *attr; + } + else + { + a = NULL; + } + + if ((thread = ptw32_new ()).p == NULL) + { + goto FAIL0; + } + + tp = (ptw32_thread_t *) thread.p; + + priority = tp->sched_priority; + + if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == NULL) + { + goto FAIL0; + } + + parms->tid = thread; + parms->start = start; + parms->arg = arg; + +#if defined(HAVE_SIGSET_T) + + /* + * Threads inherit their initial sigmask from their creator thread. + */ + self = pthread_self(); + tp->sigmask = ((ptw32_thread_t *)self.p)->sigmask; + +#endif /* HAVE_SIGSET_T */ + + + if (a != NULL) + { + stackSize = (unsigned int)a->stacksize; + tp->detachState = a->detachstate; + priority = a->param.sched_priority; + +#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL) + /* WinCE */ +#else + /* Everything else */ + + /* + * Thread priority must be set to a valid system level + * without altering the value set by pthread_attr_setschedparam(). + */ + + /* + * PTHREAD_EXPLICIT_SCHED is the default because Win32 threads + * don't inherit their creator's priority. They are started with + * THREAD_PRIORITY_NORMAL (win32 value). The result of not supplying + * an 'attr' arg to pthread_create() is equivalent to defaulting to + * PTHREAD_EXPLICIT_SCHED and priority THREAD_PRIORITY_NORMAL. + */ + if (PTHREAD_INHERIT_SCHED == a->inheritsched) + { + /* + * If the thread that called pthread_create() is a Win32 thread + * then the inherited priority could be the result of a temporary + * system adjustment. This is not the case for POSIX threads. + */ +#if ! defined(HAVE_SIGSET_T) + self = pthread_self (); +#endif + priority = ((ptw32_thread_t *) self.p)->sched_priority; + } + +#endif + + } + else + { + /* + * Default stackSize + */ + stackSize = PTHREAD_STACK_MIN; + } + + tp->state = run ? PThreadStateInitial : PThreadStateSuspended; + + tp->keys = NULL; + + /* + * Threads must be started in suspended mode and resumed if necessary + * after _beginthreadex returns us the handle. Otherwise we set up a + * race condition between the creating and the created threads. + * Note that we also retain a local copy of the handle for use + * by us in case thread.p->threadH gets NULLed later but before we've + * finished with it here. + */ + +#if ! (defined (__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) + + tp->threadH = + threadH = + (HANDLE) _beginthreadex ((void *) NULL, /* No security info */ + stackSize, /* default stack size */ + ptw32_threadStart, + parms, + (unsigned) + CREATE_SUSPENDED, + (unsigned *) &(tp->thread)); + + if (threadH != 0) + { + if (a != NULL) + { + (void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority); + } + + if (run) + { + ResumeThread (threadH); + } + } + +#else + + { + ptw32_mcs_local_node_t stateLock; + + /* + * This lock will force pthread_threadStart() to wait until we have + * the thread handle and have set the priority. + */ + ptw32_mcs_lock_acquire(&tp->stateLock, &stateLock); + + tp->threadH = + threadH = + (HANDLE) _beginthread (ptw32_threadStart, stackSize, /* default stack size */ + parms); + + /* + * Make the return code match _beginthreadex's. + */ + if (threadH == (HANDLE) - 1L) + { + tp->threadH = threadH = 0; + } + else + { + if (!run) + { + /* + * beginthread does not allow for create flags, so we do it now. + * Note that beginthread itself creates the thread in SUSPENDED + * mode, and then calls ResumeThread to start it. + */ + SuspendThread (threadH); + } + + if (a != NULL) + { + (void) ptw32_setthreadpriority (thread, SCHED_OTHER, priority); + } + } + + ptw32_mcs_lock_release (&stateLock); + } +#endif + + result = (threadH != 0) ? 0 : EAGAIN; + + /* + * Fall Through Intentionally + */ + + /* + * ------------ + * Failure Code + * ------------ + */ + +FAIL0: + if (result != 0) + { + + ptw32_threadDestroy (thread); + tp = NULL; + + if (parms != NULL) + { + free (parms); + } + } + else + { + *tid = thread; + } + +#if defined(_UWIN) + if (result == 0) + pthread_count++; +#endif + return (result); + +} /* pthread_create */ diff --git a/pthreads/dll.c b/pthreads/dll.c index c1cd4e96e..05e01bee7 100644 --- a/pthreads/dll.c +++ b/pthreads/dll.c @@ -34,12 +34,12 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ifndef PTW32_STATIC_LIB +#if !defined(PTW32_STATIC_LIB) #include "pthread.h" #include "implement.h" -#ifdef _MSC_VER +#if defined(_MSC_VER) /* * lpvReserved yields an unreferenced formal parameter; * ignore it @@ -47,7 +47,7 @@ #pragma warning( disable : 4100 ) #endif -#ifdef __cplusplus +#if defined(__cplusplus) /* * Dear c++: Please don't mangle this name. -thanks */ diff --git a/pthreads/global.c b/pthreads/global.c index 2b5542298..f1e9b3f66 100644 --- a/pthreads/global.c +++ b/pthreads/global.c @@ -49,21 +49,13 @@ pthread_cond_t ptw32_cond_list_tail = NULL; int ptw32_concurrency = 0; -/* What features have been auto-detaected */ +/* What features have been auto-detected */ int ptw32_features = 0; -BOOL ptw32_smp_system = PTW32_TRUE; /* Safer if assumed true initially. */ - -/* - * Function pointer to InterlockedCompareExchange if it exists, otherwise - * it will be set at runtime to a substitute local version with the same - * functionality but may be architecture specific. +/* + * Global [process wide] thread sequence Number */ -PTW32_INTERLOCKED_LONG - (WINAPI * ptw32_interlocked_compare_exchange) (PTW32_INTERLOCKED_LPLONG, - PTW32_INTERLOCKED_LONG, - PTW32_INTERLOCKED_LONG) = - NULL; +unsigned __int64 ptw32_threadSeqNumber = 0; /* * Function pointer to QueueUserAPCEx if it exists, otherwise @@ -75,39 +67,39 @@ DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD) = NULL; /* * Global lock for managing pthread_t struct reuse. */ -CRITICAL_SECTION ptw32_thread_reuse_lock; +ptw32_mcs_lock_t ptw32_thread_reuse_lock = 0; /* * Global lock for testing internal state of statically declared mutexes. */ -CRITICAL_SECTION ptw32_mutex_test_init_lock; +ptw32_mcs_lock_t ptw32_mutex_test_init_lock = 0; /* * Global lock for testing internal state of PTHREAD_COND_INITIALIZER * created condition variables. */ -CRITICAL_SECTION ptw32_cond_test_init_lock; +ptw32_mcs_lock_t ptw32_cond_test_init_lock = 0; /* * Global lock for testing internal state of PTHREAD_RWLOCK_INITIALIZER * created read/write locks. */ -CRITICAL_SECTION ptw32_rwlock_test_init_lock; +ptw32_mcs_lock_t ptw32_rwlock_test_init_lock = 0; /* * Global lock for testing internal state of PTHREAD_SPINLOCK_INITIALIZER * created spin locks. */ -CRITICAL_SECTION ptw32_spinlock_test_init_lock; +ptw32_mcs_lock_t ptw32_spinlock_test_init_lock = 0; /* * Global lock for condition variable linked list. The list exists * to wake up CVs when a WM_TIMECHANGE message arrives. See * w32_TimeChangeHandler.c. */ -CRITICAL_SECTION ptw32_cond_list_lock; +ptw32_mcs_lock_t ptw32_cond_list_lock = 0; -#ifdef _UWIN +#if defined(_UWIN) /* * Keep a count of the number of threads. */ diff --git a/pthreads/implement.h b/pthreads/implement.h index d22750aa4..6b9f42503 100644 --- a/pthreads/implement.h +++ b/pthreads/implement.h @@ -1,715 +1,943 @@ -/* - * 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: Ross.Johnson@homemail.com.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 - -/* - * 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 - -/* - * 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 -#endif - -#if !defined(INT_MAX) -#include -#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 -#elif defined(__BORLANDC__) -#define int64_t ULONGLONG -#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; - void *nextAssoc; -}; - - -/* - * 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; -}; - -/* - * MCS lock queue node - see ptw32_MCS_lock.c - */ -struct ptw32_mcs_node_t_ -{ - struct ptw32_mcs_node_t_ **lock; /* ptr to tail of queue */ - struct ptw32_mcs_node_t_ *next; /* ptr to successor in queue */ - LONG readyFlag; /* set after lock is released by - predecessor */ - LONG nextFlag; /* set after 'next' ptr is set by - successor */ -}; - -typedef struct ptw32_mcs_node_t_ ptw32_mcs_local_node_t; -typedef struct ptw32_mcs_node_t_ *ptw32_mcs_lock_t; - - -struct pthread_barrier_t_ -{ - unsigned int nCurrentBarrierHeight; - unsigned int nInitialBarrierHeight; - int pshared; - sem_t semBarrierBreeched; - void * lock; /* MCS lock */ - ptw32_mcs_local_node_t proxynode; -}; - -struct pthread_barrierattr_t_ -{ - int pshared; -}; - -struct pthread_key_t_ -{ - DWORD key; - void (*destructor) (void *); - pthread_mutex_t keyLock; - void *threads; -}; - - -typedef struct ThreadParms ThreadParms; - -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; -}; - -typedef struct ThreadKeyAssoc ThreadKeyAssoc; - -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. - * - * Graphically, the arrangement is as follows, where: - * - * K - Key with destructor - * (head of chain is key->threads) - * T - Thread that has called pthread_setspecific(Kn) - * (head of chain is thread->keys) - * A - Association. Each association is a node at the - * intersection of two doubly-linked lists. - * - * T1 T2 T3 - * | | | - * | | | - * K1 -----+-----A-----A-----> - * | | | - * | | | - * K2 -----A-----A-----+-----> - * | | | - * | | | - * K3 -----A-----+-----A-----> - * | | | - * | | | - * V V V - * - * Access to the association is guarded by two locks: the key's - * general lock (guarding the row) and the thread's general - * lock (guarding the column). This avoids the need for a - * dedicated lock for each association, which not only consumes - * more handles but requires that the lock resources persist - * until both the key is deleted and the thread has called the - * destructor. The two-lock arrangement allows those resources - * to be freed as soon as either thread or key is concluded. - * - * To avoid deadlock, whenever both locks are required both the - * key and thread locks are acquired consistently in the order - * "key lock then thread lock". An exception to this exists - * when a thread calls the destructors, however, this is done - * carefully (but inelegantly) to avoid deadlock. - * - * An association is created when a thread first calls - * pthread_setspecific() on a key that has a specified - * destructor. - * - * An association is destroyed either immediately after the - * thread calls the key destructor function on thread exit, or - * when the key is deleted. - * - * Attributes: - * thread - * reference to the thread that owns the - * association. This is actually the pointer to the - * thread struct itself. Since the association is - * destroyed before the thread exits, this can never - * point to a different logical thread to the one that - * created the assoc, i.e. after thread struct reuse. - * - * key - * reference to the key that owns the association. - * - * 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. - * - * prevKey - * Similarly. - * - * nextThread - * The pthread_key_t->threads attribute is the head of - * a chain of associations 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. - * - * prevThread - * Similarly. - * - * Notes: - * 1) As soon as either the key or the thread is no longer - * referencing the association, it can be destroyed. The - * association will be removed from both chains. - * - * 2) Under WIN32, an association is only created by - * pthread_setspecific if the user provided a - * destroyRoutine when they created the key. - * - * - */ - ptw32_thread_t * thread; - pthread_key_t key; - ThreadKeyAssoc *nextKey; - ThreadKeyAssoc *nextThread; - ThreadKeyAssoc *prevKey; - ThreadKeyAssoc *prevThread; -}; - - -#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 laid 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; - -#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 (ptw32_thread_t * thread, pthread_key_t key); - - void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc); - - int ptw32_semwait (sem_t * sem); - - DWORD ptw32_relmillisecs (const struct timespec * abstime); - - void ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node); - - int ptw32_mcs_lock_try_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node); - - void ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node); - - void ptw32_mcs_node_substitute (ptw32_mcs_local_node_t * new_node, ptw32_mcs_local_node_t * old_node); - -#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 -# 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 - */ -#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: Ross.Johnson@homemail.com.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(_IMPLEMENT_H) +#define _IMPLEMENT_H + +#if !defined(_WIN32_WINNT) +#define _WIN32_WINNT 0x0400 +#endif + +#include + +/* + * In case windows.h doesn't define it (e.g. WinCE perhaps) + */ +#if defined(WINCE) +typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam); +#endif + +/* + * note: ETIMEDOUT is correctly defined in winsock.h + */ +#include + +/* + * In case ETIMEDOUT hasn't been defined above somehow. + */ +#if !defined(ETIMEDOUT) +# define ETIMEDOUT 10060 /* This is the value in winsock.h. */ +#endif + +#if !defined(malloc) +#include +#endif + +#if defined(__CLEANUP_C) +# include +#endif + +#if !defined(INT_MAX) +#include +#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(_MSC_VER) && _MSC_VER < 1300 +/* + * MSVC 6 does not use the "volatile" qualifier + */ +#define PTW32_INTERLOCKED_VOLATILE +#else +#define PTW32_INTERLOCKED_VOLATILE volatile +#endif +#define PTW32_INTERLOCKED_LONG long +#define PTW32_INTERLOCKED_SIZE size_t +#define PTW32_INTERLOCKED_PVOID PVOID +#define PTW32_INTERLOCKED_LONGPTR PTW32_INTERLOCKED_VOLATILE long* +#define PTW32_INTERLOCKED_SIZEPTR PTW32_INTERLOCKED_VOLATILE size_t* +#define PTW32_INTERLOCKED_PVOID_PTR PTW32_INTERLOCKED_VOLATILE PVOID* + +#if defined(__MINGW64__) || defined(__MINGW32__) +# include +#elif defined(__BORLANDC__) +# define int64_t ULONGLONG +#else +# define int64_t _int64 +# if defined(_MSC_VER) && _MSC_VER < 1300 + typedef long intptr_t; +# endif +#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 */ + /* has cancelation pending. */ + PThreadStateCanceling, /* Thread alive but is */ + /* in the process of terminating */ + /* due to a cancellation request */ + PThreadStateExiting, /* Thread alive but exiting */ + /* due to an exception */ + PThreadStateLast, /* All handlers have been run and now */ + /* final cleanup can be done. */ + PThreadStateReuse /* In reuse pool. */ +} +PThreadState; + +typedef struct ptw32_mcs_node_t_ ptw32_mcs_local_node_t; +typedef struct ptw32_mcs_node_t_* ptw32_mcs_lock_t; +typedef struct ptw32_robust_node_t_ ptw32_robust_node_t; +typedef struct ptw32_thread_t_ ptw32_thread_t; + + +struct ptw32_thread_t_ +{ + unsigned __int64 seqNumber; /* Process-unique thread sequence number */ + 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; + ptw32_mcs_lock_t threadLock; /* Used for serialised access to public thread state */ + ptw32_mcs_lock_t stateLock; /* Used for async-cancel safety */ + HANDLE cancelEvent; + void *exitStatus; + void *parms; + void *keys; + void *nextAssoc; +#if defined(__CLEANUP_C) + jmp_buf start_mark; /* Jump buffer follows void* so should be aligned */ +#endif /* __CLEANUP_C */ +#if defined(HAVE_SIGSET_T) + sigset_t sigmask; +#endif /* HAVE_SIGSET_T */ + ptw32_mcs_lock_t + robustMxListLock; /* robustMxList lock */ + ptw32_robust_node_t* + robustMxList; /* List of currenty held robust mutexes */ + int ptErrno; + int detachState; + int sched_priority; /* As set, not as currently is */ + int cancelState; + int cancelType; + int implicit:1; + DWORD thread; /* Win32 thread ID */ +#if defined(_UWIN) + DWORD dummy[5]; +#endif + size_t align; /* Force alignment if this struct is packed */ +}; + + +/* + * 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 defined(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; +#if defined(NEED_SEM) + int leftToUnblock; +#endif +}; + +#define PTW32_OBJECT_AUTO_INIT ((void *)(size_t) -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. */ + ptw32_robust_node_t* + robustNode; /* Extra state for robust mutexes */ +}; + +enum ptw32_robust_state_t_ +{ + PTW32_ROBUST_CONSISTENT, + PTW32_ROBUST_INCONSISTENT, + PTW32_ROBUST_NOTRECOVERABLE +}; + +typedef enum ptw32_robust_state_t_ ptw32_robust_state_t; + +/* + * Node used to manage per-thread lists of currently-held robust mutexes. + */ +struct ptw32_robust_node_t_ +{ + pthread_mutex_t mx; + ptw32_robust_state_t stateInconsistent; + ptw32_robust_node_t* prev; + ptw32_robust_node_t* next; +}; + +struct pthread_mutexattr_t_ +{ + int pshared; + int kind; + int robustness; +}; + +/* + * 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 an 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_INVALID (0) +#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; +}; + +/* + * MCS lock queue node - see ptw32_MCS_lock.c + */ +struct ptw32_mcs_node_t_ +{ + struct ptw32_mcs_node_t_ **lock; /* ptr to tail of queue */ + struct ptw32_mcs_node_t_ *next; /* ptr to successor in queue */ + HANDLE readyFlag; /* set after lock is released by + predecessor */ + HANDLE nextFlag; /* set after 'next' ptr is set by + successor */ +}; + + +struct pthread_barrier_t_ +{ + unsigned int nCurrentBarrierHeight; + unsigned int nInitialBarrierHeight; + int pshared; + sem_t semBarrierBreeched; + ptw32_mcs_lock_t lock; + ptw32_mcs_local_node_t proxynode; +}; + +struct pthread_barrierattr_t_ +{ + int pshared; +}; + +struct pthread_key_t_ +{ + DWORD key; + void (*destructor) (void *); + ptw32_mcs_lock_t keyLock; + void *threads; +}; + + +typedef struct ThreadParms ThreadParms; + +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; +}; + +typedef struct ThreadKeyAssoc ThreadKeyAssoc; + +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. + * + * Graphically, the arrangement is as follows, where: + * + * K - Key with destructor + * (head of chain is key->threads) + * T - Thread that has called pthread_setspecific(Kn) + * (head of chain is thread->keys) + * A - Association. Each association is a node at the + * intersection of two doubly-linked lists. + * + * T1 T2 T3 + * | | | + * | | | + * K1 -----+-----A-----A-----> + * | | | + * | | | + * K2 -----A-----A-----+-----> + * | | | + * | | | + * K3 -----A-----+-----A-----> + * | | | + * | | | + * V V V + * + * Access to the association is guarded by two locks: the key's + * general lock (guarding the row) and the thread's general + * lock (guarding the column). This avoids the need for a + * dedicated lock for each association, which not only consumes + * more handles but requires that the lock resources persist + * until both the key is deleted and the thread has called the + * destructor. The two-lock arrangement allows those resources + * to be freed as soon as either thread or key is concluded. + * + * To avoid deadlock, whenever both locks are required both the + * key and thread locks are acquired consistently in the order + * "key lock then thread lock". An exception to this exists + * when a thread calls the destructors, however, this is done + * carefully (but inelegantly) to avoid deadlock. + * + * An association is created when a thread first calls + * pthread_setspecific() on a key that has a specified + * destructor. + * + * An association is destroyed either immediately after the + * thread calls the key destructor function on thread exit, or + * when the key is deleted. + * + * Attributes: + * thread + * reference to the thread that owns the + * association. This is actually the pointer to the + * thread struct itself. Since the association is + * destroyed before the thread exits, this can never + * point to a different logical thread to the one that + * created the assoc, i.e. after thread struct reuse. + * + * key + * reference to the key that owns the association. + * + * 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. + * + * prevKey + * Similarly. + * + * nextThread + * The pthread_key_t->threads attribute is the head of + * a chain of associations 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. + * + * prevThread + * Similarly. + * + * Notes: + * 1) As soon as either the key or the thread is no longer + * referencing the association, it can be destroyed. The + * association will be removed from both chains. + * + * 2) Under WIN32, an association is only created by + * pthread_setspecific if the user provided a + * destroyRoutine when they created the key. + * + * + */ + ptw32_thread_t * thread; + pthread_key_t key; + ThreadKeyAssoc *nextKey; + ThreadKeyAssoc *nextThread; + ThreadKeyAssoc *prevKey; + ThreadKeyAssoc *prevThread; +}; + + +#if defined(__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 laid 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 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 *)(size_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 unsigned __int64 ptw32_threadSeqNumber; + +extern int ptw32_concurrency; + +extern int ptw32_features; + +extern ptw32_mcs_lock_t ptw32_thread_reuse_lock; +extern ptw32_mcs_lock_t ptw32_mutex_test_init_lock; +extern ptw32_mcs_lock_t ptw32_cond_list_lock; +extern ptw32_mcs_lock_t ptw32_cond_test_init_lock; +extern ptw32_mcs_lock_t ptw32_rwlock_test_init_lock; +extern ptw32_mcs_lock_t ptw32_spinlock_test_init_lock; + +#if defined(_UWIN) +extern int pthread_count; +#endif + +#if defined(__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); + + int ptw32_robust_mutex_inherit(pthread_mutex_t * mutex); + void ptw32_robust_mutex_add(pthread_mutex_t* mutex, pthread_t self); + void ptw32_robust_mutex_remove(pthread_mutex_t* mutex, ptw32_thread_t* otp); + + 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 (__MINGW64__) || defined(__MINGW32__)) || (defined(__MSVCRT__) && ! defined(__DMC__)) + unsigned __stdcall +#else + void +#endif + ptw32_threadStart (void *vthreadParms); + + void ptw32_callUserDestroyRoutines (pthread_t thread); + + int ptw32_tkAssocCreate (ptw32_thread_t * thread, pthread_key_t key); + + void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc); + + int ptw32_semwait (sem_t * sem); + + DWORD ptw32_relmillisecs (const struct timespec * abstime); + + void ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node); + + int ptw32_mcs_lock_try_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node); + + void ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node); + + void ptw32_mcs_node_transfer (ptw32_mcs_local_node_t * new_node, ptw32_mcs_local_node_t * old_node); + +#if defined(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 */ +#if defined(NEED_CALLOC) +#define calloc(n, s) ptw32_calloc(n, s) + void *ptw32_calloc (size_t n, size_t s); +#endif + +/* Declared in private.c */ +#if defined(_MSC_VER) +/* + * Ignore the warning: + * "C++ exception specification ignored except to indicate that + * the function is not __declspec(nothrow)." + */ +#pragma warning(disable:4290) +#endif + void ptw32_throw (DWORD exception) +#if defined(__CLEANUP_CXX) + throw(ptw32_exception_cancel,ptw32_exception_exit) +#endif +; + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + + +#if defined(_UWIN_) +# if defined(_MT) +# if defined(__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); +# if defined(__cplusplus) +} +# endif +# endif +#else +# include +# endif + + +/* + * Use intrinsic versions wherever possible. VC will do this + * automatically where possible and GCC define these if available: + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 + * + * The full set of Interlocked intrinsics in GCC are (check versions): + * type __sync_fetch_and_add (type *ptr, type value, ...) + * type __sync_fetch_and_sub (type *ptr, type value, ...) + * type __sync_fetch_and_or (type *ptr, type value, ...) + * type __sync_fetch_and_and (type *ptr, type value, ...) + * type __sync_fetch_and_xor (type *ptr, type value, ...) + * type __sync_fetch_and_nand (type *ptr, type value, ...) + * type __sync_add_and_fetch (type *ptr, type value, ...) + * type __sync_sub_and_fetch (type *ptr, type value, ...) + * type __sync_or_and_fetch (type *ptr, type value, ...) + * type __sync_and_and_fetch (type *ptr, type value, ...) + * type __sync_xor_and_fetch (type *ptr, type value, ...) + * type __sync_nand_and_fetch (type *ptr, type value, ...) + * bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...) + * type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...) + * __sync_synchronize (...) // Full memory barrier + * type __sync_lock_test_and_set (type *ptr, type value, ...) // Acquire barrier + * void __sync_lock_release (type *ptr, ...) // Release barrier + * + * These are all overloaded and take 1,2,4,8 byte scalar or pointer types. + * + * The above aren't available in Mingw32 as of gcc 4.5.2 so define our own. + */ +#if defined(__GNUC__) +# if defined(_WIN64) +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64(location, value, comparand) \ + ({ \ + __typeof (value) _result; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "cmpxchgq %2,(%1)" \ + :"=a" (_result) \ + :"r" (location), "r" (value), "a" (comparand) \ + :"memory", "cc"); \ + _result; \ + }) +# define PTW32_INTERLOCKED_EXCHANGE_64(location, value) \ + ({ \ + __typeof (value) _result; \ + __asm__ __volatile__ \ + ( \ + "xchgq %0,(%1)" \ + :"=r" (_result) \ + :"r" (location), "0" (value) \ + :"memory", "cc"); \ + _result; \ + }) +# define PTW32_INTERLOCKED_EXCHANGE_ADD_64(location, value) \ + ({ \ + __typeof (value) _result; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "xaddq %0,(%1)" \ + :"=r" (_result) \ + :"r" (location), "0" (value) \ + :"memory", "cc"); \ + _result; \ + }) +# define PTW32_INTERLOCKED_INCREMENT_64(location) \ + ({ \ + PTW32_INTERLOCKED_LONG _temp = 1; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "xaddq %0,(%1)" \ + :"+r" (_temp) \ + :"r" (location) \ + :"memory", "cc"); \ + ++_temp; \ + }) +# define PTW32_INTERLOCKED_DECREMENT_64(location) \ + ({ \ + PTW32_INTERLOCKED_LONG _temp = -1; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "xaddq %2,(%1)" \ + :"+r" (_temp) \ + :"r" (location) \ + :"memory", "cc"); \ + --_temp; \ + }) +#endif +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(location, value, comparand) \ + ({ \ + __typeof (value) _result; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "cmpxchgl %2,(%1)" \ + :"=a" (_result) \ + :"r" (location), "r" (value), "a" (comparand) \ + :"memory", "cc"); \ + _result; \ + }) +# define PTW32_INTERLOCKED_EXCHANGE_LONG(location, value) \ + ({ \ + __typeof (value) _result; \ + __asm__ __volatile__ \ + ( \ + "xchgl %0,(%1)" \ + :"=r" (_result) \ + :"r" (location), "0" (value) \ + :"memory", "cc"); \ + _result; \ + }) +# define PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(location, value) \ + ({ \ + __typeof (value) _result; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "xaddl %0,(%1)" \ + :"=r" (_result) \ + :"r" (location), "0" (value) \ + :"memory", "cc"); \ + _result; \ + }) +# define PTW32_INTERLOCKED_INCREMENT_LONG(location) \ + ({ \ + PTW32_INTERLOCKED_LONG _temp = 1; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "xaddl %0,(%1)" \ + :"+r" (_temp) \ + :"r" (location) \ + :"memory", "cc"); \ + ++_temp; \ + }) +# define PTW32_INTERLOCKED_DECREMENT_LONG(location) \ + ({ \ + PTW32_INTERLOCKED_LONG _temp = -1; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "xaddl %0,(%1)" \ + :"+r" (_temp) \ + :"r" (location) \ + :"memory", "cc"); \ + --_temp; \ + }) +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR(location, value, comparand) \ + PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE((PTW32_INTERLOCKED_SIZEPTR)location, \ + (PTW32_INTERLOCKED_SIZE)value, \ + (PTW32_INTERLOCKED_SIZE)comparand) +# define PTW32_INTERLOCKED_EXCHANGE_PTR(location, value) \ + PTW32_INTERLOCKED_EXCHANGE_SIZE((PTW32_INTERLOCKED_SIZEPTR)location, \ + (PTW32_INTERLOCKED_SIZE)value) +#else +# if defined(_WIN64) +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_64 InterlockedCompareExchange64 +# define PTW32_INTERLOCKED_EXCHANGE_64 InterlockedExchange64 +# define PTW32_INTERLOCKED_EXCHANGE_ADD_64 InterlockedExchangeAdd64 +# define PTW32_INTERLOCKED_INCREMENT_64 InterlockedIncrement64 +# define PTW32_INTERLOCKED_DECREMENT_64 InterlockedDecrement64 +# endif +# if defined(_MSC_VER) && _MSC_VER < 1300 && !defined(_WIN64) /* MSVC 6 */ +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG(location, value, comparand) \ + ((LONG)InterlockedCompareExchange((PVOID *)(location), (PVOID)(value), (PVOID)(comparand))) +# else +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG InterlockedCompareExchange +# endif +# define PTW32_INTERLOCKED_EXCHANGE_LONG InterlockedExchange +# define PTW32_INTERLOCKED_EXCHANGE_ADD_LONG InterlockedExchangeAdd +# define PTW32_INTERLOCKED_INCREMENT_LONG InterlockedIncrement +# define PTW32_INTERLOCKED_DECREMENT_LONG InterlockedDecrement +# if defined(_MSC_VER) && _MSC_VER < 1300 && !defined(_WIN64) /* MSVC 6 */ +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR InterlockedCompareExchange +# define PTW32_INTERLOCKED_EXCHANGE_PTR(location, value) \ + ((PVOID)InterlockedExchange((LPLONG)(location), (LONG)(value))) +# else +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR InterlockedCompareExchangePointer +# define PTW32_INTERLOCKED_EXCHANGE_PTR InterlockedExchangePointer +# endif +#endif +#if defined(_WIN64) +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE PTW32_INTERLOCKED_COMPARE_EXCHANGE_64 +# define PTW32_INTERLOCKED_EXCHANGE_SIZE PTW32_INTERLOCKED_EXCHANGE_64 +# define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE PTW32_INTERLOCKED_EXCHANGE_ADD_64 +# define PTW32_INTERLOCKED_INCREMENT_SIZE PTW32_INTERLOCKED_INCREMENT_64 +# define PTW32_INTERLOCKED_DECREMENT_SIZE PTW32_INTERLOCKED_DECREMENT_64 +#else +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG +# define PTW32_INTERLOCKED_EXCHANGE_SIZE PTW32_INTERLOCKED_EXCHANGE_LONG +# define PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE PTW32_INTERLOCKED_EXCHANGE_ADD_LONG +# define PTW32_INTERLOCKED_INCREMENT_SIZE PTW32_INTERLOCKED_INCREMENT_LONG +# define PTW32_INTERLOCKED_DECREMENT_SIZE PTW32_INTERLOCKED_DECREMENT_LONG +#endif + +#if 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 /* NEED_CREATETHREAD */ + + +#endif /* _IMPLEMENT_H */ diff --git a/pthreads/manual/ChangeLog b/pthreads/manual/ChangeLog index 3b7ab307b..071b847ef 100644 --- a/pthreads/manual/ChangeLog +++ b/pthreads/manual/ChangeLog @@ -1,66 +1,74 @@ -2008-06-30 Ross Johnson - - pthread_setschedparam.html: Fix "see also" links. - -2005-05-06 Ross Johnson - - * PortabilityIssues.html: Was nonPortableIssues.html. - * index.html: Updated; add table of contents at top. - * *.html: Add Pthreads-win32 header info; add link back to the - index page 'index.html'. - -2005-05-06 Ross Johnson - - * index.html: New. - * nonPortableIssues.html: New. - * pthread_attr_init.html: New. - * pthread_attr_setstackaddr.html: New. - * pthread_attr_setstacksize.html: New. - * pthread_barrierattr_init.html: New. - * pthread_barrierattr_setpshared.html: New. - * pthread_barrier_init.html: New. - * pthread_barrier_wait.html: New. - * pthreadCancelableWait.html: New. - * pthread_cancel.html: New. - * pthread_cleanup_push.html: New. - * pthread_condattr_init.html: New. - * pthread_condattr_setpshared.html: New. - * pthread_cond_init.html: New. - * pthread_create.html: New. - * pthread_delay_np.html: New. - * pthread_detach.html: New. - * pthread_equal.html: New. - * pthread_exit.html: New. - * pthread_getw32threadhandle_np.html: New. - * pthread_join.html: New. - * pthread_key_create.html: New. - * pthread_kill.html: New. - * pthread_mutexattr_init.html: New. - * pthread_mutexattr_setpshared.html: New. - * pthread_mutex_init.html: New. - * pthread_num_processors_np.html: New. - * pthread_once.html: New. - * pthread_rwlockattr_init.html: New. - * pthread_rwlockattr_setpshared.html: New. - * pthread_rwlock_init.html: New. - * pthread_rwlock_rdlock.html: New. - * pthread_rwlock_timedrdlock.html: New. - * pthread_rwlock_timedwrlock.html: New. - * pthread_rwlock_unlock.html: New. - * pthread_rwlock_wrlock.html: New. - * pthread_self.html: New. - * pthread_setcancelstate.html: New. - * pthread_setcanceltype.html: New. - * pthread_setconcurrency.html: New. - * pthread_setschedparam.html: New. - * pthread_spin_init.html: New. - * pthread_spin_lock.html: New. - * pthread_spin_unlock.html: New. - * pthread_timechange_handler_np.html: New. - * pthread_win32_attach_detach_np.html: New. - * pthread_win32_test_features_np.html: New. - * sched_get_priority_max.html: New. - * sched_getscheduler.html: New. - * sched_setscheduler.html: New. - * sched_yield.html: New. - * sem_init.html: New. +2011-03-26 Ross Johnson + + * pthread_nutex_init.html (robust mutexes): Added + descriptions for newly implemented interface. + * pthread_mutexattr_init.html (robust mutexes): Likewise. + * pthread_getsequence_np.html: New. + * index.html: Updated. + +2008-06-30 Ross Johnson + + * pthread_setschedparam.html: Fix "see also" links. + +2005-05-06 Ross Johnson + + * PortabilityIssues.html: Was nonPortableIssues.html. + * index.html: Updated; add table of contents at top. + * *.html: Add Pthreads-win32 header info; add link back to the + index page 'index.html'. + +2005-05-06 Ross Johnson + + * index.html: New. + * nonPortableIssues.html: New. + * pthread_attr_init.html: New. + * pthread_attr_setstackaddr.html: New. + * pthread_attr_setstacksize.html: New. + * pthread_barrierattr_init.html: New. + * pthread_barrierattr_setpshared.html: New. + * pthread_barrier_init.html: New. + * pthread_barrier_wait.html: New. + * pthreadCancelableWait.html: New. + * pthread_cancel.html: New. + * pthread_cleanup_push.html: New. + * pthread_condattr_init.html: New. + * pthread_condattr_setpshared.html: New. + * pthread_cond_init.html: New. + * pthread_create.html: New. + * pthread_delay_np.html: New. + * pthread_detach.html: New. + * pthread_equal.html: New. + * pthread_exit.html: New. + * pthread_getw32threadhandle_np.html: New. + * pthread_join.html: New. + * pthread_key_create.html: New. + * pthread_kill.html: New. + * pthread_mutexattr_init.html: New. + * pthread_mutexattr_setpshared.html: New. + * pthread_mutex_init.html: New. + * pthread_num_processors_np.html: New. + * pthread_once.html: New. + * pthread_rwlockattr_init.html: New. + * pthread_rwlockattr_setpshared.html: New. + * pthread_rwlock_init.html: New. + * pthread_rwlock_rdlock.html: New. + * pthread_rwlock_timedrdlock.html: New. + * pthread_rwlock_timedwrlock.html: New. + * pthread_rwlock_unlock.html: New. + * pthread_rwlock_wrlock.html: New. + * pthread_self.html: New. + * pthread_setcancelstate.html: New. + * pthread_setcanceltype.html: New. + * pthread_setconcurrency.html: New. + * pthread_setschedparam.html: New. + * pthread_spin_init.html: New. + * pthread_spin_lock.html: New. + * pthread_spin_unlock.html: New. + * pthread_timechange_handler_np.html: New. + * pthread_win32_attach_detach_np.html: New. + * pthread_win32_test_features_np.html: New. + * sched_get_priority_max.html: New. + * sched_getscheduler.html: New. + * sched_setscheduler.html: New. + * sched_yield.html: New. + * sem_init.html: New. diff --git a/pthreads/manual/index.html b/pthreads/manual/index.html index a209dc01a..f7b5bc919 100644 --- a/pthreads/manual/index.html +++ b/pthreads/manual/index.html @@ -3,144 +3,156 @@ - + - + + + + -

POSIX Threads for Windows – REFERENCE - Pthreads-w32

-

Table of Contents

-

POSIX +

POSIX Threads for Windows – REFERENCE - +Pthreads-w32

+

Table of Contents

+

POSIX threads API reference
Miscellaneous POSIX thread safe routines provided by Pthreads-w32
Non-portable Pthreads-w32 routines
Other

-

POSIX threads API reference

-

pthread_attr_destroy

-

pthread_attr_getdetachstate

-

pthread_attr_getinheritsched

-

pthread_attr_getschedparam

-

pthread_attr_getschedpolicy

-

pthread_attr_getscope

-

pthread_attr_getstackaddr

-

pthread_attr_getstacksize

-

pthread_attr_init

-

pthread_attr_setdetachstate

-

pthread_attr_setinheritsched

-

pthread_attr_setschedparam

-

pthread_attr_setschedpolicy

-

pthread_attr_setscope

-

pthread_attr_setstackaddr

-

pthread_attr_setstacksize

-

pthread_barrierattr_destroy

-

pthread_barrierattr_getpshared

-

pthread_barrierattr_init

-

pthread_barrierattr_setpshared

-

pthread_barrier_destroy

-

pthread_barrier_init

-

pthread_barrier_wait

-

pthread_cancel

-

pthread_cleanup_pop

-

pthread_cleanup_push

-

pthread_condattr_destroy

-

pthread_condattr_getpshared

-

pthread_condattr_init

-

pthread_condattr_setpshared

-

pthread_cond_broadcast

-

pthread_cond_destroy

-

pthread_cond_init

-

pthread_cond_signal

-

pthread_cond_timedwait

-

pthread_cond_wait

-

pthread_create

-

pthread_detach

-

pthread_equal

-

pthread_exit

-

pthread_getconcurrency

-

pthread_getschedparam

-

pthread_getspecific

-

pthread_join

-

pthread_key_create

-

pthread_key_delete

-

pthread_kill

-

pthread_mutexattr_destroy

-

pthread_mutexattr_getkind_np

-

pthread_mutexattr_getpshared

-

pthread_mutexattr_gettype

-

pthread_mutexattr_init

-

pthread_mutexattr_setkind_np

-

pthread_mutexattr_setpshared

-

pthread_mutexattr_settype

-

pthread_mutex_destroy

-

pthread_mutex_init

-

pthread_mutex_lock

-

pthread_mutex_timedlock

-

pthread_mutex_trylock

-

pthread_mutex_unlock

-

pthread_once

-

pthread_rwlockattr_destroy

-

pthread_rwlockattr_getpshared

-

pthread_rwlockattr_init

-

pthread_rwlockattr_setpshared

-

pthread_rwlock_destroy

-

pthread_rwlock_init

-

pthread_rwlock_rdlock

-

pthread_rwlock_timedrdlock

-

pthread_rwlock_timedwrlock

-

pthread_rwlock_tryrdlock

-

pthread_rwlock_trywrlock

-

pthread_rwlock_unlock

-

pthread_rwlock_wrlock

-

pthread_self

-

pthread_setcancelstate

-

pthread_setcanceltype

-

pthread_setconcurrency

-

pthread_setschedparam

-

pthread_setspecific

-

pthread_sigmask

-

pthread_spin_destroy

-

pthread_spin_init

-

pthread_spin_lock

-

pthread_spin_trylock

-

pthread_spin_unlock

-

pthread_testcancel

-

sched_get_priority_max

-

sched_get_priority_min

-

sched_getscheduler

-

sched_setscheduler

-

sched_yield

-

sem_close

-

sem_destroy

-

sem_getvalue

-

sem_init

-

sem_open

-

sem_post

-

sem_post_multiple

-

sem_timedwait

-

sem_trywait

-

sem_unlink

-

sem_wait

-

sigwait

-

Miscellaneous POSIX thread safe -routines provided by Pthreads-w32

-

asctime_r

-

ctime_r

-

gmtime_r

-

localtime_r

-

rand_r

-

Non-portable Pthreads-w32 routines

-

pthreadCancelableTimedWait

-

pthreadCancelableWait

-

pthread_delay_np

-

pthread_getw32threadhandle_np

-

pthread_num_processors_np

-

pthread_win32_test_features_np

-

pthread_timechange_handler_np

-

pthread_win32_process_attach_np

-

pthread_win32_process_detach_np

-

pthread_win32_thread_attach_np

-

pthread_win32_thread_detach_np

-

Other

-

Portability +

POSIX threads API +reference

+

pthread_attr_destroy

+

pthread_attr_getdetachstate

+

pthread_attr_getinheritsched

+

pthread_attr_getschedparam

+

pthread_attr_getschedpolicy

+

pthread_attr_getscope

+

pthread_attr_getstackaddr

+

pthread_attr_getstacksize

+

pthread_attr_init

+

pthread_attr_setdetachstate

+

pthread_attr_setinheritsched

+

pthread_attr_setschedparam

+

pthread_attr_setschedpolicy

+

pthread_attr_setscope

+

pthread_attr_setstackaddr

+

pthread_attr_setstacksize

+

pthread_barrierattr_destroy

+

pthread_barrierattr_getpshared

+

pthread_barrierattr_init

+

pthread_barrierattr_setpshared

+

pthread_barrier_destroy

+

pthread_barrier_init

+

pthread_barrier_wait

+

pthread_cancel

+

pthread_cleanup_pop

+

pthread_cleanup_push

+

pthread_condattr_destroy

+

pthread_condattr_getpshared

+

pthread_condattr_init

+

pthread_condattr_setpshared

+

pthread_cond_broadcast

+

pthread_cond_destroy

+

pthread_cond_init

+

pthread_cond_signal

+

pthread_cond_timedwait

+

pthread_cond_wait

+

pthread_create

+

pthread_detach

+

pthread_equal

+

pthread_exit

+

pthread_getconcurrency

+

pthread_getschedparam

+

pthread_getunique_np

+

pthread_getspecific

+

pthread_join

+

pthread_key_create

+

pthread_key_delete

+

pthread_kill

+

pthread_mutexattr_destroy

+

pthread_mutexattr_getkind_np

+

pthread_mutexattr_getpshared

+

pthread_mutexattr_getrobust

+

pthread_mutexattr_gettype

+

pthread_mutexattr_init

+

pthread_mutexattr_setkind_np

+

pthread_mutexattr_setpshared

+

pthread_mutexattr_setrobust

+

pthread_mutexattr_settype

+

pthread_mutex_consistent

+

pthread_mutex_destroy

+

pthread_mutex_init

+

pthread_mutex_lock

+

pthread_mutex_timedlock

+

pthread_mutex_trylock

+

pthread_mutex_unlock

+

pthread_once

+

pthread_rwlockattr_destroy

+

pthread_rwlockattr_getpshared

+

pthread_rwlockattr_init

+

pthread_rwlockattr_setpshared

+

pthread_rwlock_destroy

+

pthread_rwlock_init

+

pthread_rwlock_rdlock

+

pthread_rwlock_timedrdlock

+

pthread_rwlock_timedwrlock

+

pthread_rwlock_tryrdlock

+

pthread_rwlock_trywrlock

+

pthread_rwlock_unlock

+

pthread_rwlock_wrlock

+

pthread_self

+

pthread_setcancelstate

+

pthread_setcanceltype

+

pthread_setconcurrency

+

pthread_setschedparam

+

pthread_setspecific

+

pthread_sigmask

+

pthread_spin_destroy

+

pthread_spin_init

+

pthread_spin_lock

+

pthread_spin_trylock

+

pthread_spin_unlock

+

pthread_testcancel

+

sched_get_priority_max

+

sched_get_priority_min

+

sched_getscheduler

+

sched_setscheduler

+

sched_yield

+

sem_close

+

sem_destroy

+

sem_getvalue

+

sem_init

+

sem_open

+

sem_post

+

sem_post_multiple

+

sem_timedwait

+

sem_trywait

+

sem_unlink

+

sem_wait

+

sigwait

+

Non-portable +Pthreads-w32 routines

+

pthreadCancelableTimedWait

+

pthreadCancelableWait

+

pthread_delay_np

+

pthread_getw32threadhandle_np

+

pthread_num_processors_np

+

pthread_win32_test_features_np

+

pthread_timechange_handler_np

+

pthread_win32_process_attach_np

+

pthread_win32_process_detach_np

+

pthread_win32_thread_attach_np

+

pthread_win32_thread_detach_np

+

Other

+

Portability issues

- + \ No newline at end of file diff --git a/pthreads/manual/pthread_getunique_np.html b/pthreads/manual/pthread_getunique_np.html new file mode 100644 index 000000000..182ce73c6 --- /dev/null +++ b/pthreads/manual/pthread_getunique_np.html @@ -0,0 +1,76 @@ + + + + + PTHREAD_GETW32THREADHANDLE_NP manual page + + + + + + + + + + +

POSIX Threads for Windows – REFERENCE - +Pthreads-w32

+

Reference Index

+

Table of Contents

+

Name

+

pthread_getunique_np – get the +unique sequence number associated with a thread

+

Synopsis

+

#include <pthread.h> +

+

unsigned long long pthread_getunique_np(pthread_t thread);

+

Description

+

Returns the unique 64 bit +sequence number assigned to thread.

+

In Pthreads-win32:

+
    +
  • the value returned is not reused after the thread terminates + so it is unique for the life of the process

    +
  • Windows native threads may obtain their own POSIX thread + sequence number by first retrieving their pthread_t handle + via pthread_self to use as the thread argument.

    +
+

This function was added for source code compatibility with some +other POSIX threads implementations.

+

Cancellation

+

None.

+

Return Value

+

pthread_getunique_np returns the unique sequence number for +thread.

+

Errors

+

None.

+

Author

+

Ross Johnson for use with Pthreads-w32.

+
+

Table of Contents

+ + + \ No newline at end of file diff --git a/pthreads/manual/pthread_mutex_init.html b/pthreads/manual/pthread_mutex_init.html index f9982cf61..cdb333e10 100644 --- a/pthreads/manual/pthread_mutex_init.html +++ b/pthreads/manual/pthread_mutex_init.html @@ -3,22 +3,37 @@ PTHREAD_MUTEX(3) manual page - + - + + + + + -

POSIX Threads for Windows – REFERENCE - Pthreads-w32

+

POSIX Threads for Windows – REFERENCE - +Pthreads-w32

Reference Index

Table of Contents

-

Name

+

Name

pthread_mutex_init, pthread_mutex_lock, pthread_mutex_trylock, -pthread_mutex_timedlock, pthread_mutex_unlock, pthread_mutex_destroy -- operations on mutexes +pthread_mutex_timedlock, pthread_mutex_unlock, +pthread_mutex_consistent, pthread_mutex_destroy - operations on +mutexes

-

Synopsis

+

Synopsis

#include <pthread.h>

#include <time.h>

@@ -49,9 +64,11 @@ const pthread_mutexattr_t *
mutexattr);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

+

int pthread_mutex_consistent(pthread_mutex_t *mutex); +

int pthread_mutex_destroy(pthread_mutex_t *mutex);

-

Description

+

Description

A mutex is a MUTual EXclusion device, and is useful for protecting shared data structures from concurrent modifications, and implementing critical sections and monitors. @@ -76,16 +93,22 @@ for more information on mutex attributes. statically, using the constants PTHREAD_MUTEX_INITIALIZER (for normal “fast” mutexes), PTHREAD_RECURSIVE_MUTEX_INITIALIZER (for recursive mutexes), and PTHREAD_ERRORCHECK_MUTEX_INITIALIZER -(for error checking mutexes). In -the Pthreads-w32 implementation, an application should still -call pthread_mutex_destroy at some point to ensure that any +(for error checking mutexes). In +the Pthreads-w32 implementation, +an application should still call pthread_mutex_destroy +at some point to ensure that any resources consumed by the mutex are released.

+

Any mutex type can be +initialized as a robust mutex. +See pthread_mutexattr_init(3) +for more information as well as the +section Robust Mutexes +below.

pthread_mutex_lock locks the given mutex. If the mutex is currently unlocked, it becomes locked and owned by the calling thread, and pthread_mutex_lock returns immediately. If the mutex is already locked by another thread, pthread_mutex_lock -suspends the calling thread until the mutex is unlocked. -

+suspends the calling thread until the mutex is unlocked.

If the mutex is already locked by the calling thread, the behavior of pthread_mutex_lock depends on the type of the mutex. If the mutex is of the “normal” type, the calling thread is suspended @@ -101,15 +124,18 @@ be performed before the mutex returns to the unlocked state.

pthread_mutex_trylock behaves identically to pthread_mutex_lock, except that it does not block the calling thread if the mutex is already locked by another thread (or by the -calling thread in the case of a “normal” mutex). Instead, -pthread_mutex_trylock returns immediately with the error code -EBUSY. +calling thread in the case of a “normal” or “errorcheck” +mutex). Instead, pthread_mutex_trylock returns immediately +with the error code EBUSY.

pthread_mutex_timedlock behaves identically to pthread_mutex_lock, except that if it cannot acquire the lock before the abs_timeout time, the call returns with the error code ETIMEDOUT. If the mutex can be locked immediately it is, and the abs_timeout parameter is ignored.

+

pthread_mutex_consistent may only be called for +PTHREAD_MUTEX_ROBUST mutexes. It simply marks the mutex as +consistent. See Robust Mutexes below.

pthread_mutex_unlock unlocks the given mutex. The mutex is assumed to be locked and owned by the calling thread on entrance to pthread_mutex_unlock. If the mutex is of the “normal” @@ -117,19 +143,53 @@ type, pthread_mutex_unlock always returns it to the unlocked state. If it is of the ‘‘recursive’’ type, it decrements the locking count of the mutex (number of pthread_mutex_lock operations performed on it by the calling thread), and only when this -count reaches zero is the mutex actually unlocked. -

+count reaches zero is the mutex actually unlocked. In Pthreads-win32, +non-robust normal or default mutex types do not check the owner of +the mutex. For all types of robust mutexes the owner is checked and +an error code is returned if the calling thread does not own the +mutex.

On ‘‘error checking’’ mutexes, pthread_mutex_unlock actually checks at run-time that the mutex is locked on entrance, and that it was locked by the same thread that is now calling pthread_mutex_unlock. If these conditions are not met, an error code is returned and the mutex remains unchanged. ‘‘Normal’’ -mutexes perform no such checks, thus allowing a locked mutex to be -unlocked by a thread other than its owner. This is non-portable -behavior and is not meant to be used as a feature.

+[non-robust] mutexes perform no such checks, thus allowing a locked +mutex to be unlocked by a thread other than its owner. This is +non-portable behavior and is not meant to be used as a feature.

pthread_mutex_destroy destroys a mutex object, freeing the resources it might hold. The mutex must be unlocked on entrance.

-

Cancellation

+

Robust Mutexes

+

If the mutex is PTHREAD_MUTEX_ROBUST and the owning thread +terminates without unlocking the mutex the implementation will wake +one waiting thread, if any. The next thread to acquire the mutex will +receive the error code EOWNERDEAD, +in which case that thread should if possible ensure that the state +protected by the mutex is consistent and then call +pthread_mutex_consistent before +unlocking. The mutex may then be used normally from then on.

+

If the thread cannot recover the +state then it must call pthread_mutex_unlock +without calling pthread_mutex_consistent. +This will mark the mutex as unusable and wake all currently waiting +threads with the return code ENOTRECOVERABLE. +The error indicates that the mutex is no longer usable and any +threads that receive this error code from any lock operation have not +acquired the mutex. The mutex can be made consistent by calling +pthread_mutex_destroy to +uninitialize the mutex, and calling pthread_mutex_int +to reinitialize the mutex. However, +the state that was protected by the mutex remains inconsistent and +some form of application recovery is required.

+

If a thread that receives the +EOWNERDEAD error code +itself terminates without unlocking the mutex then this behaviour +repeats for the next acquiring thread.

+

Applications must ensure that +they check the return values from all calls targeting robust mutexes.

+

Robust mutexes are slower because they +require some additional overhead, however they are not very much +slower than the non-robust recursive type.

+

Cancellation

None of the mutex functions is a cancellation point, not even pthread_mutex_lock, in spite of the fact that it can suspend a thread for arbitrary durations. This way, the status of mutexes at @@ -138,46 +198,56 @@ unlock precisely those mutexes that need to be unlocked before the thread stops executing. Consequently, threads using deferred cancellation should never hold a mutex for extended periods of time.

-

Async-signal Safety

+

Async-signal Safety

The mutex functions are not async-signal safe. What this means is that they should not be called from a signal handler. In particular, calling pthread_mutex_lock or pthread_mutex_unlock from a signal handler may deadlock the calling thread.

-

Return Value

+

Return Value

pthread_mutex_init always returns 0. The other mutex functions return 0 on success and a non-zero error code on error.

-

Errors

+

Errors

The pthread_mutex_lock function returns the following error code on error:

-
EINVAL -
+
EINVAL
the mutex has not been properly initialized. -
- EDEADLK -
+
+ EDEADLK
the mutex is already locked by the calling thread (‘‘error checking’’ mutexes only). -
-
-

-The pthread_mutex_trylock function returns the following error -codes on error: -

-
-
-
EBUSY -
+
+ EOWNERDEAD
+ the robust mutex is now locked by the calling thread after the + previous owner terminated without unlocking it.
+ ENOTRECOVERABLE
+ the robust mutex is not locked and is no longer usable after the + previous owner unlocked it without calling + pthread_mutex_consistent.
+
+ The pthread_mutex_trylock function returns the following + error codes on error: +
+
+ EBUSY +
the mutex could not be acquired because it was currently locked. -
+
EINVAL -
+
the mutex has not been properly initialized. -
+
+ EOWNERDEAD
+ the robust mutex is now locked by the calling thread after the + previous owner terminated without unlocking it.
+ ENOTRECOVERABLE
+ the robust mutex is not locked and is no longer usable after the + previous owner unlocked it without calling + pthread_mutex_consistent.

The pthread_mutex_timedlock function returns the following @@ -185,15 +255,22 @@ error codes on error:

-
ETIMEDOUT -
+
ETIMEDOUT +
the mutex could not be acquired before the abs_timeout time arrived. -
+
EINVAL -
+
the mutex has not been properly initialized. -
+
+ EOWNERDEAD
+ the robust mutex is now locked by the calling thread after the + previous owner terminated without unlocking it.
+ ENOTRECOVERABLE
+ the robust mutex is not locked and is no longer usable after the + previous owner unlocked it without calling + pthread_mutex_consistent.

The pthread_mutex_unlock function returns the following error @@ -201,12 +278,12 @@ code on error:

-
EINVAL -
+
EINVAL +
the mutex has not been properly initialized. -
+
EPERM -
+
the calling thread does not own the mutex (‘‘error checking’’ mutexes only).
@@ -217,61 +294,63 @@ code on error:

-
EBUSY -
+
EBUSY +
the mutex is currently locked.
-

+

Author

Xavier Leroy <Xavier.Leroy@inria.fr>

Modified by Ross Johnson for use with Pthreads-w32.

-

See Also

+

See Also

pthread_mutexattr_init(3) , pthread_mutexattr_settype(3) , pthread_cancel(3) .

-

Example

+

Example

A shared global variable x can be protected by a mutex as follows:

-
int x;
-pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
+
int x;
+pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
All accesses and modifications to x should be bracketed by calls to pthread_mutex_lock and pthread_mutex_unlock as follows:
-
pthread_mutex_lock(&mut);
+
pthread_mutex_lock(&mut);
 /* operate on x */
 pthread_mutex_unlock(&mut);

-
Table of -Contents
+
Table +of Contents
- + \ No newline at end of file diff --git a/pthreads/manual/pthread_mutexattr_init.html b/pthreads/manual/pthread_mutexattr_init.html index f3df9936d..f69599b00 100644 --- a/pthreads/manual/pthread_mutexattr_init.html +++ b/pthreads/manual/pthread_mutexattr_init.html @@ -3,22 +3,32 @@ PTHREAD_MUTEXATTR(3) manual page - + - + + + -

POSIX Threads for Windows – REFERENCE - Pthreads-w32

+

POSIX Threads for Windows – REFERENCE - +Pthreads-w32

Reference Index

Table of Contents

-

Name

+

Name

pthread_mutexattr_init, pthread_mutexattr_destroy, pthread_mutexattr_settype, pthread_mutexattr_gettype - mutex creation attributes

-

Synopsis

+

Synopsis

#include <pthread.h>

int pthread_mutexattr_init(pthread_mutexattr_t *attr); @@ -37,7 +47,13 @@ int type);

int pthread_mutexattr_getkind_np(const pthread_mutexattr_t *attr, int *type);

-

Description

+

int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, +int robust); +

+

int pthread_mutexattr_getrobust(pthread_mutexattr_t *attr, +int *robust); +

+

Description

Mutex attributes can be specified at mutex creation time, by passing a mutex attribute object as second argument to pthread_mutex_init(3) . @@ -50,12 +66,27 @@ attributes.

pthread_mutexattr_destroy destroys a mutex attribute object, which must not be reused until it is reinitialized.

+

pthread_mutexattr_settype sets the mutex type attribute in +attr to the value specified by type. +

+

pthread_mutexattr_gettype retrieves the current value of +the mutex kind attribute in attr and stores it in the location +pointed to by type. +

+

Pthreads-w32 also recognises the following equivalent +functions that are used in Linux:

+

pthread_mutexattr_setkind_np is an alias for +pthread_mutexattr_settype. +

+

pthread_mutexattr_getkind_np is +an alias for pthread_mutexattr_gettype. +

The following mutex types are supported:

-

PTHREAD_MUTEX_NORMAL - for +

PTHREAD_MUTEX_NORMAL - for ‘‘fast’’ mutexes.

-

PTHREAD_MUTEX_RECURSIVE - for +

PTHREAD_MUTEX_RECURSIVE - for ‘‘recursive’’ mutexes.

-

PTHREAD_MUTEX_ERRORCHECK - for +

PTHREAD_MUTEX_ERRORCHECK - for ‘‘error checking’’ mutexes.

The mutex type determines what happens if a thread attempts to lock a mutex it already owns with pthread_mutex_lock(3) @@ -75,83 +106,102 @@ state.

The default mutex type is PTHREAD_MUTEX_NORMAL

Pthreads-w32 also recognises the following equivalent types that are used by Linux:

-

PTHREAD_MUTEX_FAST_NP +

PTHREAD_MUTEX_FAST_NP – equivalent to PTHREAD_MUTEX_NORMAL

-

PTHREAD_MUTEX_RECURSIVE_NP

-

PTHREAD_MUTEX_ERRORCHECK_NP

-

pthread_mutexattr_settype sets the mutex type attribute in -attr to the value specified by type. -

-

pthread_mutexattr_gettype retrieves the current value of -the mutex kind attribute in attr and stores it in the location -pointed to by type. -

-

Pthreads-w32 also recognises the following equivalent -functions that are used in Linux:

-

pthread_mutexattr_setkind_np is an alias for -pthread_mutexattr_settype. -

-

pthread_mutexattr_getkind_np is -an alias for pthread_mutexattr_gettype. -

-

Return Value

-

pthread_mutexattr_init, pthread_mutexattr_destroy -and pthread_mutexattr_gettype always return 0. -

-

pthread_mutexattr_settype returns 0 on success and a -non-zero error code on error. -

-

Errors

-

On error, pthread_mutexattr_settype returns the following -error code: -

+

PTHREAD_MUTEX_RECURSIVE_NP

+

PTHREAD_MUTEX_ERRORCHECK_NP

+

pthread_mutexattr_setrobust +sets the robustness attribute to the value given by robust.

+

pthread_mutexattr_getrobust +returns the current robustness value to the location given by +*robust.

+

The possible values for robust +are:

+

PTHREAD_MUTEX_STALLED +- when the owner of the mutex terminates without unlocking the mutex, +all subsequent calls to pthread_mutex_*lock() are blocked from +progress in an unspecified manner.

+

PTHREAD_MUTEX_ROBUST +- when the owner of the mutex terminates without unlocking the mutex, +the mutex is unlocked. The next owner of this mutex acquires the +mutex with an error return of EOWNERDEAD.

+

Return Value

+

On success all functions return +0, otherwise they return an error code as follows:

+

pthread_mutexattr_init

+

ENOMEM +- insufficient memory for attr.

+

pthread_mutexattr_destroy

+

EINVAL +- attr +is invalid.

+

pthread_mutexattr_gettype

+

EINVAL +- attr +is invalid.

+

pthread_mutexattr_settype

-
EINVAL -
- type is none of:
PTHREAD_MUTEX_NORMAL, - PTHREAD_MUTEX_FAST_NP,
PTHREAD_MUTEX_RECURSIVE, - PTHREAD_MUTEX_RECURSIVE_NP,
PTHREAD_MUTEX_ERRORCHECK
, - PTHREAD_MUTEX_ERRORCHECK_NP +
+
+
EINVAL - attr + is invalid or type + is none of:
+
+
+ PTHREAD_MUTEX_NORMAL
PTHREAD_MUTEX_FAST_NP
PTHREAD_MUTEX_RECURSIVE
PTHREAD_MUTEX_RECURSIVE_NP
PTHREAD_MUTEX_ERRORCHECK
PTHREAD_MUTEX_ERRORCHECK_NP
+
+
+
+
+
-

-Author

+

+pthread_mutexattr_getrobust

+

EINVAL +– attr +or robust +is invalid.

+

pthread_mutexattr_setrobust

+

EINVAL +– attr +or robust +is invalid.

+

Author

Xavier Leroy <Xavier.Leroy@inria.fr>

Modified by Ross Johnson for use with Pthreads-w32.

-

See Also

+

See Also

pthread_mutex_init(3) , pthread_mutex_lock(3) , pthread_mutex_unlock(3) .

-

Notes

+

Notes

For speed, Pthreads-w32 never checks the thread ownership -of mutexes of type PTHREAD_MUTEX_NORMAL (or +of non-robust mutexes of type PTHREAD_MUTEX_NORMAL (or PTHREAD_MUTEX_FAST_NP) when performing operations on the mutex. It is therefore possible for one thread to lock such a mutex and another to unlock it.

-

When developing code, it is a -common precaution to substitute the error checking type, and drop in -the normal type for release if the extra performance is required.

+

When developing code, it is a common +precaution to substitute the error checking type, then drop in the +normal type for release if the extra performance is required.


Table of Contents

- + \ No newline at end of file diff --git a/pthreads/mutex.c b/pthreads/mutex.c index cae4c8ca0..c2b3607ca 100644 --- a/pthreads/mutex.c +++ b/pthreads/mutex.c @@ -1,59 +1,62 @@ -/* - * mutex.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 - */ - -#if ! defined(_UWIN) && ! defined(WINCE) -# include -#endif -#ifndef NEED_FTIME -#include -#endif -#include "pthread.h" -#include "implement.h" - - -#include "ptw32_mutex_check_need_init.c" -#include "pthread_mutex_init.c" -#include "pthread_mutex_destroy.c" -#include "pthread_mutexattr_init.c" -#include "pthread_mutexattr_destroy.c" -#include "pthread_mutexattr_getpshared.c" -#include "pthread_mutexattr_setpshared.c" -#include "pthread_mutexattr_settype.c" -#include "pthread_mutexattr_gettype.c" -#include "pthread_mutex_lock.c" -#include "pthread_mutex_timedlock.c" -#include "pthread_mutex_unlock.c" -#include "pthread_mutex_trylock.c" +/* + * mutex.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 + */ + +#if ! defined(_UWIN) && ! defined(WINCE) +# include +#endif +#if !defined(NEED_FTIME) +#include +#endif +#include "pthread.h" +#include "implement.h" + + +#include "ptw32_mutex_check_need_init.c" +#include "pthread_mutex_init.c" +#include "pthread_mutex_destroy.c" +#include "pthread_mutexattr_init.c" +#include "pthread_mutexattr_destroy.c" +#include "pthread_mutexattr_getpshared.c" +#include "pthread_mutexattr_setpshared.c" +#include "pthread_mutexattr_settype.c" +#include "pthread_mutexattr_gettype.c" +#include "pthread_mutexattr_setrobust.c" +#include "pthread_mutexattr_getrobust.c" +#include "pthread_mutex_lock.c" +#include "pthread_mutex_timedlock.c" +#include "pthread_mutex_unlock.c" +#include "pthread_mutex_trylock.c" +#include "pthread_mutex_consistent.c" diff --git a/pthreads/need_errno.h b/pthreads/need_errno.h index 165853bac..abf1c9557 100644 --- a/pthreads/need_errno.h +++ b/pthreads/need_errno.h @@ -1,141 +1,145 @@ -/*** -* errno.h - system wide error numbers (set by system calls) -* -* Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved. -* -* Purpose: -* This file defines the system-wide error numbers (set by -* system calls). Conforms to the XENIX standard. Extended -* for compatibility with Uniforum standard. -* [System V] -* -* [Public] -* -****/ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#ifndef _INC_ERRNO -#define _INC_ERRNO - -#if !defined(_WIN32) && !defined(_MAC) -#error ERROR: Only Mac or Win32 targets supported! -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - - -/* Define _CRTIMP */ - -#ifndef _CRTIMP -#ifdef _DLL -#define _CRTIMP __declspec(dllimport) -#else /* ndef _DLL */ -#define _CRTIMP -#endif /* _DLL */ -#endif /* _CRTIMP */ - - -/* Define __cdecl for non-Microsoft compilers */ - -#if ( !defined(_MSC_VER) && !defined(__cdecl) ) -#define __cdecl -#endif - -/* Define _CRTAPI1 (for compatibility with the NT SDK) */ - -#ifndef _CRTAPI1 -#if _MSC_VER >= 800 && _M_IX86 >= 300 -#define _CRTAPI1 __cdecl -#else -#define _CRTAPI1 -#endif -#endif - -#if !defined(PTW32_STATIC_LIB) -# ifdef PTW32_BUILD -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* declare reference to errno */ - -#if (defined(_MT) || defined(_MD) || defined(_DLL)) && !defined(_MAC) -PTW32_DLLPORT int * __cdecl _errno(void); -#define errno (*_errno()) -#else /* ndef _MT && ndef _MD && ndef _DLL */ -_CRTIMP extern int errno; -#endif /* _MT || _MD || _DLL */ - -/* Error Codes */ - -#define EPERM 1 -#define ENOENT 2 -#define ESRCH 3 -#define EINTR 4 -#define EIO 5 -#define ENXIO 6 -#define E2BIG 7 -#define ENOEXEC 8 -#define EBADF 9 -#define ECHILD 10 -#define EAGAIN 11 -#define ENOMEM 12 -#define EACCES 13 -#define EFAULT 14 -#define EBUSY 16 -#define EEXIST 17 -#define EXDEV 18 -#define ENODEV 19 -#define ENOTDIR 20 -#define EISDIR 21 -#define EINVAL 22 -#define ENFILE 23 -#define EMFILE 24 -#define ENOTTY 25 -#define EFBIG 27 -#define ENOSPC 28 -#define ESPIPE 29 -#define EROFS 30 -#define EMLINK 31 -#define EPIPE 32 -#define EDOM 33 -#define ERANGE 34 -#define EDEADLK 36 - -/* defined differently in winsock.h on WinCE */ -#ifndef ENAMETOOLONG -#define ENAMETOOLONG 38 -#endif - -#define ENOLCK 39 -#define ENOSYS 40 - -/* defined differently in winsock.h on WinCE */ -#ifndef ENOTEMPTY -#define ENOTEMPTY 41 -#endif - -#define EILSEQ 42 - -/* - * Support EDEADLOCK for compatibiity with older MS-C versions. - */ -#define EDEADLOCK EDEADLK - -#ifdef __cplusplus -} -#endif - -#endif /* _INC_ERRNO */ +/*** +* errno.h - system wide error numbers (set by system calls) +* +* Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved. +* +* Purpose: +* This file defines the system-wide error numbers (set by +* system calls). Conforms to the XENIX standard. Extended +* for compatibility with Uniforum standard. +* [System V] +* +* [Public] +* +****/ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#if !defined(_INC_ERRNO) +#define _INC_ERRNO + +#if !defined(_WIN32) +#error ERROR: Only Win32 targets supported! +#endif + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + + +/* Define _CRTIMP */ + +#ifndef _CRTIMP +#if defined(_DLL) +#define _CRTIMP __declspec(dllimport) +#else /* ndef _DLL */ +#define _CRTIMP +#endif /* _DLL */ +#endif /* _CRTIMP */ + + +/* Define __cdecl for non-Microsoft compilers */ + +#if ( !defined(_MSC_VER) && !defined(__cdecl) ) +#define __cdecl +#endif + +/* Define _CRTAPI1 (for compatibility with the NT SDK) */ + +#if !defined(_CRTAPI1) +#if _MSC_VER >= 800 && _M_IX86 >= 300 +#define _CRTAPI1 __cdecl +#else +#define _CRTAPI1 +#endif +#endif + +#if !defined(PTW32_STATIC_LIB) +# if defined(PTW32_BUILD) +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* declare reference to errno */ + +#if (defined(_MT) || defined(_MD) || defined(_DLL)) && !defined(_MAC) +PTW32_DLLPORT int * __cdecl _errno(void); +#define errno (*_errno()) +#else /* ndef _MT && ndef _MD && ndef _DLL */ +_CRTIMP extern int errno; +#endif /* _MT || _MD || _DLL */ + +/* Error Codes */ + +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EAGAIN 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define EINVAL 22 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define ERANGE 34 +#define EDEADLK 36 + +/* defined differently in winsock.h on WinCE */ +#if !defined(ENAMETOOLONG) +#define ENAMETOOLONG 38 +#endif + +#define ENOLCK 39 +#define ENOSYS 40 + +/* defined differently in winsock.h on WinCE */ +#if !defined(ENOTEMPTY) +#define ENOTEMPTY 41 +#endif + +#define EILSEQ 42 + +/* POSIX 2008 - robust mutexes */ +#define EOWNERDEAD 43 +#define ENOTRECOVERABLE 44 + +/* + * Support EDEADLOCK for compatibiity with older MS-C versions. + */ +#define EDEADLOCK EDEADLK + +#if defined(__cplusplus) +} +#endif + +#endif /* _INC_ERRNO */ diff --git a/pthreads/nonportable.c b/pthreads/nonportable.c index 6c2a990aa..742cb969b 100644 --- a/pthreads/nonportable.c +++ b/pthreads/nonportable.c @@ -40,6 +40,7 @@ #include "pthread_mutexattr_setkind_np.c" #include "pthread_mutexattr_getkind_np.c" #include "pthread_getw32threadhandle_np.c" +#include "pthread_getunique_np.c" #include "pthread_delay_np.c" #include "pthread_num_processors_np.c" #include "pthread_win32_attach_detach_np.c" diff --git a/pthreads/private.c b/pthreads/private.c index 7e311b10e..1b1ccb7c5 100644 --- a/pthreads/private.c +++ b/pthreads/private.c @@ -38,9 +38,6 @@ #include "pthread.h" #include "implement.h" -/* Must be first to define HAVE_INLINABLE_INTERLOCKED_CMPXCHG */ -#include "ptw32_InterlockedCompareExchange.c" - #include "ptw32_MCS_lock.c" #include "ptw32_is_attr.c" #include "ptw32_processInitialize.c" diff --git a/pthreads/pthread.h b/pthreads/pthread.h index 3ffad8493..9a1978820 100644 --- a/pthreads/pthread.h +++ b/pthreads/pthread.h @@ -1,1378 +1,1368 @@ -/* 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,9,0,0 -#define PTW32_VERSION_STRING "2, 9, 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(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !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 - * - * 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) -#define PTW32_INCLUDE_WINDOWS_H -#endif - -#ifdef PTW32_INCLUDE_WINDOWS_H -#include -#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 */ - -#ifndef NEED_FTIME -#include -#else /* NEED_FTIME */ -/* use native WIN32 time API */ -#endif /* NEED_FTIME */ - -#if HAVE_SIGNAL_H -#include -#endif /* HAVE_SIGNAL_H */ - -#include -#include - -/* - * 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 -#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 - -/* - * To avoid including windows.h we define only those things that we - * actually need from it. - */ -#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 - -#ifndef HAVE_STRUCT_TIMESPEC -#define HAVE_STRUCT_TIMESPEC 1 -struct timespec { - time_t 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 , 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 , 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). - * - * SEM_NSEMS_MAX - * The maximum number of semaphores a process can have. - * (must be at least 256) - * - * SEM_VALUE_MAX - * The maximum value a semaphore can have. - * (must be at least 32767) - * - */ -#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS -#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 - -#undef PTHREAD_DESTRUCTOR_ITERATIONS -#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS - -#undef _POSIX_THREAD_KEYS_MAX -#define _POSIX_THREAD_KEYS_MAX 128 - -#undef PTHREAD_KEYS_MAX -#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX - -#undef PTHREAD_STACK_MIN -#define PTHREAD_STACK_MIN 0 - -#undef _POSIX_THREAD_THREADS_MAX -#define _POSIX_THREAD_THREADS_MAX 64 - - /* Arbitrary value */ -#undef PTHREAD_THREADS_MAX -#define PTHREAD_THREADS_MAX 2019 - -#undef _POSIX_SEM_NSEMS_MAX -#define _POSIX_SEM_NSEMS_MAX 256 - - /* Arbitrary value */ -#undef SEM_NSEMS_MAX -#define SEM_NSEMS_MAX 1024 - -#undef _POSIX_SEM_VALUE_MAX -#define _POSIX_SEM_VALUE_MAX 32767 - -#undef SEM_VALUE_MAX -#define SEM_VALUE_MAX INT_MAX - - -#if __GNUC__ && ! defined (__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(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 -#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 { PTW32_FALSE, 0, 0, 0} - -struct pthread_once_t_ -{ - int done; /* indicates if user function has been executed */ - void * lock; - int reserved1; - int reserved2; -}; - - -/* - * ==================== - * ==================== - * 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 (const 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(const 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 (const 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 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); -/* - * Returns the win32 thread ID for POSIX thread. - */ -PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_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) ) - -/* - * gmtime(tm) and localtime(tm) return 0 if tm represents - * a time prior to 1/1/1970. - */ -#define gmtime_r( _clock, _result ) \ - ( gmtime( (_clock) ) \ - ? (*(_result) = *gmtime( (_clock) ), (_result) ) \ - : (0) ) - -#define localtime_r( _clock, _result ) \ - ( localtime( (_clock) ) \ - ? (*(_result) = *localtime( (_clock) ), (_result) ) \ - : (0) ) - -#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,9,0,0 +#define PTW32_VERSION_STRING "2, 9, 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. + */ +#if !defined(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(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + +#if defined(_UWIN) +# define HAVE_STRUCT_TIMESPEC 1 +# define HAVE_SIGNAL_H 1 +# undef HAVE_PTW32_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 + * + * 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(__MINGW64__) || defined(__MINGW32__)) && defined(__cplusplus) +#define PTW32_INCLUDE_WINDOWS_H +#endif + +#if defined(PTW32_INCLUDE_WINDOWS_H) +#include +#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; +typedef unsigned long ULONG_PTR; +#endif +/* + * ----------------- + * autoconf switches + * ----------------- + */ + +#if defined(HAVE_PTW32_CONFIG_H) +#include "config.h" +#endif /* HAVE_PTW32_CONFIG_H */ + +#if !defined(NEED_FTIME) +#include +#else /* NEED_FTIME */ +/* use native WIN32 time API */ +#endif /* NEED_FTIME */ + +#if defined(HAVE_SIGNAL_H) +#include +#endif /* HAVE_SIGNAL_H */ + +#include + +/* + * 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. + */ + +#if !defined(PTW32_CONFIG_H) +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(__MINGW64__) +# define HAVE_STRUCT_TIMESPEC +# define HAVE_MODE_T +# elif defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#if defined(NEED_ERRNO) +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Several systems don't define some error numbers. + */ +#if !defined(ENOTSUP) +# define ENOTSUP 48 /* This is the value in Solaris. */ +#endif + +#if !defined(ETIMEDOUT) +# define ETIMEDOUT 10060 /* Same as WSAETIMEDOUT */ +#endif + +#if !defined(ENOSYS) +# define ENOSYS 140 /* Semi-arbitrary value */ +#endif + +#if !defined(EDEADLK) +# if defined(EDEADLOCK) +# define EDEADLK EDEADLOCK +# else +# define EDEADLK 36 /* This is the value in MSVC. */ +# endif +#endif + +/* POSIX 2008 - related to robust mutexes */ +#if !defined(EOWNERDEAD) +# define EOWNERDEAD 43 +#endif +#if !defined(ENOTRECOVERABLE) +# define ENOTRECOVERABLE 44 +#endif + +#include + +/* + * To avoid including windows.h we define only those things that we + * actually need from it. + */ +#if !defined(PTW32_INCLUDE_WINDOWS_H) +#if !defined(HANDLE) +# define PTW32__HANDLE_DEF +# define HANDLE void * +#endif +#if !defined(DWORD) +# define PTW32__DWORD_DEF +# define DWORD unsigned long +#endif +#endif + +#if !defined(HAVE_STRUCT_TIMESPEC) +#define HAVE_STRUCT_TIMESPEC +#if !defined(_TIMESPEC_DEFINED) +#define _TIMESPEC_DEFINED +struct timespec { + time_t tv_sec; + long tv_nsec; +}; +#endif /* _TIMESPEC_DEFINED */ +#endif /* HAVE_STRUCT_TIMESPEC */ + +#if !defined(SIG_BLOCK) +#define SIG_BLOCK 0 +#endif /* SIG_BLOCK */ + +#if !defined(SIG_UNBLOCK) +#define SIG_UNBLOCK 1 +#endif /* SIG_UNBLOCK */ + +#if !defined(SIG_SETMASK) +#define SIG_SETMASK 2 +#endif /* SIG_SETMASK */ + +#if defined(__cplusplus) +extern "C" +{ +#endif /* __cplusplus */ + +/* + * ------------------------------------------------------------- + * + * POSIX 1003.1-2001 Options + * ========================= + * + * Options are normally set in , 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 200809L + +#undef _POSIX_READER_WRITER_LOCKS +#define _POSIX_READER_WRITER_LOCKS 200809L + +#undef _POSIX_SPIN_LOCKS +#define _POSIX_SPIN_LOCKS 200809L + +#undef _POSIX_BARRIERS +#define _POSIX_BARRIERS 200809L + +#undef _POSIX_THREAD_SAFE_FUNCTIONS +#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L + +#undef _POSIX_THREAD_ATTR_STACKSIZE +#define _POSIX_THREAD_ATTR_STACKSIZE 200809L + +/* + * 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 , 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). + * + * SEM_NSEMS_MAX + * The maximum number of semaphores a process can have. + * (must be at least 256) + * + * SEM_VALUE_MAX + * The maximum value a semaphore can have. + * (must be at least 32767) + * + */ +#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 + +#undef PTHREAD_DESTRUCTOR_ITERATIONS +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS + +#undef _POSIX_THREAD_KEYS_MAX +#define _POSIX_THREAD_KEYS_MAX 128 + +#undef PTHREAD_KEYS_MAX +#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX + +#undef PTHREAD_STACK_MIN +#define PTHREAD_STACK_MIN 0 + +#undef _POSIX_THREAD_THREADS_MAX +#define _POSIX_THREAD_THREADS_MAX 64 + + /* Arbitrary value */ +#undef PTHREAD_THREADS_MAX +#define PTHREAD_THREADS_MAX 2019 + +#undef _POSIX_SEM_NSEMS_MAX +#define _POSIX_SEM_NSEMS_MAX 256 + + /* Arbitrary value */ +#undef SEM_NSEMS_MAX +#define SEM_NSEMS_MAX 1024 + +#undef _POSIX_SEM_VALUE_MAX +#define _POSIX_SEM_VALUE_MAX 32767 + +#undef SEM_VALUE_MAX +#define SEM_VALUE_MAX INT_MAX + + +#if defined(__GNUC__) && !defined(__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the library, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the library, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#if !defined(PTW32_STATIC_LIB) +# if defined(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 +#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_mutexattr_{get,set}robust + */ + PTHREAD_MUTEX_STALLED = 0, /* Default */ + PTHREAD_MUTEX_ROBUST = 1, + +/* + * pthread_barrier_wait + */ + PTHREAD_BARRIER_SERIAL_THREAD = -1 +}; + +/* + * ==================== + * ==================== + * Cancelation + * ==================== + * ==================== + */ +#define PTHREAD_CANCELED ((void *)(size_t) -1) + + +/* + * ==================== + * ==================== + * Once Key + * ==================== + * ==================== + */ +#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0} + +struct pthread_once_t_ +{ + int done; /* indicates if user function has been executed */ + void * lock; + int reserved1; + int reserved2; +}; + + +/* + * ==================== + * ==================== + * Object initialisers + * ==================== + * ==================== + */ +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -1) +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -2) +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t)(size_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)(size_t) -1) + +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1) + +#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t)(size_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; +}; + +#if defined(__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 */ + +#if defined(__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 */ + +#if defined(__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 (const 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(const 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 (const pthread_mutexattr_t * attr, int *kind); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setrobust( + pthread_mutexattr_t *attr, + int robust); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getrobust( + const pthread_mutexattr_t * attr, + int * robust); + +/* + * 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); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_consistent (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 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); +PTW32_DLLPORT unsigned __int64 PTW32_CDECL pthread_getunique_np(pthread_t thread); + +/* + * 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); +/* + * Returns the win32 thread ID for POSIX thread. + */ +PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_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. + */ +#if !defined(_UWIN) +# if defined(NEED_ERRNO) + PTW32_DLLPORT int * PTW32_CDECL _errno( void ); +# else +# if !defined(errno) +# if (defined(_MT) || defined(_DLL)) + __declspec(dllimport) extern int * __cdecl _errno(void); +# define errno (*_errno()) +# endif +# endif +# endif +#endif + +/* + * Some compiler environments don't define some things. + */ +#if defined(__BORLANDC__) +# define _ftime ftime +# define _timeb timeb +#endif + +#if defined(__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 */ + +#if !defined(PTW32_BUILD) + +#if defined(__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 */ + +#if defined(__CLEANUP_CXX) + +/* + * Redefine the C++ catch keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#if defined(_MSC_VER) + /* + * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' + * if you want Pthread-Win32 cancelation and pthread_exit to work. + */ + +#if !defined(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(" #if defined(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 */ + +#if defined(__cplusplus) +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#if defined(PTW32__HANDLE_DEF) +# undef HANDLE +#endif +#if defined(PTW32__DWORD_DEF) +# undef DWORD +#endif + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* ! RC_INVOKED */ + +#endif /* PTHREAD_H */ diff --git a/pthreads/pthread_attr_getscope.c b/pthreads/pthread_attr_getscope.c index 3c863821e..2efdb2fe6 100644 --- a/pthreads/pthread_attr_getscope.c +++ b/pthreads/pthread_attr_getscope.c @@ -38,14 +38,14 @@ #include "implement.h" /* ignore warning "unreferenced formal parameter" */ -#ifdef _MSC_VER +#if defined(_MSC_VER) #pragma warning( disable : 4100 ) #endif int pthread_attr_getscope (const pthread_attr_t * attr, int *contentionscope) { -#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) *contentionscope = (*attr)->contentionscope; return 0; #else diff --git a/pthreads/pthread_attr_getstackaddr.c b/pthreads/pthread_attr_getstackaddr.c index 9b5595928..1a2da01c7 100644 --- a/pthreads/pthread_attr_getstackaddr.c +++ b/pthreads/pthread_attr_getstackaddr.c @@ -38,7 +38,7 @@ #include "implement.h" /* ignore warning "unreferenced formal parameter" */ -#ifdef _MSC_VER +#if defined(_MSC_VER) #pragma warning( disable : 4100 ) #endif diff --git a/pthreads/pthread_attr_getstacksize.c b/pthreads/pthread_attr_getstacksize.c index da8db636c..dff9230f2 100644 --- a/pthreads/pthread_attr_getstacksize.c +++ b/pthreads/pthread_attr_getstacksize.c @@ -38,7 +38,7 @@ #include "implement.h" /* ignore warning "unreferenced formal parameter" */ -#ifdef _MSC_VER +#if defined(_MSC_VER) #pragma warning( disable : 4100 ) #endif @@ -80,7 +80,7 @@ pthread_attr_getstacksize (const pthread_attr_t * attr, size_t * stacksize) * ------------------------------------------------------ */ { -#ifdef _POSIX_THREAD_ATTR_STACKSIZE +#if defined(_POSIX_THREAD_ATTR_STACKSIZE) if (ptw32_is_attr (attr) != 0) { diff --git a/pthreads/pthread_attr_init.c b/pthreads/pthread_attr_init.c index 6c10bd3e7..ae9d3eb5f 100644 --- a/pthreads/pthread_attr_init.c +++ b/pthreads/pthread_attr_init.c @@ -80,7 +80,7 @@ pthread_attr_init (pthread_attr_t * attr) return ENOMEM; } -#ifdef _POSIX_THREAD_ATTR_STACKSIZE +#if defined(_POSIX_THREAD_ATTR_STACKSIZE) /* * Default to zero size. Unless changed explicitly this * will allow Win32 to set the size to that of the @@ -89,14 +89,14 @@ pthread_attr_init (pthread_attr_t * attr) attr_result->stacksize = 0; #endif -#ifdef _POSIX_THREAD_ATTR_STACKADDR +#if defined(_POSIX_THREAD_ATTR_STACKADDR) /* FIXME: Set this to something sensible when we support it. */ attr_result->stackaddr = NULL; #endif attr_result->detachstate = PTHREAD_CREATE_JOINABLE; -#if HAVE_SIGSET_T +#if defined(HAVE_SIGSET_T) memset (&(attr_result->sigmask), 0, sizeof (sigset_t)); #endif /* HAVE_SIGSET_T */ diff --git a/pthreads/pthread_attr_setscope.c b/pthreads/pthread_attr_setscope.c index 9cef423b2..39a51df88 100644 --- a/pthreads/pthread_attr_setscope.c +++ b/pthreads/pthread_attr_setscope.c @@ -38,14 +38,14 @@ #include "implement.h" /* ignore warning "unreferenced formal parameter" */ -#ifdef _MSC_VER +#if defined(_MSC_VER) #pragma warning( disable : 4100 ) #endif int pthread_attr_setscope (pthread_attr_t * attr, int contentionscope) { -#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) switch (contentionscope) { case PTHREAD_SCOPE_SYSTEM: diff --git a/pthreads/pthread_attr_setstackaddr.c b/pthreads/pthread_attr_setstackaddr.c index 96a832097..1316c0659 100644 --- a/pthreads/pthread_attr_setstackaddr.c +++ b/pthreads/pthread_attr_setstackaddr.c @@ -51,8 +51,8 @@ pthread_attr_setstackaddr (pthread_attr_t * attr, void *stackaddr) * attr * pointer to an instance of pthread_attr_t * - * stacksize - * stack size, in bytes. + * stackaddr + * the address of the stack to use * * * DESCRIPTION diff --git a/pthreads/pthread_attr_setstacksize.c b/pthreads/pthread_attr_setstacksize.c index 9df46afc4..eb13589a0 100644 --- a/pthreads/pthread_attr_setstacksize.c +++ b/pthreads/pthread_attr_setstacksize.c @@ -80,7 +80,7 @@ pthread_attr_setstacksize (pthread_attr_t * attr, size_t stacksize) * ------------------------------------------------------ */ { -#ifdef _POSIX_THREAD_ATTR_STACKSIZE +#if defined(_POSIX_THREAD_ATTR_STACKSIZE) #if PTHREAD_STACK_MIN > 0 diff --git a/pthreads/pthread_barrier_destroy.c b/pthreads/pthread_barrier_destroy.c index 36472325d..55163cc85 100644 --- a/pthreads/pthread_barrier_destroy.c +++ b/pthreads/pthread_barrier_destroy.c @@ -1,103 +1,103 @@ -/* - * pthread_barrier_destroy.c - * - * Description: - * This translation unit implements barrier 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" - -int -pthread_barrier_destroy (pthread_barrier_t * barrier) -{ - int result = 0; - pthread_barrier_t b; - ptw32_mcs_local_node_t node; - - if (barrier == NULL || *barrier == (pthread_barrier_t) PTW32_OBJECT_INVALID) - { - return EINVAL; - } - - if (0 != ptw32_mcs_lock_try_acquire((ptw32_mcs_lock_t *)&(*barrier)->lock, &node)) - { - return EBUSY; - } - - b = *barrier; - - if (b->nCurrentBarrierHeight < b->nInitialBarrierHeight) - { - result = EBUSY; - } - else - { - if (0 == (result = sem_destroy (&(b->semBarrierBreeched)))) - { - *barrier = (pthread_barrier_t) PTW32_OBJECT_INVALID; - /* - * Release the lock before freeing b. - * - * FIXME: There may be successors which, when we release the lock, - * will be linked into b->lock, which will be corrupted at some - * point with undefined results for the application. To fix this - * will require changing pthread_barrier_t from a pointer to - * pthread_barrier_t_ to an instance. This is a change to the ABI - * and will require a major version number increment. - */ - ptw32_mcs_lock_release(&node); - (void) free (b); - return 0; - } - else - { - /* - * This should not ever be reached. - * Restore the barrier to working condition before returning. - */ - (void) sem_init (&(b->semBarrierBreeched), b->pshared, 0); - } - - if (result != 0) - { - /* - * The barrier still exists and is valid - * in the event of any error above. - */ - result = EBUSY; - } - } - - ptw32_mcs_lock_release(&node); - return (result); -} +/* + * pthread_barrier_destroy.c + * + * Description: + * This translation unit implements barrier 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" + +int +pthread_barrier_destroy (pthread_barrier_t * barrier) +{ + int result = 0; + pthread_barrier_t b; + ptw32_mcs_local_node_t node; + + if (barrier == NULL || *barrier == (pthread_barrier_t) PTW32_OBJECT_INVALID) + { + return EINVAL; + } + + if (0 != ptw32_mcs_lock_try_acquire(&(*barrier)->lock, &node)) + { + return EBUSY; + } + + b = *barrier; + + if (b->nCurrentBarrierHeight < b->nInitialBarrierHeight) + { + result = EBUSY; + } + else + { + if (0 == (result = sem_destroy (&(b->semBarrierBreeched)))) + { + *barrier = (pthread_barrier_t) PTW32_OBJECT_INVALID; + /* + * Release the lock before freeing b. + * + * FIXME: There may be successors which, when we release the lock, + * will be linked into b->lock, which will be corrupted at some + * point with undefined results for the application. To fix this + * will require changing pthread_barrier_t from a pointer to + * pthread_barrier_t_ to an instance. This is a change to the ABI + * and will require a major version number increment. + */ + ptw32_mcs_lock_release(&node); + (void) free (b); + return 0; + } + else + { + /* + * This should not ever be reached. + * Restore the barrier to working condition before returning. + */ + (void) sem_init (&(b->semBarrierBreeched), b->pshared, 0); + } + + if (result != 0) + { + /* + * The barrier still exists and is valid + * in the event of any error above. + */ + result = EBUSY; + } + } + + ptw32_mcs_lock_release(&node); + return (result); +} diff --git a/pthreads/pthread_barrier_wait.c b/pthreads/pthread_barrier_wait.c index a19582583..e0e97e6c7 100644 --- a/pthreads/pthread_barrier_wait.c +++ b/pthreads/pthread_barrier_wait.c @@ -1,104 +1,104 @@ -/* - * pthread_barrier_wait.c - * - * Description: - * This translation unit implements barrier 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" - - -int -pthread_barrier_wait (pthread_barrier_t * barrier) -{ - int result; - pthread_barrier_t b; - - ptw32_mcs_local_node_t node; - - if (barrier == NULL || *barrier == (pthread_barrier_t) PTW32_OBJECT_INVALID) - { - return EINVAL; - } - - ptw32_mcs_lock_acquire((ptw32_mcs_lock_t *)&(*barrier)->lock, &node); - - b = *barrier; - if (--b->nCurrentBarrierHeight == 0) - { - /* - * We are the last thread to arrive at the barrier before it releases us. - * Move our MCS local node to the global scope barrier handle so that the - * last thread out (not necessarily us) can release the lock. - */ - ptw32_mcs_node_substitute(&b->proxynode, &node); - - /* - * Any threads that have not quite entered sem_wait below when the - * multiple_post has completed will nevertheless continue through - * the semaphore (barrier). - */ - result = (b->nInitialBarrierHeight > 1 - ? sem_post_multiple (&(b->semBarrierBreeched), - b->nInitialBarrierHeight - 1) : 0); - } - else - { - ptw32_mcs_lock_release(&node); - /* - * Use the non-cancelable version of sem_wait(). - * - * It is possible that all nInitialBarrierHeight-1 threads are - * at this point when the last thread enters the barrier, resets - * nCurrentBarrierHeight = nInitialBarrierHeight and leaves. - * If pthread_barrier_destroy is called at that moment then the - * barrier will be destroyed along with the semas. - */ - result = ptw32_semwait (&(b->semBarrierBreeched)); - } - - if ((PTW32_INTERLOCKED_LONG)InterlockedIncrement((LPLONG)&b->nCurrentBarrierHeight) - == (PTW32_INTERLOCKED_LONG)b->nInitialBarrierHeight) - { - /* - * We are the last thread to cross this barrier - */ - ptw32_mcs_lock_release(&b->proxynode); - if (0 == result) - { - result = PTHREAD_BARRIER_SERIAL_THREAD; - } - } - - return (result); -} +/* + * pthread_barrier_wait.c + * + * Description: + * This translation unit implements barrier 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" + + +int +pthread_barrier_wait (pthread_barrier_t * barrier) +{ + int result; + pthread_barrier_t b; + + ptw32_mcs_local_node_t node; + + if (barrier == NULL || *barrier == (pthread_barrier_t) PTW32_OBJECT_INVALID) + { + return EINVAL; + } + + ptw32_mcs_lock_acquire(&(*barrier)->lock, &node); + + b = *barrier; + if (--b->nCurrentBarrierHeight == 0) + { + /* + * We are the last thread to arrive at the barrier before it releases us. + * Move our MCS local node to the global scope barrier handle so that the + * last thread out (not necessarily us) can release the lock. + */ + ptw32_mcs_node_transfer(&b->proxynode, &node); + + /* + * Any threads that have not quite entered sem_wait below when the + * multiple_post has completed will nevertheless continue through + * the semaphore (barrier). + */ + result = (b->nInitialBarrierHeight > 1 + ? sem_post_multiple (&(b->semBarrierBreeched), + b->nInitialBarrierHeight - 1) : 0); + } + else + { + ptw32_mcs_lock_release(&node); + /* + * Use the non-cancelable version of sem_wait(). + * + * It is possible that all nInitialBarrierHeight-1 threads are + * at this point when the last thread enters the barrier, resets + * nCurrentBarrierHeight = nInitialBarrierHeight and leaves. + * If pthread_barrier_destroy is called at that moment then the + * barrier will be destroyed along with the semas. + */ + result = ptw32_semwait (&(b->semBarrierBreeched)); + } + + if ((PTW32_INTERLOCKED_LONG)PTW32_INTERLOCKED_INCREMENT_LONG((PTW32_INTERLOCKED_LONGPTR)&b->nCurrentBarrierHeight) + == (PTW32_INTERLOCKED_LONG)b->nInitialBarrierHeight) + { + /* + * We are the last thread to cross this barrier + */ + ptw32_mcs_lock_release(&b->proxynode); + if (0 == result) + { + result = PTHREAD_BARRIER_SERIAL_THREAD; + } + } + + return (result); +} diff --git a/pthreads/pthread_cancel.c b/pthreads/pthread_cancel.c index d1f281bb0..ae60b7293 100644 --- a/pthreads/pthread_cancel.c +++ b/pthreads/pthread_cancel.c @@ -1,188 +1,189 @@ -/* - * pthread_cancel.c - * - * Description: - * POSIX thread functions related to thread cancellation. - * - * -------------------------------------------------------------------------- - * - * 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" -#include "context.h" - -static void -ptw32_cancel_self (void) -{ - ptw32_throw (PTW32_EPS_CANCEL); - - /* Never reached */ -} - -static void CALLBACK -ptw32_cancel_callback (DWORD unused) -{ - ptw32_throw (PTW32_EPS_CANCEL); - - /* Never reached */ -} - -/* - * ptw32_RegisterCancelation() - - * Must have args of same type as QueueUserAPCEx because this function - * is a substitute for QueueUserAPCEx if it's not available. - */ -DWORD -ptw32_RegisterCancelation (PAPCFUNC unused1, HANDLE threadH, DWORD unused2) -{ - CONTEXT context; - - context.ContextFlags = CONTEXT_CONTROL; - GetThreadContext (threadH, &context); - PTW32_PROGCTR (context) = (DWORD_PTR) ptw32_cancel_self; - SetThreadContext (threadH, &context); - return 0; -} - -int -pthread_cancel (pthread_t thread) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function requests cancellation of 'thread'. - * - * PARAMETERS - * thread - * reference to an instance of pthread_t - * - * - * DESCRIPTION - * This function requests cancellation of 'thread'. - * NOTE: cancellation is asynchronous; use pthread_join to - * wait for termination of 'thread' if necessary. - * - * RESULTS - * 0 successfully requested cancellation, - * ESRCH no thread found corresponding to 'thread', - * ENOMEM implicit self thread create failed. - * ------------------------------------------------------ - */ -{ - int result; - int cancel_self; - pthread_t self; - ptw32_thread_t * tp; - - result = pthread_kill (thread, 0); - - if (0 != result) - { - return result; - } - - if ((self = pthread_self ()).p == NULL) - { - return ENOMEM; - }; - - /* - * For self cancellation we need to ensure that a thread can't - * deadlock itself trying to cancel itself asynchronously - * (pthread_cancel is required to be an async-cancel - * safe function). - */ - cancel_self = pthread_equal (thread, self); - - tp = (ptw32_thread_t *) thread.p; - - /* - * Lock for async-cancel safety. - */ - (void) pthread_mutex_lock (&tp->cancelLock); - - if (tp->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS - && tp->cancelState == PTHREAD_CANCEL_ENABLE - && tp->state < PThreadStateCanceling) - { - if (cancel_self) - { - tp->state = PThreadStateCanceling; - tp->cancelState = PTHREAD_CANCEL_DISABLE; - - (void) pthread_mutex_unlock (&tp->cancelLock); - ptw32_throw (PTW32_EPS_CANCEL); - - /* Never reached */ - } - else - { - HANDLE threadH = tp->threadH; - - SuspendThread (threadH); - - if (WaitForSingleObject (threadH, 0) == WAIT_TIMEOUT) - { - tp->state = PThreadStateCanceling; - tp->cancelState = PTHREAD_CANCEL_DISABLE; - /* - * If alertdrv and QueueUserAPCEx is available then the following - * will result in a call to QueueUserAPCEx with the args given, otherwise - * this will result in a call to ptw32_RegisterCancelation and only - * the threadH arg will be used. - */ - ptw32_register_cancelation (ptw32_cancel_callback, threadH, 0); - (void) pthread_mutex_unlock (&tp->cancelLock); - ResumeThread (threadH); - } - } - } - else - { - /* - * Set for deferred cancellation. - */ - if (tp->state < PThreadStateCancelPending) - { - tp->state = PThreadStateCancelPending; - if (!SetEvent (tp->cancelEvent)) - { - result = ESRCH; - } - } - else if (tp->state >= PThreadStateCanceling) - { - result = ESRCH; - } - - (void) pthread_mutex_unlock (&tp->cancelLock); - } - - return (result); -} +/* + * pthread_cancel.c + * + * Description: + * POSIX thread functions related to thread cancellation. + * + * -------------------------------------------------------------------------- + * + * 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" +#include "context.h" + +static void +ptw32_cancel_self (void) +{ + ptw32_throw (PTW32_EPS_CANCEL); + + /* Never reached */ +} + +static void CALLBACK +ptw32_cancel_callback (ULONG_PTR unused) +{ + ptw32_throw (PTW32_EPS_CANCEL); + + /* Never reached */ +} + +/* + * ptw32_RegisterCancelation() - + * Must have args of same type as QueueUserAPCEx because this function + * is a substitute for QueueUserAPCEx if it's not available. + */ +DWORD +ptw32_RegisterCancelation (PAPCFUNC unused1, HANDLE threadH, DWORD unused2) +{ + CONTEXT context; + + context.ContextFlags = CONTEXT_CONTROL; + GetThreadContext (threadH, &context); + PTW32_PROGCTR (context) = (DWORD_PTR) ptw32_cancel_self; + SetThreadContext (threadH, &context); + return 0; +} + +int +pthread_cancel (pthread_t thread) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function requests cancellation of 'thread'. + * + * PARAMETERS + * thread + * reference to an instance of pthread_t + * + * + * DESCRIPTION + * This function requests cancellation of 'thread'. + * NOTE: cancellation is asynchronous; use pthread_join to + * wait for termination of 'thread' if necessary. + * + * RESULTS + * 0 successfully requested cancellation, + * ESRCH no thread found corresponding to 'thread', + * ENOMEM implicit self thread create failed. + * ------------------------------------------------------ + */ +{ + int result; + int cancel_self; + pthread_t self; + ptw32_thread_t * tp; + ptw32_mcs_local_node_t stateLock; + + result = pthread_kill (thread, 0); + + if (0 != result) + { + return result; + } + + if ((self = pthread_self ()).p == NULL) + { + return ENOMEM; + }; + + /* + * For self cancellation we need to ensure that a thread can't + * deadlock itself trying to cancel itself asynchronously + * (pthread_cancel is required to be an async-cancel + * safe function). + */ + cancel_self = pthread_equal (thread, self); + + tp = (ptw32_thread_t *) thread.p; + + /* + * Lock for async-cancel safety. + */ + ptw32_mcs_lock_acquire (&tp->stateLock, &stateLock); + + if (tp->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS + && tp->cancelState == PTHREAD_CANCEL_ENABLE + && tp->state < PThreadStateCanceling) + { + if (cancel_self) + { + tp->state = PThreadStateCanceling; + tp->cancelState = PTHREAD_CANCEL_DISABLE; + + ptw32_mcs_lock_release (&stateLock); + ptw32_throw (PTW32_EPS_CANCEL); + + /* Never reached */ + } + else + { + HANDLE threadH = tp->threadH; + + SuspendThread (threadH); + + if (WaitForSingleObject (threadH, 0) == WAIT_TIMEOUT) + { + tp->state = PThreadStateCanceling; + tp->cancelState = PTHREAD_CANCEL_DISABLE; + /* + * If alertdrv and QueueUserAPCEx is available then the following + * will result in a call to QueueUserAPCEx with the args given, otherwise + * this will result in a call to ptw32_RegisterCancelation and only + * the threadH arg will be used. + */ + ptw32_register_cancelation ((PAPCFUNC)ptw32_cancel_callback, threadH, 0); + ptw32_mcs_lock_release (&stateLock); + ResumeThread (threadH); + } + } + } + else + { + /* + * Set for deferred cancellation. + */ + if (tp->state < PThreadStateCancelPending) + { + tp->state = PThreadStateCancelPending; + if (!SetEvent (tp->cancelEvent)) + { + result = ESRCH; + } + } + else if (tp->state >= PThreadStateCanceling) + { + result = ESRCH; + } + + ptw32_mcs_lock_release (&stateLock); + } + + return (result); +} diff --git a/pthreads/pthread_cond_destroy.c b/pthreads/pthread_cond_destroy.c index 34550f08d..40d4a0896 100644 --- a/pthreads/pthread_cond_destroy.c +++ b/pthreads/pthread_cond_destroy.c @@ -1,251 +1,253 @@ -/* - * pthread_cond_destroy.c - * - * Description: - * This translation unit implements condition variables and their 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" - -int -pthread_cond_destroy (pthread_cond_t * cond) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function destroys a condition variable - * - * - * PARAMETERS - * cond - * pointer to an instance of pthread_cond_t - * - * - * DESCRIPTION - * This function destroys a condition variable. - * - * NOTES: - * 1) A condition variable can be destroyed - * immediately after all the threads that - * are blocked on it are awakened. e.g. - * - * struct list { - * pthread_mutex_t lm; - * ... - * } - * - * struct elt { - * key k; - * int busy; - * pthread_cond_t notbusy; - * ... - * } - * - * - * struct elt * - * list_find(struct list *lp, key k) - * { - * struct elt *ep; - * - * pthread_mutex_lock(&lp->lm); - * while ((ep = find_elt(l,k) != NULL) && ep->busy) - * pthread_cond_wait(&ep->notbusy, &lp->lm); - * if (ep != NULL) - * ep->busy = 1; - * pthread_mutex_unlock(&lp->lm); - * return(ep); - * } - * - * delete_elt(struct list *lp, struct elt *ep) - * { - * pthread_mutex_lock(&lp->lm); - * assert(ep->busy); - * ... remove ep from list ... - * ep->busy = 0; - * (A) pthread_cond_broadcast(&ep->notbusy); - * pthread_mutex_unlock(&lp->lm); - * (B) pthread_cond_destroy(&rp->notbusy); - * free(ep); - * } - * - * In this example, the condition variable - * and its list element may be freed (line B) - * immediately after all threads waiting for - * it are awakened (line A), since the mutex - * and the code ensure that no other thread - * can touch the element to be deleted. - * - * RESULTS - * 0 successfully released condition variable, - * EINVAL 'cond' is invalid, - * EBUSY 'cond' is in use, - * - * ------------------------------------------------------ - */ -{ - pthread_cond_t cv; - int result = 0, result1 = 0, result2 = 0; - - /* - * Assuming any race condition here is harmless. - */ - if (cond == NULL || *cond == NULL) - { - return EINVAL; - } - - if (*cond != PTHREAD_COND_INITIALIZER) - { - EnterCriticalSection (&ptw32_cond_list_lock); - - cv = *cond; - - /* - * Close the gate; this will synchronize this thread with - * all already signaled waiters to let them retract their - * waiter status - SEE NOTE 1 ABOVE!!! - */ - if (ptw32_semwait (&(cv->semBlockLock)) != 0) /* Non-cancelable */ - { - result = errno; - } - else - { - /* - * !TRY! lock mtxUnblockLock; try will detect busy condition - * and will not cause a deadlock with respect to concurrent - * signal/broadcast. - */ - if ((result = pthread_mutex_trylock (&(cv->mtxUnblockLock))) != 0) - { - (void) sem_post (&(cv->semBlockLock)); - } - } - - if (result != 0) - { - LeaveCriticalSection (&ptw32_cond_list_lock); - return result; - } - - /* - * Check whether cv is still busy (still has waiters) - */ - if (cv->nWaitersBlocked > cv->nWaitersGone) - { - if (sem_post (&(cv->semBlockLock)) != 0) - { - result = errno; - } - result1 = pthread_mutex_unlock (&(cv->mtxUnblockLock)); - result2 = EBUSY; - } - else - { - /* - * Now it is safe to destroy - */ - *cond = NULL; - - if (sem_destroy (&(cv->semBlockLock)) != 0) - { - result = errno; - } - if (sem_destroy (&(cv->semBlockQueue)) != 0) - { - result1 = errno; - } - if ((result2 = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0) - { - result2 = pthread_mutex_destroy (&(cv->mtxUnblockLock)); - } - - /* Unlink the CV from the list */ - - if (ptw32_cond_list_head == cv) - { - ptw32_cond_list_head = cv->next; - } - else - { - cv->prev->next = cv->next; - } - - if (ptw32_cond_list_tail == cv) - { - ptw32_cond_list_tail = cv->prev; - } - else - { - cv->next->prev = cv->prev; - } - - (void) free (cv); - } - - LeaveCriticalSection (&ptw32_cond_list_lock); - } - else - { - /* - * See notes in ptw32_cond_check_need_init() above also. - */ - EnterCriticalSection (&ptw32_cond_test_init_lock); - - /* - * Check again. - */ - if (*cond == PTHREAD_COND_INITIALIZER) - { - /* - * This is all we need to do to destroy a statically - * initialised cond that has not yet been used (initialised). - * If we get to here, another thread waiting to initialise - * this cond will get an EINVAL. That's OK. - */ - *cond = NULL; - } - else - { - /* - * The cv has been initialised while we were waiting - * so assume it's in use. - */ - result = EBUSY; - } - - LeaveCriticalSection (&ptw32_cond_test_init_lock); - } - - return ((result != 0) ? result : ((result1 != 0) ? result1 : result2)); -} +/* + * pthread_cond_destroy.c + * + * Description: + * This translation unit implements condition variables and their 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" + +int +pthread_cond_destroy (pthread_cond_t * cond) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function destroys a condition variable + * + * + * PARAMETERS + * cond + * pointer to an instance of pthread_cond_t + * + * + * DESCRIPTION + * This function destroys a condition variable. + * + * NOTES: + * 1) A condition variable can be destroyed + * immediately after all the threads that + * are blocked on it are awakened. e.g. + * + * struct list { + * pthread_mutex_t lm; + * ... + * } + * + * struct elt { + * key k; + * int busy; + * pthread_cond_t notbusy; + * ... + * } + * + * + * struct elt * + * list_find(struct list *lp, key k) + * { + * struct elt *ep; + * + * pthread_mutex_lock(&lp->lm); + * while ((ep = find_elt(l,k) != NULL) && ep->busy) + * pthread_cond_wait(&ep->notbusy, &lp->lm); + * if (ep != NULL) + * ep->busy = 1; + * pthread_mutex_unlock(&lp->lm); + * return(ep); + * } + * + * delete_elt(struct list *lp, struct elt *ep) + * { + * pthread_mutex_lock(&lp->lm); + * assert(ep->busy); + * ... remove ep from list ... + * ep->busy = 0; + * (A) pthread_cond_broadcast(&ep->notbusy); + * pthread_mutex_unlock(&lp->lm); + * (B) pthread_cond_destroy(&rp->notbusy); + * free(ep); + * } + * + * In this example, the condition variable + * and its list element may be freed (line B) + * immediately after all threads waiting for + * it are awakened (line A), since the mutex + * and the code ensure that no other thread + * can touch the element to be deleted. + * + * RESULTS + * 0 successfully released condition variable, + * EINVAL 'cond' is invalid, + * EBUSY 'cond' is in use, + * + * ------------------------------------------------------ + */ +{ + pthread_cond_t cv; + int result = 0, result1 = 0, result2 = 0; + + /* + * Assuming any race condition here is harmless. + */ + if (cond == NULL || *cond == NULL) + { + return EINVAL; + } + + if (*cond != PTHREAD_COND_INITIALIZER) + { + ptw32_mcs_local_node_t node; + ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node); + + cv = *cond; + + /* + * Close the gate; this will synchronize this thread with + * all already signaled waiters to let them retract their + * waiter status - SEE NOTE 1 ABOVE!!! + */ + if (ptw32_semwait (&(cv->semBlockLock)) != 0) /* Non-cancelable */ + { + result = errno; + } + else + { + /* + * !TRY! lock mtxUnblockLock; try will detect busy condition + * and will not cause a deadlock with respect to concurrent + * signal/broadcast. + */ + if ((result = pthread_mutex_trylock (&(cv->mtxUnblockLock))) != 0) + { + (void) sem_post (&(cv->semBlockLock)); + } + } + + if (result != 0) + { + ptw32_mcs_lock_release(&node); + return result; + } + + /* + * Check whether cv is still busy (still has waiters) + */ + if (cv->nWaitersBlocked > cv->nWaitersGone) + { + if (sem_post (&(cv->semBlockLock)) != 0) + { + result = errno; + } + result1 = pthread_mutex_unlock (&(cv->mtxUnblockLock)); + result2 = EBUSY; + } + else + { + /* + * Now it is safe to destroy + */ + *cond = NULL; + + if (sem_destroy (&(cv->semBlockLock)) != 0) + { + result = errno; + } + if (sem_destroy (&(cv->semBlockQueue)) != 0) + { + result1 = errno; + } + if ((result2 = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0) + { + result2 = pthread_mutex_destroy (&(cv->mtxUnblockLock)); + } + + /* Unlink the CV from the list */ + + if (ptw32_cond_list_head == cv) + { + ptw32_cond_list_head = cv->next; + } + else + { + cv->prev->next = cv->next; + } + + if (ptw32_cond_list_tail == cv) + { + ptw32_cond_list_tail = cv->prev; + } + else + { + cv->next->prev = cv->prev; + } + + (void) free (cv); + } + + ptw32_mcs_lock_release(&node); + } + else + { + ptw32_mcs_local_node_t node; + /* + * See notes in ptw32_cond_check_need_init() above also. + */ + ptw32_mcs_lock_acquire(&ptw32_cond_test_init_lock, &node); + + /* + * Check again. + */ + if (*cond == PTHREAD_COND_INITIALIZER) + { + /* + * This is all we need to do to destroy a statically + * initialised cond that has not yet been used (initialised). + * If we get to here, another thread waiting to initialise + * this cond will get an EINVAL. That's OK. + */ + *cond = NULL; + } + else + { + /* + * The cv has been initialised while we were waiting + * so assume it's in use. + */ + result = EBUSY; + } + + ptw32_mcs_lock_release(&node); + } + + return ((result != 0) ? result : ((result1 != 0) ? result1 : result2)); +} diff --git a/pthreads/pthread_cond_init.c b/pthreads/pthread_cond_init.c index d2de232f4..f28fd67b4 100644 --- a/pthreads/pthread_cond_init.c +++ b/pthreads/pthread_cond_init.c @@ -138,7 +138,9 @@ FAIL0: DONE: if (0 == result) { - EnterCriticalSection (&ptw32_cond_list_lock); + ptw32_mcs_local_node_t node; + + ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node); cv->next = NULL; cv->prev = ptw32_cond_list_tail; @@ -155,7 +157,7 @@ DONE: ptw32_cond_list_head = cv; } - LeaveCriticalSection (&ptw32_cond_list_lock); + ptw32_mcs_lock_release(&node); } *cond = cv; diff --git a/pthreads/pthread_cond_wait.c b/pthreads/pthread_cond_wait.c index 5511c5844..359219ae9 100644 --- a/pthreads/pthread_cond_wait.c +++ b/pthreads/pthread_cond_wait.c @@ -401,7 +401,7 @@ ptw32_cond_timedwait (pthread_cond_t * cond, cleanup_args.cv = cv; cleanup_args.resultPtr = &result; -#ifdef _MSC_VER +#if defined(_MSC_VER) && _MSC_VER < 1400 #pragma inline_depth(0) #endif pthread_cleanup_push (ptw32_cond_wait_cleanup, (void *) &cleanup_args); @@ -438,7 +438,7 @@ ptw32_cond_timedwait (pthread_cond_t * cond, * Always cleanup */ pthread_cleanup_pop (1); -#ifdef _MSC_VER +#if defined(_MSC_VER) && _MSC_VER < 1400 #pragma inline_depth() #endif diff --git a/pthreads/pthread_delay_np.c b/pthreads/pthread_delay_np.c index 7fe9ae016..e6c96d807 100644 --- a/pthreads/pthread_delay_np.c +++ b/pthreads/pthread_delay_np.c @@ -102,7 +102,7 @@ pthread_delay_np (struct timespec *interval) } /* convert secs to millisecs */ - secs_in_millisecs = interval->tv_sec * 1000L; + secs_in_millisecs = (DWORD)interval->tv_sec * 1000L; /* convert nanosecs to millisecs (rounding up) */ millisecs = (interval->tv_nsec + 999999L) / 1000000L; @@ -141,20 +141,21 @@ pthread_delay_np (struct timespec *interval) if (WAIT_OBJECT_0 == (status = WaitForSingleObject (sp->cancelEvent, wait_time))) { + ptw32_mcs_local_node_t stateLock; /* * Canceling! */ - (void) pthread_mutex_lock (&sp->cancelLock); + ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock); if (sp->state < PThreadStateCanceling) { sp->state = PThreadStateCanceling; sp->cancelState = PTHREAD_CANCEL_DISABLE; - (void) pthread_mutex_unlock (&sp->cancelLock); + ptw32_mcs_lock_release (&stateLock); ptw32_throw (PTW32_EPS_CANCEL); } - (void) pthread_mutex_unlock (&sp->cancelLock); + ptw32_mcs_lock_release (&stateLock); return ESRCH; } else if (status != WAIT_TIMEOUT) diff --git a/pthreads/pthread_detach.c b/pthreads/pthread_detach.c index a3c3ef973..9ff6587f3 100644 --- a/pthreads/pthread_detach.c +++ b/pthreads/pthread_detach.c @@ -1,141 +1,136 @@ -/* - * pthread_detach.c - * - * Description: - * This translation unit implements functions related to thread - * synchronisation. - * - * -------------------------------------------------------------------------- - * - * 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" - -/* - * Not needed yet, but defining it should indicate clashes with build target - * environment that should be fixed. - */ -#ifndef WINCE -# include -#endif - - -int -pthread_detach (pthread_t thread) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function detaches the given thread. - * - * PARAMETERS - * thread - * an instance of a pthread_t - * - * - * DESCRIPTION - * This function detaches the given thread. You may use it to - * detach the main thread or to detach a joinable thread. - * NOTE: detached threads cannot be joined; - * storage is freed immediately on termination. - * - * RESULTS - * 0 successfully detached the thread, - * EINVAL thread is not a joinable thread, - * ENOSPC a required resource has been exhausted, - * ESRCH no thread could be found for 'thread', - * - * ------------------------------------------------------ - */ -{ - int result; - BOOL destroyIt = PTW32_FALSE; - ptw32_thread_t * tp = (ptw32_thread_t *) thread.p; - - EnterCriticalSection (&ptw32_thread_reuse_lock); - - if (NULL == tp - || thread.x != tp->ptHandle.x) - { - result = ESRCH; - } - else if (PTHREAD_CREATE_DETACHED == tp->detachState) - { - result = EINVAL; - } - else - { - /* - * Joinable ptw32_thread_t structs are not scavenged until - * a join or detach is done. The thread may have exited already, - * but all of the state and locks etc are still there. - */ - result = 0; - - if (pthread_mutex_lock (&tp->cancelLock) == 0) - { - if (tp->state != PThreadStateLast) - { - tp->detachState = PTHREAD_CREATE_DETACHED; - } - else if (tp->detachState != PTHREAD_CREATE_DETACHED) - { - /* - * Thread is joinable and has exited or is exiting. - */ - destroyIt = PTW32_TRUE; - } - (void) pthread_mutex_unlock (&tp->cancelLock); - } - else - { - /* cancelLock shouldn't fail, but if it does ... */ - result = ESRCH; - } - } - - LeaveCriticalSection (&ptw32_thread_reuse_lock); - - if (result == 0) - { - /* Thread is joinable */ - - if (destroyIt) - { - /* The thread has exited or is exiting but has not been joined or - * detached. Need to wait in case it's still exiting. - */ - (void) WaitForSingleObject(tp->threadH, INFINITE); - ptw32_threadDestroy (thread); - } - } - - return (result); - -} /* pthread_detach */ +/* + * pthread_detach.c + * + * Description: + * This translation unit implements functions related to thread + * synchronisation. + * + * -------------------------------------------------------------------------- + * + * 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" + +/* + * Not needed yet, but defining it should indicate clashes with build target + * environment that should be fixed. + */ +#if !defined(WINCE) +# include +#endif + + +int +pthread_detach (pthread_t thread) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function detaches the given thread. + * + * PARAMETERS + * thread + * an instance of a pthread_t + * + * + * DESCRIPTION + * This function detaches the given thread. You may use it to + * detach the main thread or to detach a joinable thread. + * NOTE: detached threads cannot be joined; + * storage is freed immediately on termination. + * + * RESULTS + * 0 successfully detached the thread, + * EINVAL thread is not a joinable thread, + * ENOSPC a required resource has been exhausted, + * ESRCH no thread could be found for 'thread', + * + * ------------------------------------------------------ + */ +{ + int result; + BOOL destroyIt = PTW32_FALSE; + ptw32_thread_t * tp = (ptw32_thread_t *) thread.p; + ptw32_mcs_local_node_t node; + + ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node); + + if (NULL == tp + || thread.x != tp->ptHandle.x) + { + result = ESRCH; + } + else if (PTHREAD_CREATE_DETACHED == tp->detachState) + { + result = EINVAL; + } + else + { + ptw32_mcs_local_node_t stateLock; + /* + * Joinable ptw32_thread_t structs are not scavenged until + * a join or detach is done. The thread may have exited already, + * but all of the state and locks etc are still there. + */ + result = 0; + + ptw32_mcs_lock_acquire (&tp->stateLock, &stateLock); + if (tp->state != PThreadStateLast) + { + tp->detachState = PTHREAD_CREATE_DETACHED; + } + else if (tp->detachState != PTHREAD_CREATE_DETACHED) + { + /* + * Thread is joinable and has exited or is exiting. + */ + destroyIt = PTW32_TRUE; + } + ptw32_mcs_lock_release (&stateLock); + } + + ptw32_mcs_lock_release(&node); + + if (result == 0) + { + /* Thread is joinable */ + + if (destroyIt) + { + /* The thread has exited or is exiting but has not been joined or + * detached. Need to wait in case it's still exiting. + */ + (void) WaitForSingleObject(tp->threadH, INFINITE); + ptw32_threadDestroy (thread); + } + } + + return (result); + +} /* pthread_detach */ diff --git a/pthreads/pthread_equal.c b/pthreads/pthread_equal.c index f96372edb..5ddd82acb 100644 --- a/pthreads/pthread_equal.c +++ b/pthreads/pthread_equal.c @@ -44,7 +44,7 @@ pthread_equal (pthread_t t1, pthread_t t2) * ------------------------------------------------------ * DOCPUBLIC * This function returns nonzero if t1 and t2 are equal, else - * returns nonzero + * returns zero * * PARAMETERS * t1, diff --git a/pthreads/pthread_exit.c b/pthreads/pthread_exit.c index 284cdb20a..37b3c0990 100644 --- a/pthreads/pthread_exit.c +++ b/pthreads/pthread_exit.c @@ -1,106 +1,106 @@ -/* - * pthread_exit.c - * - * Description: - * This translation unit implements routines associated with exiting from - * a thread. - * - * -------------------------------------------------------------------------- - * - * 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" -#ifndef _UWIN -/*# include */ -#endif - -void -pthread_exit (void *value_ptr) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function terminates the calling thread, returning - * the value 'value_ptr' to any joining thread. - * - * PARAMETERS - * value_ptr - * a generic data value (i.e. not the address of a value) - * - * - * DESCRIPTION - * This function terminates the calling thread, returning - * the value 'value_ptr' to any joining thread. - * NOTE: thread should be joinable. - * - * RESULTS - * N/A - * - * ------------------------------------------------------ - */ -{ - ptw32_thread_t * sp; - - /* - * Don't use pthread_self() to avoid creating an implicit POSIX thread handle - * unnecessarily. - */ - sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); - -#ifdef _UWIN - if (--pthread_count <= 0) - exit ((int) value_ptr); -#endif - - if (NULL == sp) - { - /* - * A POSIX thread handle was never created. I.e. this is a - * Win32 thread that has never called a pthreads-win32 routine that - * required a POSIX handle. - * - * Implicit POSIX handles are cleaned up in ptw32_throw() now. - */ - -#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) - _endthreadex ((unsigned) value_ptr); -#else - _endthread (); -#endif - - /* Never reached */ - } - - sp->exitStatus = value_ptr; - - ptw32_throw (PTW32_EPS_EXIT); - - /* Never reached. */ - -} +/* + * pthread_exit.c + * + * Description: + * This translation unit implements routines associated with exiting from + * a thread. + * + * -------------------------------------------------------------------------- + * + * 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" +#if !defined(_UWIN) +/*# include */ +#endif + +void +pthread_exit (void *value_ptr) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function terminates the calling thread, returning + * the value 'value_ptr' to any joining thread. + * + * PARAMETERS + * value_ptr + * a generic data value (i.e. not the address of a value) + * + * + * DESCRIPTION + * This function terminates the calling thread, returning + * the value 'value_ptr' to any joining thread. + * NOTE: thread should be joinable. + * + * RESULTS + * N/A + * + * ------------------------------------------------------ + */ +{ + ptw32_thread_t * sp; + + /* + * Don't use pthread_self() to avoid creating an implicit POSIX thread handle + * unnecessarily. + */ + sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); + +#if defined(_UWIN) + if (--pthread_count <= 0) + exit ((int) value_ptr); +#endif + + if (NULL == sp) + { + /* + * A POSIX thread handle was never created. I.e. this is a + * Win32 thread that has never called a pthreads-win32 routine that + * required a POSIX handle. + * + * Implicit POSIX handles are cleaned up in ptw32_throw() now. + */ + +#if ! (defined (__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) + _endthreadex ((unsigned) (size_t) value_ptr); +#else + _endthread (); +#endif + + /* Never reached */ + } + + sp->exitStatus = value_ptr; + + ptw32_throw (PTW32_EPS_EXIT); + + /* Never reached. */ + +} diff --git a/pthreads/pthread_getunique_np.c b/pthreads/pthread_getunique_np.c new file mode 100644 index 000000000..4496c68bf --- /dev/null +++ b/pthreads/pthread_getunique_np.c @@ -0,0 +1,47 @@ +/* + * pthread_getunique_np.c + * + * Description: + * This translation unit implements non-portable 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 + */ + +#include "pthread.h" +#include "implement.h" + +/* + * + */ +unsigned __int64 +pthread_getunique_np (pthread_t thread) +{ + return ((ptw32_thread_t*)thread.p)->seqNumber; +} diff --git a/pthreads/pthread_join.c b/pthreads/pthread_join.c index 6dd394d1b..c2b7c1e75 100644 --- a/pthreads/pthread_join.c +++ b/pthreads/pthread_join.c @@ -1,156 +1,157 @@ -/* - * pthread_join.c - * - * Description: - * This translation unit implements functions related to thread - * synchronisation. - * - * -------------------------------------------------------------------------- - * - * 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" - -/* - * Not needed yet, but defining it should indicate clashes with build target - * environment that should be fixed. - */ -#ifndef WINCE -# include -#endif - - -int -pthread_join (pthread_t thread, void **value_ptr) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function waits for 'thread' to terminate and - * returns the thread's exit value if 'value_ptr' is not - * NULL. This also detaches the thread on successful - * completion. - * - * PARAMETERS - * thread - * an instance of pthread_t - * - * value_ptr - * pointer to an instance of pointer to void - * - * - * DESCRIPTION - * This function waits for 'thread' to terminate and - * returns the thread's exit value if 'value_ptr' is not - * NULL. This also detaches the thread on successful - * completion. - * NOTE: detached threads cannot be joined or canceled - * - * RESULTS - * 0 'thread' has completed - * EINVAL thread is not a joinable thread, - * ESRCH no thread could be found with ID 'thread', - * ENOENT thread couldn't find it's own valid handle, - * EDEADLK attempt to join thread with self - * - * ------------------------------------------------------ - */ -{ - int result; - pthread_t self; - ptw32_thread_t * tp = (ptw32_thread_t *) thread.p; - - EnterCriticalSection (&ptw32_thread_reuse_lock); - - if (NULL == tp - || thread.x != tp->ptHandle.x) - { - result = ESRCH; - } - else if (PTHREAD_CREATE_DETACHED == tp->detachState) - { - result = EINVAL; - } - else - { - result = 0; - } - - LeaveCriticalSection (&ptw32_thread_reuse_lock); - - if (result == 0) - { - /* - * The target thread is joinable and can't be reused before we join it. - */ - self = pthread_self(); - - if (NULL == self.p) - { - result = ENOENT; - } - else if (pthread_equal (self, thread)) - { - result = EDEADLK; - } - else - { - /* - * Pthread_join is a cancelation point. - * If we are canceled then our target thread must not be - * detached (destroyed). This is guarranteed because - * pthreadCancelableWait will not return if we - * are canceled. - */ - result = pthreadCancelableWait (tp->threadH); - - if (0 == result) - { - if (value_ptr != NULL) - { - *value_ptr = tp->exitStatus; - } - - /* - * The result of making multiple simultaneous calls to - * pthread_join() or pthread_detach() specifying the same - * target is undefined. - */ - result = pthread_detach (thread); - } - else - { - result = ESRCH; - } - } - } - - return (result); - -} /* pthread_join */ +/* + * pthread_join.c + * + * Description: + * This translation unit implements functions related to thread + * synchronisation. + * + * -------------------------------------------------------------------------- + * + * 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" + +/* + * Not needed yet, but defining it should indicate clashes with build target + * environment that should be fixed. + */ +#if !defined(WINCE) +# include +#endif + + +int +pthread_join (pthread_t thread, void **value_ptr) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function waits for 'thread' to terminate and + * returns the thread's exit value if 'value_ptr' is not + * NULL. This also detaches the thread on successful + * completion. + * + * PARAMETERS + * thread + * an instance of pthread_t + * + * value_ptr + * pointer to an instance of pointer to void + * + * + * DESCRIPTION + * This function waits for 'thread' to terminate and + * returns the thread's exit value if 'value_ptr' is not + * NULL. This also detaches the thread on successful + * completion. + * NOTE: detached threads cannot be joined or canceled + * + * RESULTS + * 0 'thread' has completed + * EINVAL thread is not a joinable thread, + * ESRCH no thread could be found with ID 'thread', + * ENOENT thread couldn't find it's own valid handle, + * EDEADLK attempt to join thread with self + * + * ------------------------------------------------------ + */ +{ + int result; + pthread_t self; + ptw32_thread_t * tp = (ptw32_thread_t *) thread.p; + ptw32_mcs_local_node_t node; + + ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node); + + if (NULL == tp + || thread.x != tp->ptHandle.x) + { + result = ESRCH; + } + else if (PTHREAD_CREATE_DETACHED == tp->detachState) + { + result = EINVAL; + } + else + { + result = 0; + } + + ptw32_mcs_lock_release(&node); + + if (result == 0) + { + /* + * The target thread is joinable and can't be reused before we join it. + */ + self = pthread_self(); + + if (NULL == self.p) + { + result = ENOENT; + } + else if (pthread_equal (self, thread)) + { + result = EDEADLK; + } + else + { + /* + * Pthread_join is a cancelation point. + * If we are canceled then our target thread must not be + * detached (destroyed). This is guarranteed because + * pthreadCancelableWait will not return if we + * are canceled. + */ + result = pthreadCancelableWait (tp->threadH); + + if (0 == result) + { + if (value_ptr != NULL) + { + *value_ptr = tp->exitStatus; + } + + /* + * The result of making multiple simultaneous calls to + * pthread_join() or pthread_detach() specifying the same + * target is undefined. + */ + result = pthread_detach (thread); + } + else + { + result = ESRCH; + } + } + } + + return (result); + +} /* pthread_join */ diff --git a/pthreads/pthread_key_create.c b/pthreads/pthread_key_create.c index 9ffa03010..bdeee09b3 100644 --- a/pthreads/pthread_key_create.c +++ b/pthreads/pthread_key_create.c @@ -1,108 +1,108 @@ -/* - * pthread_key_create.c - * - * Description: - * POSIX thread functions which implement thread-specific data (TSD). - * - * -------------------------------------------------------------------------- - * - * 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" - - -/* TLS_OUT_OF_INDEXES not defined on WinCE */ -#ifndef TLS_OUT_OF_INDEXES -#define TLS_OUT_OF_INDEXES 0xffffffff -#endif - -int -pthread_key_create (pthread_key_t * key, void (*destructor) (void *)) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function creates a thread-specific data key visible - * to all threads. All existing and new threads have a value - * NULL for key until set using pthread_setspecific. When any - * thread with a non-NULL value for key terminates, 'destructor' - * is called with key's current value for that thread. - * - * PARAMETERS - * key - * pointer to an instance of pthread_key_t - * - * - * DESCRIPTION - * This function creates a thread-specific data key visible - * to all threads. All existing and new threads have a value - * NULL for key until set using pthread_setspecific. When any - * thread with a non-NULL value for key terminates, 'destructor' - * is called with key's current value for that thread. - * - * RESULTS - * 0 successfully created semaphore, - * EAGAIN insufficient resources or PTHREAD_KEYS_MAX - * exceeded, - * ENOMEM insufficient memory to create the key, - * - * ------------------------------------------------------ - */ -{ - int result = 0; - pthread_key_t newkey; - - if ((newkey = (pthread_key_t) calloc (1, sizeof (*newkey))) == NULL) - { - result = ENOMEM; - } - else if ((newkey->key = TlsAlloc ()) == TLS_OUT_OF_INDEXES) - { - result = EAGAIN; - - free (newkey); - newkey = NULL; - } - else if (destructor != NULL) - { - /* - * Have to manage associations between thread and key; - * Therefore, need a lock that allows competing threads - * to gain exclusive access to the key->threads list. - * - * The mutex will only be created when it is first locked. - */ - newkey->keyLock = PTHREAD_MUTEX_INITIALIZER; - newkey->destructor = destructor; - } - - *key = newkey; - - return (result); -} +/* + * pthread_key_create.c + * + * Description: + * POSIX thread functions which implement thread-specific data (TSD). + * + * -------------------------------------------------------------------------- + * + * 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" + + +/* TLS_OUT_OF_INDEXES not defined on WinCE */ +#if !defined(TLS_OUT_OF_INDEXES) +#define TLS_OUT_OF_INDEXES 0xffffffff +#endif + +int +pthread_key_create (pthread_key_t * key, void (*destructor) (void *)) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function creates a thread-specific data key visible + * to all threads. All existing and new threads have a value + * NULL for key until set using pthread_setspecific. When any + * thread with a non-NULL value for key terminates, 'destructor' + * is called with key's current value for that thread. + * + * PARAMETERS + * key + * pointer to an instance of pthread_key_t + * + * + * DESCRIPTION + * This function creates a thread-specific data key visible + * to all threads. All existing and new threads have a value + * NULL for key until set using pthread_setspecific. When any + * thread with a non-NULL value for key terminates, 'destructor' + * is called with key's current value for that thread. + * + * RESULTS + * 0 successfully created semaphore, + * EAGAIN insufficient resources or PTHREAD_KEYS_MAX + * exceeded, + * ENOMEM insufficient memory to create the key, + * + * ------------------------------------------------------ + */ +{ + int result = 0; + pthread_key_t newkey; + + if ((newkey = (pthread_key_t) calloc (1, sizeof (*newkey))) == NULL) + { + result = ENOMEM; + } + else if ((newkey->key = TlsAlloc ()) == TLS_OUT_OF_INDEXES) + { + result = EAGAIN; + + free (newkey); + newkey = NULL; + } + else if (destructor != NULL) + { + /* + * Have to manage associations between thread and key; + * Therefore, need a lock that allows competing threads + * to gain exclusive access to the key->threads list. + * + * The mutex will only be created when it is first locked. + */ + newkey->keyLock = 0; + newkey->destructor = destructor; + } + + *key = newkey; + + return (result); +} diff --git a/pthreads/pthread_key_delete.c b/pthreads/pthread_key_delete.c index a92b6465f..09d70c63f 100644 --- a/pthreads/pthread_key_delete.c +++ b/pthreads/pthread_key_delete.c @@ -1,133 +1,125 @@ -/* - * pthread_key_delete.c - * - * Description: - * POSIX thread functions which implement thread-specific data (TSD). - * - * -------------------------------------------------------------------------- - * - * 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" - - -int -pthread_key_delete (pthread_key_t key) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function deletes a thread-specific data key. This - * does not change the value of the thread specific data key - * for any thread and does not run the key's destructor - * in any thread so it should be used with caution. - * - * PARAMETERS - * key - * pointer to an instance of pthread_key_t - * - * - * DESCRIPTION - * This function deletes a thread-specific data key. This - * does not change the value of the thread specific data key - * for any thread and does not run the key's destructor - * in any thread so it should be used with caution. - * - * RESULTS - * 0 successfully deleted the key, - * EINVAL key is invalid, - * - * ------------------------------------------------------ - */ -{ - int result = 0; - - if (key != NULL) - { - if (key->threads != NULL && - key->destructor != NULL && - pthread_mutex_lock (&(key->keyLock)) == 0) - { - ThreadKeyAssoc *assoc; - /* - * Run through all Thread<-->Key associations - * for this key. - * - * While we hold at least one of the locks guarding - * the assoc, we know that the assoc pointed to by - * key->threads is valid. - */ - while ((assoc = (ThreadKeyAssoc *) key->threads) != NULL) - { - ptw32_thread_t * thread = assoc->thread; - - if (assoc == NULL) - { - /* Finished */ - break; - } - - if (pthread_mutex_lock (&(thread->threadLock)) == 0) - { - /* - * Since we are starting at the head of the key's threads - * chain, this will also point key->threads at the next assoc. - * While we hold key->keyLock, no other thread can insert - * a new assoc via pthread_setspecific. - */ - ptw32_tkAssocDestroy (assoc); - (void) pthread_mutex_unlock (&(thread->threadLock)); - } - else - { - /* Thread or lock is no longer valid? */ - ptw32_tkAssocDestroy (assoc); - } - } - pthread_mutex_unlock (&(key->keyLock)); - } - - TlsFree (key->key); - if (key->destructor != NULL) - { - /* A thread could be holding the keyLock */ - while (EBUSY == pthread_mutex_destroy (&(key->keyLock))) - { - Sleep(0); /* Ugly */ - } - } - -#if defined( _DEBUG ) - memset ((char *) key, 0, sizeof (*key)); -#endif - free (key); - } - - return (result); -} +/* + * pthread_key_delete.c + * + * Description: + * POSIX thread functions which implement thread-specific data (TSD). + * + * -------------------------------------------------------------------------- + * + * 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" + + +int +pthread_key_delete (pthread_key_t key) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function deletes a thread-specific data key. This + * does not change the value of the thread specific data key + * for any thread and does not run the key's destructor + * in any thread so it should be used with caution. + * + * PARAMETERS + * key + * pointer to an instance of pthread_key_t + * + * + * DESCRIPTION + * This function deletes a thread-specific data key. This + * does not change the value of the thread specific data key + * for any thread and does not run the key's destructor + * in any thread so it should be used with caution. + * + * RESULTS + * 0 successfully deleted the key, + * EINVAL key is invalid, + * + * ------------------------------------------------------ + */ +{ + ptw32_mcs_local_node_t keyLock; + int result = 0; + + if (key != NULL) + { + if (key->threads != NULL && key->destructor != NULL) + { + ThreadKeyAssoc *assoc; + ptw32_mcs_lock_acquire (&(key->keyLock), &keyLock); + /* + * Run through all Thread<-->Key associations + * for this key. + * + * While we hold at least one of the locks guarding + * the assoc, we know that the assoc pointed to by + * key->threads is valid. + */ + while ((assoc = (ThreadKeyAssoc *) key->threads) != NULL) + { + ptw32_mcs_local_node_t threadLock; + ptw32_thread_t * thread = assoc->thread; + + if (assoc == NULL) + { + /* Finished */ + break; + } + + ptw32_mcs_lock_acquire (&(thread->threadLock), &threadLock); + /* + * Since we are starting at the head of the key's threads + * chain, this will also point key->threads at the next assoc. + * While we hold key->keyLock, no other thread can insert + * a new assoc via pthread_setspecific. + */ + ptw32_tkAssocDestroy (assoc); + ptw32_mcs_lock_release (&threadLock); + ptw32_mcs_lock_release (&keyLock); + } + } + + TlsFree (key->key); + if (key->destructor != NULL) + { + /* A thread could be holding the keyLock */ + ptw32_mcs_lock_acquire (&(key->keyLock), &keyLock); + ptw32_mcs_lock_release (&keyLock); + } + +#if defined( _DEBUG ) + memset ((char *) key, 0, sizeof (*key)); +#endif + free (key); + } + + return (result); +} diff --git a/pthreads/pthread_kill.c b/pthreads/pthread_kill.c index 081ec48f5..5473b43cd 100644 --- a/pthreads/pthread_kill.c +++ b/pthreads/pthread_kill.c @@ -1,104 +1,105 @@ -/* - * pthread_kill.c - * - * Description: - * This translation unit implements the pthread_kill routine. - * - * -------------------------------------------------------------------------- - * - * 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" - -/* - * Not needed yet, but defining it should indicate clashes with build target - * environment that should be fixed. - */ -#ifndef WINCE -# include -#endif - -int -pthread_kill (pthread_t thread, int sig) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function requests that a signal be delivered to the - * specified thread. If sig is zero, error checking is - * performed but no signal is actually sent such that this - * function can be used to check for a valid thread ID. - * - * PARAMETERS - * thread reference to an instances of pthread_t - * sig signal. Currently only a value of 0 is supported. - * - * - * DESCRIPTION - * This function requests that a signal be delivered to the - * specified thread. If sig is zero, error checking is - * performed but no signal is actually sent such that this - * function can be used to check for a valid thread ID. - * - * RESULTS - * ESRCH the thread is not a valid thread ID, - * EINVAL the value of the signal is invalid - * or unsupported. - * 0 the signal was successfully sent. - * - * ------------------------------------------------------ - */ -{ - int result = 0; - ptw32_thread_t * tp; - - EnterCriticalSection (&ptw32_thread_reuse_lock); - - tp = (ptw32_thread_t *) thread.p; - - if (NULL == tp - || thread.x != tp->ptHandle.x - || NULL == tp->threadH) - { - result = ESRCH; - } - - LeaveCriticalSection (&ptw32_thread_reuse_lock); - - if (0 == result && 0 != sig) - { - /* - * Currently does not support any signals. - */ - result = EINVAL; - } - - return result; - -} /* pthread_kill */ +/* + * pthread_kill.c + * + * Description: + * This translation unit implements the pthread_kill routine. + * + * -------------------------------------------------------------------------- + * + * 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" + +/* + * Not needed yet, but defining it should indicate clashes with build target + * environment that should be fixed. + */ +#if !defined(WINCE) +# include +#endif + +int +pthread_kill (pthread_t thread, int sig) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function requests that a signal be delivered to the + * specified thread. If sig is zero, error checking is + * performed but no signal is actually sent such that this + * function can be used to check for a valid thread ID. + * + * PARAMETERS + * thread reference to an instances of pthread_t + * sig signal. Currently only a value of 0 is supported. + * + * + * DESCRIPTION + * This function requests that a signal be delivered to the + * specified thread. If sig is zero, error checking is + * performed but no signal is actually sent such that this + * function can be used to check for a valid thread ID. + * + * RESULTS + * ESRCH the thread is not a valid thread ID, + * EINVAL the value of the signal is invalid + * or unsupported. + * 0 the signal was successfully sent. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + ptw32_thread_t * tp; + ptw32_mcs_local_node_t node; + + ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node); + + tp = (ptw32_thread_t *) thread.p; + + if (NULL == tp + || thread.x != tp->ptHandle.x + || NULL == tp->threadH) + { + result = ESRCH; + } + + ptw32_mcs_lock_release(&node); + + if (0 == result && 0 != sig) + { + /* + * Currently does not support any signals. + */ + result = EINVAL; + } + + return result; + +} /* pthread_kill */ diff --git a/pthreads/pthread_mutex_consistent.c b/pthreads/pthread_mutex_consistent.c new file mode 100644 index 000000000..b7805e7b1 --- /dev/null +++ b/pthreads/pthread_mutex_consistent.c @@ -0,0 +1,190 @@ +/* + * pthread_mutex_consistent.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 + */ + +/* + * From the Sun Multi-threaded Programming Guide + * + * robustness defines the behavior when the owner of the mutex terminates without unlocking the + * mutex, usually because its process terminated abnormally. The value of robustness that is + * defined in pthread.h is PTHREAD_MUTEX_ROBUST or PTHREAD_MUTEX_STALLED. The + * default value is PTHREAD_MUTEX_STALLED . + * ■ PTHREAD_MUTEX_STALLED + * When the owner of the mutex terminates without unlocking the mutex, all subsequent calls + * to pthread_mutex_lock() are blocked from progress in an unspecified manner. + * ■ PTHREAD_MUTEX_ROBUST + * When the owner of the mutex terminates without unlocking the mutex, the mutex is + * unlocked. The next owner of this mutex acquires the mutex with an error return of + * EOWNERDEAD. + * Note – Your application must always check the return code from pthread_mutex_lock() for + * a mutex initialized with the PTHREAD_MUTEX_ROBUST attribute. + * ■ The new owner of this mutex should make the state protected by the mutex consistent. + * This state might have been left inconsistent when the previous owner terminated. + * ■ If the new owner is able to make the state consistent, call + * pthread_mutex_consistent() for the mutex before unlocking the mutex. This + * marks the mutex as consistent and subsequent calls to pthread_mutex_lock() and + * pthread_mutex_unlock() will behave in the normal manner. + * ■ If the new owner is not able to make the state consistent, do not call + * pthread_mutex_consistent() for the mutex, but unlock the mutex. + * All waiters are woken up and all subsequent calls to pthread_mutex_lock() fail to + * acquire the mutex. The return code is ENOTRECOVERABLE. The mutex can be made + * consistent by calling pthread_mutex_destroy() to uninitialize the mutex, and calling + * pthread_mutex_int() to reinitialize the mutex.However, the state that was protected + * by the mutex remains inconsistent and some form of application recovery is required. + * ■ If the thread that acquires the lock with EOWNERDEAD terminates without unlocking the + * mutex, the next owner acquires the lock with an EOWNERDEAD return code. + */ +#if !defined(_UWIN) +/*# include */ +#endif +#include "pthread.h" +#include "implement.h" + +INLINE +int +ptw32_robust_mutex_inherit(pthread_mutex_t * mutex) +{ + int result; + pthread_mutex_t mx = *mutex; + ptw32_robust_node_t* robust = mx->robustNode; + + switch ((LONG)PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR)&robust->stateInconsistent, + (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_INCONSISTENT, + (PTW32_INTERLOCKED_LONG)-1 /* The terminating thread sets this */)) + { + case -1L: + result = EOWNERDEAD; + break; + case (LONG)PTW32_ROBUST_NOTRECOVERABLE: + result = ENOTRECOVERABLE; + break; + default: + result = 0; + break; + } + + return result; +} + +/* + * The next two internal support functions depend on only being + * called by the thread that owns the robust mutex. This enables + * us to avoid additional locks. + * Any mutex currently in the thread's robust mutex list is held + * by the thread, again eliminating the need for locks. + * The forward/backward links allow the thread to unlock mutexes + * in any order, not necessarily the reverse locking order. + * This is all possible because it is an error if a thread that + * does not own the [robust] mutex attempts to unlock it. + */ + +INLINE +void +ptw32_robust_mutex_add(pthread_mutex_t* mutex, pthread_t self) +{ + ptw32_robust_node_t** list; + pthread_mutex_t mx = *mutex; + ptw32_thread_t* tp = (ptw32_thread_t*)self.p; + ptw32_robust_node_t* robust = mx->robustNode; + + list = &tp->robustMxList; + mx->ownerThread = self; + if (NULL == *list) + { + robust->prev = NULL; + robust->next = NULL; + *list = robust; + } + else + { + robust->prev = NULL; + robust->next = *list; + (*list)->prev = robust; + *list = robust; + } +} + +INLINE +void +ptw32_robust_mutex_remove(pthread_mutex_t* mutex, ptw32_thread_t* otp) +{ + ptw32_robust_node_t** list; + pthread_mutex_t mx = *mutex; + ptw32_robust_node_t* robust = mx->robustNode; + + list = &(((ptw32_thread_t*)mx->ownerThread.p)->robustMxList); + mx->ownerThread.p = otp; + if (robust->next != NULL) + { + robust->next->prev = robust->prev; + } + if (robust->prev != NULL) + { + robust->prev->next = robust->next; + } + if (*list == robust) + { + *list = robust->next; + } +} + + +int +pthread_mutex_consistent (pthread_mutex_t* mutex) +{ + pthread_mutex_t mx = *mutex; + int result = 0; + + /* + * Let the system deal with invalid pointers. + */ + if (mx == NULL) + { + return EINVAL; + } + + if (mx->kind >= 0 + || (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_INCONSISTENT != PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR)&mx->robustNode->stateInconsistent, + (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_CONSISTENT, + (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_INCONSISTENT)) + { + result = EINVAL; + } + + return (result); +} + diff --git a/pthreads/pthread_mutex_destroy.c b/pthreads/pthread_mutex_destroy.c index 95509b3df..7b8c9cd65 100644 --- a/pthreads/pthread_mutex_destroy.c +++ b/pthreads/pthread_mutex_destroy.c @@ -61,7 +61,7 @@ pthread_mutex_destroy (pthread_mutex_t * mutex) * If trylock succeeded and the mutex is not recursively locked it * can be destroyed. */ - if (result == 0) + if (0 == result || ENOTRECOVERABLE == result) { if (mx->kind != PTHREAD_MUTEX_RECURSIVE || 1 == mx->recursive_count) { @@ -71,17 +71,17 @@ pthread_mutex_destroy (pthread_mutex_t * mutex) * be too late invalidating the mutex below since another thread * may already have entered mutex_lock and the check for a valid * *mutex != NULL. - * - * Note that this would be an unusual situation because it is not - * common that mutexes are destroyed while they are still in - * use by other threads. */ *mutex = NULL; - result = pthread_mutex_unlock (&mx); + result = (0 == result)?pthread_mutex_unlock(&mx):0; - if (result == 0) + if (0 == result) { + if (mx->robustNode != NULL) + { + free(mx->robustNode); + } if (!CloseHandle (mx->event)) { *mutex = mx; @@ -112,10 +112,13 @@ pthread_mutex_destroy (pthread_mutex_t * mutex) } else { + ptw32_mcs_local_node_t node; + /* * See notes in ptw32_mutex_check_need_init() above also. */ - EnterCriticalSection (&ptw32_mutex_test_init_lock); + + ptw32_mcs_lock_acquire(&ptw32_mutex_test_init_lock, &node); /* * Check again. @@ -138,8 +141,7 @@ pthread_mutex_destroy (pthread_mutex_t * mutex) */ result = EBUSY; } - - LeaveCriticalSection (&ptw32_mutex_test_init_lock); + ptw32_mcs_lock_release(&node); } return (result); diff --git a/pthreads/pthread_mutex_init.c b/pthreads/pthread_mutex_init.c index cff8e5054..daf805e5b 100644 --- a/pthreads/pthread_mutex_init.c +++ b/pthreads/pthread_mutex_init.c @@ -49,27 +49,28 @@ pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr) return EINVAL; } - if (attr != NULL - && *attr != NULL && (*attr)->pshared == PTHREAD_PROCESS_SHARED) + if (attr != NULL && *attr != NULL) { - /* - * Creating mutex that can be shared between - * processes. - */ + if ((*attr)->pshared == PTHREAD_PROCESS_SHARED) + { + /* + * Creating mutex that can be shared between + * processes. + */ #if _POSIX_THREAD_PROCESS_SHARED >= 0 - /* - * Not implemented yet. - */ + /* + * Not implemented yet. + */ #error ERROR [__FILE__, line __LINE__]: Process shared mutexes are not supported yet. #else - return ENOSYS; + return ENOSYS; #endif /* _POSIX_THREAD_PROCESS_SHARED */ - + } } mx = (pthread_mutex_t) calloc (1, sizeof (*mx)); @@ -82,8 +83,33 @@ pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr) { mx->lock_idx = 0; mx->recursive_count = 0; - mx->kind = (attr == NULL || *attr == NULL - ? PTHREAD_MUTEX_DEFAULT : (*attr)->kind); + mx->robustNode = NULL; + if (attr == NULL || *attr == NULL) + { + mx->kind = PTHREAD_MUTEX_DEFAULT; + } + else + { + mx->kind = (*attr)->kind; + if ((*attr)->robustness == PTHREAD_MUTEX_ROBUST) + { + /* + * Use the negative range to represent robust types. + * Replaces a memory fetch with a register negate and incr + * in pthread_mutex_lock etc. + * + * Map 0,1,..,n to -1,-2,..,(-n)-1 + */ + mx->kind = -mx->kind - 1; + + mx->robustNode = (ptw32_robust_node_t*) malloc(sizeof(ptw32_robust_node_t)); + mx->robustNode->stateInconsistent = PTW32_ROBUST_CONSISTENT; + mx->robustNode->mx = mx; + mx->robustNode->next = NULL; + mx->robustNode->prev = NULL; + } + } + mx->ownerThread.p = NULL; mx->event = CreateEvent (NULL, PTW32_FALSE, /* manual reset = No */ diff --git a/pthreads/pthread_mutex_lock.c b/pthreads/pthread_mutex_lock.c index f15cf6ab0..eee9abe8c 100644 --- a/pthreads/pthread_mutex_lock.c +++ b/pthreads/pthread_mutex_lock.c @@ -1,139 +1,269 @@ -/* - * pthread_mutex_lock.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 */ -#endif -#include "pthread.h" -#include "implement.h" - -int -pthread_mutex_lock (pthread_mutex_t * mutex) -{ - int result = 0; - pthread_mutex_t mx; - - /* - * Let the system deal with invalid pointers. - */ - if (*mutex == NULL) - { - return EINVAL; - } - - /* - * 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 (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE)) - { - result = EINVAL; - break; - } - } - } - } - 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 - { - result = EDEADLK; - } - } - else - { - while ((LONG) PTW32_INTERLOCKED_EXCHANGE( - (LPLONG) &mx->lock_idx, - (LONG) -1) != 0) - { - if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE)) - { - result = EINVAL; - break; - } - } - - if (0 == result) - { - mx->recursive_count = 1; - mx->ownerThread = self; - } - } - } - } - - return (result); -} +/* + * pthread_mutex_lock.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 + */ + +#if !defined(_UWIN) +/*# include */ +#endif +#include "pthread.h" +#include "implement.h" + +int +pthread_mutex_lock (pthread_mutex_t * mutex) +{ + int kind; + pthread_mutex_t mx; + int result = 0; + + /* + * Let the system deal with invalid pointers. + */ + if (*mutex == NULL) + { + return EINVAL; + } + + /* + * 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; + kind = mx->kind; + + if (kind >= 0) + { + /* Non-robust */ + if (PTHREAD_MUTEX_NORMAL == kind) + { + if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) 1) != 0) + { + while ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) -1) != 0) + { + if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE)) + { + result = EINVAL; + break; + } + } + } + } + else + { + pthread_t self = pthread_self(); + + if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &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 (kind == PTHREAD_MUTEX_RECURSIVE) + { + mx->recursive_count++; + } + else + { + result = EDEADLK; + } + } + else + { + while ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) -1) != 0) + { + if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE)) + { + result = EINVAL; + break; + } + } + + if (0 == result) + { + mx->recursive_count = 1; + mx->ownerThread = self; + } + } + } + } + } + else + { + /* + * Robust types + * All types record the current owner thread. + * The mutex is added to a per thread list when ownership is acquired. + */ + ptw32_robust_state_t* statePtr = &mx->robustNode->stateInconsistent; + + if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE == PTW32_INTERLOCKED_EXCHANGE_ADD_LONG( + (PTW32_INTERLOCKED_LONGPTR)statePtr, + (PTW32_INTERLOCKED_LONG)0)) + { + result = ENOTRECOVERABLE; + } + else + { + pthread_t self = pthread_self(); + + kind = -kind - 1; /* Convert to non-robust range */ + + if (PTHREAD_MUTEX_NORMAL == kind) + { + if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) 1) != 0) + { + while (0 == (result = ptw32_robust_mutex_inherit(mutex)) + && (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) -1) != 0) + { + if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE)) + { + result = EINVAL; + break; + } + if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE == + PTW32_INTERLOCKED_EXCHANGE_ADD_LONG( + (PTW32_INTERLOCKED_LONGPTR)statePtr, + (PTW32_INTERLOCKED_LONG)0)) + { + /* Unblock the next thread */ + SetEvent(mx->event); + result = ENOTRECOVERABLE; + break; + } + } + } + if (0 == result || EOWNERDEAD == result) + { + /* + * Add mutex to the per-thread robust mutex currently-held list. + * If the thread terminates, all mutexes in this list will be unlocked. + */ + ptw32_robust_mutex_add(mutex, self); + } + } + else + { + if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) 1, + (PTW32_INTERLOCKED_LONG) 0) == 0) + { + mx->recursive_count = 1; + /* + * Add mutex to the per-thread robust mutex currently-held list. + * If the thread terminates, all mutexes in this list will be unlocked. + */ + ptw32_robust_mutex_add(mutex, self); + } + else + { + if (pthread_equal (mx->ownerThread, self)) + { + if (PTHREAD_MUTEX_RECURSIVE == kind) + { + mx->recursive_count++; + } + else + { + result = EDEADLK; + } + } + else + { + while (0 == (result = ptw32_robust_mutex_inherit(mutex)) + && (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) -1) != 0) + { + if (WAIT_OBJECT_0 != WaitForSingleObject (mx->event, INFINITE)) + { + result = EINVAL; + break; + } + if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE == + PTW32_INTERLOCKED_EXCHANGE_ADD_LONG( + (PTW32_INTERLOCKED_LONGPTR)statePtr, + (PTW32_INTERLOCKED_LONG)0)) + { + /* Unblock the next thread */ + SetEvent(mx->event); + result = ENOTRECOVERABLE; + break; + } + } + + if (0 == result || EOWNERDEAD == result) + { + mx->recursive_count = 1; + /* + * Add mutex to the per-thread robust mutex currently-held list. + * If the thread terminates, all mutexes in this list will be unlocked. + */ + ptw32_robust_mutex_add(mutex, self); + } + } + } + } + } + } + + return (result); +} + diff --git a/pthreads/pthread_mutex_timedlock.c b/pthreads/pthread_mutex_timedlock.c index a2385522d..174531679 100644 --- a/pthreads/pthread_mutex_timedlock.c +++ b/pthreads/pthread_mutex_timedlock.c @@ -109,8 +109,9 @@ int pthread_mutex_timedlock (pthread_mutex_t * mutex, const struct timespec *abstime) { - int result; pthread_mutex_t mx; + int kind; + int result = 0; /* * Let the system deal with invalid pointers. @@ -131,66 +132,193 @@ pthread_mutex_timedlock (pthread_mutex_t * mutex, } mx = *mutex; + kind = mx->kind; - if (mx->kind == PTHREAD_MUTEX_NORMAL) + if (kind >= 0) { - 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_NORMAL) + { + if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) 1) != 0) { - 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) + while ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) -1) != 0) { - if (0 != (result = ptw32_timed_eventwait (mx->event, abstime))) + 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_LONG( + (PTW32_INTERLOCKED_LONGPTR) &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 ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) -1) != 0) + { + if (0 != (result = ptw32_timed_eventwait (mx->event, abstime))) + { + return result; + } + } + + mx->recursive_count = 1; + mx->ownerThread = self; + } + } + } } + else + { + /* + * Robust types + * All types record the current owner thread. + * The mutex is added to a per thread list when ownership is acquired. + */ + ptw32_robust_state_t* statePtr = &mx->robustNode->stateInconsistent; - return 0; + if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE == PTW32_INTERLOCKED_EXCHANGE_ADD_LONG( + (PTW32_INTERLOCKED_LONGPTR)statePtr, + (PTW32_INTERLOCKED_LONG)0)) + { + result = ENOTRECOVERABLE; + } + else + { + pthread_t self = pthread_self(); + + kind = -kind - 1; /* Convert to non-robust range */ + + if (PTHREAD_MUTEX_NORMAL == kind) + { + if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) 1) != 0) + { + while (0 == (result = ptw32_robust_mutex_inherit(mutex)) + && (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) -1) != 0) + { + if (0 != (result = ptw32_timed_eventwait (mx->event, abstime))) + { + return result; + } + if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE == + PTW32_INTERLOCKED_EXCHANGE_ADD_LONG( + (PTW32_INTERLOCKED_LONGPTR)statePtr, + (PTW32_INTERLOCKED_LONG)0)) + { + /* Unblock the next thread */ + SetEvent(mx->event); + result = ENOTRECOVERABLE; + break; + } + } + + if (0 == result || EOWNERDEAD == result) + { + /* + * Add mutex to the per-thread robust mutex currently-held list. + * If the thread terminates, all mutexes in this list will be unlocked. + */ + ptw32_robust_mutex_add(mutex, self); + } + } + } + else + { + pthread_t self = pthread_self(); + + if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) 1, + (PTW32_INTERLOCKED_LONG) 0)) + { + mx->recursive_count = 1; + /* + * Add mutex to the per-thread robust mutex currently-held list. + * If the thread terminates, all mutexes in this list will be unlocked. + */ + ptw32_robust_mutex_add(mutex, self); + } + else + { + if (pthread_equal (mx->ownerThread, self)) + { + if (PTHREAD_MUTEX_RECURSIVE == kind) + { + mx->recursive_count++; + } + else + { + return EDEADLK; + } + } + else + { + while (0 == (result = ptw32_robust_mutex_inherit(mutex)) + && (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) -1) != 0) + { + if (0 != (result = ptw32_timed_eventwait (mx->event, abstime))) + { + return result; + } + } + + if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE == + PTW32_INTERLOCKED_EXCHANGE_ADD_LONG( + (PTW32_INTERLOCKED_LONGPTR)statePtr, + (PTW32_INTERLOCKED_LONG)0)) + { + /* Unblock the next thread */ + SetEvent(mx->event); + result = ENOTRECOVERABLE; + } + else if (0 == result || EOWNERDEAD == result) + { + mx->recursive_count = 1; + /* + * Add mutex to the per-thread robust mutex currently-held list. + * If the thread terminates, all mutexes in this list will be unlocked. + */ + ptw32_robust_mutex_add(mutex, self); + } + } + } + } + } + } + + return result; } diff --git a/pthreads/pthread_mutex_trylock.c b/pthreads/pthread_mutex_trylock.c index 50e8bc65c..d6b68724d 100644 --- a/pthreads/pthread_mutex_trylock.c +++ b/pthreads/pthread_mutex_trylock.c @@ -41,8 +41,9 @@ int pthread_mutex_trylock (pthread_mutex_t * mutex) { - int result = 0; pthread_mutex_t mx; + int kind; + int result = 0; /* * Let the system deal with invalid pointers. @@ -63,29 +64,90 @@ pthread_mutex_trylock (pthread_mutex_t * mutex) } mx = *mutex; + kind = mx->kind; - if (0 == (LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE ( - (PTW32_INTERLOCKED_LPLONG) &mx->lock_idx, - (PTW32_INTERLOCKED_LONG) 1, - (PTW32_INTERLOCKED_LONG) 0)) + if (kind >= 0) { - if (mx->kind != PTHREAD_MUTEX_NORMAL) - { - mx->recursive_count = 1; - mx->ownerThread = pthread_self (); - } + /* Non-robust */ + if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) 1, + (PTW32_INTERLOCKED_LONG) 0)) + { + if (kind != PTHREAD_MUTEX_NORMAL) + { + mx->recursive_count = 1; + mx->ownerThread = pthread_self (); + } + } + else + { + if (kind == PTHREAD_MUTEX_RECURSIVE && + pthread_equal (mx->ownerThread, pthread_self ())) + { + mx->recursive_count++; + } + else + { + result = EBUSY; + } + } } else { - if (mx->kind == PTHREAD_MUTEX_RECURSIVE && - pthread_equal (mx->ownerThread, pthread_self ())) - { - mx->recursive_count++; - } + /* + * Robust types + * All types record the current owner thread. + * The mutex is added to a per thread list when ownership is acquired. + */ + pthread_t self; + ptw32_robust_state_t* statePtr = &mx->robustNode->stateInconsistent; + + if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE == + PTW32_INTERLOCKED_EXCHANGE_ADD_LONG( + (PTW32_INTERLOCKED_LONGPTR)statePtr, + (PTW32_INTERLOCKED_LONG)0)) + { + return ENOTRECOVERABLE; + } + + self = pthread_self(); + kind = -kind - 1; /* Convert to non-robust range */ + + if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ( + (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) 1, + (PTW32_INTERLOCKED_LONG) 0)) + { + if (kind != PTHREAD_MUTEX_NORMAL) + { + mx->recursive_count = 1; + } + ptw32_robust_mutex_add(mutex, self); + } else - { - result = EBUSY; - } + { + if (PTHREAD_MUTEX_RECURSIVE == kind && + pthread_equal (mx->ownerThread, pthread_self ())) + { + mx->recursive_count++; + } + else + { + if (EOWNERDEAD == (result = ptw32_robust_mutex_inherit(mutex))) + { + mx->recursive_count = 1; + ptw32_robust_mutex_add(mutex, self); + } + else + { + if (0 == result) + { + result = EBUSY; + } + } + } + } } return (result); diff --git a/pthreads/pthread_mutex_unlock.c b/pthreads/pthread_mutex_unlock.c index 9ebe4e378..3d65d1a95 100644 --- a/pthreads/pthread_mutex_unlock.c +++ b/pthreads/pthread_mutex_unlock.c @@ -42,6 +42,7 @@ int pthread_mutex_unlock (pthread_mutex_t * mutex) { int result = 0; + int kind; pthread_mutex_t mx; /* @@ -57,60 +58,115 @@ pthread_mutex_unlock (pthread_mutex_t * mutex) */ if (mx < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER) { - if (mx->kind == PTHREAD_MUTEX_NORMAL) - { - LONG idx; + kind = mx->kind; - idx = (LONG) PTW32_INTERLOCKED_EXCHANGE ((LPLONG) &mx->lock_idx, - (LONG) 0); - if (idx != 0) + if (kind >= 0) + { + if (kind == PTHREAD_MUTEX_NORMAL) { - if (idx < 0) - { - /* - * Someone may be waiting on that mutex. - */ - if (SetEvent (mx->event) == 0) - { - result = EINVAL; - } - } - } - else - { - /* - * Was not locked (so can't be owned by us). - */ - result = EPERM; - } - } - else - { - if (pthread_equal (mx->ownerThread, pthread_self ())) - { - if (mx->kind != PTHREAD_MUTEX_RECURSIVE - || 0 == --mx->recursive_count) - { - mx->ownerThread.p = NULL; + LONG idx; - if ((LONG) PTW32_INTERLOCKED_EXCHANGE ((LPLONG) &mx->lock_idx, - (LONG) 0) < 0) + idx = (LONG) PTW32_INTERLOCKED_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR)&mx->lock_idx, + (PTW32_INTERLOCKED_LONG)0); + if (idx != 0) + { + if (idx < 0) { - /* Someone may be waiting on that mutex */ + /* + * Someone may be waiting on that mutex. + */ if (SetEvent (mx->event) == 0) - { - result = EINVAL; - } + { + result = EINVAL; + } } - } + } } - else + else { - result = EPERM; + if (pthread_equal (mx->ownerThread, pthread_self())) + { + if (kind != PTHREAD_MUTEX_RECURSIVE + || 0 == --mx->recursive_count) + { + mx->ownerThread.p = NULL; + + if ((LONG) PTW32_INTERLOCKED_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR)&mx->lock_idx, + (PTW32_INTERLOCKED_LONG)0) < 0L) + { + /* Someone may be waiting on that mutex */ + if (SetEvent (mx->event) == 0) + { + result = EINVAL; + } + } + } + } + else + { + result = EPERM; + } } - } + } + else + { + /* Robust types */ + pthread_t self = pthread_self(); + kind = -kind - 1; /* Convert to non-robust range */ + + /* + * The thread must own the lock regardless of type if the mutex + * is robust. + */ + if (pthread_equal (mx->ownerThread, self)) + { + PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG((PTW32_INTERLOCKED_LONGPTR) &mx->robustNode->stateInconsistent, + (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE, + (PTW32_INTERLOCKED_LONG)PTW32_ROBUST_INCONSISTENT); + if (PTHREAD_MUTEX_NORMAL == kind) + { + ptw32_robust_mutex_remove(mutex, NULL); + + if ((LONG) PTW32_INTERLOCKED_EXCHANGE_LONG((PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) 0) < 0) + { + /* + * Someone may be waiting on that mutex. + */ + if (SetEvent (mx->event) == 0) + { + result = EINVAL; + } + } + } + else + { + if (kind != PTHREAD_MUTEX_RECURSIVE + || 0 == --mx->recursive_count) + { + ptw32_robust_mutex_remove(mutex, NULL); + + if ((LONG) PTW32_INTERLOCKED_EXCHANGE_LONG((PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) 0) < 0) + { + /* + * Someone may be waiting on that mutex. + */ + if (SetEvent (mx->event) == 0) + { + result = EINVAL; + } + } + } + } + } + else + { + result = EPERM; + } + } } - else + else if (mx != PTHREAD_MUTEX_INITIALIZER) { result = EINVAL; } diff --git a/pthreads/pthread_mutexattr_getrobust.c b/pthreads/pthread_mutexattr_getrobust.c new file mode 100644 index 000000000..be004837b --- /dev/null +++ b/pthreads/pthread_mutexattr_getrobust.c @@ -0,0 +1,113 @@ +/* + * pthread_mutexattr_getrobust.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" + + +int +pthread_mutexattr_getrobust (const pthread_mutexattr_t * attr, int * robust) + /* + * ------------------------------------------------------ + * + * DOCPUBLIC + * The pthread_mutexattr_setrobust() and + * pthread_mutexattr_getrobust() functions respectively set and + * get the mutex robust attribute. This attribute is set in the + * robust parameter to these functions. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_mutexattr_t + * + * robust + * must be one of: + * + * PTHREAD_MUTEX_STALLED + * + * PTHREAD_MUTEX_ROBUST + * + * DESCRIPTION + * The pthread_mutexattr_setrobust() and + * pthread_mutexattr_getrobust() functions respectively set and + * get the mutex robust attribute. This attribute is set in the + * robust parameter to these functions. The default value of the + * robust attribute is PTHREAD_MUTEX_STALLED. + * + * The robustness of mutex is contained in the robustness attribute + * of the mutex attributes. Valid mutex robustness values are: + * + * PTHREAD_MUTEX_STALLED + * No special actions are taken if the owner of the mutex is + * terminated while holding the mutex lock. This can lead to + * deadlocks if no other thread can unlock the mutex. + * This is the default value. + * + * PTHREAD_MUTEX_ROBUST + * If the process containing the owning thread of a robust mutex + * terminates while holding the mutex lock, the next thread that + * acquires the mutex shall be notified about the termination by + * the return value [EOWNERDEAD] from the locking function. If the + * owning thread of a robust mutex terminates while holding the mutex + * lock, the next thread that acquires the mutex may be notified + * about the termination by the return value [EOWNERDEAD]. The + * notified thread can then attempt to mark the state protected by + * the mutex as consistent again by a call to + * pthread_mutex_consistent(). After a subsequent successful call to + * pthread_mutex_unlock(), the mutex lock shall be released and can + * be used normally by other threads. If the mutex is unlocked without + * a call to pthread_mutex_consistent(), it shall be in a permanently + * unusable state and all attempts to lock the mutex shall fail with + * the error [ENOTRECOVERABLE]. The only permissible operation on such + * a mutex is pthread_mutex_destroy(). + * + * RESULTS + * 0 successfully set attribute, + * EINVAL 'attr' or 'robust' is invalid, + * + * ------------------------------------------------------ + */ +{ + int result = EINVAL; + + if ((attr != NULL && *attr != NULL && robust != NULL)) + { + *robust = (*attr)->robustness; + result = 0; + } + + return (result); +} /* pthread_mutexattr_getrobust */ diff --git a/pthreads/pthread_mutexattr_setrobust.c b/pthreads/pthread_mutexattr_setrobust.c new file mode 100644 index 000000000..b1acef757 --- /dev/null +++ b/pthreads/pthread_mutexattr_setrobust.c @@ -0,0 +1,119 @@ +/* + * pthread_mutexattr_setrobust.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" + + +int +pthread_mutexattr_setrobust (pthread_mutexattr_t * attr, int robust) + /* + * ------------------------------------------------------ + * + * DOCPUBLIC + * The pthread_mutexattr_setrobust() and + * pthread_mutexattr_getrobust() functions respectively set and + * get the mutex robust attribute. This attribute is set in the + * robust parameter to these functions. + * + * PARAMETERS + * attr + * pointer to an instance of pthread_mutexattr_t + * + * robust + * must be one of: + * + * PTHREAD_MUTEX_STALLED + * + * PTHREAD_MUTEX_ROBUST + * + * DESCRIPTION + * The pthread_mutexattr_setrobust() and + * pthread_mutexattr_getrobust() functions respectively set and + * get the mutex robust attribute. This attribute is set in the + * robust parameter to these functions. The default value of the + * robust attribute is PTHREAD_MUTEX_STALLED. + * + * The robustness of mutex is contained in the robustness attribute + * of the mutex attributes. Valid mutex robustness values are: + * + * PTHREAD_MUTEX_STALLED + * No special actions are taken if the owner of the mutex is + * terminated while holding the mutex lock. This can lead to + * deadlocks if no other thread can unlock the mutex. + * This is the default value. + * + * PTHREAD_MUTEX_ROBUST + * If the process containing the owning thread of a robust mutex + * terminates while holding the mutex lock, the next thread that + * acquires the mutex shall be notified about the termination by + * the return value [EOWNERDEAD] from the locking function. If the + * owning thread of a robust mutex terminates while holding the mutex + * lock, the next thread that acquires the mutex may be notified + * about the termination by the return value [EOWNERDEAD]. The + * notified thread can then attempt to mark the state protected by + * the mutex as consistent again by a call to + * pthread_mutex_consistent(). After a subsequent successful call to + * pthread_mutex_unlock(), the mutex lock shall be released and can + * be used normally by other threads. If the mutex is unlocked without + * a call to pthread_mutex_consistent(), it shall be in a permanently + * unusable state and all attempts to lock the mutex shall fail with + * the error [ENOTRECOVERABLE]. The only permissible operation on such + * a mutex is pthread_mutex_destroy(). + * + * RESULTS + * 0 successfully set attribute, + * EINVAL 'attr' or 'robust' is invalid, + * + * ------------------------------------------------------ + */ +{ + int result = EINVAL; + + if ((attr != NULL && *attr != NULL)) + { + switch (robust) + { + case PTHREAD_MUTEX_STALLED: + case PTHREAD_MUTEX_ROBUST: + (*attr)->robustness = robust; + result = 0; + break; + } + } + + return (result); +} /* pthread_mutexattr_setrobust */ diff --git a/pthreads/pthread_once.c b/pthreads/pthread_once.c index 74add02c3..ef2c1f168 100644 --- a/pthreads/pthread_once.c +++ b/pthreads/pthread_once.c @@ -1,86 +1,79 @@ -/* - * 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 - */ - -#include "pthread.h" -#include "implement.h" - - -static void PTW32_CDECL -ptw32_once_on_init_cancel (void * arg) -{ - /* when the initing thread is cancelled we have to release the lock */ - ptw32_mcs_local_node_t *node = (ptw32_mcs_local_node_t *)arg; - ptw32_mcs_lock_release(node); -} - -int -pthread_once (pthread_once_t * once_control, void (*init_routine) (void)) -{ - if (once_control == NULL || init_routine == NULL) - { - return EINVAL; - } - - if (!InterlockedExchangeAdd((LPLONG)&once_control->done, 0)) /* MBR fence */ - { - ptw32_mcs_local_node_t node; - - ptw32_mcs_lock_acquire((ptw32_mcs_lock_t *)&once_control->lock, &node); - - if (!once_control->done) - { - -#ifdef _MSC_VER -#pragma inline_depth(0) -#endif - - pthread_cleanup_push(ptw32_once_on_init_cancel, (void *)&node); - (*init_routine)(); - pthread_cleanup_pop(0); - -#ifdef _MSC_VER -#pragma inline_depth() -#endif - - once_control->done = PTW32_TRUE; - } - - ptw32_mcs_lock_release(&node); - } - - return 0; - -} /* 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 + */ + +#include "pthread.h" +#include "implement.h" + +int +pthread_once (pthread_once_t * once_control, void (*init_routine) (void)) +{ + if (once_control == NULL || init_routine == NULL) + { + return EINVAL; + } + + if ((PTW32_INTERLOCKED_LONG)PTW32_FALSE == + (PTW32_INTERLOCKED_LONG)PTW32_INTERLOCKED_EXCHANGE_ADD_LONG((PTW32_INTERLOCKED_LONGPTR)&once_control->done, + (PTW32_INTERLOCKED_LONG)0)) /* MBR fence */ + { + ptw32_mcs_local_node_t node; + + ptw32_mcs_lock_acquire((ptw32_mcs_lock_t *)&once_control->lock, &node); + + if (!once_control->done) + { + +#if defined(_MSC_VER) && _MSC_VER < 1400 +#pragma inline_depth(0) +#endif + + pthread_cleanup_push(ptw32_mcs_lock_release, &node); + (*init_routine)(); + pthread_cleanup_pop(0); + +#if defined(_MSC_VER) && _MSC_VER < 1400 +#pragma inline_depth() +#endif + + once_control->done = PTW32_TRUE; + } + + ptw32_mcs_lock_release(&node); + } + + return 0; + +} /* pthread_once */ diff --git a/pthreads/pthread_rwlock_destroy.c b/pthreads/pthread_rwlock_destroy.c index bc7889e55..245a89241 100644 --- a/pthreads/pthread_rwlock_destroy.c +++ b/pthreads/pthread_rwlock_destroy.c @@ -1,142 +1,143 @@ -/* - * pthread_rwlock_destroy.c - * - * Description: - * This translation unit implements read/write lock 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 - -#include "pthread.h" -#include "implement.h" - -int -pthread_rwlock_destroy (pthread_rwlock_t * rwlock) -{ - pthread_rwlock_t rwl; - int result = 0, result1 = 0, result2 = 0; - - if (rwlock == NULL || *rwlock == NULL) - { - return EINVAL; - } - - if (*rwlock != PTHREAD_RWLOCK_INITIALIZER) - { - rwl = *rwlock; - - if (rwl->nMagic != PTW32_RWLOCK_MAGIC) - { - return EINVAL; - } - - if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0) - { - return result; - } - - if ((result = - pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0) - { - (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); - return result; - } - - /* - * Check whether any threads own/wait for the lock (wait for ex.access); - * report "BUSY" if so. - */ - if (rwl->nExclusiveAccessCount > 0 - || rwl->nSharedAccessCount > rwl->nCompletedSharedAccessCount) - { - result = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted)); - result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); - result2 = EBUSY; - } - else - { - rwl->nMagic = 0; - - if ((result = - pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0) - { - pthread_mutex_unlock (&rwl->mtxExclusiveAccess); - return result; - } - - if ((result = - pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))) != 0) - { - return result; - } - - *rwlock = NULL; /* Invalidate rwlock before anything else */ - result = pthread_cond_destroy (&(rwl->cndSharedAccessCompleted)); - result1 = pthread_mutex_destroy (&(rwl->mtxSharedAccessCompleted)); - result2 = pthread_mutex_destroy (&(rwl->mtxExclusiveAccess)); - (void) free (rwl); - } - } - else - { - /* - * See notes in ptw32_rwlock_check_need_init() above also. - */ - EnterCriticalSection (&ptw32_rwlock_test_init_lock); - - /* - * Check again. - */ - if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) - { - /* - * This is all we need to do to destroy a statically - * initialised rwlock that has not yet been used (initialised). - * If we get to here, another thread - * waiting to initialise this rwlock will get an EINVAL. - */ - *rwlock = NULL; - } - else - { - /* - * The rwlock has been initialised while we were waiting - * so assume it's in use. - */ - result = EBUSY; - } - - LeaveCriticalSection (&ptw32_rwlock_test_init_lock); - } - - return ((result != 0) ? result : ((result1 != 0) ? result1 : result2)); -} +/* + * pthread_rwlock_destroy.c + * + * Description: + * This translation unit implements read/write lock 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 + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlock_destroy (pthread_rwlock_t * rwlock) +{ + pthread_rwlock_t rwl; + int result = 0, result1 = 0, result2 = 0; + + if (rwlock == NULL || *rwlock == NULL) + { + return EINVAL; + } + + if (*rwlock != PTHREAD_RWLOCK_INITIALIZER) + { + rwl = *rwlock; + + if (rwl->nMagic != PTW32_RWLOCK_MAGIC) + { + return EINVAL; + } + + if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0) + { + return result; + } + + if ((result = + pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return result; + } + + /* + * Check whether any threads own/wait for the lock (wait for ex.access); + * report "BUSY" if so. + */ + if (rwl->nExclusiveAccessCount > 0 + || rwl->nSharedAccessCount > rwl->nCompletedSharedAccessCount) + { + result = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted)); + result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + result2 = EBUSY; + } + else + { + rwl->nMagic = 0; + + if ((result = + pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + pthread_mutex_unlock (&rwl->mtxExclusiveAccess); + return result; + } + + if ((result = + pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))) != 0) + { + return result; + } + + *rwlock = NULL; /* Invalidate rwlock before anything else */ + result = pthread_cond_destroy (&(rwl->cndSharedAccessCompleted)); + result1 = pthread_mutex_destroy (&(rwl->mtxSharedAccessCompleted)); + result2 = pthread_mutex_destroy (&(rwl->mtxExclusiveAccess)); + (void) free (rwl); + } + } + else + { + ptw32_mcs_local_node_t node; + /* + * See notes in ptw32_rwlock_check_need_init() above also. + */ + ptw32_mcs_lock_acquire(&ptw32_rwlock_test_init_lock, &node); + + /* + * Check again. + */ + if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) + { + /* + * This is all we need to do to destroy a statically + * initialised rwlock that has not yet been used (initialised). + * If we get to here, another thread + * waiting to initialise this rwlock will get an EINVAL. + */ + *rwlock = NULL; + } + else + { + /* + * The rwlock has been initialised while we were waiting + * so assume it's in use. + */ + result = EBUSY; + } + + ptw32_mcs_lock_release(&node); + } + + return ((result != 0) ? result : ((result1 != 0) ? result1 : result2)); +} diff --git a/pthreads/pthread_rwlock_timedwrlock.c b/pthreads/pthread_rwlock_timedwrlock.c index 1f23639dc..8c111bbb1 100644 --- a/pthreads/pthread_rwlock_timedwrlock.c +++ b/pthreads/pthread_rwlock_timedwrlock.c @@ -1,139 +1,139 @@ -/* - * pthread_rwlock_timedwrlock.c - * - * Description: - * This translation unit implements read/write lock 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 - -#include "pthread.h" -#include "implement.h" - -int -pthread_rwlock_timedwrlock (pthread_rwlock_t * rwlock, - const struct timespec *abstime) -{ - int result; - pthread_rwlock_t rwl; - - if (rwlock == NULL || *rwlock == NULL) - { - return EINVAL; - } - - /* - * We do a quick check to see if we need to do more work - * to initialise a static rwlock. We check - * again inside the guarded section of ptw32_rwlock_check_need_init() - * to avoid race conditions. - */ - if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) - { - result = ptw32_rwlock_check_need_init (rwlock); - - if (result != 0 && result != EBUSY) - { - return result; - } - } - - rwl = *rwlock; - - if (rwl->nMagic != PTW32_RWLOCK_MAGIC) - { - return EINVAL; - } - - if ((result = - pthread_mutex_timedlock (&(rwl->mtxExclusiveAccess), abstime)) != 0) - { - return result; - } - - if ((result = - pthread_mutex_timedlock (&(rwl->mtxSharedAccessCompleted), - abstime)) != 0) - { - (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); - return result; - } - - if (rwl->nExclusiveAccessCount == 0) - { - if (rwl->nCompletedSharedAccessCount > 0) - { - rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; - rwl->nCompletedSharedAccessCount = 0; - } - - if (rwl->nSharedAccessCount > 0) - { - rwl->nCompletedSharedAccessCount = -rwl->nSharedAccessCount; - - /* - * This routine may be a cancelation point - * according to POSIX 1003.1j section 18.1.2. - */ -#ifdef _MSC_VER -#pragma inline_depth(0) -#endif - pthread_cleanup_push (ptw32_rwlock_cancelwrwait, (void *) rwl); - - do - { - result = - pthread_cond_timedwait (&(rwl->cndSharedAccessCompleted), - &(rwl->mtxSharedAccessCompleted), - abstime); - } - while (result == 0 && rwl->nCompletedSharedAccessCount < 0); - - pthread_cleanup_pop ((result != 0) ? 1 : 0); -#ifdef _MSC_VER -#pragma inline_depth() -#endif - - if (result == 0) - { - rwl->nSharedAccessCount = 0; - } - } - } - - if (result == 0) - { - rwl->nExclusiveAccessCount++; - } - - return result; -} +/* + * pthread_rwlock_timedwrlock.c + * + * Description: + * This translation unit implements read/write lock 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 + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlock_timedwrlock (pthread_rwlock_t * rwlock, + const struct timespec *abstime) +{ + int result; + pthread_rwlock_t rwl; + + if (rwlock == NULL || *rwlock == NULL) + { + return EINVAL; + } + + /* + * We do a quick check to see if we need to do more work + * to initialise a static rwlock. We check + * again inside the guarded section of ptw32_rwlock_check_need_init() + * to avoid race conditions. + */ + if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) + { + result = ptw32_rwlock_check_need_init (rwlock); + + if (result != 0 && result != EBUSY) + { + return result; + } + } + + rwl = *rwlock; + + if (rwl->nMagic != PTW32_RWLOCK_MAGIC) + { + return EINVAL; + } + + if ((result = + pthread_mutex_timedlock (&(rwl->mtxExclusiveAccess), abstime)) != 0) + { + return result; + } + + if ((result = + pthread_mutex_timedlock (&(rwl->mtxSharedAccessCompleted), + abstime)) != 0) + { + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return result; + } + + if (rwl->nExclusiveAccessCount == 0) + { + if (rwl->nCompletedSharedAccessCount > 0) + { + rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; + rwl->nCompletedSharedAccessCount = 0; + } + + if (rwl->nSharedAccessCount > 0) + { + rwl->nCompletedSharedAccessCount = -rwl->nSharedAccessCount; + + /* + * This routine may be a cancelation point + * according to POSIX 1003.1j section 18.1.2. + */ +#if defined(_MSC_VER) && _MSC_VER < 1400 +#pragma inline_depth(0) +#endif + pthread_cleanup_push (ptw32_rwlock_cancelwrwait, (void *) rwl); + + do + { + result = + pthread_cond_timedwait (&(rwl->cndSharedAccessCompleted), + &(rwl->mtxSharedAccessCompleted), + abstime); + } + while (result == 0 && rwl->nCompletedSharedAccessCount < 0); + + pthread_cleanup_pop ((result != 0) ? 1 : 0); +#if defined(_MSC_VER) && _MSC_VER < 1400 +#pragma inline_depth() +#endif + + if (result == 0) + { + rwl->nSharedAccessCount = 0; + } + } + } + + if (result == 0) + { + rwl->nExclusiveAccessCount++; + } + + return result; +} diff --git a/pthreads/pthread_rwlock_wrlock.c b/pthreads/pthread_rwlock_wrlock.c index d7e2c9c26..e8b4fbb30 100644 --- a/pthreads/pthread_rwlock_wrlock.c +++ b/pthreads/pthread_rwlock_wrlock.c @@ -1,133 +1,133 @@ -/* - * pthread_rwlock_wrlock.c - * - * Description: - * This translation unit implements read/write lock 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 - -#include "pthread.h" -#include "implement.h" - -int -pthread_rwlock_wrlock (pthread_rwlock_t * rwlock) -{ - int result; - pthread_rwlock_t rwl; - - if (rwlock == NULL || *rwlock == NULL) - { - return EINVAL; - } - - /* - * We do a quick check to see if we need to do more work - * to initialise a static rwlock. We check - * again inside the guarded section of ptw32_rwlock_check_need_init() - * to avoid race conditions. - */ - if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) - { - result = ptw32_rwlock_check_need_init (rwlock); - - if (result != 0 && result != EBUSY) - { - return result; - } - } - - rwl = *rwlock; - - if (rwl->nMagic != PTW32_RWLOCK_MAGIC) - { - return EINVAL; - } - - if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0) - { - return result; - } - - if ((result = pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0) - { - (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); - return result; - } - - if (rwl->nExclusiveAccessCount == 0) - { - if (rwl->nCompletedSharedAccessCount > 0) - { - rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; - rwl->nCompletedSharedAccessCount = 0; - } - - if (rwl->nSharedAccessCount > 0) - { - rwl->nCompletedSharedAccessCount = -rwl->nSharedAccessCount; - - /* - * This routine may be a cancelation point - * according to POSIX 1003.1j section 18.1.2. - */ -#ifdef _MSC_VER -#pragma inline_depth(0) -#endif - pthread_cleanup_push (ptw32_rwlock_cancelwrwait, (void *) rwl); - - do - { - result = pthread_cond_wait (&(rwl->cndSharedAccessCompleted), - &(rwl->mtxSharedAccessCompleted)); - } - while (result == 0 && rwl->nCompletedSharedAccessCount < 0); - - pthread_cleanup_pop ((result != 0) ? 1 : 0); -#ifdef _MSC_VER -#pragma inline_depth() -#endif - - if (result == 0) - { - rwl->nSharedAccessCount = 0; - } - } - } - - if (result == 0) - { - rwl->nExclusiveAccessCount++; - } - - return result; -} +/* + * pthread_rwlock_wrlock.c + * + * Description: + * This translation unit implements read/write lock 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 + +#include "pthread.h" +#include "implement.h" + +int +pthread_rwlock_wrlock (pthread_rwlock_t * rwlock) +{ + int result; + pthread_rwlock_t rwl; + + if (rwlock == NULL || *rwlock == NULL) + { + return EINVAL; + } + + /* + * We do a quick check to see if we need to do more work + * to initialise a static rwlock. We check + * again inside the guarded section of ptw32_rwlock_check_need_init() + * to avoid race conditions. + */ + if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) + { + result = ptw32_rwlock_check_need_init (rwlock); + + if (result != 0 && result != EBUSY) + { + return result; + } + } + + rwl = *rwlock; + + if (rwl->nMagic != PTW32_RWLOCK_MAGIC) + { + return EINVAL; + } + + if ((result = pthread_mutex_lock (&(rwl->mtxExclusiveAccess))) != 0) + { + return result; + } + + if ((result = pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0) + { + (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)); + return result; + } + + if (rwl->nExclusiveAccessCount == 0) + { + if (rwl->nCompletedSharedAccessCount > 0) + { + rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; + rwl->nCompletedSharedAccessCount = 0; + } + + if (rwl->nSharedAccessCount > 0) + { + rwl->nCompletedSharedAccessCount = -rwl->nSharedAccessCount; + + /* + * This routine may be a cancelation point + * according to POSIX 1003.1j section 18.1.2. + */ +#if defined(_MSC_VER) && _MSC_VER < 1400 +#pragma inline_depth(0) +#endif + pthread_cleanup_push (ptw32_rwlock_cancelwrwait, (void *) rwl); + + do + { + result = pthread_cond_wait (&(rwl->cndSharedAccessCompleted), + &(rwl->mtxSharedAccessCompleted)); + } + while (result == 0 && rwl->nCompletedSharedAccessCount < 0); + + pthread_cleanup_pop ((result != 0) ? 1 : 0); +#if defined(_MSC_VER) && _MSC_VER < 1400 +#pragma inline_depth() +#endif + + if (result == 0) + { + rwl->nSharedAccessCount = 0; + } + } + } + + if (result == 0) + { + rwl->nExclusiveAccessCount++; + } + + return result; +} diff --git a/pthreads/pthread_self.c b/pthreads/pthread_self.c index d72a0971d..9a1765f82 100644 --- a/pthreads/pthread_self.c +++ b/pthreads/pthread_self.c @@ -63,7 +63,7 @@ pthread_self (void) pthread_t nil = {NULL, 0}; ptw32_thread_t * sp; -#ifdef _UWIN +#if defined(_UWIN) if (!ptw32_selfThreadKey) return nil; #endif @@ -95,7 +95,7 @@ pthread_self (void) sp->detachState = PTHREAD_CREATE_DETACHED; sp->thread = GetCurrentThreadId (); -#ifdef NEED_DUPLICATEHANDLE +#if defined(NEED_DUPLICATEHANDLE) /* * DuplicateHandle does not exist on WinCE. * @@ -119,6 +119,10 @@ pthread_self (void) * Thread structs are never freed. */ ptw32_threadReusePush (self); + /* + * As this is a win32 thread calling us and we have failed, + * return a value that makes sense to win32. + */ return nil; } #endif @@ -128,8 +132,7 @@ pthread_self (void) * because the new handle is not yet public. */ sp->sched_priority = GetThreadPriority (sp->threadH); - - pthread_setspecific (ptw32_selfThreadKey, (void *) sp); + pthread_setspecific (ptw32_selfThreadKey, (void *) sp); } } diff --git a/pthreads/pthread_setcancelstate.c b/pthreads/pthread_setcancelstate.c index 002cfe5e4..bbcd624af 100644 --- a/pthreads/pthread_setcancelstate.c +++ b/pthreads/pthread_setcancelstate.c @@ -79,6 +79,7 @@ pthread_setcancelstate (int state, int *oldstate) * ------------------------------------------------------ */ { + ptw32_mcs_local_node_t stateLock; int result = 0; pthread_t self = pthread_self (); ptw32_thread_t * sp = (ptw32_thread_t *) self.p; @@ -92,7 +93,7 @@ pthread_setcancelstate (int state, int *oldstate) /* * Lock for async-cancel safety. */ - (void) pthread_mutex_lock (&sp->cancelLock); + ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock); if (oldstate != NULL) { @@ -111,13 +112,13 @@ pthread_setcancelstate (int state, int *oldstate) sp->state = PThreadStateCanceling; sp->cancelState = PTHREAD_CANCEL_DISABLE; ResetEvent (sp->cancelEvent); - (void) pthread_mutex_unlock (&sp->cancelLock); + ptw32_mcs_lock_release (&stateLock); ptw32_throw (PTW32_EPS_CANCEL); /* Never reached */ } - (void) pthread_mutex_unlock (&sp->cancelLock); + ptw32_mcs_lock_release (&stateLock); return (result); diff --git a/pthreads/pthread_setcanceltype.c b/pthreads/pthread_setcanceltype.c index 3fb3f0e49..72b0af5bb 100644 --- a/pthreads/pthread_setcanceltype.c +++ b/pthreads/pthread_setcanceltype.c @@ -79,6 +79,7 @@ pthread_setcanceltype (int type, int *oldtype) * ------------------------------------------------------ */ { + ptw32_mcs_local_node_t stateLock; int result = 0; pthread_t self = pthread_self (); ptw32_thread_t * sp = (ptw32_thread_t *) self.p; @@ -93,7 +94,7 @@ pthread_setcanceltype (int type, int *oldtype) /* * Lock for async-cancel safety. */ - (void) pthread_mutex_lock (&sp->cancelLock); + ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock); if (oldtype != NULL) { @@ -112,13 +113,13 @@ pthread_setcanceltype (int type, int *oldtype) sp->state = PThreadStateCanceling; sp->cancelState = PTHREAD_CANCEL_DISABLE; ResetEvent (sp->cancelEvent); - (void) pthread_mutex_unlock (&sp->cancelLock); + ptw32_mcs_lock_release (&stateLock); ptw32_throw (PTW32_EPS_CANCEL); /* Never reached */ } - (void) pthread_mutex_unlock (&sp->cancelLock); + ptw32_mcs_lock_release (&stateLock); return (result); diff --git a/pthreads/pthread_setschedparam.c b/pthreads/pthread_setschedparam.c index a122eaca6..b762753cd 100644 --- a/pthreads/pthread_setschedparam.c +++ b/pthreads/pthread_setschedparam.c @@ -71,7 +71,8 @@ int ptw32_setthreadpriority (pthread_t thread, int policy, int priority) { int prio; - int result; + ptw32_mcs_local_node_t threadLock; + int result = 0; ptw32_thread_t * tp = (ptw32_thread_t *) thread.p; prio = priority; @@ -100,26 +101,23 @@ ptw32_setthreadpriority (pthread_t thread, int policy, int priority) #endif - result = pthread_mutex_lock (&tp->threadLock); + ptw32_mcs_lock_acquire (&tp->threadLock, &threadLock); - if (0 == result) + /* If this fails, the current priority is unchanged. */ + if (0 == SetThreadPriority (tp->threadH, prio)) + { + result = EINVAL; + } + else { - /* If this fails, the current priority is unchanged. */ - if (0 == SetThreadPriority (tp->threadH, prio)) - { - result = EINVAL; - } - else - { - /* - * Must record the thread's sched_priority as given, - * not as finally adjusted. - */ - tp->sched_priority = priority; - } - - (void) pthread_mutex_unlock (&tp->threadLock); + /* + * Must record the thread's sched_priority as given, + * not as finally adjusted. + */ + tp->sched_priority = priority; } + ptw32_mcs_lock_release (&threadLock); + return result; } diff --git a/pthreads/pthread_setspecific.c b/pthreads/pthread_setspecific.c index 23aa81b5f..0f29e704a 100644 --- a/pthreads/pthread_setspecific.c +++ b/pthreads/pthread_setspecific.c @@ -1,168 +1,167 @@ -/* - * pthread_setspecific.c - * - * Description: - * POSIX thread functions which implement thread-specific data (TSD). - * - * -------------------------------------------------------------------------- - * - * 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" - - -int -pthread_setspecific (pthread_key_t key, const void *value) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function sets the value of the thread specific - * key in the calling thread. - * - * PARAMETERS - * key - * an instance of pthread_key_t - * value - * the value to set key to - * - * - * DESCRIPTION - * This function sets the value of the thread specific - * key in the calling thread. - * - * RESULTS - * 0 successfully set value - * EAGAIN could not set value - * ENOENT SERIOUS!! - * - * ------------------------------------------------------ - */ -{ - pthread_t self; - int result = 0; - - if (key != ptw32_selfThreadKey) - { - /* - * Using pthread_self will implicitly create - * an instance of pthread_t for the current - * thread if one wasn't explicitly created - */ - self = pthread_self (); - if (self.p == NULL) - { - return ENOENT; - } - } - else - { - /* - * Resolve catch-22 of registering thread with selfThread - * key - */ - ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); - - if (sp == NULL) - { - if (value == NULL) - { - return ENOENT; - } - self = *((pthread_t *) value); - } - else - { - self = sp->ptHandle; - } - } - - result = 0; - - if (key != NULL) - { - if (self.p != NULL && key->destructor != NULL && value != NULL) - { - /* - * Only require associations if we have to - * call user destroy routine. - * Don't need to locate an existing association - * when setting data to NULL for WIN32 since the - * data is stored with the operating system; not - * on the association; setting assoc to NULL short - * circuits the search. - */ - ThreadKeyAssoc *assoc; - - if (pthread_mutex_lock(&(key->keyLock)) == 0) - { - ptw32_thread_t * sp = (ptw32_thread_t *) self.p; - - (void) pthread_mutex_lock(&(sp->threadLock)); - - assoc = (ThreadKeyAssoc *) sp->keys; - /* - * Locate existing association - */ - while (assoc != NULL) - { - if (assoc->key == key) - { - /* - * Association already exists - */ - break; - } - assoc = assoc->nextKey; - } - - /* - * create an association if not found - */ - if (assoc == NULL) - { - result = ptw32_tkAssocCreate (sp, key); - } - - (void) pthread_mutex_unlock(&(sp->threadLock)); - } - (void) pthread_mutex_unlock(&(key->keyLock)); - } - - if (result == 0) - { - if (!TlsSetValue (key->key, (LPVOID) value)) - { - result = EAGAIN; - } - } - } - - return (result); -} /* pthread_setspecific */ +/* + * pthread_setspecific.c + * + * Description: + * POSIX thread functions which implement thread-specific data (TSD). + * + * -------------------------------------------------------------------------- + * + * 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" + + +int +pthread_setspecific (pthread_key_t key, const void *value) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function sets the value of the thread specific + * key in the calling thread. + * + * PARAMETERS + * key + * an instance of pthread_key_t + * value + * the value to set key to + * + * + * DESCRIPTION + * This function sets the value of the thread specific + * key in the calling thread. + * + * RESULTS + * 0 successfully set value + * EAGAIN could not set value + * ENOENT SERIOUS!! + * + * ------------------------------------------------------ + */ +{ + pthread_t self; + int result = 0; + + if (key != ptw32_selfThreadKey) + { + /* + * Using pthread_self will implicitly create + * an instance of pthread_t for the current + * thread if one wasn't explicitly created + */ + self = pthread_self (); + if (self.p == NULL) + { + return ENOENT; + } + } + else + { + /* + * Resolve catch-22 of registering thread with selfThread + * key + */ + ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); + + if (sp == NULL) + { + if (value == NULL) + { + return ENOENT; + } + self = *((pthread_t *) value); + } + else + { + self = sp->ptHandle; + } + } + + result = 0; + + if (key != NULL) + { + if (self.p != NULL && key->destructor != NULL && value != NULL) + { + ptw32_mcs_local_node_t keyLock; + ptw32_mcs_local_node_t threadLock; + ptw32_thread_t * sp = (ptw32_thread_t *) self.p; + /* + * Only require associations if we have to + * call user destroy routine. + * Don't need to locate an existing association + * when setting data to NULL for WIN32 since the + * data is stored with the operating system; not + * on the association; setting assoc to NULL short + * circuits the search. + */ + ThreadKeyAssoc *assoc; + + ptw32_mcs_lock_acquire(&(key->keyLock), &keyLock); + ptw32_mcs_lock_acquire(&(sp->threadLock), &threadLock); + + assoc = (ThreadKeyAssoc *) sp->keys; + /* + * Locate existing association + */ + while (assoc != NULL) + { + if (assoc->key == key) + { + /* + * Association already exists + */ + break; + } + assoc = assoc->nextKey; + } + + /* + * create an association if not found + */ + if (assoc == NULL) + { + result = ptw32_tkAssocCreate (sp, key); + } + + ptw32_mcs_lock_release(&threadLock); + ptw32_mcs_lock_release(&keyLock); + } + + if (result == 0) + { + if (!TlsSetValue (key->key, (LPVOID) value)) + { + result = EAGAIN; + } + } + } + + return (result); +} /* pthread_setspecific */ diff --git a/pthreads/pthread_spin_destroy.c b/pthreads/pthread_spin_destroy.c index 8fe22674d..786c4e34c 100644 --- a/pthreads/pthread_spin_destroy.c +++ b/pthreads/pthread_spin_destroy.c @@ -56,12 +56,9 @@ pthread_spin_destroy (pthread_spinlock_t * lock) result = pthread_mutex_destroy (&(s->u.mutex)); } else if ((PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED != - PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG) - & (s->interlock), - (PTW32_INTERLOCKED_LONG) - PTW32_OBJECT_INVALID, - (PTW32_INTERLOCKED_LONG) - PTW32_SPIN_UNLOCKED)) + PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR) &s->interlock, + (PTW32_INTERLOCKED_LONG) PTW32_SPIN_INVALID, + (PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED)) { result = EINVAL; } @@ -81,7 +78,9 @@ pthread_spin_destroy (pthread_spinlock_t * lock) /* * See notes in ptw32_spinlock_check_need_init() above also. */ - EnterCriticalSection (&ptw32_spinlock_test_init_lock); + ptw32_mcs_local_node_t node; + + ptw32_mcs_lock_acquire(&ptw32_spinlock_test_init_lock, &node); /* * Check again. @@ -105,7 +104,7 @@ pthread_spin_destroy (pthread_spinlock_t * lock) result = EBUSY; } - LeaveCriticalSection (&ptw32_spinlock_test_init_lock); + ptw32_mcs_lock_release(&node); } return (result); diff --git a/pthreads/pthread_spin_lock.c b/pthreads/pthread_spin_lock.c index 90b3abee4..b560e1489 100644 --- a/pthreads/pthread_spin_lock.c +++ b/pthreads/pthread_spin_lock.c @@ -61,12 +61,9 @@ pthread_spin_lock (pthread_spinlock_t * lock) s = *lock; while ((PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED == - PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG) & - (s->interlock), - (PTW32_INTERLOCKED_LONG) - PTW32_SPIN_LOCKED, - (PTW32_INTERLOCKED_LONG) - PTW32_SPIN_UNLOCKED)) + PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR) &s->interlock, + (PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED, + (PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED)) { } diff --git a/pthreads/pthread_spin_trylock.c b/pthreads/pthread_spin_trylock.c index c601a191f..a6c65aff6 100644 --- a/pthreads/pthread_spin_trylock.c +++ b/pthreads/pthread_spin_trylock.c @@ -61,12 +61,9 @@ pthread_spin_trylock (pthread_spinlock_t * lock) s = *lock; switch ((long) - PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG) & - (s->interlock), - (PTW32_INTERLOCKED_LONG) - PTW32_SPIN_LOCKED, - (PTW32_INTERLOCKED_LONG) - PTW32_SPIN_UNLOCKED)) + PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR) &s->interlock, + (PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED, + (PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED)) { case PTW32_SPIN_UNLOCKED: return 0; diff --git a/pthreads/pthread_spin_unlock.c b/pthreads/pthread_spin_unlock.c index 67bc2c218..3a6932aef 100644 --- a/pthreads/pthread_spin_unlock.c +++ b/pthreads/pthread_spin_unlock.c @@ -56,17 +56,13 @@ pthread_spin_unlock (pthread_spinlock_t * lock) } switch ((long) - PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG) & - (s->interlock), - (PTW32_INTERLOCKED_LONG) - PTW32_SPIN_UNLOCKED, - (PTW32_INTERLOCKED_LONG) - PTW32_SPIN_LOCKED)) + PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG ((PTW32_INTERLOCKED_LONGPTR) &s->interlock, + (PTW32_INTERLOCKED_LONG) PTW32_SPIN_UNLOCKED, + (PTW32_INTERLOCKED_LONG) PTW32_SPIN_LOCKED)) { case PTW32_SPIN_LOCKED: - return 0; case PTW32_SPIN_UNLOCKED: - return EPERM; + return 0; case PTW32_SPIN_USE_MUTEX: return pthread_mutex_unlock (&(s->u.mutex)); } diff --git a/pthreads/pthread_testcancel.c b/pthreads/pthread_testcancel.c index 7a9980bcd..665865000 100644 --- a/pthreads/pthread_testcancel.c +++ b/pthreads/pthread_testcancel.c @@ -1,102 +1,103 @@ -/* - * pthread_testcancel.c - * - * Description: - * POSIX thread functions related to thread cancellation. - * - * -------------------------------------------------------------------------- - * - * 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" - - -void -pthread_testcancel (void) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function creates a deferred cancellation point - * in the calling thread. The call has no effect if the - * current cancelability state is - * PTHREAD_CANCEL_DISABLE - * - * PARAMETERS - * N/A - * - * - * DESCRIPTION - * This function creates a deferred cancellation point - * in the calling thread. The call has no effect if the - * current cancelability state is - * PTHREAD_CANCEL_DISABLE - * - * NOTES: - * 1) Cancellation is asynchronous. Use pthread_join - * to wait for termination of thread if necessary - * - * RESULTS - * N/A - * - * ------------------------------------------------------ - */ -{ - pthread_t self = pthread_self (); - ptw32_thread_t * sp = (ptw32_thread_t *) self.p; - - if (sp == NULL) - { - return; - } - - /* - * Pthread_cancel() will have set sp->state to PThreadStateCancelPending - * and set an event, so no need to enter kernel space if - * sp->state != PThreadStateCancelPending - that only slows us down. - */ - if (sp->state != PThreadStateCancelPending) - { - return; - } - - (void) pthread_mutex_lock (&sp->cancelLock); - - if (sp->cancelState != PTHREAD_CANCEL_DISABLE) - { - ResetEvent(sp->cancelEvent); - sp->state = PThreadStateCanceling; - sp->cancelState = PTHREAD_CANCEL_DISABLE; - (void) pthread_mutex_unlock (&sp->cancelLock); - ptw32_throw (PTW32_EPS_CANCEL); - /* Never returns here */ - } - - (void) pthread_mutex_unlock (&sp->cancelLock); -} /* pthread_testcancel */ +/* + * pthread_testcancel.c + * + * Description: + * POSIX thread functions related to thread cancellation. + * + * -------------------------------------------------------------------------- + * + * 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" + + +void +pthread_testcancel (void) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function creates a deferred cancellation point + * in the calling thread. The call has no effect if the + * current cancelability state is + * PTHREAD_CANCEL_DISABLE + * + * PARAMETERS + * N/A + * + * + * DESCRIPTION + * This function creates a deferred cancellation point + * in the calling thread. The call has no effect if the + * current cancelability state is + * PTHREAD_CANCEL_DISABLE + * + * NOTES: + * 1) Cancellation is asynchronous. Use pthread_join + * to wait for termination of thread if necessary + * + * RESULTS + * N/A + * + * ------------------------------------------------------ + */ +{ + ptw32_mcs_local_node_t stateLock; + pthread_t self = pthread_self (); + ptw32_thread_t * sp = (ptw32_thread_t *) self.p; + + if (sp == NULL) + { + return; + } + + /* + * Pthread_cancel() will have set sp->state to PThreadStateCancelPending + * and set an event, so no need to enter kernel space if + * sp->state != PThreadStateCancelPending - that only slows us down. + */ + if (sp->state != PThreadStateCancelPending) + { + return; + } + + ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock); + + if (sp->cancelState != PTHREAD_CANCEL_DISABLE) + { + ResetEvent(sp->cancelEvent); + sp->state = PThreadStateCanceling; + sp->cancelState = PTHREAD_CANCEL_DISABLE; + ptw32_mcs_lock_release (&stateLock); + ptw32_throw (PTW32_EPS_CANCEL); + /* Never returns here */ + } + + ptw32_mcs_lock_release (&stateLock); +} /* pthread_testcancel */ diff --git a/pthreads/pthread_timechange_handler_np.c b/pthreads/pthread_timechange_handler_np.c index 7d8170a3f..0f97e74f1 100644 --- a/pthreads/pthread_timechange_handler_np.c +++ b/pthreads/pthread_timechange_handler_np.c @@ -90,8 +90,9 @@ pthread_timechange_handler_np (void *arg) { int result = 0; pthread_cond_t cv; + ptw32_mcs_local_node_t node; - EnterCriticalSection (&ptw32_cond_list_lock); + ptw32_mcs_lock_acquire(&ptw32_cond_list_lock, &node); cv = ptw32_cond_list_head; @@ -101,7 +102,7 @@ pthread_timechange_handler_np (void *arg) cv = cv->next; } - LeaveCriticalSection (&ptw32_cond_list_lock); + ptw32_mcs_lock_release(&node); - return (void *) (result != 0 ? EAGAIN : 0); + return (void *) (size_t) (result != 0 ? EAGAIN : 0); } diff --git a/pthreads/pthread_win32_attach_detach_np.c b/pthreads/pthread_win32_attach_detach_np.c index cdb5a73b4..bfad45065 100644 --- a/pthreads/pthread_win32_attach_detach_np.c +++ b/pthreads/pthread_win32_attach_detach_np.c @@ -1,314 +1,256 @@ -/* - * pthread_win32_attach_detach_np.c - * - * Description: - * This translation unit implements non-portable 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 - */ - -#include "pthread.h" -#include "implement.h" - -/* - * Handle to kernel32.dll - */ -static HINSTANCE ptw32_h_kernel32; - -/* - * Handle to quserex.dll - */ -static HINSTANCE ptw32_h_quserex; - -BOOL -pthread_win32_process_attach_np () -{ - BOOL result = TRUE; - DWORD_PTR vProcessCPUs; - DWORD_PTR vSystemCPUs; - - result = ptw32_processInitialize (); - -#ifdef _UWIN - pthread_count++; -#endif - - ptw32_features = 0; - - -#if defined(NEED_PROCESS_AFFINITY_MASK) - - ptw32_smp_system = PTW32_FALSE; - -#else - - if (GetProcessAffinityMask (GetCurrentProcess (), - &vProcessCPUs, &vSystemCPUs)) - { - int CPUs = 0; - DWORD_PTR bit; - - for (bit = 1; bit != 0; bit <<= 1) - { - if (vSystemCPUs & bit) - { - CPUs++; - } - } - ptw32_smp_system = (CPUs > 1); - } - else - { - ptw32_smp_system = PTW32_FALSE; - } - -#endif - -#ifdef _WIN64 - -/* - * InterlockedCompareExchange routine in WIN64 is an intrinsic function. - * See PTW32_INTERLOCKED_COMPARE_EXCHANGE implement.h - */ - -#else - -#ifdef WINCE - - /* - * Load COREDLL and try to get address of InterlockedCompareExchange - */ - ptw32_h_kernel32 = LoadLibrary (TEXT ("COREDLL.DLL")); - -#else - - /* - * Load KERNEL32 and try to get address of InterlockedCompareExchange - */ - ptw32_h_kernel32 = LoadLibrary (TEXT ("KERNEL32.DLL")); - -#endif - - ptw32_interlocked_compare_exchange = - (PTW32_INTERLOCKED_LONG (WINAPI *) - (PTW32_INTERLOCKED_LPLONG, PTW32_INTERLOCKED_LONG, - PTW32_INTERLOCKED_LONG)) -#if defined(NEED_UNICODE_CONSTS) - GetProcAddress (ptw32_h_kernel32, - (const TCHAR *) TEXT ("InterlockedCompareExchange")); -#else - GetProcAddress (ptw32_h_kernel32, (LPCSTR) "InterlockedCompareExchange"); -#endif - - if (ptw32_interlocked_compare_exchange == NULL) - { - ptw32_interlocked_compare_exchange = ptw32_InterlockedCompareExchange; - - /* - * If InterlockedCompareExchange 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 InterlockedCompareExchange, the bug will be - * effortlessly avoided. - */ - (void) FreeLibrary (ptw32_h_kernel32); - ptw32_h_kernel32 = 0; - } - else - { - ptw32_features |= PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE; - } - -#endif - - /* - * Load QUSEREX.DLL and try to get address of QueueUserAPCEx - */ - ptw32_h_quserex = LoadLibrary (TEXT ("QUSEREX.DLL")); - - if (ptw32_h_quserex != NULL) - { - ptw32_register_cancelation = (DWORD (*)(PAPCFUNC, HANDLE, DWORD)) -#if defined(NEED_UNICODE_CONSTS) - GetProcAddress (ptw32_h_quserex, - (const TCHAR *) TEXT ("QueueUserAPCEx")); -#else - GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx"); -#endif - } - - if (NULL == ptw32_register_cancelation) - { - ptw32_register_cancelation = ptw32_RegisterCancelation; - - if (ptw32_h_quserex != NULL) - { - (void) FreeLibrary (ptw32_h_quserex); - } - ptw32_h_quserex = 0; - } - else - { - /* Initialise QueueUserAPCEx */ - BOOL (*queue_user_apc_ex_init) (VOID); - - queue_user_apc_ex_init = (BOOL (*)(VOID)) -#if defined(NEED_UNICODE_CONSTS) - GetProcAddress (ptw32_h_quserex, - (const TCHAR *) TEXT ("QueueUserAPCEx_Init")); -#else - GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx_Init"); -#endif - - if (queue_user_apc_ex_init == NULL || !queue_user_apc_ex_init ()) - { - ptw32_register_cancelation = ptw32_RegisterCancelation; - - (void) FreeLibrary (ptw32_h_quserex); - ptw32_h_quserex = 0; - } - } - - if (ptw32_h_quserex) - { - ptw32_features |= PTW32_ALERTABLE_ASYNC_CANCEL; - } - - return result; -} - - -BOOL -pthread_win32_process_detach_np () -{ - if (ptw32_processInitialized) - { - ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); - - if (sp != NULL) - { - /* - * Detached threads have their resources automatically - * cleaned up upon exit (others must be 'joined'). - */ - if (sp->detachState == PTHREAD_CREATE_DETACHED) - { - ptw32_threadDestroy (sp->ptHandle); - TlsSetValue (ptw32_selfThreadKey->key, NULL); - } - } - - /* - * The DLL is being unmapped from the process's address space - */ - ptw32_processTerminate (); - - if (ptw32_h_quserex) - { - /* Close QueueUserAPCEx */ - BOOL (*queue_user_apc_ex_fini) (VOID); - - queue_user_apc_ex_fini = (BOOL (*)(VOID)) -#if defined(NEED_UNICODE_CONSTS) - GetProcAddress (ptw32_h_quserex, - (const TCHAR *) TEXT ("QueueUserAPCEx_Fini")); -#else - GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx_Fini"); -#endif - - if (queue_user_apc_ex_fini != NULL) - { - (void) queue_user_apc_ex_fini (); - } - (void) FreeLibrary (ptw32_h_quserex); - } - - if (ptw32_h_kernel32) - { - (void) FreeLibrary (ptw32_h_kernel32); - } - } - - return TRUE; -} - -BOOL -pthread_win32_thread_attach_np () -{ - return TRUE; -} - -BOOL -pthread_win32_thread_detach_np () -{ - if (ptw32_processInitialized) - { - /* - * Don't use pthread_self() - to avoid creating an implicit POSIX thread handle - * unnecessarily. - */ - ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); - - if (sp != NULL) // otherwise Win32 thread with no implicit POSIX handle. - { - ptw32_callUserDestroyRoutines (sp->ptHandle); - - (void) pthread_mutex_lock (&sp->cancelLock); - sp->state = PThreadStateLast; - /* - * If the thread is joinable at this point then it MUST be joined - * or detached explicitly by the application. - */ - (void) pthread_mutex_unlock (&sp->cancelLock); - - if (sp->detachState == PTHREAD_CREATE_DETACHED) - { - ptw32_threadDestroy (sp->ptHandle); - - TlsSetValue (ptw32_selfThreadKey->key, NULL); - } - } - } - - return TRUE; -} - -BOOL -pthread_win32_test_features_np (int feature_mask) -{ - return ((ptw32_features & feature_mask) == feature_mask); -} +/* + * pthread_win32_attach_detach_np.c + * + * Description: + * This translation unit implements non-portable 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 + */ + +#include "pthread.h" +#include "implement.h" + +/* + * Handle to quserex.dll + */ +static HINSTANCE ptw32_h_quserex; + +BOOL +pthread_win32_process_attach_np () +{ + TCHAR QuserExDLLPathBuf[1024]; + BOOL result = TRUE; + + result = ptw32_processInitialize (); + +#if defined(_UWIN) + pthread_count++; +#endif + +#if defined(__GNUC__) + ptw32_features = 0; +#else + /* + * This is obsolete now. + */ + ptw32_features = PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE; +#endif + + /* + * Load QUSEREX.DLL and try to get address of QueueUserAPCEx. + * Because QUSEREX.DLL requires a driver to be installed we will + * assume the DLL is in the system directory. + * + * This should take care of any security issues. + */ +#if defined(__GNUC__) || _MSC_VER < 1400 + if(GetSystemDirectory(QuserExDLLPathBuf, sizeof(QuserExDLLPathBuf))) + { + (void) strncat(QuserExDLLPathBuf, + "\\QUSEREX.DLL", + sizeof(QuserExDLLPathBuf) - strlen(QuserExDLLPathBuf) - 1); + ptw32_h_quserex = LoadLibrary(QuserExDLLPathBuf); + } +#else + /* strncat is secure - this is just to avoid a warning */ + if(GetSystemDirectory(QuserExDLLPathBuf, sizeof(QuserExDLLPathBuf)) && + 0 == strncat_s(QuserExDLLPathBuf, sizeof(QuserExDLLPathBuf), "\\QUSEREX.DLL", 12)) + { + ptw32_h_quserex = LoadLibrary(QuserExDLLPathBuf); + } +#endif + + if (ptw32_h_quserex != NULL) + { + ptw32_register_cancelation = (DWORD (*)(PAPCFUNC, HANDLE, DWORD)) +#if defined(NEED_UNICODE_CONSTS) + GetProcAddress (ptw32_h_quserex, + (const TCHAR *) TEXT ("QueueUserAPCEx")); +#else + GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx"); +#endif + } + + if (NULL == ptw32_register_cancelation) + { + ptw32_register_cancelation = ptw32_RegisterCancelation; + + if (ptw32_h_quserex != NULL) + { + (void) FreeLibrary (ptw32_h_quserex); + } + ptw32_h_quserex = 0; + } + else + { + /* Initialise QueueUserAPCEx */ + BOOL (*queue_user_apc_ex_init) (VOID); + + queue_user_apc_ex_init = (BOOL (*)(VOID)) +#if defined(NEED_UNICODE_CONSTS) + GetProcAddress (ptw32_h_quserex, + (const TCHAR *) TEXT ("QueueUserAPCEx_Init")); +#else + GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx_Init"); +#endif + + if (queue_user_apc_ex_init == NULL || !queue_user_apc_ex_init ()) + { + ptw32_register_cancelation = ptw32_RegisterCancelation; + + (void) FreeLibrary (ptw32_h_quserex); + ptw32_h_quserex = 0; + } + } + + if (ptw32_h_quserex) + { + ptw32_features |= PTW32_ALERTABLE_ASYNC_CANCEL; + } + + return result; +} + + +BOOL +pthread_win32_process_detach_np () +{ + if (ptw32_processInitialized) + { + ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); + + if (sp != NULL) + { + /* + * Detached threads have their resources automatically + * cleaned up upon exit (others must be 'joined'). + */ + if (sp->detachState == PTHREAD_CREATE_DETACHED) + { + ptw32_threadDestroy (sp->ptHandle); + TlsSetValue (ptw32_selfThreadKey->key, NULL); + } + } + + /* + * The DLL is being unmapped from the process's address space + */ + ptw32_processTerminate (); + + if (ptw32_h_quserex) + { + /* Close QueueUserAPCEx */ + BOOL (*queue_user_apc_ex_fini) (VOID); + + queue_user_apc_ex_fini = (BOOL (*)(VOID)) +#if defined(NEED_UNICODE_CONSTS) + GetProcAddress (ptw32_h_quserex, + (const TCHAR *) TEXT ("QueueUserAPCEx_Fini")); +#else + GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx_Fini"); +#endif + + if (queue_user_apc_ex_fini != NULL) + { + (void) queue_user_apc_ex_fini (); + } + (void) FreeLibrary (ptw32_h_quserex); + } + } + + return TRUE; +} + +BOOL +pthread_win32_thread_attach_np () +{ + return TRUE; +} + +BOOL +pthread_win32_thread_detach_np () +{ + if (ptw32_processInitialized) + { + /* + * Don't use pthread_self() - to avoid creating an implicit POSIX thread handle + * unnecessarily. + */ + ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); + + if (sp != NULL) // otherwise Win32 thread with no implicit POSIX handle. + { + ptw32_mcs_local_node_t stateLock; + ptw32_callUserDestroyRoutines (sp->ptHandle); + + ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock); + sp->state = PThreadStateLast; + /* + * If the thread is joinable at this point then it MUST be joined + * or detached explicitly by the application. + */ + ptw32_mcs_lock_release (&stateLock); + + /* + * Robust Mutexes + */ + while (sp->robustMxList != NULL) + { + pthread_mutex_t mx = sp->robustMxList->mx; + ptw32_robust_mutex_remove(&mx, sp); + (void) PTW32_INTERLOCKED_EXCHANGE_LONG( + (PTW32_INTERLOCKED_LONGPTR)&mx->robustNode->stateInconsistent, + (PTW32_INTERLOCKED_LONG)-1); + /* + * If there are no waiters then the next thread to block will + * sleep, wakeup immediately and then go back to sleep. + * See pthread_mutex_lock.c. + */ + SetEvent(mx->event); + } + + + if (sp->detachState == PTHREAD_CREATE_DETACHED) + { + ptw32_threadDestroy (sp->ptHandle); + + TlsSetValue (ptw32_selfThreadKey->key, NULL); + } + } + } + + return TRUE; +} + +BOOL +pthread_win32_test_features_np (int feature_mask) +{ + return ((ptw32_features & feature_mask) == feature_mask); +} diff --git a/pthreads/ptw32_InterlockedCompareExchange.c b/pthreads/ptw32_InterlockedCompareExchange.c deleted file mode 100644 index 34ebfce22..000000000 --- a/pthreads/ptw32_InterlockedCompareExchange.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * ptw32_InterlockedCompareExchange.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 - */ - -#ifndef _WIN64 - -#include "pthread.h" -#include "implement.h" - - -/* - * ptw32_InterlockedCompareExchange -- - * - * Originally needed because W9x doesn't support InterlockedCompareExchange. - * We now use this version wherever possible so we can inline it. - */ - -PTW32_INTERLOCKED_LONG WINAPI -ptw32_InterlockedCompareExchange (PTW32_INTERLOCKED_LPLONG location, - PTW32_INTERLOCKED_LONG value, - PTW32_INTERLOCKED_LONG comparand) -{ - -#if defined(__WATCOMC__) -/* Don't report that result is not assigned a value before being referenced */ -#pragma disable_message (200) -#endif - - PTW32_INTERLOCKED_LONG result; - - /* - * Using the LOCK prefix on uni-processor machines is significantly slower - * and it is not necessary. The overhead of the conditional below is - * negligible in comparison. Since an optimised DLL will inline this - * routine, this will be faster than calling the system supplied - * Interlocked routine, which appears to avoid the LOCK prefix on - * uniprocessor systems. So one DLL works for all systems. - */ - if (ptw32_smp_system) - -/* *INDENT-OFF* */ - -#if defined(_M_IX86) || defined(_X86_) - -#if defined(_MSC_VER) || defined(__WATCOMC__) || (defined(__BORLANDC__) && defined(HAVE_TASM32)) -#define HAVE_INLINABLE_INTERLOCKED_CMPXCHG - { - _asm { - PUSH ecx - PUSH edx - MOV ecx,dword ptr [location] - MOV edx,dword ptr [value] - MOV eax,dword ptr [comparand] - LOCK CMPXCHG dword ptr [ecx],edx - MOV dword ptr [result], eax - POP edx - POP ecx - } - } - else - { - _asm { - PUSH ecx - PUSH edx - MOV ecx,dword ptr [location] - MOV edx,dword ptr [value] - MOV eax,dword ptr [comparand] - CMPXCHG dword ptr [ecx],edx - MOV dword ptr [result], eax - POP edx - POP ecx - } - } - -#elif defined(__GNUC__) -#define HAVE_INLINABLE_INTERLOCKED_CMPXCHG - - { - __asm__ __volatile__ - ( - "lock\n\t" - "cmpxchgl %2,%1" /* if (EAX == [location]) */ - /* [location] = value */ - /* else */ - /* EAX = [location] */ - :"=a" (result) - :"m" (*location), "r" (value), "a" (comparand)); - } - else - { - __asm__ __volatile__ - ( - "cmpxchgl %2,%1" /* if (EAX == [location]) */ - /* [location] = value */ - /* else */ - /* EAX = [location] */ - :"=a" (result) - :"m" (*location), "r" (value), "a" (comparand)); - } - -#endif - -#else - - /* - * If execution gets to here then we're running on a currently - * unsupported processor or compiler. - */ - -#error Unsupported platform or compiler! - -#endif - -/* *INDENT-ON* */ - - return result; - -#if defined(__WATCOMC__) -#pragma enable_message (200) -#endif - -} - -/* - * ptw32_InterlockedExchange -- - * - * We now use this version wherever possible so we can inline it. - */ - -LONG WINAPI -ptw32_InterlockedExchange (LPLONG location, - LONG value) -{ - -#if defined(__WATCOMC__) -/* Don't report that result is not assigned a value before being referenced */ -#pragma disable_message (200) -#endif - - LONG result; - - /* - * The XCHG instruction always locks the bus with or without the - * LOCKED prefix. This makes it significantly slower than CMPXCHG on - * uni-processor machines. The Windows InterlockedExchange function - * is nearly 3 times faster than the XCHG instruction, so this routine - * is not yet very useful for speeding up pthreads. - */ - if (ptw32_smp_system) - -/* *INDENT-OFF* */ - -#if defined(_M_IX86) || defined(_X86_) - -#if defined(_MSC_VER) || defined(__WATCOMC__) || (defined(__BORLANDC__) && defined(HAVE_TASM32)) -#define HAVE_INLINABLE_INTERLOCKED_XCHG - - { - _asm { - PUSH ecx - MOV ecx,dword ptr [location] - MOV eax,dword ptr [value] - XCHG dword ptr [ecx],eax - MOV dword ptr [result], eax - POP ecx - } - } - else - { - /* - * Faster version of XCHG for uni-processor systems because - * it doesn't lock the bus. If an interrupt or context switch - * occurs between the MOV and the CMPXCHG then the value in - * 'location' may have changed, in which case we will loop - * back to do the MOV again. - * - * FIXME! Need memory barriers for the MOV+CMPXCHG combo? - * - * Tests show that this routine has almost identical timing - * to Win32's InterlockedExchange(), which is much faster than - * using the inlined 'xchg' instruction above, so it's probably - * doing something similar to this (on UP systems). - * - * Can we do without the PUSH/POP instructions? - */ - _asm { - PUSH ecx - PUSH edx - MOV ecx,dword ptr [location] - MOV edx,dword ptr [value] -L1: MOV eax,dword ptr [ecx] - CMPXCHG dword ptr [ecx],edx - JNZ L1 - MOV dword ptr [result], eax - POP edx - POP ecx - } - } - -#elif defined(__GNUC__) -#define HAVE_INLINABLE_INTERLOCKED_XCHG - - { - __asm__ __volatile__ - ( - "xchgl %2,%1" - :"=r" (result) - :"m" (*location), "0" (value)); - } - else - { - /* - * Faster version of XCHG for uni-processor systems because - * it doesn't lock the bus. If an interrupt or context switch - * occurs between the movl and the cmpxchgl then the value in - * 'location' may have changed, in which case we will loop - * back to do the movl again. - * - * FIXME! Need memory barriers for the MOV+CMPXCHG combo? - * - * Tests show that this routine has almost identical timing - * to Win32's InterlockedExchange(), and is much faster than - * using an inlined 'xchg' instruction, so Win32 is probably - * doing something similar to this (on UP systems). - */ - __asm__ __volatile__ - ( - "0:\n\t" - "movl %1,%%eax\n\t" - "cmpxchgl %2,%1\n\t" - "jnz 0b" - :"=&a" (result) - :"m" (*location), "r" (value)); - } - -#endif - -#else - - /* - * If execution gets to here then we're running on a currently - * unsupported processor or compiler. - */ - -#error Unsupported platform or compiler! - -#endif - -/* *INDENT-ON* */ - - return result; - -#if defined(__WATCOMC__) -#pragma enable_message (200) -#endif - -} - - -#if 1 - -#if defined(PTW32_BUILD_INLINED) && defined(HAVE_INLINABLE_INTERLOCKED_CMPXCHG) -#undef PTW32_INTERLOCKED_COMPARE_EXCHANGE -#define PTW32_INTERLOCKED_COMPARE_EXCHANGE ptw32_InterlockedCompareExchange -#endif - -#if defined(PTW32_BUILD_INLINED) && defined(HAVE_INLINABLE_INTERLOCKED_XCHG) -#undef PTW32_INTERLOCKED_EXCHANGE -#define PTW32_INTERLOCKED_EXCHANGE ptw32_InterlockedExchange -#endif - -#endif - -#endif diff --git a/pthreads/ptw32_MCS_lock.c b/pthreads/ptw32_MCS_lock.c index 270c31e9c..d69cf80eb 100644 --- a/pthreads/ptw32_MCS_lock.c +++ b/pthreads/ptw32_MCS_lock.c @@ -1,263 +1,278 @@ -/* - * ptw32_MCS_lock.c - * - * Description: - * This translation unit implements queue-based locks. - * - * -------------------------------------------------------------------------- - * - * 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 - */ - -/* - * About MCS locks: - * - * MCS locks are queue-based locks, where the queue nodes are local to the - * thread. The 'lock' is nothing more than a global pointer that points to - * the last node in the queue, or is NULL if the queue is empty. - * - * Originally designed for use as spin locks requiring no kernel resources - * for synchronisation or blocking, the implementation below has adapted - * the MCS spin lock for use as a general mutex that will suspend threads - * when there is lock contention. - * - * Because the queue nodes are thread-local, most of the memory read/write - * operations required to add or remove nodes from the queue do not trigger - * cache-coherence updates. - * - * Like 'named' mutexes, MCS locks consume system resources transiently - - * they are able to acquire and free resources automatically - but MCS - * locks do not require any unique 'name' to identify the lock to all - * threads using it. - * - * Usage of MCS locks: - * - * - you need a global ptw32_mcs_lock_t instance initialised to 0 or NULL. - * - you need a local thread-scope ptw32_mcs_local_node_t instance, which - * may serve several different locks but you need at least one node for - * every lock held concurrently by a thread. - * - * E.g.: - * - * ptw32_mcs_lock_t lock1 = 0; - * ptw32_mcs_lock_t lock2 = 0; - * - * void *mythread(void *arg) - * { - * ptw32_mcs_local_node_t node; - * - * ptw32_mcs_acquire (&lock1, &node); - * ptw32_mcs_release (&node); - * - * ptw32_mcs_acquire (&lock2, &node); - * ptw32_mcs_release (&node); - * { - * ptw32_mcs_local_node_t nodex; - * - * ptw32_mcs_acquire (&lock1, &node); - * ptw32_mcs_acquire (&lock2, &nodex); - * - * ptw32_mcs_release (&nodex); - * ptw32_mcs_release (&node); - * } - * return (void *)0; - * } - */ - -#include "implement.h" -#include "pthread.h" - -/* - * ptw32_mcs_flag_set -- notify another thread about an event. - * - * Set event if an event handle has been stored in the flag, and - * set flag to -1 otherwise. Note that -1 cannot be a valid handle value. - */ -INLINE void -ptw32_mcs_flag_set (LONG * flag) -{ - HANDLE e = (HANDLE)PTW32_INTERLOCKED_COMPARE_EXCHANGE( - (PTW32_INTERLOCKED_LPLONG)flag, - (PTW32_INTERLOCKED_LONG)-1, - (PTW32_INTERLOCKED_LONG)0); - if ((HANDLE)0 != e) - { - /* another thread has already stored an event handle in the flag */ - SetEvent(e); - } -} - -/* - * ptw32_mcs_flag_set -- wait for notification from another. - * - * Store an event handle in the flag and wait on it if the flag has not been - * set, and proceed without creating an event otherwise. - */ -INLINE void -ptw32_mcs_flag_wait (LONG * flag) -{ - if (0 == InterlockedExchangeAdd((LPLONG)flag, 0)) /* MBR fence */ - { - /* the flag is not set. create event. */ - - HANDLE e = CreateEvent(NULL, PTW32_FALSE, PTW32_FALSE, NULL); - - if (0 == PTW32_INTERLOCKED_COMPARE_EXCHANGE( - (PTW32_INTERLOCKED_LPLONG)flag, - (PTW32_INTERLOCKED_LONG)e, - (PTW32_INTERLOCKED_LONG)0)) - { - /* stored handle in the flag. wait on it now. */ - WaitForSingleObject(e, INFINITE); - } - - CloseHandle(e); - } -} - -/* - * ptw32_mcs_lock_acquire -- acquire an MCS lock. - * - * See: - * J. M. Mellor-Crummey and M. L. Scott. - * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors. - * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991. - */ -INLINE void -ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node) -{ - ptw32_mcs_local_node_t *pred; - - node->lock = lock; - node->nextFlag = 0; - node->readyFlag = 0; - node->next = 0; /* initially, no successor */ - - /* queue for the lock */ - pred = (ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_EXCHANGE((PTW32_INTERLOCKED_LPLONG)lock, - (PTW32_INTERLOCKED_LONG)node); - - if (0 != pred) - { - /* the lock was not free. link behind predecessor. */ - pred->next = node; - ptw32_mcs_flag_set(&pred->nextFlag); - ptw32_mcs_flag_wait(&node->readyFlag); - } -} - -/* - * ptw32_mcs_lock_release -- release an MCS lock. - * - * See: - * J. M. Mellor-Crummey and M. L. Scott. - * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors. - * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991. - */ -INLINE void -ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node) -{ - ptw32_mcs_lock_t *lock = node->lock; - ptw32_mcs_local_node_t *next = (ptw32_mcs_local_node_t *) - InterlockedExchangeAdd((LPLONG)&node->next, - (LONG)0); /* MBR fence */ - - if (0 == next) - { - /* no known successor */ - - if (node == (ptw32_mcs_local_node_t *) - PTW32_INTERLOCKED_COMPARE_EXCHANGE((PTW32_INTERLOCKED_LPLONG)lock, - (PTW32_INTERLOCKED_LONG)0, - (PTW32_INTERLOCKED_LONG)node)) - { - /* no successor, lock is free now */ - return; - } - - /* wait for successor */ - ptw32_mcs_flag_wait(&node->nextFlag); - next = (ptw32_mcs_local_node_t *) - InterlockedExchangeAdd((LPLONG)&node->next, 0); /* MBR fence */ - } - - /* pass the lock */ - ptw32_mcs_flag_set(&next->readyFlag); -} - -/* - * ptw32_mcs_lock_try_acquire - */ -INLINE int -ptw32_mcs_lock_try_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node) -{ - node->lock = lock; - node->nextFlag = 0; - node->readyFlag = 0; - node->next = 0; /* initially, no successor */ - - return ((PTW32_INTERLOCKED_LPLONG)PTW32_INTERLOCKED_COMPARE_EXCHANGE( - (PTW32_INTERLOCKED_LPLONG)lock, - (PTW32_INTERLOCKED_LONG)node, - (PTW32_INTERLOCKED_LONG)0) - == (PTW32_INTERLOCKED_LPLONG)0) ? 0 : EBUSY; -} - -/* - * ptw32_mcs_node_substitute -- move an MCS lock local node, usually from thread - * space to, for example, global space so that another thread can release - * the lock on behalf of the current lock owner. - * - * Example: used in pthread_barrier_wait where we want the last thread out of - * the barrier to release the lock owned by the last thread to enter the barrier - * (the one that releases all threads but not necessarily the last to leave). - * - * Should only be called by the thread that has the lock. - */ -INLINE void -ptw32_mcs_node_substitute (ptw32_mcs_local_node_t * new_node, ptw32_mcs_local_node_t * old_node) -{ - new_node->lock = old_node->lock; - new_node->nextFlag = 0; /* Not needed - used only in initial Acquire */ - new_node->readyFlag = 0; /* Not needed - we were waiting on this */ - new_node->next = 0; - - if ((ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_COMPARE_EXCHANGE((PTW32_INTERLOCKED_LPLONG)new_node->lock, - (PTW32_INTERLOCKED_LONG)new_node, - (PTW32_INTERLOCKED_LONG)old_node) != old_node) - { - /* - * A successor has queued after us, so wait for them to link to us - */ - while (old_node->next == 0) - { - Sleep(0); - } - new_node->next = old_node->next; - } -} +/* + * ptw32_MCS_lock.c + * + * Description: + * This translation unit implements queue-based locks. + * + * -------------------------------------------------------------------------- + * + * 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 + */ + +/* + * About MCS locks: + * + * MCS locks are queue-based locks, where the queue nodes are local to the + * thread. The 'lock' is nothing more than a global pointer that points to + * the last node in the queue, or is NULL if the queue is empty. + * + * Originally designed for use as spin locks requiring no kernel resources + * for synchronisation or blocking, the implementation below has adapted + * the MCS spin lock for use as a general mutex that will suspend threads + * when there is lock contention. + * + * Because the queue nodes are thread-local, most of the memory read/write + * operations required to add or remove nodes from the queue do not trigger + * cache-coherence updates. + * + * Like 'named' mutexes, MCS locks consume system resources transiently - + * they are able to acquire and free resources automatically - but MCS + * locks do not require any unique 'name' to identify the lock to all + * threads using it. + * + * Usage of MCS locks: + * + * - you need a global ptw32_mcs_lock_t instance initialised to 0 or NULL. + * - you need a local thread-scope ptw32_mcs_local_node_t instance, which + * may serve several different locks but you need at least one node for + * every lock held concurrently by a thread. + * + * E.g.: + * + * ptw32_mcs_lock_t lock1 = 0; + * ptw32_mcs_lock_t lock2 = 0; + * + * void *mythread(void *arg) + * { + * ptw32_mcs_local_node_t node; + * + * ptw32_mcs_acquire (&lock1, &node); + * ptw32_mcs_lock_release (&node); + * + * ptw32_mcs_lock_acquire (&lock2, &node); + * ptw32_mcs_lock_release (&node); + * { + * ptw32_mcs_local_node_t nodex; + * + * ptw32_mcs_lock_acquire (&lock1, &node); + * ptw32_mcs_lock_acquire (&lock2, &nodex); + * + * ptw32_mcs_lock_release (&nodex); + * ptw32_mcs_lock_release (&node); + * } + * return (void *)0; + * } + */ + +#include "pthread.h" +#include "sched.h" +#include "implement.h" + +/* + * ptw32_mcs_flag_set -- notify another thread about an event. + * + * Set event if an event handle has been stored in the flag, and + * set flag to -1 otherwise. Note that -1 cannot be a valid handle value. + */ +INLINE void +ptw32_mcs_flag_set (HANDLE * flag) +{ + HANDLE e = (HANDLE)(PTW32_INTERLOCKED_SIZE)PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE( + (PTW32_INTERLOCKED_SIZEPTR)flag, + (PTW32_INTERLOCKED_SIZE)-1, + (PTW32_INTERLOCKED_SIZE)0); + if ((HANDLE)0 != e) + { + /* another thread has already stored an event handle in the flag */ + SetEvent(e); + } +} + +/* + * ptw32_mcs_flag_set -- wait for notification from another. + * + * Store an event handle in the flag and wait on it if the flag has not been + * set, and proceed without creating an event otherwise. + */ +INLINE void +ptw32_mcs_flag_wait (HANDLE * flag) +{ + if ((PTW32_INTERLOCKED_LONG)0 == + PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)flag, + (PTW32_INTERLOCKED_SIZE)0)) /* MBR fence */ + { + /* the flag is not set. create event. */ + + HANDLE e = CreateEvent(NULL, PTW32_FALSE, PTW32_FALSE, NULL); + + if ((PTW32_INTERLOCKED_SIZE)0 == PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE( + (PTW32_INTERLOCKED_SIZEPTR)flag, + (PTW32_INTERLOCKED_SIZE)e, + (PTW32_INTERLOCKED_SIZE)0)) + { + /* stored handle in the flag. wait on it now. */ + WaitForSingleObject(e, INFINITE); + } + + CloseHandle(e); + } +} + +/* + * ptw32_mcs_lock_acquire -- acquire an MCS lock. + * + * See: + * J. M. Mellor-Crummey and M. L. Scott. + * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors. + * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991. + */ +#if defined(PTW32_BUILD_INLINED) +INLINE +#endif /* PTW32_BUILD_INLINED */ +void +ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node) +{ + ptw32_mcs_local_node_t *pred; + + node->lock = lock; + node->nextFlag = 0; + node->readyFlag = 0; + node->next = 0; /* initially, no successor */ + + /* queue for the lock */ + pred = (ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)lock, + (PTW32_INTERLOCKED_PVOID)node); + + if (0 != pred) + { + /* the lock was not free. link behind predecessor. */ + pred->next = node; + ptw32_mcs_flag_set(&pred->nextFlag); + ptw32_mcs_flag_wait(&node->readyFlag); + } +} + +/* + * ptw32_mcs_lock_release -- release an MCS lock. + * + * See: + * J. M. Mellor-Crummey and M. L. Scott. + * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors. + * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991. + */ +#if defined(PTW32_BUILD_INLINED) +INLINE +#endif /* PTW32_BUILD_INLINED */ +void +ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node) +{ + ptw32_mcs_lock_t *lock = node->lock; + ptw32_mcs_local_node_t *next = + (ptw32_mcs_local_node_t *) + PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)&node->next, (PTW32_INTERLOCKED_SIZE)0); /* MBR fence */ + + if (0 == next) + { + /* no known successor */ + + if (node == (ptw32_mcs_local_node_t *) + PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)lock, + (PTW32_INTERLOCKED_PVOID)0, + (PTW32_INTERLOCKED_PVOID)node)) + { + /* no successor, lock is free now */ + return; + } + + /* wait for successor */ + ptw32_mcs_flag_wait(&node->nextFlag); + next = (ptw32_mcs_local_node_t *) + PTW32_INTERLOCKED_EXCHANGE_ADD_SIZE((PTW32_INTERLOCKED_SIZEPTR)&node->next, (PTW32_INTERLOCKED_SIZE)0); /* MBR fence */ + } + + /* pass the lock */ + ptw32_mcs_flag_set(&next->readyFlag); +} + +/* + * ptw32_mcs_lock_try_acquire + */ +#if defined(PTW32_BUILD_INLINED) +INLINE +#endif /* PTW32_BUILD_INLINED */ +int +ptw32_mcs_lock_try_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node) +{ + node->lock = lock; + node->nextFlag = 0; + node->readyFlag = 0; + node->next = 0; /* initially, no successor */ + + return ((PTW32_INTERLOCKED_PVOID)PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)lock, + (PTW32_INTERLOCKED_PVOID)node, + (PTW32_INTERLOCKED_PVOID)0) + == (PTW32_INTERLOCKED_PVOID)0) ? 0 : EBUSY; +} + +/* + * ptw32_mcs_node_transfer -- move an MCS lock local node, usually from thread + * space to, for example, global space so that another thread can release + * the lock on behalf of the current lock owner. + * + * Example: used in pthread_barrier_wait where we want the last thread out of + * the barrier to release the lock owned by the last thread to enter the barrier + * (the one that releases all threads but not necessarily the last to leave). + * + * Should only be called by the thread that has the lock. + */ +#if defined(PTW32_BUILD_INLINED) +INLINE +#endif /* PTW32_BUILD_INLINED */ +void +ptw32_mcs_node_transfer (ptw32_mcs_local_node_t * new_node, ptw32_mcs_local_node_t * old_node) +{ + new_node->lock = old_node->lock; + new_node->nextFlag = 0; /* Not needed - used only in initial Acquire */ + new_node->readyFlag = 0; /* Not needed - we were waiting on this */ + new_node->next = 0; + + if ((ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR((PTW32_INTERLOCKED_PVOID_PTR)new_node->lock, + (PTW32_INTERLOCKED_PVOID)new_node, + (PTW32_INTERLOCKED_PVOID)old_node) + != old_node) + { + /* + * A successor has queued after us, so wait for them to link to us + */ + while (old_node->next == 0) + { + sched_yield(); + } + new_node->next = old_node->next; + } +} diff --git a/pthreads/ptw32_callUserDestroyRoutines.c b/pthreads/ptw32_callUserDestroyRoutines.c index a583f188d..f290f7ba5 100644 --- a/pthreads/ptw32_callUserDestroyRoutines.c +++ b/pthreads/ptw32_callUserDestroyRoutines.c @@ -38,10 +38,20 @@ #include "pthread.h" #include "implement.h" -#ifdef __cplusplus -# if ! defined (_MSC_VER) && ! (defined(__GNUC__) && __GNUC__ < 3) && ! defined(__WATCOMC__) -using - std::terminate; +#if defined(__CLEANUP_CXX) +# if defined(_MSC_VER) +# include +# elif defined(__WATCOMC__) +# include +# include +# else +# if defined(__GNUC__) && __GNUC__ < 3 +# include +# else +# include + using + std::terminate; +# endif # endif #endif @@ -68,6 +78,8 @@ ptw32_callUserDestroyRoutines (pthread_t thread) if (thread.p != NULL) { + ptw32_mcs_local_node_t threadLock; + ptw32_mcs_local_node_t keyLock; int assocsRemaining; int iterations = 0; ptw32_thread_t * sp = (ptw32_thread_t *) thread.p; @@ -83,7 +95,7 @@ ptw32_callUserDestroyRoutines (pthread_t thread) assocsRemaining = 0; iterations++; - (void) pthread_mutex_lock(&(sp->threadLock)); + ptw32_mcs_lock_acquire(&(sp->threadLock), &threadLock); /* * The pointer to the next assoc is stored in the thread struct so that * the assoc destructor in pthread_key_delete can adjust it @@ -93,7 +105,7 @@ ptw32_callUserDestroyRoutines (pthread_t thread) * before us. */ sp->nextAssoc = sp->keys; - (void) pthread_mutex_unlock(&(sp->threadLock)); + ptw32_mcs_lock_release(&threadLock); for (;;) { @@ -106,12 +118,12 @@ ptw32_callUserDestroyRoutines (pthread_t thread) * both assoc guards, but in the reverse order to our convention, * so we must be careful to avoid deadlock. */ - (void) pthread_mutex_lock(&(sp->threadLock)); + ptw32_mcs_lock_acquire(&(sp->threadLock), &threadLock); if ((assoc = (ThreadKeyAssoc *)sp->nextAssoc) == NULL) { /* Finished */ - pthread_mutex_unlock(&(sp->threadLock)); + ptw32_mcs_lock_release(&threadLock); break; } else @@ -126,10 +138,10 @@ ptw32_callUserDestroyRoutines (pthread_t thread) * If we fail, we need to relinquish the first lock and the * processor and then try to acquire them all again. */ - if (pthread_mutex_trylock(&(assoc->key->keyLock)) == EBUSY) + if (ptw32_mcs_lock_try_acquire(&(assoc->key->keyLock), &keyLock) == EBUSY) { - pthread_mutex_unlock(&(sp->threadLock)); - Sleep(1); // Ugly but necessary to avoid priority effects. + ptw32_mcs_lock_release(&threadLock); + Sleep(0); /* * Go around again. * If pthread_key_delete has removed this assoc in the meantime, @@ -165,12 +177,12 @@ ptw32_callUserDestroyRoutines (pthread_t thread) * pthread_setspecific can also be run from destructors and * also needs to be able to access the assocs. */ - (void) pthread_mutex_unlock(&(sp->threadLock)); - (void) pthread_mutex_unlock(&(k->keyLock)); + ptw32_mcs_lock_release(&threadLock); + ptw32_mcs_lock_release(&keyLock); assocsRemaining++; -#ifdef __cplusplus +#if defined(__cplusplus) try { @@ -210,8 +222,8 @@ ptw32_callUserDestroyRoutines (pthread_t thread) * and reclaim it's memory resources. */ ptw32_tkAssocDestroy (assoc); - (void) pthread_mutex_unlock(&(sp->threadLock)); - (void) pthread_mutex_unlock(&(k->keyLock)); + ptw32_mcs_lock_release(&threadLock); + ptw32_mcs_lock_release(&keyLock); } } } diff --git a/pthreads/ptw32_calloc.c b/pthreads/ptw32_calloc.c index eea7c7482..e7b9e64fe 100644 --- a/pthreads/ptw32_calloc.c +++ b/pthreads/ptw32_calloc.c @@ -38,7 +38,7 @@ #include "implement.h" -#ifdef NEED_CALLOC +#if defined(NEED_CALLOC) void * ptw32_calloc (size_t n, size_t s) { diff --git a/pthreads/ptw32_cond_check_need_init.c b/pthreads/ptw32_cond_check_need_init.c index 31359ad3f..ec3e8bbd6 100644 --- a/pthreads/ptw32_cond_check_need_init.c +++ b/pthreads/ptw32_cond_check_need_init.c @@ -43,29 +43,13 @@ INLINE int ptw32_cond_check_need_init (pthread_cond_t * cond) { int result = 0; + ptw32_mcs_local_node_t node; /* * The following guarded test is specifically for statically * initialised condition variables (via PTHREAD_OBJECT_INITIALIZER). - * - * Note that by not providing this synchronisation we risk - * introducing race conditions into applications which are - * correctly written. - * - * Approach - * -------- - * We know that static condition variables will not be PROCESS_SHARED - * so we can serialise access to internal state using - * Win32 Critical Sections rather than Win32 Mutexes. - * - * If using a single global lock slows applications down too much, - * multiple global locks could be created and hashed on some random - * value associated with each mutex, the pointer perhaps. At a guess, - * a good value for the optimal number of global locks might be - * the number of processors + 1. - * */ - EnterCriticalSection (&ptw32_cond_test_init_lock); + ptw32_mcs_lock_acquire(&ptw32_cond_test_init_lock, &node); /* * We got here possibly under race @@ -88,7 +72,7 @@ ptw32_cond_check_need_init (pthread_cond_t * cond) result = EINVAL; } - LeaveCriticalSection (&ptw32_cond_test_init_lock); + ptw32_mcs_lock_release(&node); return result; } diff --git a/pthreads/ptw32_mutex_check_need_init.c b/pthreads/ptw32_mutex_check_need_init.c index 35ec366bd..897db3c68 100644 --- a/pthreads/ptw32_mutex_check_need_init.c +++ b/pthreads/ptw32_mutex_check_need_init.c @@ -50,29 +50,9 @@ ptw32_mutex_check_need_init (pthread_mutex_t * mutex) { register int result = 0; register pthread_mutex_t mtx; + ptw32_mcs_local_node_t node; - /* - * The following guarded test is specifically for statically - * initialised mutexes (via PTHREAD_MUTEX_INITIALIZER). - * - * Note that by not providing this synchronisation we risk - * introducing race conditions into applications which are - * correctly written. - * - * Approach - * -------- - * We know that static mutexes will not be PROCESS_SHARED - * so we can serialise access to internal state using - * Win32 Critical Sections rather than Win32 Mutexes. - * - * If using a single global lock slows applications down too much, - * multiple global locks could be created and hashed on some random - * value associated with each mutex, the pointer perhaps. At a guess, - * a good value for the optimal number of global locks might be - * the number of processors + 1. - * - */ - EnterCriticalSection (&ptw32_mutex_test_init_lock); + ptw32_mcs_lock_acquire(&ptw32_mutex_test_init_lock, &node); /* * We got here possibly under race @@ -106,7 +86,7 @@ ptw32_mutex_check_need_init (pthread_mutex_t * mutex) result = EINVAL; } - LeaveCriticalSection (&ptw32_mutex_test_init_lock); + ptw32_mcs_lock_release(&node); return (result); } diff --git a/pthreads/ptw32_new.c b/pthreads/ptw32_new.c index 281256741..ac836ead3 100644 --- a/pthreads/ptw32_new.c +++ b/pthreads/ptw32_new.c @@ -70,12 +70,15 @@ ptw32_new (void) } /* Set default state. */ + tp->seqNumber = ++ptw32_threadSeqNumber; tp->sched_priority = THREAD_PRIORITY_NORMAL; tp->detachState = PTHREAD_CREATE_JOINABLE; tp->cancelState = PTHREAD_CANCEL_ENABLE; tp->cancelType = PTHREAD_CANCEL_DEFERRED; - tp->cancelLock = PTHREAD_MUTEX_INITIALIZER; - tp->threadLock = PTHREAD_MUTEX_INITIALIZER; + tp->stateLock = 0; + tp->threadLock = 0; + tp->robustMxListLock = 0; + tp->robustMxList = NULL; tp->cancelEvent = CreateEvent (0, (int) PTW32_TRUE, /* manualReset */ (int) PTW32_FALSE, /* setSignaled */ NULL); diff --git a/pthreads/ptw32_processInitialize.c b/pthreads/ptw32_processInitialize.c index d13b0226f..8da3e41fa 100644 --- a/pthreads/ptw32_processInitialize.c +++ b/pthreads/ptw32_processInitialize.c @@ -87,16 +87,6 @@ ptw32_processInitialize (void) ptw32_processTerminate (); } - /* - * Set up the global locks. - */ - InitializeCriticalSection (&ptw32_thread_reuse_lock); - InitializeCriticalSection (&ptw32_mutex_test_init_lock); - InitializeCriticalSection (&ptw32_cond_list_lock); - InitializeCriticalSection (&ptw32_cond_test_init_lock); - InitializeCriticalSection (&ptw32_rwlock_test_init_lock); - InitializeCriticalSection (&ptw32_spinlock_test_init_lock); - return (ptw32_processInitialized); } /* processInitialize */ diff --git a/pthreads/ptw32_processTerminate.c b/pthreads/ptw32_processTerminate.c index d2dfa7a24..83f0f23ca 100644 --- a/pthreads/ptw32_processTerminate.c +++ b/pthreads/ptw32_processTerminate.c @@ -65,6 +65,7 @@ ptw32_processTerminate (void) if (ptw32_processInitialized) { ptw32_thread_t * tp, * tpNext; + ptw32_mcs_local_node_t node; if (ptw32_selfThreadKey != NULL) { @@ -86,7 +87,7 @@ ptw32_processTerminate (void) ptw32_cleanupKey = NULL; } - EnterCriticalSection (&ptw32_thread_reuse_lock); + ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node); tp = ptw32_threadReuseTop; while (tp != PTW32_THREAD_REUSE_EMPTY) @@ -96,17 +97,7 @@ ptw32_processTerminate (void) tp = tpNext; } - LeaveCriticalSection (&ptw32_thread_reuse_lock); - - /* - * Destroy the global locks and other objects. - */ - DeleteCriticalSection (&ptw32_spinlock_test_init_lock); - DeleteCriticalSection (&ptw32_rwlock_test_init_lock); - DeleteCriticalSection (&ptw32_cond_test_init_lock); - DeleteCriticalSection (&ptw32_cond_list_lock); - DeleteCriticalSection (&ptw32_mutex_test_init_lock); - DeleteCriticalSection (&ptw32_thread_reuse_lock); + ptw32_mcs_lock_release(&node); ptw32_processInitialized = PTW32_FALSE; } diff --git a/pthreads/ptw32_relmillisecs.c b/pthreads/ptw32_relmillisecs.c index 85274b22e..894d5c9d4 100644 --- a/pthreads/ptw32_relmillisecs.c +++ b/pthreads/ptw32_relmillisecs.c @@ -1,120 +1,132 @@ -/* - * 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 */ -#endif -#include "pthread.h" -#include "implement.h" -#ifndef NEED_FTIME -#include -#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 + */ + +#include "pthread.h" +#include "implement.h" +#if !defined(NEED_FTIME) +#include +#endif + + +#if defined(PTW32_BUILD_INLINED) +INLINE +#endif /* PTW32_BUILD_INLINED */ +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; +#if defined(NEED_FTIME) + struct timespec currSysTime; + FILETIME ft; + SYSTEMTIME st; +#else /* ! NEED_FTIME */ +#if ( defined(_MSC_VER) && _MSC_VER >= 1300 ) || \ + ( (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 ) + struct __timeb64 currSysTime; +#else + struct _timeb currSysTime; +#endif +#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 */ + +#if defined(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 */ + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + _ftime64_s(&currSysTime); +#elif ( defined(_MSC_VER) && _MSC_VER >= 1300 ) || \ + ( (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 ) + _ftime64(&currSysTime); +#else + _ftime(&currSysTime); +#endif + + 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/pthreads/ptw32_reuse.c b/pthreads/ptw32_reuse.c index 0e8698496..7325857ba 100644 --- a/pthreads/ptw32_reuse.c +++ b/pthreads/ptw32_reuse.c @@ -76,8 +76,9 @@ pthread_t ptw32_threadReusePop (void) { pthread_t t = {NULL, 0}; + ptw32_mcs_local_node_t node; - EnterCriticalSection (&ptw32_thread_reuse_lock); + ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node); if (PTW32_THREAD_REUSE_EMPTY != ptw32_threadReuseTop) { @@ -97,7 +98,7 @@ ptw32_threadReusePop (void) t = tp->ptHandle; } - LeaveCriticalSection (&ptw32_thread_reuse_lock); + ptw32_mcs_lock_release(&node); return t; @@ -114,8 +115,9 @@ ptw32_threadReusePush (pthread_t thread) { ptw32_thread_t * tp = (ptw32_thread_t *) thread.p; pthread_t t; + ptw32_mcs_local_node_t node; - EnterCriticalSection (&ptw32_thread_reuse_lock); + ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node); t = tp->ptHandle; memset(tp, 0, sizeof(ptw32_thread_t)); @@ -124,12 +126,14 @@ ptw32_threadReusePush (pthread_t thread) tp->ptHandle = t; /* Bump the reuse counter now */ -#ifdef PTW32_THREAD_ID_REUSE_INCREMENT +#if defined(PTW32_THREAD_ID_REUSE_INCREMENT) tp->ptHandle.x += PTW32_THREAD_ID_REUSE_INCREMENT; #else tp->ptHandle.x++; #endif + tp->state = PThreadStateReuse; + tp->prevReuse = PTW32_THREAD_REUSE_EMPTY; if (PTW32_THREAD_REUSE_EMPTY != ptw32_threadReuseBottom) @@ -143,5 +147,5 @@ ptw32_threadReusePush (pthread_t thread) ptw32_threadReuseBottom = tp; - LeaveCriticalSection (&ptw32_thread_reuse_lock); + ptw32_mcs_lock_release(&node); } diff --git a/pthreads/ptw32_rwlock_check_need_init.c b/pthreads/ptw32_rwlock_check_need_init.c index ea2561eef..858ee271c 100644 --- a/pthreads/ptw32_rwlock_check_need_init.c +++ b/pthreads/ptw32_rwlock_check_need_init.c @@ -41,29 +41,13 @@ INLINE int ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock) { int result = 0; + ptw32_mcs_local_node_t node; /* * The following guarded test is specifically for statically * initialised rwlocks (via PTHREAD_RWLOCK_INITIALIZER). - * - * Note that by not providing this synchronisation we risk - * introducing race conditions into applications which are - * correctly written. - * - * Approach - * -------- - * We know that static rwlocks will not be PROCESS_SHARED - * so we can serialise access to internal state using - * Win32 Critical Sections rather than Win32 Mutexes. - * - * If using a single global lock slows applications down too much, - * multiple global locks could be created and hashed on some random - * value associated with each mutex, the pointer perhaps. At a guess, - * a good value for the optimal number of global locks might be - * the number of processors + 1. - * */ - EnterCriticalSection (&ptw32_rwlock_test_init_lock); + ptw32_mcs_lock_acquire(&ptw32_rwlock_test_init_lock, &node); /* * We got here possibly under race @@ -87,7 +71,7 @@ ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock) result = EINVAL; } - LeaveCriticalSection (&ptw32_rwlock_test_init_lock); + ptw32_mcs_lock_release(&node); return result; } diff --git a/pthreads/ptw32_semwait.c b/pthreads/ptw32_semwait.c index e97784977..c3c4fd0e5 100644 --- a/pthreads/ptw32_semwait.c +++ b/pthreads/ptw32_semwait.c @@ -1,135 +1,135 @@ -/* - * 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 */ -#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; - - /* See sem_destroy.c - */ - if (*sem == NULL) - { - (void) pthread_mutex_unlock (&s->lock); - errno = EINVAL; - return -1; - } - - 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 (*sem == NULL) - { - (void) pthread_mutex_unlock (&s->lock); - errno = EINVAL; - return -1; - } - - 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 + */ + +#if !defined(_UWIN) +/*# include */ +#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; + + /* See sem_destroy.c + */ + if (*sem == NULL) + { + (void) pthread_mutex_unlock (&s->lock); + errno = EINVAL; + return -1; + } + + v = --s->value; + (void) pthread_mutex_unlock (&s->lock); + + if (v < 0) + { + /* Must wait */ + if (WaitForSingleObject (s->sem, INFINITE) == WAIT_OBJECT_0) + { +#if defined(NEED_SEM) + if (pthread_mutex_lock (&s->lock) == 0) + { + if (*sem == NULL) + { + (void) pthread_mutex_unlock (&s->lock); + errno = EINVAL; + return -1; + } + + 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/pthreads/ptw32_spinlock_check_need_init.c b/pthreads/ptw32_spinlock_check_need_init.c index bf45bc397..8808454ee 100644 --- a/pthreads/ptw32_spinlock_check_need_init.c +++ b/pthreads/ptw32_spinlock_check_need_init.c @@ -42,16 +42,13 @@ INLINE int ptw32_spinlock_check_need_init (pthread_spinlock_t * lock) { int result = 0; + ptw32_mcs_local_node_t node; /* * The following guarded test is specifically for statically * initialised spinlocks (via PTHREAD_SPINLOCK_INITIALIZER). - * - * Note that by not providing this synchronisation we risk - * introducing race conditions into applications which are - * correctly written. */ - EnterCriticalSection (&ptw32_spinlock_test_init_lock); + ptw32_mcs_lock_acquire(&ptw32_spinlock_test_init_lock, &node); /* * We got here possibly under race @@ -75,7 +72,7 @@ ptw32_spinlock_check_need_init (pthread_spinlock_t * lock) result = EINVAL; } - LeaveCriticalSection (&ptw32_spinlock_test_init_lock); + ptw32_mcs_lock_release(&node); return (result); } diff --git a/pthreads/ptw32_threadDestroy.c b/pthreads/ptw32_threadDestroy.c index eb9abfc61..41499b11b 100644 --- a/pthreads/ptw32_threadDestroy.c +++ b/pthreads/ptw32_threadDestroy.c @@ -64,10 +64,7 @@ ptw32_threadDestroy (pthread_t thread) CloseHandle (threadCopy.cancelEvent); } - (void) pthread_mutex_destroy(&threadCopy.cancelLock); - (void) pthread_mutex_destroy(&threadCopy.threadLock); - -#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) +#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) /* * See documentation for endthread vs endthreadex. */ diff --git a/pthreads/ptw32_threadStart.c b/pthreads/ptw32_threadStart.c index 5c0fe0e85..cb08403b1 100644 --- a/pthreads/ptw32_threadStart.c +++ b/pthreads/ptw32_threadStart.c @@ -37,8 +37,13 @@ #include "pthread.h" #include "implement.h" +#include -#ifdef __CLEANUP_SEH +#if defined(__CLEANUP_C) +# include +#endif + +#if defined(__CLEANUP_SEH) static DWORD ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei) @@ -69,7 +74,6 @@ ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei) */ pthread_t self = pthread_self (); - (void) pthread_mutex_destroy (&((ptw32_thread_t *)self.p)->cancelLock); ptw32_callUserDestroyRoutines (self); return EXCEPTION_CONTINUE_SEARCH; @@ -116,7 +120,7 @@ ptw32_terminate () #endif -#if ! defined (__MINGW32__) || (defined (__MSVCRT__) && ! defined (__DMC__)) +#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || (defined (__MSVCRT__) && ! defined (__DMC__)) unsigned __stdcall #else @@ -130,15 +134,16 @@ ptw32_threadStart (void *vthreadParms) void *(*start) (void *); void * arg; -#ifdef __CLEANUP_SEH +#if defined(__CLEANUP_SEH) DWORD ei[] = { 0, 0, 0 }; #endif -#ifdef __CLEANUP_C +#if defined(__CLEANUP_C) int setjmp_rc; #endif + ptw32_mcs_local_node_t stateLock; void * status = (void *) 0; self = threadParms->tid; @@ -148,28 +153,28 @@ ptw32_threadStart (void *vthreadParms) free (threadParms); -#if defined (__MINGW32__) && ! defined (__MSVCRT__) +#if (defined(__MINGW64__) || defined(__MINGW32__)) && ! defined (__MSVCRT__) /* * beginthread does not return the thread id and is running * before it returns us the thread handle, and so we do it here. */ sp->thread = GetCurrentThreadId (); /* - * Here we're using cancelLock as a general-purpose lock + * Here we're using stateLock as a general-purpose lock * to make the new thread wait until the creating thread * has the new handle. */ - if (pthread_mutex_lock (&sp->cancelLock) == 0) - { - (void) pthread_mutex_unlock (&sp->cancelLock); - } -#endif - + ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock); + pthread_setspecific (ptw32_selfThreadKey, sp); +#else pthread_setspecific (ptw32_selfThreadKey, sp); + ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock); +#endif sp->state = PThreadStateRunning; + ptw32_mcs_lock_release (&stateLock); -#ifdef __CLEANUP_SEH +#if defined(__CLEANUP_SEH) __try { @@ -177,8 +182,9 @@ ptw32_threadStart (void *vthreadParms) * Run the caller's routine; */ status = sp->exitStatus = (*start) (arg); + sp->state = PThreadStateExiting; -#ifdef _UWIN +#if defined(_UWIN) if (--pthread_count <= 0) exit (0); #endif @@ -190,7 +196,7 @@ ptw32_threadStart (void *vthreadParms) { case PTW32_EPS_CANCEL: status = sp->exitStatus = PTHREAD_CANCELED; -#ifdef _UWIN +#if defined(_UWIN) if (--pthread_count <= 0) exit (0); #endif @@ -206,7 +212,7 @@ ptw32_threadStart (void *vthreadParms) #else /* __CLEANUP_SEH */ -#ifdef __CLEANUP_C +#if defined(__CLEANUP_C) setjmp_rc = setjmp (sp->start_mark); @@ -217,6 +223,7 @@ ptw32_threadStart (void *vthreadParms) * Run the caller's routine; */ status = sp->exitStatus = (*start) (arg); + sp->state = PThreadStateExiting; } else { @@ -236,7 +243,7 @@ ptw32_threadStart (void *vthreadParms) #else /* __CLEANUP_C */ -#ifdef __CLEANUP_CXX +#if defined(__CLEANUP_CXX) ptw32_oldTerminate = set_terminate (&ptw32_terminate); @@ -250,6 +257,7 @@ ptw32_threadStart (void *vthreadParms) try { status = sp->exitStatus = (*start) (arg); + sp->state = PThreadStateExiting; } catch (ptw32_exception &) { @@ -268,7 +276,6 @@ ptw32_threadStart (void *vthreadParms) * ptw32_terminate() will be called if there is no user * supplied function. */ - terminate_function term_func = set_terminate (0); set_terminate (term_func); @@ -277,7 +284,6 @@ ptw32_threadStart (void *vthreadParms) { term_func (); } - throw; } } @@ -299,20 +305,11 @@ ptw32_threadStart (void *vthreadParms) { /* * A system unexpected exception has occurred running the user's - * terminate routine. We get control back within this block - cleanup - * and release the exception out of thread scope. + * terminate routine. We get control back within this block + * and exit with a substitute status. If the thread was not + * cancelled then this indicates the unhandled exception. */ status = sp->exitStatus = PTHREAD_CANCELED; - (void) pthread_mutex_lock (&sp->cancelLock); - sp->state = PThreadStateException; - (void) pthread_mutex_unlock (&sp->cancelLock); - (void) pthread_win32_thread_detach_np (); - (void) set_terminate (ptw32_oldTerminate); - throw; - - /* - * Never reached. - */ } (void) set_terminate (ptw32_oldTerminate); @@ -343,8 +340,8 @@ ptw32_threadStart (void *vthreadParms) (void) pthread_win32_thread_detach_np (); #endif -#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) - _endthreadex ((unsigned) status); +#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) + _endthreadex ((unsigned)(size_t) status); #else _endthread (); #endif @@ -353,8 +350,8 @@ ptw32_threadStart (void *vthreadParms) * Never reached. */ -#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) - return (unsigned) status; +#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) + return (unsigned)(size_t) status; #endif } /* ptw32_threadStart */ diff --git a/pthreads/ptw32_throw.c b/pthreads/ptw32_throw.c index a9a47dbf3..1404e940f 100644 --- a/pthreads/ptw32_throw.c +++ b/pthreads/ptw32_throw.c @@ -1,172 +1,189 @@ -/* - * ptw32_throw.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" - -/* - * ptw32_throw - * - * All canceled and explicitly exited POSIX threads go through - * here. This routine knows how to exit both POSIX initiated threads and - * 'implicit' POSIX threads for each of the possible language modes (C, - * C++, and SEH). - */ -void -ptw32_throw (DWORD exception) -{ - /* - * Don't use pthread_self() to avoid creating an implicit POSIX thread handle - * unnecessarily. - */ - ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); - -#ifdef __CLEANUP_SEH - DWORD exceptionInformation[3]; -#endif - - if (exception != PTW32_EPS_CANCEL && exception != PTW32_EPS_EXIT) - { - /* Should never enter here */ - exit (1); - } - - if (NULL == sp || sp->implicit) - { - /* - * We're inside a non-POSIX initialised Win32 thread - * so there is no point to jump or throw back to. Just do an - * explicit thread exit here after cleaning up POSIX - * residue (i.e. cleanup handlers, POSIX thread handle etc). - */ -#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) - unsigned exitCode = 0; - - switch (exception) - { - case PTW32_EPS_CANCEL: - exitCode = (unsigned) PTHREAD_CANCELED; - break; - case PTW32_EPS_EXIT: - if (NULL != sp) - { - exitCode = (unsigned) sp->exitStatus; - } - break; - } -#endif - -#if defined(PTW32_STATIC_LIB) - - pthread_win32_thread_detach_np (); - -#endif - -#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) - _endthreadex (exitCode); -#else - _endthread (); -#endif - - } - -#ifdef __CLEANUP_SEH - - - exceptionInformation[0] = (DWORD) (exception); - exceptionInformation[1] = (DWORD) (0); - exceptionInformation[2] = (DWORD) (0); - - RaiseException (EXCEPTION_PTW32_SERVICES, 0, 3, exceptionInformation); - -#else /* __CLEANUP_SEH */ - -#ifdef __CLEANUP_C - - ptw32_pop_cleanup_all (1); - longjmp (sp->start_mark, exception); - -#else /* __CLEANUP_C */ - -#ifdef __CLEANUP_CXX - - switch (exception) - { - case PTW32_EPS_CANCEL: - throw ptw32_exception_cancel (); - break; - case PTW32_EPS_EXIT: - throw ptw32_exception_exit (); - break; - } - -#else - -#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. - -#endif /* __CLEANUP_CXX */ - -#endif /* __CLEANUP_C */ - -#endif /* __CLEANUP_SEH */ - - /* Never reached */ -} - - -void -ptw32_pop_cleanup_all (int execute) -{ - while (NULL != ptw32_pop_cleanup (execute)) - { - } -} - - -DWORD -ptw32_get_exception_services_code (void) -{ -#ifdef __CLEANUP_SEH - - return EXCEPTION_PTW32_SERVICES; - -#else - - return (DWORD) NULL; - -#endif -} +/* + * ptw32_throw.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" + +#if defined(__CLEANUP_C) +# include +#endif + +/* + * ptw32_throw + * + * All canceled and explicitly exited POSIX threads go through + * here. This routine knows how to exit both POSIX initiated threads and + * 'implicit' POSIX threads for each of the possible language modes (C, + * C++, and SEH). + */ +#if defined(_MSC_VER) +/* + * Ignore the warning: + * "C++ exception specification ignored except to indicate that + * the function is not __declspec(nothrow)." + */ +#pragma warning(disable:4290) +#endif +void +ptw32_throw (DWORD exception) +#if defined(__CLEANUP_CXX) + throw(ptw32_exception_cancel,ptw32_exception_exit) +#endif +{ + /* + * Don't use pthread_self() to avoid creating an implicit POSIX thread handle + * unnecessarily. + */ + ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); + +#if defined(__CLEANUP_SEH) + DWORD exceptionInformation[3]; +#endif + + sp->state = PThreadStateExiting; + + if (exception != PTW32_EPS_CANCEL && exception != PTW32_EPS_EXIT) + { + /* Should never enter here */ + exit (1); + } + + if (NULL == sp || sp->implicit) + { + /* + * We're inside a non-POSIX initialised Win32 thread + * so there is no point to jump or throw back to. Just do an + * explicit thread exit here after cleaning up POSIX + * residue (i.e. cleanup handlers, POSIX thread handle etc). + */ +#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) + unsigned exitCode = 0; + + switch (exception) + { + case PTW32_EPS_CANCEL: + exitCode = (unsigned)(size_t) PTHREAD_CANCELED; + break; + case PTW32_EPS_EXIT: + if (NULL != sp) + { + exitCode = (unsigned)(size_t) sp->exitStatus; + } + break; + } +#endif + +#if defined(PTW32_STATIC_LIB) + + pthread_win32_thread_detach_np (); + +#endif + +#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) + _endthreadex (exitCode); +#else + _endthread (); +#endif + + } + +#if defined(__CLEANUP_SEH) + + + exceptionInformation[0] = (DWORD) (exception); + exceptionInformation[1] = (DWORD) (0); + exceptionInformation[2] = (DWORD) (0); + + RaiseException (EXCEPTION_PTW32_SERVICES, 0, 3, exceptionInformation); + +#else /* __CLEANUP_SEH */ + +#if defined(__CLEANUP_C) + + ptw32_pop_cleanup_all (1); + longjmp (sp->start_mark, exception); + +#else /* __CLEANUP_C */ + +#if defined(__CLEANUP_CXX) + + switch (exception) + { + case PTW32_EPS_CANCEL: + throw ptw32_exception_cancel (); + break; + case PTW32_EPS_EXIT: + throw ptw32_exception_exit (); + break; + } + +#else + +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* __CLEANUP_CXX */ + +#endif /* __CLEANUP_C */ + +#endif /* __CLEANUP_SEH */ + + /* Never reached */ +} + + +void +ptw32_pop_cleanup_all (int execute) +{ + while (NULL != ptw32_pop_cleanup (execute)) + { + } +} + + +DWORD +ptw32_get_exception_services_code (void) +{ +#if defined(__CLEANUP_SEH) + + return EXCEPTION_PTW32_SERVICES; + +#else + + return (DWORD)0; + +#endif +} diff --git a/pthreads/ptw32_timespec.c b/pthreads/ptw32_timespec.c index 6a2cb565a..6318957a8 100644 --- a/pthreads/ptw32_timespec.c +++ b/pthreads/ptw32_timespec.c @@ -39,13 +39,13 @@ #include "implement.h" -#ifdef NEED_FTIME +#if defined(NEED_FTIME) /* * time between jan 1, 1601 and jan 1, 1970 in units of 100 nanoseconds */ #define PTW32_TIMESPEC_TO_FILETIME_OFFSET \ - ( ((LONGLONG) 27111902 << 32) + (LONGLONG) 3577643008 ) + ( ((int64_t) 27111902 << 32) + (int64_t) 3577643008 ) INLINE void ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft) @@ -58,7 +58,7 @@ ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft) * ------------------------------------------------------------------- */ { - *(LONGLONG *) ft = ts->tv_sec * 10000000 + *(int64_t *) ft = ts->tv_sec * 10000000 + (ts->tv_nsec + 50) / 100 + PTW32_TIMESPEC_TO_FILETIME_OFFSET; } @@ -74,10 +74,10 @@ ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts) */ { ts->tv_sec = - (int) ((*(LONGLONG *) ft - PTW32_TIMESPEC_TO_FILETIME_OFFSET) / 10000000); + (int) ((*(int64_t *) ft - PTW32_TIMESPEC_TO_FILETIME_OFFSET) / 10000000); ts->tv_nsec = - (int) ((*(LONGLONG *) ft - PTW32_TIMESPEC_TO_FILETIME_OFFSET - - ((LONGLONG) ts->tv_sec * (LONGLONG) 10000000)) * 100); + (int) ((*(int64_t *) ft - PTW32_TIMESPEC_TO_FILETIME_OFFSET - + ((int64_t) ts->tv_sec * (int64_t) 10000000)) * 100); } #endif /* NEED_FTIME */ diff --git a/pthreads/ptw32_tkAssocCreate.c b/pthreads/ptw32_tkAssocCreate.c index 5ba24bbf7..50d6c500c 100644 --- a/pthreads/ptw32_tkAssocCreate.c +++ b/pthreads/ptw32_tkAssocCreate.c @@ -78,7 +78,7 @@ ptw32_tkAssocCreate (ptw32_thread_t * sp, pthread_key_t key) * Have to create an association and add it * to both the key and the thread. * - * Both key->keyLock and thread->threadLock are locked on + * Both key->keyLock and thread->threadLock are locked before * entry to this routine. */ assoc = (ThreadKeyAssoc *) calloc (1, sizeof (*assoc)); diff --git a/pthreads/ptw32_tkAssocDestroy.c b/pthreads/ptw32_tkAssocDestroy.c index a7842ea87..fedebf593 100644 --- a/pthreads/ptw32_tkAssocDestroy.c +++ b/pthreads/ptw32_tkAssocDestroy.c @@ -57,7 +57,7 @@ ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc) { /* - * Both key->keyLock and thread->threadLock are locked on + * Both key->keyLock and thread->threadLock are locked before * entry to this routine. */ if (assoc != NULL) diff --git a/pthreads/sched.h b/pthreads/sched.h index 8db97a901..f36a97a66 100644 --- a/pthreads/sched.h +++ b/pthreads/sched.h @@ -1,180 +1,183 @@ -/* - * Module: sched.h - * - * Purpose: - * Provides an implementation of POSIX realtime extensions - * as defined in - * - * 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 _SCHED_H -#define _SCHED_H - -#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(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_LEVEL) -#define PTW32_LEVEL PTW32_LEVEL_MAX -/* Include everything */ -#endif - - -#if __GNUC__ && ! defined (__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(PTW32_STATIC_LIB) -# ifdef PTW32_BUILD -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* - * 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 -#endif -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -#if defined(__MINGW32__) || defined(_UWIN) -# if PTW32_LEVEL >= PTW32_LEVEL_MAX -/* For pid_t */ -# include -/* Required by Unix 98 */ -# include -# else - typedef int pid_t; -# endif -#else -typedef int pid_t; -#endif - -/* Thread scheduling policies */ - -enum { - SCHED_OTHER = 0, - SCHED_FIFO, - SCHED_RR, - SCHED_MIN = SCHED_OTHER, - SCHED_MAX = SCHED_RR -}; - -struct sched_param { - int sched_priority; -}; - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -PTW32_DLLPORT int __cdecl sched_yield (void); - -PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); - -PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); - -PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); - -PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); - -/* - * Note that this macro returns ENOTSUP rather than - * ENOSYS as might be expected. However, returning ENOSYS - * should mean that sched_get_priority_{min,max} are - * not implemented as well as sched_rr_get_interval. - * This is not the case, since we just don't support - * round-robin scheduling. Therefore I have chosen to - * return the same value as sched_setscheduler when - * SCHED_RR is passed to it. - */ -#define sched_rr_get_interval(_pid, _interval) \ - ( errno = ENOTSUP, (int) -1 ) - - -#ifdef __cplusplus -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#undef PTW32_LEVEL -#undef PTW32_LEVEL_MAX - -#endif /* !_SCHED_H */ - +/* + * Module: sched.h + * + * Purpose: + * Provides an implementation of POSIX realtime extensions + * as defined in + * + * 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 + */ +#if !defined(_SCHED_H) +#define _SCHED_H + +#undef PTW32_SCHED_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_SCHED_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_SCHED_LEVEL +#define PTW32_SCHED_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_SCHED_LEVEL +#define PTW32_SCHED_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_SCHED_LEVEL_MAX 3 + +#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_SCHED_LEVEL) +#define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX +/* Include everything */ +#endif + + +#if defined(__GNUC__) && !defined(__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the library, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the library, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#if !defined(PTW32_STATIC_LIB) +# if defined(PTW32_BUILD) +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#if !defined(PTW32_CONFIG_H) +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(__MINGW64__) +# define HAVE_STRUCT_TIMESPEC +# define HAVE_MODE_T +# elif defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX +#if defined(NEED_ERRNO) +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */ + +#if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN) +# if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX +/* For pid_t */ +# include +/* Required by Unix 98 */ +# include +# else + typedef int pid_t; +# endif +#else + typedef int pid_t; +#endif + +/* Thread scheduling policies */ + +enum { + SCHED_OTHER = 0, + SCHED_FIFO, + SCHED_RR, + SCHED_MIN = SCHED_OTHER, + SCHED_MAX = SCHED_RR +}; + +struct sched_param { + int sched_priority; +}; + +#if defined(__cplusplus) +extern "C" +{ +#endif /* __cplusplus */ + +PTW32_DLLPORT int __cdecl sched_yield (void); + +PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); + +PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); + +PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); + +PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); + +/* + * Note that this macro returns ENOTSUP rather than + * ENOSYS as might be expected. However, returning ENOSYS + * should mean that sched_get_priority_{min,max} are + * not implemented as well as sched_rr_get_interval. + * This is not the case, since we just don't support + * round-robin scheduling. Therefore I have chosen to + * return the same value as sched_setscheduler when + * SCHED_RR is passed to it. + */ +#define sched_rr_get_interval(_pid, _interval) \ + ( errno = ENOTSUP, (int) -1 ) + + +#if defined(__cplusplus) +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_SCHED_LEVEL +#undef PTW32_SCHED_LEVEL_MAX + +#endif /* !_SCHED_H */ + diff --git a/pthreads/sched_getscheduler.c b/pthreads/sched_getscheduler.c index 9bc819e47..8769c15e5 100644 --- a/pthreads/sched_getscheduler.c +++ b/pthreads/sched_getscheduler.c @@ -62,6 +62,8 @@ sched_getscheduler (pid_t pid) (0xFF & ERROR_ACCESS_DENIED)) ? EPERM : ESRCH; return -1; } + else + CloseHandle(h); } } diff --git a/pthreads/sched_setscheduler.c b/pthreads/sched_setscheduler.c index 4e060c7e5..869131637 100644 --- a/pthreads/sched_setscheduler.c +++ b/pthreads/sched_setscheduler.c @@ -64,6 +64,8 @@ sched_setscheduler (pid_t pid, int policy) (0xFF & ERROR_ACCESS_DENIED)) ? EPERM : ESRCH; return -1; } + else + CloseHandle(h); } } diff --git a/pthreads/sem_close.c b/pthreads/sem_close.c index 2f95c8785..6d7280f29 100644 --- a/pthreads/sem_close.c +++ b/pthreads/sem_close.c @@ -46,7 +46,7 @@ #include "implement.h" /* ignore warning "unreferenced formal parameter" */ -#ifdef _MSC_VER +#if defined(_MSC_VER) #pragma warning( disable : 4100 ) #endif diff --git a/pthreads/sem_init.c b/pthreads/sem_init.c index 02acd90f1..f682f4b20 100644 --- a/pthreads/sem_init.c +++ b/pthreads/sem_init.c @@ -112,7 +112,7 @@ sem_init (sem_t * sem, int pshared, unsigned int value) if (pthread_mutex_init(&s->lock, NULL) == 0) { -#ifdef NEED_SEM +#if defined(NEED_SEM) s->sem = CreateEvent (NULL, PTW32_FALSE, /* auto (not manual) reset */ diff --git a/pthreads/sem_open.c b/pthreads/sem_open.c index bf48c831c..fb1cc541f 100644 --- a/pthreads/sem_open.c +++ b/pthreads/sem_open.c @@ -46,7 +46,7 @@ #include "implement.h" /* ignore warning "unreferenced formal parameter" */ -#ifdef _MSC_VER +#if defined(_MSC_VER) #pragma warning( disable : 4100 ) #endif diff --git a/pthreads/sem_post.c b/pthreads/sem_post.c index c7a7a3cf9..34832527b 100644 --- a/pthreads/sem_post.c +++ b/pthreads/sem_post.c @@ -93,7 +93,7 @@ sem_post (sem_t * sem) if (s->value < SEM_VALUE_MAX) { -#ifdef NEED_SEM +#if defined(NEED_SEM) if (++s->value <= 0 && !SetEvent(s->sem)) { diff --git a/pthreads/sem_post_multiple.c b/pthreads/sem_post_multiple.c index 3d1e4ef28..44c168c6c 100644 --- a/pthreads/sem_post_multiple.c +++ b/pthreads/sem_post_multiple.c @@ -101,7 +101,7 @@ sem_post_multiple (sem_t * sem, int count) s->value += count; if (waiters > 0) { -#ifdef NEED_SEM +#if defined(NEED_SEM) if (SetEvent(s->sem)) { waiters--; diff --git a/pthreads/sem_timedwait.c b/pthreads/sem_timedwait.c index 52146b478..638431cf1 100644 --- a/pthreads/sem_timedwait.c +++ b/pthreads/sem_timedwait.c @@ -77,7 +77,7 @@ ptw32_sem_timedwait_cleanup (void * args) { /* Indicate we're no longer waiting */ s->value++; -#ifdef NEED_SEM +#if defined(NEED_SEM) if (s->value > 0) { s->leftToUnblock = 0; @@ -177,7 +177,7 @@ sem_timedwait (sem_t * sem, const struct timespec *abstime) if (v < 0) { -#ifdef NEED_SEM +#if defined(NEED_SEM) int timedout; #endif sem_timedwait_cleanup_args_t cleanup_args; @@ -185,21 +185,21 @@ sem_timedwait (sem_t * sem, const struct timespec *abstime) cleanup_args.sem = s; cleanup_args.resultPtr = &result; -#ifdef _MSC_VER +#if defined(_MSC_VER) && _MSC_VER < 1400 #pragma inline_depth(0) #endif /* Must wait */ pthread_cleanup_push(ptw32_sem_timedwait_cleanup, (void *) &cleanup_args); -#ifdef NEED_SEM +#if defined(NEED_SEM) timedout = #endif result = pthreadCancelableTimedWait (s->sem, milliseconds); pthread_cleanup_pop(result); -#ifdef _MSC_VER +#if defined(_MSC_VER) && _MSC_VER < 1400 #pragma inline_depth() #endif -#ifdef NEED_SEM +#if defined(NEED_SEM) if (!timedout && pthread_mutex_lock (&s->lock) == 0) { diff --git a/pthreads/sem_unlink.c b/pthreads/sem_unlink.c index a6c6f81b0..fb80569a0 100644 --- a/pthreads/sem_unlink.c +++ b/pthreads/sem_unlink.c @@ -46,7 +46,7 @@ #include "implement.h" /* ignore warning "unreferenced formal parameter" */ -#ifdef _MSC_VER +#if defined(_MSC_VER) #pragma warning( disable : 4100 ) #endif diff --git a/pthreads/sem_wait.c b/pthreads/sem_wait.c index d39d2b4b6..50c11d808 100644 --- a/pthreads/sem_wait.c +++ b/pthreads/sem_wait.c @@ -63,7 +63,7 @@ ptw32_sem_wait_cleanup(void * sem) if (*((sem_t *)sem) != NULL && !(WaitForSingleObject(s->sem, 0) == WAIT_OBJECT_0)) { ++s->value; -#ifdef NEED_SEM +#if defined(NEED_SEM) if (s->value > 0) { s->leftToUnblock = 0; @@ -139,7 +139,7 @@ sem_wait (sem_t * sem) if (v < 0) { -#ifdef _MSC_VER +#if defined(_MSC_VER) && _MSC_VER < 1400 #pragma inline_depth(0) #endif /* Must wait */ @@ -147,11 +147,11 @@ sem_wait (sem_t * sem) result = pthreadCancelableWait (s->sem); /* Cleanup if we're canceled or on any other error */ pthread_cleanup_pop(result); -#ifdef _MSC_VER +#if defined(_MSC_VER) && _MSC_VER < 1400 #pragma inline_depth() #endif } -#ifdef NEED_SEM +#if defined(NEED_SEM) if (!result && pthread_mutex_lock (&s->lock) == 0) { diff --git a/pthreads/semaphore.c b/pthreads/semaphore.c index 6b2b10e85..64fc0e366 100644 --- a/pthreads/semaphore.c +++ b/pthreads/semaphore.c @@ -45,7 +45,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ifndef NEED_FTIME +#if !defined(NEED_FTIME) # include #endif diff --git a/pthreads/semaphore.h b/pthreads/semaphore.h index b58a9cb1a..c6e9407e2 100644 --- a/pthreads/semaphore.h +++ b/pthreads/semaphore.h @@ -1,166 +1,169 @@ -/* - * Module: semaphore.h - * - * 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 - */ -#if !defined( SEMAPHORE_H ) -#define SEMAPHORE_H - -#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 - -#if __GNUC__ && ! defined (__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(PTW32_STATIC_LIB) -# ifdef PTW32_BUILD -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* - * 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 -#endif -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -#define _POSIX_SEMAPHORES - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -#ifndef HAVE_MODE_T -typedef unsigned int mode_t; -#endif - - -typedef struct sem_t_ * sem_t; - -PTW32_DLLPORT int __cdecl sem_init (sem_t * sem, - int pshared, - unsigned int value); - -PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem, - const struct timespec * abstime); - -PTW32_DLLPORT int __cdecl sem_post (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem, - int count); - -PTW32_DLLPORT int __cdecl sem_open (const char * name, - int oflag, - mode_t mode, - unsigned int value); - -PTW32_DLLPORT int __cdecl sem_close (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_unlink (const char * name); - -PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem, - int * sval); - -#ifdef __cplusplus -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#undef PTW32_LEVEL -#undef PTW32_LEVEL_MAX - -#endif /* !SEMAPHORE_H */ +/* + * Module: semaphore.h + * + * 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 + */ +#if !defined( SEMAPHORE_H ) +#define SEMAPHORE_H + +#undef PTW32_SEMAPHORE_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_SEMAPHORE_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_SEMAPHORE_LEVEL +#define PTW32_SEMAPHORE_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_SEMAPHORE_LEVEL +#define PTW32_SEMAPHORE_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_SEMAPHORE_LEVEL_MAX 3 + +#if !defined(PTW32_SEMAPHORE_LEVEL) +#define PTW32_SEMAPHORE_LEVEL PTW32_SEMAPHORE_LEVEL_MAX +/* Include everything */ +#endif + +#if defined(__GNUC__) && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the library, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the library, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#if !defined(PTW32_STATIC_LIB) +# if defined(PTW32_BUILD) +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#if !defined(PTW32_CONFIG_H) +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(__MINGW64__) +# define HAVE_STRUCT_TIMESPEC +# define HAVE_MODE_T +# elif defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX +#if defined(NEED_ERRNO) +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX */ + +#define _POSIX_SEMAPHORES + +#if defined(__cplusplus) +extern "C" +{ +#endif /* __cplusplus */ + +#if !defined(HAVE_MODE_T) +typedef unsigned int mode_t; +#endif + + +typedef struct sem_t_ * sem_t; + +PTW32_DLLPORT int __cdecl sem_init (sem_t * sem, + int pshared, + unsigned int value); + +PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem, + const struct timespec * abstime); + +PTW32_DLLPORT int __cdecl sem_post (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem, + int count); + +PTW32_DLLPORT int __cdecl sem_open (const char * name, + int oflag, + mode_t mode, + unsigned int value); + +PTW32_DLLPORT int __cdecl sem_close (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_unlink (const char * name); + +PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem, + int * sval); + +#if defined(__cplusplus) +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_SEMAPHORE_LEVEL +#undef PTW32_SEMAPHORE_LEVEL_MAX + +#endif /* !SEMAPHORE_H */ diff --git a/pthreads/signal.c b/pthreads/signal.c index 8f56c48b5..eef466962 100644 --- a/pthreads/signal.c +++ b/pthreads/signal.c @@ -84,7 +84,7 @@ #include "pthread.h" #include "implement.h" -#if HAVE_SIGSET_T +#if defined(HAVE_SIGSET_T) static void ptw32_signal_thread () diff --git a/pthreads/tests/Bmakefile b/pthreads/tests/Bmakefile index b561cad8c..df2ac1b1b 100644 --- a/pthreads/tests/Bmakefile +++ b/pthreads/tests/Bmakefile @@ -1,354 +1,358 @@ -# 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 - -# The next path is relative to $BUILD_DIR -QAPC = ..\QueueUserAPCEx\User\quserex.dll - -CPHDR = pthread.h semaphore.h sched.h - -OPTIM = -O2 - -XXLIBS = cw32mti.lib 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) /D_WIN32_WINNT=0x400 -w -tWC -tWM -4 -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.pass exit5.pass \ - join0.pass join1.pass detach1.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 \ - self2.pass \ - cancel1.pass cancel2.pass \ - semaphore4.pass semaphore4t.pass semaphore5.pass \ - barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass barrier6.pass \ - tsd1.pass tsd2.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.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 \ - exception1.pass exception2.pass exception3.pass \ - cancel9.pass create3.pass stress1.pass - -BENCHRESULTS = \ - benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench \ - benchtest6.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 $(BUILD_DIR)\$@ - @ $(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: -benchtest6.bench: -barrier1.pass: semaphore4.pass -barrier2.pass: barrier1.pass -barrier3.pass: barrier2.pass -barrier4.pass: barrier3.pass -barrier5.pass: barrier4.pass -barrier6.pass: barrier5.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 -cancel9.pass: cancel8.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 -detach1.pass: join0.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 -semaphore5.pass: semaphore4.pass -sizes.pass: -spin1.pass: -spin2.pass: spin1.pass -spin3.pass: spin2.pass -spin4.pass: spin3.pass -stress1.pass: -tsd1.pass: barrier5.pass join1.pass -tsd2.pass: tsd1.pass -valid1.pass: join1.pass -valid2.pass: valid1.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 + +# The next path is relative to $BUILD_DIR +QAPC = # ..\QueueUserAPCEx\User\quserex.dll + +CPHDR = pthread.h semaphore.h sched.h + +OPTIM = -O2 + +XXLIBS = cw32mti.lib 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) /D_WIN32_WINNT=0x400 -w -tWC -tWM -4 -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 \ + sequence1.pass kill1.pass valid1.pass valid2.pass \ + exit2.pass exit3.pass exit4.pass exit5.pass \ + join0.pass join1.pass detach1.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 \ + robust1.pass robust2.pass robust3.pass robust4.pass robust5.pass \ + count1.pass \ + once1.pass once2.pass once3.pass once4.pass \ + self2.pass \ + cancel1.pass cancel2.pass \ + semaphore4.pass semaphore4t.pass semaphore5.pass \ + barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass barrier6.pass \ + tsd1.pass tsd2.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.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 \ + exception1.pass exception2.pass exception3.pass \ + cancel9.pass stress1.pass + +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 $(BUILD_DIR)\$@ + @ $(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: semaphore4.pass +barrier2.pass: barrier1.pass +barrier3.pass: barrier2.pass +barrier4.pass: barrier3.pass +barrier5.pass: barrier4.pass +barrier6.pass: barrier5.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 +cancel9.pass: cancel8.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: cancel1.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +create2.pass: create1.pass +delay1.pass: +delay2.pass: delay1.pass +detach1.pass: join0.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 +robust1.pass: mutex8r.pass +robust2.pass: mutex8r.pass +robust3.pass: robust2.pass +robust4.pass: robust3.pass +robust5.pass: robust4.pass +rwlock1.pass: condvar6.pass +rwlock2.pass: rwlock1.pass +rwlock3.pass: rwlock2.pass join2.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 +semaphore5.pass: semaphore4.pass +sequence1.pass: reuse2.pass +sizes.pass: +spin1.pass: +spin2.pass: spin1.pass +spin3.pass: spin2.pass +spin4.pass: spin3.pass +stress1.pass: +tsd1.pass: barrier5.pass join1.pass +tsd2.pass: tsd1.pass +valid1.pass: join1.pass +valid2.pass: valid1.pass diff --git a/pthreads/tests/ChangeLog b/pthreads/tests/ChangeLog index b254381b2..dfb4f4555 100644 --- a/pthreads/tests/ChangeLog +++ b/pthreads/tests/ChangeLog @@ -1,918 +1,1000 @@ -2010-06-19 Ross Johnson - - * Makefile (STATICRESULTS): Add all tests into suite for static - library. - * GNUmakefile (STATICTESTS): Likewise, except for openmp1.c which - has a DLL dependency. - -2010-02-04 Ross Johnson - - * openmp1.c: New; for libgomp compatibility (OpenMP). - * barrier5.c: Rewrite after changes to barriers. - * barrier6.c: New. - * benchtest6.c: New; timing barriers. - * GNUMakefile: Update for new tests. - * Makefile: Ditto. - * BMakefile: Ditto. - * once3.c: Improve cancelation testing. - * stress1.c: Fix comment. - -2007-01-04 Ross Johnson - - * context1.c: Include context.h from library sources and remove - x86 dependence in main(). - -2005-06-12 Ross Johnson - - * stress1.c (millisecondsFromNow): Remove limit 0 <= millisecs < 1000; - now works for -INT_MAX <= millisecs <= INT_MAX; not needed for - stress1.c but should be general anyway. - -2005-05-18 Ross Johnson - - * reuse2.c (main): Must use a read with memory barrier semantics - when polling 'done' to force the cache into coherence on MP systems. - -2005-05-15 Ross Johnson - - * detach1.c: New test. - * join1.c: Reduce sleep times. - * join0.c: Remove MSVCRT conditional compile - join should always - return the thread exit code. - * join1.c: Likewise. - * join2.c: Likewise. - * join3.c: Likewise. - -2005-04-18 Ross Johnson - - * 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 - - * 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 - - * 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 - - * 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 - - * mutex5.c: Prevent optimiser from removing asserts. - -2005-03-12 Ross Johnson - - * once3.c: New test. - -2005-03-08 Ross Johnson - - * once2.c: New test. - -2004-11-19 Ross Johnson - - * Bmakefile: New makefile for Borland. - * Makefile (DLL_VER): Added. - * GNUmakefile (DLL_VER): Added. - * Wmakefile (DLL_VER): Added. - -2004-10-29 Ross Johnson - - * 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 - - * 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 - - * semaphore3.c: New test. - -2004-10-14 Ross Johnson - - * rwlock7.c (main): Tidy up statistics reporting; randomise - update accesses. - * rwlock8.c: New test. - -2004-09-08 Alexandre Girao - - * 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 - - * create3.c: New test. - -2004-06-21 Ross Johnson - - * 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 - - * join3.c: New test. - -2004-05-16 Ross Johnson - - * 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 - - * 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 - - * Wmakefile: New makefile for Watcom testing. - -2003-09-18 Ross Johnson - - * 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 - - * priority1.c: Reworked to comply with modified priority - management and provide additional output. - * priority2.c: Likewise. - * inherit1.c: Likewise. - -2003-09-03 Ross Johnson - - * exit4.c: New test. - * exit5.c: New test. - * cancel7.c: New test. - * cancel8.c: New test. - -2003-08-13 Ross Johnson - - * 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 - - * 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 to . - * 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 - - * mutex7e.c: Assert EBUSY return instead of EDEADLK. - -2002-06-03 Ross Johnson - - * semaphore2.c: New test. - -2002-03-02 Ross Johnson - - * Makefile (CFLAGS): Changed /MT to /MD to link with - the correct library MSVCRT.LIB. Otherwise errno doesn't - work. - -2002-02-28 Ross Johnson - - * exception3.c: Correct recent change. - - * semaphore1.c: New test. - - * Makefile: Add rule to generate pre-processor output. - -2002-02-28 Ross Johnson - - * 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 - - * 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 - - * condvar1_1.c: New test. - * condvar1_2.c: New test. - -2002-02-07 Ross Johnson - - * delay1.c: New test. - * delay2.c: New test. - * exit4.c: New test. - -2002-02-02 Ross Johnson - - * 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 - - * cleanup1.c (): Must be declared __cdecl when compiled - as C++ AND testing the standard C library version. - -2002-01-16 Ross Johnson - - * spin4.c (main): Fix renamed function call. - -2002-01-14 Ross Johnson - - * exception3.c (main): Shorten wait time. - -2002-01-09 Ross Johnson - - * 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 - - * 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 - - * barrier5.c: Assert that precisely one thread receives - PTHREAD_BARRIER_SERIAL_THREAD at each barrier. - -2001-07-09 Ross Johnson - - * 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 - - * spin3.c: Changed test and fixed. - * spin4.c: Fixed. - * barrier3.c: Fixed. - * barrier4.c: Fixed. - -2001-07-05 Ross Johnson - - * 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 - - * 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 - - * 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 - - * mutex5.c: Insert inert change to quell compiler warnings. - * condvar3_2.c: Remove unused variable. - -2001-06-3 Ross Johnson - - * condvar2_1.c: New test. - * condvar3_1.c: New test. - * condvar3_2.c: New test. - -2001-05-30 Ross Johnson - - * 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 - - * Makefile: Reorganisation. - * GNUmakefile: Likewise. - - Thomas Pfaff - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * create2.c: New; Test that pthread_t contains - the W32 HANDLE before it calls the thread routine - proper. - -2000-08-13 Ross Johnson - - * 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 - - * 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 - - * 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 - - * cancel2.c: Use PtW32CatchAll macro if defined. - - * exception1.c: Use PtW32CatchAll macro if defined. - -2000-08-02 Ross Johnson - - * 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 - - * 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 - - * 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 - - * 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 - - * test.h: Add header includes; include local header versions rather - than system versions; rearrange the assert macro defines. - -1999-11-07 Ross Johnson - - * loadfree.c: New. Test loading and freeing the library (DLL). - -1999-10-30 Ross Johnson - - * cancel1.c: New. Test pthread_setcancelstate and - pthread_setcanceltype functions. - * eyal1.c (waste_time): Change calculation to avoid FP exception - on Aplhas - - Rich Peters - -Oct 14 1999 Ross Johnson - - * 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 - - * rwlock6.c: New test. - -Sep 15 1999 Ross Johnson - - * 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 - - * runall.bat (join2): Add test. - -Aug 19 1999 Ross Johnson - - * join2.c: New test. - -Wed Aug 12 1999 Ross Johnson - - * Makefile (LIBS): Add -L. - -Mon May 31 10:25:01 1999 Ross Johnson - - * Makefile (GLANG): Add GCC language option. - -Sat May 29 23:29:04 1999 Ross Johnson - - * 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 - - * 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 - - * *.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 - - * 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 - - * 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 - - * 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 - - * tryentercs.c: Apply typo patch from bje. - - * tryentercs2.c: Ditto. - -Sun Mar 7 10:41:52 1999 Ross Johnson - - * 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 - - * 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 - - * 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 - - * self2.c: Bring up to date. - - * self3.c: Ditto. - -1999-02-21 Ben Elliston - - * 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 - - * mutex2.c: Test static mutex initialisation. - - * test.h: New. Declares a table mapping error numbers to - error names. - -1999-01-17 Ross Johnson - - * runtest: New script to build and run a test in the tests directory. - -Wed Dec 30 11:22:44 1998 Ross Johnson - - * 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 - - * tsd1.c (destroy_key): Add function. Change diagnostics. - -Thu Oct 15 17:42:37 1998 Ross Johnson - - * tsd1.c (mythread): Fix some casts and add some message - output. Fix inverted conditional. - -Mon Oct 12 02:12:29 1998 Ross Johnson - - * tsd1.c: New. Test TSD using 1 key and 2 threads. - -1998-09-13 Ben Elliston - - * eyal1.c: New file; contributed by Eyal Lebedinsky - . - -1998-09-12 Ben Elliston - - * exit2.c (func): Return a value. - (main): Call the right thread entry function. - -1998-07-22 Ben Elliston - - * exit2.c (main): Fix size of pthread_t array. - -1998-07-10 Ben Elliston - - * exit2.c: New file; test pthread_exit() harder. - - * exit1.c: New file; test pthread_exit(). +2011-07-03 Ross Johnson + + * create3.c: Removed; testing a condition that is not in the library's + scope and was more trouble than it was worth. + * cancel2.c: Ensure this test only runs for Structured or C++ EH. + * exit2.c: Shorten Sleep() time. + * exit3.c: Likewise. + * cancel1.c: Likewise. + * cancel3.c: Likewise. + * exception3.c: Likewise; make terminate routine consistent for all + build environments. + +2011-07-02 Ross Johnson + + * spin3.c: Unlock the unlocked spinlock now returns success. + * rwlock3.c: Join the thread to ensure it's completed. + * rwlock4.c: Likewise. + * rwlock5.c: Likewise. + * Makefile: Adjust prerequisites. + * GNUmakefile: Likewise. + * Bmakefile: Likewise. + * Wmakefile: Likewise. + +2011-07-02 Daniel Richard G. + + * *.[ch]: Cleanups around timeb struct, mainly centralising + macro definitions in test.h. + * Makefile: Fix annoying nmake warning. + +2011-06-30 Ross Johnson + + * sequence1.c: Fix loop overrun. + +2011-05-11 Ross Johnson + + * GNUmakefile (GCE-debug): New target; expects pthreadGCE2d.dll. + +2011-05-05 Ross Johnson + + * openmp1.c: Add missing test; used to comfirm that this + library works with libgomp; if this test produces a segfault + then try upgrading your version of libgomp/gcc; gcc version + 4.5.2 passes this test. + +2011-03-26 Ross Johnson + + * sequence1.c: New test for new pthread_getsequence_np(). + +2011-03-24 Ross Johnson + + * mutex*.c: Include tests for robust mutexes wherever + appropriate. + * benchtest*.c: Include comparisons for robust mutexes. + * robust1.c: New test for robust mutex handling. + * robust2.c: Likewise. + * robust3.c: Likewise. + * robust4.c: Likewise. + * robust5.c: Likewise. + * GNUmakefile: Include new tests. + * Makefile: Likewise. + * Bmakefile: Likewise (not tested). + * Wmakefile: Likewise (not tested). + +2011-03-06 Ross Johnson + + * several (MINGW64): Cast and call fixups for 64 bit compatibility; + clean build via x86_64-w64-mingw32 cross toolchain on Linux + i686 targeting x86_64 win64. + +2011-03-04 Ross Johnson + + * condvar3_2.c: abstime.tv_sec operation warning fixed. + * several: Use correct casting on pthread_join result arg + and associated declaration and usage; assumed that 64 bit + gcc gave some warnings for it. + +2011-02-28 Ross Johnson + + * test.h: Define FTIME to be _ftime64_s or _ftime64 or _ftime + in that order of preference where supported. + * several: Replace calls to _ftime with the FTIME macro. + +2010-06-19 Ross Johnson + + * Makefile (STATICRESULTS): Add all tests into suite for static + library. + * GNUmakefile (STATICTESTS): Likewise, except for openmp1.c which + has a DLL dependency. + +2010-02-04 Ross Johnson + + * openmp1.c: New; for libgomp compatibility (OpenMP). + * barrier5.c: Rewrite after changes to barriers. + * barrier6.c: New. + * benchtest6.c: New; timing barriers. + * GNUMakefile: Update for new tests. + * Makefile: Ditto. + * BMakefile: Ditto. + * once3.c: Improve cancelation testing. + * stress1.c: Fix comment. + +2007-01-04 Ross Johnson + + * context1.c: Include context.h from library sources and remove + x86 dependence in main(). + +2005-06-12 Ross Johnson + + * stress1.c (millisecondsFromNow): Remove limit 0 <= millisecs < 1000; + now works for -INT_MAX <= millisecs <= INT_MAX; not needed for + stress1.c but should be general anyway. + +2005-05-18 Ross Johnson + + * reuse2.c (main): Must use a read with memory barrier semantics + when polling 'done' to force the cache into coherence on MP systems. + +2005-05-15 Ross Johnson + + * detach1.c: New test. + * join1.c: Reduce sleep times. + * join0.c: Remove MSVCRT conditional compile - join should always + return the thread exit code. + * join1.c: Likewise. + * join2.c: Likewise. + * join3.c: Likewise. + +2005-04-18 Ross Johnson + + * 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 + + * 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 + + * 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 + + * 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 + + * mutex5.c: Prevent optimiser from removing asserts. + +2005-03-12 Ross Johnson + + * once3.c: New test. + +2005-03-08 Ross Johnson + + * once2.c: New test. + +2004-11-19 Ross Johnson + + * Bmakefile: New makefile for Borland. + * Makefile (DLL_VER): Added. + * GNUmakefile (DLL_VER): Added. + * Wmakefile (DLL_VER): Added. + +2004-10-29 Ross Johnson + + * 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 + + * 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 + + * semaphore3.c: New test. + +2004-10-14 Ross Johnson + + * rwlock7.c (main): Tidy up statistics reporting; randomise + update accesses. + * rwlock8.c: New test. + +2004-09-08 Alexandre Girao + + * 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 + + * create3.c: New test. + +2004-06-21 Ross Johnson + + * 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 + + * join3.c: New test. + +2004-05-16 Ross Johnson + + * 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 + + * 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 + + * Wmakefile: New makefile for Watcom testing. + +2003-09-18 Ross Johnson + + * 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 + + * priority1.c: Reworked to comply with modified priority + management and provide additional output. + * priority2.c: Likewise. + * inherit1.c: Likewise. + +2003-09-03 Ross Johnson + + * exit4.c: New test. + * exit5.c: New test. + * cancel7.c: New test. + * cancel8.c: New test. + +2003-08-13 Ross Johnson + + * 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 + + * 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 to . + * 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 + + * mutex7e.c: Assert EBUSY return instead of EDEADLK. + +2002-06-03 Ross Johnson + + * semaphore2.c: New test. + +2002-03-02 Ross Johnson + + * Makefile (CFLAGS): Changed /MT to /MD to link with + the correct library MSVCRT.LIB. Otherwise errno doesn't + work. + +2002-02-28 Ross Johnson + + * exception3.c: Correct recent change. + + * semaphore1.c: New test. + + * Makefile: Add rule to generate pre-processor output. + +2002-02-28 Ross Johnson + + * 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 + + * 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 + + * condvar1_1.c: New test. + * condvar1_2.c: New test. + +2002-02-07 Ross Johnson + + * delay1.c: New test. + * delay2.c: New test. + * exit4.c: New test. + +2002-02-02 Ross Johnson + + * 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 + + * cleanup1.c (): Must be declared __cdecl when compiled + as C++ AND testing the standard C library version. + +2002-01-16 Ross Johnson + + * spin4.c (main): Fix renamed function call. + +2002-01-14 Ross Johnson + + * exception3.c (main): Shorten wait time. + +2002-01-09 Ross Johnson + + * 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 + + * 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 + + * barrier5.c: Assert that precisely one thread receives + PTHREAD_BARRIER_SERIAL_THREAD at each barrier. + +2001-07-09 Ross Johnson + + * 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 + + * spin3.c: Changed test and fixed. + * spin4.c: Fixed. + * barrier3.c: Fixed. + * barrier4.c: Fixed. + +2001-07-05 Ross Johnson + + * 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 + + * 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 + + * 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 + + * mutex5.c: Insert inert change to quell compiler warnings. + * condvar3_2.c: Remove unused variable. + +2001-06-3 Ross Johnson + + * condvar2_1.c: New test. + * condvar3_1.c: New test. + * condvar3_2.c: New test. + +2001-05-30 Ross Johnson + + * 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 + + * Makefile: Reorganisation. + * GNUmakefile: Likewise. + - Thomas Pfaff + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * create2.c: New; Test that pthread_t contains + the W32 HANDLE before it calls the thread routine + proper. + +2000-08-13 Ross Johnson + + * 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 + + * 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 + + * 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 + + * cancel2.c: Use PtW32CatchAll macro if defined. + + * exception1.c: Use PtW32CatchAll macro if defined. + +2000-08-02 Ross Johnson + + * 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 + + * 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 + + * 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 + + * 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 + + * test.h: Add header includes; include local header versions rather + than system versions; rearrange the assert macro defines. + +1999-11-07 Ross Johnson + + * loadfree.c: New. Test loading and freeing the library (DLL). + +1999-10-30 Ross Johnson + + * cancel1.c: New. Test pthread_setcancelstate and + pthread_setcanceltype functions. + * eyal1.c (waste_time): Change calculation to avoid FP exception + on Aplhas + - Rich Peters + +Oct 14 1999 Ross Johnson + + * 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 + + * rwlock6.c: New test. + +Sep 15 1999 Ross Johnson + + * 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 + + * runall.bat (join2): Add test. + +Aug 19 1999 Ross Johnson + + * join2.c: New test. + +Wed Aug 12 1999 Ross Johnson + + * Makefile (LIBS): Add -L. + +Mon May 31 10:25:01 1999 Ross Johnson + + * Makefile (GLANG): Add GCC language option. + +Sat May 29 23:29:04 1999 Ross Johnson + + * 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 + + * 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 + + * *.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 + + * 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 + + * 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 + + * 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 + + * tryentercs.c: Apply typo patch from bje. + + * tryentercs2.c: Ditto. + +Sun Mar 7 10:41:52 1999 Ross Johnson + + * 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 + + * 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 + + * 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 + + * self2.c: Bring up to date. + + * self3.c: Ditto. + +1999-02-21 Ben Elliston + + * 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 + + * mutex2.c: Test static mutex initialisation. + + * test.h: New. Declares a table mapping error numbers to + error names. + +1999-01-17 Ross Johnson + + * runtest: New script to build and run a test in the tests directory. + +Wed Dec 30 11:22:44 1998 Ross Johnson + + * 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 + + * tsd1.c (destroy_key): Add function. Change diagnostics. + +Thu Oct 15 17:42:37 1998 Ross Johnson + + * tsd1.c (mythread): Fix some casts and add some message + output. Fix inverted conditional. + +Mon Oct 12 02:12:29 1998 Ross Johnson + + * tsd1.c: New. Test TSD using 1 key and 2 threads. + +1998-09-13 Ben Elliston + + * eyal1.c: New file; contributed by Eyal Lebedinsky + . + +1998-09-12 Ben Elliston + + * exit2.c (func): Return a value. + (main): Call the right thread entry function. + +1998-07-22 Ben Elliston + + * exit2.c (main): Fix size of pthread_t array. + +1998-07-10 Ben Elliston + + * exit2.c: New file; test pthread_exit() harder. + + * exit1.c: New file; test pthread_exit(). diff --git a/pthreads/tests/GNUmakefile b/pthreads/tests/GNUmakefile index 4c9ed765b..355c27e8c 100644 --- a/pthreads/tests/GNUmakefile +++ b/pthreads/tests/GNUmakefile @@ -1,408 +1,442 @@ -# 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 -k - -# -# Mingw32 -# -XXCFLAGS = -XXLIBS = -lws2_32 -lgomp -#CFLAGS = -O3 -UNDEBUG -Wall $(XXCFLAGS) -CFLAGS = -O3 -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 -# The next path is relative to $BUILD_DIR -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 detach1 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 self2 \ - cancel1 cancel2 \ - semaphore4 semaphore4t semaphore5 \ - barrier1 barrier2 barrier3 barrier4 barrier5 barrier6 \ - tsd1 tsd2 openmp1 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 \ - exception1 exception2 exception3 \ - cancel9 create3 stress1 - -STRESSTESTS = \ - stress1 - -BENCHTESTS = \ - benchtest1 benchtest2 benchtest3 benchtest4 benchtest5 benchtest6 - -STATICTESTS = \ - sizes \ - 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 detach1 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 self2 \ - cancel1 cancel2 \ - semaphore4 semaphore4t semaphore5 \ - barrier1 barrier2 barrier3 barrier4 barrier5 barrier6 \ - tsd1 tsd2 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 \ - exception1 exception2 exception3 \ - cancel9 create3 stress1 - -PASSES = $(TESTS:%=%.pass) -BENCHRESULTS = $(BENCHTESTS:%=%.bench) -STRESSRESULTS = $(STRESSTESTS:%=%.pass) -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-stress (to stresstest using GNU C dll with C cleanup code)" - @ $(ECHO) "make clean GCE-stress (to stresstest 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="-fopenmp -D__CLEANUP_C" all-pass - -GCE: - $(MAKE) TEST=GCE CC=g++ XXCFLAGS="-fopenmp -mthreads -D__CLEANUP_CXX" all-pass - -GCX: - $(MAKE) TEST=GC CC=g++ XXCFLAGS="-fopenmp -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-debug: - $(MAKE) TEST=GC CC=gcc XXCFLAGS="-fopenmp -D__CLEANUP_C" DLL_VER="$(DLL_VER)d" all-pass - -GC-static: - $(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C -DPTW32_STATIC_LIB" XXLIBS="-lws2_32" DLL="" all-static - -GC-stress: - $(ECHO) Stress tests can take a long time since they are trying to - $(ECHO) expose weaknesses that may be intermittant or statistically rare. - $(ECHO) A pass does not prove correctness, but may give greater confidence. - $(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" XXLIBS="" all-stress - -GCE-stress: - $(MAKE) TEST=GCE CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" XXLIBS="" all-stress - -all-pass: $(PASSES) - @ $(ECHO) ALL TESTS PASSED! Congratulations! - -all-bench: $(BENCHRESULTS) - @ $(ECHO) BENCH TESTS COMPLETED. - -all-stress: $(STRESSRESULTS) - @ $(ECHO) STRESS TESTS COMPLETED. - -all-static: $(STATICRESULTS) - @ $(ECHO) ALL STATIC TESTS PASSED! Congratulations! - -benchtest1.bench: -benchtest2.bench: -benchtest3.bench: -benchtest4.bench: -benchtest5.bench: -benchtest6.bench: - -barrier1.pass: semaphore4.pass -barrier2.pass: barrier1.pass -barrier3.pass: barrier2.pass -barrier4.pass: barrier3.pass -barrier5.pass: barrier4.pass -barrier6.pass: barrier5.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 -cancel9.pass: cancel8.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 -detach1.pass: join0.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 -openmp1.pass: tsd2.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 -semaphore5.pass: semaphore4.pass -sizes.pass: -spin1.pass: -spin2.pass: spin1.pass -spin3.pass: spin2.pass -spin4.pass: spin3.pass -stress1.pass: -tsd1.pass: barrier5.pass join1.pass -tsd2.pass: tsd1.pass -valid1.pass: join1.pass -valid2.pass: valid1.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 $(BUILD_DIR)/$@ - @ $(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) *.so - - $(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 +MKDIR = mkdir +TOUCH = echo Passed > +ECHO = @echo +MAKE = make -k + +# For cross compiling use e.g. +# # make CROSS=i386-mingw32msvc- clean GC +CROSS = + +AR = $(CROSS)ar +DLLTOOL = $(CROSS)dlltool +CC = $(CROSS)gcc +CXX = $(CROSS)g++ +RANLIB = $(CROSS)ranlib + +# +# Mingw32 +# +XXCFLAGS = +XXLIBS = -lws2_32 -lgomp +OPT = -O3 +DOPT = -g -O0 +#CFLAGS = -O3 -UNDEBUG -Wall $(XXCFLAGS) +CFLAGS = ${OPT} -UNDEBUG -Wall $(XXCFLAGS) +BUILD_DIR = .. +INCLUDES = -I. + +.INTERMEDIATE: %.exe %.pass +.SECONDARY: %.exe %.pass +.PRECIOUS: %.exe %.pass + +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 +# The next path is relative to $BUILD_DIR +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 \ + sequence1 kill1 valid1 valid2 \ + exit2 exit3 exit4 exit5 \ + join0 join1 detach1 join2 join3 \ + mutex2 mutex2r mutex2e mutex3 mutex3r mutex3e \ + mutex4 mutex6 mutex6n mutex6e mutex6r \ + mutex6s mutex6es mutex6rs \ + mutex7 mutex7n mutex7e mutex7r mutex8 mutex8n mutex8e mutex8r \ + robust1 robust2 robust3 robust4 robust5 \ + count1 \ + once1 once2 once3 once4 self2 \ + cancel1 cancel2 \ + semaphore4 semaphore4t semaphore5 \ + barrier1 barrier2 barrier3 barrier4 barrier5 barrier6 \ + tsd1 tsd2 openmp1 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 \ + exception1 exception2 exception3 \ + cancel9 stress1 + +STRESSTESTS = \ + stress1 + +BENCHTESTS = \ + benchtest1 benchtest2 benchtest3 benchtest4 benchtest5 + +STATICTESTS = \ + sizes \ + self1 mutex5 mutex1 mutex1e mutex1n mutex1r \ + semaphore1 semaphore2 semaphore3 \ + condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 \ + create1 create2 reuse1 reuse2 equal1 \ + sequence1 kill1 valid1 valid2 \ + exit2 exit3 exit4 exit5 \ + join0 join1 detach1 join2 join3 \ + mutex2 mutex2r mutex2e mutex3 mutex3r mutex3e \ + mutex4 mutex6 mutex6n mutex6e mutex6r \ + mutex6s mutex6es mutex6rs \ + mutex7 mutex7n mutex7e mutex7r mutex8 mutex8n mutex8e mutex8r \ + robust1 robust2 robust3 robust4 robust5 \ + count1 \ + once1 once2 once3 once4 self2 \ + cancel1 cancel2 \ + semaphore4 semaphore4t semaphore5 \ + barrier1 barrier2 barrier3 barrier4 barrier5 barrier6 \ + tsd1 tsd2 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 \ + exception1 exception2 exception3 \ + cancel9 stress1 + +ALLTESTS = $(TESTS) $(BENCHTESTS) + +ASM = $(ALLTESTS:%=%.s) +PASSES = $(TESTS:%=%.pass) +BENCHRESULTS = $(BENCHTESTS:%=%.bench) +STRESSRESULTS = $(STRESSTESTS:%=%.pass) +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-stress (to stresstest using GNU C dll with C cleanup code)" + @ $(ECHO) "make clean GCE-stress (to stresstest using GNU C dll with C++ exception handling)" + @ $(ECHO) "make clean GC-static (to test using GC static lib with C (no EH) applications)" + @ $(ECHO) "make clean GC-debug (to test using GC dll with C (no EH) applications)" + +all: + @ $(MAKE) clean GC + @ $(MAKE) clean GCX + @ $(MAKE) clean GCE + +GC: + $(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-fopenmp -D__CLEANUP_C" all-pass + +GC-asm: + $(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-fopenmp -D__CLEANUP_C" all-asm + +GCE: + $(MAKE) TEST=GCE CC=$(CXX) XXCFLAGS="-fopenmp -mthreads -D__CLEANUP_CXX" all-pass + +GCX: + $(MAKE) TEST=GC CC=$(CXX) XXCFLAGS="-fopenmp -mthreads -D__CLEANUP_C" all-pass + +GC-bench: + $(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-D__CLEANUP_C" XXLIBS="benchlib.o" all-bench + +GCE-bench: + $(MAKE) TEST=GCE CC=$(CXX) XXCFLAGS="-mthreads -D__CLEANUP_CXX" XXLIBS="benchlib." all-bench + +GC-debug: + $(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-fopenmp -D__CLEANUP_C" OPT="${DOPT}" DLL_VER="$(DLL_VER)d" all-pass + +GCE-debug: + $(MAKE) TEST=GCE CC=$(CXX) XXCFLAGS="-fopenmp -D__CLEANUP_CXX" OPT="${DOPT}" DLL_VER="$(DLL_VER)d" all-pass + +GC-bench-debug: + $(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-D__CLEANUP_C" XXLIBS="benchlib.o" OPT="${OPT}" DLL_VER="$(DLL_VER)d" all-bench + +GC-static: + $(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-D__CLEANUP_C -DPTW32_STATIC_LIB" XXLIBS="-lws2_32" DLL="" all-static + +GC-stress: + $(ECHO) Stress tests can take a long time since they are trying to + $(ECHO) expose weaknesses that may be intermittant or statistically rare. + $(ECHO) A pass does not prove correctness, but may give greater confidence. + $(MAKE) TEST=GC CC=$(CC) XXCFLAGS="-D__CLEANUP_C" XXLIBS="" all-stress + +GCE-stress: + $(MAKE) TEST=GCE CC=$(CXX) XXCFLAGS="-mthreads -D__CLEANUP_CXX" XXLIBS="" all-stress + +all-asm: $(ASM) + @ $(ECHO) ALL TESTS PASSED! Congratulations! + +all-pass: $(PASSES) + @ $(ECHO) ALL TESTS PASSED! Congratulations! + +all-bench: $(BENCHRESULTS) + @ $(ECHO) BENCH TESTS COMPLETED. + +all-stress: $(STRESSRESULTS) + @ $(ECHO) STRESS TESTS COMPLETED. + +all-static: $(STATICRESULTS) + @ $(ECHO) ALL STATIC TESTS PASSED! Congratulations! + +benchtest1.bench: +benchtest2.bench: +benchtest3.bench: +benchtest4.bench: +benchtest5.bench: + +barrier1.pass: semaphore4.pass +barrier2.pass: barrier1.pass +barrier3.pass: barrier2.pass +barrier4.pass: barrier3.pass +barrier5.pass: barrier4.pass +barrier6.pass: barrier5.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 +cancel9.pass: cancel8.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: cancel1.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +create2.pass: create1.pass +delay1.pass: +delay2.pass: delay1.pass +detach1.pass: join0.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 +openmp1.pass: tsd2.pass +priority1.pass: join1.pass +priority2.pass: priority1.pass barrier3.pass +reuse1.pass: create2.pass +reuse2.pass: reuse1.pass +robust1.pass: mutex8r.pass +robust2.pass: mutex8r.pass +robust3.pass: robust2.pass +robust4.pass: robust3.pass +robust5.pass: robust4.pass +rwlock1.pass: condvar6.pass +rwlock2.pass: rwlock1.pass +rwlock3.pass: rwlock2.pass join2.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 +semaphore5.pass: semaphore4.pass +sequence1.pass: reuse2.pass +sizes.pass: +spin1.pass: +spin2.pass: spin1.pass +spin3.pass: spin2.pass +spin4.pass: spin3.pass +stress1.pass: +tsd1.pass: barrier5.pass join1.pass +tsd2.pass: tsd1.pass +valid1.pass: join1.pass +valid2.pass: valid1.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) + @ $(ECHO) Compiling $@ + @ $(CC) -S $(CFLAGS) -o $@ $< $(INCLUDES) + +$(COPYFILES): + @ $(ECHO) Copying $(BUILD_DIR)/$@ + @ $(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) *.s + - $(RM) *.so + - $(RM) *.obj + - $(RM) *.pdb + - $(RM) *.exe + - $(RM) *.pass + - $(RM) *.bench + - $(RM) *.static + - $(RM) *.log diff --git a/pthreads/tests/Makefile b/pthreads/tests/Makefile index 8c89349c1..9b0ca3094 100644 --- a/pthreads/tests/Makefile +++ b/pthreads/tests/Makefile @@ -1,442 +1,449 @@ -# 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 - -# The next path is relative to $BUILD_DIR -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 /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 detach1.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 \ - self2.pass \ - cancel1.pass cancel2.pass \ - semaphore4.pass semaphore4t.pass semaphore5.pass \ - barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass barrier6.pass \ - tsd1.pass tsd2.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 \ - exception1.pass exception2.pass exception3.pass \ - cancel9.pass create3.pass stress1.pass - -BENCHRESULTS = \ - benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench \ - benchtest6.bench - -STRESSRESULTS = \ - stress1.stress - -STATICRESULTS = \ - sizes.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 detach1.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 \ - self2.pass \ - cancel1.pass cancel2.pass \ - semaphore4.pass semaphore4t.pass semaphore5.pass \ - barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass barrier6.pass \ - tsd1.pass tsd2.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 \ - exception1.pass exception2.pass exception3.pass \ - cancel9.pass create3.pass stress1.pass - -help: - @ $(ECHO) Run one of the following command lines: - @ $(ECHO) nmake clean VC (to test using VC dll with VC (no EH) apps) - @ $(ECHO) nmake clean VC-bench (to benchtest using VC dll with C bench apps) - @ $(ECHO) nmake clean VC-stress (to stresstest using VC dll with C stress apps) - @ $(ECHO) nmake clean VC-static (to test using VC static lib with VC (no EH) apps) - @ $(ECHO) nmake clean VCX (to test using VC dll with VC++ (EH) applications) - @ $(ECHO) nmake clean VCX-bench (to benchtest using VC dll with C++ bench apps) - @ $(ECHO) nmake clean VCX-stress (to stresstest using VC dll with C++ stress apps) - @ $(ECHO) nmake clean VCE (to test using the VCE dll with VC++ EH applications) - @ $(ECHO) nmake clean VCE-bench (to benchtest using VCE dll with C++ bench apps) - @ $(ECHO) nmake clean VCE-stress (to stresstest using VCE dll with C++ stress apps) - @ $(ECHO) nmake clean VSE (to test using VSE dll with VC (SEH) apps) - @ $(ECHO) nmake clean VSE-bench (to benchtest using VSE dll with SEH bench apps) - @ $(ECHO) nmake clean VSE-stress (to stresstest using VSE dll with SEH stress apps) - -all: - @ nmake clean VC - @ nmake clean VCX - @ nmake clean VCE - @ nmake clean VSE - @ nmake clean VC-bench - @ nmake clean VC-stress - -# 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. - -stresstests: $(CPLIB) $(CPDLL) $(CPHDR) $(STRESSRESULTS) - @ $(ECHO) ALL STRESS TESTS DONE. - -statictests: $(CPLIB) $(CPDLL) $(CPHDR) $(STATICRESULTS) - @ $(ECHO) ALL STATIC TESTS DONE. - -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 - -$(STRESSRESULTS): $*.exe - @ $(ECHO) ... Running $(TEST) stresstest: $*.exe - @ .\$*.exe - @ $(ECHO) ...... Done - @ $(TOUCH) $*.pass - -VC: - @ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" tests - -VCE: - @ nmake TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" tests - -VSE: - @ nmake TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" tests - -VCX: - @ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" tests - -VC-bench: - @ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" XXLIBS="benchlib.o" benchtests - -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 - -VCX-bench: - @ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" XXLIBS="benchlib.o" benchtests - -VC-stress: - @ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" stresstests - -VCE-stress: - @ nmake TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" stresstests - -VSE-stress: - @ nmake TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" stresstests - -VCX-stress: - @ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" stresstests - -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 $(BUILD_DIR)\$@ - @ $(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: -benchtest6.bench: - -barrier1.pass: semaphore4.pass -barrier2.pass: barrier1.pass -barrier3.pass: barrier2.pass -barrier4.pass: barrier3.pass -barrier5.pass: barrier4.pass -barrier6.pass: barrier5.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 -cancel9.pass: cancel8.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 -detach1.pass: join0.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 -semaphore5.pass: semaphore4.pass -sizes.pass: -spin1.pass: -spin2.pass: spin1.pass -spin3.pass: spin2.pass -spin4.pass: spin3.pass -stress1.pass: condvar9.pass barrier5.pass -tsd1.pass: barrier5.pass join1.pass -tsd2.pass: tsd1.pass -valid1.pass: join1.pass -valid2.pass: valid1.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 + +# The next path is relative to $BUILD_DIR +QAPC = # ..\QueueUserAPCEx\User\quserex.dll + +CPHDR = pthread.h semaphore.h sched.h + +OPTIM = /O2 /Ob0 + +XXLIBS = ws2_32.lib + +# C++ Exceptions +VCEFLAGS = /EHsc /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 = /EHsc /TP /D__CLEANUP_C + +# Defaults +CPLIB = $(VCLIB) +CPDLL = $(VCDLL) + +CFLAGS= $(OPTIM) /W3 /MD /nologo /Z7 +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 $(REGULAR_PASSES) + +REGULAR_PASSES = 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 \ + sequence1.pass kill1.pass valid1.pass valid2.pass \ + exit2.pass exit3.pass exit4.pass exit5.pass \ + join0.pass join1.pass detach1.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 \ + robust1.pass robust2.pass robust3.pass robust4.pass robust5.pass \ + count1.pass \ + once1.pass once2.pass once3.pass once4.pass \ + self2.pass \ + cancel1.pass cancel2.pass \ + semaphore4.pass semaphore4t.pass semaphore5.pass \ + barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass barrier6.pass \ + tsd1.pass tsd2.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 \ + exception1.pass exception2.pass exception3.pass \ + cancel9.pass stress1.pass + +BENCHRESULTS = \ + benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench + +STRESSRESULTS = \ + stress1.stress + +STATICRESULTS = \ + sizes.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 \ + sequence1.pass kill1.pass valid1.pass valid2.pass \ + exit2.pass exit3.pass exit4.pass exit5.pass \ + join0.pass join1.pass detach1.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 \ + robust1.pass robust2.pass robust3.pass robust4.pass robust5.pass \ + count1.pass \ + once1.pass once2.pass once3.pass once4.pass \ + self2.pass \ + cancel1.pass cancel2.pass \ + semaphore4.pass semaphore4t.pass semaphore5.pass \ + barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass barrier6.pass \ + tsd1.pass tsd2.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 \ + exception1.pass exception2.pass exception3.pass \ + cancel9.pass stress1.pass + +help: + @ $(ECHO) Run one of the following command lines: + @ $(ECHO) nmake clean VC (to test using VC dll with VC (no EH) apps) + @ $(ECHO) nmake clean VC-bench (to benchtest using VC dll with C bench apps) + @ $(ECHO) nmake clean VC-stress (to stresstest using VC dll with C stress apps) + @ $(ECHO) nmake clean VC-static (to test using VC static lib with VC (no EH) apps) + @ $(ECHO) nmake clean VCX (to test using VC dll with VC++ (EH) applications) + @ $(ECHO) nmake clean VCX-bench (to benchtest using VC dll with C++ bench apps) + @ $(ECHO) nmake clean VCX-stress (to stresstest using VC dll with C++ stress apps) + @ $(ECHO) nmake clean VCE (to test using the VCE dll with VC++ EH applications) + @ $(ECHO) nmake clean VCE-bench (to benchtest using VCE dll with C++ bench apps) + @ $(ECHO) nmake clean VCE-stress (to stresstest using VCE dll with C++ stress apps) + @ $(ECHO) nmake clean VSE (to test using VSE dll with VC (SEH) apps) + @ $(ECHO) nmake clean VSE-bench (to benchtest using VSE dll with SEH bench apps) + @ $(ECHO) nmake clean VSE-stress (to stresstest using VSE dll with SEH stress apps) + +all: + @ $(MAKE) /E clean VC + @ $(MAKE) /E clean VCX + @ $(MAKE) /E clean VCE + @ $(MAKE) /E clean VSE + @ $(MAKE) /E clean VC-bench + @ $(MAKE) /E clean VC-stress + +# 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. + +stresstests: $(CPLIB) $(CPDLL) $(CPHDR) $(STRESSRESULTS) + @ $(ECHO) ALL STRESS TESTS DONE. + +statictests: $(CPLIB) $(CPDLL) $(CPHDR) $(STATICRESULTS) + @ $(ECHO) ALL STATIC TESTS DONE. + +sizes.pass: sizes.exe + @ $(ECHO) ... Running $(TEST)$(DLL_VER) test: $*.exe + @ .\$*.exe > SIZES.$(TEST) + @ $(CAT) SIZES.$(TEST) + @ $(ECHO) ...... Passed + @ $(TOUCH) $*.pass + +$(REGULAR_PASSES): $*.exe + @ $(ECHO) ... Running $(TEST) test: $*.exe + @ .\$*.exe + @ $(ECHO) ...... Passed + @ $(TOUCH) $*.pass + +$(BENCHRESULTS): $*.exe + @ $(ECHO) ... Running $(TEST) benchtest: $*.exe + @ .\$*.exe + @ $(ECHO) ...... Done + @ $(TOUCH) $*.bench + +$(STRESSRESULTS): $*.exe + @ $(ECHO) ... Running $(TEST) stresstest: $*.exe + @ .\$*.exe + @ $(ECHO) ...... Done + @ $(TOUCH) $*.pass + +VC: + @ $(MAKE) /E TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" tests + +VCE: + @ $(MAKE) /E TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" tests + +VSE: + @ $(MAKE) /E TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" tests + +VCX: + @ $(MAKE) /E TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" tests + +VC-bench: + @ $(MAKE) /E TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" XXLIBS="benchlib.o" benchtests + +VCE-bench: + @ $(MAKE) /E TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" XXLIBS="benchlib.o" benchtests + +VSE-bench: + @ $(MAKE) /E TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" XXLIBS="benchlib.o" benchtests + +VCX-bench: + @ $(MAKE) /E TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" XXLIBS="benchlib.o" benchtests + +VC-stress: + @ $(MAKE) /E TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" stresstests + +VCE-stress: + @ $(MAKE) /E TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" stresstests + +VSE-stress: + @ $(MAKE) /E TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" stresstests + +VCX-stress: + @ $(MAKE) /E TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" stresstests + +VC-static: + @ $(MAKE) /E 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 $(BUILD_DIR)\$@ + @ $(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: semaphore4.pass +barrier2.pass: barrier1.pass +barrier3.pass: barrier2.pass +barrier4.pass: barrier3.pass +barrier5.pass: barrier4.pass +barrier6.pass: barrier5.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 +cancel9.pass: cancel8.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: cancel1.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +create2.pass: create1.pass +delay1.pass: +delay2.pass: delay1.pass +detach1.pass: join0.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 +robust1.pass: mutex8r.pass +robust2.pass: mutex8r.pass +robust3.pass: robust2.pass +robust4.pass: robust3.pass +robust5.pass: robust4.pass +rwlock1.pass: condvar6.pass +rwlock2.pass: rwlock1.pass +rwlock3.pass: rwlock2.pass join2.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 +semaphore5.pass: semaphore4.pass +sequence1.pass: reuse2.pass +sizes.pass: +spin1.pass: +spin2.pass: spin1.pass +spin3.pass: spin2.pass +spin4.pass: spin3.pass +stress1.pass: condvar9.pass barrier5.pass +tsd1.pass: barrier5.pass join1.pass +tsd2.pass: tsd1.pass +valid1.pass: join1.pass +valid2.pass: valid1.pass diff --git a/pthreads/tests/SIZES.GC b/pthreads/tests/SIZES.GC index 5c5df2952..d5ddf363f 100644 --- a/pthreads/tests/SIZES.GC +++ b/pthreads/tests/SIZES.GC @@ -1,21 +1,21 @@ -Sizes of pthreads-win32 structs -------------------------------- - pthread_t 8 - ptw32_thread_t 140 - pthread_attr_t_ 28 - sem_t_ 12 - pthread_mutex_t_ 24 - pthread_mutexattr_t_ 8 - pthread_spinlock_t_ 8 - pthread_barrier_t_ 36 - pthread_barrierattr_t_ 4 - pthread_key_t_ 16 - pthread_cond_t_ 32 - pthread_condattr_t_ 4 - pthread_rwlock_t_ 28 - pthread_rwlockattr_t_ 4 - pthread_once_t_ 16 - ptw32_cleanup_t 12 - ptw32_mcs_node_t_ 16 - sched_param 4 -------------------------------- +Sizes of pthreads-win32 structs +------------------------------- + pthread_t 8 + ptw32_thread_t 160 + pthread_attr_t_ 28 + sem_t_ 12 + pthread_mutex_t_ 28 + pthread_mutexattr_t_ 12 + pthread_spinlock_t_ 8 + pthread_barrier_t_ 36 + pthread_barrierattr_t_ 4 + pthread_key_t_ 16 + pthread_cond_t_ 32 + pthread_condattr_t_ 4 + pthread_rwlock_t_ 28 + pthread_rwlockattr_t_ 4 + pthread_once_t_ 16 + ptw32_cleanup_t 12 + ptw32_mcs_node_t_ 16 + sched_param 4 +------------------------------- diff --git a/pthreads/tests/SIZES.GCE b/pthreads/tests/SIZES.GCE index 0db5de0b4..709114d52 100644 --- a/pthreads/tests/SIZES.GCE +++ b/pthreads/tests/SIZES.GCE @@ -1,21 +1,21 @@ Sizes of pthreads-win32 structs ------------------------------- - pthread_t 8 - ptw32_thread_t 76 + pthread_t 8 + ptw32_thread_t 96 pthread_attr_t_ 28 - sem_t_ 12 - pthread_mutex_t_ 24 - pthread_mutexattr_t_ 8 + sem_t_ 12 + pthread_mutex_t_ 28 + pthread_mutexattr_t_ 12 pthread_spinlock_t_ 8 - pthread_barrier_t_ 36 + pthread_barrier_t_ 36 pthread_barrierattr_t_ 4 pthread_key_t_ 16 pthread_cond_t_ 32 pthread_condattr_t_ 4 pthread_rwlock_t_ 28 pthread_rwlockattr_t_ 4 - pthread_once_t_ 16 + pthread_once_t_ 16 ptw32_cleanup_t 12 - ptw32_mcs_node_t_ 16 + ptw32_mcs_node_t_ 16 sched_param 4 ------------------------------- diff --git a/pthreads/tests/SIZES.VC b/pthreads/tests/SIZES.VC index ae09a84e6..d5ddf363f 100644 --- a/pthreads/tests/SIZES.VC +++ b/pthreads/tests/SIZES.VC @@ -1,20 +1,21 @@ -Sizes of pthreads-win32 structs -------------------------------- - pthread_t_ 124 - pthread_attr_t_ 28 - sem_t_ 4 - pthread_mutex_t_ 44 - pthread_mutexattr_t_ 8 - pthread_spinlock_t_ 8 - pthread_barrier_t_ 24 - pthread_barrierattr_t_ 4 - pthread_key_t_ 16 - pthread_cond_t_ 32 - pthread_condattr_t_ 4 - pthread_rwlock_t_ 28 - pthread_rwlockattr_t_ 4 - pthread_once_t_ 8 - ptw32_cleanup_t 12 - sched_param 4 -------------------------------- - +Sizes of pthreads-win32 structs +------------------------------- + pthread_t 8 + ptw32_thread_t 160 + pthread_attr_t_ 28 + sem_t_ 12 + pthread_mutex_t_ 28 + pthread_mutexattr_t_ 12 + pthread_spinlock_t_ 8 + pthread_barrier_t_ 36 + pthread_barrierattr_t_ 4 + pthread_key_t_ 16 + pthread_cond_t_ 32 + pthread_condattr_t_ 4 + pthread_rwlock_t_ 28 + pthread_rwlockattr_t_ 4 + pthread_once_t_ 16 + ptw32_cleanup_t 12 + ptw32_mcs_node_t_ 16 + sched_param 4 +------------------------------- diff --git a/pthreads/tests/SIZES.VCE b/pthreads/tests/SIZES.VCE index edc642719..709114d52 100644 --- a/pthreads/tests/SIZES.VCE +++ b/pthreads/tests/SIZES.VCE @@ -1,19 +1,21 @@ -Sizes of pthreads-win32 structs -------------------------------- - pthread_t_ 68 - pthread_attr_t_ 28 - sem_t_ 4 - pthread_mutex_t_ 44 - pthread_mutexattr_t_ 8 - pthread_spinlock_t_ 8 - pthread_barrier_t_ 24 - pthread_barrierattr_t_ 4 - pthread_key_t_ 16 - pthread_cond_t_ 32 - pthread_condattr_t_ 4 - pthread_rwlock_t_ 28 - pthread_rwlockattr_t_ 4 - pthread_once_t_ 8 - ptw32_cleanup_t 12 - sched_param 4 -------------------------------- +Sizes of pthreads-win32 structs +------------------------------- + pthread_t 8 + ptw32_thread_t 96 + pthread_attr_t_ 28 + sem_t_ 12 + pthread_mutex_t_ 28 + pthread_mutexattr_t_ 12 + pthread_spinlock_t_ 8 + pthread_barrier_t_ 36 + pthread_barrierattr_t_ 4 + pthread_key_t_ 16 + pthread_cond_t_ 32 + pthread_condattr_t_ 4 + pthread_rwlock_t_ 28 + pthread_rwlockattr_t_ 4 + pthread_once_t_ 16 + ptw32_cleanup_t 12 + ptw32_mcs_node_t_ 16 + sched_param 4 +------------------------------- diff --git a/pthreads/tests/SIZES.VSE b/pthreads/tests/SIZES.VSE index edc642719..709114d52 100644 --- a/pthreads/tests/SIZES.VSE +++ b/pthreads/tests/SIZES.VSE @@ -1,19 +1,21 @@ -Sizes of pthreads-win32 structs -------------------------------- - pthread_t_ 68 - pthread_attr_t_ 28 - sem_t_ 4 - pthread_mutex_t_ 44 - pthread_mutexattr_t_ 8 - pthread_spinlock_t_ 8 - pthread_barrier_t_ 24 - pthread_barrierattr_t_ 4 - pthread_key_t_ 16 - pthread_cond_t_ 32 - pthread_condattr_t_ 4 - pthread_rwlock_t_ 28 - pthread_rwlockattr_t_ 4 - pthread_once_t_ 8 - ptw32_cleanup_t 12 - sched_param 4 -------------------------------- +Sizes of pthreads-win32 structs +------------------------------- + pthread_t 8 + ptw32_thread_t 96 + pthread_attr_t_ 28 + sem_t_ 12 + pthread_mutex_t_ 28 + pthread_mutexattr_t_ 12 + pthread_spinlock_t_ 8 + pthread_barrier_t_ 36 + pthread_barrierattr_t_ 4 + pthread_key_t_ 16 + pthread_cond_t_ 32 + pthread_condattr_t_ 4 + pthread_rwlock_t_ 28 + pthread_rwlockattr_t_ 4 + pthread_once_t_ 16 + ptw32_cleanup_t 12 + ptw32_mcs_node_t_ 16 + sched_param 4 +------------------------------- diff --git a/pthreads/tests/Wmakefile b/pthreads/tests/Wmakefile index 6525c1ed6..2b37c4691 100644 --- a/pthreads/tests/Wmakefile +++ b/pthreads/tests/Wmakefile @@ -1,349 +1,355 @@ -# 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=.. - -# The next path is relative to $BUILD_DIR -QAPC = ..\QueueUserAPCEx\User\quserex.dll - -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 exit5 & - join0.pass join1.pass detach1.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 semaphore5.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 create3.pass stress1.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 $(BUILD_DIR)\$@ - @ $(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 -create3.pass: -delay1.pass: -delay2.pass: delay1.pass -detach1.pass: join0.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 -semaphore5.pass: semaphore4.pass -sizes.pass: -spin1.pass: -spin2.pass: spin1.pass -spin3.pass: spin2.pass -spin4.pass: spin3.pass -stress1.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=.. + +# The next path is relative to $BUILD_DIR +QAPC = # ..\QueueUserAPCEx\User\quserex.dll + +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 & + sequence1.pass kill1.pass valid1.pass valid2.pass & + exit2.pass exit3.pass exit4 exit5 & + join0.pass join1.pass detach1.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 & + robust1.pass robust2.pass robust3.pass robust4.pass robust5.pass & + count1.pass & + once1.pass once2.pass once3.pass once4.pass tsd1.pass & + self2.pass & + cancel1.pass cancel2.pass & + semaphore4.pass semaphore4t.pass semaphore5.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 stress1.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 $(BUILD_DIR)\$@ + @ $(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: cancel1.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +create2.pass: create1.pass +delay1.pass: +delay2.pass: delay1.pass +detach1.pass: join0.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 +robust1.pass: mutex8r.pass +robust2.pass: mutex8r.pass +robust3.pass: robust2.pass +robust4.pass: robust3.pass +robust5.pass: robust4.pass +rwlock1.pass: condvar6.pass +rwlock2.pass: rwlock1.pass +rwlock3.pass: rwlock2.pass join2.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 +semaphore5.pass: semaphore4.pass +sequence1.pass: reuse2.pass +sizes.pass: +spin1.pass: +spin2.pass: spin1.pass +spin3.pass: spin2.pass +spin4.pass: spin3.pass +stress1.pass: +tsd1.pass: join1.pass +valid1.pass: join1.pass +valid2.pass: valid1.pass +cancel9.pass: cancel8.pass diff --git a/pthreads/tests/barrier3.c b/pthreads/tests/barrier3.c index 3e4009068..dece77068 100644 --- a/pthreads/tests/barrier3.c +++ b/pthreads/tests/barrier3.c @@ -41,11 +41,11 @@ #include "test.h" pthread_barrier_t barrier = NULL; -static int result = 1; +static void* result = (void*)1; void * func(void * arg) { - return (void *) pthread_barrier_wait(&barrier); + return (void *) (size_t)pthread_barrier_wait(&barrier); } int @@ -60,9 +60,9 @@ main() assert(pthread_create(&t, NULL, func, NULL) == 0); - assert(pthread_join(t, (void **) &result) == 0); + assert(pthread_join(t, &result) == 0); - assert(result == PTHREAD_BARRIER_SERIAL_THREAD); + assert((int)(size_t)result == PTHREAD_BARRIER_SERIAL_THREAD); assert(pthread_barrier_destroy(&barrier) == 0); assert(pthread_barrierattr_destroy(&ba) == 0); diff --git a/pthreads/tests/barrier5.c b/pthreads/tests/barrier5.c index 42c2e36d9..353384081 100644 --- a/pthreads/tests/barrier5.c +++ b/pthreads/tests/barrier5.c @@ -1,118 +1,118 @@ -/* - * barrier5.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 - * - * -------------------------------------------------------------------------- - * - * Set up a series of barriers at different heights and test various numbers - * of threads accessing, especially cases where there are more threads than the - * barrier height (count), i.e. test contention when the barrier is released. - */ - -#include "test.h" - -enum { - NUMTHREADS = 15, - HEIGHT = 10, - BARRIERMULTIPLE = 1000 -}; - -pthread_barrier_t barrier = NULL; -pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; -LONG totalThreadCrossings; - -void * -func(void * crossings) -{ - int result; - int serialThreads = 0; - - while ((LONG)crossings >= (LONG)InterlockedIncrement((LPLONG)&totalThreadCrossings)) - { - result = pthread_barrier_wait(&barrier); - - if (result == PTHREAD_BARRIER_SERIAL_THREAD) - { - serialThreads++; - } - else if (result != 0) - { - printf("Barrier failed: result = %s\n", error_string[result]); - fflush(stdout); - return NULL; - } - } - - return (void *) serialThreads; -} - -int -main() -{ - int i, j; - int result; - int serialThreadsTotal; - LONG Crossings; - pthread_t t[NUMTHREADS + 1]; - - for (j = 1; j <= NUMTHREADS; j++) - { - int height = j= (LONG)InterlockedIncrement((LPLONG)&totalThreadCrossings)) + { + result = pthread_barrier_wait(&barrier); + + if (result == PTHREAD_BARRIER_SERIAL_THREAD) + { + serialThreads++; + } + else if (result != 0) + { + printf("Barrier failed: result = %s\n", error_string[result]); + fflush(stdout); + return NULL; + } + } + + return (void*)(size_t)serialThreads; +} + +int +main() +{ + int i, j; + void* result; + int serialThreadsTotal; + LONG Crossings; + pthread_t t[NUMTHREADS + 1]; + + for (j = 1; j <= NUMTHREADS; j++) + { + int height = j int main() { + fprintf(stderr, "Test N/A for this compiler environment.\n"); return 0; } -#endif /* defined(_MSC_VER) || defined(__cplusplus) */ +#endif /* defined(__cplusplus) */ + diff --git a/pthreads/tests/cancel3.c b/pthreads/tests/cancel3.c index 7bc3b6ea0..5020648a6 100644 --- a/pthreads/tests/cancel3.c +++ b/pthreads/tests/cancel3.c @@ -1,201 +1,201 @@ -/* - * File: cancel3.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 asynchronous cancelation (alertable or non-alertable). - * - * Test Method (Validation or Falsification): - * - - * - * Requirements Tested: - * - Async cancel if thread is not blocked (i.e. voluntarily resumes if blocked). - * - * Features Tested: - * - - * - * Cases Tested: - * - - * - * Description: - * - - * - * Environment: - * - - * - * Input: - * - None. - * - * Output: - * - File name, Line number, and failed expression on failure. - * - No output on success. - * - * Assumptions: - * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock - * pthread_testcancel, pthread_cancel, pthread_join. - * - quserex.dll and alertdrv.sys are not available. - * - * Pass Criteria: - * - Process returns zero exit status. - * - * Fail Criteria: - * - Process returns non-zero exit status. - */ - -#include "test.h" - -/* - * Create NUMTHREADS threads in addition to the Main thread. - */ -enum -{ - NUMTHREADS = 4 -}; - -typedef struct bag_t_ bag_t; -struct bag_t_ -{ - int threadnum; - int started; - /* Add more per-thread state variables here */ - int count; -}; - -static bag_t threadbag[NUMTHREADS + 1]; - -void * -mythread (void *arg) -{ - int result = ((int) PTHREAD_CANCELED + 1); - bag_t *bag = (bag_t *) arg; - - assert (bag == &threadbag[bag->threadnum]); - assert (bag->started == 0); - bag->started = 1; - - /* Set to known state and type */ - - assert (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) == 0); - - assert (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); - - /* - * We wait up to 10 seconds, waking every 0.1 seconds, - * for a cancelation to be applied to us. - */ - for (bag->count = 0; bag->count < 100; bag->count++) - Sleep (100); - - return (void *) result; -} - -int -main () -{ - int failed = 0; - int i; - pthread_t t[NUMTHREADS + 1]; - - assert ((t[0] = pthread_self ()).p != NULL); - - for (i = 1; i <= NUMTHREADS; i++) - { - threadbag[i].started = 0; - threadbag[i].threadnum = i; - assert (pthread_create (&t[i], NULL, mythread, (void *) &threadbag[i]) - == 0); - } - - /* - * Code to control or munipulate child threads should probably go here. - */ - Sleep (500); - - for (i = 1; i <= NUMTHREADS; i++) - { - assert (pthread_cancel (t[i]) == 0); - } - - /* - * Give threads time to run. - */ - Sleep (NUMTHREADS * 100); - - /* - * Standard check that all threads started. - */ - for (i = 1; i <= NUMTHREADS; i++) - { - if (!threadbag[i].started) - { - failed |= !threadbag[i].started; - fprintf (stderr, "Thread %d: started %d\n", i, - threadbag[i].started); - } - } - - assert (!failed); - - /* - * Check any results here. Set "failed" and only print output on failure. - */ - failed = 0; - for (i = 1; i <= NUMTHREADS; i++) - { - int fail = 0; - int result = 0; - - /* - * The thread does not contain any cancelation points, so - * a return value of PTHREAD_CANCELED confirms that async - * cancelation succeeded. - */ - assert (pthread_join (t[i], (void **) &result) == 0); - - fail = (result != (int) PTHREAD_CANCELED); - - if (fail) - { - fprintf (stderr, "Thread %d: started %d: count %d\n", - i, threadbag[i].started, threadbag[i].count); - } - failed = (failed || fail); - } - - assert (!failed); - - /* - * Success. - */ - return 0; -} +/* + * File: cancel3.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 asynchronous cancelation (alertable or non-alertable). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - Async cancel if thread is not blocked (i.e. voluntarily resumes if blocked). + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join. + * - quserex.dll and alertdrv.sys are not available. + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ +{ + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +void * +mythread (void *arg) +{ + void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1); + bag_t *bag = (bag_t *) arg; + + assert (bag == &threadbag[bag->threadnum]); + assert (bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (bag->count = 0; bag->count < 100; bag->count++) + Sleep (100); + + return result; +} + +int +main () +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + assert ((t[0] = pthread_self ()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert (pthread_create (&t[i], NULL, mythread, (void *) &threadbag[i]) + == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep (NUMTHREADS * 100); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert (pthread_cancel (t[i]) == 0); + } + + /* + * Give threads time to complete. + */ + Sleep (NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf (stderr, "Thread %d: started %d\n", i, + threadbag[i].started); + } + } + + assert (!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + void* result = (void*)0; + + /* + * The thread does not contain any cancelation points, so + * a return value of PTHREAD_CANCELED confirms that async + * cancelation succeeded. + */ + assert (pthread_join (t[i], &result) == 0); + + fail = (result != PTHREAD_CANCELED); + + if (fail) + { + fprintf (stderr, "Thread %d: started %d: count %d\n", + i, threadbag[i].started, threadbag[i].count); + } + failed = (failed || fail); + } + + assert (!failed); + + /* + * Success. + */ + return 0; +} diff --git a/pthreads/tests/cancel4.c b/pthreads/tests/cancel4.c index 6d6d3dc7b..893f33b12 100644 --- a/pthreads/tests/cancel4.c +++ b/pthreads/tests/cancel4.c @@ -98,7 +98,7 @@ static bag_t threadbag[NUMTHREADS + 1]; void * mythread(void * arg) { - int result = ((int)PTHREAD_CANCELED + 1); + void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1); bag_t * bag = (bag_t *) arg; assert(bag == &threadbag[bag->threadnum]); @@ -118,7 +118,7 @@ mythread(void * arg) for (bag->count = 0; bag->count < 20; bag->count++) Sleep(100); - return (void *) result; + return result; } int @@ -173,16 +173,16 @@ main() for (i = 1; i <= NUMTHREADS; i++) { int fail = 0; - int result = 0; + void* result = (void*)0; /* * The thread does not contain any cancelation points, so * a return value of PTHREAD_CANCELED indicates that async * cancelation occurred. */ - assert(pthread_join(t[i], (void **) &result) == 0); + assert(pthread_join(t[i], &result) == 0); - fail = (result == (int) PTHREAD_CANCELED); + fail = (result == PTHREAD_CANCELED); if (fail) { diff --git a/pthreads/tests/cancel5.c b/pthreads/tests/cancel5.c index dd6cb8bae..6c3951634 100644 --- a/pthreads/tests/cancel5.c +++ b/pthreads/tests/cancel5.c @@ -96,7 +96,7 @@ static bag_t threadbag[NUMTHREADS + 1]; void * mythread (void *arg) { - int result = ((int) PTHREAD_CANCELED + 1); + void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1); bag_t *bag = (bag_t *) arg; assert (bag == &threadbag[bag->threadnum]); @@ -116,7 +116,7 @@ mythread (void *arg) for (bag->count = 0; bag->count < 100; bag->count++) Sleep (100); - return (void *) result; + return result; } int @@ -171,16 +171,16 @@ main () for (i = 1; i <= NUMTHREADS; i++) { int fail = 0; - int result = 0; + void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1); /* * The thread does not contain any cancelation points, so * a return value of PTHREAD_CANCELED confirms that async * cancelation succeeded. */ - assert (pthread_join (t[i], (void **) &result) == 0); + assert (pthread_join (t[i], &result) == 0); - fail = (result != (int) PTHREAD_CANCELED); + fail = (result != PTHREAD_CANCELED); if (fail) { diff --git a/pthreads/tests/cancel6a.c b/pthreads/tests/cancel6a.c index 644cd4a53..58063d573 100644 --- a/pthreads/tests/cancel6a.c +++ b/pthreads/tests/cancel6a.c @@ -85,7 +85,7 @@ static bag_t threadbag[NUMTHREADS + 1]; void * mythread(void * arg) { - int result = ((int)PTHREAD_CANCELED + 1); + void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1); bag_t * bag = (bag_t *) arg; assert(bag == &threadbag[bag->threadnum]); @@ -105,7 +105,7 @@ mythread(void * arg) for (bag->count = 0; bag->count < 100; bag->count++) Sleep(100); - return (void *) result; + return result; } int @@ -161,16 +161,16 @@ main() for (i = 1; i <= NUMTHREADS; i++) { int fail = 0; - int result = 0; + void* result = (void*)0; /* * The thread does not contain any cancelation points, so * a return value of PTHREAD_CANCELED confirms that async * cancelation succeeded. */ - assert(pthread_join(t[i], (void **) &result) == 0); + assert(pthread_join(t[i], &result) == 0); - fail = (result != (int) PTHREAD_CANCELED); + fail = (result != PTHREAD_CANCELED); if (fail) { diff --git a/pthreads/tests/cancel6d.c b/pthreads/tests/cancel6d.c index d0ad7ac2c..37f9ca5f3 100644 --- a/pthreads/tests/cancel6d.c +++ b/pthreads/tests/cancel6d.c @@ -86,7 +86,7 @@ static bag_t threadbag[NUMTHREADS + 1]; void * mythread(void * arg) { - int result = ((int)PTHREAD_CANCELED + 1); + void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1); bag_t * bag = (bag_t *) arg; assert(bag == &threadbag[bag->threadnum]); @@ -109,7 +109,7 @@ mythread(void * arg) pthread_testcancel(); } - return (void *) result; + return result; } int @@ -125,7 +125,7 @@ main() { threadbag[i].started = 0; threadbag[i].threadnum = i; - assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + assert(pthread_create(&t[i], NULL, mythread, (void *)(size_t) &threadbag[i]) == 0); } /* @@ -136,7 +136,10 @@ main() for (i = 1; i <= NUMTHREADS; i++) { assert(pthread_cancel(t[i]) == 0); - assert(pthread_cancel(t[i]) == 0); + if (pthread_cancel(t[i]) != 0) + { + printf("Second cancelation failed but this is expected sometimes.\n"); + } } /* @@ -165,11 +168,11 @@ main() for (i = 1; i <= NUMTHREADS; i++) { int fail = 0; - int result = 0; + void* result = (void*)0; - assert(pthread_join(t[i], (void **) &result) == 0); + assert(pthread_join(t[i], &result) == 0); - fail = (result != (int) PTHREAD_CANCELED); + fail = (result != PTHREAD_CANCELED); if (fail) { diff --git a/pthreads/tests/cancel7.c b/pthreads/tests/cancel7.c index 9fb2e6166..5f1390f7b 100644 --- a/pthreads/tests/cancel7.c +++ b/pthreads/tests/cancel7.c @@ -63,7 +63,7 @@ * * Assumptions: * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock - * pthread_testcancel, pthread_cancel, pthread_join + * pthread_testcancel, pthread_cancel * * Pass Criteria: * - Process returns zero exit status. @@ -118,7 +118,9 @@ Win32thread(void * arg) pthread_testcancel(); } +#if ! defined (__MINGW32__) || defined (__MSVCRT__) return 0; +#endif } int @@ -188,13 +190,13 @@ main() /* * Can't get a result code. */ - result = (int) PTHREAD_CANCELED; + result = (int)(size_t)PTHREAD_CANCELED; #endif assert(threadbag[i].self.p != NULL); assert(pthread_kill(threadbag[i].self, 0) == ESRCH); - fail = (result != (int) PTHREAD_CANCELED); + fail = (result != (int)(size_t)PTHREAD_CANCELED); if (fail) { diff --git a/pthreads/tests/cancel8.c b/pthreads/tests/cancel8.c index 69eafe98e..7204d19b1 100644 --- a/pthreads/tests/cancel8.c +++ b/pthreads/tests/cancel8.c @@ -63,7 +63,7 @@ * * Assumptions: * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock - * pthread_testcancel, pthread_cancel, pthread_join + * pthread_testcancel, pthread_cancel * * Pass Criteria: * - Process returns zero exit status. @@ -119,7 +119,9 @@ Win32thread(void * arg) pthread_cond_wait(&CV, &CVLock); pthread_cleanup_pop(1); +#if ! defined (__MINGW32__) || defined (__MSVCRT__) return 0; +#endif } int @@ -189,13 +191,13 @@ main() /* * Can't get a result code. */ - result = (int) PTHREAD_CANCELED; + result = (int)(size_t)PTHREAD_CANCELED; #endif assert(threadbag[i].self.p != NULL); assert(pthread_kill(threadbag[i].self, 0) == ESRCH); - fail = (result != (int) PTHREAD_CANCELED); + fail = (result != (int)(size_t)PTHREAD_CANCELED); if (fail) { diff --git a/pthreads/tests/cleanup0.c b/pthreads/tests/cleanup0.c index 77626eb66..d9fbedccc 100644 --- a/pthreads/tests/cleanup0.c +++ b/pthreads/tests/cleanup0.c @@ -137,7 +137,7 @@ mythread(void * arg) #pragma inline_depth() #endif - return (void *) result; + return (void *) (size_t)result; } int @@ -189,18 +189,18 @@ main() for (i = 1; i <= NUMTHREADS; i++) { int fail = 0; - int result = 0; + void* result = (void*)0; - assert(pthread_join(t[i], (void **) &result) == 0); + assert(pthread_join(t[i], &result) == 0); - fail = (result == (int) PTHREAD_CANCELED); + fail = ((int)(size_t)result == (int) PTHREAD_CANCELED); if (fail) { fprintf(stderr, "Thread %d: started %d: result %d\n", i, threadbag[i].started, - result); + (int)(size_t)result); fflush(stderr); } failed = (failed || fail); diff --git a/pthreads/tests/cleanup1.c b/pthreads/tests/cleanup1.c index 385aed959..30d4940b7 100644 --- a/pthreads/tests/cleanup1.c +++ b/pthreads/tests/cleanup1.c @@ -146,7 +146,7 @@ mythread(void * arg) #pragma inline_depth() #endif - return (void *) result; + return (void *) (size_t)result; } int @@ -203,18 +203,18 @@ main() for (i = 1; i <= NUMTHREADS; i++) { int fail = 0; - int result = 0; + void* result = (void*)0; - assert(pthread_join(t[i], (void **) &result) == 0); + assert(pthread_join(t[i], &result) == 0); - fail = (result != (int) PTHREAD_CANCELED); + fail = ((int)(size_t)result != (int) PTHREAD_CANCELED); if (fail) { fprintf(stderr, "Thread %d: started %d: result %d\n", i, threadbag[i].started, - result); + (int)(size_t)result); } failed = (failed || fail); } diff --git a/pthreads/tests/cleanup2.c b/pthreads/tests/cleanup2.c index 4c639181b..67037c255 100644 --- a/pthreads/tests/cleanup2.c +++ b/pthreads/tests/cleanup2.c @@ -131,7 +131,7 @@ mythread(void * arg) #pragma inline_depth() #endif - return (void *) result; + return (void *) (size_t)result; } int @@ -178,18 +178,18 @@ main() for (i = 1; i <= NUMTHREADS; i++) { int fail = 0; - int result = 0; + void* result = (void*)0; - assert(pthread_join(t[i], (void **) &result) == 0); + assert(pthread_join(t[i], &result) == 0); - fail = (result != 0); + fail = ((int)(size_t)result != 0); if (fail) { fprintf(stderr, "Thread %d: started %d: result: %d\n", i, threadbag[i].started, - result); + (int)(size_t)result); } failed = (failed || fail); } diff --git a/pthreads/tests/cleanup3.c b/pthreads/tests/cleanup3.c index b595ab43c..62317b3b0 100644 --- a/pthreads/tests/cleanup3.c +++ b/pthreads/tests/cleanup3.c @@ -136,7 +136,7 @@ mythread(void * arg) #pragma inline_depth() #endif - return (void *) result; + return (void *) (size_t)result; } int @@ -183,18 +183,18 @@ main() for (i = 1; i <= NUMTHREADS; i++) { int fail = 0; - int result = 0; + void* result = (void*)0; - assert(pthread_join(t[i], (void **) &result) == 0); + assert(pthread_join(t[i], &result) == 0); - fail = (result != 0); + fail = ((int)(size_t)result != 0); if (fail) { fprintf(stderr, "Thread %d: started %d: result: %d\n", i, threadbag[i].started, - result); + (int)(size_t)result); } failed = (failed || fail); } diff --git a/pthreads/tests/condvar1_2.c b/pthreads/tests/condvar1_2.c index 503e821b6..3d961f06d 100644 --- a/pthreads/tests/condvar1_2.c +++ b/pthreads/tests/condvar1_2.c @@ -89,7 +89,7 @@ int main() { int i, j, k; - int result = -1; + void* result = (void*)-1; pthread_t t; for (k = 0; k < NUM_LOOPS; k++) @@ -116,8 +116,8 @@ main() } while (j > 0); - assert(pthread_join(t, (void **) &result) == 0); - assert (result == 0); + assert(pthread_join(t, &result) == 0); + assert ((int)(size_t)result == 0); } return 0; diff --git a/pthreads/tests/condvar2.c b/pthreads/tests/condvar2.c index 33f1d3f1d..6e2fa52d2 100644 --- a/pthreads/tests/condvar2.c +++ b/pthreads/tests/condvar2.c @@ -87,7 +87,7 @@ int main() { struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert(pthread_cond_init(&cv, NULL) == 0); @@ -97,9 +97,9 @@ main() assert(pthread_mutex_lock(&mutex) == 0); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; diff --git a/pthreads/tests/condvar2_1.c b/pthreads/tests/condvar2_1.c index 92dddfd9a..3486d2110 100644 --- a/pthreads/tests/condvar2_1.c +++ b/pthreads/tests/condvar2_1.c @@ -105,8 +105,8 @@ main() { int i; pthread_t t[NUMTHREADS + 1]; - int result = 0; - struct _timeb currSysTime; + void* result = (void*)0; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert(pthread_cond_init(&cv, NULL) == 0); @@ -114,9 +114,9 @@ main() assert(pthread_mutex_init(&mutex, NULL) == 0); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 5; @@ -125,15 +125,15 @@ main() for (i = 1; i <= NUMTHREADS; i++) { - assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0); + assert(pthread_create(&t[i], NULL, mythread, (void *)(size_t)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); + assert(pthread_join(t[i], &result) == 0); + assert((int)(size_t)result == i); } { diff --git a/pthreads/tests/condvar3.c b/pthreads/tests/condvar3.c index e3a23f54f..056334b37 100644 --- a/pthreads/tests/condvar3.c +++ b/pthreads/tests/condvar3.c @@ -112,7 +112,7 @@ main() { pthread_t t[NUMTHREADS]; struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert((t[0] = pthread_self()).p != NULL); @@ -124,9 +124,9 @@ main() assert(pthread_mutex_lock(&mutex) == 0); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); diff --git a/pthreads/tests/condvar3_1.c b/pthreads/tests/condvar3_1.c index 25a50e4bb..33baeb14d 100644 --- a/pthreads/tests/condvar3_1.c +++ b/pthreads/tests/condvar3_1.c @@ -126,8 +126,8 @@ main() { int i; pthread_t t[NUMTHREADS + 1]; - int result = 0; - struct _timeb currSysTime; + void* result = (void*)0; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert(pthread_cond_init(&cv, NULL) == 0); @@ -137,9 +137,9 @@ main() assert(pthread_mutex_init(&mutex1, NULL) == 0); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 5; @@ -148,7 +148,7 @@ main() for (i = 1; i <= NUMTHREADS; i++) { - assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0); + assert(pthread_create(&t[i], NULL, mythread, (void *)(size_t)i) == 0); } do { @@ -168,8 +168,8 @@ main() for (i = 1; i <= NUMTHREADS; i++) { - assert(pthread_join(t[i], (void **) &result) == 0); - assert(result == i); + assert(pthread_join(t[i], &result) == 0); + assert((int)(size_t)result == i); } fprintf(stderr, "awk = %d\n", awoken); diff --git a/pthreads/tests/condvar3_2.c b/pthreads/tests/condvar3_2.c index 5ddcf5748..4c3580152 100644 --- a/pthreads/tests/condvar3_2.c +++ b/pthreads/tests/condvar3_2.c @@ -100,7 +100,7 @@ mythread(void * arg) abstime2.tv_sec = abstime.tv_sec; - if ((int) arg % 3 == 0) + if ((int) (size_t)arg % 3 == 0) { abstime2.tv_sec += 2; } @@ -127,8 +127,8 @@ main() { int i; pthread_t t[NUMTHREADS + 1]; - int result = 0; - struct _timeb currSysTime; + void* result = (void*)0; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert(pthread_cond_init(&cv, NULL) == 0); @@ -136,24 +136,24 @@ main() assert(pthread_mutex_init(&mutex, NULL) == 0); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = abstime.tv_sec = currSysTime.time + 5; + abstime.tv_sec = abstime2.tv_sec = (long)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_create(&t[i], NULL, mythread, (void *)(size_t)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); + assert(pthread_join(t[i], &result) == 0); + assert((int)(size_t)result == i); /* * Approximately 2/3rds of the threads are expected to time out. * Signal the remainder after some threads have woken up and exited diff --git a/pthreads/tests/condvar3_3.c b/pthreads/tests/condvar3_3.c index fe6763249..f842440a1 100644 --- a/pthreads/tests/condvar3_3.c +++ b/pthreads/tests/condvar3_3.c @@ -87,16 +87,16 @@ int main() int rc; struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_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); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; @@ -120,7 +120,7 @@ int main() assert(pthread_mutex_lock(&mtx) == 0); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; diff --git a/pthreads/tests/condvar4.c b/pthreads/tests/condvar4.c index 3babeeac5..3f6879b0a 100644 --- a/pthreads/tests/condvar4.c +++ b/pthreads/tests/condvar4.c @@ -112,7 +112,7 @@ main() { pthread_t t[NUMTHREADS]; struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; cvthing.shared = 0; @@ -128,9 +128,9 @@ main() assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 5; @@ -141,9 +141,9 @@ main() assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 5; diff --git a/pthreads/tests/condvar5.c b/pthreads/tests/condvar5.c index 4d51f396a..73083a55e 100644 --- a/pthreads/tests/condvar5.c +++ b/pthreads/tests/condvar5.c @@ -111,7 +111,7 @@ main() { pthread_t t[NUMTHREADS]; struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; cvthing.shared = 0; @@ -127,9 +127,9 @@ main() assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 5; @@ -140,9 +140,9 @@ main() assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 5; diff --git a/pthreads/tests/condvar6.c b/pthreads/tests/condvar6.c index e63132c5d..9d0b75d81 100644 --- a/pthreads/tests/condvar6.c +++ b/pthreads/tests/condvar6.c @@ -144,7 +144,7 @@ main() int i; pthread_t t[NUMTHREADS + 1]; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; cvthing.shared = 0; @@ -157,9 +157,9 @@ main() assert(pthread_mutex_lock(&start_flag) == 0); - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 5; diff --git a/pthreads/tests/condvar7.c b/pthreads/tests/condvar7.c index 6d89f2ea9..0647e7d91 100644 --- a/pthreads/tests/condvar7.c +++ b/pthreads/tests/condvar7.c @@ -154,7 +154,7 @@ main() int i; pthread_t t[NUMTHREADS + 1]; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; cvthing.shared = 0; @@ -167,9 +167,9 @@ main() assert(pthread_mutex_lock(&start_flag) == 0); - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (time_t)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 10; diff --git a/pthreads/tests/condvar8.c b/pthreads/tests/condvar8.c index e384a1c9c..7c2579d98 100644 --- a/pthreads/tests/condvar8.c +++ b/pthreads/tests/condvar8.c @@ -155,7 +155,7 @@ main() int first, last; pthread_t t[NUMTHREADS + 1]; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert((t[0] = pthread_self()).p != NULL); @@ -164,9 +164,9 @@ main() assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 10; diff --git a/pthreads/tests/condvar9.c b/pthreads/tests/condvar9.c index c75127108..62d044bf8 100644 --- a/pthreads/tests/condvar9.c +++ b/pthreads/tests/condvar9.c @@ -163,7 +163,7 @@ main() int canceledThreads = 0; pthread_t t[NUMTHREADS + 1]; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; assert((t[0] = pthread_self()).p != NULL); @@ -172,9 +172,9 @@ main() assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 5; diff --git a/pthreads/tests/create2.c b/pthreads/tests/create2.c index 2ffb64e08..9b4e86480 100644 --- a/pthreads/tests/create2.c +++ b/pthreads/tests/create2.c @@ -100,7 +100,8 @@ main() { washere = 0; assert(pthread_create(&t, &attr, func, NULL) == 0); - pthread_join(t, &result); + assert(pthread_join(t, &result) == 0); + assert((int)(size_t)result == 0); assert(washere == 1); } diff --git a/pthreads/tests/create3.c b/pthreads/tests/create3.c deleted file mode 100644 index 98bd5200e..000000000 --- a/pthreads/tests/create3.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * File: create3.c - * - * - * -------------------------------------------------------------------------- - * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2003 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 passing NULL as thread id arg to pthread_create. - * - * Test Method (Validation or Falsification): - * - - * - * Requirements Tested: - * - - * - * Features Tested: - * - - * - * Cases Tested: - * - - * - * Description: - * - - * - * Environment: - * - - * - * Input: - * - None. - * - * Output: - * - File name, Line number, and failed expression on failure. - * - No output on success. - * - * Assumptions: - * - - * - * Pass Criteria: - * - Process returns zero exit status. - * - * Fail Criteria: - * - Process returns non-zero exit status. - */ - - -#ifdef __GNUC__ -#include -#endif - -#include "test.h" - -/* - * Create NUMTHREADS threads in addition to the Main thread. - */ -enum { - NUMTHREADS = 1 -}; - - -void * -threadFunc(void * arg) -{ - return (void *) 0; -} - -int -main(int argc, char * argv[]) -{ - int i; - pthread_t mt; - - if (argc <= 1) - { - int result; - - printf("You should see an application memory write error message\n"); - fflush(stdout); - result = system("create3.exe die"); - exit(0); - } - - assert((mt = pthread_self()).p != NULL); - - for (i = 0; i < NUMTHREADS; i++) - { - assert(pthread_create(NULL, NULL, threadFunc, NULL) == 0); - } - - /* - * Success. - */ - return 0; -} - diff --git a/pthreads/tests/delay2.c b/pthreads/tests/delay2.c index 8ecaf0b94..071b837f1 100644 --- a/pthreads/tests/delay2.c +++ b/pthreads/tests/delay2.c @@ -58,14 +58,14 @@ func(void * arg) #pragma inline_depth() #endif - return (void *) 1; + return (void *)(size_t)1; } int main(int argc, char * argv[]) { pthread_t t; - int result = 0; + void* result = (void*)0; assert(pthread_mutex_lock(&mx) == 0); @@ -74,8 +74,8 @@ main(int argc, char * argv[]) assert(pthread_mutex_unlock(&mx) == 0); - assert(pthread_join(t, (void **) &result) == 0); - assert(result == (int) PTHREAD_CANCELED); + assert(pthread_join(t, &result) == 0); + assert(result == (void*)PTHREAD_CANCELED); return 0; } diff --git a/pthreads/tests/detach1.c b/pthreads/tests/detach1.c index 165c8c1d1..89756c7ad 100644 --- a/pthreads/tests/detach1.c +++ b/pthreads/tests/detach1.c @@ -46,7 +46,7 @@ enum { void * func(void * arg) { - int i = (int) arg; + int i = (int)(size_t)arg; Sleep(i * 10); @@ -65,7 +65,7 @@ main(int argc, char * argv[]) /* Create a few threads and then exit. */ for (i = 0; i < NUMTHREADS; i++) { - assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + assert(pthread_create(&id[i], NULL, func, (void *)(size_t)i) == 0); } /* Some threads will finish before they are detached, some after. */ diff --git a/pthreads/tests/exception1.c b/pthreads/tests/exception1.c index 3f9f59578..62a5a63cb 100644 --- a/pthreads/tests/exception1.c +++ b/pthreads/tests/exception1.c @@ -86,7 +86,7 @@ void * exceptionedThread(void * arg) { int dummy = 0; - int result = ((int)PTHREAD_CANCELED + 1); + void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1); /* Set to async cancelable */ assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); @@ -98,7 +98,7 @@ exceptionedThread(void * arg) #if defined(_MSC_VER) && !defined(__cplusplus) __try { - int zero = (int) arg; /* Passed in from arg to avoid compiler error */ + int zero = (int) (size_t)arg; /* Passed in from arg to avoid compiler error */ int one = 1; /* * The deliberate exception condition (zero divide) is @@ -110,7 +110,7 @@ exceptionedThread(void * arg) __except (EXCEPTION_EXECUTE_HANDLER) { /* Should get into here. */ - result = ((int)PTHREAD_CANCELED + 2); + result = (void*)((int)(size_t)PTHREAD_CANCELED + 2); } #elif defined(__cplusplus) try @@ -129,17 +129,17 @@ exceptionedThread(void * arg) #endif { /* Should get into here. */ - result = ((int)PTHREAD_CANCELED + 2); + result = (void*)((int)(size_t)PTHREAD_CANCELED + 2); } #endif - return (void *) result; + return (void *) (size_t)result; } void * canceledThread(void * arg) { - int result = ((int)PTHREAD_CANCELED + 1); + void* result = (void*)((int)(size_t)PTHREAD_CANCELED + 1); int count; /* Set to async cancelable */ @@ -161,7 +161,7 @@ canceledThread(void * arg) __except (EXCEPTION_EXECUTE_HANDLER) { /* Should NOT get into here. */ - result = ((int)PTHREAD_CANCELED + 2); + result = (void*)((int)(size_t)PTHREAD_CANCELED + 2); } #elif defined(__cplusplus) try @@ -180,11 +180,11 @@ canceledThread(void * arg) #endif { /* Should NOT get into here. */ - result = ((int)PTHREAD_CANCELED + 2); + result = (void*)((int)(size_t)PTHREAD_CANCELED + 2); } #endif - return (void *) result; + return (void *) (size_t)result; } int @@ -226,17 +226,17 @@ main() for (i = 0; i < NUMTHREADS; i++) { int fail = 0; - int result = 0; + void* result = (void*)0; /* Canceled thread */ - assert(pthread_join(ct[i], (void **) &result) == 0); - assert(!(fail = (result != (int) PTHREAD_CANCELED))); + assert(pthread_join(ct[i], &result) == 0); + assert(!(fail = (result != PTHREAD_CANCELED))); failed = (failed || fail); /* Exceptioned thread */ - assert(pthread_join(et[i], (void **) &result) == 0); - assert(!(fail = (result != ((int) PTHREAD_CANCELED + 2)))); + assert(pthread_join(et[i], &result) == 0); + assert(!(fail = (result != (void*)((int)(size_t)PTHREAD_CANCELED + 2)))); failed = (failed || fail); } diff --git a/pthreads/tests/exception2.c b/pthreads/tests/exception2.c index 5c1856810..faf677d9b 100644 --- a/pthreads/tests/exception2.c +++ b/pthreads/tests/exception2.c @@ -62,7 +62,7 @@ * * Assumptions: * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock - * pthread_testcancel, pthread_cancel, pthread_join + * pthread_testcancel, pthread_cancel * * Pass Criteria: * - Process returns zero exit status. @@ -113,7 +113,7 @@ exceptionedThread(void * arg) } int -main(int argc, char argv[]) +main(int argc, char* argv[]) { int i; pthread_t mt; diff --git a/pthreads/tests/exception3.c b/pthreads/tests/exception3.c index 9a70a405a..65bcdbef3 100644 --- a/pthreads/tests/exception3.c +++ b/pthreads/tests/exception3.c @@ -62,7 +62,7 @@ * * Assumptions: * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock - * pthread_testcancel, pthread_cancel, pthread_join + * pthread_testcancel, pthread_cancel * * Pass Criteria: * - Process returns zero exit status. @@ -101,7 +101,7 @@ terminateFunction () { assert(pthread_mutex_lock(&caughtLock) == 0); caught++; -#if 1 +#if 0 { FILE * fp = fopen("pthread.log", "a"); fprintf(fp, "Caught = %d\n", caught); @@ -110,18 +110,6 @@ terminateFunction () #endif assert(pthread_mutex_unlock(&caughtLock) == 0); -#if defined(__MINGW32__) - /* - * Seems to work. That is, threads exit and the process - * continues. Note: need to check correct POSIX behaviour. - * My guess is: this is because of the - * eh incompatibility between g++ and MSVC++. That is, - * an exception thrown in g++ code doesn't propogate - * through or to MSVC++ code, and vice versa. - * Applications should probably not depend on this. - */ - pthread_exit((void *) 0); -#else /* * Notes from the MSVC++ manual: * 1) A term_func() should call exit(), otherwise @@ -129,13 +117,12 @@ terminateFunction () * 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 + * 2) A term_func() must not throw an exception. Dev: Therefore * term_func() should not call pthread_exit() if an - * an exception-using version of pthreads-win32 library + * exception-using version of pthreads-win32 library * is being used (i.e. either pthreadVCE or pthreadVSE). */ exit(0); -#endif } void * @@ -172,7 +159,7 @@ main() assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0); } - Sleep(5000); + Sleep(NUMTHREADS * 100); assert(caught == NUMTHREADS); diff --git a/pthreads/tests/exit2.c b/pthreads/tests/exit2.c index 196139a9f..b9f785edf 100644 --- a/pthreads/tests/exit2.c +++ b/pthreads/tests/exit2.c @@ -58,7 +58,7 @@ main(int argc, char * argv[]) assert(pthread_create(&t, NULL, func, (void *) NULL) == 0); - Sleep(1000); + Sleep(100); return 0; } diff --git a/pthreads/tests/exit3.c b/pthreads/tests/exit3.c index 574a92df7..18859e4ee 100644 --- a/pthreads/tests/exit3.c +++ b/pthreads/tests/exit3.c @@ -58,10 +58,10 @@ main(int argc, char * argv[]) /* Create a few threads and then exit. */ for (i = 0; i < 4; i++) { - assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + assert(pthread_create(&id[i], NULL, func, (void *)(size_t)i) == 0); } - Sleep(1000); + Sleep(400); /* Success. */ return 0; diff --git a/pthreads/tests/exit4.c b/pthreads/tests/exit4.c index 1ceca4e35..06dd8b1ee 100644 --- a/pthreads/tests/exit4.c +++ b/pthreads/tests/exit4.c @@ -63,7 +63,7 @@ * * Assumptions: * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock - * pthread_testcancel, pthread_cancel, pthread_join + * pthread_testcancel, pthread_cancel * * Pass Criteria: * - Process returns zero exit status. @@ -111,7 +111,7 @@ Win32thread(void * arg) /* * Doesn't return and doesn't create an implicit POSIX handle. */ - pthread_exit((void *) result); + pthread_exit((void *)(size_t)result); return 0; } diff --git a/pthreads/tests/exit5.c b/pthreads/tests/exit5.c index 450ed3bea..ac98f996c 100644 --- a/pthreads/tests/exit5.c +++ b/pthreads/tests/exit5.c @@ -63,7 +63,7 @@ * * Assumptions: * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock - * pthread_testcancel, pthread_cancel, pthread_join + * pthread_testcancel, pthread_cancel * * Pass Criteria: * - Process returns zero exit status. @@ -115,7 +115,7 @@ Win32thread(void * arg) /* * Doesn't return. */ - pthread_exit((void *) result); + pthread_exit((void *)(size_t)result); return 0; } diff --git a/pthreads/tests/inherit1.c b/pthreads/tests/inherit1.c index 482a5a884..24ceec557 100644 --- a/pthreads/tests/inherit1.c +++ b/pthreads/tests/inherit1.c @@ -89,7 +89,7 @@ void * func(void * arg) struct sched_param param; assert(pthread_getschedparam(pthread_self(), &policy, ¶m) == 0); - return (void *) param.sched_priority; + return (void *) (size_t)param.sched_priority; } @@ -169,7 +169,7 @@ main() assert(pthread_attr_setschedparam(&attr, ¶m) == 0); assert(pthread_create(&t, &attr, func, NULL) == 0); pthread_join(t, &result); - assert((int) result == mainParam.sched_priority); + assert((int)(size_t) result == mainParam.sched_priority); } } diff --git a/pthreads/tests/join0.c b/pthreads/tests/join0.c index a6cb25dcc..d888e9d6b 100644 --- a/pthreads/tests/join0.c +++ b/pthreads/tests/join0.c @@ -53,14 +53,14 @@ int main(int argc, char * argv[]) { pthread_t id; - int result; + void* result = (void*)0; /* Create a single thread and wait for it to exit. */ assert(pthread_create(&id, NULL, func, (void *) 123) == 0); - assert(pthread_join(id, (void **) &result) == 0); + assert(pthread_join(id, &result) == 0); - assert(result == 123); + assert((int)(size_t)result == 123); /* Success. */ return 0; diff --git a/pthreads/tests/join1.c b/pthreads/tests/join1.c index 8b11e9503..337af832d 100644 --- a/pthreads/tests/join1.c +++ b/pthreads/tests/join1.c @@ -41,7 +41,7 @@ void * func(void * arg) { - int i = (int) arg; + int i = (int)(size_t)arg; Sleep(i * 100); @@ -56,12 +56,12 @@ main(int argc, char * argv[]) { pthread_t id[4]; int i; - int result; + void* result = (void*)-1; /* Create a few threads and then exit. */ for (i = 0; i < 4; i++) { - assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + assert(pthread_create(&id[i], NULL, func, (void *)(size_t)i) == 0); } /* Some threads will finish before they are joined, some after. */ @@ -69,8 +69,8 @@ main(int argc, char * argv[]) for (i = 0; i < 4; i++) { - assert(pthread_join(id[i], (void **) &result) == 0); - assert(result == i); + assert(pthread_join(id[i], &result) == 0); + assert((int)(size_t)result == i); } /* Success. */ diff --git a/pthreads/tests/join2.c b/pthreads/tests/join2.c index 4fa30129e..b3b85ee81 100644 --- a/pthreads/tests/join2.c +++ b/pthreads/tests/join2.c @@ -50,18 +50,18 @@ main(int argc, char * argv[]) { pthread_t id[4]; int i; - int result; + void* result = (void*)-1; /* Create a few threads and then exit. */ for (i = 0; i < 4; i++) { - assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + assert(pthread_create(&id[i], NULL, func, (void *)(size_t)i) == 0); } for (i = 0; i < 4; i++) { - assert(pthread_join(id[i], (void **) &result) == 0); - assert(result == i); + assert(pthread_join(id[i], &result) == 0); + assert((int)(size_t)result == i); } /* Success. */ diff --git a/pthreads/tests/join3.c b/pthreads/tests/join3.c index 70cf3e97f..44380ace3 100644 --- a/pthreads/tests/join3.c +++ b/pthreads/tests/join3.c @@ -50,12 +50,12 @@ main(int argc, char * argv[]) { pthread_t id[4]; int i; - int result; + void* result = (void*)-1; /* Create a few threads and then exit. */ for (i = 0; i < 4; i++) { - assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + assert(pthread_create(&id[i], NULL, func, (void *)(size_t)i) == 0); } /* @@ -66,8 +66,8 @@ main(int argc, char * argv[]) for (i = 0; i < 4; i++) { - assert(pthread_join(id[i], (void **) &result) == 0); - assert(result == i); + assert(pthread_join(id[i], &result) == 0); + assert((int)(size_t)result == i); } /* Success. */ diff --git a/pthreads/tests/mutex1e.c b/pthreads/tests/mutex1e.c index e52810728..d32adb3a1 100644 --- a/pthreads/tests/mutex1e.c +++ b/pthreads/tests/mutex1e.c @@ -54,6 +54,8 @@ main() { assert(pthread_mutexattr_init(&mxAttr) == 0); + BEGIN_MUTEX_STALLED_ROBUST(mxAttr) + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0); assert(mutex == NULL); @@ -70,5 +72,7 @@ main() assert(mutex == NULL); + END_MUTEX_STALLED_ROBUST(mxAttr) + return 0; } diff --git a/pthreads/tests/mutex1n.c b/pthreads/tests/mutex1n.c index 74850d6c8..fcfc1347c 100644 --- a/pthreads/tests/mutex1n.c +++ b/pthreads/tests/mutex1n.c @@ -54,6 +54,8 @@ main() { assert(pthread_mutexattr_init(&mxAttr) == 0); + BEGIN_MUTEX_STALLED_ROBUST(mxAttr) + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0); assert(mutex == NULL); @@ -70,5 +72,7 @@ main() assert(mutex == NULL); + END_MUTEX_STALLED_ROBUST(mxAttr) + return 0; } diff --git a/pthreads/tests/mutex1r.c b/pthreads/tests/mutex1r.c index 0666dec0d..15083f27a 100644 --- a/pthreads/tests/mutex1r.c +++ b/pthreads/tests/mutex1r.c @@ -54,6 +54,8 @@ main() { assert(pthread_mutexattr_init(&mxAttr) == 0); + BEGIN_MUTEX_STALLED_ROBUST(mxAttr) + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); assert(mutex == NULL); @@ -70,5 +72,7 @@ main() assert(mutex == NULL); + END_MUTEX_STALLED_ROBUST(mxAttr) + return 0; } diff --git a/pthreads/tests/mutex4.c b/pthreads/tests/mutex4.c index 547d9cb73..6d36e0aa1 100644 --- a/pthreads/tests/mutex4.c +++ b/pthreads/tests/mutex4.c @@ -49,7 +49,7 @@ static pthread_mutex_t mutex1; void * unlocker(void * arg) { - int expectedResult = (int) arg; + int expectedResult = (int)(size_t)arg; wasHere++; assert(pthread_mutex_unlock(&mutex1) == expectedResult); @@ -65,35 +65,31 @@ main() assert(pthread_mutexattr_init(&ma) == 0); + BEGIN_MUTEX_STALLED_ROBUST(ma) + wasHere = 0; assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_DEFAULT) == 0); assert(pthread_mutex_init(&mutex1, &ma) == 0); assert(pthread_mutex_lock(&mutex1) == 0); - /* - * NORMAL (fast) mutexes don't check ownership. - */ - assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0); + assert(pthread_create(&t, NULL, unlocker, (void *)(size_t)(IS_ROBUST?EPERM:0)) == 0); assert(pthread_join(t, NULL) == 0); - assert(pthread_mutex_unlock(&mutex1) == EPERM); + assert(pthread_mutex_unlock(&mutex1) == 0); assert(wasHere == 2); wasHere = 0; assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_NORMAL) == 0); assert(pthread_mutex_init(&mutex1, &ma) == 0); assert(pthread_mutex_lock(&mutex1) == 0); - /* - * NORMAL (fast) mutexes don't check ownership. - */ - assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0); + assert(pthread_create(&t, NULL, unlocker, (void *)(size_t)(IS_ROBUST?EPERM:0)) == 0); assert(pthread_join(t, NULL) == 0); - assert(pthread_mutex_unlock(&mutex1) == EPERM); + assert(pthread_mutex_unlock(&mutex1) == 0); assert(wasHere == 2); wasHere = 0; assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0); assert(pthread_mutex_init(&mutex1, &ma) == 0); assert(pthread_mutex_lock(&mutex1) == 0); - assert(pthread_create(&t, NULL, unlocker, (void *) EPERM) == 0); + assert(pthread_create(&t, NULL, unlocker, (void *)(size_t) EPERM) == 0); assert(pthread_join(t, NULL) == 0); assert(pthread_mutex_unlock(&mutex1) == 0); assert(wasHere == 2); @@ -102,10 +98,12 @@ main() assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE) == 0); assert(pthread_mutex_init(&mutex1, &ma) == 0); assert(pthread_mutex_lock(&mutex1) == 0); - assert(pthread_create(&t, NULL, unlocker, (void *) EPERM) == 0); + assert(pthread_create(&t, NULL, unlocker, (void *)(size_t) EPERM) == 0); assert(pthread_join(t, NULL) == 0); assert(pthread_mutex_unlock(&mutex1) == 0); assert(wasHere == 2); + END_MUTEX_STALLED_ROBUST(ma) + return 0; } diff --git a/pthreads/tests/mutex6e.c b/pthreads/tests/mutex6e.c index 8af9274f2..908a51ba1 100644 --- a/pthreads/tests/mutex6e.c +++ b/pthreads/tests/mutex6e.c @@ -53,7 +53,7 @@ #include "test.h" -static int lockCount = 0; +static int lockCount; static pthread_mutex_t mutex; static pthread_mutexattr_t mxAttr; @@ -74,10 +74,14 @@ int main() { pthread_t t; - int result = 0; + void* result = (void*)0; int mxType = -1; assert(pthread_mutexattr_init(&mxAttr) == 0); + + BEGIN_MUTEX_STALLED_ROBUST(mxAttr) + + lockCount = 0; assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0); assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); assert(mxType == PTHREAD_MUTEX_ERRORCHECK); @@ -86,12 +90,15 @@ main() assert(pthread_create(&t, NULL, locker, NULL) == 0); - assert(pthread_join(t, (void **) &result) == 0); - assert(result == 555); + assert(pthread_join(t, &result) == 0); + assert((int)(size_t)result == 555); assert(lockCount == 2); assert(pthread_mutex_destroy(&mutex) == 0); + + END_MUTEX_STALLED_ROBUST(mxAttr) + assert(pthread_mutexattr_destroy(&mxAttr) == 0); exit(0); diff --git a/pthreads/tests/mutex6es.c b/pthreads/tests/mutex6es.c index 0d879c4ea..d4b624959 100644 --- a/pthreads/tests/mutex6es.c +++ b/pthreads/tests/mutex6es.c @@ -73,14 +73,14 @@ int main() { pthread_t t; - int result = 0; + void* result = (void*)0; assert(mutex == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER); assert(pthread_create(&t, NULL, locker, NULL) == 0); - assert(pthread_join(t, (void **) &result) == 0); - assert(result == 555); + assert(pthread_join(t, &result) == 0); + assert((int)(size_t)result == 555); assert(lockCount == 2); diff --git a/pthreads/tests/mutex6n.c b/pthreads/tests/mutex6n.c index 9b4bbb920..9cb309c2c 100644 --- a/pthreads/tests/mutex6n.c +++ b/pthreads/tests/mutex6n.c @@ -49,7 +49,7 @@ #include "test.h" -static int lockCount = 0; +static int lockCount; static pthread_mutex_t mutex; static pthread_mutexattr_t mxAttr; @@ -61,6 +61,7 @@ void * locker(void * arg) /* Should wait here (deadlocked) */ assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; assert(pthread_mutex_unlock(&mutex) == 0); @@ -74,6 +75,10 @@ main() int mxType = -1; assert(pthread_mutexattr_init(&mxAttr) == 0); + + BEGIN_MUTEX_STALLED_ROBUST(mxAttr) + + lockCount = 0; assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0); assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); assert(mxType == PTHREAD_MUTEX_NORMAL); @@ -82,19 +87,17 @@ main() assert(pthread_create(&t, NULL, locker, NULL) == 0); - Sleep(1000); + Sleep(100); assert(lockCount == 1); - /* - * Should succeed even though we don't own the lock - * because FAST mutexes don't check ownership. - */ - assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == IS_ROBUST?EPERM:0); + + Sleep (100); - Sleep (1000); + assert(lockCount == IS_ROBUST?1:2); - assert(lockCount == 2); + END_MUTEX_STALLED_ROBUST(mxAttr) exit(0); diff --git a/pthreads/tests/mutex6r.c b/pthreads/tests/mutex6r.c index 4bf853f8d..9d81ad849 100644 --- a/pthreads/tests/mutex6r.c +++ b/pthreads/tests/mutex6r.c @@ -52,7 +52,7 @@ #include "test.h" -static int lockCount = 0; +static int lockCount; static pthread_mutex_t mutex; static pthread_mutexattr_t mxAttr; @@ -73,10 +73,14 @@ int main() { pthread_t t; - int result = 0; + void* result = (void*)0; int mxType = -1; assert(pthread_mutexattr_init(&mxAttr) == 0); + + BEGIN_MUTEX_STALLED_ROBUST(mxAttr) + + lockCount = 0; assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); assert(mxType == PTHREAD_MUTEX_RECURSIVE); @@ -85,12 +89,15 @@ main() assert(pthread_create(&t, NULL, locker, NULL) == 0); - assert(pthread_join(t, (void **) &result) == 0); - assert(result == 555); + assert(pthread_join(t, &result) == 0); + assert((int)(size_t)result == 555); assert(lockCount == 2); assert(pthread_mutex_destroy(&mutex) == 0); + + END_MUTEX_STALLED_ROBUST(mxAttr) + assert(pthread_mutexattr_destroy(&mxAttr) == 0); exit(0); diff --git a/pthreads/tests/mutex6rs.c b/pthreads/tests/mutex6rs.c index 4ebe44ef0..4242fd627 100644 --- a/pthreads/tests/mutex6rs.c +++ b/pthreads/tests/mutex6rs.c @@ -72,14 +72,14 @@ int main() { pthread_t t; - int result = 0; + void* result = (void*)0; assert(mutex == PTHREAD_RECURSIVE_MUTEX_INITIALIZER); assert(pthread_create(&t, NULL, locker, NULL) == 0); - assert(pthread_join(t, (void **) &result) == 0); - assert(result == 555); + assert(pthread_join(t, &result) == 0); + assert((int)(size_t)result == 555); assert(lockCount == 2); diff --git a/pthreads/tests/mutex7.c b/pthreads/tests/mutex7.c index 8772b9712..4137c351d 100644 --- a/pthreads/tests/mutex7.c +++ b/pthreads/tests/mutex7.c @@ -57,7 +57,7 @@ void * locker(void * arg) assert(pthread_mutex_trylock(&mutex) == EBUSY); lockCount++; assert(pthread_mutex_unlock(&mutex) == 0); - assert(pthread_mutex_unlock(&mutex) == EPERM); + assert(pthread_mutex_unlock(&mutex) == 0); return 0; } diff --git a/pthreads/tests/mutex7e.c b/pthreads/tests/mutex7e.c index 854789b9b..80981b3e1 100644 --- a/pthreads/tests/mutex7e.c +++ b/pthreads/tests/mutex7e.c @@ -53,7 +53,7 @@ #include "test.h" -static int lockCount = 0; +static int lockCount; static pthread_mutex_t mutex; static pthread_mutexattr_t mxAttr; @@ -65,7 +65,6 @@ void * locker(void * arg) assert(pthread_mutex_trylock(&mutex) == EBUSY); lockCount++; assert(pthread_mutex_unlock(&mutex) == 0); - assert(pthread_mutex_unlock(&mutex) == EPERM); return (void *) 555; } @@ -74,10 +73,14 @@ int main() { pthread_t t; - int result = 0; + void* result = (void*)0; int mxType = -1; assert(pthread_mutexattr_init(&mxAttr) == 0); + + BEGIN_MUTEX_STALLED_ROBUST(mxAttr) + + lockCount = 0; assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0); assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); assert(mxType == PTHREAD_MUTEX_ERRORCHECK); @@ -86,12 +89,15 @@ main() assert(pthread_create(&t, NULL, locker, NULL) == 0); - assert(pthread_join(t, (void **) &result) == 0); - assert(result == 555); + assert(pthread_join(t, &result) == 0); + assert((int)(size_t)result == 555); assert(lockCount == 2); assert(pthread_mutex_destroy(&mutex) == 0); + + END_MUTEX_STALLED_ROBUST(mxAttr) + assert(pthread_mutexattr_destroy(&mxAttr) == 0); exit(0); diff --git a/pthreads/tests/mutex7n.c b/pthreads/tests/mutex7n.c index 174355fca..87ba10a57 100644 --- a/pthreads/tests/mutex7n.c +++ b/pthreads/tests/mutex7n.c @@ -49,7 +49,7 @@ #include "test.h" -static int lockCount = 0; +static int lockCount; static pthread_mutex_t mutex; static pthread_mutexattr_t mxAttr; @@ -61,7 +61,6 @@ void * locker(void * arg) assert(pthread_mutex_trylock(&mutex) == EBUSY); lockCount++; assert(pthread_mutex_unlock(&mutex) == 0); - assert(pthread_mutex_unlock(&mutex) == EPERM); return (void *) 555; } @@ -73,6 +72,10 @@ main() int mxType = -1; assert(pthread_mutexattr_init(&mxAttr) == 0); + + BEGIN_MUTEX_STALLED_ROBUST(mxAttr) + + lockCount = 0; assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0); assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); assert(mxType == PTHREAD_MUTEX_NORMAL); @@ -81,10 +84,14 @@ main() assert(pthread_create(&t, NULL, locker, NULL) == 0); - Sleep(1000); + Sleep(100); assert(lockCount == 2); + END_MUTEX_STALLED_ROBUST(mxAttr) + + assert(pthread_mutexattr_destroy(&mxAttr) == 0); + exit(0); /* Never reached */ diff --git a/pthreads/tests/mutex7r.c b/pthreads/tests/mutex7r.c index f9e5ff0e2..4e4ae8a9a 100644 --- a/pthreads/tests/mutex7r.c +++ b/pthreads/tests/mutex7r.c @@ -52,7 +52,7 @@ #include "test.h" -static int lockCount = 0; +static int lockCount; static pthread_mutex_t mutex; static pthread_mutexattr_t mxAttr; @@ -73,10 +73,14 @@ int main() { pthread_t t; - int result = 0; + void* result = (void*)0; int mxType = -1; assert(pthread_mutexattr_init(&mxAttr) == 0); + + BEGIN_MUTEX_STALLED_ROBUST(mxAttr) + + lockCount = 0; assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); assert(mxType == PTHREAD_MUTEX_RECURSIVE); @@ -85,12 +89,15 @@ main() assert(pthread_create(&t, NULL, locker, NULL) == 0); - assert(pthread_join(t, (void **) &result) == 0); - assert(result == 555); + assert(pthread_join(t, &result) == 0); + assert((int)(size_t)result == 555); assert(lockCount == 2); assert(pthread_mutex_destroy(&mutex) == 0); + + END_MUTEX_STALLED_ROBUST(mxAttr) + assert(pthread_mutexattr_destroy(&mxAttr) == 0); exit(0); diff --git a/pthreads/tests/mutex8.c b/pthreads/tests/mutex8.c index 5ca99822e..f2636786c 100644 --- a/pthreads/tests/mutex8.c +++ b/pthreads/tests/mutex8.c @@ -44,12 +44,12 @@ static pthread_mutex_t mutex; void * locker(void * arg) { struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; diff --git a/pthreads/tests/mutex8e.c b/pthreads/tests/mutex8e.c index b99d24edd..a36056673 100644 --- a/pthreads/tests/mutex8e.c +++ b/pthreads/tests/mutex8e.c @@ -44,7 +44,7 @@ #include "test.h" #include -static int lockCount = 0; +static int lockCount; static pthread_mutex_t mutex; static pthread_mutexattr_t mxAttr; @@ -52,12 +52,12 @@ static pthread_mutexattr_t mxAttr; void * locker(void * arg) { struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; @@ -76,6 +76,10 @@ main() int mxType = -1; assert(pthread_mutexattr_init(&mxAttr) == 0); + + BEGIN_MUTEX_STALLED_ROBUST(mxAttr) + + lockCount = 0; assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0); assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); assert(mxType == PTHREAD_MUTEX_ERRORCHECK); @@ -92,6 +96,8 @@ main() assert(pthread_mutex_unlock(&mutex) == 0); + END_MUTEX_STALLED_ROBUST(mxAttr) + return 0; } diff --git a/pthreads/tests/mutex8n.c b/pthreads/tests/mutex8n.c index 3cfdae620..0c6d97d7f 100644 --- a/pthreads/tests/mutex8n.c +++ b/pthreads/tests/mutex8n.c @@ -44,7 +44,7 @@ #include "test.h" #include -static int lockCount = 0; +static int lockCount; static pthread_mutex_t mutex; static pthread_mutexattr_t mxAttr; @@ -52,12 +52,12 @@ static pthread_mutexattr_t mxAttr; void * locker(void * arg) { struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; @@ -76,6 +76,10 @@ main() int mxType = -1; assert(pthread_mutexattr_init(&mxAttr) == 0); + + BEGIN_MUTEX_STALLED_ROBUST(mxAttr) + + lockCount = 0; assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0); assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); assert(mxType == PTHREAD_MUTEX_NORMAL); @@ -92,6 +96,8 @@ main() assert(pthread_mutex_unlock(&mutex) == 0); + END_MUTEX_STALLED_ROBUST(mxAttr) + return 0; } diff --git a/pthreads/tests/mutex8r.c b/pthreads/tests/mutex8r.c index d1328cad9..434b9af8e 100644 --- a/pthreads/tests/mutex8r.c +++ b/pthreads/tests/mutex8r.c @@ -44,7 +44,7 @@ #include "test.h" #include -static int lockCount = 0; +static int lockCount; static pthread_mutex_t mutex; static pthread_mutexattr_t mxAttr; @@ -52,12 +52,12 @@ static pthread_mutexattr_t mxAttr; void * locker(void * arg) { struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; @@ -76,6 +76,10 @@ main() int mxType = -1; assert(pthread_mutexattr_init(&mxAttr) == 0); + + BEGIN_MUTEX_STALLED_ROBUST(mxAttr) + + lockCount = 0; assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); assert(mxType == PTHREAD_MUTEX_RECURSIVE); @@ -92,6 +96,8 @@ main() assert(pthread_mutex_unlock(&mutex) == 0); + END_MUTEX_STALLED_ROBUST(mxAttr) + return 0; } diff --git a/pthreads/tests/once2.c b/pthreads/tests/once2.c index 248ccb1a7..84e3f4bf6 100644 --- a/pthreads/tests/once2.c +++ b/pthreads/tests/once2.c @@ -70,11 +70,11 @@ myfunc(void) void * mythread(void * arg) { - assert(pthread_once(&once[(int) arg], myfunc) == 0); + assert(pthread_once(&once[(int)(size_t)arg], myfunc) == 0); EnterCriticalSection(&numThreads.cs); numThreads.i++; LeaveCriticalSection(&numThreads.cs); - return 0; + return (void*)(size_t)0; } int @@ -91,7 +91,7 @@ main() once[j] = o; for (i = 0; i < NUM_THREADS; i++) - assert(pthread_create(&t[i][j], NULL, mythread, (void *) j) == 0); + assert(pthread_create(&t[i][j], NULL, mythread, (void *)(size_t)j) == 0); } for (j = 0; j < NUM_ONCE; j++) diff --git a/pthreads/tests/once3.c b/pthreads/tests/once3.c index 291f26019..ef1229043 100644 --- a/pthreads/tests/once3.c +++ b/pthreads/tests/once3.c @@ -1,132 +1,132 @@ -/* - * once3.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 with - * waiters waiting. - * - * Depends on API functions: - * pthread_once() - * pthread_create() - * pthread_testcancel() - * pthread_cancel() - * pthread_once() - */ - -/* #define ASSERT_TRACE */ - -#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}}; - -void -myfunc(void) -{ - EnterCriticalSection(&numOnce.cs); - numOnce.i++; - assert(numOnce.i > 0); - 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) -{ - /* - * Cancel every thread. These threads are deferred cancelable only, so - * only the thread performing the once routine (my_func) 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 once thread. - */ - assert(pthread_cancel(pthread_self()) == 0); - assert(pthread_once(&once[(int) arg], myfunc) == 0); - EnterCriticalSection(&numThreads.cs); - numThreads.i++; - LeaveCriticalSection(&numThreads.cs); - return 0; -} - -int -main() -{ - pthread_t t[NUM_THREADS][NUM_ONCE]; - int i, j; - - InitializeCriticalSection(&numThreads.cs); - InitializeCriticalSection(&numOnce.cs); - - for (j = 0; j < NUM_ONCE; j++) - { - once[j] = o; - - for (i = 0; i < NUM_THREADS; i++) - { - assert(pthread_create(&t[i][j], NULL, mythread, (void *) j) == 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); - - return 0; -} +/* + * once3.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 with + * waiters waiting. + * + * Depends on API functions: + * pthread_once() + * pthread_create() + * pthread_testcancel() + * pthread_cancel() + * pthread_once() + */ + +/* #define ASSERT_TRACE */ + +#include "test.h" + +#define NUM_THREADS 100 /* Targeting each once control */ +#define NUM_ONCE 10 + +static pthread_once_t o = PTHREAD_ONCE_INIT; +static 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}}; + +void +myfunc(void) +{ + EnterCriticalSection(&numOnce.cs); + numOnce.i++; + assert(numOnce.i > 0); + 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) +{ + /* + * Cancel every thread. These threads are deferred cancelable only, so + * only the thread performing the once routine (my_func) 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 'once' thread. + */ + assert(pthread_cancel(pthread_self()) == 0); + assert(pthread_once(&once[(int)(size_t)arg], myfunc) == 0); + EnterCriticalSection(&numThreads.cs); + numThreads.i++; + LeaveCriticalSection(&numThreads.cs); + return (void*)(size_t)0; +} + +int +main() +{ + pthread_t t[NUM_THREADS][NUM_ONCE]; + int i, j; + + InitializeCriticalSection(&numThreads.cs); + InitializeCriticalSection(&numOnce.cs); + + for (j = 0; j < NUM_ONCE; j++) + { + once[j] = o; + + for (i = 0; i < NUM_THREADS; i++) + { + assert(pthread_create(&t[i][j], NULL, mythread, (void *)(size_t)j) == 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); + + return 0; +} diff --git a/pthreads/tests/openmp1.c b/pthreads/tests/openmp1.c new file mode 100644 index 000000000..ee36e75c8 --- /dev/null +++ b/pthreads/tests/openmp1.c @@ -0,0 +1,140 @@ +#include +#include +#ifdef _OPENMP +# include +#endif +#include + +enum { + Size = 10000 +}; + +const int ShouldSum = (Size-1)*Size/2; + +short Verbose = 1; + +short ThreadOK[3] = {0,0,0}; // Main, Thread1, Thread2 + +// Thread +void *_thread(void* Id) { + int i; + int x[Size]; + +#ifdef _OPENMP +# pragma omp parallel for +#endif + for ( i = 0; i < Size; i++ ) { +#ifdef _OPENMP + if (Verbose && i%1000==0) { + int tid = omp_get_thread_num(); +# pragma omp critical + printf("thread %d : tid %d handles %d\n",(int)Id,tid,i); + } +#endif + + x[i] = i; + } + + int Sum=0; + for ( i = 0; i < Size; i++ ) { + Sum += x[i]; + } + if (Verbose) { +#ifdef _OPENMP +# pragma omp critical +#endif + printf("Id %d : %s : %d(should be %d)\n",(int)Id, __FUNCTION__, Sum,ShouldSum); + } + if (Sum == ShouldSum) ThreadOK[(int)Id] = 1; + return NULL; +} + +// MainThread +void MainThread() { + int i; + +#ifdef _OPENMP +# pragma omp parallel for +#endif + for ( i = 0; i < 4; i++ ) { +#ifdef _OPENMP + int tid = omp_get_thread_num(); +# pragma omp critical + printf("Main : tid %d\n",tid); + _thread((void *)tid); +#endif + } + return; +} + +// Comment in/out for checking the effect of multiple threads. +#define SPAWN_THREADS + +// main +int main(int argc, char *argv[]) { + + if (argc>1) Verbose = 1; + +#ifdef _OPENMP + omp_set_nested(-1); + printf("%s%s%s\n", "Nested parallel blocks are ", omp_get_nested()?" ":"NOT ", "supported."); +#endif + + MainThread(); + +#ifdef SPAWN_THREADS + { + pthread_t a_thr; + pthread_t b_thr; + int status; + + printf("%s:%d - %s - a_thr:%p - b_thr:%p\n", + __FILE__,__LINE__,__FUNCTION__,a_thr.p,b_thr.p); + + status = pthread_create(&a_thr, NULL, _thread, (void*) 1 ); + if ( status != 0 ) { + printf("Failed to create thread 1\n"); + return (-1); + } + + status = pthread_create(&b_thr, NULL, _thread, (void*) 2 ); + if ( status != 0 ) { + printf("Failed to create thread 2\n"); + return (-1); + } + + status = pthread_join(a_thr, NULL); + if ( status != 0 ) { + printf("Failed to join thread 1\n"); + return (-1); + } + printf("Joined thread1\n"); + + status = pthread_join(b_thr, NULL); + if ( status != 0 ) { + printf("Failed to join thread 2\n"); + return (-1); + } + printf("Joined thread2\n"); + } +#endif // SPAWN_THREADS + + short OK = 0; + // Check that we have OpenMP before declaring things OK formally. +#ifdef _OPENMP + OK = 1; + { + short i; + for (i=0;i<3;i++) OK &= ThreadOK[i]; + } + if (OK) printf("OMP : All looks good\n"); + else printf("OMP : Error\n"); +#else + printf("OpenMP seems not enabled ...\n"); +#endif + + return OK?0:1; +} + +//g++ -fopenmp omp_test.c -o omp_test -lpthread + diff --git a/pthreads/tests/priority1.c b/pthreads/tests/priority1.c index c270e998a..40316cc64 100644 --- a/pthreads/tests/priority1.c +++ b/pthreads/tests/priority1.c @@ -91,7 +91,7 @@ func(void * arg) assert(pthread_getschedparam(threadID, &policy, ¶m) == 0); assert(policy == SCHED_OTHER); - return (void *) (param.sched_priority); + return (void *) (size_t)(param.sched_priority); } void * @@ -164,8 +164,8 @@ main() assert(pthread_join(t, &result) == 0); - assert(param.sched_priority == (int) result); - printf("%10d %10d %10d\n", param.sched_priority, (int) result, prio); + assert(param.sched_priority == (int)(size_t) result); + printf("%10d %10d %10d\n", param.sched_priority, (int)(size_t) result, prio); } return 0; diff --git a/pthreads/tests/priority2.c b/pthreads/tests/priority2.c index a5575abe9..7d4648f90 100644 --- a/pthreads/tests/priority2.c +++ b/pthreads/tests/priority2.c @@ -95,7 +95,7 @@ void * func(void * arg) assert(policy == SCHED_OTHER); result = pthread_barrier_wait(&endBarrier); assert(result == 0 || result == PTHREAD_BARRIER_SERIAL_THREAD); - return (void *) param.sched_priority; + return (void *) (size_t)param.sched_priority; } @@ -162,7 +162,7 @@ main() assert(GetThreadPriority(pthread_getw32threadhandle_np(t)) == validPriorities[param.sched_priority+(PTW32TEST_MAXPRIORITIES/2)]); pthread_join(t, &result); - assert(param.sched_priority == (int)result); + assert(param.sched_priority == (int)(size_t)result); } return 0; diff --git a/pthreads/tests/reuse1.c b/pthreads/tests/reuse1.c index ae9efe400..1a7dff0e0 100644 --- a/pthreads/tests/reuse1.c +++ b/pthreads/tests/reuse1.c @@ -100,16 +100,16 @@ main() washere = 0; assert(pthread_create(&t, &attr, func, NULL) == 0); assert(pthread_join(t, &result) == 0);; - assert(result == 0); + assert((int)(size_t)result == 0); assert(washere == 1); last_t = t; for (i = 1; i < NUMTHREADS; i++) { washere = 0; - assert(pthread_create(&t, &attr, func, (void *) i) == 0); + assert(pthread_create(&t, &attr, func, (void *)(size_t)i) == 0); pthread_join(t, &result); - assert((int) result == i); + assert((int)(size_t) result == i); assert(washere == 1); /* thread IDs should be unique */ assert(!pthread_equal(t, last_t)); diff --git a/pthreads/tests/reuse2.c b/pthreads/tests/reuse2.c index c4db81199..362e547d9 100644 --- a/pthreads/tests/reuse2.c +++ b/pthreads/tests/reuse2.c @@ -111,7 +111,8 @@ main() for (i = 0; i < NUMTHREADS; i++) { - assert(pthread_create(&t[i], &attr, func, NULL) == 0); + while(pthread_create(&t[i], &attr, func, NULL) != 0) + Sleep(1); } while (NUMTHREADS > InterlockedExchangeAdd((LPLONG)&done, 0L)) diff --git a/pthreads/tests/robust1.c b/pthreads/tests/robust1.c new file mode 100644 index 000000000..100a8545b --- /dev/null +++ b/pthreads/tests/robust1.c @@ -0,0 +1,141 @@ +/* + * robust1.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 + * + * -------------------------------------------------------------------------- + * + * For all robust mutex types. + * Thread A locks mutex + * Thread A terminates with no threads waiting on robust mutex + * Thread B acquires (inherits) mutex and unlocks + * Main attempts to lock mutex with unrecovered state. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutex_init() + * pthread_mutex_lock() + * pthread_mutex_unlock() + * pthread_mutex_destroy() + * pthread_mutexattr_init() + * pthread_mutexattr_setrobust() + * pthread_mutexattr_settype() + * pthread_mutexattr_destroy() + */ + +#include "test.h" + +static int lockCount; + +static pthread_mutex_t mutex; + +void * owner(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + + return 0; +} + +void * inheritor(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == EOWNERDEAD); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + + return 0; +} + +int +main() +{ + pthread_t to, ti; + pthread_mutexattr_t ma; + + assert(pthread_mutexattr_init(&ma) == 0); + assert(pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST) == 0); + + /* Default (NORMAL) type */ + lockCount = 0; + assert(pthread_mutex_init(&mutex, &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_create(&ti, NULL, inheritor, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 2); + assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE); + assert(pthread_mutex_unlock(&mutex) == EPERM); + assert(pthread_mutex_destroy(&mutex) == 0); + + /* NORMAL type */ + lockCount = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_NORMAL) == 0); + assert(pthread_mutex_init(&mutex, &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_create(&ti, NULL, inheritor, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 2); + assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE); + assert(pthread_mutex_unlock(&mutex) == EPERM); + assert(pthread_mutex_destroy(&mutex) == 0); + + /* ERRORCHECK type */ + lockCount = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0); + assert(pthread_mutex_init(&mutex, &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_create(&ti, NULL, inheritor, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 2); + assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE); + assert(pthread_mutex_unlock(&mutex) == EPERM); + assert(pthread_mutex_destroy(&mutex) == 0); + + /* RECURSIVE type */ + lockCount = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE) == 0); + assert(pthread_mutex_init(&mutex, &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_create(&ti, NULL, inheritor, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 2); + assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE); + assert(pthread_mutex_unlock(&mutex) == EPERM); + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(pthread_mutexattr_destroy(&ma) == 0); + + return 0; +} diff --git a/pthreads/tests/robust2.c b/pthreads/tests/robust2.c new file mode 100644 index 000000000..2b3917a6e --- /dev/null +++ b/pthreads/tests/robust2.c @@ -0,0 +1,143 @@ +/* + * robust2.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 + * + * -------------------------------------------------------------------------- + * + * For all robust mutex types. + * Thread A locks mutex + * Thread B blocks on mutex + * Thread A terminates with threads waiting on robust mutex + * Thread B awakes and inherits mutex and unlocks + * Main attempts to lock mutex with unrecovered state. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutex_init() + * pthread_mutex_lock() + * pthread_mutex_unlock() + * pthread_mutex_destroy() + * pthread_mutexattr_init() + * pthread_mutexattr_setrobust() + * pthread_mutexattr_settype() + * pthread_mutexattr_destroy() + */ + +#include "test.h" + +static int lockCount; + +static pthread_mutex_t mutex; + +void * owner(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + Sleep(200); + + return 0; +} + +void * inheritor(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == EOWNERDEAD); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + + return 0; +} + +int +main() +{ + pthread_t to, ti; + pthread_mutexattr_t ma; + + assert(pthread_mutexattr_init(&ma) == 0); + assert(pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST) == 0); + + /* Default (NORMAL) type */ + lockCount = 0; + assert(pthread_mutex_init(&mutex, &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + Sleep(100); + assert(pthread_create(&ti, NULL, inheritor, NULL) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 2); + assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE); + assert(pthread_mutex_destroy(&mutex) == 0); + + /* NORMAL type */ + lockCount = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_NORMAL) == 0); + assert(pthread_mutex_init(&mutex, &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + Sleep(100); + assert(pthread_create(&ti, NULL, inheritor, NULL) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 2); + assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE); + assert(pthread_mutex_destroy(&mutex) == 0); + + /* ERRORCHECK type */ + lockCount = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0); + assert(pthread_mutex_init(&mutex, &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + Sleep(100); + assert(pthread_create(&ti, NULL, inheritor, NULL) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 2); + assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE); + assert(pthread_mutex_destroy(&mutex) == 0); + + /* RECURSIVE type */ + lockCount = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE) == 0); + assert(pthread_mutex_init(&mutex, &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + Sleep(100); + assert(pthread_create(&ti, NULL, inheritor, NULL) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 2); + assert(pthread_mutex_lock(&mutex) == ENOTRECOVERABLE); + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(pthread_mutexattr_destroy(&ma) == 0); + + return 0; +} diff --git a/pthreads/tests/robust3.c b/pthreads/tests/robust3.c new file mode 100644 index 000000000..cbf99df73 --- /dev/null +++ b/pthreads/tests/robust3.c @@ -0,0 +1,149 @@ +/* + * robust3.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 + * + * -------------------------------------------------------------------------- + * + * For all robust mutex types. + * Thread A locks mutex + * Thread B blocks on mutex + * Thread A terminates with threads waiting on robust mutex + * Thread B awakes and inherits mutex, sets consistent and unlocks + * Main acquires mutex with recovered state. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutex_init() + * pthread_mutex_lock() + * pthread_mutex_unlock() + * pthread_mutex_consistent() + * pthread_mutex_destroy() + * pthread_mutexattr_init() + * pthread_mutexattr_setrobust() + * pthread_mutexattr_settype() + * pthread_mutexattr_destroy() + */ + +#include "test.h" + +static int lockCount; + +static pthread_mutex_t mutex; + +void * owner(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + Sleep(200); + + return 0; +} + +void * inheritor(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == EOWNERDEAD); + lockCount++; + assert(pthread_mutex_consistent(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == 0); + + return 0; +} + +int +main() +{ + pthread_t to, ti; + pthread_mutexattr_t ma; + + assert(pthread_mutexattr_init(&ma) == 0); + assert(pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST) == 0); + + /* Default (NORMAL) type */ + lockCount = 0; + assert(pthread_mutex_init(&mutex, &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + Sleep(100); + assert(pthread_create(&ti, NULL, inheritor, NULL) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 2); + assert(pthread_mutex_lock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_destroy(&mutex) == 0); + + /* NORMAL type */ + lockCount = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_NORMAL) == 0); + assert(pthread_mutex_init(&mutex, &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + Sleep(100); + assert(pthread_create(&ti, NULL, inheritor, NULL) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 2); + assert(pthread_mutex_lock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_destroy(&mutex) == 0); + + /* ERRORCHECK type */ + lockCount = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0); + assert(pthread_mutex_init(&mutex, &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + Sleep(100); + assert(pthread_create(&ti, NULL, inheritor, NULL) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 2); + assert(pthread_mutex_lock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_destroy(&mutex) == 0); + + /* RECURSIVE type */ + lockCount = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE) == 0); + assert(pthread_mutex_init(&mutex, &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + Sleep(100); + assert(pthread_create(&ti, NULL, inheritor, NULL) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 2); + assert(pthread_mutex_lock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(pthread_mutexattr_destroy(&ma) == 0); + + return 0; +} diff --git a/pthreads/tests/robust4.c b/pthreads/tests/robust4.c new file mode 100644 index 000000000..136a183bd --- /dev/null +++ b/pthreads/tests/robust4.c @@ -0,0 +1,199 @@ +/* + * robust4.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 + * + * -------------------------------------------------------------------------- + * + * Thread A locks multiple robust mutexes + * Thread B blocks on same mutexes in different orderings + * Thread A terminates with thread waiting on mutexes + * Thread B awakes and inherits each mutex in turn, sets consistent and unlocks + * Main acquires mutexes with recovered state. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutex_init() + * pthread_mutex_lock() + * pthread_mutex_unlock() + * pthread_mutex_destroy() + * pthread_mutexattr_init() + * pthread_mutexattr_setrobust() + * pthread_mutexattr_settype() + * pthread_mutexattr_destroy() + */ + +#include "test.h" + +static int lockCount; + +static pthread_mutex_t mutex[3]; + +void * owner(void * arg) +{ + assert(pthread_mutex_lock(&mutex[0]) == 0); + lockCount++; + assert(pthread_mutex_lock(&mutex[1]) == 0); + lockCount++; + assert(pthread_mutex_lock(&mutex[2]) == 0); + lockCount++; + Sleep(200); + + return 0; +} + +void * inheritor(void * arg) +{ + int* o = (int*)arg; + + assert(pthread_mutex_lock(&mutex[o[0]]) == EOWNERDEAD); + lockCount++; + assert(pthread_mutex_lock(&mutex[o[1]]) == EOWNERDEAD); + lockCount++; + assert(pthread_mutex_lock(&mutex[o[2]]) == EOWNERDEAD); + lockCount++; + assert(pthread_mutex_consistent(&mutex[o[2]]) == 0); + assert(pthread_mutex_consistent(&mutex[o[1]]) == 0); + assert(pthread_mutex_consistent(&mutex[o[0]]) == 0); + assert(pthread_mutex_unlock(&mutex[o[2]]) == 0); + assert(pthread_mutex_unlock(&mutex[o[1]]) == 0); + assert(pthread_mutex_unlock(&mutex[o[0]]) == 0); + + return 0; +} + +int +main() +{ + pthread_t to, ti; + pthread_mutexattr_t ma; + int order[3]; + + assert(pthread_mutexattr_init(&ma) == 0); + assert(pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST) == 0); + + order[0]=0; + order[1]=1; + order[2]=2; + lockCount = 0; + assert(pthread_mutex_init(&mutex[0], &ma) == 0); + assert(pthread_mutex_init(&mutex[1], &ma) == 0); + assert(pthread_mutex_init(&mutex[2], &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + Sleep(100); + assert(pthread_create(&ti, NULL, inheritor, (void *)order) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 6); + assert(pthread_mutex_lock(&mutex[0]) == 0); + assert(pthread_mutex_unlock(&mutex[0]) == 0); + assert(pthread_mutex_destroy(&mutex[0]) == 0); + assert(pthread_mutex_lock(&mutex[1]) == 0); + assert(pthread_mutex_unlock(&mutex[1]) == 0); + assert(pthread_mutex_destroy(&mutex[1]) == 0); + assert(pthread_mutex_lock(&mutex[2]) == 0); + assert(pthread_mutex_unlock(&mutex[2]) == 0); + assert(pthread_mutex_destroy(&mutex[2]) == 0); + + order[0]=1; + order[1]=0; + order[2]=2; + lockCount = 0; + assert(pthread_mutex_init(&mutex[0], &ma) == 0); + assert(pthread_mutex_init(&mutex[1], &ma) == 0); + assert(pthread_mutex_init(&mutex[2], &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + Sleep(100); + assert(pthread_create(&ti, NULL, inheritor, (void *)order) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 6); + assert(pthread_mutex_lock(&mutex[0]) == 0); + assert(pthread_mutex_unlock(&mutex[0]) == 0); + assert(pthread_mutex_destroy(&mutex[0]) == 0); + assert(pthread_mutex_lock(&mutex[1]) == 0); + assert(pthread_mutex_unlock(&mutex[1]) == 0); + assert(pthread_mutex_destroy(&mutex[1]) == 0); + assert(pthread_mutex_lock(&mutex[2]) == 0); + assert(pthread_mutex_unlock(&mutex[2]) == 0); + assert(pthread_mutex_destroy(&mutex[2]) == 0); + + order[0]=0; + order[1]=2; + order[2]=1; + lockCount = 0; + assert(pthread_mutex_init(&mutex[0], &ma) == 0); + assert(pthread_mutex_init(&mutex[1], &ma) == 0); + assert(pthread_mutex_init(&mutex[2], &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + Sleep(100); + assert(pthread_create(&ti, NULL, inheritor, (void *)order) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 6); + assert(pthread_mutex_lock(&mutex[0]) == 0); + assert(pthread_mutex_unlock(&mutex[0]) == 0); + assert(pthread_mutex_destroy(&mutex[0]) == 0); + assert(pthread_mutex_lock(&mutex[1]) == 0); + assert(pthread_mutex_unlock(&mutex[1]) == 0); + assert(pthread_mutex_destroy(&mutex[1]) == 0); + assert(pthread_mutex_lock(&mutex[2]) == 0); + assert(pthread_mutex_unlock(&mutex[2]) == 0); + assert(pthread_mutex_destroy(&mutex[2]) == 0); + + order[0]=2; + order[1]=1; + order[2]=0; + lockCount = 0; + assert(pthread_mutex_init(&mutex[0], &ma) == 0); + assert(pthread_mutex_init(&mutex[1], &ma) == 0); + assert(pthread_mutex_init(&mutex[2], &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + Sleep(100); + assert(pthread_create(&ti, NULL, inheritor, (void *)order) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 6); + assert(pthread_mutex_lock(&mutex[0]) == 0); + assert(pthread_mutex_unlock(&mutex[0]) == 0); + assert(pthread_mutex_destroy(&mutex[0]) == 0); + assert(pthread_mutex_lock(&mutex[1]) == 0); + assert(pthread_mutex_unlock(&mutex[1]) == 0); + assert(pthread_mutex_destroy(&mutex[1]) == 0); + assert(pthread_mutex_lock(&mutex[2]) == 0); + assert(pthread_mutex_unlock(&mutex[2]) == 0); + assert(pthread_mutex_destroy(&mutex[2]) == 0); + + assert(pthread_mutexattr_destroy(&ma) == 0); + + return 0; +} diff --git a/pthreads/tests/robust5.c b/pthreads/tests/robust5.c new file mode 100644 index 000000000..c67d12482 --- /dev/null +++ b/pthreads/tests/robust5.c @@ -0,0 +1,120 @@ +/* + * robust5.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 + * + * -------------------------------------------------------------------------- + * + * Thread A locks multiple robust mutexes + * Thread B blocks on same mutexes + * Thread A terminates with thread waiting on mutexes + * Thread B awakes and inherits each mutex in turn + * Thread B terminates leaving orphaned mutexes + * Main inherits mutexes, sets consistent and unlocks. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutex_init() + * pthread_mutex_lock() + * pthread_mutex_unlock() + * pthread_mutex_destroy() + * pthread_mutexattr_init() + * pthread_mutexattr_setrobust() + * pthread_mutexattr_settype() + * pthread_mutexattr_destroy() + */ + +#include "test.h" + +static int lockCount; + +static pthread_mutex_t mutex[3]; + +void * owner(void * arg) +{ + assert(pthread_mutex_lock(&mutex[0]) == 0); + lockCount++; + assert(pthread_mutex_lock(&mutex[1]) == 0); + lockCount++; + assert(pthread_mutex_lock(&mutex[2]) == 0); + lockCount++; + + return 0; +} + +void * inheritor(void * arg) +{ + assert(pthread_mutex_lock(&mutex[0]) == EOWNERDEAD); + lockCount++; + assert(pthread_mutex_lock(&mutex[1]) == EOWNERDEAD); + lockCount++; + assert(pthread_mutex_lock(&mutex[2]) == EOWNERDEAD); + lockCount++; + + return 0; +} + +int +main() +{ + pthread_t to, ti; + pthread_mutexattr_t ma; + + assert(pthread_mutexattr_init(&ma) == 0); + assert(pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST) == 0); + + lockCount = 0; + assert(pthread_mutex_init(&mutex[0], &ma) == 0); + assert(pthread_mutex_init(&mutex[1], &ma) == 0); + assert(pthread_mutex_init(&mutex[2], &ma) == 0); + assert(pthread_create(&to, NULL, owner, NULL) == 0); + assert(pthread_join(to, NULL) == 0); + assert(pthread_create(&ti, NULL, inheritor, NULL) == 0); + assert(pthread_join(ti, NULL) == 0); + assert(lockCount == 6); + assert(pthread_mutex_lock(&mutex[0]) == EOWNERDEAD); + assert(pthread_mutex_consistent(&mutex[0]) == 0); + assert(pthread_mutex_unlock(&mutex[0]) == 0); + assert(pthread_mutex_destroy(&mutex[0]) == 0); + assert(pthread_mutex_lock(&mutex[1]) == EOWNERDEAD); + assert(pthread_mutex_consistent(&mutex[1]) == 0); + assert(pthread_mutex_unlock(&mutex[1]) == 0); + assert(pthread_mutex_destroy(&mutex[1]) == 0); + assert(pthread_mutex_lock(&mutex[2]) == EOWNERDEAD); + assert(pthread_mutex_consistent(&mutex[2]) == 0); + assert(pthread_mutex_unlock(&mutex[2]) == 0); + assert(pthread_mutex_destroy(&mutex[2]) == 0); + + assert(pthread_mutexattr_destroy(&ma) == 0); + + return 0; +} diff --git a/pthreads/tests/rwlock2_t.c b/pthreads/tests/rwlock2_t.c index 8e6ab6da0..4267ddbc8 100644 --- a/pthreads/tests/rwlock2_t.c +++ b/pthreads/tests/rwlock2_t.c @@ -50,12 +50,12 @@ int main() { struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; diff --git a/pthreads/tests/rwlock3.c b/pthreads/tests/rwlock3.c index 4b22c5a16..d30f04088 100644 --- a/pthreads/tests/rwlock3.c +++ b/pthreads/tests/rwlock3.c @@ -37,6 +37,8 @@ * and then unlock it again. * * Depends on API functions: + * pthread_create() + * pthread_join() * pthread_rwlock_wrlock() * pthread_rwlock_trywrlock() * pthread_rwlock_unlock() @@ -66,7 +68,7 @@ main() assert(pthread_create(&t, NULL, func, NULL) == 0); - Sleep(2000); + assert(pthread_join(t, NULL) == 0); assert(pthread_rwlock_unlock(&rwlock1) == 0); diff --git a/pthreads/tests/rwlock3_t.c b/pthreads/tests/rwlock3_t.c index bc45abc4d..6419de13e 100644 --- a/pthreads/tests/rwlock3_t.c +++ b/pthreads/tests/rwlock3_t.c @@ -63,12 +63,12 @@ main() { pthread_t t; struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; diff --git a/pthreads/tests/rwlock4.c b/pthreads/tests/rwlock4.c index edd9dc2c3..a19a00132 100644 --- a/pthreads/tests/rwlock4.c +++ b/pthreads/tests/rwlock4.c @@ -37,6 +37,8 @@ * and then unlock it again. * * Depends on API functions: + * pthread_create() + * pthread_join() * pthread_rwlock_rdlock() * pthread_rwlock_trywrlock() * pthread_rwlock_unlock() @@ -66,7 +68,7 @@ main() assert(pthread_create(&t, NULL, func, NULL) == 0); - Sleep(2000); + assert(pthread_join(t, NULL) == 0); assert(pthread_rwlock_unlock(&rwlock1) == 0); diff --git a/pthreads/tests/rwlock4_t.c b/pthreads/tests/rwlock4_t.c index 37ec34fa3..58b3602fb 100644 --- a/pthreads/tests/rwlock4_t.c +++ b/pthreads/tests/rwlock4_t.c @@ -63,12 +63,12 @@ main() { pthread_t t; struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; diff --git a/pthreads/tests/rwlock5.c b/pthreads/tests/rwlock5.c index 75b82f32a..3b4054756 100644 --- a/pthreads/tests/rwlock5.c +++ b/pthreads/tests/rwlock5.c @@ -37,6 +37,8 @@ * and then unlock it again. * * Depends on API functions: + * pthread_create() + * pthread_join() * pthread_rwlock_rdlock() * pthread_rwlock_tryrdlock() * pthread_rwlock_unlock() @@ -68,7 +70,7 @@ main() assert(pthread_create(&t, NULL, func, NULL) == 0); - Sleep(2000); + assert(pthread_join(t, NULL) == 0); assert(pthread_rwlock_unlock(&rwlock1) == 0); diff --git a/pthreads/tests/rwlock5_t.c b/pthreads/tests/rwlock5_t.c index bf473a40e..4a94658fb 100644 --- a/pthreads/tests/rwlock5_t.c +++ b/pthreads/tests/rwlock5_t.c @@ -65,12 +65,12 @@ main() { pthread_t t; struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; diff --git a/pthreads/tests/rwlock6.c b/pthreads/tests/rwlock6.c index 22d10db42..f667ce5ce 100644 --- a/pthreads/tests/rwlock6.c +++ b/pthreads/tests/rwlock6.c @@ -52,12 +52,12 @@ void * wrfunc(void * arg) int ba; assert(pthread_rwlock_wrlock(&rwlock1) == 0); - Sleep(2000); + Sleep(200); bankAccount += 10; ba = bankAccount; assert(pthread_rwlock_unlock(&rwlock1) == 0); - return ((void *) ba); + return ((void *)(size_t)ba); } void * rdfunc(void * arg) @@ -68,7 +68,7 @@ void * rdfunc(void * arg) ba = bankAccount; assert(pthread_rwlock_unlock(&rwlock1) == 0); - return ((void *) ba); + return ((void *)(size_t)ba); } int @@ -77,25 +77,25 @@ main() pthread_t wrt1; pthread_t wrt2; pthread_t rdt; - int wr1Result = 0; - int wr2Result = 0; - int rdResult = 0; + void* wr1Result = (void*)0; + void* wr2Result = (void*)0; + void* rdResult = (void*)0; bankAccount = 0; assert(pthread_create(&wrt1, NULL, wrfunc, NULL) == 0); - Sleep(500); + Sleep(50); assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0); - Sleep(500); + Sleep(50); assert(pthread_create(&wrt2, NULL, wrfunc, NULL) == 0); - assert(pthread_join(wrt1, (void **) &wr1Result) == 0); - assert(pthread_join(rdt, (void **) &rdResult) == 0); - assert(pthread_join(wrt2, (void **) &wr2Result) == 0); + assert(pthread_join(wrt1, &wr1Result) == 0); + assert(pthread_join(rdt, &rdResult) == 0); + assert(pthread_join(wrt2, &wr2Result) == 0); - assert(wr1Result == 10); - assert(rdResult == 10); - assert(wr2Result == 20); + assert((int)(size_t)wr1Result == 10); + assert((int)(size_t)rdResult == 10); + assert((int)(size_t)wr2Result == 20); return 0; } diff --git a/pthreads/tests/rwlock6_t.c b/pthreads/tests/rwlock6_t.c index aa38bf564..71cbe220a 100644 --- a/pthreads/tests/rwlock6_t.c +++ b/pthreads/tests/rwlock6_t.c @@ -55,29 +55,29 @@ void * wrfunc(void * arg) bankAccount += 10; assert(pthread_rwlock_unlock(&rwlock1) == 0); - return ((void *) bankAccount); + return ((void *)(size_t)bankAccount); } void * rdfunc(void * arg) { int ba = -1; struct timespec abstime = { 0, 0 }; - struct _timeb currSysTime; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; - if ((int) arg == 1) + if ((int) (size_t)arg == 1) { abstime.tv_sec += 1; assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == ETIMEDOUT); ba = 0; } - else if ((int) arg == 2) + else if ((int) (size_t)arg == 2) { abstime.tv_sec += 3; assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0); @@ -85,7 +85,7 @@ void * rdfunc(void * arg) assert(pthread_rwlock_unlock(&rwlock1) == 0); } - return ((void *) ba); + return ((void *)(size_t)ba); } int @@ -95,30 +95,30 @@ main() pthread_t wrt2; pthread_t rdt1; pthread_t rdt2; - int wr1Result = 0; - int wr2Result = 0; - int rd1Result = 0; - int rd2Result = 0; + void* wr1Result = (void*)0; + void* wr2Result = (void*)0; + void* rd1Result = (void*)0; + void* rd2Result = (void*)0; bankAccount = 0; assert(pthread_create(&wrt1, NULL, wrfunc, NULL) == 0); Sleep(500); - assert(pthread_create(&rdt1, NULL, rdfunc, (void *) 1) == 0); + assert(pthread_create(&rdt1, NULL, rdfunc, (void *)(size_t)1) == 0); Sleep(500); assert(pthread_create(&wrt2, NULL, wrfunc, NULL) == 0); Sleep(500); - assert(pthread_create(&rdt2, NULL, rdfunc, (void *) 2) == 0); + assert(pthread_create(&rdt2, NULL, rdfunc, (void *)(size_t)2) == 0); - assert(pthread_join(wrt1, (void **) &wr1Result) == 0); - assert(pthread_join(rdt1, (void **) &rd1Result) == 0); - assert(pthread_join(wrt2, (void **) &wr2Result) == 0); - assert(pthread_join(rdt2, (void **) &rd2Result) == 0); + assert(pthread_join(wrt1, &wr1Result) == 0); + assert(pthread_join(rdt1, &rd1Result) == 0); + assert(pthread_join(wrt2, &wr2Result) == 0); + assert(pthread_join(rdt2, &rd2Result) == 0); - assert(wr1Result == 10); - assert(rd1Result == 0); - assert(wr2Result == 20); - assert(rd2Result == 20); + assert((int)(size_t)wr1Result == 10); + assert((int)(size_t)rd1Result == 0); + assert((int)(size_t)wr2Result == 20); + assert((int)(size_t)rd2Result == 20); return 0; } diff --git a/pthreads/tests/rwlock6_t2.c b/pthreads/tests/rwlock6_t2.c index 58bfc3d94..b8b0df9f2 100644 --- a/pthreads/tests/rwlock6_t2.c +++ b/pthreads/tests/rwlock6_t2.c @@ -54,21 +54,21 @@ void * wrfunc(void * arg) int result; result = pthread_rwlock_timedwrlock(&rwlock1, &abstime); - if ((int) arg == 1) + if ((int) (size_t)arg == 1) { assert(result == 0); Sleep(2000); bankAccount += 10; assert(pthread_rwlock_unlock(&rwlock1) == 0); - return ((void *) bankAccount); + return ((void *)(size_t)bankAccount); } - else if ((int) arg == 2) + else if ((int) (size_t)arg == 2) { assert(result == ETIMEDOUT); return ((void *) 100); } - return ((void *) -1); + return ((void *)(size_t)-1); } void * rdfunc(void * arg) @@ -77,7 +77,7 @@ void * rdfunc(void * arg) assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == ETIMEDOUT); - return ((void *) ba); + return ((void *)(size_t)ba); } int @@ -86,34 +86,34 @@ main() pthread_t wrt1; pthread_t wrt2; pthread_t rdt; - int wr1Result = 0; - int wr2Result = 0; - int rdResult = 0; - struct _timeb currSysTime; + void* wr1Result = (void*)0; + void* wr2Result = (void*)0; + void* rdResult = (void*)0; + PTW32_STRUCT_TIMEB currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = currSysTime.time; + abstime.tv_sec = (long)currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; abstime.tv_sec += 1; bankAccount = 0; - assert(pthread_create(&wrt1, NULL, wrfunc, (void *) 1) == 0); + assert(pthread_create(&wrt1, NULL, wrfunc, (void *)(size_t)1) == 0); Sleep(100); assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0); Sleep(100); - assert(pthread_create(&wrt2, NULL, wrfunc, (void *) 2) == 0); + assert(pthread_create(&wrt2, NULL, wrfunc, (void *)(size_t)2) == 0); - assert(pthread_join(wrt1, (void **) &wr1Result) == 0); - assert(pthread_join(rdt, (void **) &rdResult) == 0); - assert(pthread_join(wrt2, (void **) &wr2Result) == 0); + assert(pthread_join(wrt1, &wr1Result) == 0); + assert(pthread_join(rdt, &rdResult) == 0); + assert(pthread_join(wrt2, &wr2Result) == 0); - assert(wr1Result == 10); - assert(rdResult == 0); - assert(wr2Result == 100); + assert((int)(size_t)wr1Result == 10); + assert((int)(size_t)rdResult == 0); + assert((int)(size_t)wr2Result == 100); return 0; } diff --git a/pthreads/tests/rwlock7.c b/pthreads/tests/rwlock7.c index 91466e4de..69d1a73fd 100644 --- a/pthreads/tests/rwlock7.c +++ b/pthreads/tests/rwlock7.c @@ -108,8 +108,8 @@ main (int argc, char *argv[]) int data_updates = 0; int seed = 1; - struct _timeb currSysTime1; - struct _timeb currSysTime2; + PTW32_STRUCT_TIMEB currSysTime1; + PTW32_STRUCT_TIMEB currSysTime2; /* * Initialize the shared data. @@ -122,7 +122,7 @@ main (int argc, char *argv[]) assert(pthread_rwlock_init (&data[data_count].lock, NULL) == 0); } - _ftime(&currSysTime1); + PTW32_FTIME(&currSysTime1); /* * Create THREADS threads to access shared data. @@ -135,7 +135,7 @@ main (int argc, char *argv[]) threads[count].seed = 1 + rand_r (&seed) % 71; assert(pthread_create (&threads[count].thread_id, - NULL, thread_routine, (void*)&threads[count]) == 0); + NULL, thread_routine, (void*)(size_t)&threads[count]) == 0); } /* @@ -187,13 +187,13 @@ main (int argc, char *argv[]) printf ("%d thread updates, %d data updates\n", thread_updates, data_updates); - _ftime(&currSysTime2); + PTW32_FTIME(&currSysTime2); printf( "\nstart: %ld/%d, stop: %ld/%d, duration:%ld\n", - currSysTime1.time,currSysTime1.millitm, - currSysTime2.time,currSysTime2.millitm, - (currSysTime2.time*1000+currSysTime2.millitm) - - (currSysTime1.time*1000+currSysTime1.millitm)); + (long)currSysTime1.time,currSysTime1.millitm, + (long)currSysTime2.time,currSysTime2.millitm, + ((long)((currSysTime2.time*1000+currSysTime2.millitm) - + (currSysTime1.time*1000+currSysTime1.millitm)))); return 0; } diff --git a/pthreads/tests/rwlock8.c b/pthreads/tests/rwlock8.c index c83a775ce..99c357aab 100644 --- a/pthreads/tests/rwlock8.c +++ b/pthreads/tests/rwlock8.c @@ -114,8 +114,8 @@ main (int argc, char *argv[]) int data_updates = 0; int seed = 1; - struct _timeb currSysTime1; - struct _timeb currSysTime2; + PTW32_STRUCT_TIMEB currSysTime1; + PTW32_STRUCT_TIMEB currSysTime2; /* * Initialize the shared data. @@ -128,7 +128,7 @@ main (int argc, char *argv[]) assert(pthread_rwlock_init (&data[data_count].lock, NULL) == 0); } - _ftime(&currSysTime1); + PTW32_FTIME(&currSysTime1); /* * Create THREADS threads to access shared data. @@ -141,7 +141,7 @@ main (int argc, char *argv[]) threads[count].seed = 1 + rand_r (&seed) % 71; assert(pthread_create (&threads[count].thread_id, - NULL, thread_routine, (void*)&threads[count]) == 0); + NULL, thread_routine, (void*)(size_t)&threads[count]) == 0); } /* @@ -193,13 +193,13 @@ main (int argc, char *argv[]) printf ("%d thread updates, %d data updates\n", thread_updates, data_updates); - _ftime(&currSysTime2); + PTW32_FTIME(&currSysTime2); printf( "\nstart: %ld/%d, stop: %ld/%d, duration:%ld\n", - currSysTime1.time,currSysTime1.millitm, - currSysTime2.time,currSysTime2.millitm, - (currSysTime2.time*1000+currSysTime2.millitm) - - (currSysTime1.time*1000+currSysTime1.millitm)); + (long)currSysTime1.time,currSysTime1.millitm, + (long)currSysTime2.time,currSysTime2.millitm, + ((long)((currSysTime2.time*1000+currSysTime2.millitm) - + (currSysTime1.time*1000+currSysTime1.millitm)))); return 0; } diff --git a/pthreads/tests/semaphore1.c b/pthreads/tests/semaphore1.c index f89a43081..8fc91ee02 100644 --- a/pthreads/tests/semaphore1.c +++ b/pthreads/tests/semaphore1.c @@ -86,8 +86,11 @@ thr(void * arg) if ( result == -1 ) { int err = errno; - printf("thread: sem_trywait 1: expecting error %s: got %s\n", - error_string[EAGAIN], error_string[err]); fflush(stdout); + if (err != EAGAIN) + { + printf("thread: sem_trywait 1: expecting error %s: got %s\n", + error_string[EAGAIN], error_string[err]); fflush(stdout); + } assert(err == EAGAIN); } else @@ -99,18 +102,9 @@ thr(void * arg) 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; + return NULL; } @@ -119,21 +113,25 @@ main() { pthread_t t; sem_t s; - int result; + void* result1 = (void*)-1; + int result2; assert(pthread_create(&t, NULL, thr, NULL) == 0); - assert(pthread_join(t, (void **)&result) == 0); - assert(result == 0); + assert(pthread_join(t, &result1) == 0); + assert((int)(size_t)result1 == 0); assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); - assert((result = sem_trywait(&s)) == -1); + assert((result2 = sem_trywait(&s)) == -1); - if ( result == -1 ) + if (result2 == -1) { int err = errno; - printf("main: sem_trywait 1: expecting error %s: got %s\n", - error_string[EAGAIN], error_string[err]); fflush(stdout); + if (err != EAGAIN) + { + printf("main: sem_trywait 1: expecting error %s: got %s\n", + error_string[EAGAIN], error_string[err]); fflush(stdout); + } assert(err == EAGAIN); } else @@ -141,18 +139,9 @@ main() printf("main: ok 1\n"); } - assert((result = sem_post(&s)) == 0); + assert((result2 = 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((result2 = sem_trywait(&s)) == 0); assert(sem_post(&s) == 0); diff --git a/pthreads/tests/semaphore4.c b/pthreads/tests/semaphore4.c index 37613ac39..3a28c7b50 100644 --- a/pthreads/tests/semaphore4.c +++ b/pthreads/tests/semaphore4.c @@ -94,7 +94,6 @@ main() assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); assert(sem_getvalue(&s, &value) == 0); -// printf("Value = %d\n", value); fflush(stdout); assert(value == 0); for (i = 1; i <= MAX_COUNT; i++) @@ -104,28 +103,23 @@ main() sched_yield(); assert(sem_getvalue(&s, &value) == 0); } while (value != -i); -// printf("Value = %d\n", value); fflush(stdout); assert(-value == i); } assert(sem_getvalue(&s, &value) == 0); assert(-value == MAX_COUNT); -//printf("value = %d\n", -value); fflush(stdout); assert(pthread_cancel(t[50]) == 0); { - int result; - assert(pthread_join(t[50], (void **) &result) == 0); -// printf("result = %d\n", result); fflush(stdout); + void* result; + assert(pthread_join(t[50], &result) == 0); } assert(sem_getvalue(&s, &value) == 0); -//printf("value = %d\n", -value); fflush(stdout); assert(-value == (MAX_COUNT - 1)); for (i = MAX_COUNT - 2; i >= 0; i--) { assert(sem_post(&s) == 0); assert(sem_getvalue(&s, &value) == 0); -// printf("Value = %d\n", value); fflush(stdout); assert(-value == i); } diff --git a/pthreads/tests/semaphore4t.c b/pthreads/tests/semaphore4t.c index 14a46694c..97bc7f88a 100644 --- a/pthreads/tests/semaphore4t.c +++ b/pthreads/tests/semaphore4t.c @@ -94,7 +94,6 @@ main() assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); assert(sem_getvalue(&s, &value) == 0); -// printf("Value = %d\n", value); fflush(stdout); assert(value == 0); for (i = 1; i <= MAX_COUNT; i++) @@ -104,7 +103,6 @@ main() sched_yield(); assert(sem_getvalue(&s, &value) == 0); } while (value != -i); -// printf("Value = %d\n", value); fflush(stdout); assert(-value == i); } @@ -119,7 +117,6 @@ main() { assert(sem_post(&s) == 0); assert(sem_getvalue(&s, &value) == 0); -// printf("Value = %d\n", value); fflush(stdout); assert(-value == i); } diff --git a/pthreads/tests/sequence1.c b/pthreads/tests/sequence1.c new file mode 100644 index 000000000..46388eebd --- /dev/null +++ b/pthreads/tests/sequence1.c @@ -0,0 +1,142 @@ +/* + * File: sequence1.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: + * - that unique thread sequence numbers are generated. + * - Analyse thread struct reuse. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - This test is implementation specific + * because it uses knowledge of internals that should be + * opaque to an application. + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - analysis output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - unique sequence numbers are generated for every new thread. + * + * Fail Criteria: + * - + */ + +#include "test.h" + +/* + */ + +enum { + NUMTHREADS = 10000 +}; + + +static long done = 0; +/* + * seqmap should have 1 in every element except [0] + * Thread sequence numbers start at 1 and we will also + * include this main thread so we need NUMTHREADS+2 + * elements. + */ +static UINT64 seqmap[NUMTHREADS+2]; + +void * func(void * arg) +{ + sched_yield(); + seqmap[(int)pthread_getunique_np(pthread_self())] = 1; + InterlockedIncrement(&done); + + return (void *) 0; +} + +int +main() +{ + pthread_t t[NUMTHREADS]; + pthread_attr_t attr; + int i; + + assert(pthread_attr_init(&attr) == 0); + assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0); + + for (i = 0; i < NUMTHREADS+2; i++) + { + seqmap[i] = 0; + } + + for (i = 0; i < NUMTHREADS; i++) + { + if (NUMTHREADS/2 == i) + { + /* Include this main thread, which will be an implicit pthread_t */ + seqmap[(int)pthread_getunique_np(pthread_self())] = 1; + } + assert(pthread_create(&t[i], &attr, func, NULL) == 0); + } + + while (NUMTHREADS > InterlockedExchangeAdd((LPLONG)&done, 0L)) + Sleep(100); + + Sleep(100); + + assert(seqmap[0] == 0); + for (i = 1; i < NUMTHREADS+2; i++) + { + assert(seqmap[i] == 1); + } + + return 0; +} diff --git a/pthreads/tests/sizes.c b/pthreads/tests/sizes.c index 73c726171..554d0e843 100644 --- a/pthreads/tests/sizes.c +++ b/pthreads/tests/sizes.c @@ -8,24 +8,24 @@ main() { printf("Sizes of pthreads-win32 structs\n"); printf("-------------------------------\n"); - printf("%30s %4d\n", "pthread_t", sizeof(pthread_t)); - printf("%30s %4d\n", "ptw32_thread_t", sizeof(ptw32_thread_t)); - printf("%30s %4d\n", "pthread_attr_t_", sizeof(struct pthread_attr_t_)); - printf("%30s %4d\n", "sem_t_", sizeof(struct sem_t_)); - printf("%30s %4d\n", "pthread_mutex_t_", sizeof(struct pthread_mutex_t_)); - printf("%30s %4d\n", "pthread_mutexattr_t_", sizeof(struct pthread_mutexattr_t_)); - printf("%30s %4d\n", "pthread_spinlock_t_", sizeof(struct pthread_spinlock_t_)); - printf("%30s %4d\n", "pthread_barrier_t_", sizeof(struct pthread_barrier_t_)); - printf("%30s %4d\n", "pthread_barrierattr_t_", sizeof(struct pthread_barrierattr_t_)); - printf("%30s %4d\n", "pthread_key_t_", sizeof(struct pthread_key_t_)); - printf("%30s %4d\n", "pthread_cond_t_", sizeof(struct pthread_cond_t_)); - printf("%30s %4d\n", "pthread_condattr_t_", sizeof(struct pthread_condattr_t_)); - printf("%30s %4d\n", "pthread_rwlock_t_", sizeof(struct pthread_rwlock_t_)); - printf("%30s %4d\n", "pthread_rwlockattr_t_", sizeof(struct pthread_rwlockattr_t_)); - printf("%30s %4d\n", "pthread_once_t_", sizeof(struct pthread_once_t_)); - printf("%30s %4d\n", "ptw32_cleanup_t", sizeof(struct ptw32_cleanup_t)); - printf("%30s %4d\n", "ptw32_mcs_node_t_", sizeof(struct ptw32_mcs_node_t_)); - printf("%30s %4d\n", "sched_param", sizeof(struct sched_param)); + printf("%30s %4d\n", "pthread_t", (int)sizeof(pthread_t)); + printf("%30s %4d\n", "ptw32_thread_t", (int)sizeof(ptw32_thread_t)); + printf("%30s %4d\n", "pthread_attr_t_", (int)sizeof(struct pthread_attr_t_)); + printf("%30s %4d\n", "sem_t_", (int)sizeof(struct sem_t_)); + printf("%30s %4d\n", "pthread_mutex_t_", (int)sizeof(struct pthread_mutex_t_)); + printf("%30s %4d\n", "pthread_mutexattr_t_", (int)sizeof(struct pthread_mutexattr_t_)); + printf("%30s %4d\n", "pthread_spinlock_t_", (int)sizeof(struct pthread_spinlock_t_)); + printf("%30s %4d\n", "pthread_barrier_t_", (int)sizeof(struct pthread_barrier_t_)); + printf("%30s %4d\n", "pthread_barrierattr_t_", (int)sizeof(struct pthread_barrierattr_t_)); + printf("%30s %4d\n", "pthread_key_t_", (int)sizeof(struct pthread_key_t_)); + printf("%30s %4d\n", "pthread_cond_t_", (int)sizeof(struct pthread_cond_t_)); + printf("%30s %4d\n", "pthread_condattr_t_", (int)sizeof(struct pthread_condattr_t_)); + printf("%30s %4d\n", "pthread_rwlock_t_", (int)sizeof(struct pthread_rwlock_t_)); + printf("%30s %4d\n", "pthread_rwlockattr_t_", (int)sizeof(struct pthread_rwlockattr_t_)); + printf("%30s %4d\n", "pthread_once_t_", (int)sizeof(struct pthread_once_t_)); + printf("%30s %4d\n", "ptw32_cleanup_t", (int)sizeof(struct ptw32_cleanup_t)); + printf("%30s %4d\n", "ptw32_mcs_node_t_", (int)sizeof(struct ptw32_mcs_node_t_)); + printf("%30s %4d\n", "sched_param", (int)sizeof(struct sched_param)); printf("-------------------------------\n"); return 0; diff --git a/pthreads/tests/spin3.c b/pthreads/tests/spin3.c index 8c0dae69f..bbf8bfb22 100644 --- a/pthreads/tests/spin3.c +++ b/pthreads/tests/spin3.c @@ -46,7 +46,7 @@ static pthread_spinlock_t spin; void * unlocker(void * arg) { - int expectedResult = (int) arg; + int expectedResult = (int)(size_t)arg; wasHere++; assert(pthread_spin_unlock(&spin) == expectedResult); @@ -62,9 +62,13 @@ main() wasHere = 0; assert(pthread_spin_init(&spin, PTHREAD_PROCESS_PRIVATE) == 0); assert(pthread_spin_lock(&spin) == 0); - assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0); + assert(pthread_create(&t, NULL, unlocker, (void*)0) == 0); assert(pthread_join(t, NULL) == 0); - assert(pthread_spin_unlock(&spin) == EPERM); + /* + * Our spinlocks don't record the owner thread so any thread can unlock the spinlock, + * but nor is it an error for any thread to unlock a spinlock that is not locked. + */ + assert(pthread_spin_unlock(&spin) == 0); assert(pthread_spin_destroy(&spin) == 0); assert(wasHere == 2); diff --git a/pthreads/tests/spin4.c b/pthreads/tests/spin4.c index 8386d0956..3a4fd6f24 100644 --- a/pthreads/tests/spin4.c +++ b/pthreads/tests/spin4.c @@ -41,8 +41,8 @@ #include pthread_spinlock_t lock = PTHREAD_SPINLOCK_INITIALIZER; -struct _timeb currSysTimeStart; -struct _timeb currSysTimeStop; +PTW32_STRUCT_TIMEB currSysTimeStart; +PTW32_STRUCT_TIMEB currSysTimeStop; #define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ - (_TStart.time*1000+_TStart.millitm)) @@ -51,22 +51,22 @@ static int washere = 0; void * func(void * arg) { - _ftime(&currSysTimeStart); + PTW32_FTIME(&currSysTimeStart); washere = 1; assert(pthread_spin_lock(&lock) == 0); assert(pthread_spin_unlock(&lock) == 0); - _ftime(&currSysTimeStop); + PTW32_FTIME(&currSysTimeStop); - return (void *) GetDurationMilliSecs(currSysTimeStart, currSysTimeStop); + return (void *)(size_t)GetDurationMilliSecs(currSysTimeStart, currSysTimeStop); } int main() { - long result = 0; + void* result = (void*)0; pthread_t t; int CPUs; - struct _timeb sysTime; + PTW32_STRUCT_TIMEB sysTime; if ((CPUs = pthread_num_processors_np()) == 1) { @@ -86,14 +86,14 @@ main() do { sched_yield(); - _ftime(&sysTime); + PTW32_FTIME(&sysTime); } while (GetDurationMilliSecs(currSysTimeStart, sysTime) <= 1000); assert(pthread_spin_unlock(&lock) == 0); - assert(pthread_join(t, (void **) &result) == 0); - assert(result > 1000); + assert(pthread_join(t, &result) == 0); + assert((int)(size_t)result > 1000); assert(pthread_spin_destroy(&lock) == 0); diff --git a/pthreads/tests/stress1.c b/pthreads/tests/stress1.c index ac882503c..7c787dcfb 100644 --- a/pthreads/tests/stress1.c +++ b/pthreads/tests/stress1.c @@ -1,278 +1,278 @@ -/* - * stress1.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: - * - Stress test condition variables, mutexes, semaphores. - * - * Test Method (Validation or Falsification): - * - Validation - * - * Requirements Tested: - * - Correct accounting of semaphore and condition variable waiters. - * - * Features Tested: - * - - * - * Cases Tested: - * - - * - * Description: - * Attempting to expose race conditions in cond vars, semaphores etc. - * - Master attempts to signal slave close to when timeout is due. - * - Master and slave do battle continuously until main tells them to stop. - * - Afterwards, the CV must be successfully destroyed (will return an - * error if there are waiters (including any internal semaphore waiters, - * which, if there are, cannot be real waiters). - * - * Environment: - * - - * - * Input: - * - None. - * - * Output: - * - File name, Line number, and failed expression on failure. - * - No output on success. - * - * Assumptions: - * - - * - * Pass Criteria: - * - CV is successfully destroyed. - * - * Fail Criteria: - * - CV destroy fails. - */ - -#include "test.h" -#include -#include - - -const unsigned int ITERATIONS = 1000; - -static pthread_t master, slave; -typedef struct { - int value; - pthread_cond_t cv; - pthread_mutex_t mx; -} mysig_t; - -static int allExit; -static mysig_t control = {0, PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER}; -static pthread_barrier_t startBarrier, readyBarrier, holdBarrier; -static int timeoutCount = 0; -static int signalsTakenCount = 0; -static int signalsSent = 0; -static int bias = 0; -static int timeout = 10; // Must be > 0 - -enum { - CTL_STOP = -1 -}; - -/* - * Returns abstime 'milliseconds' from 'now'. - * - * Works for: -INT_MAX <= millisecs <= INT_MAX - */ -struct timespec * -millisecondsFromNow (struct timespec * time, int millisecs) -{ - struct _timeb currSysTime; - int64_t nanosecs, secs; - const int64_t NANOSEC_PER_MILLISEC = 1000000; - const int64_t NANOSEC_PER_SEC = 1000000000; - - /* get current system time and add millisecs */ - _ftime(&currSysTime); - - secs = (int64_t)(currSysTime.time) + (millisecs / 1000); - nanosecs = ((int64_t) (millisecs%1000 + currSysTime.millitm)) * NANOSEC_PER_MILLISEC; - if (nanosecs >= NANOSEC_PER_SEC) - { - secs++; - nanosecs -= NANOSEC_PER_SEC; - } - else if (nanosecs < 0) - { - secs--; - nanosecs += NANOSEC_PER_SEC; - } - - time->tv_nsec = (long)nanosecs; - time->tv_sec = (long)secs; - - return time; -} - -void * -masterThread (void * arg) -{ - int dither = (int) arg; - - timeout = (int) arg; - - pthread_barrier_wait(&startBarrier); - - do - { - int sleepTime; - - assert(pthread_mutex_lock(&control.mx) == 0); - control.value = timeout; - assert(pthread_mutex_unlock(&control.mx) == 0); - - /* - * We are attempting to send the signal close to when the slave - * is due to timeout. We feel around by adding some [non-random] dither. - * - * dither is in the range 2*timeout peak-to-peak - * sleep time is the average of timeout plus dither. - * e.g. - * if timeout = 10 then dither = 20 and - * sleep millisecs is: 5 <= ms <= 15 - * - * The bias value attempts to apply some negative feedback to keep - * the ratio of timeouts to signals taken close to 1:1. - * bias changes more slowly than dither so as to average more. - * - * Finally, if abs(bias) exceeds timeout then timeout is incremented. - */ - if (signalsSent % timeout == 0) - { - if (timeoutCount > signalsTakenCount) - { - bias++; - } - else if (timeoutCount < signalsTakenCount) - { - bias--; - } - if (bias < -timeout || bias > timeout) - { - timeout++; - } - } - dither = (dither + 1 ) % (timeout * 2); - sleepTime = (timeout - bias + dither) / 2; - Sleep(sleepTime); - assert(pthread_cond_signal(&control.cv) == 0); - signalsSent++; - - pthread_barrier_wait(&holdBarrier); - pthread_barrier_wait(&readyBarrier); - } - while (!allExit); - - return NULL; -} - -void * -slaveThread (void * arg) -{ - struct timespec time; - - pthread_barrier_wait(&startBarrier); - - do - { - assert(pthread_mutex_lock(&control.mx) == 0); - if (pthread_cond_timedwait(&control.cv, - &control.mx, - millisecondsFromNow(&time, control.value)) == ETIMEDOUT) - { - timeoutCount++; - } - else - { - signalsTakenCount++; - } - assert(pthread_mutex_unlock(&control.mx) == 0); - - pthread_barrier_wait(&holdBarrier); - pthread_barrier_wait(&readyBarrier); - } - while (!allExit); - - return NULL; -} - -int -main () -{ - unsigned int i; - - assert(pthread_barrier_init(&startBarrier, NULL, 3) == 0); - assert(pthread_barrier_init(&readyBarrier, NULL, 3) == 0); - assert(pthread_barrier_init(&holdBarrier, NULL, 3) == 0); - - assert(pthread_create(&master, NULL, masterThread, (void *) timeout) == 0); - assert(pthread_create(&slave, NULL, slaveThread, NULL) == 0); - - allExit = FALSE; - - pthread_barrier_wait(&startBarrier); - - for (i = 1; !allExit; i++) - { - pthread_barrier_wait(&holdBarrier); - if (i >= ITERATIONS) - { - allExit = TRUE; - } - pthread_barrier_wait(&readyBarrier); - } - - assert(pthread_join(slave, NULL) == 0); - assert(pthread_join(master, NULL) == 0); - - printf("Signals sent = %d\nWait timeouts = %d\nSignals taken = %d\nBias = %d\nTimeout = %d\n", - signalsSent, - timeoutCount, - signalsTakenCount, - (int) bias, - timeout); - - /* Cleanup */ - assert(pthread_barrier_destroy(&holdBarrier) == 0); - assert(pthread_barrier_destroy(&readyBarrier) == 0); - assert(pthread_barrier_destroy(&startBarrier) == 0); - assert(pthread_cond_destroy(&control.cv) == 0); - assert(pthread_mutex_destroy(&control.mx) == 0); - - /* Success. */ - return 0; -} +/* + * stress1.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: + * - Stress test condition variables, mutexes, semaphores. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - Correct accounting of semaphore and condition variable waiters. + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * Attempting to expose race conditions in cond vars, semaphores etc. + * - Master attempts to signal slave close to when timeout is due. + * - Master and slave do battle continuously until main tells them to stop. + * - Afterwards, the CV must be successfully destroyed (will return an + * error if there are waiters (including any internal semaphore waiters, + * which, if there are, cannot be real waiters). + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - CV is successfully destroyed. + * + * Fail Criteria: + * - CV destroy fails. + */ + +#include "test.h" +#include +#include + + +const unsigned int ITERATIONS = 1000; + +static pthread_t master, slave; +typedef struct { + int value; + pthread_cond_t cv; + pthread_mutex_t mx; +} mysig_t; + +static int allExit; +static mysig_t control = {0, PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER}; +static pthread_barrier_t startBarrier, readyBarrier, holdBarrier; +static int timeoutCount = 0; +static int signalsTakenCount = 0; +static int signalsSent = 0; +static int bias = 0; +static int timeout = 10; // Must be > 0 + +enum { + CTL_STOP = -1 +}; + +/* + * Returns abstime 'milliseconds' from 'now'. + * + * Works for: -INT_MAX <= millisecs <= INT_MAX + */ +struct timespec * +millisecondsFromNow (struct timespec * time, int millisecs) +{ + PTW32_STRUCT_TIMEB currSysTime; + int64_t nanosecs, secs; + const int64_t NANOSEC_PER_MILLISEC = 1000000; + const int64_t NANOSEC_PER_SEC = 1000000000; + + /* get current system time and add millisecs */ + PTW32_FTIME(&currSysTime); + + secs = (int64_t)(currSysTime.time) + (millisecs / 1000); + nanosecs = ((int64_t) (millisecs%1000 + currSysTime.millitm)) * NANOSEC_PER_MILLISEC; + if (nanosecs >= NANOSEC_PER_SEC) + { + secs++; + nanosecs -= NANOSEC_PER_SEC; + } + else if (nanosecs < 0) + { + secs--; + nanosecs += NANOSEC_PER_SEC; + } + + time->tv_nsec = (long)nanosecs; + time->tv_sec = (long)secs; + + return time; +} + +void * +masterThread (void * arg) +{ + int dither = (int)(size_t)arg; + + timeout = (int)(size_t)arg; + + pthread_barrier_wait(&startBarrier); + + do + { + int sleepTime; + + assert(pthread_mutex_lock(&control.mx) == 0); + control.value = timeout; + assert(pthread_mutex_unlock(&control.mx) == 0); + + /* + * We are attempting to send the signal close to when the slave + * is due to timeout. We feel around by adding some [non-random] dither. + * + * dither is in the range 2*timeout peak-to-peak + * sleep time is the average of timeout plus dither. + * e.g. + * if timeout = 10 then dither = 20 and + * sleep millisecs is: 5 <= ms <= 15 + * + * The bias value attempts to apply some negative feedback to keep + * the ratio of timeouts to signals taken close to 1:1. + * bias changes more slowly than dither so as to average more. + * + * Finally, if abs(bias) exceeds timeout then timeout is incremented. + */ + if (signalsSent % timeout == 0) + { + if (timeoutCount > signalsTakenCount) + { + bias++; + } + else if (timeoutCount < signalsTakenCount) + { + bias--; + } + if (bias < -timeout || bias > timeout) + { + timeout++; + } + } + dither = (dither + 1 ) % (timeout * 2); + sleepTime = (timeout - bias + dither) / 2; + Sleep(sleepTime); + assert(pthread_cond_signal(&control.cv) == 0); + signalsSent++; + + pthread_barrier_wait(&holdBarrier); + pthread_barrier_wait(&readyBarrier); + } + while (!allExit); + + return NULL; +} + +void * +slaveThread (void * arg) +{ + struct timespec time; + + pthread_barrier_wait(&startBarrier); + + do + { + assert(pthread_mutex_lock(&control.mx) == 0); + if (pthread_cond_timedwait(&control.cv, + &control.mx, + millisecondsFromNow(&time, control.value)) == ETIMEDOUT) + { + timeoutCount++; + } + else + { + signalsTakenCount++; + } + assert(pthread_mutex_unlock(&control.mx) == 0); + + pthread_barrier_wait(&holdBarrier); + pthread_barrier_wait(&readyBarrier); + } + while (!allExit); + + return NULL; +} + +int +main () +{ + unsigned int i; + + assert(pthread_barrier_init(&startBarrier, NULL, 3) == 0); + assert(pthread_barrier_init(&readyBarrier, NULL, 3) == 0); + assert(pthread_barrier_init(&holdBarrier, NULL, 3) == 0); + + assert(pthread_create(&master, NULL, masterThread, (void *)(size_t)timeout) == 0); + assert(pthread_create(&slave, NULL, slaveThread, NULL) == 0); + + allExit = FALSE; + + pthread_barrier_wait(&startBarrier); + + for (i = 1; !allExit; i++) + { + pthread_barrier_wait(&holdBarrier); + if (i >= ITERATIONS) + { + allExit = TRUE; + } + pthread_barrier_wait(&readyBarrier); + } + + assert(pthread_join(slave, NULL) == 0); + assert(pthread_join(master, NULL) == 0); + + printf("Signals sent = %d\nWait timeouts = %d\nSignals taken = %d\nBias = %d\nTimeout = %d\n", + signalsSent, + timeoutCount, + signalsTakenCount, + (int) bias, + timeout); + + /* Cleanup */ + assert(pthread_barrier_destroy(&holdBarrier) == 0); + assert(pthread_barrier_destroy(&readyBarrier) == 0); + assert(pthread_barrier_destroy(&startBarrier) == 0); + assert(pthread_cond_destroy(&control.cv) == 0); + assert(pthread_mutex_destroy(&control.mx) == 0); + + /* Success. */ + return 0; +} diff --git a/pthreads/tests/test.h b/pthreads/tests/test.h index dad485590..042e87b68 100644 --- a/pthreads/tests/test.h +++ b/pthreads/tests/test.h @@ -1,140 +1,182 @@ -/* - * test.h - * - * Useful definitions and declarations for tests. - * - * - * -------------------------------------------------------------------------- - * - * 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 _PTHREAD_TEST_H_ -#define _PTHREAD_TEST_H_ - -#include "pthread.h" -#include "sched.h" -#include "semaphore.h" - -#include -#include - -#define PTW32_THREAD_NULL_ID {NULL,0} - -#if defined(__MINGW32__) -#include -#elif defined(__BORLANDC__) -#define int64_t ULONGLONG -#else -#define int64_t _int64 -#endif - - -const char * error_string[] = { - "ZERO_or_EOK", - "EPERM", - "ENOFILE_or_ENOENT", - "ESRCH", - "EINTR", - "EIO", - "ENXIO", - "E2BIG", - "ENOEXEC", - "EBADF", - "ECHILD", - "EAGAIN", - "ENOMEM", - "EACCES", - "EFAULT", - "UNKNOWN_15", - "EBUSY", - "EEXIST", - "EXDEV", - "ENODEV", - "ENOTDIR", - "EISDIR", - "EINVAL", - "ENFILE", - "EMFILE", - "ENOTTY", - "UNKNOWN_26", - "EFBIG", - "ENOSPC", - "ESPIPE", - "EROFS", - "EMLINK", - "EPIPE", - "EDOM", - "ERANGE", - "UNKNOWN_35", - "EDEADLOCK_or_EDEADLK", - "UNKNOWN_37", - "ENAMETOOLONG", - "ENOLCK", - "ENOSYS", - "ENOTEMPTY", - "EILSEQ" -}; - -/* - * The Mingw32 assert macro calls the CRTDLL _assert function - * which pops up a dialog. We want to run in batch mode so - * we define our own assert macro. - */ -#ifdef assert -# undef assert -#endif - -#ifndef ASSERT_TRACE -# define ASSERT_TRACE 0 -#else -# undef ASSERT_TRACE -# define ASSERT_TRACE 1 -#endif - -# define assert(e) \ - ((e) ? ((ASSERT_TRACE) ? fprintf(stderr, \ - "Assertion succeeded: (%s), file %s, line %d\n", \ - #e, __FILE__, (int) __LINE__), \ - fflush(stderr) : \ - 0) : \ - (fprintf(stderr, "Assertion failed: (%s), file %s, line %d\n", \ - #e, __FILE__, (int) __LINE__), exit(1), 0)) - -int assertE; -# define assert_e(e, o, r) \ - (((assertE = e) o (r)) ? ((ASSERT_TRACE) ? fprintf(stderr, \ - "Assertion succeeded: (%s), file %s, line %d\n", \ - #e, __FILE__, (int) __LINE__), \ - fflush(stderr) : \ - 0) : \ - (fprintf(stderr, "Assertion failed: (%s %s %s), file %s, line %d, error %s\n", \ - #e,#o,#r, __FILE__, (int) __LINE__, error_string[assertE]), exit(1), 0)) - -#endif +/* + * test.h + * + * Useful definitions and declarations for tests. + * + * + * -------------------------------------------------------------------------- + * + * 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 _PTHREAD_TEST_H_ +#define _PTHREAD_TEST_H_ + +#include "pthread.h" +#include "sched.h" +#include "semaphore.h" + +#include +#include + +#define PTW32_THREAD_NULL_ID {NULL,0} + +/* + * Some non-thread POSIX API substitutes + */ +#define rand_r( _seed ) \ + ( _seed == _seed? rand() : rand() ) + +#if defined(__MINGW32__) +#include +#elif defined(__BORLANDC__) +#define int64_t ULONGLONG +#else +#define int64_t _int64 +#endif + +#if defined(_MSC_VER) && _MSC_VER >= 1400 +# define PTW32_FTIME(x) _ftime64_s(x) +# define PTW32_STRUCT_TIMEB struct __timeb64 +#elif ( defined(_MSC_VER) && _MSC_VER >= 1300 ) || \ + ( defined(__MINGW32__) && __MSVCRT_VERSION__ >= 0x0601 ) +# define PTW32_FTIME(x) _ftime64(x) +# define PTW32_STRUCT_TIMEB struct __timeb64 +#else +# define PTW32_FTIME(x) _ftime(x) +# define PTW32_STRUCT_TIMEB struct _timeb +#endif + + +const char * error_string[] = { + "ZERO_or_EOK", + "EPERM", + "ENOFILE_or_ENOENT", + "ESRCH", + "EINTR", + "EIO", + "ENXIO", + "E2BIG", + "ENOEXEC", + "EBADF", + "ECHILD", + "EAGAIN", + "ENOMEM", + "EACCES", + "EFAULT", + "UNKNOWN_15", + "EBUSY", + "EEXIST", + "EXDEV", + "ENODEV", + "ENOTDIR", + "EISDIR", + "EINVAL", + "ENFILE", + "EMFILE", + "ENOTTY", + "UNKNOWN_26", + "EFBIG", + "ENOSPC", + "ESPIPE", + "EROFS", + "EMLINK", + "EPIPE", + "EDOM", + "ERANGE", + "UNKNOWN_35", + "EDEADLOCK_or_EDEADLK", + "UNKNOWN_37", + "ENAMETOOLONG", + "ENOLCK", + "ENOSYS", + "ENOTEMPTY", + "EILSEQ", + "EOWNERDEAD", + "ENOTRECOVERABLE" +}; + +/* + * The Mingw32 assert macro calls the CRTDLL _assert function + * which pops up a dialog. We want to run in batch mode so + * we define our own assert macro. + */ +#ifdef assert +# undef assert +#endif + +#ifndef ASSERT_TRACE +# define ASSERT_TRACE 0 +#else +# undef ASSERT_TRACE +# define ASSERT_TRACE 1 +#endif + +# define assert(e) \ + ((e) ? ((ASSERT_TRACE) ? fprintf(stderr, \ + "Assertion succeeded: (%s), file %s, line %d\n", \ + #e, __FILE__, (int) __LINE__), \ + fflush(stderr) : \ + 0) : \ + (fprintf(stderr, "Assertion failed: (%s), file %s, line %d\n", \ + #e, __FILE__, (int) __LINE__), exit(1), 0)) + +int assertE; +# define assert_e(e, o, r) \ + (((assertE = e) o (r)) ? ((ASSERT_TRACE) ? fprintf(stderr, \ + "Assertion succeeded: (%s), file %s, line %d\n", \ + #e, __FILE__, (int) __LINE__), \ + fflush(stderr) : \ + 0) : \ + (fprintf(stderr, "Assertion failed: (%s %s %s), file %s, line %d, error %s\n", \ + #e,#o,#r, __FILE__, (int) __LINE__, error_string[assertE]), exit(1), 0)) + +#endif + +# define BEGIN_MUTEX_STALLED_ROBUST(mxAttr) \ + for(;;) \ + { \ + static int _i=0; \ + static int _robust; \ + pthread_mutexattr_getrobust(&(mxAttr), &_robust); + +# define END_MUTEX_STALLED_ROBUST(mxAttr) \ + printf("Pass %s\n", _robust==PTHREAD_MUTEX_ROBUST?"Robust":"Non-robust"); \ + if (++_i > 1) \ + break; \ + else \ + { \ + pthread_mutexattr_t *pma, *pmaEnd; \ + for(pma = &(mxAttr), pmaEnd = pma + sizeof(mxAttr)/sizeof(pthread_mutexattr_t); \ + pma < pmaEnd; \ + pthread_mutexattr_setrobust(pma++, PTHREAD_MUTEX_ROBUST)); \ + } \ + } + +# define IS_ROBUST (_robust==PTHREAD_MUTEX_ROBUST) diff --git a/pthreads/tests/tsd1.c b/pthreads/tests/tsd1.c index c28e4c53e..84d78886c 100644 --- a/pthreads/tests/tsd1.c +++ b/pthreads/tests/tsd1.c @@ -179,9 +179,7 @@ main() */ for (i = 1; i < NUM_THREADS; i++) { - int result = 0; - - assert(pthread_join(thread[i], (void **) &result) == 0); + assert(pthread_join(thread[i], NULL) == 0); } assert(pthread_key_delete(key) == 0); diff --git a/pthreads/tests/tsd2.c b/pthreads/tests/tsd2.c index d1f50cde3..16e69948c 100644 --- a/pthreads/tests/tsd2.c +++ b/pthreads/tests/tsd2.c @@ -183,9 +183,7 @@ main() */ for (i = 1; i < NUM_THREADS; i++) { - int result = 0; - - assert(pthread_join(thread[i], (void **) &result) == 0); + assert(pthread_join(thread[i], NULL) == 0); } assert(pthread_key_delete(key) == 0); diff --git a/pthreads/tests/valid1.c b/pthreads/tests/valid1.c index 4d5cab592..a3913fd04 100644 --- a/pthreads/tests/valid1.c +++ b/pthreads/tests/valid1.c @@ -94,7 +94,7 @@ main() washere = 0; assert(pthread_create(&t, NULL, func, NULL) == 0); assert(pthread_join(t, &result) == 0); - assert(result == 0); + assert((int)(size_t)result == 0); assert(washere == 1); sched_yield(); assert(pthread_kill(t, 0) == ESRCH); diff --git a/pthreads/version.rc b/pthreads/version.rc index a6c22a2ac..02d779c2e 100644 --- a/pthreads/version.rc +++ b/pthreads/version.rc @@ -41,47 +41,52 @@ * If using the default (no __CLEANUP_* defined), pthread.h will define it * as __CLEANUP_C. */ +#if defined(_WIN64) +# define PTW32_ARCH "64 bit" +#else +# define PTW32_ARCH "32 bit" +#endif -#ifdef PTW32_RC_MSC +#if defined(PTW32_RC_MSC) # if defined(__CLEANUP_C) # define PTW32_VERSIONINFO_NAME "pthreadVC\0" -# define PTW32_VERSIONINFO_COMMENT "MS C build -- longjmp thread exiting\0" +# define PTW32_VERSIONINFO_DESCRIPTION "MS C " PTW32_ARCH "\0" # elif defined(__CLEANUP_CXX) # define PTW32_VERSIONINFO_NAME "pthreadVCE\0" -# define PTW32_VERSIONINFO_COMMENT "MS C++ build -- C++ exception thread exiting\0" +# define PTW32_VERSIONINFO_DESCRIPTION "MS C++ " PTW32_ARCH "\0" # elif defined(__CLEANUP_SEH) # define PTW32_VERSIONINFO_NAME "pthreadVSE\0" -# define PTW32_VERSIONINFO_COMMENT "MS C build -- structured exception thread exiting\0" +# define PTW32_VERSIONINFO_DESCRIPTION "MS C SEH " PTW32_ARCH "\0" # else # error Resource compiler doesn't know which cleanup style you're using - see version.rc # endif #elif defined(__GNUC__) # if defined(__CLEANUP_C) # define PTW32_VERSIONINFO_NAME "pthreadGC\0" -# define PTW32_VERSIONINFO_COMMENT "GNU C build -- longjmp thread exiting\0" +# define PTW32_VERSIONINFO_DESCRIPTION "GNU C " PTW32_ARCH "\0" # elif defined(__CLEANUP_CXX) # define PTW32_VERSIONINFO_NAME "pthreadGCE\0" -# define PTW32_VERSIONINFO_COMMENT "GNU C++ build -- C++ exception thread exiting\0" +# define PTW32_VERSIONINFO_DESCRIPTION "GNU C++ " PTW32_ARCH "\0" # else # error Resource compiler doesn't know which cleanup style you're using - see version.rc # endif #elif defined(__BORLANDC__) # if defined(__CLEANUP_C) # define PTW32_VERSIONINFO_NAME "pthreadBC\0" -# define PTW32_VERSIONINFO_COMMENT "BORLAND C build -- longjmp thread exiting\0" +# define PTW32_VERSIONINFO_DESCRIPTION "BORLAND C " PTW32_ARCH "\0" # elif defined(__CLEANUP_CXX) # define PTW32_VERSIONINFO_NAME "pthreadBCE\0" -# define PTW32_VERSIONINFO_COMMENT "BORLAND C++ build -- C++ exception thread exiting\0" +# define PTW32_VERSIONINFO_DESCRIPTION "BORLAND C++ " PTW32_ARCH "\0" # else # error Resource compiler doesn't know which cleanup style you're using - see version.rc # endif #elif defined(__WATCOMC__) # if defined(__CLEANUP_C) # define PTW32_VERSIONINFO_NAME "pthreadWC\0" -# define PTW32_VERSIONINFO_COMMENT "WATCOM C build -- longjmp thread exiting\0" +# define PTW32_VERSIONINFO_DESCRIPTION "WATCOM C " PTW32_ARCH "\0" # elif defined(__CLEANUP_CXX) # define PTW32_VERSIONINFO_NAME "pthreadWCE\0" -# define PTW32_VERSIONINFO_COMMENT "WATCOM C++ build -- C++ exception thread exiting\0" +# define PTW32_VERSIONINFO_DESCRIPTION "WATCOM C++ " PTW32_ARCH "\0" # else # error Resource compiler doesn't know which cleanup style you're using - see version.rc # endif @@ -102,16 +107,15 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "FileDescription", "POSIX Threads for Windows32 Library\0" + VALUE "ProductName", "POSIX Threads for Windows LPGL\0" VALUE "ProductVersion", PTW32_VERSION_STRING VALUE "FileVersion", PTW32_VERSION_STRING + VALUE "FileDescription", PTW32_VERSIONINFO_DESCRIPTION VALUE "InternalName", PTW32_VERSIONINFO_NAME VALUE "OriginalFilename", PTW32_VERSIONINFO_NAME - VALUE "CompanyName", "Open Source Software community project\0" - VALUE "LegalCopyright", "Copyright (C) Project contributors 1998-2004\0" - VALUE "Licence", "LGPL\0" - VALUE "Info", "http://sources.redhat.com/pthreads-win32/\0" - VALUE "Comment", PTW32_VERSIONINFO_COMMENT + VALUE "CompanyName", "Open Source Software community LGPL\0" + VALUE "LegalCopyright", "Copyright (C) Project contributors 2011\0" + VALUE "Comments", "http://sourceware.org/pthreads-win32/\0" END END BLOCK "VarFileInfo" diff --git a/pthreads/w32_CancelableWait.c b/pthreads/w32_CancelableWait.c index 97e15aa31..070633e0f 100644 --- a/pthreads/w32_CancelableWait.c +++ b/pthreads/w32_CancelableWait.c @@ -110,21 +110,22 @@ ptw32_cancelable_wait (HANDLE waitHandle, DWORD timeout) if (sp != NULL) { + ptw32_mcs_local_node_t stateLock; /* * Should handle POSIX and implicit POSIX threads.. * Make sure we haven't been async-canceled in the meantime. */ - (void) pthread_mutex_lock (&sp->cancelLock); + ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock); if (sp->state < PThreadStateCanceling) { sp->state = PThreadStateCanceling; sp->cancelState = PTHREAD_CANCEL_DISABLE; - (void) pthread_mutex_unlock (&sp->cancelLock); + ptw32_mcs_lock_release (&stateLock); ptw32_throw (PTW32_EPS_CANCEL); /* Never reached */ } - (void) pthread_mutex_unlock (&sp->cancelLock); + ptw32_mcs_lock_release (&stateLock); } /* Should never get to here. */ -- cgit v1.2.3