aboutsummaryrefslogtreecommitdiff
path: root/pthreads
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2009-06-28 22:07:26 +0000
committermarha <marha@users.sourceforge.net>2009-06-28 22:07:26 +0000
commit3562e78743202e43aec8727005182a2558117eca (patch)
tree8f9113a77d12470c5c851a2a8e4cb02e89df7d43 /pthreads
downloadvcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.gz
vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.bz2
vcxsrv-3562e78743202e43aec8727005182a2558117eca.zip
Checked in the following released items:
xkeyboard-config-1.4.tar.gz ttf-bitstream-vera-1.10.tar.gz font-alias-1.0.1.tar.gz font-sun-misc-1.0.0.tar.gz font-sun-misc-1.0.0.tar.gz font-sony-misc-1.0.0.tar.gz font-schumacher-misc-1.0.0.tar.gz font-mutt-misc-1.0.0.tar.gz font-misc-misc-1.0.0.tar.gz font-misc-meltho-1.0.0.tar.gz font-micro-misc-1.0.0.tar.gz font-jis-misc-1.0.0.tar.gz font-isas-misc-1.0.0.tar.gz font-dec-misc-1.0.0.tar.gz font-daewoo-misc-1.0.0.tar.gz font-cursor-misc-1.0.0.tar.gz font-arabic-misc-1.0.0.tar.gz font-winitzki-cyrillic-1.0.0.tar.gz font-misc-cyrillic-1.0.0.tar.gz font-cronyx-cyrillic-1.0.0.tar.gz font-screen-cyrillic-1.0.1.tar.gz font-xfree86-type1-1.0.1.tar.gz font-adobe-utopia-type1-1.0.1.tar.gz font-ibm-type1-1.0.0.tar.gz font-bitstream-type1-1.0.0.tar.gz font-bitstream-speedo-1.0.0.tar.gz font-bh-ttf-1.0.0.tar.gz font-bh-type1-1.0.0.tar.gz font-bitstream-100dpi-1.0.0.tar.gz font-bh-lucidatypewriter-100dpi-1.0.0.tar.gz font-bh-100dpi-1.0.0.tar.gz font-adobe-utopia-100dpi-1.0.1.tar.gz font-adobe-100dpi-1.0.0.tar.gz font-util-1.0.1.tar.gz font-bitstream-75dpi-1.0.0.tar.gz font-bh-lucidatypewriter-75dpi-1.0.0.tar.gz font-adobe-utopia-75dpi-1.0.1.tar.gz font-bh-75dpi-1.0.0.tar.gz bdftopcf-1.0.1.tar.gz font-adobe-75dpi-1.0.0.tar.gz mkfontscale-1.0.6.tar.gz openssl-0.9.8k.tar.gz bigreqsproto-1.0.2.tar.gz xtrans-1.2.2.tar.gz resourceproto-1.0.2.tar.gz inputproto-1.4.4.tar.gz compositeproto-0.4.tar.gz damageproto-1.1.0.tar.gz zlib-1.2.3.tar.gz xkbcomp-1.0.5.tar.gz freetype-2.3.9.tar.gz pthreads-w32-2-8-0-release.tar.gz pixman-0.12.0.tar.gz kbproto-1.0.3.tar.gz evieext-1.0.2.tar.gz fixesproto-4.0.tar.gz recordproto-1.13.2.tar.gz randrproto-1.2.2.tar.gz scrnsaverproto-1.1.0.tar.gz renderproto-0.9.3.tar.gz xcmiscproto-1.1.2.tar.gz fontsproto-2.0.2.tar.gz xextproto-7.0.3.tar.gz xproto-7.0.14.tar.gz libXdmcp-1.0.2.tar.gz libxkbfile-1.0.5.tar.gz libfontenc-1.0.4.tar.gz libXfont-1.3.4.tar.gz libX11-1.1.5.tar.gz libXau-1.0.4.tar.gz libxcb-1.1.tar.gz xorg-server-1.5.3.tar.gz
Diffstat (limited to 'pthreads')
-rw-r--r--pthreads/ANNOUNCE476
-rw-r--r--pthreads/BUGS133
-rw-r--r--pthreads/Bmakefile266
-rw-r--r--pthreads/CONTRIBUTORS129
-rw-r--r--pthreads/COPYING150
-rw-r--r--pthreads/COPYING.LIB504
-rw-r--r--pthreads/ChangeLog4821
-rw-r--r--pthreads/FAQ403
-rw-r--r--pthreads/GNUmakefile583
-rw-r--r--pthreads/MAINTAINERS4
-rw-r--r--pthreads/Makefile504
-rw-r--r--pthreads/NEWS1110
-rw-r--r--pthreads/Nmakefile24
-rw-r--r--pthreads/Nmakefile.tests260
-rw-r--r--pthreads/PROGRESS4
-rw-r--r--pthreads/README593
-rw-r--r--pthreads/README.Borland57
-rw-r--r--pthreads/README.CV3036
-rw-r--r--pthreads/README.NONPORTABLE285
-rw-r--r--pthreads/README.Watcom62
-rw-r--r--pthreads/README.WinCE6
-rw-r--r--pthreads/TODO7
-rw-r--r--pthreads/WinCE-PORT217
-rw-r--r--pthreads/attr.c53
-rw-r--r--pthreads/barrier.c47
-rw-r--r--pthreads/builddmc.bat9
-rw-r--r--pthreads/cancel.c44
-rw-r--r--pthreads/cleanup.c148
-rw-r--r--pthreads/condvar.c50
-rw-r--r--pthreads/config.h134
-rw-r--r--pthreads/create.c305
-rw-r--r--pthreads/dll.c92
-rw-r--r--pthreads/errno.c94
-rw-r--r--pthreads/exit.c44
-rw-r--r--pthreads/fork.c39
-rw-r--r--pthreads/global.c115
-rw-r--r--pthreads/implement.h710
-rw-r--r--pthreads/manual/ChangeLog62
-rw-r--r--pthreads/manual/PortabilityIssues.html718
-rw-r--r--pthreads/manual/index.html146
-rw-r--r--pthreads/manual/pthreadCancelableWait.html86
-rw-r--r--pthreads/manual/pthread_attr_init.html280
-rw-r--r--pthreads/manual/pthread_attr_setstackaddr.html158
-rw-r--r--pthreads/manual/pthread_attr_setstacksize.html127
-rw-r--r--pthreads/manual/pthread_barrier_init.html200
-rw-r--r--pthreads/manual/pthread_barrier_wait.html167
-rw-r--r--pthreads/manual/pthread_barrierattr_init.html142
-rw-r--r--pthreads/manual/pthread_barrierattr_setpshared.html159
-rw-r--r--pthreads/manual/pthread_cancel.html205
-rw-r--r--pthreads/manual/pthread_cleanup_push.html140
-rw-r--r--pthreads/manual/pthread_cond_init.html313
-rw-r--r--pthreads/manual/pthread_condattr_init.html98
-rw-r--r--pthreads/manual/pthread_condattr_setpshared.html153
-rw-r--r--pthreads/manual/pthread_create.html94
-rw-r--r--pthreads/manual/pthread_delay_np.html71
-rw-r--r--pthreads/manual/pthread_detach.html90
-rw-r--r--pthreads/manual/pthread_equal.html48
-rw-r--r--pthreads/manual/pthread_exit.html59
-rw-r--r--pthreads/manual/pthread_getw32threadhandle_np.html57
-rw-r--r--pthreads/manual/pthread_join.html118
-rw-r--r--pthreads/manual/pthread_key_create.html211
-rw-r--r--pthreads/manual/pthread_kill.html152
-rw-r--r--pthreads/manual/pthread_mutex_init.html277
-rw-r--r--pthreads/manual/pthread_mutexattr_init.html157
-rw-r--r--pthreads/manual/pthread_mutexattr_setpshared.html151
-rw-r--r--pthreads/manual/pthread_num_processors_np.html57
-rw-r--r--pthreads/manual/pthread_once.html83
-rw-r--r--pthreads/manual/pthread_rwlock_init.html193
-rw-r--r--pthreads/manual/pthread_rwlock_rdlock.html168
-rw-r--r--pthreads/manual/pthread_rwlock_timedrdlock.html156
-rw-r--r--pthreads/manual/pthread_rwlock_timedwrlock.html150
-rw-r--r--pthreads/manual/pthread_rwlock_unlock.html141
-rw-r--r--pthreads/manual/pthread_rwlock_wrlock.html153
-rw-r--r--pthreads/manual/pthread_rwlockattr_init.html141
-rw-r--r--pthreads/manual/pthread_rwlockattr_setpshared.html160
-rw-r--r--pthreads/manual/pthread_self.html70
-rw-r--r--pthreads/manual/pthread_setcancelstate.html207
-rw-r--r--pthreads/manual/pthread_setcanceltype.html207
-rw-r--r--pthreads/manual/pthread_setconcurrency.html155
-rw-r--r--pthreads/manual/pthread_setschedparam.html113
-rw-r--r--pthreads/manual/pthread_spin_init.html176
-rw-r--r--pthreads/manual/pthread_spin_lock.html141
-rw-r--r--pthreads/manual/pthread_spin_unlock.html124
-rw-r--r--pthreads/manual/pthread_timechange_handler_np.html76
-rw-r--r--pthreads/manual/pthread_win32_attach_detach_np.html74
-rw-r--r--pthreads/manual/pthread_win32_test_features_np.html68
-rw-r--r--pthreads/manual/sched_get_priority_max.html115
-rw-r--r--pthreads/manual/sched_getscheduler.html127
-rw-r--r--pthreads/manual/sched_setscheduler.html181
-rw-r--r--pthreads/manual/sched_yield.html98
-rw-r--r--pthreads/manual/sem_init.html200
-rw-r--r--pthreads/misc.c50
-rw-r--r--pthreads/mutex.c59
-rw-r--r--pthreads/need_errno.h132
-rw-r--r--pthreads/nonportable.c46
-rw-r--r--pthreads/private.c57
-rw-r--r--pthreads/pthread.c65
-rw-r--r--pthreads/pthread.dsp142
-rw-r--r--pthreads/pthread.dsw29
-rw-r--r--pthreads/pthread.h1368
-rw-r--r--pthreads/pthread_attr_destroy.c79
-rw-r--r--pthreads/pthread_attr_getdetachstate.c87
-rw-r--r--pthreads/pthread_attr_getinheritsched.c51
-rw-r--r--pthreads/pthread_attr_getschedparam.c52
-rw-r--r--pthreads/pthread_attr_getschedpolicy.c61
-rw-r--r--pthreads/pthread_attr_getscope.c54
-rw-r--r--pthreads/pthread_attr_getstackaddr.c97
-rw-r--r--pthreads/pthread_attr_getstacksize.c100
-rw-r--r--pthreads/pthread_attr_init.c117
-rw-r--r--pthreads/pthread_attr_setdetachstate.c91
-rw-r--r--pthreads/pthread_attr_setinheritsched.c57
-rw-r--r--pthreads/pthread_attr_setschedparam.c63
-rw-r--r--pthreads/pthread_attr_setschedpolicy.c55
-rw-r--r--pthreads/pthread_attr_setscope.c62
-rw-r--r--pthreads/pthread_attr_setstackaddr.c97
-rw-r--r--pthreads/pthread_attr_setstacksize.c110
-rw-r--r--pthreads/pthread_barrier_destroy.c67
-rw-r--r--pthreads/pthread_barrier_init.c81
-rw-r--r--pthreads/pthread_barrier_wait.c99
-rw-r--r--pthreads/pthread_barrierattr_destroy.c83
-rw-r--r--pthreads/pthread_barrierattr_getpshared.c95
-rw-r--r--pthreads/pthread_barrierattr_init.c85
-rw-r--r--pthreads/pthread_barrierattr_setpshared.c119
-rw-r--r--pthreads/pthread_cancel.c223
-rw-r--r--pthreads/pthread_cond_destroy.c244
-rw-r--r--pthreads/pthread_cond_init.c165
-rw-r--r--pthreads/pthread_cond_signal.c231
-rw-r--r--pthreads/pthread_cond_wait.c567
-rw-r--r--pthreads/pthread_condattr_destroy.c86
-rw-r--r--pthreads/pthread_condattr_getpshared.c97
-rw-r--r--pthreads/pthread_condattr_init.c87
-rw-r--r--pthreads/pthread_condattr_setpshared.c117
-rw-r--r--pthreads/pthread_delay_np.c171
-rw-r--r--pthreads/pthread_detach.c139
-rw-r--r--pthreads/pthread_equal.c76
-rw-r--r--pthreads/pthread_exit.c106
-rw-r--r--pthreads/pthread_getconcurrency.c45
-rw-r--r--pthreads/pthread_getschedparam.c75
-rw-r--r--pthreads/pthread_getspecific.c84
-rw-r--r--pthreads/pthread_getw32threadhandle_np.c53
-rw-r--r--pthreads/pthread_join.c154
-rw-r--r--pthreads/pthread_key_create.c108
-rw-r--r--pthreads/pthread_key_delete.c133
-rw-r--r--pthreads/pthread_kill.c102
-rw-r--r--pthreads/pthread_mutex_destroy.c146
-rw-r--r--pthreads/pthread_mutex_init.c104
-rw-r--r--pthreads/pthread_mutex_lock.c139
-rw-r--r--pthreads/pthread_mutex_timedlock.c196
-rw-r--r--pthreads/pthread_mutex_trylock.c92
-rw-r--r--pthreads/pthread_mutex_unlock.c119
-rw-r--r--pthreads/pthread_mutexattr_destroy.c83
-rw-r--r--pthreads/pthread_mutexattr_getkind_np.c44
-rw-r--r--pthreads/pthread_mutexattr_getpshared.c95
-rw-r--r--pthreads/pthread_mutexattr_gettype.c56
-rw-r--r--pthreads/pthread_mutexattr_init.c86
-rw-r--r--pthreads/pthread_mutexattr_setkind_np.c44
-rw-r--r--pthreads/pthread_mutexattr_setpshared.c119
-rw-r--r--pthreads/pthread_mutexattr_settype.c143
-rw-r--r--pthreads/pthread_num_processors_np.c56
-rw-r--r--pthreads/pthread_once.c86
-rw-r--r--pthreads/pthread_rwlock_destroy.c143
-rw-r--r--pthreads/pthread_rwlock_init.c110
-rw-r--r--pthreads/pthread_rwlock_rdlock.c103
-rw-r--r--pthreads/pthread_rwlock_timedrdlock.c110
-rw-r--r--pthreads/pthread_rwlock_timedwrlock.c140
-rw-r--r--pthreads/pthread_rwlock_tryrdlock.c103
-rw-r--r--pthreads/pthread_rwlock_trywrlock.c123
-rw-r--r--pthreads/pthread_rwlock_unlock.c94
-rw-r--r--pthreads/pthread_rwlock_wrlock.c134
-rw-r--r--pthreads/pthread_rwlockattr_destroy.c85
-rw-r--r--pthreads/pthread_rwlockattr_getpshared.c98
-rw-r--r--pthreads/pthread_rwlockattr_init.c84
-rw-r--r--pthreads/pthread_rwlockattr_setpshared.c121
-rw-r--r--pthreads/pthread_self.c138
-rw-r--r--pthreads/pthread_setcancelstate.c124
-rw-r--r--pthreads/pthread_setcanceltype.c125
-rw-r--r--pthreads/pthread_setconcurrency.c53
-rw-r--r--pthreads/pthread_setschedparam.c125
-rw-r--r--pthreads/pthread_setspecific.c168
-rw-r--r--pthreads/pthread_spin_destroy.c112
-rw-r--r--pthreads/pthread_spin_init.c123
-rw-r--r--pthreads/pthread_spin_lock.c83
-rw-r--r--pthreads/pthread_spin_trylock.c80
-rw-r--r--pthreads/pthread_spin_unlock.c75
-rw-r--r--pthreads/pthread_testcancel.c102
-rw-r--r--pthreads/pthread_timechange_handler_np.c107
-rw-r--r--pthreads/pthread_win32_attach_detach_np.c303
-rw-r--r--pthreads/ptw32_InterlockedCompareExchange.c303
-rw-r--r--pthreads/ptw32_MCS_lock.c210
-rw-r--r--pthreads/ptw32_callUserDestroyRoutines.c220
-rw-r--r--pthreads/ptw32_calloc.c56
-rw-r--r--pthreads/ptw32_cond_check_need_init.c94
-rw-r--r--pthreads/ptw32_getprocessors.c91
-rw-r--r--pthreads/ptw32_is_attr.c47
-rw-r--r--pthreads/ptw32_mutex_check_need_init.c112
-rw-r--r--pthreads/ptw32_new.c91
-rw-r--r--pthreads/ptw32_processInitialize.c102
-rw-r--r--pthreads/ptw32_processTerminate.c114
-rw-r--r--pthreads/ptw32_relmillisecs.c120
-rw-r--r--pthreads/ptw32_reuse.c147
-rw-r--r--pthreads/ptw32_rwlock_cancelwrwait.c50
-rw-r--r--pthreads/ptw32_rwlock_check_need_init.c93
-rw-r--r--pthreads/ptw32_semwait.c118
-rw-r--r--pthreads/ptw32_spinlock_check_need_init.c81
-rw-r--r--pthreads/ptw32_threadDestroy.c82
-rw-r--r--pthreads/ptw32_threadStart.c360
-rw-r--r--pthreads/ptw32_throw.c167
-rw-r--r--pthreads/ptw32_timespec.c83
-rw-r--r--pthreads/ptw32_tkAssocCreate.c118
-rw-r--r--pthreads/ptw32_tkAssocDestroy.c114
-rw-r--r--pthreads/rwlock.c51
-rw-r--r--pthreads/sched.c53
-rw-r--r--pthreads/sched.h178
-rw-r--r--pthreads/sched_get_priority_max.c134
-rw-r--r--pthreads/sched_get_priority_min.c135
-rw-r--r--pthreads/sched_getscheduler.c69
-rw-r--r--pthreads/sched_setscheduler.c81
-rw-r--r--pthreads/sched_yield.c71
-rw-r--r--pthreads/sem_close.c58
-rw-r--r--pthreads/sem_destroy.c144
-rw-r--r--pthreads/sem_getvalue.c110
-rw-r--r--pthreads/sem_init.c169
-rw-r--r--pthreads/sem_open.c58
-rw-r--r--pthreads/sem_post.c128
-rw-r--r--pthreads/sem_post_multiple.c142
-rw-r--r--pthreads/sem_timedwait.c238
-rw-r--r--pthreads/sem_trywait.c117
-rw-r--r--pthreads/sem_unlink.c58
-rw-r--r--pthreads/sem_wait.c187
-rw-r--r--pthreads/semaphore.c69
-rw-r--r--pthreads/semaphore.h166
-rw-r--r--pthreads/signal.c179
-rw-r--r--pthreads/spin.c46
-rw-r--r--pthreads/sync.c43
-rw-r--r--pthreads/tests/Bmakefile350
-rw-r--r--pthreads/tests/ChangeLog894
-rw-r--r--pthreads/tests/Debug.dsp93
-rw-r--r--pthreads/tests/Debug.dsw29
-rw-r--r--pthreads/tests/Debug.txt6
-rw-r--r--pthreads/tests/GNUmakefile375
-rw-r--r--pthreads/tests/Makefile404
-rw-r--r--pthreads/tests/README44
-rw-r--r--pthreads/tests/README.BENCHTESTS74
-rw-r--r--pthreads/tests/SIZES.GC20
-rw-r--r--pthreads/tests/SIZES.GCE20
-rw-r--r--pthreads/tests/SIZES.VC20
-rw-r--r--pthreads/tests/SIZES.VCE19
-rw-r--r--pthreads/tests/SIZES.VSE19
-rw-r--r--pthreads/tests/Wmakefile346
-rw-r--r--pthreads/tests/barrier1.c58
-rw-r--r--pthreads/tests/barrier2.c55
-rw-r--r--pthreads/tests/barrier3.c71
-rw-r--r--pthreads/tests/barrier4.c110
-rw-r--r--pthreads/tests/barrier5.c128
-rw-r--r--pthreads/tests/benchlib.c363
-rw-r--r--pthreads/tests/benchtest.h70
-rw-r--r--pthreads/tests/benchtest1.c249
-rw-r--r--pthreads/tests/benchtest2.c311
-rw-r--r--pthreads/tests/benchtest3.c201
-rw-r--r--pthreads/tests/benchtest4.c182
-rw-r--r--pthreads/tests/benchtest5.c159
-rw-r--r--pthreads/tests/cancel1.c179
-rw-r--r--pthreads/tests/cancel2.c251
-rw-r--r--pthreads/tests/cancel3.c201
-rw-r--r--pthreads/tests/cancel4.c203
-rw-r--r--pthreads/tests/cancel5.c199
-rw-r--r--pthreads/tests/cancel6a.c191
-rw-r--r--pthreads/tests/cancel6d.c190
-rw-r--r--pthreads/tests/cancel7.c216
-rw-r--r--pthreads/tests/cancel8.c217
-rw-r--r--pthreads/tests/cancel9.c202
-rw-r--r--pthreads/tests/cleanup0.c229
-rw-r--r--pthreads/tests/cleanup1.c242
-rw-r--r--pthreads/tests/cleanup2.c217
-rw-r--r--pthreads/tests/cleanup3.c222
-rw-r--r--pthreads/tests/condvar1.c97
-rw-r--r--pthreads/tests/condvar1_1.c115
-rw-r--r--pthreads/tests/condvar1_2.c124
-rw-r--r--pthreads/tests/condvar2.c125
-rw-r--r--pthreads/tests/condvar2_1.c153
-rw-r--r--pthreads/tests/condvar3.c148
-rw-r--r--pthreads/tests/condvar3_1.c201
-rw-r--r--pthreads/tests/condvar3_2.c193
-rw-r--r--pthreads/tests/condvar3_3.c132
-rw-r--r--pthreads/tests/condvar4.c169
-rw-r--r--pthreads/tests/condvar5.c168
-rw-r--r--pthreads/tests/condvar6.c242
-rw-r--r--pthreads/tests/condvar7.c257
-rw-r--r--pthreads/tests/condvar8.c258
-rw-r--r--pthreads/tests/condvar9.c267
-rw-r--r--pthreads/tests/context1.c144
-rw-r--r--pthreads/tests/count1.c90
-rw-r--r--pthreads/tests/create1.c66
-rw-r--r--pthreads/tests/create2.c108
-rw-r--r--pthreads/tests/create3.c122
-rw-r--r--pthreads/tests/delay1.c51
-rw-r--r--pthreads/tests/delay2.c82
-rw-r--r--pthreads/tests/detach1.c93
-rw-r--r--pthreads/tests/equal1.c66
-rw-r--r--pthreads/tests/errno1.c177
-rw-r--r--pthreads/tests/exception1.c263
-rw-r--r--pthreads/tests/exception2.c158
-rw-r--r--pthreads/tests/exception3.c196
-rw-r--r--pthreads/tests/exit1.c50
-rw-r--r--pthreads/tests/exit2.c64
-rw-r--r--pthreads/tests/exit3.c68
-rw-r--r--pthreads/tests/exit4.c199
-rw-r--r--pthreads/tests/exit5.c205
-rw-r--r--pthreads/tests/eyal1.c367
-rw-r--r--pthreads/tests/inherit1.c177
-rw-r--r--pthreads/tests/join0.c67
-rw-r--r--pthreads/tests/join1.c78
-rw-r--r--pthreads/tests/join2.c69
-rw-r--r--pthreads/tests/join3.c75
-rw-r--r--pthreads/tests/kill1.c83
-rw-r--r--pthreads/tests/loadfree.c70
-rw-r--r--pthreads/tests/mutex1.c68
-rw-r--r--pthreads/tests/mutex1e.c74
-rw-r--r--pthreads/tests/mutex1n.c74
-rw-r--r--pthreads/tests/mutex1r.c74
-rw-r--r--pthreads/tests/mutex2.c66
-rw-r--r--pthreads/tests/mutex2e.c66
-rw-r--r--pthreads/tests/mutex2r.c66
-rw-r--r--pthreads/tests/mutex3.c75
-rw-r--r--pthreads/tests/mutex3e.c75
-rw-r--r--pthreads/tests/mutex3r.c75
-rw-r--r--pthreads/tests/mutex4.c111
-rw-r--r--pthreads/tests/mutex5.c67
-rw-r--r--pthreads/tests/mutex6.c93
-rw-r--r--pthreads/tests/mutex6e.c102
-rw-r--r--pthreads/tests/mutex6es.c94
-rw-r--r--pthreads/tests/mutex6n.c104
-rw-r--r--pthreads/tests/mutex6r.c100
-rw-r--r--pthreads/tests/mutex6rs.c92
-rw-r--r--pthreads/tests/mutex6s.c93
-rw-r--r--pthreads/tests/mutex7.c82
-rw-r--r--pthreads/tests/mutex7e.c102
-rw-r--r--pthreads/tests/mutex7n.c93
-rw-r--r--pthreads/tests/mutex7r.c100
-rw-r--r--pthreads/tests/mutex8.c82
-rw-r--r--pthreads/tests/mutex8e.c97
-rw-r--r--pthreads/tests/mutex8n.c97
-rw-r--r--pthreads/tests/mutex8r.c97
-rw-r--r--pthreads/tests/once1.c77
-rw-r--r--pthreads/tests/once2.c109
-rw-r--r--pthreads/tests/once3.c132
-rw-r--r--pthreads/tests/once4.c191
-rw-r--r--pthreads/tests/priority1.c172
-rw-r--r--pthreads/tests/priority2.c169
-rw-r--r--pthreads/tests/reuse1.c124
-rw-r--r--pthreads/tests/reuse2.c167
-rw-r--r--pthreads/tests/rwlock1.c61
-rw-r--r--pthreads/tests/rwlock2.c66
-rw-r--r--pthreads/tests/rwlock2_t.c78
-rw-r--r--pthreads/tests/rwlock3.c76
-rw-r--r--pthreads/tests/rwlock3_t.c87
-rw-r--r--pthreads/tests/rwlock4.c76
-rw-r--r--pthreads/tests/rwlock4_t.c87
-rw-r--r--pthreads/tests/rwlock5.c78
-rw-r--r--pthreads/tests/rwlock5_t.c89
-rw-r--r--pthreads/tests/rwlock6.c101
-rw-r--r--pthreads/tests/rwlock6_t.c126
-rw-r--r--pthreads/tests/rwlock6_t2.c119
-rw-r--r--pthreads/tests/rwlock7.c199
-rw-r--r--pthreads/tests/rwlock8.c205
-rw-r--r--pthreads/tests/self1.c69
-rw-r--r--pthreads/tests/self2.c73
-rw-r--r--pthreads/tests/semaphore1.c161
-rw-r--r--pthreads/tests/semaphore2.c108
-rw-r--r--pthreads/tests/semaphore3.c121
-rw-r--r--pthreads/tests/semaphore4.c138
-rw-r--r--pthreads/tests/semaphore4t.c132
-rw-r--r--pthreads/tests/sizes.c32
-rw-r--r--pthreads/tests/spin1.c59
-rw-r--r--pthreads/tests/spin2.c75
-rw-r--r--pthreads/tests/spin3.c72
-rw-r--r--pthreads/tests/spin4.c103
-rw-r--r--pthreads/tests/stress1.c278
-rw-r--r--pthreads/tests/test.h140
-rw-r--r--pthreads/tests/tryentercs.c103
-rw-r--r--pthreads/tests/tryentercs2.c92
-rw-r--r--pthreads/tests/tsd1.c211
-rw-r--r--pthreads/tests/tsd2.c215
-rw-r--r--pthreads/tests/valid1.c103
-rw-r--r--pthreads/tests/valid2.c84
-rw-r--r--pthreads/tsd.c44
-rw-r--r--pthreads/version.rc384
-rw-r--r--pthreads/w32_CancelableWait.c160
388 files changed, 62326 insertions, 0 deletions
diff --git a/pthreads/ANNOUNCE b/pthreads/ANNOUNCE
new file mode 100644
index 000000000..97d94e702
--- /dev/null
+++ b/pthreads/ANNOUNCE
@@ -0,0 +1,476 @@
+ PTHREADS-WIN32 RELEASE 2.8.0 (2006-12-22)
+ -----------------------------------------
+ Web Site: http://sources.redhat.com/pthreads-win32/
+ FTP Site: ftp://sources.redhat.com/pub/pthreads-win32
+ Maintainer: Ross Johnson <rpj@callisto.canberra.edu.au>
+
+
+We are pleased to announce the availability of a new release of
+Pthreads-win32, an Open Source Software implementation of the
+Threads component of the POSIX 1003.1 2001 Standard for Microsoft's
+Win32 environment. Some functions from other sections of POSIX
+1003.1 2001 are also supported including semaphores and scheduling
+functions.
+
+Some common non-portable functions are also implemented for
+additional compatibility, as are a few functions specific
+to pthreads-win32 for easier integration with Win32 applications.
+
+Pthreads-win32 is free software, distributed under the GNU Lesser
+General Public License (LGPL).
+
+
+Acknowledgements
+----------------
+This library is based originally on a Win32 pthreads
+implementation contributed by John Bossom <John.Bossom@cognos.com>.
+
+The implementation of Condition Variables uses algorithms developed
+by Alexander Terekhov and Louis Thomas.
+
+The implementation of POSIX mutexes has been improved by Thomas Pfaff
+and later by Alexander Terekhov.
+
+The implementation of Spinlocks and Barriers was contributed
+by Ross Johnson.
+
+The implementation of read/write locks was contributed by
+Aurelio Medina and improved by Alexander Terekhov.
+
+Many others have contributed significant time and effort to solve crutial
+problems in order to make the library workable, robust and reliable.
+
+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
diff --git a/pthreads/BUGS b/pthreads/BUGS
new file mode 100644
index 000000000..29cee0033
--- /dev/null
+++ b/pthreads/BUGS
@@ -0,0 +1,133 @@
+----------
+Known bugs
+----------
+
+1. Not strictly a bug, more of a gotcha.
+
+ Under MS VC++ (only tested with version 6.0), a term_func
+ set via the standard C++ set_terminate() function causes the
+ application to abort.
+
+ Notes from the MSVC++ manual:
+ 1) A term_func() should call exit(), otherwise
+ abort() will be called on return to the caller.
+ A call to abort() raises SIGABRT and the default signal handler
+ for all signals terminates the calling program with
+ exit code 3.
+ 2) A term_func() must not throw an exception. Therefore
+ term_func() should not call pthread_exit(), which
+ works by throwing an exception (pthreadVCE or pthreadVSE)
+ or by calling longjmp (pthreadVC).
+
+ Workaround: avoid using pthread_exit() in C++ applications. Exit
+ threads by dropping through the end of the thread routine.
+
+2. Cancellation problems in optimised code
+ - Milan Gardian
+
+ This is suspected to be a compiler bug in VC6.0, and also seen in
+ VC7.0 and VS .NET 2003. The GNU C++ compiler does not have a problem
+ with this, and it has been reported that the Intel C++ 8.1 compiler
+ and Visual C++ 2005 Express Edition Beta2 pass tests\semaphore4.c
+ (which exposes the bug).
+
+ Workaround [rpj - 2 Feb 2002]
+ -----------------------------
+ [Please note: this workaround did not solve a similar problem in
+ snapshot-2004-11-03 or later, even though similar symptoms were seen.
+ tests\semaphore4.c fails in that snapshot for the VCE version of the
+ DLL.]
+
+ The problem disappears when /Ob0 is used, i.e. /O2 /Ob0 works OK,
+ but if you want to use inlining optimisation you can be much more
+ specific about where it's switched off and on by using a pragma.
+
+ So the inlining optimisation is interfering with the way that cleanup
+ handlers are run. It appears to relate to auto-inlining of class methods
+ since this is the only auto inlining that is performed at /O1 optimisation
+ (functions with the "inline" qualifier are also inlined, but the problem
+ doesn't appear to involve any such functions in the library or testsuite).
+
+ In order to confirm the inlining culprit, the following use of pragmas
+ eliminate the problem but I don't know how to make it transparent, putting
+ it in, say, pthread.h where pthread_cleanup_push defined as a macro.
+
+ #pragma inline_depth(0)
+ pthread_cleanup_push(handlerFunc, (void *) &arg);
+
+ /* ... */
+
+ pthread_cleanup_pop(0);
+ #pragma inline_depth()
+
+ Note the empty () pragma value after the pop macro. This resets depth to the
+ default. Or you can specify a non-zero depth here.
+
+ The pragma is also needed (and now used) within the library itself wherever
+ cleanup handlers are used (condvar.c and rwlock.c).
+
+ Use of these pragmas allows compiler optimisations /O1 and /O2 to be
+ used for either or both the library and applications.
+
+ Experimenting further, I found that wrapping the actual cleanup handler
+ function with #pragma auto_inline(off|on) does NOT work.
+
+ MSVC6.0 doesn't appear to support the C99 standard's _Pragma directive,
+ however, later versions may. This form is embeddable inside #define
+ macros, which would be ideal because it would mean that it could be added
+ to the push/pop macro definitions in pthread.h and hidden from the
+ application programmer.
+
+ [/rpj]
+
+ Original problem description
+ ----------------------------
+
+ The cancellation (actually, cleanup-after-cancel) tests fail when using VC
+ (professional) optimisation switches (/O1 or /O2) in pthreads library. I
+ have not investigated which concrete optimisation technique causes this
+ problem (/Og, /Oi, /Ot, /Oy, /Ob1, /Gs, /Gf, /Gy, etc.), but here is a
+ summary of builds and corresponding failures:
+
+ * pthreads VSE (optimised tests): OK
+ * pthreads VCE (optimised tests): Failed "cleanup1" test (runtime)
+
+ * pthreads VSE (DLL in CRT, optimised tests): OK
+ * pthreads VCE (DLL in CRT, optimised tests): Failed "cleanup1" test
+ (runtime)
+
+ Please note that while in VSE version of the pthreads library the
+ optimisation does not really have any impact on the tests (they pass OK), in
+ VCE version addition of optimisation (/O2 in this case) causes the tests to
+ fail uniformly - either in "cleanup0" or "cleanup1" test cases.
+
+ Please note that all the tests above use default pthreads DLL (no
+ optimisations, linked with either static or DLL CRT, based on test type).
+ Therefore the problem lies not within the pthreads DLL but within the
+ compiled client code (the application using pthreads -> involvement of
+ "pthread.h").
+
+ I think the message of this section is that usage of VCE version of pthreads
+ in applications relying on cancellation/cleanup AND using optimisations for
+ creation of production code is highly unreliable for the current version of
+ the pthreads library.
+
+3. The Borland Builder 5.5 version of the library produces memory read exceptions
+in some tests.
+
+4. pthread_barrier_wait() can deadlock if the number of potential calling
+threads for a particular barrier is greater than the barrier count parameter
+given to pthread_barrier_init() for that barrier.
+
+This is due to the very lightweight implementation of pthread-win32 barriers.
+To cope with more than "count" possible waiters, barriers must effectively
+implement all the same safeguards as condition variables, making them much
+"heavier" than at present.
+
+The workaround is to ensure that no more than "count" threads attempt to wait
+at the barrier.
+
+5. Canceling a thread blocked on pthread_once appears not to work in the MSVC++
+version of the library "pthreadVCE.dll". The test case "once3.c" hangs. I have no
+clues on this at present. All other versions pass this test ok - pthreadsVC.dll,
+pthreadsVSE.dll, pthreadsGC.dll and pthreadsGCE.dll.
diff --git a/pthreads/Bmakefile b/pthreads/Bmakefile
new file mode 100644
index 000000000..66707bf4c
--- /dev/null
+++ b/pthreads/Bmakefile
@@ -0,0 +1,266 @@
+# This makefile is compatible with BCB make. Use "make -fBMakefile" to compile.
+#
+# The variables $DLLDEST and $LIBDEST hold the destination directories for the
+# dll and the lib, respectively. Probably all that needs to change is $DEVROOT.
+#
+# Currently only the recommended pthreadBC.dll is built by this makefile.
+#
+
+
+DLL_VER = 2
+
+DEVROOT = .
+
+DLLDEST = $(DEVROOT)\DLL
+LIBDEST = $(DEVROOT)\DLL
+
+DLLS = pthreadBC$(DLL_VER).dll
+
+OPTIM = /O2
+
+RC = brcc32
+RCFLAGS = -i.
+
+CFLAGS = /q /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H=1 /4 /tWD /tWM \
+ /w-aus /w-asc /w-par
+
+#C cleanup code
+BCFLAGS = $(PTW32_FLAGS) $(CFLAGS)
+
+# Agregate modules for inlinability
+DLL_OBJS = \
+ attr.obj \
+ barrier.obj \
+ cancel.obj \
+ cleanup.obj \
+ condvar.obj \
+ create.obj \
+ dll.obj \
+ errno.obj \
+ exit.obj \
+ fork.obj \
+ global.obj \
+ misc.obj \
+ mutex.obj \
+ nonportable.obj \
+ private.obj \
+ rwlock.obj \
+ sched.obj \
+ semaphore.obj \
+ signal.obj \
+ spin.obj \
+ sync.obj \
+ tsd.obj
+
+INCL = config.h implement.h semaphore.h pthread.h need_errno.h
+
+ATTR_SRCS = \
+ pthread_attr_init.c \
+ pthread_attr_destroy.c \
+ pthread_attr_getdetachstate.c \
+ pthread_attr_setdetachstate.c \
+ pthread_attr_getstackaddr.c \
+ pthread_attr_setstackaddr.c \
+ pthread_attr_getstacksize.c \
+ pthread_attr_setstacksize.c \
+ pthread_attr_getscope.c \
+ pthread_attr_setscope.c
+
+BARRIER_SRCS = \
+ pthread_barrier_init.c \
+ pthread_barrier_destroy.c \
+ pthread_barrier_wait.c \
+ pthread_barrierattr_init.c \
+ pthread_barrierattr_destroy.c \
+ pthread_barrierattr_setpshared.c \
+ pthread_barrierattr_getpshared.c
+
+CANCEL_SRCS = \
+ pthread_setcancelstate.c \
+ pthread_setcanceltype.c \
+ pthread_testcancel.c \
+ pthread_cancel.c
+
+CONDVAR_SRCS = \
+ ptw32_cond_check_need_init.c \
+ pthread_condattr_destroy.c \
+ pthread_condattr_getpshared.c \
+ pthread_condattr_init.c \
+ pthread_condattr_setpshared.c \
+ pthread_cond_destroy.c \
+ pthread_cond_init.c \
+ pthread_cond_signal.c \
+ pthread_cond_wait.c
+
+EXIT_SRCS = \
+ pthread_exit.c
+
+MISC_SRCS = \
+ pthread_equal.c \
+ pthread_getconcurrency.c \
+ pthread_once.c \
+ pthread_self.c \
+ pthread_setconcurrency.c \
+ ptw32_calloc.c \
+ ptw32_MCS_lock.c \
+ ptw32_new.c \
+ w32_CancelableWait.c
+
+MUTEX_SRCS = \
+ ptw32_mutex_check_need_init.c \
+ pthread_mutex_init.c \
+ pthread_mutex_destroy.c \
+ pthread_mutexattr_init.c \
+ pthread_mutexattr_destroy.c \
+ pthread_mutexattr_getpshared.c \
+ pthread_mutexattr_setpshared.c \
+ pthread_mutexattr_settype.c \
+ pthread_mutexattr_gettype.c \
+ pthread_mutex_lock.c \
+ pthread_mutex_timedlock.c \
+ pthread_mutex_unlock.c \
+ pthread_mutex_trylock.c
+
+NONPORTABLE_SRCS = \
+ pthread_mutexattr_setkind_np.c \
+ pthread_mutexattr_getkind_np.c \
+ pthread_getw32threadhandle_np.c \
+ pthread_delay_np.c \
+ pthread_num_processors_np.c \
+ pthread_win32_attach_detach_np.c \
+ pthread_timechange_handler_np.c
+
+PRIVATE_SRCS = \
+ ptw32_is_attr.c \
+ ptw32_processInitialize.c \
+ ptw32_processTerminate.c \
+ ptw32_threadStart.c \
+ ptw32_threadDestroy.c \
+ ptw32_tkAssocCreate.c \
+ ptw32_tkAssocDestroy.c \
+ ptw32_callUserDestroyRoutines.c \
+ ptw32_timespec.c \
+ ptw32_relmillisecs.c \
+ ptw32_throw.c \
+ ptw32_InterlockedCompareExchange.c \
+ ptw32_getprocessors.c
+
+RWLOCK_SRCS = \
+ ptw32_rwlock_check_need_init.c \
+ ptw32_rwlock_cancelwrwait.c \
+ pthread_rwlock_init.c \
+ pthread_rwlock_destroy.c \
+ pthread_rwlockattr_init.c \
+ pthread_rwlockattr_destroy.c \
+ pthread_rwlockattr_getpshared.c \
+ pthread_rwlockattr_setpshared.c \
+ pthread_rwlock_rdlock.c \
+ pthread_rwlock_timedrdlock.c \
+ pthread_rwlock_wrlock.c \
+ pthread_rwlock_timedwrlock.c \
+ pthread_rwlock_unlock.c \
+ pthread_rwlock_tryrdlock.c \
+ pthread_rwlock_trywrlock.c
+
+SCHED_SRCS = \
+ pthread_attr_setschedpolicy.c \
+ pthread_attr_getschedpolicy.c \
+ pthread_attr_setschedparam.c \
+ pthread_attr_getschedparam.c \
+ pthread_attr_setinheritsched.c \
+ pthread_attr_getinheritsched.c \
+ pthread_setschedparam.c \
+ pthread_getschedparam.c \
+ sched_get_priority_max.c \
+ sched_get_priority_min.c \
+ sched_setscheduler.c \
+ sched_getscheduler.c \
+ sched_yield.c
+
+SEMAPHORE_SRCS = \
+ sem_init.c \
+ sem_destroy.c \
+ sem_trywait.c \
+ sem_timedwait.c \
+ sem_wait.c \
+ sem_post.c \
+ sem_post_multiple.c \
+ sem_getvalue.c \
+ sem_open.c \
+ sem_close.c \
+ sem_unlink.c
+
+SPIN_SRCS = \
+ ptw32_spinlock_check_need_init.c \
+ pthread_spin_init.c \
+ pthread_spin_destroy.c \
+ pthread_spin_lock.c \
+ pthread_spin_unlock.c \
+ pthread_spin_trylock.c
+
+SYNC_SRCS = \
+ pthread_detach.c \
+ pthread_join.c
+
+TSD_SRCS = \
+ pthread_key_create.c \
+ pthread_key_delete.c \
+ pthread_setspecific.c \
+ pthread_getspecific.c
+
+
+all: clean $(DLLS)
+
+realclean: clean
+ if exist 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 *.ilc del *.ilc
+ if exist *.ild del *.ild
+ if exist *.ilf del *.ilf
+ if exist *.ils del *.ils
+ if exist *.tds del *.tds
+ if exist *.pdb del *.pdb
+ if exist *.exp del *.exp
+ if exist *.map del *.map
+ if exist *.o del *.o
+ if exist *.i del *.i
+ if exist *.res del *.res
+
+
+install: $(DLLS)
+ copy pthread*.dll $(DLLDEST)
+ copy pthread*.lib $(LIBDEST)
+
+$(DLLS): $(DLL_OBJS) version.res
+ ilink32 /Tpd /Gi c0d32x.obj $(DLL_OBJS), \
+ $@, ,\
+ cw32mti.lib import32.lib, ,\
+ version.res
+
+.c.obj:
+ $(CC) $(OPTIM) $(BCFLAGS) -c $<
+
+.rc.res:
+ $(RC) $(RCFLAGS) $<
+
+attr.obj: attr.c $(ATTR_SRCS) $(INCL)
+barrier.obj: barrier.c $(BARRIER_SRCS) $(INCL)
+cancel.obj: cancel.c $(CANCEL_SRCS) $(INCL)
+condvar.obj: condvar.c $(CONDVAR_SRCS) $(INCL)
+exit.obj: exit.c $(EXIT_SRCS) $(INCL)
+misc.obj: misc.c $(MISC_SRCS) $(INCL)
+mutex.obj: mutex.c $(MUTEX_SRCS) $(INCL)
+nonportable.obj: nonportable.c $(NONPORTABLE_SRCS) $(INCL)
+private.obj: private.c $(PRIVATE_SRCS) $(INCL)
+rwlock.obj: rwlock.c $(RWLOCK_SRCS) $(INCL)
+sched.obj: sched.c $(SCHED_SRCS) $(INCL)
+semaphore.obj: semaphore.c $(SEMAPHORE_SRCS) $(INCL)
+spin.obj: spin.c $(SPIN_SRCS) $(INCL)
+sync.obj: sync.c $(SYNC_SRCS) $(INCL)
+tsd.obj: tsd.c $(TSD_SRCS) $(INCL)
+version.res: version.rc $(INCL)
diff --git a/pthreads/CONTRIBUTORS b/pthreads/CONTRIBUTORS
new file mode 100644
index 000000000..e5b7325d1
--- /dev/null
+++ b/pthreads/CONTRIBUTORS
@@ -0,0 +1,129 @@
+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
+ 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.
diff --git a/pthreads/COPYING b/pthreads/COPYING
new file mode 100644
index 000000000..5cfea0d0e
--- /dev/null
+++ b/pthreads/COPYING
@@ -0,0 +1,150 @@
+ pthreads-win32 - a POSIX threads library for Microsoft Windows
+
+
+This file is Copyrighted
+------------------------
+
+ This file is covered under the following Copyright:
+
+ Copyright (C) 2001,2006 Ross P. Johnson
+ All rights reserved.
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+Pthreads-win32 is covered by the GNU Lesser General Public License
+------------------------------------------------------------------
+
+ Pthreads-win32 is open 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 version 2.1 of the
+ License.
+
+ Pthreads-win32 is several binary link libraries, several modules,
+ associated interface definition files and scripts used to control
+ its compilation and installation.
+
+ Pthreads-win32 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.
+
+ A copy of the GNU Lesser General Public License is distributed with
+ pthreads-win32 under the filename:
+
+ COPYING.LIB
+
+ You should have received a copy of the version 2.1 GNU Lesser General
+ Public License with pthreads-win32; if not, write to:
+
+ Free Software Foundation, Inc.
+ 59 Temple Place
+ Suite 330
+ Boston, MA 02111-1307
+ USA
+
+ The contact addresses for pthreads-win32 is as follows:
+
+ Web: http://sources.redhat.com/pthreads-win32
+ Email: Ross Johnson
+ Please use: Firstname.Lastname@homemail.com.au
+
+
+
+Pthreads-win32 copyrights and exception files
+---------------------------------------------
+
+ With the exception of the files listed below, Pthreads-win32
+ is covered under the following GNU Lesser General Public License
+ Copyrights:
+
+ Pthreads-win32 - POSIX Threads Library for Win32
+ Copyright(C) 1998 John E. Bossom
+ Copyright(C) 1999,2006 Pthreads-win32 contributors
+
+ The current list of contributors is contained
+ in the file CONTRIBUTORS included with the source
+ code distribution. The current list of CONTRIBUTORS
+ can also be seen at the following WWW location:
+ http://sources.redhat.com/pthreads-win32/contributors.html
+
+ Contact Email: Ross Johnson
+ Please use: Firstname.Lastname@homemail.com.au
+
+ These files are not covered under one of the Copyrights listed above:
+
+ COPYING
+ COPYING.LIB
+ tests/rwlock7.c
+
+ This file, COPYING, is distributed under the Copyright found at the
+ top of this file. It is important to note that you may distribute
+ verbatim copies of this file but you may not modify this file.
+
+ The file COPYING.LIB, which contains a copy of the version 2.1
+ GNU Lesser General Public License, is itself copyrighted by the
+ Free Software Foundation, Inc. Please note that the Free Software
+ Foundation, Inc. does NOT have a copyright over Pthreads-win32,
+ only the COPYING.LIB that is supplied with pthreads-win32.
+
+ The file tests/rwlock7.c is derived from code written by
+ Dave Butenhof for his book 'Programming With POSIX(R) Threads'.
+ The original code was obtained by free download from his website
+ http://home.earthlink.net/~anneart/family/Threads/source.html
+ and did not contain a copyright or author notice. It is assumed to
+ be freely distributable.
+
+ In all cases one may use and distribute these exception files freely.
+ And because one may freely distribute the LGPL covered files, the
+ entire pthreads-win32 source may be freely used and distributed.
+
+
+
+General Copyleft and License info
+---------------------------------
+
+ For general information on Copylefts, see:
+
+ http://www.gnu.org/copyleft/
+
+ For information on GNU Lesser General Public Licenses, see:
+
+ http://www.gnu.org/copyleft/lesser.html
+ http://www.gnu.org/copyleft/lesser.txt
+
+
+Why pthreads-win32 did not use the GNU General Public License
+-------------------------------------------------------------
+
+ The goal of the pthreads-win32 project has been to
+ provide a quality and complete implementation of the POSIX
+ threads API for Microsoft Windows within the limits imposed
+ by virtue of it being a stand-alone library and not
+ linked directly to other POSIX compliant libraries. For
+ example, some functions and features, such as those based
+ on POSIX signals, are missing.
+
+ Pthreads-win32 is a library, available in several different
+ versions depending on supported compilers, and may be used
+ as a dynamically linked module or a statically linked set of
+ binary modules. It is not an application on it's own.
+
+ It was fully intended that pthreads-win32 be usable with
+ commercial software not covered by either the GPL or the LGPL
+ licenses. Pthreads-win32 has many contributors to it's
+ code base, many of whom have done so because they have
+ used the library in commercial or proprietry software
+ projects.
+
+ Releasing pthreads-win32 under the LGPL ensures that the
+ library can be used widely, while at the same time ensures
+ that bug fixes and improvements to the pthreads-win32 code
+ itself is returned to benefit all current and future users
+ of the library.
+
+ Although pthreads-win32 makes it possible for applications
+ that use POSIX threads to be ported to Win32 platforms, the
+ broader goal of the project is to encourage the use of open
+ standards, and in particular, to make it just a little easier
+ for developers writing Win32 applications to consider
+ widening the potential market for their products.
diff --git a/pthreads/COPYING.LIB b/pthreads/COPYING.LIB
new file mode 100644
index 000000000..b1e3f5a26
--- /dev/null
+++ b/pthreads/COPYING.LIB
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/pthreads/ChangeLog b/pthreads/ChangeLog
new file mode 100644
index 000000000..b85d9f9b8
--- /dev/null
+++ b/pthreads/ChangeLog
@@ -0,0 +1,4821 @@
+2006-12-20 Ross Johnson <ross.johnson@homemail.com.au>
+
+ * 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 <prashant.thakre at gmail.com>
+
+ * pthread_cancel.c: Added _M_IA64 register context support.
+
+2005-05-13 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * 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 <vladimir at kliatchko.com>
+
+ * 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 <alexander.gottwald at s1999.tu-chemnitz.de>
+
+ * pthread.h: Some things, like HANDLE, were only defined if
+ PTW32_LEVEL was >= 3. They should always be defined.
+
+2005-05-25 Vladimir Kliatchko <vladimir at kliatchko.com>
+
+ * 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 <mikaelmagnusson at glocalnet.net>
+
+ * 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 <ross at callisto.canberra.edu.au>
+
+ * 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 <ross at callisto.canberra.edu.au>
+
+ * 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 <ross at callisto.canberra.edu.au>
+
+ * 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 <ross at callisto.canberra.edu.au>
+
+ * 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 <ross at callisto.canberra.edu.au>
+
+ * 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 <ross at callisto.canberra.edu.au>
+
+ * 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 <ross at callisto.canberra.edu.au>
+
+ * 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 <ross at callisto.canberra.edu.au>
+
+ * 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 <Kevin at codegreennetworks.com>
+
+ * Makefile: Added debug targets for all versions of the library.
+
+2005-04-01 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * GNUmakefile: Add target to build libpthreadGC1.a as a static link
+ library.
+ * Makefile: Likewise for pthreadGC1.lib.
+
+2005-04-01 Kevin Lussier <Kevin at codegreennetworks.com>
+
+ * 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 <develop at mail.bg>^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 <ross at callisto.canberra.edu.au>^M
+
+ * pthread_setcancelstate.c: Undo the last change.
+
+2005-03-16 Ross Johnson <ross at callisto.canberra.edu.au>^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 <ross at callisto.canberra.edu.au>
+
+ * pthread_once.c (pthread_once): Downgrade interlocked operations to simple
+ memory operations where these are protected by the critical section; edit
+ comments.
+
+2005-03-13 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_once.c (pthread_once): Completely redesigned; a change was
+ required to the ABI (pthread_once_t_), and resulting in a version
+ compatibility index increment.
+
+ NOTES:
+ The design (based on pseudo code contributed by Gottlob Frege) avoids
+ creating a kernel object if there is no contention. See URL for details:-
+ http://sources.redhat.com/ml/pthreads-win32/2005/msg00029.html
+ This uses late initialisation similar to the technique already used for
+ pthreads-win32 mutexes and semaphores (from Alexander Terekhov).
+
+ The subsequent cancelation cleanup additions (by rpj) could not be implemented
+ without sacrificing some of the efficiency in Gottlob's design. In particular,
+ although each once_control uses it's own event to block on, a global CS is
+ required to manage it - since the event must be either re-usable or
+ re-creatable under cancelation. This is not needed in the non-cancelable
+ design because it is able to mark the event as closed (forever).
+
+ When uncontested, a CS operation is equivalent to an Interlocked operation
+ in speed. So, in the final design with cancelability, an uncontested
+ once_control operation involves a minimum of five interlocked operations
+ (including the LeaveCS operation).
+
+ ALTERNATIVES:
+ An alternative design from Alexander Terekhov proposed using a named mutex,
+ as sketched below:-
+
+ if (!once_control) { // May be in TLS
+ named_mutex::guard guard(&once_control2);
+ if (!once_control2) {
+ <init>
+ once_control2 = true;
+ }
+ once_control = true;
+ }
+
+ A more detailed description of this can be found here:-
+ http://groups.yahoo.com/group/boost/message/15442
+
+ [Although the definition of a suitable PTHREAD_ONCE_INIT precludes use of the
+ TLS located flag, this is not critical.]
+
+ There are three primary concerns though:-
+ 1) The [named] mutex is 'created' even in the uncontended case.
+ 2) A system wide unique name must be generated.
+ 3) Win32 mutexes are VERY slow even in the uncontended case. An uncontested
+ Win32 mutex lock operation can be 50 (or more) times slower than an
+ uncontested EnterCS operation.
+
+ Ultimately, the named mutex trick is making use of the global locks maintained
+ by the kernel.
+
+ * pthread.h (pthread_once_t_): One flag and an event HANDLE added.
+ (PTHREAD_ONCE_INIT): Additional values included.
+
+2005-03-08 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_once.c (pthread_once): Redesigned to elliminate potential
+ starvation problem.
+ - reported by Gottlob Frege <gottlobfrege at gmail.com>
+
+ * ptw32_threadDestroy.c (ptw32_threadDestroy): Implicit threads were
+ not closing their Win32 thread duplicate handle.
+ - reported by Dmitrii Semii <bogolt at gmail.com>
+
+2005-01-25 Ralf Kubis <RKubis at mc.com>
+
+ * Attempted acquisition of recursive mutex was causing waiting
+ threads to not be woken when the mutex is released.
+
+ * GNUmakefile (GCE): Generate correct version resource comments.
+
+2005-01-01 Konstantin Voronkov <beowinkle at yahoo.com>
+
+ * pthread_mutex_lock.c (pthread_mutex_lock): The new atomic exchange
+ mutex algorithm is known to allow a thread to steal the lock off
+ FIFO waiting threads. The next waiting FIFO thread gets a spurious
+ wake-up and must attempt to re-acquire the lock. The woken thread
+ was setting itself as the mutex's owner before the re-acquisition.
+
+2004-11-22 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_cond_wait.c (ptw32_cond_wait_cleanup): Undo change
+ from 2004-11-02.
+ * Makefile (DLL_VER): Added for DLL naming suffix - see README.
+ * GNUmakefile (DLL_VER): Likewise.
+ * Wmakefile (DLL_VER): Likewise.
+ * Bmakefile (DLL_VER): Likewise.
+ * pthread.dsw (version.rc): Added to MSVS workspace.
+
+2004-11-20 Boudewijn Dekker <b.dekker at ellipsis.nl>
+
+ * pthread_getspecific.c (pthread_getspecific): Check for
+ invalid (NULL) key argument.
+
+2004-11-19 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * config.h (PTW32_THREAD_ID_REUSE_INCREMENT): Added to allow
+ building the library for either unique thread IDs like Solaris
+ or non-unique thread IDs like Linux; allows application developers
+ to override the library's default insensitivity to some apps
+ that may not be strictly POSIX compliant.
+ * version.rc: New resource module to encode version information
+ within the DLL.
+ * pthread.h: Added PTW32_VERSION* defines and grouped sections
+ required by resource compiler together; bulk of file is skipped
+ if RC_INVOKED. Defined some error numbers and other names for
+ Borland compiler.
+
+2004-11-02 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_cond_wait.c (ptw32_cond_wait_cleanup): Lock CV mutex at
+ start of cleanup handler rather than at the end.
+ * implement.h (PTW32_THREAD_REUSE_EMPTY): Renamed from *_BOTTOM.
+ (ptw32_threadReuseBottom): New global variable.
+ * global.c (ptw32_threadReuseBottom): Declare new variable.
+ * ptw32_reuse.c (ptw32_reuse): Change reuse LIFO stack to LILO queue
+ to more evenly distribute use of reusable thread IDs; use renamed
+ PTW32_THREAD_REUSE_EMPTY.
+ * ptw32_processTerminate.c (ptw2_processTerminate): Use renamed
+ PTW32_THREAD_REUSE_EMPTY.
+
+2004-10-31 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * implement.h (PThreadState): Add new state value
+ 'PThreadStateCancelPending'.
+ * pthread_testcancel.c (pthread_testcancel): Use new thread
+ 'PThreadStateCancelPending' state as short cut to avoid entering
+ kernel space via WaitForSingleObject() call. This was obviated
+ by user space sema acquisition in sem_wait() and sem_timedwait(),
+ which are also cancelation points. A call to pthread_testcancel()
+ was required, which introduced a kernel call, effectively nullifying
+ any gains made by the user space sem acquisition checks.
+ * pthread_cancel.c (pthread_cancel): Set new thread
+ 'PThreadStateCancelPending' state.
+
+2004-10-29 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * implement.h (pthread_t): Renamed to ptw32_thread_t; struct contains
+ all thread state.
+ * pthread.h (ptw32_handle_t): New general purpose struct to serve
+ as a handle for various reusable object IDs - currently only used
+ by pthread_t; contains a pointer to ptw32_thread_t (thread state)
+ and a general purpose uint for use as a reuse counter or flags etc.
+ (pthread_t): typedef'ed to ptw32_handle_t; the uint is the reuse
+ counter that allows the library to maintain unique POSIX thread IDs.
+ When the pthread struct reuse stack was introduced, threads would
+ often acquire an identical ID to a previously destroyed thread. The
+ same was true for the pre-reuse stack library, by virtue of pthread_t
+ being the address of the thread struct. The new pthread_t retains
+ the reuse stack but provides virtually unique thread IDs.
+ * sem_wait.c (ptw32_sem_wait_cleanup): New routine used for
+ cancelation cleanup.
+ * sem_timedwait.c (ptw32_sem_timedwait_cleanup): Likewise.
+
+2004-10-22 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * sem_init.c (sem_init): Introduce a 'lock' element in order to
+ replace the interlocked operations with conventional serialisation.
+ This is needed in order to be able to atomically modify the sema
+ value and perform Win32 sema release operations. Win32 semaphores are
+ used instead of events in order to support efficient multiple posting.
+ If the whole modify/release isn't atomic, a race between
+ sem_timedwait() and sem_post() could result in a release when there is
+ no waiting semaphore, which would cause too many threads to proceed.
+ * sem_wait.c (sem_wait): Use new 'lock'element.
+ * sem_timedwait.c (sem_timedwait): Likewise.
+ * sem_trywait.c (sem_trywait): Likewise.
+ * sem_post.c (sem_post): Likewise.
+ * sem_post_multiple.c (sem_post_multiple): Likewise.
+ * sem_getvalue.c (sem_getvalue): Likewise.
+ * ptw32_semwait.c (ptw32_semwait): Likewise.
+ * sem_destroy.c (sem_destroy): Likewise; also tightened the conditions
+ for semaphore destruction; in particular, a semaphore will not be
+ destroyed if it has waiters.
+ * sem_timedwait.c (sem_timedwait): Added cancel cleanup handler to
+ restore sema value when cancelled.
+ * sem_wait.c (sem_wait): Likewise.
+
+2004-10-21 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_mutex_unlock.c (pthread_mutex_unlock): Must use PulseEvent()
+ rather than SetEvent() to reset the event if there are no waiters.
+
+2004-10-19 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * sem_init.c (sem_init): New semaphore model based on the same idea
+ as mutexes, i.e. user space interlocked check to avoid
+ unnecessarily entering kernel space. Wraps the Win32 semaphore and
+ keeps it's own counter. Although the motivation to do this has existed
+ for a long time, credit goes to Alexander Terekhov for providing
+ the logic. I have deviated slightly from AT's logic to add the waiters
+ count, which has made the code more complicated by adding cancelation
+ cleanup. This also appears to have broken the VCE (C++ EH) version of
+ the library (the same problem as previously reported - see BUGS #2),
+ only apparently not fixable using the usual workaround, nor by turning
+ all optimisation off. The GCE version works fine, so it is presumed to
+ be a bug in MSVC++ 6.0. The cancelation exception is thrown and caught
+ correctly, but the cleanup class destructor is never called. The failing
+ test is tests\semaphore4.c.
+ * sem_wait.c (sem_wait): Implemented user space check model.
+ * sem_post.c (sem_post): Likewise.
+ * sem_trywait.c (sem_trywait): Likewise.
+ * sem_timedwait.c (sem_timedwait): Likewise.
+ * sem_post_multiple.c (sem_post_multiple): Likewise.
+ * sem_getvalue.c (sem_getvalue): Likewise.
+ * ptw32_semwait.c (ptw32_semwait): Likewise.
+ * implement.h (sem_t_): Add counter element.
+
+2004-10-15 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * implement.h (pthread_mutex_t_): Use an event in place of
+ the POSIX semaphore.
+ * pthread_mutex_init.c: Create the event; remove semaphore init.
+ * pthread_mutex_destroy.c: Delete the event.
+ * pthread_mutex_lock.c: Replace the semaphore wait with the event wait.
+ * pthread_mutex_trylock.c: Likewise.
+ * pthread_mutex_timedlock.c: Likewise.
+ * pthread_mutex_unlock.c: Set the event.
+
+2004-10-14 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_mutex_lock.c (pthread_mutex_lock): New algorithm using
+ Terekhov's xchg based variation of Drepper's cmpxchg model.
+ Theoretically, xchg uses fewer clock cycles than cmpxchg (using IA-32
+ as a reference), however, in my opinion bus locking dominates the
+ equation on smp systems, so the model with the least number of bus
+ lock operations in the execution path should win, which is Terekhov's
+ variant. On IA-32 uni-processor systems, it's faster to use the
+ CMPXCHG instruction without locking the bus than to use the XCHG
+ instruction, which always locks the bus. This makes the two variants
+ equal for the non-contended lock (fast lane) execution path on up
+ IA-32. Testing shows that the xchg variant is faster on up IA-32 as
+ well if the test forces higher lock contention frequency, even though
+ kernel calls should be dominating the times (on up IA-32, both
+ variants used CMPXCHG instructions and neither locked the bus).
+ * pthread_mutex_timedlock.c pthread_mutex_timedlock(): Similarly.
+ * pthread_mutex_trylock.c (pthread_mutex_trylock): Similarly.
+ * pthread_mutex_unlock.c (pthread_mutex_unlock): Similarly.
+ * ptw32_InterlockedCompareExchange.c (ptw32_InterlockExchange): New
+ function.
+ (PTW32_INTERLOCKED_EXCHANGE): Sets up macro to use inlined
+ ptw32_InterlockedExchange.
+ * implement.h (PTW32_INTERLOCKED_EXCHANGE): Set default to
+ InterlockedExchange().
+ * Makefile: Building using /Ob2 so that asm sections within inline
+ functions are inlined.
+
+2004-10-08 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_mutex_destroy.c (pthread_mutex_destroy): Critical Section
+ element is no longer required.
+ * pthread_mutex_init.c (pthread_mutex_init): Likewise.
+ * pthread_mutex_lock.c (pthread_mutex_lock): New algorithm following
+ Drepper's paper at http://people.redhat.com/drepper/futex.pdf, but
+ using the existing semaphore in place of the futex described in the
+ paper. Idea suggested by Alexander Terekhov - see:
+ http://sources.redhat.com/ml/pthreads-win32/2003/msg00108.html
+ * pthread_mutex_timedlock.c pthread_mutex_timedlock(): Similarly.
+ * pthread_mutex_trylock.c (pthread_mutex_trylock): Similarly.
+ * pthread_mutex_unlock.c (pthread_mutex_unlock): Similarly.
+ * pthread_barrier_wait.c (pthread_barrier_wait): Use inlined version
+ of InterlockedCompareExchange() if possible - determined at
+ build-time.
+ * pthread_spin_destroy.c pthread_spin_destroy(): Likewise.
+ * pthread_spin_lock.c pthread_spin_lock():Likewise.
+ * pthread_spin_trylock.c (pthread_spin_trylock):Likewise.
+ * pthread_spin_unlock.c (pthread_spin_unlock):Likewise.
+ * ptw32_InterlockedCompareExchange.c: Sets up macro for inlined use.
+ * implement.h (pthread_mutex_t_): Remove Critical Section element.
+ (PTW32_INTERLOCKED_COMPARE_EXCHANGE): Set to default non-inlined
+ version of InterlockedCompareExchange().
+ * private.c: Include ptw32_InterlockedCompareExchange.c first for
+ inlining.
+ * GNUmakefile: Add commandline option to use inlined
+ InterlockedCompareExchange().
+ * Makefile: Likewise.
+
+2004-09-27 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_mutex_lock.c (pthread_mutex_lock): Separate
+ PTHREAD_MUTEX_NORMAL logic since we do not need to keep or check some
+ state required by other mutex types; do not check mutex pointer arg
+ for validity - leave this to the system since we are only checking
+ for NULL pointers. This should improve speed of NORMAL mutexes and
+ marginally improve speed of other type.
+ * pthread_mutex_trylock.c (pthread_mutex_trylock): Likewise.
+ * pthread_mutex_unlock.c (pthread_mutex_unlock): Likewise; also avoid
+ entering the critical section for the no-waiters case, with approx.
+ 30% reduction in lock/unlock overhead for this case.
+ * pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise; also
+ no longer keeps mutex if post-timeout second attempt succeeds - this
+ will assist applications that wish to impose strict lock deadlines,
+ rather than simply to escape from frozen locks.
+
+2004-09-09 Tristan Savatier <tristan at mpegtv.com>
+ * pthread.h (struct pthread_once_t_): Qualify the 'done' element
+ as 'volatile'.
+ * pthread_once.c: Concerned about possible race condition,
+ specifically on MPU systems re concurrent access to multibyte types.
+ [Maintainer's note: the race condition is harmless on SPU systems
+ and only a problem on MPU systems if concurrent access results in an
+ exception (presumably generated by a hardware interrupt). There are
+ other instances of similar harmless race conditions that have not
+ been identified as issues.]
+
+2004-09-09 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread.h: Declare additional types as volatile.
+
+2004-08-27 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_barrier_wait.c (pthread_barrier_wait): Remove excessive code
+ by substituting the internal non-cancelable version of sem_wait
+ (ptw32_semwait).
+
+2004-08-25 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_join.c (pthread_join): Rewrite and re-order the conditional
+ tests in an attempt to improve efficiency and remove a race
+ condition.
+
+2004-08-23 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * create.c (pthread_create): Don't create a thread if the thread
+ id pointer location (first arg) is inaccessible. A memory
+ protection fault will result if the thread id arg isn't an accessible
+ location. This is consistent with GNU/Linux but different to
+ Solaris or MKS (and possibly others), which accept NULL as meaning
+ 'don't return the created thread's ID'. Applications that run
+ using pthreads-win32 will run on all other POSIX threads
+ implementations, at least w.r.t. this feature.
+
+ It was decided not to copy the Solaris et al behaviour because,
+ although it would have simplified some application porting (but only
+ from Solaris to Windows), the feature is not technically necessary,
+ and the alternative segfault behaviour helps avoid buggy application
+ code.
+
+2004-07-01 Anuj Goyal <anuj.goyal at gmail.com>
+
+ * builddmc.bat: New; Windows bat file to build the library.
+ * config.h (__DMC__): Support for Digital Mars compiler.
+ * create.c (__DMC__): Likewise.
+ * pthread_exit.c (__DMC__): Likewise.
+ * pthread_join.c (__DMC__): Likewise.
+ * ptw32_threadDestroy.c (__DMC__): Likewise.
+ * ptw32_threadStart.c (__DMC__): Likewise.
+ * ptw32_throw.c (__DMC__): Likewise.
+
+2004-06-29 Anuj Goyal <anuj.goyal at gmail.com>
+
+ * pthread.h (__DMC__): Initial support for Digital Mars compiler.
+
+2004-06-29 Will Bryant <will.bryant at ecosm.com>
+
+ * README.Borland: New; description of Borland changes.
+ * Bmakefile: New makefile for the Borland make utility.
+ * ptw32_InterlockedCompareExchange.c:
+ Add Borland compatible asm code.
+
+2004-06-26 Jason Bard <BardJA at Npt.NUWC.Navy.Mil>
+
+ * pthread.h (HAVE_STRUCT_TIMESPEC): If undefined, define it
+ to avoid timespec struct redefined errors elsewhere in an
+ application.
+
+2004-06-21 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread.h (PTHREAD_RECURSIVE_MUTEX_INITIALIZER): Mutex
+ initialiser added for compatibility with Linux threads and
+ others; currently not included in SUSV3.
+ * pthread.h (PTHREAD_ERRORCHECK_MUTEX_INITIALIZER): Likewise.
+ * pthread.h (PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP): Likewise.
+ * pthread.h (PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP): Likewise.
+
+ * ptw32_mutex_check_need_init.c (ptw32_mutex_check_need_init):
+ Add new initialisers.
+
+ * pthread_mutex_lock.c (pthread_mutex_lock): Check for new
+ initialisers.
+ * pthread_mutex_trylock.c (pthread_mutex_trylock): Likewise.
+ * pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise.
+ * pthread_mutex_unlock.c (pthread_mutex_unlock): Likewise.
+ * pthread_mutex_destroy.c (pthread_mutex_destroy): Likewise.
+
+2004-05-20 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * README.NONPORTABLE: Document pthread_win32_test_features_np().
+ * FAQ: Update various answers.
+
+2004-05-19 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * Makefile: Don't define _WIN32_WINNT on compiler command line.
+ * GNUmakefile: Likewise.
+
+2004-05-16 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_cancel.c (pthread_cancel): Adapted to use auto-detected
+ QueueUserAPCEx features at run-time.
+ (ptw32_RegisterCancelation): Drop in replacement for QueueUserAPCEx()
+ if it can't be used. Provides older style non-preemptive async
+ cancelation.
+ * pthread_win32_attach_detach_np.c (pthread_win32_attach_np):
+ Auto-detect quserex.dll and the availability of alertdrv.sys;
+ initialise and close on process attach/detach.
+ * global.c (ptw32_register_cancelation): Pointer to either
+ QueueUserAPCEx() or ptw32_RegisterCancelation() depending on
+ availability. QueueUserAPCEx makes pre-emptive async cancelation
+ possible.
+ * implement.h: Add definitions and prototypes related to QueueUserAPC.
+
+2004-05-16 Panagiotis E. Hadjidoukas <peh at hpclab.ceid.upatras.gr>
+
+ * QueueUserAPCEx (separate contributed package): Provides preemptive
+ APC feature.
+ * pthread_cancel.c (pthread_cancel): Initial integration of
+ QueueUserAPCEx into pthreads-win32 to provide true pre-emptive
+ async cancelation of threads, including blocked threads.
+
+2004-05-06 Makoto Kato <raven at oldskool.jp>
+
+ * pthread.h (DWORD_PTR): Define typedef for older MSVC.
+ * pthread_cancel.c (AMD64): Add architecture specific Context register.
+ * ptw32_getprocessors.c: Use correct types (DWORD_PTR) for mask
+ variables.
+
+2004-04-06 P. van Bruggen <pietvb at newbridges.nl>
+
+ * ptw32_threadDestroy.c: Destroy threadLock mutex to
+ close a memory leak.
+
+2004-02-13 Gustav Hallberg <gustav at virtutech.com>
+
+ * pthread_equal.c: Remove redundant equality logic.
+
+2003-12-10 Philippe Di Cristo <philipped at voicebox.com>
+
+ * sem_timedwait.c (sem_timedwait): Fix timeout calculations.
+
+2003-10-20 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * pthread_mutex_timedlock.c (ptw32_semwait): Move to individual module.
+ * ptw32_semwait.c: New module.
+ * pthread_cond_wait.c (ptw32_cond_wait_cleanup): Replace cancelable
+ sem_wait() call with non-cancelable ptw32_semwait() call.
+ * pthread.c (private.c): Re-order for inlining. GNU C warned that
+ function ptw32_semwait() was defined 'inline' after it was called.
+ * pthread_cond_signal.c (ptw32_cond_unblock): Likewise.
+ * pthread_delay_np.c: Disable Watcom warning with comment.
+ * *.c (process.h): Remove include from .c files. This is conditionally
+ included by the common project include files.
+
+2003-10-20 James Ewing <james.ewing at sveasoft.com>
+
+ * ptw32_getprocessors.c: Some Win32 environments don't have
+ GetProcessAffinityMask(), so always return CPU count = 1 for them.
+ * config.h (NEED_PROCESSOR_AFFINITY_MASK): Define for WinCE.
+
+2003-10-15 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * Re-indented all .c files using default GNU style to remove assorted
+ editor ugliness (used GNU indent utility in default style).
+
+2003-10-15 Alex Blanco <Alex.Blanco at motorola.com>
+
+ * sem_init.c (sem_init): Would call CreateSemaphore even if the sema
+ struct calloc failed; was not freeing calloced memory if either
+ CreateSemaphore or CreateEvent failed.
+
+2003-10-14 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * pthread.h: Add Watcom compiler compatibility. Esssentially just add
+ the cdecl attribute to all exposed function prototypes so that Watcom
+ generates function call code compatible with non-Watcom built libraries.
+ By default, Watcom uses registers to pass function args if possible rather
+ than pushing to stack.
+ * semaphore.h: Likewise.
+ * sched.h: Likewise.
+ * pthread_cond_wait.c (ptw32_cond_wait_cleanup): Define with cdecl attribute
+ for Watcom compatibility. This routine is called via pthread_cleanup_push so
+ it had to match function arg definition.
+ * Wmakefile: New makefile for Watcom builds.
+
+2003-09-14 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_setschedparam.c (pthread_setschedparam): Attempt to map
+ all priority levels between max and min (as returned by
+ sched_get_priority_min/max) to reasonable Win32 priority levels - i.e.
+ levels between THREAD_PRIORITY_LOWEST/IDLE to THREAD_PRIORITY_LOWEST and
+ between THREAD_PRIORITY_HIGHEST/TIME_CRITICAL to THREAD_PRIORITY_HIGHEST
+ while others remain unchanged; record specified thread priority level
+ for return by pthread_getschedparam.
+
+ Note that, previously, specified levels not matching Win32 priority levels
+ would silently leave the current thread priority unaltered.
+
+ * pthread_getschedparam.c (pthread_getschedparam): Return the priority
+ level specified by the latest pthread_setschedparam or pthread_create rather
+ than the actual running thread priority as returned by GetThreadPriority - as
+ required by POSIX. I.e. temporary or adjusted actual priority levels are not
+ returned by this routine.
+
+ * pthread_create.c (pthread_create): For priority levels specified via
+ pthread attributes, attempt to map all priority levels between max and
+ min (as returned by sched_get_priority_min/max) to reasonable Win32
+ priority levels; record priority level given via attributes, or
+ inherited from parent thread, for later return by pthread_getschedparam.
+
+ * ptw32_new.c (ptw32_new): Initialise pthread_t_ sched_priority element.
+
+ * pthread_self.c (pthread_self): Set newly created implicit POSIX thread
+ sched_priority to Win32 thread's current actual priority. Temporarily
+ altered priorities can't be avoided in this case.
+
+ * implement.h (struct pthread_t_): Add new sched_priority element.
+
+2003-09-12 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * sched_get_priority_min.c (sched_get_priority_min): On error should return -1
+ with errno set.
+ * sched_get_priority_max.c (sched_get_priority_max): Likewise.
+
+2003-09-03 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * w32_cancelableWait.c (ptw32_cancelable_wait): Allow cancelation
+ of implicit POSIX threads as well.
+
+2003-09-02 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_win32_attach_detach_np.c (pthread_win32_thread_detach_np):
+ Add comment.
+
+ * pthread_exit.c (pthread_exit): Fix to recycle the POSIX thread handle in
+ addition to calling user TSD destructors. Move the implicit POSIX thread exit
+ handling to ptw32_throw to centralise the logic.
+
+ * ptw32_throw.c (ptw32_throw): Implicit POSIX threads have no point
+ to jump or throw to, so cleanup and exit the thread here in this case. For
+ processes using the C runtime, the exit code will be set to the POSIX
+ reason for the throw (i.e. PTHREAD_CANCEL or the value given to pthread_exit).
+ Note that pthread_exit() already had similar logic, which has been moved to
+ here.
+
+ * ptw32_threadDestroy.c (ptw32_threadDestroy): Don't close the Win32 handle
+ of implicit POSIX threads - expect this to be done by Win32?
+
+2003-09-01 Ross Johnson <rpj at callisto.canberra.edu.au>
+
+ * pthread_self.c (pthread_self): The newly aquired pthread_t must be
+ assigned to the reuse stack, not freed, if the routine fails somehow.
+
+2003-08-13 Ross Johnson <rpj at ise.canberra.edu.au>
+
+ * pthread_getschedparam.c (pthread_getschedparam): An invalid thread ID
+ parameter was returning an incorrect error value; now uses a more exhaustive
+ check for validity.
+
+ * pthread_setschedparam.c (pthread_setschedparam): Likewise.
+
+ * pthread_join.c (pthread_join): Now uses a more exhaustive
+ check for validity.
+
+ * pthread_detach.c (pthread_detach): Likewise.
+
+ * pthread_cancel.c (pthread_cancel): Likewise.
+
+ * ptw32_threadDestroy.c (ptw32_threadDestroy): pthread_t structs are
+ never freed - push them onto a stack for reuse.
+
+ * ptw32_new.c (ptw32_new): Check for reusable pthread_t before dynamically
+ allocating new memory for the struct.
+
+ * pthread_kill.c (pthread_kill): New file; new routine; takes only a zero
+ signal arg so that applications can check the thread arg for validity; checks
+ that the underlying Win32 thread HANDLE is valid.
+
+ * pthread.h (pthread_kill): Add prototype.
+
+ * ptw32_reuse.c (ptw32_threadReusePop): New file; new routine; pop a
+ pthread_t off the reuse stack. pthread_t_ structs that have been destroyed, i.e.
+ have exited detached or have been joined, are cleaned up and put onto a reuse
+ stack. Consequently, thread IDs are no longer freed once calloced. The library
+ will attempt to get a struct off this stack before asking the system to alloc
+ new memory when creating threads. The stack is guarded by a global mutex.
+ (ptw32_threadReusePush): New routine; push a pthread_t onto the reuse stack.
+
+ * implement.h (ptw32_threadReusePush): Add new prototype.
+ (ptw32_threadReusePop): Likewise.
+ (pthread_t): Add new element.
+
+ * ptw32_processTerminate.c (ptw32_processTerminate): Delete the thread
+ reuse lock; free all thread ID structs on the thread reuse stack.
+
+ * ptw32_processInitialize.c (ptw32_processInitialize): Initialise the
+ thread reuse lock.
+
+2003-07-19 Ross Johnson <rpj at ise.canberra.edu.au>
+
+ * GNUmakefile: modified to work under MsysDTK environment.
+ * pthread_spin_lock.c (pthread_spin_lock): Check for NULL arg.
+ * pthread_spin_unlock.c (pthread_spin_unlock): Likewise.
+ * pthread_spin_trylock.c (pthread_spin_trylock): Likewise;
+ fix incorrect pointer value if lock is dynamically initialised by
+ this function.
+ * sem_init.c (sem_init): Initialise sem_t value to quell compiler warning.
+ * sem_destroy.c (sem_destroy): Likewise.
+ * ptw32_threadStart.c (non-MSVC code sections): Include <exception> rather
+ than old-style <new.h>; fix all std:: namespace entities such as
+ std::terminate_handler instances and associated methods.
+ * ptw32_callUserDestroyRoutines.c (non-MSVC code sections): Likewise.
+
+2003-06-24 Piet van Bruggen <pietvb at newbridges.nl>
+
+ * pthread_spin_destroy.c (pthread_spin_destroy): Was not freeing the
+ spinlock struct.
+
+2003-06-22 Nicolas Barry <boozai at yahoo.com>
+
+ * pthread_mutex_destroy.c (pthread_mutex_destroy): When called
+ with a recursive mutex that was locked by the current thread, the
+ function was failing with a success return code.
+
+2003-05-15 Steven Reddie <Steven.Reddie at ca.com>
+
+ * pthread_win32_attach_detach_np.c (pthread_win32_process_detach_np):
+ NULLify ptw32_selfThreadKey after the thread is destroyed, otherwise
+ destructors calling pthreads routines might resurrect it again, creating
+ memory leaks. Call the underlying Win32 Tls routine directly rather than
+ pthread_setspecific().
+ (pthread_win32_thread_detach_np): Likewise.
+
+2003-05-14 Viv <vcotirlea at hotmail.com>
+
+ * pthread.dsp: Change /MT compile flag to /MD.
+
+2003-03-04 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * pthread_mutex_timedlock.c (pthread_mutex_timedlock): Fix failure to
+ set ownership of mutex on second grab after abstime timeout.
+ - bug reported by Robert Strycek <strycek at posam.sk>
+
+2002-12-17 Thomas Pfaff <tpfaff at gmx.net>
+
+ * pthread_mutex_lock.c (ptw32_semwait): New static routine to provide
+ a non-cancelable sem_wait() function. This is consistent with the
+ way that pthread_mutex_timedlock.c does it.
+ (pthread_mutex_lock): Use ptw32_semwait() instead of sem_wait().
+
+2002-12-11 Thomas Pfaff <tpfaff at gmx.net>
+
+ * pthread_mutex_trylock.c: Should return EBUSY rather than EDEADLK.
+ * pthread_mutex_destroy.c: Remove redundant ownership test (the
+ trylock call does this for us); do not destroy a recursively locked
+ mutex.
+
+2002-09-20 Michael Johnson <michaelj at maine.rr.com>
+
+ * pthread_cond_destroy.c (pthread_cond_destroy):
+ When two different threads exist, and one is attempting to
+ destroy a condition variable while the other is attempting to
+ initialize a condition variable that was created with
+ PTHREAD_COND_INITIALIZER, a deadlock can occur. Shrink
+ the ptw32_cond_list_lock critical section to fix it.
+
+2002-07-31 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * ptw32_threadStart.c (ptw32_threadStart): Thread cancelLock
+ destruction moved to ptw32_threadDestroy().
+
+ * ptw32_threadDestroy.c (ptw32_threadDestroy): Destroy
+ the thread's cancelLock. Moved here from ptw32_threadStart.c
+ to cleanup implicit threads as well.
+
+2002-07-30 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * pthread_cond_wait.c (ptw32_cond_wait_cleanup):
+ Remove code designed to avoid/prevent spurious wakeup
+ problems. It is believed that the sem_timedwait() call
+ is consuming a CV signal that it shouldn't and this is
+ breaking the avoidance logic.
+
+2002-07-30 Ross Johnson <rpj at ise.canberra.edu.au>
+
+ * sem_timedwait.c (sem_timedwait): Tighten checks for
+ unreasonable abstime values - that would result in
+ unexpected timeout values.
+
+ * w32_CancelableWait.c (ptw32_cancelable_wait):
+ Tighten up return value checking and add comments.
+
+
+2002-06-08 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * sem_getvalue.c (sem_getvalue): Now returns a value for the
+ NEED_SEM version (i.e. earlier versions of WinCE).
+
+
+2002-06-04 Rob Fanner <rfanner at stonethree.com>
+
+ * sem_getvalue.c (sem_getvalue): The Johnson M. Hart
+ approach didn't work - we are forced to take an
+ intrusive approach. We try to decrement the sema
+ and then immediately release it again to get the
+ value. There is a small probability that this may
+ block other threads, but only momentarily.
+
+2002-06-03 Ross Johnson <rpj at ise.canberra.edu.au>
+
+ * sem_init.c (sem_init): Initialise Win32 semaphores
+ to _POSIX_SEM_VALUE_MAX (which this implementation
+ defines in pthread.h) so that sem_getvalue() can use
+ the trick described in the comments in sem_getvalue().
+ * pthread.h (_POSIX_SEM_VALUE_MAX): Defined.
+ (_POSIX_SEM_NSEMS_MAX): Defined - not used but may be
+ useful for source code portability.
+
+2002-06-03 Rob Fanner <rfanner at stonethree.com>
+
+ * sem_getvalue.c (sem_getvalue): Did not work on NT.
+ Use approach suggested by Johnson M. Hart in his book
+ "Win32 System Programming".
+
+2002-02-28 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * errno.c: Compiler directive was incorrectly including code.
+ * pthread.h: Conditionally added some #defines from config.h
+ needed when not building the library. e.g. NEED_ERRNO, NEED_SEM.
+ (PTW32_DLLPORT): Now only defined if _DLL defined.
+ (_errno): Compiler directive was incorrectly including prototype.
+ * sched.h: Conditionally added some #defines from config.h
+ needed when not building the library.
+ * semaphore.h: Replace an instance of NEED_SEM that should
+ have been NEED_ERRNO. This change currently has nil effect.
+
+ * GNUmakefile: Correct some recent changes.
+
+ * Makefile: Add rule to generate pre-processor output.
+
+2002-02-23 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * pthread_rwlock_timedrdlock.c: New - untested.
+ * pthread_rwlock_timedwrlock.c: New - untested.
+
+ * Testsuite passed (except known MSVC++ problems)
+
+ * pthread_cond_destroy.c: Expand the time change
+ critical section to solve deadlock problem.
+
+ * pthread.c: Add all remaining C modules.
+ * pthread.h: Use dllexport/dllimport attributes on functions
+ to avoid using pthread.def.
+ * sched.h: Likewise.
+ * semaphore.h: Likewise.
+ * GNUmakefile: Add new targets for single translation
+ unit build to maximise inlining potential; generate
+ pthread.def automatically.
+ * Makefile: Likewise, but no longer uses pthread.def.
+
+2002-02-20 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * pthread_cond_destroy.c (pthread_cond_destroy):
+ Enter the time change critical section earlier.
+
+2002-02-17 Ross Johnson <rpj at setup1.ise.canberra.edu.au
+
+ * Testsuite passed.
+
+ * pthread_timechange_handler_np.c: New; following
+ a suggestion from Alexander Terekhov that CVs should
+ be broadcast so that they all re-evaluate their
+ condition variables and reset a new timeout if
+ required, whenever an application receives a
+ WM_TIMECHANGE message. This message indicates that
+ the system time has been changed. Therefore, CVs
+ waiting for a timeout set as an abs_time will possibly
+ not wake up at the expected time. Some applications
+ may not be tolerant of this.
+ * pthread_cond_init.c: Add CV to linked list.
+ * pthread_cond_destroy.c: Remove CV from linked list.
+ * global.c (ptw32_cond_list_head): New variable.
+ (ptw32_cond_list_tail): New variable.
+ (ptw32_cond_list_cs): New critical section.
+ * ptw32_processInitialize (ptw32_cond_list_cs): Initialize.
+ * ptw32_processTerminate (ptw32_cond_list_cs): Delete.
+
+
+ * Reduce executable size.
+ -----------------------
+ When linking with the static library, only those
+ routines actually called, either directly or indirectly
+ should be included.
+
+ [Gcc has the -ffunction-segments option to do this but MSVC
+ doesn't have this feature as far as I can determine. Other
+ compilers are undetermined as well. - rpj]
+
+ * spin.c: Split file into function segments.
+ * ptw32_spinlock_check_need_init.c: Separated routine from spin.c.
+ * pthread_spin_init.c: Likewise.
+ * pthread_spin_destroy.c: Likewise.
+ * pthread_spin_lock.c: Likewise.
+ * pthread_spin_unlock.c: Likewise.
+ * pthread_spin_trylock.c: Likewise.
+
+ * sync.c: Split file into function segments.
+ * pthread_detach.c: Separated routine from sync.c.
+ * pthread_join.c: Likewise.
+
+ * tsd.c: Split file into function segments.
+ * pthread_key_create.c: Separated routine from tsd.c.
+ * pthread_key_delete.c: Likewise.
+ * pthread_setspecific.c: Likewise.
+ * pthread_getspecific.c: Likewise.
+
+ * sched.c: Split file into function segments.
+ * pthread_attr_setschedpolicy.c: Separated routine from sched.c.
+ * pthread_attr_getschedpolicy.c: Likewise.
+ * pthread_attr_setschedparam.c: Likewise.
+ * pthread_attr_getschedparam.c: Likewise.
+ * pthread_attr_setinheritsched.c: Likewise.
+ * pthread_attr_getinheritsched.c: Likewise.
+ * pthread_setschedparam.c: Likewise.
+ * pthread_getschedparam.c: Likewise.
+ * sched_get_priority_max.c: Likewise.
+ * sched_get_priority_min.c: Likewise.
+ * sched_setscheduler.c: Likewise.
+ * sched_getscheduler.c: Likewise.
+ * sched_yield.c: Likewise.
+
+
+2002-02-16 Ross Johnson <rpj at setup1.ise.canberra.edu.au
+
+ Reduce executable size.
+ -----------------------
+ When linking with the static library, only those
+ routines actually called, either directly or indirectly
+ should be included.
+
+ [Gcc has the -ffunction-segments option to do this but MSVC
+ doesn't have this feature as far as I can determine. Other
+ compilers are undetermined as well. - rpj]
+
+ * mutex.c: Split file into function segments.
+ * pthread_mutexattr_destroy.c: Separated routine from mutex.c
+ * pthread_mutexattr_getpshared.c: Likewise.
+ * pthread_mutexattr_gettype.c: Likewise.
+ * pthread_mutexattr_init.c: Likewise.
+ * pthread_mutexattr_setpshared.c: Likewise.
+ * pthread_mutexattr_settype.c: Likewise.
+ * ptw32_mutex_check_need_init.c: Likewise.
+ * pthread_mutex_destroy.c: Likewise.
+ * pthread_mutex_init.c: Likewise.
+ * pthread_mutex_lock.c: Likewise.
+ * pthread_mutex_timedlock.c: Likewise.
+ * pthread_mutex_trylock.c: Likewise.
+ * pthread_mutex_unlock.c: Likewise.
+
+ * private.c: Split file into function segments.
+ * ptw32_InterlockedCompareExchange.c: Separated routine from private.c
+ * ptw32_callUserDestroyRoutines.c: Likewise.
+ * ptw32_getprocessors.c: Likewise.
+ * ptw32_processInitialize.c: Likewise.
+ * ptw32_processTerminate.c: Likewise.
+ * ptw32_threadDestroy.c: Likewise.
+ * ptw32_threadStart.c: Likewise.
+ * ptw32_throw.c: Likewise.
+ * ptw32_timespec.c: Likewise.
+ * ptw32_tkAssocCreate.c: Likewise.
+ * ptw32_tkAssocDestroy.c: Likewise.
+
+ * rwlock.c: Split file into function segments.
+ * pthread_rwlockattr_destroy.c: Separated routine from rwlock.c
+ * pthread_rwlockattr_getpshared.c: Likewise.
+ * pthread_rwlockattr_init.c: Likewise.
+ * pthread_rwlockattr_setpshared.c: Likewise.
+ * ptw32_rwlock_check_need_init.c: Likewise.
+ * pthread_rwlock_destroy.c: Likewise.
+ * pthread_rwlock_init.c: Likewise.
+ * pthread_rwlock_rdlock.c: Likewise.
+ * pthread_rwlock_tryrdlock.c: Likewise.
+ * pthread_rwlock_trywrlock.c: Likewise.
+ * pthread_rwlock_unlock.c: Likewise.
+ * pthread_rwlock_wrlock.c: Likewise.
+
+2002-02-10 Ross Johnson <rpj at setup1.ise.canberra.edu.au
+
+ Reduce executable size.
+ -----------------------
+ When linking with the static library, only those
+ routines actually called, either directly or indirectly
+ should be included.
+
+ [Gcc has the -ffunction-segments option to do this but MSVC
+ doesn't have this feature as far as I can determine. Other
+ compilers are undetermined as well. - rpj]
+
+ * nonportable.c: Split file into function segments.
+ * np_delay.c: Separated routine from nonportable.c
+ * np_getw32threadhandle.c: Likewise.
+ * np_mutexattr_setkind.c: Likewise.
+ * np_mutexattr_getkind.c: Likewise.
+ * np_num_processors.c: Likewise.
+ * np_win32_attach_detach.c: Likewise.
+
+ * misc.c: Split file into function segments.
+ * pthread_equal.c: Separated routine from nonportable.c.
+ * pthread_getconcurrency.c: Likewise.
+ * pthread_once.c: Likewise.
+ * pthread_self.c: Likewise.
+ * pthread_setconcurrency.c: Likewise.
+ * ptw32_calloc.c: Likewise.
+ * ptw32_new.c: Likewise.
+ * w32_CancelableWait.c: Likewise.
+
+2002-02-09 Ross Johnson <rpj at setup1.ise.canberra.edu.au
+
+ Reduce executable size.
+ -----------------------
+ When linking with the static library, only those
+ routines actually called, either directly or indirectly
+ should be included.
+
+ [Gcc has the -ffunction-segments option to do this but MSVC
+ doesn't have this feature as far as I can determine. Other
+ compilers are undetermined as well. - rpj]
+
+ * condvar.c: Split file into function segments.
+ * pthread_condattr_destroy.c: Separated routine from condvar.c.
+ * pthread_condattr_getpshared.c: Likewise.
+ * pthread_condattr_init.c: Likewise.
+ * pthread_condattr_setpshared.c: Likewise.
+ * ptw32_cond_check_need_init.c: Likewise.
+ * pthread_cond_destroy.c: Likewise.
+ * pthread_cond_init.c: Likewise.
+ * pthread_cond_signal.c: Likewise.
+ * pthread_cond_wait.c: Likewise.
+
+2002-02-07 Alexander Terekhov<TEREKHOV at de.ibm.com>
+
+ * nonportable.c (pthread_delay_np): Make a true
+ cancelation point. Deferred cancels will interrupt the
+ wait.
+
+2002-02-07 Ross Johnson <rpj at setup1.ise.canberra.edu.au
+
+ * misc.c (ptw32_new): Add creation of cancelEvent so that
+ implicit POSIX threads (Win32 threads with a POSIX face)
+ are cancelable; mainly so that pthread_delay_np doesn't fail
+ if called from the main thread.
+ * create.c (pthread_create): Remove creation of cancelEvent
+ from here; now in ptw32_new().
+
+ Reduce executable size.
+ -----------------------
+ When linking with the static library, only those
+ routines actually called, either directly or indirectly
+ should be included.
+
+ [Gcc has the -ffunction-segments option to do this but MSVC
+ doesn't have this feature as far as I can determine. Other
+ compilers are undetermined as well. - rpj]
+
+ * barrier.c: All routines are now in separate compilation units;
+ This file is used to congregate the separate modules for
+ potential inline optimisation and backward build compatibility.
+ * cancel.c: Likewise.
+ * pthread_barrierattr_destroy.c: Separated routine from cancel.c.
+ * pthread_barrierattr_getpshared.c: Likewise.
+ * pthread_barrierattr_init.c: Likewise.
+ * pthread_barrierattr_setpshared.c: Likewise.
+ * pthread_barrier_destroy.c: Likewise.
+ * pthread_barrier_init.c: Likewise.
+ * pthread_barrier_wait.c: Likewise.
+ * pthread_cancel.c: Likewise.
+ * pthread_setcancelstate.c: Likewise.
+ * pthread_setcanceltype.c: Likewise.
+ * pthread_testcancel.c: Likewise.
+
+2002-02-04 Max Woodbury <mtew at cds.duke.edu>
+
+ Reduced name space pollution.
+ -----------------------------
+ When the appropriate symbols are defined, the headers
+ will restrict the definitions of new names. In particular,
+ it must be possible to NOT include the <windows.h>
+ header and related definitions with some combination
+ of symbol definitions. Secondly, it should be possible
+ that additional definitions should be limited to POSIX
+ compliant symbols by the definition of appropriate symbols.
+
+ * pthread.h: POSIX conditionals.
+ * sched.h: POSIX conditionals.
+ * semaphore.h: POSIX conditionals.
+
+ * semaphore.c: Included <limits.h>.
+ (sem_init): Changed magic 0x7FFFFFFFL to INT_MAX.
+ (sem_getvalue): Trial version.
+
+ Reduce executable size.
+ -----------------------
+ When linking with the static library, only those
+ routines actually called, either directly or indirectly
+ should be included.
+
+ [Gcc has the -ffunction-segments option to do this but MSVC
+ doesn't have this feature as far as I can determine. Other
+ compilers are undetermined as well. - rpj]
+
+ * semaphore.c: All routines are now in separate compilation units;
+ This file is used to congregate the separate modules for
+ potential inline optimisation and backward build compatibility.
+ * sem_close.c: Separated routine from semaphore.c.
+ * ptw32_decrease_semaphore.c: Likewise.
+ * sem_destroy.c: Likewise.
+ * sem_getvalue.c: Likewise.
+ * ptw32_increase_semaphore.c: Likewise.
+ * sem_init.c: Likewise.
+ * sem_open.c: Likewise.
+ * sem_post.c: Likewise.
+ * sem_post_multiple.c: Likewise.
+ * sem_timedwait.c: Likewise.
+ * sem_trywait.c: Likewise.
+ * sem_unlink.c: Likewise.
+ * sem_wait.c: Likewise.
+
+2002-02-04 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ The following extends the idea above to the rest of pthreads-win32 - rpj
+
+ * attr.c: All routines are now in separate compilation units;
+ This file is used to congregate the separate modules for
+ potential inline optimisation and backward build compatibility.
+ * pthread_attr_destroy.c: Separated routine from attr.c.
+ * pthread_attr_getdetachstate.c: Likewise.
+ * pthread_attr_getscope.c: Likewise.
+ * pthread_attr_getstackaddr.c: Likewise.
+ * pthread_attr_getstacksize.c: Likewise.
+ * pthread_attr_init.c: Likewise.
+ * pthread_attr_is_attr.c: Likewise.
+ * pthread_attr_setdetachstate.c: Likewise.
+ * pthread_attr_setscope.c: Likewise.
+ * pthread_attr_setstackaddr.c: Likewise.
+ * pthread_attr_setstacksize.c: Likewise.
+
+ * pthread.c: Agregation of agregate modules for super-inlineability.
+
+2002-02-02 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * cancel.c: Rearranged some code and introduced checks
+ to disable cancelation at the start of a thread's cancelation
+ run to prevent double cancelation. The main problem
+ arises if a thread is canceling and then receives a subsequent
+ async cancel request.
+ * private.c: Likewise.
+ * condvar.c: Place pragmas around cleanup_push/pop to turn
+ off inline optimisation (/Obn where n>0 - MSVC only). Various
+ optimisation switches in MSVC turn this on, which interferes with
+ the way that cleanup handlers are run in C++ EH and SEH
+ code. Application code compiled with inline optimisation must
+ also wrap cleanup_push/pop blocks with the pragmas, e.g.
+ #pragma inline_depth(0)
+ pthread_cleanup_push(...)
+ ...
+ pthread_cleanup_pop(...)
+ #pragma inline_depth(8)
+ * rwlock.c: Likewise.
+ * mutex.c: Remove attempts to inline some functions.
+ * signal.c: Modify misleading comment.
+
+2002-02-01 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * semaphore.c (sem_trywait): Fix missing errno return
+ for systems that define NEED_SEM (e.g. early WinCE).
+ * mutex.c (pthread_mutex_timedlock): Return ENOTSUP
+ for systems that define NEED_SEM since they don't
+ have sem_trywait().
+
+2002-01-27 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * mutex.c (pthread_mutex_timedlock): New function suggested by
+ Alexander Terekhov. The logic required to implement this
+ properly came from Alexander, with some collaboration
+ with Thomas Pfaff.
+ (pthread_mutex_unlock): Wrap the waiters check and sema
+ post in a critical section to prevent a race with
+ pthread_mutex_timedlock.
+ (ptw32_timed_semwait): New function;
+ returns a special result if the absolute timeout parameter
+ represents a time already passed when called; used by
+ pthread_mutex_timedwait(). Have deliberately not reused
+ the name "ptw32_sem_timedwait" because they are not the same
+ routine.
+ * condvar.c (ptw32_cond_timedwait): Use the new sem_timedwait()
+ instead of ptw32_sem_timedwait(), which now has a different
+ function. See previous.
+ * implement.h: Remove prototype for ptw32_sem_timedwait.
+ See next.
+ (pthread_mutex_t_): Add critical section element for access
+ to lock_idx during mutex post-timeout processing.
+ * semaphore.h (sem_timedwait): See next.
+ * semaphore.c (sem_timedwait): See next.
+ * private.c (ptw32_sem_timedwait): Move to semaphore.c
+ and rename as sem_timedwait().
+
+2002-01-18 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * sync.c (pthread_join): Was getting the exit code from the
+ calling thread rather than the joined thread if
+ defined(__MINGW32__) && !defined(__MSVCRT__).
+
+2002-01-15 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.h: Unless the build explicitly defines __CLEANUP_SEH,
+ __CLEANUP_CXX, or __CLEANUP_C, then the build defaults to
+ __CLEANUP_C style cleanup. This style uses setjmp/longjmp
+ in the cancelation and thread exit implementations and therefore
+ won't do stack unwinding if linked to applications that have it
+ (e.g. C++ apps). This is currently consistent with most/all
+ commercial Unix POSIX threads implementations.
+
+ * spin.c (pthread_spin_init): Edit renamed function call.
+ * nonportable.c (pthread_num_processors_np): New.
+ (pthread_getprocessors_np): Renamed to ptw32_getprocessors
+ and moved to private.c.
+ * private.c (pthread_getprocessors): Moved here from
+ nonportable.c.
+ * pthread.def (pthread_getprocessors_np): Removed
+ from export list.
+
+ * rwlock.c (pthread_rwlockattr_init): New.
+ (pthread_rwlockattr_destroy): New.
+ (pthread_rwlockattr_getpshared): New.
+ (pthread_rwlockattr_setpshared): New.
+
+2002-01-14 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * attr.c (pthread_attr_setscope): Fix struct pointer
+ indirection error introduced 2002-01-04.
+ (pthread_attr_getscope): Likewise.
+
+2002-01-12 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.dsp (SOURCE): Add missing source files.
+
+2002-01-08 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * mutex.c (pthread_mutex_trylock): use
+ ptw32_interlocked_compare_exchange function pointer
+ rather than ptw32_InterlockedCompareExchange() directly
+ to retain portability to non-iX86 processors,
+ e.g. WinCE etc. The pointer will point to the native
+ OS version of InterlockedCompareExchange() if the
+ OS supports it (see ChangeLog entry of 2001-10-17).
+
+2002-01-07 Thomas Pfaff <tpfaff at gmx.net>, Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * mutex.c (pthread_mutex_init): Remove critical
+ section calls.
+ (pthread_mutex_destroy): Likewise.
+ (pthread_mutex_unlock): Likewise.
+ (pthread_mutex_trylock): Likewise; uses
+ ptw32_InterlockedCompareExchange() to avoid need for
+ critical section; library is no longer i386 compatible;
+ recursive mutexes now increment the lock count rather
+ than return EBUSY; errorcheck mutexes return EDEADLCK
+ rather than EBUSY. This behaviour is consistent with the
+ Solaris pthreads implementation.
+ * implement.h (pthread_mutex_t_): Remove critical
+ section element - no longer needed.
+
+
+2002-01-04 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * attr.c (pthread_attr_setscope): Add more error
+ checking and actually store the scope value even
+ though it's not really necessary.
+ (pthread_attr_getscope): Return stored value.
+ * implement.h (pthread_attr_t_): Add new scope element.
+ * ANNOUNCE: Fix out of date comment next to
+ pthread_attr_setscope in conformance section.
+
+2001-12-21 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * mutex.c (pthread_mutex_lock): Decrementing lock_idx was
+ not thread-safe.
+ (pthread_mutex_trylock): Likewise.
+
+2001-10-26 prionx@juno.com
+
+ * semaphore.c (sem_init): Fix typo and missing bracket
+ in conditionally compiled code. Only older versions of
+ WinCE require this code, hence it doesn't normally get
+ tested; somehow when sem_t reverted to an opaque struct
+ the calloc NULL check was left in the conditionally included
+ section.
+ (sem_destroy): Likewise, the calloced sem_t wasn't being freed.
+
+2001-10-25 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * GNUmakefile (libwsock32): Add to linker flags for
+ WSAGetLastError() and WSASetLastError().
+ * Makefile (wsock32.lib): Likewise.
+ * create.c: Minor mostly inert changes.
+ * implement.h (PTW32_MAX): Move into here and renamed
+ from sched.h.
+ (PTW32_MIN): Likewise.
+ * GNUmakefile (TEST_ICE): Define if testing internal
+ implementation of InterlockedCompareExchange.
+ * Makefile (TEST_ICE): Likewise.
+ * private.c (TEST_ICE): Likewise.
+
+2001-10-24 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * attr.c (pthread_attr_setstacksize): Quell warning
+ from LCC by conditionally compiling the stacksize
+ validity check. LCC correctly warns that the condition
+ (stacksize < PTHREAD_STACK_MIN) is suspicious
+ because STACK_MIN is 0 and stacksize is of type
+ size_t (or unsigned int).
+
+2001-10-17 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * barrier.c: Move _LONG and _LPLONG defines into
+ implement.h; rename to PTW32_INTERLOCKED_LONG and
+ PTW32_INTERLOCKED_LPLONG respectively.
+ * spin.c: Likewise; ptw32_interlocked_compare_exchange used
+ in place of InterlockedCompareExchange directly.
+ * global.c (ptw32_interlocked_compare_exchange): Add
+ prototype for this new routine pointer to be used when
+ InterlockedCompareExchange isn't supported by Windows.
+ * nonportable.c (pthread_win32_process_attach_np): Check for
+ support of InterlockedCompareExchange in kernel32 and assign its
+ address to ptw32_interlocked_compare_exchange if it exists, or
+ our own ix86 specific implementation ptw32_InterlockedCompareExchange.
+ *private.c (ptw32_InterlockedCompareExchange): An
+ implementation of InterlockedCompareExchange() which is
+ specific to ix86; written directly in assembler for either
+ MSVC or GNU C; needed because Windows 95 doesn't support
+ InterlockedCompareExchange().
+
+ * sched.c (sched_get_priority_min): Extend to return
+ THREAD_PRIORITY_IDLE.
+ (sched_get_priority_max): Extend to return
+ THREAD_PRIORITY_CRITICAL.
+
+2001-10-15 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * spin.c (pthread_spin_lock): PTHREAD_SPINLOCK_INITIALIZER
+ was causing a program fault.
+ (pthread_spin_init): Could have alloced memory
+ without freeing under some error conditions.
+
+ * mutex.c (pthread_mutex_init): Move memory
+ allocation of mutex struct after checking for
+ PROCESS_SHARED.
+
+2001-10-12 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * spin.c (pthread_spin_unlock): Was not returning
+ EPERM if the spinlock was not locked, for multi CPU
+ machines.
+
+2001-10-08 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * spin.c (pthread_spin_trylock): Was not returning
+ EBUSY for multi CPU machines.
+
+2001-08-24 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * condvar.c (pthread_cond_destroy): Remove cv element
+ that is no longer used.
+ * implement.h: Likewise.
+
+2001-08-23 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * condvar.c (pthread_cond_destroy): fix bug with
+ respect to deadlock in the case of concurrent
+ _destroy/_unblock; a condition variable can be destroyed
+ immediately after all the threads that are blocked on
+ it are awakened.
+
+2001-08-23 Phil Frisbie, Jr. <phil at hawksoft.com>
+
+ * tsd.c (pthread_getspecific): Preserve the last
+ winsock error [from WSAGetLastError()].
+
+2001-07-18 Scott McCaskill <scott at magruder.org>
+
+ * mutex.c (pthread_mutexattr_init): Return ENOMEM
+ immediately and don't dereference the NULL pointer
+ if calloc fails.
+ (pthread_mutexattr_getpshared): Don't dereference
+ a pointer that is possibly NULL.
+ * barrier.c (pthread_barrierattr_init): Likewise
+ (pthread_barrierattr_getpshared): Don't dereference
+ a pointer that is possibly NULL.
+ * condvar.c (pthread_condattr_getpshared): Don't dereference
+ a pointer that is possibly NULL.
+
+2001-07-15 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * rwlock.c (pthread_rwlock_wrlock): Is allowed to be
+ a cancelation point; re-enable deferred cancelability
+ around the CV call.
+
+2001-07-10 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * barrier.c: Still more revamping. The exclusive access
+ mutex isn't really needed so it has been removed and replaced
+ by an InterlockedDecrement(). nSerial has been removed.
+ iStep is now dual-purpose. The process shared attribute
+ is now stored in the barrier struct.
+ * implement.h (pthread_barrier_t_): Lost some/gained one
+ elements.
+ * private.c (ptw32_threadStart): Removed some comments.
+
+2001-07-10 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * barrier.c: Revamped to fix the race condition. Two alternating
+ semaphores are used instead of the PulseEvent. Also improved
+ overall throughput by returning PTHREAD_BARRIER_SERIAL_THREAD
+ to the first waking thread.
+ * implement.h (pthread_barrier_t_): Revamped.
+
+2001-07-09 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * barrier.c: Fix several bugs in all routines. Now passes
+ tests/barrier5.c which is fairly rigorous. There is still
+ a non-optimal work-around for a race condition between
+ the barrier breeched event signal and event wait. Basically
+ the last (signalling) thread to hit the barrier yields
+ to allow any other threads, which may have lost the race,
+ to complete.
+
+2001-07-07 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * barrier.c: Changed synchronisation mechanism to a
+ Win32 manual reset Event and use PulseEvent to signal
+ waiting threads. If the implementation continued to use
+ a semaphore it would require a second semaphore and
+ some management to use them alternately as barriers. A
+ single semaphore allows threads to cascade from one barrier
+ through the next, leaving some threads blocked at the first.
+ * implement.h (pthread_barrier_t_): As per above.
+ * general: Made a number of other routines inlinable.
+
+2001-07-07 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * spin.c: Revamped and working; included static initialiser.
+ Now beta level.
+ * barrier.c: Likewise.
+ * condvar.c: Macro constant change; inline auto init routine.
+ * mutex.c: Likewise.
+ * rwlock.c: Likewise.
+ * private.c: Add support for spinlock initialiser.
+ * global.c: Likewise.
+ * implement.h: Likewise.
+ * pthread.h (PTHREAD_SPINLOCK_INITIALIZER): Fix typo.
+
+2001-07-05 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * barrier.c: Remove static initialisation - irrelevent
+ for this object.
+ * pthread.h (PTHREAD_BARRIER_INITIALIZER): Removed.
+ * rwlock.c (pthread_rwlock_wrlock): This routine is
+ not a cancelation point - disable deferred
+ cancelation around call to pthread_cond_wait().
+
+2001-07-05 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * spin.c: New module implementing spin locks.
+ * barrier.c: New module implementing barriers.
+ * pthread.h (_POSIX_SPIN_LOCKS): defined.
+ (_POSIX_BARRIERS): Defined.
+ (pthread_spin_*): Defined.
+ (pthread_barrier*): Defined.
+ (PTHREAD_BARRIER_SERIAL_THREAD): Defined.
+ * implement.h (pthread_spinlock_t_): Defined.
+ (pthread_barrier_t_): Defined.
+ (pthread_barrierattr_t_): Defined.
+
+ * mutex.c (pthread_mutex_lock): Return with the error
+ if an auto-initialiser initialisation fails.
+
+ * nonportable.c (pthread_getprocessors_np): New; gets the
+ number of available processors for the current process.
+
+2001-07-03 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * pthread.h (_POSIX_READER_WRITER_LOCKS): Define it
+ if not already defined.
+
+2001-07-01 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * condvar.c: Fixed lost signal bug reported by Timur Aydin
+ (taydin@snet.net).
+ [RPJ (me) didn't translate the original algorithm
+ correctly.]
+ * semaphore.c: Added sem_post_multiple; this is a useful
+ routine, but it doesn't appear to be standard. For now it's
+ not an exported function.
+
+2001-06-25 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * create.c (pthread_create): Add priority inheritance
+ attributes.
+ * mutex.c (pthread_mutex_lock): Remove some overhead for
+ PTHREAD_MUTEX_NORMAL mutex types. Specifically, avoid
+ calling pthread_self() and pthread_equal() to check/set
+ the mutex owner. Introduce a new pseudo owner for this
+ type. Test results suggest increases in speed of up to
+ 90% for non-blocking locks.
+ This is the default type of mutex used internally by other
+ synchronising objects, ie. condition variables and
+ read-write locks. The test rwlock7.c shows about a
+ 30-35% speed increase over snapshot 2001-06-06. The
+ price of this is that the application developer
+ must ensure correct behaviour, or explicitly set the
+ mutex to a safer type such as PTHREAD_MUTEX_ERRORCHECK.
+ For example, PTHREAD_MUTEX_NORMAL (or PTHREAD_MUTEX_DEFAULT)
+ type mutexes will not return an error if a thread which is not
+ the owner calls pthread_mutex_unlock. The call will succeed
+ in unlocking the mutex if it is currently locked, but a
+ subsequent unlock by the true owner will then fail with EPERM.
+ This is however consistent with some other implementations.
+ (pthread_mutex_unlock): Likewise.
+ (pthread_mutex_trylock): Likewise.
+ (pthread_mutex_destroy): Likewise.
+ * attr.c (pthread_attr_init): PTHREAD_EXPLICIT_SCHED is the
+ default inheritance attribute; THREAD_PRIORITY_NORMAL is
+ the default priority for new threads.
+ * sched.c (pthread_attr_setschedpolicy): Added routine.
+ (pthread_attr_getschedpolicy): Added routine.
+ (pthread_attr_setinheritsched): Added routine.
+ (pthread_attr_getinheritsched): Added routine.
+ * pthread.h (sched_rr_set_interval): Added as a macro;
+ returns -1 with errno set to ENOSYS.
+
+2001-06-23 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ *sched.c (pthread_attr_setschedparam): Add priority range
+ check.
+ (sched_setscheduler): New function; checks for a valid
+ pid and policy; checks for permission to set information
+ in the target process; expects pid to be a Win32 process ID,
+ not a process handle; the only scheduler policy allowed is
+ SCHED_OTHER.
+ (sched_getscheduler): Likewise, but checks for permission
+ to query.
+ * pthread.h (SCHED_*): Moved to sched.h as defined in the
+ POSIX standard.
+ * sched.h (SCHED_*): Moved from pthread.h.
+ (pid_t): Defined if necessary.
+ (sched_setscheduler): Defined.
+ (sched_getscheduler): Defined.
+ * pthread.def (sched_setscheduler): Exported.
+ (sched_getscheduler): Likewise.
+
+2001-06-23 Ralf Brese <Ralf.Brese at pdb4.siemens.de>
+
+ * create.c (pthread_create): Set thread priority from
+ thread attributes.
+
+2001-06-18 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * Made organisational-only changes to UWIN additions.
+ * dll.c (dllMain): Moved UWIN process attach code
+ to pthread_win32_process_attach_np(); moved
+ instance of pthread_count to global.c.
+ * global.c (pthread_count): Moved from dll.c.
+ * nonportable.c (pthread_win32_process_attach_np):
+ Moved _UWIN code to here from dll.c.
+ * implement.h (pthread_count): Define extern int.
+ * create.c (pthread_count): Remove extern int.
+ * private.c (pthread_count): Likewise.
+ * exit.c (pthread_count): Likewise.
+
+2001-06-18 David Korn <dgk at research.att.com>
+
+ * dll.c: Added changes necessary to work with UWIN.
+ * create.c: Likewise.
+ * pthread.h: Likewise.
+ * misc.c: Likewise.
+ * exit.c: Likewise.
+ * private.c: Likewise.
+ * implement.h: Likewise.
+ There is some room at the start of struct pthread_t_
+ to implement the signal semantics in UWIN's posix.dll
+ although this is not yet complete.
+ * Nmakefile: Compatible with UWIN's Nmake utility.
+ * Nmakefile.tests: Likewise - for running the tests.
+
+2001-06-08 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * semaphore.h (sem_t): Fixed for compile and test.
+ * implement.h (sem_t_): Likewise.
+ * semaphore.c: Likewise.
+ * private.c (ptw32_sem_timedwait): Updated to use new
+ opaque sem_t.
+
+2001-06-06 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * semaphore.h (sem_t): Is now an opaque pointer;
+ moved actual definition to implement.h.
+ * implement.h (sem_t_): Move here from semaphore.h;
+ was the definition of sem_t.
+ * semaphore.c: Wherever necessary, changed use of sem
+ from that of a pointer to a pointer-pointer; added
+ extra checks for a valid sem_t; NULL sem_t when
+ it is destroyed; added extra checks when creating
+ and destroying sem_t elements in the NEED_SEM
+ code branches; changed from using a pthread_mutex_t
+ ((*sem)->mutex) to CRITICAL_SECTION ((*sem)->sem_lock_cs)
+ in NEED_SEM branches for access serialisation.
+
+2001-06-06 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * mutex.c (pthread_mutexattr_init): Remove
+ ptw32_mutex_default_kind.
+
+2001-06-05 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * nonportable.c (pthread_mutex_setdefaultkind_np):
+ Remove - should not have been included in the first place.
+ (pthread_mutex_getdefaultkind_np): Likewise.
+ * global.c (ptw32_mutex_default_kind): Likewise.
+ * mutex.c (pthread_mutex_init): Remove use of
+ ptw32_mutex_default_kind.
+ * pthread.h (pthread_mutex_setdefaultkind_np): Likewise.
+ (pthread_mutex_getdefaultkind_np): Likewise.
+ * pthread.def (pthread_mutexattr_setkind_np): Added.
+ (pthread_mutexattr_getkind_np): Likewise.
+
+ * README: Many changes that should have gone in before
+ the last snapshot.
+ * README.NONPORTABLE: New - referred to by ANNOUNCE
+ but never created; documents the non-portable routines
+ included in the library - moved from README with new
+ routines added.
+ * ANNOUNCE (pthread_mutexattr_setkind_np): Added to
+ compliance list.
+ (pthread_mutexattr_getkind_np): Likewise.
+
+2001-06-04 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * condvar.c: Add original description of the algorithm as
+ developed by Terekhov and Thomas, plus reference to
+ README.CV.
+
+2001-06-03 Alexander Terekhov <TEREKHOV at de.ibm.com>, Louis Thomas <lthomas at arbitrade.com>
+
+ * condvar.c (pthread_cond_init): Completely revamped.
+ (pthread_cond_destroy): Likewise.
+ (ptw32_cond_wait_cleanup): Likewise.
+ (ptw32_cond_timedwait): Likewise.
+ (ptw32_cond_unblock): New general signaling routine.
+ (pthread_cond_signal): Now calls ptw32_cond_unblock.
+ (pthread_cond_broadcast): Likewise.
+ * implement.h (pthread_cond_t_): Revamped.
+ * README.CV: New; explanation of the above changes.
+
+2001-05-30 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * pthread.h (rand_r): Fake using _seed argument to quell
+ compiler warning (compiler should optimise this away later).
+
+ * GNUmakefile (OPT): Leave symbolic information out of the library
+ and increase optimisation level - for smaller faster prebuilt
+ dlls.
+
+2001-05-29 Milan Gardian <Milan.Gardian at LEIBINGER.com>
+
+ * Makefile: fix typo.
+ * pthreads.h: Fix problems with stdcall/cdecl conventions, in particular
+ remove the need for PT_STDCALL everywhere; remove warning supression.
+ * (errno): Fix the longstanding "inconsistent dll linkage" problem
+ with errno; now also works with /MD debugging libs -
+ warnings emerged when compiling pthreads library with /MD (or /MDd)
+ compiler switch, instead of /MT (or /MTd) (i.e. when compiling pthreads
+ using Multithreaded DLL CRT instead of Multithreaded statically linked
+ CRT).
+ * create.c (pthread_create): Likewise; fix typo.
+ * private.c (ptw32_threadStart): Eliminate use of terminate() which doesn't
+ throw exceptions.
+ * Remove unnecessary #includes from a number of modules -
+ [I had to #include malloc.h in implement.h for gcc - rpj].
+
+2001-05-29 Thomas Pfaff <tpfaff at gmx.net>
+
+ * pthread.h (PTHREAD_MUTEX_DEFAULT): New; equivalent to
+ PTHREAD_MUTEX_DEFAULT_NP.
+ * (PTHREAD_MUTEX_NORMAL): Similarly.
+ * (PTHREAD_MUTEX_ERRORCHECK): Similarly.
+ * (PTHREAD_MUTEX_RECURSIVE): Similarly.
+ * (pthread_mutex_setdefaultkind_np): New; Linux compatibility stub
+ for pthread_mutexattr_settype.
+ * (pthread_mutexattr_getkind_np): New; Linux compatibility stub
+ for pthread_mutexattr_gettype.
+ * mutex.c (pthread_mutexattr_settype): New; allow
+ the following types of mutex:
+ PTHREAD_MUTEX_DEFAULT_NP
+ PTHREAD_MUTEX_NORMAL_NP
+ PTHREAD_MUTEX_ERRORCHECK_NP
+ PTHREAD_MUTEX_RECURSIVE_NP
+ * Note that PTHREAD_MUTEX_DEFAULT is equivalent to
+ PTHREAD_MUTEX_NORMAL - ie. mutexes should no longer
+ be recursive by default, and a thread will deadlock if it
+ tries to relock a mutex it already owns. This is inline with
+ other pthreads implementations.
+ * (pthread_mutex_lock): Process the lock request
+ according to the mutex type.
+ * (pthread_mutex_init): Eliminate use of Win32 mutexes as the
+ basis of POSIX mutexes - instead, a combination of one critical section
+ and one semaphore are used in conjunction with Win32 Interlocked* routines.
+ * (pthread_mutex_destroy): Likewise.
+ * (pthread_mutex_lock): Likewise.
+ * (pthread_mutex_trylock): Likewise.
+ * (pthread_mutex_unlock): Likewise.
+ * Use longjmp/setjmp to implement cancelation when building the library
+ using a C compiler which doesn't support exceptions, e.g. gcc -x c (note
+ that gcc -x c++ uses exceptions).
+ * Also fixed some of the same typos and eliminated PT_STDCALL as
+ Milan Gardian's patches above.
+
+2001-02-07 Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+ * rwlock.c: Revamped.
+ * implement.h (pthread_rwlock_t_): Redefined.
+ This implementation does not have reader/writer starvation problem.
+ Rwlock attempts to behave more like a normal mutex with
+ races and scheduling policy determining who is more important;
+ It also supports recursive locking,
+ has less synchronization overhead (no broadcasts at all,
+ readers are not blocked on any condition variable) and seem to
+ be faster than the current implementation [W98 appears to be
+ approximately 15 percent faster at least - on top of speed increase
+ from Thomas Pfaff's changes to mutex.c - rpj].
+
+2000-12-29 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * Makefile: Back-out "for" loops which don't work.
+
+ * GNUmakefile: Remove the fake.a target; add the "realclean"
+ target; don't remove built libs under the "clean" target.
+
+ * config.h: Add a guard against multiple inclusion.
+
+ * semaphore.h: Add some defines from config.h to make
+ semaphore.h independent of config.h when building apps.
+
+ * pthread.h (_errno): Back-out previous fix until we know how to
+ fix it properly.
+
+ * implement.h (lockCount): Add missing element to pthread_mutex_t_.
+
+ * sync.c (pthread_join): Spelling fix in comment.
+
+ * private.c (ptw32_threadStart): Reset original termination
+ function (C++).
+ (ptw32_threadStart): Cleanup detached threads early in case
+ the library is statically linked.
+ (ptw32_callUserDestroyRoutines): Remove [SEH] __try block from
+ destructor call so that unhandled exceptions will be passed through
+ to the system; call terminate() from [C++] try block for the same
+ reason.
+
+ * tsd.c (pthread_getspecific): Add comment.
+
+ * mutex.c (pthread_mutex_init): Initialise new elements in
+ pthread_mutex_t.
+ (pthread_mutex_unlock): Invert "pthread_equal()" test.
+
+2000-12-28 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * semaphore.c (mode_t): Use ifndef HAVE_MODE_T to include definition.
+
+ * config.h.in (HAVE_MODE_T): Added.
+ (_UWIN): Start adding defines for the UWIN package.
+
+ * private.c (ptw32_threadStart): Unhandled exceptions are
+ now passed through to the system to deal with. This is consistent
+ with normal Windows behaviour. C++ applications may use
+ set_terminate() to override the default behaviour which is
+ to call ptw32_terminate(). Ptw32_terminate() cleans up some
+ POSIX thread stuff before calling the system default function
+ which calls abort(). The users termination function should conform
+ to standard C++ semantics which is to not return. It should
+ exit the thread (call pthread_exit()) or exit the application.
+ * private.c (ptw32_terminate): Added as the default set_terminate()
+ function. It calls the system default function after cleaning up
+ some POSIX thread stuff.
+
+ * implement.h (ptw32_try_enter_critical_section): Move
+ declaration.
+ * global.c (ptw32_try_enter_critical_section): Moved
+ from dll.c.
+ * dll.c: Move process and thread attach/detach code into
+ functions in nonportable.c.
+ * nonportable.c (pthread_win32_process_attach_np): Process
+ attach code from dll.c is now available to static linked
+ applications.
+ * nonportable.c (pthread_win32_process_detach_np): Likewise.
+ * nonportable.c (pthread_win32_thread_attach_np): Likewise.
+ * nonportable.c (pthread_win32_thread_detach_np): Likewise.
+
+ * pthread.h: Add new non-portable prototypes for static
+ linked applications.
+
+ * GNUmakefile (OPT): Increase optimisation flag and remove
+ debug info flag.
+
+ * pthread.def: Add new non-portable exports for static
+ linked applications.
+
+2000-12-11 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * FAQ: Update Answer 6 re getting a fully working
+ Mingw32 built library.
+
+2000-10-10 Steven Reddie <smr at essemer.com.au>
+
+ * misc.c (pthread_self): Restore Win32 "last error"
+ cleared by TlsGetValue() call in
+ pthread_getspecific()
+
+2000-09-20 Arthur Kantor <akantor at bexusa.com>
+
+ * mutex.c (pthread_mutex_lock): Record the owner
+ of the mutex. This requires also keeping count of
+ recursive locks ourselves rather than leaving it
+ to Win32 since we need to know when to NULL the
+ thread owner when the mutex is unlocked.
+ (pthread_mutex_trylock): Likewise.
+ (pthread_mutex_unlock): Check that the calling
+ thread owns the mutex, decrement the recursive
+ lock count, and NULL the owner if zero. Return
+ EPERM if the mutex is owned by another thread.
+ * implement.h (pthread_mutex_t_): Add ownerThread
+ and lockCount members.
+
+2000-09-13 Jef Gearhart <jgearhart at tpssys.com>
+
+ * mutex.c (pthread_mutex_init): Call
+ TryEnterCriticalSection through the pointer
+ rather than directly so that the dll can load
+ on Windows versions that can't resolve the
+ function, eg. Windows 95
+
+2000-09-09 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.h (ctime_r): Fix arg.
+
+2000-09-08 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * GNUmakefile(_WIN32_WINNT=0x400): Define in CFLAGS;
+ doesn't seem to be needed though.
+
+ * cancel.c (pthread_cancel): Must get "self" through
+ calling pthread_self() which will ensure a POSIX thread
+ struct is built for non-POSIX threads; return an error
+ if this fails
+ - Ollie Leahy <ollie at mpt.ie>
+ (pthread_setcancelstate): Likewise.
+ (pthread_setcanceltype): Likewise.
+ * misc.c (ptw32_cancelable_wait): Likewise.
+
+ * private.c (ptw32_tkAssocCreate): Remove unused #if 0
+ wrapped code.
+
+ * pthread.h (ptw32_get_exception_services_code):
+ Needed to be forward declared unconditionally.
+
+2000-09-06 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * cancel.c (pthread_cancel): If called from the main
+ thread "self" would be NULL; get "self" via pthread_self()
+ instead of directly from TLS so that an implicit
+ pthread object is created.
+
+ * misc.c (pthread_equal): Strengthen test for NULLs.
+
+2000-09-02 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * condvar.c (ptw32_cond_wait_cleanup): Ensure that all
+ waking threads check if they are the last, and notify
+ the broadcaster if so - even if an error occurs in the
+ waiter.
+
+ * semaphore.c (_decrease_semaphore): Should be
+ a call to ptw32_decrease_semaphore.
+ (_increase_semaphore): Should be a call to
+ ptw32_increase_semaphore.
+
+ * misc.c (ptw32_cancelable_wait): Renamed from
+ CancelableWait.
+ * rwlock.c (_rwlock_check*): Renamed to
+ ptw32_rwlock_check*.
+ * mutex.c (_mutex_check*): Renamed to ptw32_mutex_check*.
+ * condvar.c (cond_timed*): Renamed to ptw32_cond_timed*.
+ (_cond_check*): Renamed to ptw32_cond_check*.
+ (cond_wait_cleanup*): Rename to ptw32_cond_wait_cleanup*.
+ (ptw32_cond_timedwait): Add comments.
+
+2000-08-22 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * private.c (ptw32_throw): Fix exception test;
+ move exceptionInformation declaration.
+
+ * tsd.c (pthread_key_create): newkey wrongly declared.
+
+ * pthread.h: Fix comment block.
+
+2000-08-18 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * mutex.c (pthread_mutex_destroy): Check that the mutex isn't
+ held; invalidate the mutex as early as possible to avoid
+ contention; not perfect - FIXME!
+
+ * rwlock.c (pthread_rwlock_init): Remove redundant assignment
+ to "rw".
+ (pthread_rwlock_destroy): Invalidate the rwlock before
+ freeing up any of it's resources - to avoid contention.
+
+ * private.c (ptw32_tkAssocCreate): Change assoc->lock
+ to use a dynamically initialised mutex - only consumes
+ a W32 mutex or critical section when first used,
+ not before.
+
+ * mutex.c (pthread_mutex_init): Remove redundant assignment
+ to "mx".
+ (pthread_mutexattr_destroy): Set attribute to NULL
+ before freeing it's memory - to avoid contention.
+
+ * implement.h (PTW32_EPS_CANCEL/PTW32_EPS_EXIT):
+ Must be defined for all compilers - used as generic
+ exception selectors by ptw32_throw().
+
+ * Several: Fix typos from scripted edit session
+ yesterday.
+
+ * nonportable.c (pthread_mutexattr_setforcecs_np):
+ Moved this function from mutex.c.
+ (pthread_getw32threadhandle_np): New function to
+ return the win32 thread handle that the POSIX
+ thread is using.
+ * mutex.c (pthread_mutexattr_setforcecs_np):
+ Moved to new file "nonportable.c".
+
+ * pthread.h (PTW32_BUILD): Only redefine __except
+ and catch compiler keywords if we aren't building
+ the library (ie. PTW32_BUILD is not defined) -
+ this is safer than defining and then undefining
+ if not building the library.
+ * implement.h: Remove __except and catch undefines.
+ * Makefile (CFLAGS): Define PTW32_BUILD.
+ * GNUmakefile (CFLAGS): Define PTW32_BUILD.
+
+ * All appropriate: Change Pthread_exception* to
+ ptw32_exception* to be consistent with internal
+ identifier naming.
+
+ * private.c (ptw32_throw): New function to provide
+ a generic exception throw for all internal
+ exceptions and EH schemes.
+ (ptw32_threadStart): pthread_exit() value is now
+ returned via the thread structure exitStatus
+ element.
+ * exit.c (pthread_exit): pthread_exit() value is now
+ returned via the thread structure exitStatus
+ element.
+ * cancel.c (ptw32_cancel_self): Now uses ptw32_throw.
+ (pthread_setcancelstate): Ditto.
+ (pthread_setcanceltype): Ditto.
+ (pthread_testcancel): Ditto.
+ (pthread_cancel): Ditto.
+ * misc.c (CancelableWait): Ditto.
+ * exit.c (pthread_exit): Ditto.
+ * All applicable: Change PTW32_ prefix to
+ PTW32_ prefix to remove leading underscores
+ from private library identifiers.
+
+2000-08-17 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * All applicable: Change _pthread_ prefix to
+ ptw32_ prefix to remove leading underscores
+ from private library identifiers (single
+ and double leading underscores are reserved in the
+ ANSI C standard for compiler implementations).
+
+ * tsd.c (pthread_create_key): Initialise temporary
+ key before returning it's address to avoid race
+ conditions.
+
+2000-08-13 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * errno.c: Add _MD precompile condition; thus far
+ had no effect when using /MD compile option but I
+ thnk it should be there.
+
+ * exit.c: Add __cplusplus to various #if lines;
+ was compiling SEH code even when VC++ had
+ C++ compile options.
+
+ * private.c: ditto.
+
+ * create.c (pthread_create): Add PT_STDCALL macro to
+ function pointer arg in _beginthread().
+
+ * pthread.h: PT_STDCALL really does need to be defined
+ in both this and impliment.h; don't set it to __cdecl
+ - this macro is only used to extend function pointer
+ casting for functions that will be passed as parameters.
+ (~PThreadCleanup): add cast and group expression.
+ (_errno): Add _MD compile conditional.
+ (PtW32NoCatchWarn): Change pragma message.
+
+ * implement.h: Move and change PT_STDCALL define.
+
+ * need_errno.h: Add _MD to compilation conditional.
+
+ * GNUmakefile: Substantial rewrite for new naming
+ convention; set for nil optimisation (turn it up
+ when we have a working library build; add target
+ "fake.a" to build a libpthreadw32.a from the VC++
+ built DLL pthreadVCE.dll.
+
+ * pthread.def (LIBRARY): Don't specify in the .def
+ file - it is specified on the linker command line
+ since we now use the same .def file for variously
+ named .dlls.
+
+ * Makefile: Substantial rewrite for new naming
+ convention; default nmake target only issues a
+ help message; run nmake with specific target
+ corresponding to the EH scheme being used.
+
+ * README: Update information; add naming convention
+ explanation.
+
+ * ANNOUNCE: Update information.
+
+2000-08-12 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.h: Add compile-time message when using
+ MSC_VER compiler and C++ EH to warn application
+ programmers to use PtW32Catch instead of catch(...)
+ if they want cancelation and pthread_exit to work.
+
+ * implement.h: Remove #include <semaphore.h>; we
+ use our own local semaphore.h.
+
+2000-08-10 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * cleanup.c (pthread_pop_cleanup): Remove _pthread
+ prefix from __except and catch keywords; implement.h
+ now simply undefines ptw32__except and
+ ptw32_catch if defined; VC++ was not textually
+ substituting ptw32_catch etc back to catch as
+ it was redefined; the reason for using the prefixed
+ version was to make it clear that it was not using
+ the pthread.h redefined catch keyword.
+
+ * private.c (ptw32_threadStart): Ditto.
+ (ptw32_callUserDestroyRoutines): Ditto.
+
+ * implement.h (ptw32__except): Remove #define.
+ (ptw32_catch): Remove #define.
+
+ * GNUmakefile (pthread.a): New target to build
+ libpthread32.a from pthread.dll using dlltool.
+
+ * buildlib.bat: Duplicate cl commands with args to
+ build C++ EH version of pthread.dll; use of .bat
+ files is redundant now that nmake compatible
+ Makefile is included; used as a kludge only now.
+
+ * Makefile: Localise some macros and fix up the clean:
+ target to extend it and work properly.
+
+ * CONTRIBUTORS: Add contributors.
+
+ * ANNOUNCE: Updated.
+
+ * README: Updated.
+
+2000-08-06 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.h: Remove #warning - VC++ doesn't accept it.
+
+2000-08-05 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.h (PtW32CatchAll): Add macro. When compiling
+ applications using VC++ with C++ EH rather than SEH
+ 'PtW32CatchAll' must be used in place of any 'catch( ... )'
+ if the application wants pthread cancelation or
+ pthread_exit() to work.
+
+2000-08-03 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * pthread.h: Add a base class ptw32_exception for
+ library internal exceptions and change the "catch"
+ re-define macro to use it.
+
+2000-08-02 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * GNUmakefile (CFLAGS): Add -mthreads.
+ Add new targets to generate cpp and asm output.
+
+ * sync.c (pthread_join): Remove dead code.
+
+2000-07-25 Tristan Savatier <tristan at mpegtv.com>
+
+ * sched.c (sched_get_priority_max): Handle different WinCE and
+ Win32 priority values together.
+ (sched_get_priority_min): Ditto.
+
+2000-07-25 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * create.c (pthread_create): Force new threads to wait until
+ pthread_create has the new thread's handle; we also retain
+ a local copy of the handle for internal use until
+ pthread_create returns.
+
+ * private.c (ptw32_threadStart): Initialise ei[].
+ (ptw32_threadStart): When beginthread is used to start the
+ thread, force waiting until the creator thread had the
+ thread handle.
+
+ * cancel.c (ptw32_cancel_thread): Include context switch
+ code for defined(_X86_) environments in addition to _M_IX86.
+
+ * rwlock.c (pthread_rwlock_destroy): Assignment changed
+ to avoid compiler warning.
+
+ * private.c (ptw32_get_exception_services_code): Cast
+ NULL return value to avoid compiler warning.
+
+ * cleanup.c (pthread_pop_cleanup): Initialise "cleanup" variable
+ to avoid compiler warnings.
+
+ * misc.c (ptw32_new): Change "new" variable to "t" to avoid
+ confusion with the C++ keyword of the same name.
+
+ * condvar.c (cond_wait_cleanup): Initialise lastWaiter variable.
+ (cond_timedwait): Remove unused local variables. to avoid
+ compiler warnings.
+
+ * dll.c (dllMain): Remove 2000-07-21 change - problem
+ appears to be in pthread_create().
+
+2000-07-22 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * tsd.c (pthread_key_create): If a destructor was given
+ and the pthread_mutex_init failed, then would try to
+ reference a NULL pointer (*key); eliminate this section of
+ code by using a dynamically initialised mutex
+ (PTHREAD_MUTEX_INITIALIZER).
+
+ * tsd.c (pthread_setspecific): Return an error if
+ unable to set the value; simplify cryptic conditional.
+
+ * tsd.c (pthread_key_delete): Locking threadsLock relied
+ on mutex_lock returning an error if the key has no destructor.
+ ThreadsLock is only initialised if the key has a destructor.
+ Making this mutex a static could reduce the number of mutexes
+ used by an application since it is actually created only at
+ first use and it's often destroyed soon after.
+
+2000-07-22 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * FAQ: Added Q5 and Q6.
+
+2000-07-21 David Baggett <dmb at itasoftware.com>
+
+ * dll.c: Include resource leakage work-around. This is a
+ partial FIXME which doesn't stop all leakage. The real
+ problem needs to be found and fixed.
+
+2000-07-21 Ross Johnson <rpj at setup1.ise.canberra.edu.au>
+
+ * create.c (pthread_create): Set threadH to 0 (zero)
+ everywhere. Some assignments were using NULL. Maybe
+ it should be NULL everywhere - need to check. (I know
+ they are nearly always the same thing - but not by
+ definition.)
+
+ * misc.c (pthread_self): Try to catch NULL thread handles
+ at the point where they might be generated, even though
+ they should always be valid at this point.
+
+ * tsd.c (pthread_setspecific): return an error value if
+ pthread_self() returns NULL.
+
+ * sync.c (pthread_join): return an error value if
+ pthread_self() returns NULL.
+
+ * signal.c (pthread_sigmask): return an error value if
+ pthread_self() returns NULL.
+
+2000-03-02 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * attr.c (pthread_attr_init): Set default stacksize to zero (0)
+ rather than PTHREAD_STACK_MIN even though these are now the same.
+
+ * pthread.h (PTHREAD_STACK_MIN): Lowered to 0.
+
+2000-01-28 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * mutex.c (pthread_mutex_init): Free mutex if it has been alloced;
+ if critical sections can be used instead of Win32 mutexes, test
+ that the critical section works and return an error if not.
+
+2000-01-07 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * cleanup.c (pthread_pop_cleanup): Include SEH code only if MSC is not
+ compiling as C++.
+ (pthread_push_cleanup): Include SEH code only if MSC is not
+ compiling as C++.
+
+ * pthread.h: Include SEH code only if MSC is not
+ compiling as C++.
+
+ * implement.h: Include SEH code only if MSC is not
+ compiling as C++.
+
+ * cancel.c (ptw32_cancel_thread): Add _M_IX86 check.
+ (pthread_testcancel): Include SEH code only if MSC is not
+ compiling as C++.
+ (ptw32_cancel_self): Include SEH code only if MSC is not
+ compiling as C++.
+
+2000-01-06 Erik Hensema <erik.hensema at group2000.nl>
+
+ * Makefile: Remove inconsistencies in 'cl' args
+
+2000-01-04 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * private.c (ptw32_get_exception_services_code): New; returns
+ value of EXCEPTION_PTW32_SERVICES.
+ (ptw32_processInitialize): Remove initialisation of
+ ptw32_exception_services which is no longer needed.
+
+ * pthread.h (ptw32_exception_services): Remove extern.
+ (ptw32_get_exception_services_code): Add function prototype;
+ use this to return EXCEPTION_PTW32_SERVICES value instead of
+ using the ptw32_exception_services variable which I had
+ trouble exporting through pthread.def.
+
+ * global.c (ptw32_exception_services): Remove declaration.
+
+1999-11-22 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * implement.h: Forward declare ptw32_new();
+
+ * misc.c (ptw32_new): New; alloc and initialise a new pthread_t.
+ (pthread_self): New thread struct is generated by new routine
+ ptw32_new().
+
+ * create.c (pthread_create): New thread struct is generated
+ by new routine ptw32_new().
+
+1999-11-21 Ross Johnson <rpj at special.ise.canberra.edu.au>
+
+ * global.c (ptw32_exception_services): Declare new variable.
+
+ * private.c (ptw32_threadStart): Destroy thread's
+ cancelLock mutex; make 'catch' and '__except' usageimmune to
+ redfinitions in pthread.h.
+ (ptw32_processInitialize): Init new constant ptw32_exception_services.
+
+ * create.c (pthread_create): Initialise thread's cancelLock
+ mutex.
+
+ * cleanup.c (pthread_pop_cleanup): Make 'catch' and '__except'
+ usage immune to redfinition s in pthread.h.
+
+ * private.c: Ditto.
+
+ * pthread.h (catch): Redefine 'catch' so that C++ applications
+ won't catch our internal exceptions.
+ (__except): ditto for __except.
+
+ * implement.h (ptw32_catch): Define internal version
+ of 'catch' because 'catch' is redefined by pthread.h.
+ (__except): ditto for __except.
+ (struct pthread_t_): Add cancelLock mutex for async cancel
+ safety.
+
+1999-11-21 Jason Nye <jnye at nbnet.nb.ca>, Erik Hensema <erik.hensema at group2000.nl>
+
+ * cancel.c (ptw32_cancel_self): New; part of the async
+ cancellation implementation.
+ (ptw32_cancel_thread): Ditto; this function is X86
+ processor specific.
+ (pthread_setcancelstate): Add check for pending async
+ cancel request and cancel the calling thread if
+ required; add async-cancel safety lock.
+ (pthread_setcanceltype): Ditto.
+
+1999-11-13 Erik Hensema <erik.hensema at group2000.nl>
+
+ * configure.in (AC_OUTPUT): Put generated output into GNUmakefile
+ rather than Makefile. Makefile will become the MSC nmake compatible
+ version
+
+1999-11-13 John Bossom (John.Bossom@cognos.com>
+
+ * misc.c (pthread_self): Add a note about GetCurrentThread
+ returning a pseudo-handle
+
+1999-11-10 Todd Owen <towen at lucidcalm.dropbear.id.au>
+
+ * dll.c (dllMain): Free kernel32 ASAP.
+ If TryEnterCriticalSection is not being used, then free
+ the kernel32.dll handle now, rather than leaving it until
+ DLL_PROCESS_DETACH.
+
+ Note: this is not a pedantic exercise in freeing unused
+ resources! It is a work-around for a bug in Windows 95
+ (see microsoft knowledge base article, Q187684) which
+ does Bad Things when FreeLibrary is called within
+ the DLL_PROCESS_DETACH code, in certain situations.
+ Since w95 just happens to be a platform which does not
+ provide TryEnterCriticalSection, the bug will be
+ effortlessly avoided.
+
+1999-11-10 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sync.c (pthread_join): Make it a deferred cancelation point.
+
+ * misc.c (pthread_self): Explicitly initialise implicitly
+ created thread state to default values.
+
+1999-11-05 Tristan Savatier <tristan at mpegtv.com>
+
+ * pthread.h (winsock.h): Include unconditionally.
+ (ETIMEDOUT): Change fallback value to that defined by winsock.h.
+
+ * general: Patched for portability to WinCE. The details are
+ described in the file WinCE-PORT. Follow the instructions
+ in README.WinCE to make the appropriate changes in config.h.
+
+1999-10-30 Erik Hensema <erik.hensema at group2000.nl>
+
+ * create.c (pthread_create): Explicitly initialise thread state to
+ default values.
+
+ * cancel.c (pthread_setcancelstate): Check for NULL 'oldstate'
+ for compatibility with Solaris pthreads;
+ (pthread_setcanceltype): ditto:
+
+1999-10-23 Erik Hensema <erik.hensema at group2000.nl>
+
+ * pthread.h (ctime_r): Fix incorrect argument "_tm"
+
+1999-10-21 Aurelio Medina <aureliom at crt.com>
+
+ * pthread.h (_POSIX_THREADS): Only define it if it isn't
+ already defined. Projects may need to define this on
+ the CC command line under Win32 as it doesn't have unistd.h
+
+1999-10-17 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * rwlock.c (pthread_rwlock_destroy): Add cast to remove compile
+ warning.
+
+ * condvar.c (pthread_cond_broadcast): Only release semaphores
+ if there are waiting threads.
+
+1999-10-15 Lorin Hochstein <lmh at xiphos.ca>, Peter Slacik <Peter.Slacik at tatramed.sk>
+
+ * condvar.c (cond_wait_cleanup): New static cleanup handler for
+ cond_timedwait;
+ (cond_timedwait): pthread_cleanup_push args changed;
+ canceling a thread while it's in pthread_cond_wait
+ will now decrement the waiters count and cleanup if it's the
+ last waiter.
+
+1999-10-15 Graham Dumpleton <Graham.Dumpleton at ra.pad.otc.telstra.com.au>
+
+ * condvar.c (cond_wait_cleanup): the last waiter will now reset the CV's
+ wasBroadcast flag
+
+Thu Sep 16 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * rwlock.c (pthread_rwlock_destroy): Add serialisation.
+ (_rwlock_check_need_init): Check for detroyed rwlock.
+ * rwlock.c: Check return codes from _rwlock_check_need_init();
+ modify comments; serialise access to rwlock objects during
+ operations; rename rw_mutex to rw_lock.
+ * implement.h: Rename rw_mutex to rw_lock.
+ * mutex.c (pthread_mutex_destroy): Add serialisation.
+ (_mutex_check_need_init): Check for detroyed mutex.
+ * condvar.c (pthread_cond_destroy): Add serialisation.
+ (_cond_check_need_init): Check for detroyed condvar.
+ * mutex.c: Modify comments.
+ * condvar.c: Modify comments.
+
+1999-08-10 Aurelio Medina <aureliom at crt.com>
+
+ * implement.h (pthread_rwlock_t_): Add.
+ * pthread.h (pthread_rwlock_t): Add.
+ (PTHREAD_RWLOCK_INITIALIZER): Add.
+ Add rwlock function prototypes.
+ * rwlock.c: New module.
+ * pthread.def: Add new rwlock functions.
+ * private.c (ptw32_processInitialize): initialise
+ ptw32_rwlock_test_init_lock critical section.
+ * global.c (ptw32_rwlock_test_init_lock): Add.
+
+ * mutex.c (pthread_mutex_destroy): Don't free mutex memory
+ if mutex is PTHREAD_MUTEX_INITIALIZER and has not been
+ initialised yet.
+
+1999-08-08 Milan Gardian <mg at tatramed.sk>
+
+ * mutex.c (pthread_mutex_destroy): Free mutex memory.
+
+1999-08-22 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * exit.c (pthread_exit): Fix reference to potentially
+ uninitialised pointer.
+
+1999-08-21 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_threadStart): Apply fix of 1999-08-19
+ this time to C++ and non-trapped C versions. Ommitted to
+ do this the first time through.
+
+1999-08-19 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_threadStart): Return exit status from
+ the application thread startup routine.
+ - Milan Gardian <mg at tatramed.sk>
+
+1999-08-18 John Bossom <john.Bossom at cognos.com>
+
+ * exit.c (pthread_exit): Put status into pthread_t->exitStatus
+ * private.c (ptw32_threadStart): Set pthread->exitStatus
+ on exit of try{} block.
+ * sync.c (pthread_join): use pthread_exitStatus value if the
+ thread exit doesn't return a value (for Mingw32 CRTDLL
+ which uses endthread instead of _endthreadex).
+
+Tue Aug 17 20:17:58 CDT 1999 Mumit Khan <khan at xraylith.wisc.edu>
+
+ * create.c (pthread_create): Add CRTDLL suppport.
+ * exit.c (pthread_exit): Likewise.
+ * private.c (ptw32_threadStart): Likewise.
+ (ptw32_threadDestroy): Likewise.
+ * sync.c (pthread_join): Likewise.
+ * tests/join1.c (main): Warn about partial support for CRTDLL.
+
+Tue Aug 17 20:00:08 1999 Mumit Khan <khan at xraylith.wisc.edu>
+
+ * Makefile.in (LD): Delete entry point.
+ * acconfig.h (STDCALL): Delete unused macro.
+ * configure.in: Remove test for STDCALL.
+ * config.h.in: Regenerate.
+ * errno.c (_errno): Fix self type.
+ * pthread.h (PT_STDCALL): Move from here to
+ * implement.h (PT_STDCALL): here.
+ (ptw32_threadStart): Fix prototype.
+ * private.c (ptw32_threadStart): Likewise.
+
+1999-08-14 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * exit.c (pthread_exit): Don't call pthread_self() but
+ get thread handle directly from TSD for efficiency.
+
+1999-08-12 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_threadStart): ei[] only declared if _MSC_VER.
+
+ * exit.c (pthread_exit): Check for implicitly created threads
+ to avoid raising an unhandled exception.
+
+1999-07-12 Peter Slacik <Peter.Slacik at tatramed.sk>
+
+ * condvar.c (pthread_cond_destroy): Add critical section.
+ (cond_timedwait): Add critical section; check for timeout
+ waiting on semaphore.
+ (pthread_cond_broadcast): Add critical section.
+
+1999-07-09 Lorin Hochstein <lmh at xiphos.ca>, John Bossom <John.Bossom at Cognos.COM>
+
+ The problem was that cleanup handlers were not executed when
+ pthread_exit() was called.
+
+ * implement.h (pthread_t_): Add exceptionInformation element for
+ C++ per-thread exception information.
+ (general): Define and rename exceptions.
+
+1999-07-09 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * misc.c (CancelableWait): PTW32_EPS_CANCEL (SEH) and
+ ptw32_exception_cancel (C++) used to identify the exception.
+
+ * cancel.c (pthread_testcancel): PTW32_EPS_CANCEL (SEH) and
+ ptw32_exception_cancel (C++) used to identify the exception.
+
+ * exit.c (pthread_exit): throw/raise an exception to return to
+ ptw32_threadStart() to exit the thread. PTW32_EPS_EXIT (SEH)
+ and ptw32_exception_exit (C++) used to identify the exception.
+
+ * private.c (ptw32_threadStart): Add pthread_exit exception trap;
+ clean up and exit the thread directly rather than via pthread_exit().
+
+Sun May 30 00:25:02 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * semaphore.h (mode_t): Conditionally typedef it.
+
+Fri May 28 13:33:05 1999 Mark E. Armstrong <avail at pacbell.net>
+
+ * condvar.c (pthread_cond_broadcast): Fix possible memory fault
+
+Thu May 27 13:08:46 1999 Peter Slacik <Peter.Slacik at tatramed.sk>
+
+ * condvar.c (pthread_cond_broadcast): Fix logic bug
+
+Thu May 27 13:08:46 1999 Bossom, John <John.Bossom at Cognos.COM>
+
+ * condvar.c (pthread_cond_broadcast): optimise sem_post loop
+
+Fri May 14 12:13:18 1999 Mike Russo <miker at eai.com>
+
+ * attr.c (pthread_attr_setdetachstate): Fix logic bug
+
+Sat May 8 09:42:30 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.def (sem_open): Add.
+ (sem_close): Add.
+ (sem_unlink): Add.
+ (sem_getvalue): Add.
+
+ * FAQ (Question 3): Add.
+
+Thu Apr 8 01:16:23 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * semaphore.c (sem_open): New function; returns an error (ENOSYS).
+ (sem_close): ditto.
+ (sem_unlink): ditto.
+ (sem_getvalue): ditto.
+
+ * semaphore.h (_POSIX_SEMAPHORES): define.
+
+Wed Apr 7 14:09:52 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * errno.c (_REENTRANT || _MT): Invert condition.
+
+ * pthread.h (_errno): Conditionally include prototype.
+
+Wed Apr 7 09:37:00 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * *.c (comments): Remove individual attributions - these are
+ documented sufficiently elsewhere.
+
+ * implement.h (pthread.h): Remove extraneous include.
+
+Sun Apr 4 11:05:57 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sched.c (sched.h): Include.
+
+ * sched.h: New file for POSIX 1b scheduling.
+
+ * pthread.h: Move opaque structures to implement.h; move sched_*
+ prototypes out and into sched.h.
+
+ * implement.h: Add opaque structures from pthread.h.
+
+ * sched.c (sched_yield): New function.
+
+ * condvar.c (ptw32_sem_*): Rename to sem_*; except for
+ ptw32_sem_timedwait which is an private function.
+
+Sat Apr 3 23:28:00 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * Makefile.in (OBJS): Add errno.o.
+
+Fri Apr 2 11:08:50 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h (ptw32_sem_*): Remove prototypes now defined in
+ semaphore.h.
+
+ * pthread.h (sempahore.h): Include.
+
+ * semaphore.h: New file for POSIX 1b semaphores.
+
+ * semaphore.c (ptw32_sem_timedwait): Moved to private.c.
+
+ * pthread.h (ptw32_sem_t): Change to sem_t.
+
+ * private.c (ptw32_sem_timedwait): Moved from semaphore.c;
+ set errno on error.
+
+ * pthread.h (pthread_t_): Add per-thread errno element.
+
+Fri Apr 2 11:08:50 1999 John Bossom <jebossom at cognos.com>
+
+ * semaphore.c (ptw32_sem_*): Change to sem_*; these functions
+ will be exported from the library; set errno on error.
+
+ * errno.c (_errno): New file. New function.
+
+Fri Mar 26 14:11:45 1999 Tor Lillqvist <tml at iki.fi>
+
+ * semaphore.c (ptw32_sem_timedwait): Check for negative
+ milliseconds.
+
+Wed Mar 24 11:32:07 1999 John Bossom <jebossom at cognos.com>
+
+ * misc.c (CancelableWait): Initialise exceptionInformation[2].
+ (pthread_self): Get a real Win32 thread handle for implicit threads.
+
+ * cancel.c (pthread_testcancel): Initialise exceptionInformation[2].
+
+ * implement.h (SE_INFORMATION): Fix values.
+
+ * private.c (ptw32_threadDestroy): Close the thread handle.
+
+Fri Mar 19 12:57:27 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cancel.c (comments): Update and cleanup.
+
+Fri Mar 19 09:12:59 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_threadStart): status returns PTHREAD_CANCELED.
+
+ * pthread.h (PTHREAD_CANCELED): defined.
+
+Tue Mar 16 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * all: Add GNU LGPL and Copyright and Warranty.
+
+Mon Mar 15 00:20:13 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * condvar.c (pthread_cond_init): fix possible uninitialised use
+ of cv.
+
+Sun Mar 14 21:01:59 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * condvar.c (pthread_cond_destroy): don't do full cleanup if
+ static initialised cv has never been used.
+ (cond_timedwait): check result of auto-initialisation.
+
+Thu Mar 11 09:01:48 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (pthread_mutex_t): revert to (pthread_mutex_t *);
+ define a value to serve as PTHREAD_MUTEX_INITIALIZER.
+ (pthread_mutex_t_): remove staticinit and valid elements.
+ (pthread_cond_t): revert to (pthread_cond_t_ *);
+ define a value to serve as PTHREAD_COND_INITIALIZER.
+ (pthread_cond_t_): remove staticinit and valid elements.
+
+ * mutex.c (pthread_mutex_t args): adjust indirection of references.
+ (all functions): check for PTHREAD_MUTEX_INITIALIZER value;
+ check for NULL (invalid).
+
+ * condvar.c (pthread_cond_t args): adjust indirection of references.
+ (all functions): check for PTHREAD_COND_INITIALIZER value;
+ check for NULL (invalid).
+
+Wed Mar 10 17:18:12 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * misc.c (CancelableWait): Undo changes from Mar 8 and 7.
+
+Mon Mar 8 11:18:59 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * misc.c (CancelableWait): Ensure cancelEvent handle is the lowest
+ indexed element in the handles array. Enhance test for abandoned
+ objects.
+
+ * pthread.h (PTHREAD_MUTEX_INITIALIZER): Trailing elements not
+ initialised are set to zero by the compiler. This avoids the
+ problem of initialising the opaque critical section element in it.
+ (PTHREAD_COND_INITIALIZER): Ditto.
+
+ * semaphore.c (ptw32_sem_timedwait): Check sem == NULL earlier.
+
+Sun Mar 7 12:31:14 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * condvar.c (pthread_cond_init): set semaphore initial value
+ to 0, not 1. cond_timedwait was returning signaled immediately.
+
+ * misc.c (CancelableWait): Place the cancel event handle first
+ in the handle table for WaitForMultipleObjects. This ensures that
+ the cancel event is recognised and acted apon if both objects
+ happen to be signaled together.
+
+ * private.c (ptw32_cond_test_init_lock): Initialise and destroy.
+
+ * implement.h (ptw32_cond_test_init_lock): Add extern.
+
+ * global.c (ptw32_cond_test_init_lock): Add declaration.
+
+ * condvar.c (pthread_cond_destroy): check for valid initialised CV;
+ flag destroyed CVs as invalid.
+ (pthread_cond_init): pthread_cond_t is no longer just a pointer.
+ This is because PTHREAD_COND_INITIALIZER needs state info to reside
+ in pthread_cond_t so that it can initialise on first use. Will work on
+ making pthread_cond_t (and other objects like it) opaque again, if
+ possible, later.
+ (cond_timedwait): add check for statically initialisation of
+ CV; initialise on first use.
+ (pthread_cond_signal): check for valid CV.
+ (pthread_cond_broadcast): check for valid CV.
+ (_cond_check_need_init): Add.
+
+ * pthread.h (PTHREAD_COND_INITIALIZER): Fix.
+ (pthread_cond_t): no longer a pointer to pthread_cond_t_.
+ (pthread_cond_t_): add 'staticinit' and 'valid' elements.
+
+Sat Mar 6 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Undate comments.
+
+Sun Feb 21 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (PTHREAD_MUTEX_INITIALIZER): missing braces around
+ cs element initialiser.
+
+1999-02-21 Ben Elliston <bje at cygnus.com>
+
+ * pthread.h (pthread_exit): The return type of this function is
+ void, not int.
+
+ * exit.c (pthread_exit): Do not return 0.
+
+Sat Feb 20 16:03:30 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * dll.c (DLLMain): Expand TryEnterCriticalSection support test.
+
+ * mutex.c (pthread_mutex_trylock): The check for
+ ptw32_try_enter_critical_section == NULL should have been
+ removed long ago.
+
+Fri Feb 19 16:03:30 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sync.c (pthread_join): Fix pthread_equal() test.
+
+ * mutex.c (pthread_mutex_trylock): Check mutex != NULL before
+ using it.
+
+Thu Feb 18 16:17:30 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * misc.c (pthread_equal): Fix inverted result.
+
+ * Makefile.in: Use libpthread32.a as the name of the DLL export
+ library instead of pthread.lib.
+
+ * condvar.c (pthread_cond_init): cv could have been used unitialised;
+ initialise.
+
+ * create.c (pthread_create): parms could have been used unitialised;
+ initialise.
+
+ * pthread.h (struct pthread_once_t_): Remove redefinition.
+
+Sat Feb 13 03:03:30 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (struct pthread_once_t_): Replaced.
+
+ * misc.c (pthread_once): Replace with John Bossom's version;
+ has lighter weight serialisation; fixes problem of not holding
+ competing threads until after the init_routine completes.
+
+Thu Feb 11 13:34:14 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * misc.c (CancelableWait): Change C++ exception throw.
+
+ * sync.c (pthread_join): Change FIXME comment - issue resolved.
+
+Wed Feb 10 12:49:11 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * configure: Various temporary changes.
+ - Kevin Ruland <Kevin.Ruland at anheuser-busch.com>
+
+ * README: Update.
+
+ * pthread.def (pthread_attr_getstackaddr): uncomment
+ (pthread_attr_setstackaddr): uncomment
+
+Fri Feb 5 13:42:30 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * semaphore.c: Comment format changes.
+
+Thu Feb 4 10:07:28 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * global.c: Remove ptw32_exception instantiation.
+
+ * cancel.c (pthread_testcancel): Change C++ exception throw.
+
+ * implement.h: Remove extern declaration.
+
+Wed Feb 3 13:04:44 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cleanup.c: Rename ptw32_*_cleanup() to pthread_*_cleanup().
+
+ * pthread.def: Ditto.
+
+ * pthread.h: Ditto.
+
+ * pthread.def (pthread_cleanup_push): Remove from export list;
+ the function is defined as a macro under all compilers.
+ (pthread_cleanup_pop): Ditto.
+
+ * pthread.h: Remove #if defined().
+
+Wed Feb 3 10:13:48 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sync.c (pthread_join): Check for NULL value_ptr arg;
+ check for detached threads.
+
+Tue Feb 2 18:07:43 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * implement.h: Add #include <pthread.h>.
+ Change sem_t to ptw32_sem_t.
+
+Tue Feb 2 18:07:43 1999 Kevin Ruland <Kevin.Ruland at anheuser-busch.com>
+
+ * signal.c (pthread_sigmask): Add and modify casts.
+ Reverse LHS/RHS bitwise assignments.
+
+ * pthread.h: Remove #include <semaphore.h>.
+ (PTW32_ATTR_VALID): Add cast.
+ (struct pthread_t_): Add sigmask element.
+
+ * dll.c: Add "extern C" for DLLMain.
+ (DllMain): Add cast.
+
+ * create.c (pthread_create): Set sigmask in thread.
+
+ * condvar.c: Remove #include. Change sem_* to ptw32_sem_*.
+
+ * attr.c: Changed #include.
+
+ * Makefile.in: Additional targets and changes to build the library
+ as a DLL.
+
+Fri Jan 29 11:56:28 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * Makefile.in (OBJS): Add semaphore.o to list.
+
+ * semaphore.c (ptw32_sem_timedwait): Move from private.c.
+ Rename sem_* to ptw32_sem_*.
+
+ * pthread.h (pthread_cond_t): Change type of sem_t.
+ _POSIX_SEMAPHORES no longer defined.
+
+ * semaphore.h: Contents moved to implement.h.
+ Removed from source tree.
+
+ * implement.h: Add semaphore function prototypes and rename all
+ functions to prepend 'ptw32_'. They are
+ now private to the pthreads-win32 implementation.
+
+ * private.c: Change #warning.
+ Move ptw32_sem_timedwait() to semaphore.c.
+
+ * cleanup.c: Change #warning.
+
+ * misc.c: Remove #include <errno.h>
+
+ * pthread.def: Cleanup CVS merge conflicts.
+
+ * global.c: Ditto.
+
+ * ChangeLog: Ditto.
+
+ * cleanup.c: Ditto.
+
+Sun Jan 24 01:34:52 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * semaphore.c (sem_wait): Remove second arg to
+ pthreadCancelableWait() call.
+
+Sat Jan 23 17:36:40 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.def: Add new functions to export list.
+
+ * pthread.h (PTHREAD_MUTEX_AUTO_CS_NP): New.
+ (PTHREAD_MUTEX_FORCE_CS_NP): New.
+
+ * README: Updated.
+
+Fri Jan 22 14:31:59 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * Makefile.in (CFLAGS): Remove -fhandle-exceptions. Not needed
+ with egcs. Add -g for debugging.
+
+ * create.c (pthread_create): Replace __stdcall with PT_STDCALL
+ macro. This is a hack and must be fixed.
+
+ * misc.c (CancelableWait): Remove redundant statement.
+
+ * mutex.c (pthread_mutexattr_init): Cast calloc return value.
+
+ * misc.c (CancelableWait): Add cast.
+ (pthread_self): Add cast.
+
+ * exit.c (pthread_exit): Add cast.
+
+ * condvar.c (pthread_condattr_init): Cast calloc return value.
+
+ * cleanup.c: Reorganise conditional compilation.
+
+ * attr.c (pthread_attr_init): Remove unused 'result'.
+ Cast malloc return value.
+
+ * private.c (ptw32_callUserDestroyRoutines): Redo conditional
+ compilation.
+
+ * misc.c (CancelableWait): C++ version uses 'throw'.
+
+ * cancel.c (pthread_testcancel): Ditto.
+
+ * implement.h (class ptw32_exception): Define for C++.
+
+ * pthread.h: Fix C, C++, and Win32 SEH condition compilation
+ mayhem around pthread_cleanup_* defines. C++ version now uses John
+ Bossom's cleanup handlers.
+ (pthread_attr_t): Make 'valid' unsigned.
+ Define '_timeb' as 'timeb' for Ming32.
+ Define PT_STDCALL as nothing for Mingw32. May be temporary.
+
+ * cancel.c (pthread_testcancel): Cast return value.
+
+Wed Jan 20 09:31:28 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (pthread_mutexattr_t): Changed to a pointer.
+
+ * mutex.c (pthread_mutex_init): Conditionally create Win32 mutex
+ - from John Bossom's implementation.
+ (pthread_mutex_destroy): Conditionally close Win32 mutex
+ - from John Bossom's implementation.
+ (pthread_mutexattr_init): Replaced by John Bossom's version.
+ (pthread_mutexattr_destroy): Ditto.
+ (pthread_mutexattr_getpshared): New function from John Bossom's
+ implementation.
+ (pthread_mutexattr_setpshared): New function from John Bossom's
+ implementation.
+
+Tue Jan 19 18:27:42 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * pthread.h (pthreadCancelableTimedWait): New prototype.
+ (pthreadCancelableWait): Remove second argument.
+
+ * misc.c (CancelableWait): New static function is
+ pthreadCancelableWait() renamed.
+ (pthreadCancelableWait): Now just calls CancelableWait() with
+ INFINITE timeout.
+ (pthreadCancelableTimedWait): Just calls CancelableWait()
+ with passed in timeout.
+
+Tue Jan 19 18:27:42 1999 Scott Lightner <scott at curriculum.com>
+
+ * private.c (ptw32_sem_timedwait): 'abstime' arg really is
+ absolute time. Calculate relative time to wait from current
+ time before passing timeout to new routine
+ pthreadCancelableTimedWait().
+
+Tue Jan 19 10:27:39 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (pthread_mutexattr_setforcecs_np): New prototype.
+
+ * mutex.c (pthread_mutexattr_init): Init 'pshared' and 'forcecs'
+ attributes to 0.
+ (pthread_mutexattr_setforcecs_np): New function (not portable).
+
+ * pthread.h (pthread_mutex_t):
+ Add 'mutex' element. Set to NULL in PTHREAD_MUTEX_INITIALIZER.
+ The pthread_mutex_*() routines will try to optimise performance
+ by choosing either mutexes or critical sections as the basis
+ for pthread mutexes for each indevidual mutex.
+ (pthread_mutexattr_t_): Add 'forcecs' element.
+ Some applications may choose to force use of critical sections
+ if they know that:-
+ the mutex is PROCESS_PRIVATE and,
+ either the OS supports TryEnterCriticalSection() or
+ pthread_mutex_trylock() will never be called on the mutex.
+ This attribute will be setable via a non-portable routine.
+
+ Note: We don't yet support PROCESS_SHARED mutexes, so the
+ implementation as it stands will default to Win32 mutexes only if
+ the OS doesn't support TryEnterCriticalSection. On Win9x, and early
+ versions of NT 'forcecs' will need to be set in order to get
+ critical section based mutexes.
+
+Sun Jan 17 12:01:26 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (PTHREAD_MUTEX_INITIALIZER): Init new 'staticinit'
+ value to '1' and existing 'valid' value to '1'.
+
+ * global.c (ptw32_mutex_test_init_lock): Add.
+
+ * implement.h (ptw32_mutex_test_init_lock.): Add extern.
+
+ * private.c (ptw32_processInitialize): Init critical section for
+ global lock used by _mutex_check_need_init().
+ (ptw32_processTerminate): Ditto (:s/Init/Destroy/).
+
+ * dll.c (dllMain): Move call to FreeLibrary() so that it is only
+ called once when the process detaches.
+
+ * mutex.c (_mutex_check_need_init): New static function to test
+ and init PTHREAD_MUTEX_INITIALIZER mutexes. Provides serialised
+ access to the internal state of the uninitialised static mutex.
+ Called from pthread_mutex_trylock() and pthread_mutex_lock() which
+ do a quick unguarded test to check if _mutex_check_need_init()
+ needs to be called. This is safe as the test is conservative
+ and is repeated inside the guarded section of
+ _mutex_check_need_init(). Thus in all calls except the first
+ calls to lock static mutexes, the additional overhead to lock any
+ mutex is a single memory fetch and test for zero.
+
+ * pthread.h (pthread_mutex_t_): Add 'staticinit' member. Mutexes
+ initialised by PTHREAD_MUTEX_INITIALIZER aren't really initialised
+ until the first attempt to lock it. Using the 'valid'
+ flag (which flags the mutex as destroyed or not) to record this
+ information would be messy. It is possible for a statically
+ initialised mutex such as this to be destroyed before ever being
+ used.
+
+ * mutex.c (pthread_mutex_trylock): Call _mutex_check_need_init()
+ to test/init PTHREAD_MUTEX_INITIALIZER mutexes.
+ (pthread_mutex_lock): Ditto.
+ (pthread_mutex_unlock): Add check to ensure we don't try to unlock
+ an unitialised static mutex.
+ (pthread_mutex_destroy): Add check to ensure we don't try to delete
+ a critical section that we never created. Allows us to destroy
+ a static mutex that has never been locked (and hence initialised).
+ (pthread_mutex_init): Set 'staticinit' flag to 0 for the new mutex.
+
+Sun Jan 17 12:01:26 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_sem_timedwait): Move from semaphore.c.
+
+ * semaphore.c : Remove redundant #includes.
+ (ptw32_sem_timedwait): Move to private.c.
+ (sem_wait): Add missing abstime arg to pthreadCancelableWait() call.
+
+Fri Jan 15 23:38:05 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * condvar.c (cond_timedwait): Remove comment.
+
+Fri Jan 15 15:41:28 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * pthread.h: Add new 'abstime' arg to pthreadCancelableWait()
+ prototype.
+
+ * condvar.c (cond_timedwait): New generalised function called by
+ both pthread_cond_wait() and pthread_cond_timedwait(). This is
+ essentially pthread_cond_wait() renamed and modified to add the
+ 'abstime' arg and call the new ptw32_sem_timedwait() instead of
+ sem_wait().
+ (pthread_cond_wait): Now just calls the internal static
+ function cond_timedwait() with an INFINITE wait.
+ (pthread_cond_timedwait): Now implemented. Calls the internal
+ static function cond_timedwait().
+
+ * implement.h (ptw32_sem_timedwait): New internal function
+ prototype.
+
+ * misc.c (pthreadCancelableWait): Added new 'abstime' argument
+ to allow shorter than INFINITE wait.
+
+ * semaphore.c (ptw32_sem_timedwait): New function for internal
+ use. This is essentially sem_wait() modified to add the
+ 'abstime' arg and call the modified (see above)
+ pthreadCancelableWait().
+
+Thu Jan 14 14:27:13 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cleanup.c: Correct _cplusplus to __cplusplus wherever used.
+
+ * Makefile.in: Add CC=g++ and add -fhandle-exceptions to CFLAGS.
+ The derived Makefile will compile all units of the package as C++
+ so that those which include try/catch exception handling should work
+ properly. The package should compile ok if CC=gcc, however, exception
+ handling will not be included and thus thread cancellation, for
+ example, will not work.
+
+ * cleanup.c (ptw32_pop_cleanup): Add #warning to compile this
+ file as C++ if using a cygwin32 environment. Perhaps the whole package
+ should be compiled using g++ under cygwin.
+
+ * private.c (ptw32_threadStart): Change #error directive
+ into #warning and bracket for __CYGWIN__ and derivative compilers.
+
+Wed Jan 13 09:34:52 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * build.bat: Delete old binaries before compiling/linking.
+
+Tue Jan 12 09:58:38 1999 Tor Lillqvist <tml at iki.fi>
+
+ * dll.c: The Microsoft compiler pragmas probably are more
+ appropriately protected by _MSC_VER than by _WIN32.
+
+ * pthread.h: Define ETIMEDOUT. This should be returned by
+ pthread_cond_timedwait which is not implemented yet as of
+ snapshot-1999-01-04-1305. It was implemented in the older version.
+ The Microsoft compiler pragmas probably are more appropriately
+ protected by _MSC_VER than by _WIN32.
+
+ * pthread.def: pthread_mutex_destroy was missing from the def file
+
+ * condvar.c (pthread_cond_broadcast): Ensure we only wait on threads
+ if there were any waiting on the condition.
+ I think pthread_cond_broadcast should do the WaitForSingleObject
+ only if cv->waiters > 0? Otherwise it seems to hang, at least in the
+ testg thread program from glib.
+
+Tue Jan 12 09:58:38 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * condvar.c (pthread_cond_timedwait): Fix function description
+ comments.
+
+ * semaphore.c (sem_post): Correct typo in comment.
+
+Mon Jan 11 20:33:19 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h: Re-arrange conditional compile of pthread_cleanup-*
+ macros.
+
+ * cleanup.c (ptw32_push_cleanup): Provide conditional
+ compile of cleanup->prev.
+
+1999-01-11 Tor Lillqvist <tml at iki.fi>
+
+ * condvar.c (pthread_cond_init): Invert logic when testing the
+ return value from calloc().
+
+Sat Jan 9 14:32:08 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Compile-time switch for CYGWIN derived environments
+ to use CreateThread instead of _beginthreadex. Ditto for ExitThread.
+ Patch provided by Anders Norlander <anorland at hem2.passagen.se>.
+
+Tue Jan 5 16:33:04 1999 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cleanup.c (ptw32_pop_cleanup): Add C++ version of __try/__except
+ block. Move trailing "}" out of #ifdef _WIN32 block left there by
+ (rpj's) mistake.
+
+ * private.c: Remove #include <errno.h> which is included by pthread.h.
+
+1998-12-11 Ben Elliston <bje at toilet.to.cygnus.com>
+
+ * README: Update info about subscribing to the mailing list.
+
+Mon Jan 4 11:23:40 1999 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * all: No code changes, just cleanup.
+ - remove #if 0 /* Pre Bossom */ enclosed code.
+ - Remove some redundant #includes.
+ * pthread.h: Update implemented/unimplemented routines list.
+ * Tag the bossom merge branch getting ready to merge back to main
+ trunk.
+
+Tue Dec 29 13:11:16 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Move the following struct definitions to pthread.h:
+ pthread_t_, pthread_attr_t_, pthread_mutex_t_, pthread_mutex_t_,
+ pthread_mutexattr_t_, pthread_key_t_, pthread_cond_t_,
+ pthread_condattr_t_, pthread_once_t_.
+
+ * pthread.h: Add "_" prefix to pthread_push_cleanup and
+ pthread_pop_cleanup internal routines, and associated struct and
+ typedefs.
+
+ * buildlib.bat: Add compile command for semaphore.c
+
+ * pthread.def: Comment out pthread_atfork routine name.
+ Now unimplemented.
+
+ * tsd.c (pthread_setspecific): Rename tkAssocCreate to
+ ptw32_tkAssocCreate.
+ (pthread_key_delete): Rename tkAssocDestroy to
+ ptw32_tkAssocDestroy.
+
+ * sync.c (pthread_join): Rename threadDestroy to ptw32_threadDestroy
+
+ * sched.c (is_attr): attr is now **attr (was *attr), so add extra
+ NULL pointer test.
+ (pthread_attr_setschedparam): Increase redirection for attr which is
+ now a **.
+ (pthread_attr_getschedparam): Ditto.
+ (pthread_setschedparam): Change thread validation and rename "thread"
+ Win32 thread Handle element name to match John Bossom's version.
+ (pthread_getschedparam): Ditto.
+
+ * private.c (ptw32_threadDestroy): Rename call to
+ callUserDestroyRoutines() as ptw32_callUserDestroyRoutines()
+
+ * misc.c: Add #include "implement.h".
+
+ * dll.c: Remove defined(KLUDGE) wrapped code.
+
+ * fork.c: Remove redefinition of ENOMEM.
+ Remove pthread_atfork() and fork() with #if 0/#endif.
+
+ * create.c (pthread_create): Rename threadStart and threadDestroy calls
+ to ptw32_threadStart and ptw32_threadDestroy.
+
+ * implement.h: Rename "detachedstate" to "detachstate".
+
+ * attr.c: Rename "detachedstate" to "detachstate".
+
+Mon Dec 28 09:54:39 1998 John Bossom
+
+ * semaphore.c: Initial version.
+ * semaphore.h: Initial version.
+
+Mon Dec 28 09:54:39 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.h (pthread_attr_t_): Change to *pthread_attr_t.
+
+Mon Dec 28 09:54:39 1998 John Bossom, Ben Elliston
+
+ * attr.c (pthread_attr_setstacksize): Merge with John's version.
+ (pthread_attr_getstacksize): Merge with John's version.
+ (pthread_attr_setstackaddr): Merge with John's version.
+ (pthread_attr_getstackaddr): Merge with John's version.
+ (pthread_attr_init): Merge with John's version.
+ (pthread_attr_destroy): Merge with John's version.
+ (pthread_attr_getdetachstate): Merge with John's version.
+ (pthread_attr_setdetachstate): Merge with John's version.
+ (is_attr): attr is now **attr (was *attr), so add extra NULL pointer
+ test.
+
+Mon Dec 28 09:54:39 1998 Ross Johnson
+
+ * implement.h (pthread_attr_t_): Add and rename elements in JEB's
+ version to correspond to original, so that it can be used with
+ original attr routines.
+
+ * pthread.h: Add #endif at end which was truncated in merging.
+
+Sun Dec 20 14:51:58 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * misc.c (pthreadCancelableWait): New function by John Bossom. Non-standard
+ but provides a hook that can be used to implement cancellation points in
+ applications that use this library.
+
+ * pthread.h (pthread_cleanup_pop): C++ (non-WIN32) version uses
+ try/catch to emulate John Bossom's WIN32 __try/__finally behaviour.
+ In the WIN32 version __finally block, add a test for AbnormalTermination otherwise
+ cleanup is only run if the cleanup_pop execute arg is non-zero. Cancellation
+ should cause the cleanup to run irrespective of the execute arg.
+
+ * condvar.c (pthread_condattr_init): Replaced by John Bossom's version.
+ (pthread_condattr_destroy): Replaced by John Bossom's version.
+ (pthread_condattr_getpshared): Replaced by John Bossom's version.
+ (pthread_condattr_setpshared): Replaced by John Bossom's version.
+ (pthread_cond_init): Replaced by John Bossom's version.
+ Fix comment (refered to mutex rather than condition variable).
+ (pthread_cond_destroy): Replaced by John Bossom's version.
+ (pthread_cond_wait): Replaced by John Bossom's version.
+ (pthread_cond_timedwait): Replaced by John Bossom's version.
+ (pthread_cond_signal): Replaced by John Bossom's version.
+ (pthread_cond_broadcast): Replaced by John Bossom's version.
+
+Thu Dec 17 19:10:46 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * tsd.c (pthread_key_create): Replaced by John Bossom's version.
+ (pthread_key_delete): Replaced by John Bossom's version.
+ (pthread_setspecific): Replaced by John Bossom's version.
+ (pthread_getspecific): Replaced by John Bossom's version.
+
+Mon Dec 7 09:44:40 1998 John Bossom
+
+ * cancel.c (pthread_setcancelstate): Replaced.
+ (pthread_setcanceltype): Replaced.
+ (pthread_testcancel): Replaced.
+ (pthread_cancel): Replaced.
+
+ * exit.c (pthread_exit): Replaced.
+
+ * misc.c (pthread_self): Replaced.
+ (pthread_equal): Replaced.
+
+ * sync.c (pthread_detach): Replaced.
+ (pthread_join): Replaced.
+
+ * create.c (pthread_create): Replaced.
+
+ * private.c (ptw32_processInitialize): New.
+ (ptw32_processTerminate): New.
+ (ptw32_threadStart): New.
+ (ptw32_threadDestroy): New.
+ (ptw32_cleanupStack): New.
+ (ptw32_tkAssocCreate): New.
+ (ptw32_tkAssocDestroy): New.
+ (ptw32_callUserDestroyRoutines): New.
+
+ * implement.h: Added non-API structures and declarations.
+
+ * dll.c (PthreadsEntryPoint): Cast return value of GetProcAddress
+ to resolve compile warning from MSVC.
+
+ * dll.c (DLLmain): Replaced.
+ * dll.c (PthreadsEntryPoint):
+ Re-applied Anders Norlander's patch:-
+ Initialize ptw32_try_enter_critical_section at startup
+ and release kernel32 handle when DLL is being unloaded.
+
+Sun Dec 6 21:54:35 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * buildlib.bat: Fix args to CL when building the .DLL
+
+ * cleanup.c (ptw32_destructor_run_all): Fix TSD key management.
+ This is a tidy-up before TSD and Thread management is completely
+ replaced by John Bossom's code.
+
+ * tsd.c (pthread_key_create): Fix TSD key management.
+
+ * global.c (ptw32_key_virgin_next): Initialise.
+
+ * build.bat: New DOS script to compile and link a pthreads app
+ using Microsoft's CL compiler linker.
+ * buildlib.bat: New DOS script to compile all the object files
+ and create pthread.lib and pthread.dll using Microsoft's CL
+ compiler linker.
+
+1998-12-05 Anders Norlander <anorland at hem2.passagen.se>
+
+ * implement.h (ptw32_try_enter_critical_section): New extern
+ * dll.c (ptw32_try_enter_critical_section): New pointer to
+ TryEnterCriticalSection if it exists; otherwise NULL.
+ * dll.c (PthreadsEntryPoint):
+ Initialize ptw32_try_enter_critical_section at startup
+ and release kernel32 handle when DLL is being unloaded.
+ * mutex.c (pthread_mutex_trylock): Replaced check for NT with
+ a check if ptw32_try_enter_critical_section is valid
+ pointer to a function. Call ptw32_try_enter_critical_section
+ instead of TryEnterCriticalSection to avoid errors on Win95.
+
+Thu Dec 3 13:32:00 1998 Ross Johnson <rpj at ise.canberra.edu.au>
+
+ * README: Correct cygwin32 compatibility statement.
+
+Sun Nov 15 21:24:06 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * cleanup.c (ptw32_destructor_run_all): Declare missing void * arg.
+ Fixup CVS merge conflicts.
+
+1998-10-30 Ben Elliston <bje at cygnus.com>
+
+ * condvar.c (cond_wait): Fix semantic error. Test for equality
+ instead of making an assignment.
+
+Fri Oct 30 15:15:50 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cleanup.c (ptw32_handler_push): Fixed bug appending new
+ handler to list reported by Peter Slacik
+ <Peter.Slacik at leibinger.freinet.de>.
+ (new_thread): Rename poorly named local variable to
+ "new_handler".
+
+Sat Oct 24 18:34:59 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * global.c: Add TSD key management array and index declarations.
+
+ * implement.h: Ditto for externs.
+
+Fri Oct 23 00:08:09 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h (PTW32_TSD_KEY_REUSE): Add enum.
+
+ * private.c (ptw32_delete_thread): Add call to
+ ptw32_destructor_run_all() to clean up the threads keys.
+
+ * cleanup.c (ptw32_destructor_run_all): Check for no more dirty
+ keys to run destructors on. Assume that the destructor call always
+ succeeds and set the key value to NULL.
+
+Thu Oct 22 21:44:44 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * tsd.c (pthread_setspecific): Add key management code.
+ (pthread_key_create): Ditto.
+ (pthread_key_delete): Ditto.
+
+ * implement.h (struct ptw32_tsd_key): Add status member.
+
+ * tsd.c: Add description of pthread_key_delete() from the
+ standard as a comment.
+
+Fri Oct 16 17:38:47 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cleanup.c (ptw32_destructor_run_all): Fix and improve
+ stepping through the key table.
+
+Thu Oct 15 14:05:01 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * private.c (ptw32_new_thread): Remove init of destructorstack.
+ No longer an element of pthread_t.
+
+ * tsd.c (pthread_setspecific): Fix type declaration and cast.
+ (pthread_getspecific): Ditto.
+ (pthread_getspecific): Change error return value to NULL if key
+ is not in use.
+
+Thu Oct 15 11:53:21 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * global.c (ptw32_tsd_key_table): Fix declaration.
+
+ * implement.h(ptw32_TSD_keys_TlsIndex): Add missing extern.
+ (ptw32_tsd_mutex): Ditto.
+
+ * create.c (ptw32_start_call): Fix "keys" array declaration.
+ Add comment.
+
+ * tsd.c (pthread_setspecific): Fix type declaration and cast.
+ (pthread_getspecific): Ditto.
+
+ * cleanup.c (ptw32_destructor_run_all): Declare missing loop
+ counter.
+
+Wed Oct 14 21:09:24 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_new_thread): Increment ptw32_threads_count.
+ (ptw32_delete_thread): Decrement ptw32_threads_count.
+ Remove some comments.
+
+ * exit.c (ptw32_exit): : Fix two pthread_mutex_lock() calls that
+ should have been pthread_mutex_unlock() calls.
+ (ptw32_vacuum): Remove call to ptw32_destructor_pop_all().
+
+ * create.c (pthread_create): Fix two pthread_mutex_lock() calls that
+ should have been pthread_mutex_unlock() calls.
+
+ * global.c (ptw32_tsd_mutex): Add mutex for TSD operations.
+
+ * tsd.c (pthread_key_create): Add critical section.
+ (pthread_setspecific): Ditto.
+ (pthread_getspecific): Ditto.
+ (pthread_key_delete): Ditto.
+
+ * sync.c (pthread_join): Fix two pthread_mutex_lock() calls that
+ should have been pthread_mutex_unlock() calls.
+
+Mon Oct 12 00:00:44 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h (ptw32_tsd_key_table): New.
+
+ * create.c (ptw32_start_call): Initialise per-thread TSD keys
+ to NULL.
+
+ * misc.c (pthread_once): Correct typo in comment.
+
+ * implement.h (ptw32_destructor_push): Remove.
+ (ptw32_destructor_pop): Remove.
+ (ptw32_destructor_run_all): Rename from ptw32_destructor_pop_all.
+ (PTW32_TSD_KEY_DELETED): Add enum.
+ (PTW32_TSD_KEY_INUSE): Add enum.
+
+ * cleanup.c (ptw32_destructor_push): Remove.
+ (ptw32_destructor_pop): Remove.
+ (ptw32_destructor_run_all): Totally revamped TSD.
+
+ * dll.c (ptw32_TSD_keys_TlsIndex): Initialise.
+
+ * tsd.c (pthread_setspecific): Totally revamped TSD.
+ (pthread_getspecific): Ditto.
+ (pthread_create): Ditto.
+ (pthread_delete): Ditto.
+
+Sun Oct 11 22:44:55 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * global.c (ptw32_tsd_key_table): Add new global.
+
+ * implement.h (ptw32_tsd_key_t and struct ptw32_tsd_key):
+ Add.
+ (struct _pthread): Remove destructorstack.
+
+ * cleanup.c (ptw32_destructor_run_all): Rename from
+ ptw32_destructor_pop_all. The key destructor stack was made
+ global rather than per-thread. No longer removes destructor nodes
+ from the stack. Comments updated.
+
+1998-10-06 Ben Elliston <bje at cygnus.com>
+
+ * condvar.c (cond_wait): Use POSIX, not Win32 mutex calls.
+ (pthread_cond_broadcast): Likewise.
+ (pthread_cond_signal): Likewise.
+
+1998-10-05 Ben Elliston <bje at cygnus.com>
+
+ * pthread.def: Update. Some functions aren't available yet, others
+ are macros in <pthread.h>.
+
+ * tests/join.c: Remove; useless.
+
+Mon Oct 5 14:25:08 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * pthread.def: New file for building the DLL.
+
+1998-10-05 Ben Elliston <bje at cygnus.com>
+
+ * misc.c (pthread_equal): Correct inverted logic bug.
+ (pthread_once): Use the POSIX mutex primitives, not Win32. Remove
+ irrelevant FIXME comment.
+
+ * global.c (PTHREAD_MUTEX_INITIALIZER): Move to pthread.h.
+
+ * pthread.h (PTHREAD_MUTEX_INITIALIZER): Define.
+ (pthread_mutex_t): Reimplement as a struct containing a valid
+ flag. If the flag is ever down upon entry to a mutex operation,
+ we call pthread_mutex_create() to initialise the object. This
+ fixes the problem of how to handle statically initialised objects
+ that can't call InitializeCriticalSection() due to their context.
+ (PTHREAD_ONCE_INIT): Define.
+
+ * mutex.c (pthread_mutex_init): Set valid flag.
+ (pthread_mutex_destroy): Clear valid flag.
+ (pthread_mutex_lock): Check and handle the valid flag.
+ (pthread_mutex_unlock): Likewise.
+ (pthread_mutex_trylock): Likewise.
+
+ * tests/mutex3.c: New file; test for the static initialisation
+ macro. Passes.
+
+ * tests/create1.c: New file; test pthread_create(). Passes.
+
+ * tests/equal.c: Poor test; remove.
+
+ * tests/equal1.c New file; test pthread_equal(). Passes.
+
+ * tests/once1.c: New file; test for pthread_once(). Passes.
+
+ * tests/self.c: Remove; rename to self1.c.
+
+ * tests/self1.c: This is the old self.c.
+
+ * tests/self2.c: New file. Test pthread_self() with a single
+ thread. Passes.
+
+ * tests/self3.c: New file. Test pthread_self() with a couple of
+ threads to ensure their thread IDs differ. Passes.
+
+1998-10-04 Ben Elliston <bje at cygnus.com>
+
+ * tests/mutex2.c: Test pthread_mutex_trylock(). Passes.
+
+ * tests/mutex1.c: New basic test for mutex functions (it passes).
+ (main): Eliminate warning.
+
+ * configure.in: Test for __stdcall, not _stdcall. Typo.
+
+ * configure: Regenerate.
+
+ * attr.c (pthread_attr_setstackaddr): Remove FIXME comment. Win32
+ does know about ENOSYS after all.
+ (pthread_attr_setstackaddr): Likewise.
+
+1998-10-03 Ben Elliston <bje at cygnus.com>
+
+ * configure.in: Test for the `_stdcall' keyword. Define `STDCALL'
+ to `_stdcall' if we have it, null otherwise.
+
+ * configure: Regenerate.
+
+ * acconfig.h (STDCALL): New define.
+
+ * config.h.in: Regenerate.
+
+ * create.c (ptw32_start_call): Add STDCALL prefix.
+
+ * mutex.c (pthread_mutex_init): Correct function signature.
+
+ * attr.c (pthread_attr_init): Only zero out the `sigmask' member
+ if we have the sigset_t type.
+
+ * pthread.h: No need to include <unistd.h>. It doesn't even exist
+ on Win32! Again, an artifact of cross-compilation.
+ (pthread_sigmask): Only provide if we have the sigset_t type.
+
+ * process.h: Remove. This was a stand-in before we started doing
+ native compilation under Win32.
+
+ * pthread.h (pthread_mutex_init): Make `attr' argument const.
+
+1998-10-02 Ben Elliston <bje at cygnus.com>
+
+ * COPYING: Remove.
+
+ * COPYING.LIB: Add. This library is under the LGPL.
+
+1998-09-13 Ben Elliston <bje at cygnus.com>
+
+ * configure.in: Test for required system features.
+
+ * configure: Generate.
+
+ * acconfig.h: New file.
+
+ * config.h.in: Generate.
+
+ * Makefile.in: Renamed from Makefile.
+
+ * COPYING: Import from a recent GNU package.
+
+ * config.guess: Likewise.
+
+ * config.sub: Likewise.
+
+ * install-sh: Likewise.
+
+ * config.h: Remove.
+
+ * Makefile: Likewise.
+
+1998-09-12 Ben Elliston <bje at cygnus.com>
+
+ * windows.h: No longer needed; remove.
+
+ * windows.c: Likewise.
+
+Sat Sep 12 20:09:24 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * windows.h: Remove error number definitions. These are in <errno.h>
+
+ * tsd.c: Add comment explaining rationale for not building
+ POSIX TSD on top of Win32 TLS.
+
+1998-09-12 Ben Elliston <bje at cygnus.com>
+
+ * {most}.c: Include <errno.h> to get POSIX error values.
+
+ * signal.c (pthread_sigmask): Only provide if HAVE_SIGSET_T is
+ defined.
+
+ * config.h: #undef features, don't #define them. This will be
+ generated by autoconf very soon.
+
+1998-08-11 Ben Elliston <bje at cygnus.com>
+
+ * Makefile (LIB): Define.
+ (clean): Define target.
+ (all): Build a library not just the object files.
+
+ * pthread.h: Provide a definition for struct timespec if we don't
+ already have one.
+
+ * windows.c (TlsGetValue): Bug fix.
+
+Thu Aug 6 15:19:22 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * misc.c (pthread_once): Fix arg 1 of EnterCriticalSection()
+ and LeaveCriticalSection() calls to pass address-of lock.
+
+ * fork.c (pthread_atfork): Typecast (void (*)(void *)) funcptr
+ in each ptw32_handler_push() call.
+
+ * exit.c (ptw32_exit): Fix attr arg in
+ pthread_attr_getdetachstate() call.
+
+ * private.c (ptw32_new_thread): Typecast (HANDLE) NULL.
+ (ptw32_delete_thread): Ditto.
+
+ * implement.h: (PTW32_MAX_THREADS): Add define. This keeps
+ changing in an attempt to make thread administration data types
+ opaque and cleanup DLL startup.
+
+ * dll.c (PthreadsEntryPoint):
+ (ptw32_virgins): Remove malloc() and free() calls.
+ (ptw32_reuse): Ditto.
+ (ptw32_win32handle_map): Ditto.
+ (ptw32_threads_mutex_table): Ditto.
+
+ * global.c (_POSIX_THREAD_THREADS_MAX): Initialise with
+ PTW32_MAX_THREADS.
+ (ptw32_virgins): Ditto.
+ (ptw32_reuse): Ditto.
+ (ptw32_win32handle_map): Ditto.
+ (ptw32_threads_mutex_table): Ditto.
+
+ * create.c (pthread_create): Typecast (HANDLE) NULL.
+ Typecast (unsigned (*)(void *)) start_routine.
+
+ * condvar.c (pthread_cond_init): Add address-of operator & to
+ arg 1 of pthread_mutex_init() call.
+ (pthread_cond_destroy): Add address-of operator & to
+ arg 1 of pthread_mutex_destroy() call.
+
+ * cleanup.c (ptw32_destructor_pop_all): Add (int) cast to
+ pthread_getspecific() arg.
+ (ptw32_destructor_pop): Add (void *) cast to "if" conditional.
+ (ptw32_destructor_push): Add (void *) cast to
+ ptw32_handler_push() "key" arg.
+ (malloc.h): Add include.
+
+ * implement.h (ptw32_destructor_pop): Add prototype.
+
+ * tsd.c (implement.h): Add include.
+
+ * sync.c (pthread_join): Remove target_thread_mutex and it's
+ initialisation. Rename getdetachedstate to getdetachstate.
+ Remove unused variable "exitcode".
+ (pthread_detach): Remove target_thread_mutex and it's
+ initialisation. Rename getdetachedstate to getdetachstate.
+ Rename setdetachedstate to setdetachstate.
+
+ * signal.c (pthread_sigmask): Rename SIG_SET to SIG_SETMASK.
+ Cast "set" to (long *) in assignment to passify compiler warning.
+ Add address-of operator & to thread->attr.sigmask in memcpy() call
+ and assignment.
+ (pthread_sigmask): Add address-of operator & to thread->attr.sigmask
+ in memcpy() call and assignment.
+
+ * windows.h (THREAD_PRIORITY_ERROR_RETURN): Add.
+ (THREAD_PRIORITY_LOWEST): Add.
+ (THREAD_PRIORITY_HIGHEST): Add.
+
+ * sched.c (is_attr): Add function.
+ (implement.h): Add include.
+ (pthread_setschedparam): Rename all instances of "sched_policy"
+ to "sched_priority".
+ (pthread_getschedparam): Ditto.
+
+Tue Aug 4 16:57:58 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * private.c (ptw32_delete_thread): Fix typo. Add missing ';'.
+
+ * global.c (ptw32_virgins): Change types from pointer to
+ array pointer.
+ (ptw32_reuse): Ditto.
+ (ptw32_win32handle_map): Ditto.
+ (ptw32_threads_mutex_table): Ditto.
+
+ * implement.h(ptw32_virgins): Change types from pointer to
+ array pointer.
+ (ptw32_reuse): Ditto.
+ (ptw32_win32handle_map): Ditto.
+ (ptw32_threads_mutex_table): Ditto.
+
+ * private.c (ptw32_delete_thread): Fix "entry" should be "thread".
+
+ * misc.c (pthread_self): Add extern for ptw32_threadID_TlsIndex.
+
+ * global.c: Add comment.
+
+ * misc.c (pthread_once): Fix member -> dereferences.
+ Change ptw32_once_flag to once_control->flag in "if" test.
+
+Tue Aug 4 00:09:30 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h(ptw32_virgins): Add extern.
+ (ptw32_virgin_next): Ditto.
+ (ptw32_reuse): Ditto.
+ (ptw32_reuse_top): Ditto.
+ (ptw32_win32handle_map): Ditto.
+ (ptw32_threads_mutex_table): Ditto.
+
+ * global.c (ptw32_virgins): Changed from array to pointer.
+ Storage allocation for the array moved into dll.c.
+ (ptw32_reuse): Ditto.
+ (ptw32_win32handle_map): Ditto.
+ (ptw32_threads_mutex_table): Ditto.
+
+ * dll.c (PthreadsEntryPoint): Set up thread admin storage when
+ DLL is loaded.
+
+ * fork.c (pthread_atfork): Fix function pointer arg to all
+ ptw32_handler_push() calls. Change "arg" arg to NULL in child push.
+
+ * exit.c: Add windows.h and process.h includes.
+ (ptw32_exit): Add local detachstate declaration.
+ (ptw32_exit): Fix incorrect name for pthread_attr_getdetachstate().
+
+ * pthread.h (_POSIX_THREAD_ATTR_STACKSIZE): Move from global.c
+ (_POSIX_THREAD_ATTR_STACKADDR): Ditto.
+
+ * create.c (pthread_create): Fix #if should be #ifdef.
+ (ptw32_start_call): Remove usused variables.
+
+ * process.h: Create.
+
+ * windows.h: Move _beginthreadex and _endthreadex into
+ process.h
+
+Mon Aug 3 21:19:57 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * condvar.c (pthread_cond_init): Add NULL attr to
+ pthread_mutex_init() call - default attributes will be used.
+ (cond_wait): Fix typo.
+ (cond_wait): Fix typo - cv was ev.
+ (pthread_cond_broadcast): Fix two identical typos.
+
+ * cleanup.c (ptw32_destructor_pop_all): Remove _ prefix from
+ PTHREAD_DESTRUCTOR_ITERATIONS.
+
+ * pthread.h: Move _POSIX_* values into posix.h
+
+ * pthread.h: Fix typo in pthread_mutex_init() prototype.
+
+ * attr.c (pthread_attr_init): Fix error in priority member init.
+
+ * windows.h (THREAD_PRIORITY_NORMAL): Add.
+
+ * pthread.h (sched_param): Add missing ';' to struct definition.
+
+ * attr.c (pthread_attr_init): Remove obsolete pthread_attr_t
+ member initialisation - cancelstate, canceltype, cancel_pending.
+ (is_attr): Make arg "attr" a const.
+
+ * implement.h (PTW32_HANDLER_POP_LIFO): Remove definition.
+ (PTW32_HANDLER_POP_FIFO): Ditto.
+ (PTW32_VALID): Add missing newline escape (\).
+ (ptw32_handler_node): Make element "next" a pointer.
+
+1998-08-02 Ben Elliston <bje at cygnus.com>
+
+ * windows.h: Remove duplicate TlsSetValue() prototype. Add
+ TlsGetValue() prototype.
+ (FALSE): Define.
+ (TRUE): Likewise.
+ Add forgotten errno values. Guard against multiple #includes.
+
+ * windows.c: New file. Implement stubs for Win32 functions.
+
+ * Makefile (SRCS): Remove. Not explicitly needed.
+ (CFLAGS): Add -Wall for all warnings with GCC.
+
+Sun Aug 2 19:03:42 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * config.h: Create. This is a temporary stand-in for autoconf yet
+ to be done.
+ (HAVE_SIGNAL_H): Add.
+
+ * pthread.h: Minor rearrangement for temporary config.h.
+
+Fri Jul 31 14:00:29 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * cleanup.c (ptw32_destructor_pop): Implement. Removes
+ destructors associated with a key without executing them.
+ (ptw32_destructor_pop_all): Add FIXME comment.
+
+ * tsd.c (pthread_key_delete): Add call to ptw32_destructor_pop().
+
+Fri Jul 31 00:05:45 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * tsd.c (pthread_key_create): Update to properly associate
+ the destructor routine with the key.
+ (pthread_key_delete): Add FIXME comment.
+
+ * exit.c (ptw32_vacuum): Add call to
+ ptw32_destructor_pop_all().
+
+ * implement.h (ptw32_handler_pop_all): Add prototype.
+ (ptw32_destructor_pop_all): Ditto.
+
+ * cleanup.c (ptw32_destructor_push): Implement. This is just a
+ call to ptw32_handler_push().
+ (ptw32_destructor_pop_all): Implement. This is significantly
+ different to ptw32_handler_pop_all().
+
+ * Makefile (SRCS): Create. Preliminary.
+
+ * windows.h: Create. Contains Win32 definitions for compile
+ testing. This is just a standin for the real one.
+
+ * pthread.h (SIG_UNBLOCK): Fix typo. Was SIG_BLOCK.
+ (windows.h): Add include. Required for CRITICAL_SECTION.
+ (pthread_cond_t): Move enum declaration outside of struct
+ definition.
+ (unistd.h): Add include - may be temporary.
+
+ * condvar.c (windows.h): Add include.
+
+ * implement.h (PTW32_THIS): Remove - no longer required.
+ (PTW32_STACK): Use pthread_self() instead of PTW32_THIS.
+
+Thu Jul 30 23:12:45 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Remove ptw32_find_entry() prototype.
+
+ * private.c: Extend comments.
+ Remove ptw32_find_entry() - no longer needed.
+
+ * create.c (ptw32_start_call): Add call to TlsSetValue() to
+ store the thread ID.
+
+ * dll.c (PthreadsEntryPoint): Implement. This is called
+ whenever a process loads the DLL. Used to initialise thread
+ local storage.
+
+ * implement.h: Add ptw32_threadID_TlsIndex.
+ Add ()s around PTW32_VALID expression.
+
+ * misc.c (pthread_self): Re-implement using Win32 TLS to store
+ the threads own ID.
+
+Wed Jul 29 11:39:03 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c: Corrections in comments.
+ (ptw32_new_thread): Alter "if" flow to be more natural.
+
+ * cleanup.c (ptw32_handler_push): Same as below.
+
+ * create.c (pthread_create): Same as below.
+
+ * private.c (ptw32_new_thread): Rename "new" to "new_thread".
+ Since when has a C programmer been required to know C++?
+
+Tue Jul 28 14:04:29 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * implement.h: Add PTW32_VALID macro.
+
+ * sync.c (pthread_join): Modify to use the new thread
+ type and ptw32_delete_thread(). Rename "target" to "thread".
+ Remove extra local variable "target".
+ (pthread_detach): Ditto.
+
+ * signal.c (pthread_sigmask): Move init of "us" out of inner block.
+ Fix instance of "this" should have been "us". Rename "us" to "thread".
+
+ * sched.c (pthread_setschedparam): Modify to use the new thread
+ type.
+ (pthread_getschedparam): Ditto.
+
+ * private.c (ptw32_find_thread): Fix return type and arg.
+
+ * implement.h: Remove PTW32_YES and PTW32_NO.
+ (ptw32_new_thread): Add prototype.
+ (ptw32_find_thread): Ditto.
+ (ptw32_delete_thread): Ditto.
+ (ptw32_new_thread_entry): Remove prototype.
+ (ptw32_find_thread_entry): Ditto.
+ (ptw32_delete_thread_entry): Ditto.
+ ( PTW32_NEW, PTW32_INUSE, PTW32_EXITED, PTW32_REUSE):
+ Add.
+
+
+ * create.c (pthread_create): Minor rename "us" to "new" (I need
+ these cues but it doesn't stop me coming out with some major bugs
+ at times).
+ Load start_routine and arg into the thread so the wrapper can
+ call it.
+
+ * exit.c (pthread_exit): Fix pthread_this should be pthread_self.
+
+ * cancel.c (pthread_setcancelstate): Change
+ ptw32_threads_thread_t * to pthread_t and init with
+ pthread_this().
+ (pthread_setcanceltype): Ditto.
+
+ * exit.c (ptw32_exit): Add new pthread_t arg.
+ Rename ptw32_delete_thread_entry to ptw32_delete_thread.
+ Rename "us" to "thread".
+ (pthread_exit): Call ptw32_exit with added thread arg.
+
+ * create.c (ptw32_start_call): Insert missing ")".
+ Add "us" arg to ptw32_exit() call.
+ (pthread_create): Modify to use new thread allocation scheme.
+
+ * private.c: Added detailed explanation of the new thread
+ allocation scheme.
+ (ptw32_new_thread): Totally rewritten to use
+ new thread allocation scheme.
+ (ptw32_delete_thread): Ditto.
+ (ptw32_find_thread): Obsolete.
+
+Mon Jul 27 17:46:37 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * create.c (pthread_create): Start of rewrite. Not completed yet.
+
+ * private.c (ptw32_new_thread_entry): Start of rewrite. Not
+ complete.
+
+ * implement.h (ptw32_threads_thread): Rename, remove thread
+ member, add win32handle and ptstatus members.
+ (ptw32_t): Add.
+
+ * pthread.h: pthread_t is no longer mapped directly to a Win32
+ HANDLE type. This is so we can let the Win32 thread terminate and
+ reuse the HANDLE while pthreads holds it's own thread ID until
+ the last waiting join exits.
+
+Mon Jul 27 00:20:37 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_delete_thread_entry): Destroy the thread
+ entry attribute object before deleting the thread entry itself.
+
+ * attr.c (pthread_attr_init): Initialise cancel_pending = FALSE.
+ (pthread_attr_setdetachstate): Rename "detached" to "detachedstate".
+ (pthread_attr_getdetachstate): Ditto.
+
+ * exit.c (ptw32_exit): Fix incorrect check for detachedstate.
+
+ * implement.h (ptw32_call_t): Remove env member.
+
+Sun Jul 26 13:06:12 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h (ptw32_new_thread_entry): Fix prototype.
+ (ptw32_find_thread_entry): Ditto.
+ (ptw32_delete_thread_entry): Ditto.
+ (ptw32_exit): Add prototype.
+
+ * exit.c (ptw32_exit): New function. Called from pthread_exit()
+ and ptw32_start_call() to exit the thread. It allows an extra
+ argument which is the return code passed to _endthreadex().
+ (ptw32_exit): Move thread entry delete call from ptw32_vacuum()
+ into here. Add more explanation of thread entry deletion.
+ (ptw32_exit): Clarify comment.
+
+ * create.c (ptw32_start_call): Change pthread_exit() call to
+ ptw32_exit() call.
+
+ * exit.c (ptw32_vacuum): Add thread entry deletion code
+ moved from ptw32_start_call(). See next item.
+ (pthread_exit): Remove longjmp(). Add mutex lock around thread table
+ manipulation code. This routine now calls _enthreadex().
+
+ * create.c (ptw32_start_call): Remove setjmp() call and move
+ cleanup code out. Call pthread_exit(NULL) to terminate the thread.
+
+1998-07-26 Ben Elliston <bje at cygnus.com>
+
+ * tsd.c (pthread_getspecific): Update comments.
+
+ * mutex.c (pthread_mutexattr_setpshared): Not supported; remove.
+ (pthread_mutexattr_getpshared): Likewise.
+
+ * pthread.h (pthread_mutexattr_setpshared): Remove prototype.
+ (pthread_mutexattr_getpshared): Likewise.
+
+Sun Jul 26 00:09:59 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sync.c: Rename all instances of ptw32_count_mutex to
+ ptw32_table_mutex.
+
+ * implement.h: Rename ptw32_count_mutex to
+ ptw32_table_mutex.
+
+ * global.c: Rename ptw32_count_mutex to
+ ptw32_table_mutex.
+
+ * create.c (pthread_create): Add critical sections.
+ (ptw32_start_call): Rename ptw32_count_mutex to
+ ptw32_table_mutex.
+
+ * cancel.c (pthread_setcancelstate): Fix indirection bug and rename
+ "this" to "us".
+
+ * signal.c (pthread_sigmask): Rename "this" to "us" and fix some
+ minor syntax errors. Declare "us" and initialise it.
+
+ * sync.c (pthread_detach): Rename "this" to "target".
+
+ * pthread.h: Converting PTHREAD_* defines to alias the (const int)
+ values in global.c.
+
+ * global.c: Started converting PTHREAD_* defines to (const int) as
+ a part of making the eventual pthreads DLL binary compatible
+ through version changes.
+
+ * condvar.c (cond_wait): Add cancelation point. This applies the
+ point to both pthread_cond_wait() and pthread_cond_timedwait().
+
+ * exit.c (pthread_exit): Rename "this" to "us".
+
+ * implement.h: Add comment.
+
+ * sync.c (pthread_join): I've satisfied myself that pthread_detach()
+ does set the detached attribute in the thread entry attributes
+ to PTHREAD_CREATE_DETACHED. "if" conditions were changed to test
+ that attribute instead of a separate flag.
+
+ * create.c (pthread_create): Rename "this" to "us".
+ (pthread_create): cancelstate and canceltype are not attributes
+ so the copy to thread entry attribute storage was removed.
+ Only the thread itself can change it's cancelstate or canceltype,
+ ie. the thread must exist already.
+
+ * private.c (ptw32_delete_thread_entry): Mutex locks removed.
+ Mutexes must be applied at the caller level.
+ (ptw32_new_thread_entry): Ditto.
+ (ptw32_new_thread_entry): Init cancelstate, canceltype, and
+ cancel_pending to default values.
+ (ptw32_new_thread_entry): Rename "this" to "new".
+ (ptw32_find_thread_entry): Rename "this" to "entry".
+ (ptw32_delete_thread_entry): Rename "thread_entry" to "entry".
+
+ * create.c (ptw32_start_call): Mutexes changed to
+ ptw32_count_mutex. All access to the threads table entries is
+ under the one mutex. Otherwise chaos reigns.
+
+Sat Jul 25 23:16:51 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h (ptw32_threads_thread): Move cancelstate and
+ canceltype members out of pthread_attr_t into here.
+
+ * fork.c (fork): Add comment.
+
+1998-07-25 Ben Elliston <bje at cygnus.com>
+
+ * fork.c (fork): Autoconfiscate.
+
+Sat Jul 25 00:00:13 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * create.c (ptw32_start_call): Set thread priority. Ensure our
+ thread entry is removed from the thread table but only if
+ pthread_detach() was called and there are no waiting joins.
+ (pthread_create): Set detach flag in thread entry if the
+ thread is created PTHREAD_CREATE_DETACHED.
+
+ * pthread.h (pthread_attr_t): Rename member "detachedstate".
+
+ * attr.c (pthread_attr_init): Rename attr members.
+
+ * exit.c (pthread_exit): Fix indirection mistake.
+
+ * implement.h (PTW32_THREADS_TABLE_INDEX): Add.
+
+ * exit.c (ptw32_vacuum): Fix incorrect args to
+ ptw32_handler_pop_all() calls.
+ Make thread entry removal conditional.
+
+ * sync.c (pthread_join): Add multiple join and async detach handling.
+
+ * implement.h (PTW32_THREADS_TABLE_INDEX): Add.
+
+ * global.c (ptw32_threads_mutex_table): Add.
+
+ * implement.h (ptw32_once_flag): Remove.
+ (ptw32_once_lock): Ditto.
+ (ptw32_threads_mutex_table): Add.
+
+ * global.c (ptw32_once_flag): Remove.
+ (ptw32_once_lock): Ditto.
+
+ * sync.c (pthread_join): Fix tests involving new return value
+ from ptw32_find_thread_entry().
+ (pthread_detach): Ditto.
+
+ * private.c (ptw32_find_thread_entry): Failure return code
+ changed from -1 to NULL.
+
+Fri Jul 24 23:09:33 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * create.c (pthread_create): Change . to -> in sigmask memcpy() args.
+
+ * pthread.h: (pthread_cancel): Add function prototype.
+ (pthread_testcancel): Ditto.
+
+1998-07-24 Ben Elliston <bje at cygnus.com>
+
+ * pthread.h (pthread_condattr_t): Rename dummy structure member.
+ (pthread_mutexattr_t): Likewise.
+
+Fri Jul 24 21:13:55 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * cancel.c (pthread_cancel): Implement.
+ (pthread_testcancel): Implement.
+
+ * exit.c (pthread_exit): Add comment explaining the longjmp().
+
+ * implement.h (ptw32_threads_thread_t): New member cancelthread.
+ (PTW32_YES): Define.
+ (PTW32_NO): Define.
+ (RND_SIZEOF): Remove.
+
+ * create.c (pthread_create): Rename cancelability to cancelstate.
+
+ * pthread.h (pthread_attr_t): Rename cancelability to cancelstate.
+ (PTHREAD_CANCELED): Define.
+
+1998-07-24 Ben Elliston <bje at cygnus.com>
+
+ * pthread.h (SIG_BLOCK): Define if not already defined.
+ (SIG_UNBLOCK): Likewise.
+ (SIG_SETMASK): Likewise.
+ (pthread_attr_t): Add signal mask member.
+ (pthread_sigmask): Add function prototype.
+
+ * signal.c (pthread_sigmask): Implement.
+
+ * create.c: #include <string.h> to get a prototype for memcpy().
+ (pthread_create): New threads inherit their creator's signal
+ mask. Copy the signal mask to the new thread structure if we know
+ about signals.
+
+Fri Jul 24 16:33:17 1998 Ross Johnson <rpj at swan.canberra.edu.au>
+
+ * fork.c (pthread_atfork): Add all the necessary push calls.
+ Local implementation semantics:
+ If we get an ENOMEM at any time then ALL handlers
+ (including those from previous pthread_atfork() calls) will be
+ popped off each of the three atfork stacks before we return.
+ (fork): Add all the necessary pop calls. Add the thread cancellation
+ and join calls to the child fork.
+ Add #includes.
+
+ * implement.h: (ptw32_handler_push): Fix return type and stack arg
+ type in prototype.
+ (ptw32_handler_pop): Fix stack arg type in prototype.
+ (ptw32_handler_pop_all): Fix stack arg type in prototype.
+
+ * cleanup.c (ptw32_handler_push): Change return type to int and
+ return ENOMEM if malloc() fails.
+
+ * sync.c (pthread_detach): Use equality test, not assignment.
+
+ * create.c (ptw32_start_call): Add call to Win32 CloseHandle()
+ if thread is detached.
+
+1998-07-24 Ben Elliston <bje at cygnus.com>
+
+ * sync.c (pthread_detach): Close the Win32 thread handle to
+ emulate detached (or daemon) threads.
+
+Fri Jul 24 03:00:25 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sync.c (pthread_join): Save valueptr arg in joinvalueptr for
+ pthread_exit() to use.
+
+ * private.c (ptw32_new_thread_entry): Initialise joinvalueptr to
+ NULL.
+
+ * create.c (ptw32_start_call): Rewrite to facilitate joins.
+ pthread_exit() will do a longjmp() back to here. Does appropriate
+ cleanup and exit/return from the thread.
+ (pthread_create): _beginthreadex() now passes a pointer to our
+ thread table entry instead of just the call member of that entry.
+
+ * implement.h (ptw32_threads_thread): New member
+ void ** joinvalueptr.
+ (ptw32_call_t): New member jmpbuf env.
+
+ * exit.c (pthread_exit): Major rewrite to handle joins and handing
+ value pointer to joining thread. Uses longjmp() back to
+ ptw32_start_call().
+
+ * create.c (pthread_create): Ensure values of new attribute members
+ are copied to the thread attribute object.
+
+ * attr.c (pthread_attr_destroy): Fix merge conflicts.
+ (pthread_attr_getdetachstate): Fix merge conflicts.
+ (pthread_attr_setdetachstate): Fix merge conflicts.
+
+ * pthread.h: Fix merge conflicts.
+
+ * sync.c (pthread_join): Fix merge conflicts.
+
+Fri Jul 24 00:21:21 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * sync.c (pthread_join): Add check for valid and joinable
+ thread.
+ (pthread_detach): Implement. After checking for a valid and joinable
+ thread, it's still a no-op.
+
+ * private.c (ptw32_find_thread_entry): Bug prevented returning
+ an error value in some cases.
+
+ * attr.c (pthread_attr_setdetachedstate): Implement.
+ (pthread_attr_getdetachedstate): Implement.
+
+ * implement.h: Move more hidden definitions into here from
+ pthread.h.
+
+1998-07-24 Ben Elliston <bje at cygnus.com>
+
+ * pthread.h (PTHREAD_CREATE_JOINABLE): Define.
+ (PTHREAD_CREATE_DETACHED): Likewise.
+ (pthread_attr_t): Add new structure member `detached'.
+ (pthread_attr_getdetachstate): Add function prototype.
+ (pthread_attr_setdetachstate): Likewise.
+
+ * sync.c (pthread_join): Return if the target thread is detached.
+
+ * attr.c (pthread_attr_init): Initialise cancelability and
+ canceltype structure members.
+ (pthread_attr_getdetachstate): Implement.
+ (pthread_attr_setdetachstate): Likewise.
+
+ * implement.h (PTW32_CANCEL_DEFAULTS): Remove. Bit fields
+ proved to be too cumbersome. Set the defaults in attr.c using the
+ public PTHREAD_CANCEL_* constants.
+
+ * cancel.c: New file.
+
+ * pthread.h (sched_param): Define this type.
+ (pthread_attr_getschedparam): Add function prototype.
+ (pthread_attr_setschedparam): Likewise.
+ (pthread_setcancelstate): Likewise.
+ (pthread_setcanceltype): Likewise.
+ (sched_get_priority_min): Likewise.
+ (sched_get_priority_max): Likewise.
+ (pthread_mutexattr_setprotocol): Remove; not supported.
+ (pthread_mutexattr_getprotocol): Likewise.
+ (pthread_mutexattr_setprioceiling): Likewise.
+ (pthread_mutexattr_getprioceiling): Likewise.
+ (pthread_attr_t): Add canceltype member. Update comments.
+ (SCHED_OTHER): Define this scheduling policy constant.
+ (SCHED_FIFO): Likewise.
+ (SCHED_RR): Likewise.
+ (SCHED_MIN): Define the lowest possible value for this constant.
+ (SCHED_MAX): Likewise, the maximum possible value.
+ (PTHREAD_CANCEL_ASYNCHRONOUS): Redefine.
+ (PTHREAD_CANCEL_DEFERRED): Likewise.
+
+ * sched.c: New file.
+ (pthread_setschedparam): Implement.
+ (pthread_getschedparam): Implement.
+ (sched_get_priority_max): Validate policy argument.
+ (sched_get_priority_min): Likewise.
+
+ * mutex.c (pthread_mutexattr_setprotocol): Remove; not supported.
+ (pthread_mutexattr_getprotocol): Likewise.
+ (pthread_mutexattr_setprioceiling): Likewise.
+ (pthread_mutexattr_getprioceiling): Likewise.
+
+Fri Jul 24 00:21:21 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * create.c (pthread_create): Arg to ptw32_new_thread_entry()
+ changed. See next entry. Move mutex locks out. Changes made yesterday
+ and today allow us to start the new thread running rather than
+ temporarily suspended.
+
+ * private.c (ptw32_new_thread_entry): ptw32_thread_table
+ was changed back to a table of thread structures rather than pointers.
+ As such we're trading storage for increaded speed. This routine
+ was modified to work with the new table. Mutex lock put in around
+ global data accesses.
+ (ptw32_find_thread_entry): Ditto
+ (ptw32_delete_thread_entry): Ditto
+
+Thu Jul 23 23:25:30 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * global.c: New. Global data objects declared here. These moved from
+ pthread.h.
+
+ * pthread.h: Move implementation hidden definitions into
+ implement.h.
+
+ * implement.h: Move implementation hidden definitions from
+ pthread.h. Add constants to index into the different handler stacks.
+
+ * cleanup.c (ptw32_handler_push): Simplify args. Restructure.
+ (ptw32_handler_pop): Simplify args. Restructure.
+ (ptw32_handler_pop_all): Simplify args. Restructure.
+
+Wed Jul 22 00:16:22 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * attr.c, implement.h, pthread.h, ChangeLog: Resolve CVS merge
+ conflicts.
+
+ * private.c (ptw32_find_thread_entry): Changes to return type
+ to support leaner ptw32_threads_table[] which now only stores
+ ptw32_thread_thread_t *.
+ (ptw32_new_thread_entry): Internal changes.
+ (ptw32_delete_thread_entry): Internal changes to avoid contention.
+ Calling routines changed accordingly.
+
+ * pthread.h: Modified cleanup macros to use new generic push and pop.
+ Added destructor and atfork stacks to ptw32_threads_thread_t.
+
+ * cleanup.c (ptw32_handler_push, ptw32_handler_pop,
+ ptw32_handler_pop_all): Renamed cleanup push and pop routines
+ and made generic to handle destructors and atfork handlers as
+ well.
+
+ * create.c (ptw32_start_call): New function is a wrapper for
+ all new threads. It allows us to do some cleanup when the thread
+ returns, ie. that is otherwise only done if the thread is cancelled.
+
+ * exit.c (ptw32_vacuum): New function contains code from
+ pthread_exit() that we need in the new ptw32_start_call()
+ as well.
+
+ * implement.h: Various additions and minor changes.
+
+ * pthread.h: Various additions and minor changes.
+ Change cleanup handler macros to use generic handler push and pop
+ functions.
+
+ * attr.c: Minor mods to all functions.
+ (is_attr): Implemented missing function.
+
+ * create.c (pthread_create): More clean up.
+
+ * private.c (ptw32_find_thread_entry): Implement.
+ (ptw32_delete_thread_entry): Implement.
+ (ptw32_new_thread_entry): Implement.
+ These functions manipulate the implementations internal thread
+ table and are part of general code cleanup and modularisation.
+ They replace ptw32_getthreadindex() which was removed.
+
+ * exit.c (pthread_exit): Changed to use the new code above.
+
+ * pthread.h: Add cancelability constants. Update comments.
+
+1998-07-22 Ben Elliston <bje at cygnus.com>
+
+ * attr.c (pthread_setstacksize): Update test of attr argument.
+ (pthread_getstacksize): Likewise.
+ (pthread_setstackaddr): Likewise.
+ (pthread_getstackaddr): Likewise.
+ (pthread_attr_init): No need to allocate any storage.
+ (pthread_attr_destroy): No need to free any storage.
+
+ * mutex.c (is_attr): Not likely to be needed; remove.
+ (remove_attr): Likewise.
+ (insert_attr): Likewise.
+
+ * implement.h (ptw32_mutexattr_t): Moved to a public definition
+ in pthread.h. There was little gain in hiding these details.
+ (ptw32_condattr_t): Likewise.
+ (ptw32_attr_t): Likewise.
+
+ * pthread.h (pthread_atfork): Add function prototype.
+ (pthread_attr_t): Moved here from implement.h.
+
+ * fork.c (pthread_atfork): Preliminary implementation.
+ (ptw32_fork): Likewise.
+
+Wed Jul 22 00:16:22 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * cleanup.c (ptw32_cleanup_push): Implement.
+ (ptw32_cleanup_pop): Implement.
+ (ptw32_do_cancellation): Implement.
+ These are private to the implementation. The real cleanup functions
+ are macros. See below.
+
+ * pthread.h (pthread_cleanup_push): Implement as a macro.
+ (pthread_cleanup_pop): Implement as a macro.
+ Because these are macros which start and end a block, the POSIX scoping
+ requirement is observed. See the comment in the file.
+
+ * exit.c (pthread_exit): Refine the code.
+
+ * create.c (pthread_create): Code cleanup.
+
+ * implement.h (RND_SIZEOF): Add RND_SIZEOF(T) to round sizeof(T)
+ up to multiple of DWORD.
+ Add function prototypes.
+
+ * private.c (ptw32_getthreadindex): "*thread" should have been
+ "thread". Detect empty slot fail condition.
+
+1998-07-20 Ben Elliston <bje at cygnus.com>
+
+ * misc.c (pthread_once): Implement. Don't use a per-application
+ flag and mutex--make `pthread_once_t' contain these elements in
+ their structure. The earlier version had incorrect semantics.
+
+ * pthread.h (ptw32_once_flag): Add new variable. Remove.
+ (ptw32_once_lock): Add new mutex lock to ensure integrity of
+ access to ptw32_once_flag. Remove.
+ (pthread_once): Add function prototype.
+ (pthread_once_t): Define this type.
+
+Mon Jul 20 02:31:05 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * private.c (ptw32_getthreadindex): Implement.
+
+ * pthread.h: Add application static data dependent on
+ _PTHREADS_BUILD_DLL define. This is needed to avoid allocating
+ non-sharable static data within the pthread DLL.
+
+ * implement.h: Add ptw32_cleanup_stack_t, ptw32_cleanup_node_t
+ and PTW32_HASH_INDEX.
+
+ * exit.c (pthread_exit): Begin work on cleanup and de-allocate
+ thread-private storage.
+
+ * create.c (pthread_create): Add thread to thread table.
+ Keep a thread-private copy of the attributes with default values
+ filled in when necessary. Same for the cleanup stack. Make
+ pthread_create C run-time library friendly by using _beginthreadex()
+ instead of CreateThread(). Fix error returns.
+
+Sun Jul 19 16:26:23 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Rename pthreads_thread_count to ptw32_threads_count.
+ Create ptw32_threads_thread_t struct to keep thread specific data.
+
+ * create.c: Rename pthreads_thread_count to ptw32_threads_count.
+ (pthread_create): Handle errors from CreateThread().
+
+1998-07-19 Ben Elliston <bje at cygnus.com>
+
+ * condvar.c (pthread_cond_wait): Generalise. Moved from here ..
+ (cond_wait): To here.
+ (pthread_cond_timedwait): Implement; use generalised cond_wait().
+
+ * pthread.h (pthread_key_t): Define this type.
+ (pthread_key_create): Add function prototype.
+ (pthread_setspecific): Likewise.
+ (pthread_getspecific): Likwise.
+ (pthread_key_delete): Likewise.
+
+ * tsd.c (pthread_key_create): Implement.
+ (pthread_setspecific): Likewise.
+ (pthread_getspecific): Likewise.
+ (pthread_key_delete): Likewise.
+
+ * mutex.c (pthread_mutex_trylock): Return ENOSYS if this function
+ is called on a Win32 platform which is not Windows NT.
+
+1998-07-18 Ben Elliston <bje at cygnus.com>
+
+ * condvar.c (pthread_condattr_init): Do not attempt to malloc any
+ storage; none is needed now that condattr_t is an empty struct.
+ (pthread_condattr_destory): Likewise; do not free storage.
+ (pthread_condattr_setpshared): No longer supported; return ENOSYS.
+ (pthread_condattr_getpshared): Likewise.
+ (pthread_cond_init): Implement with help from Douglas Schmidt.
+ Remember to initialise the cv's internal mutex.
+ (pthread_cond_wait): Likewise.
+ (pthread_cond_signal): Likewise.
+ (pthread_cond_broadcast): Likewise.
+ (pthread_cond_timedwait): Preliminary implementation, but I need
+ to see some API documentation for `WaitForMultipleObject'.
+ (pthread_destory): Implement.
+
+ * pthread.h (pthread_cond_init): Add function protoype.
+ (pthread_cond_broadcast): Likewise.
+ (pthread_cond_signal): Likewise.
+ (pthread_cond_timedwait): Likewise.
+ (pthread_cond_wait): Likewise.
+ (pthread_cond_destroy): Likewise.
+ (pthread_cond_t): Define this type. Fix for u_int. Do not assume
+ that the mutex contained withing the pthread_cond_t structure will
+ be a critical section. Use our new POSIX type!
+
+ * implement.h (ptw32_condattr_t): Remove shared attribute.
+
+1998-07-17 Ben Elliston <bje at cygnus.com>
+
+ * pthread.h (PTHREADS_PROCESS_PRIVATE): Remove.
+ (PTHREAD_PROCESS_SHARED): Likewise. No support for mutexes shared
+ across processes for now.
+ (pthread_mutex_t): Use a Win32 CRITICAL_SECTION type for better
+ performance.
+
+ * implement.h (ptw32_mutexattr_t): Remove shared attribute.
+
+ * mutex.c (pthread_mutexattr_setpshared): This optional function
+ is no longer supported, since we want to implement POSIX mutex
+ variables using the much more efficient Win32 critical section
+ primitives. Critical section objects in Win32 cannot be shared
+ between processes.
+ (pthread_mutexattr_getpshared): Likewise.
+ (pthread_mutexattr_init): No need to malloc any storage; the
+ attributes structure is now empty.
+ (pthread_mutexattr_destroy): This is now a nop.
+ (pthread_mutex_init): Use InitializeCriticalSection().
+ (pthread_mutex_destroy): Use DeleteCriticalSection().
+ (pthread_mutex_lock): Use EnterCriticalSection().
+ (pthread_mutex_trylock): Use TryEnterCriticalSection(). This is
+ not supported by Windows 9x, but trylock is a hack anyway, IMHO.
+ (pthread_mutex_unlock): Use LeaveCriticalSection().
+
+1998-07-14 Ben Elliston <bje at cygnus.com>
+
+ * attr.c (pthread_attr_setstacksize): Implement.
+ (pthread_attr_getstacksize): Likewise.
+ (pthread_attr_setstackaddr): Likewise.
+ (pthread_attr_getstackaddr): Likewise.
+ (pthread_attr_init): Likewise.
+ (pthread_attr_destroy): Likewise.
+
+ * condvar.c (pthread_condattr_init): Add `_cond' to function name.
+
+ * mutex.c (pthread_mutex_lock): Add `_mutex' to function name.
+ (pthread_mutex_trylock): Likewise.
+ (pthread_mutex_unlock): Likewise.
+
+ * pthread.h (pthread_condattr_setpshared): Fix typo.
+ (pthread_attr_init): Add function prototype.
+ (pthread_attr_destroy): Likewise.
+ (pthread_attr_setstacksize): Likewise.
+ (pthread_attr_getstacksize): Likewise.
+ (pthread_attr_setstackaddr): Likewise.
+ (pthread_attr_getstackaddr): Likewise.
+
+Mon Jul 13 01:09:55 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Wrap in #ifndef _IMPLEMENT_H
+
+ * create.c (pthread_create): Map stacksize attr to Win32.
+
+ * mutex.c: Include implement.h
+
+1998-07-13 Ben Elliston <bje at cygnus.com>
+
+ * condvar.c (pthread_condattr_init): Implement.
+ (pthread_condattr_destroy): Likewise.
+ (pthread_condattr_setpshared): Likewise.
+ (pthread_condattr_getpshared): Likewise.
+
+ * implement.h (PTHREAD_THREADS_MAX): Remove trailing semicolon.
+ (PTHREAD_STACK_MIN): Specify; needs confirming.
+ (ptw32_attr_t): Define this type.
+ (ptw32_condattr_t): Likewise.
+
+ * pthread.h (pthread_mutex_t): Define this type.
+ (pthread_condattr_t): Likewise.
+ (pthread_mutex_destroy): Add function prototype.
+ (pthread_lock): Likewise.
+ (pthread_trylock): Likewise.
+ (pthread_unlock): Likewise.
+ (pthread_condattr_init): Likewise.
+ (pthread_condattr_destroy): Likewise.
+ (pthread_condattr_setpshared): Likewise.
+ (pthread_condattr_getpshared): Likewise.
+
+ * mutex.c (pthread_mutex_init): Implement.
+ (pthread_mutex_destroy): Likewise.
+ (pthread_lock): Likewise.
+ (pthread_trylock): Likewise.
+ (pthread_unlock): Likewise.
+
+1998-07-12 Ben Elliston <bje at cygnus.com>
+
+ * implement.h (ptw32_mutexattr_t): Define this implementation
+ internal type. Application programmers only see a mutex attribute
+ object as a void pointer.
+
+ * pthread.h (pthread_mutexattr_t): Define this type.
+ (pthread_mutexattr_init): Add function prototype.
+ (pthread_mutexattr_destroy): Likewise.
+ (pthread_mutexattr_setpshared): Likewise.
+ (pthread_mutexattr_getpshared): Likewise.
+ (pthread_mutexattr_setprotocol): Likewise.
+ (pthread_mutexattr_getprotocol): Likewise.
+ (pthread_mutexattr_setprioceiling): Likewise.
+ (pthread_mutexattr_getprioceiling): Likewise.
+ (PTHREAD_PROCESS_PRIVATE): Define.
+ (PTHREAD_PROCESS_SHARED): Define.
+
+ * mutex.c (pthread_mutexattr_init): Implement.
+ (pthread_mutexattr_destroy): Implement.
+ (pthread_mutexattr_setprotocol): Implement.
+ (pthread_mutexattr_getprotocol): Likewise.
+ (pthread_mutexattr_setprioceiling): Likewise.
+ (pthread_mutexattr_getprioceiling): Likewise.
+ (pthread_mutexattr_setpshared): Likewise.
+ (pthread_mutexattr_getpshared): Likewise.
+ (insert_attr): New function; very preliminary implementation!
+ (is_attr): Likewise.
+ (remove_attr): Likewise.
+
+Sat Jul 11 14:48:54 1998 Ross Johnson <rpj at ixobrychus.canberra.edu.au>
+
+ * implement.h: Preliminary implementation specific defines.
+
+ * create.c (pthread_create): Preliminary implementation.
+
+1998-07-11 Ben Elliston <bje at cygnus.com>
+
+ * sync.c (pthread_join): Implement.
+
+ * misc.c (pthread_equal): Likewise.
+
+ * pthread.h (pthread_join): Add function prototype.
+ (pthread_equal): Likewise.
+
+1998-07-10 Ben Elliston <bje at cygnus.com>
+
+ * misc.c (pthread_self): Implement.
+
+ * exit.c (pthread_exit): Implement.
+
+ * pthread.h (pthread_exit): Add function prototype.
+ (pthread_self): Likewise.
+ (pthread_t): Define this type.
+
+1998-07-09 Ben Elliston <bje at cygnus.com>
+
+ * create.c (pthread_create): A dummy stub right now.
+
+ * pthread.h (pthread_create): Add function prototype.
diff --git a/pthreads/FAQ b/pthreads/FAQ
new file mode 100644
index 000000000..4f2d449b9
--- /dev/null
+++ b/pthreads/FAQ
@@ -0,0 +1,403 @@
+ =========================================
+ PTHREADS-WIN32 Frequently Asked Questions
+ =========================================
+
+INDEX
+-----
+
+Q 1 What is it?
+
+Q 2 Which of the several dll versions do I use?
+ or,
+ What are all these pthread*.dll and pthread*.lib files?
+
+Q 3 What is the library naming convention?
+
+Q 4 Cleanup code default style or: it used to work when I built
+ the library myself, but now it doesn't - why?
+
+Q 5 Why is the default library version now less exception-friendly?
+
+Q 6 Should I use Cygwin or Mingw32 as a development environment?
+
+Q 7 Now that pthreads-win32 builds under Mingw32, why do I get
+ memory access violations (segfaults)?
+
+Q 8 How do I use pthread.dll for Win32 (Visual C++ 5.0)
+
+Q 9 Cancelation doesn't work for me, why?
+
+Q 10 How do I generate pthreadGCE.dll and libpthreadw32.a for use
+ with Mingw32?
+
+=============================================================================
+
+Q 1 What is it?
+---
+
+Pthreads-win32 is an Open Source Software implementation of the
+Threads component of the POSIX 1003.1c 1995 Standard for Microsoft's
+Win32 environment. Some functions from POSIX 1003.1b are also
+supported including semaphores. Other related functions include
+the set of read-write lock functions. The library also supports
+some of the functionality of the Open Group's Single Unix
+specification, version 2, namely mutex types.
+
+See the file "ANNOUNCE" for more information including standards
+conformance details and list of supported routines.
+
+
+------------------------------------------------------------------------------
+
+Q 2 Which of the several dll versions do I use?
+--- or,
+ What are all these pthread*.dll and pthread*.lib files?
+
+Simply, you only use one of them, but you need to choose carefully.
+
+The most important choice you need to make is whether to use a
+version that uses exceptions internally, or not (there are versions
+of the library that use exceptions as part of the thread
+cancelation and cleanup implementation, and one that uses
+setjmp/longjmp instead).
+
+There is some contension amongst POSIX threads experts as
+to how POSIX threads cancelation and exit should work
+with languages that include exceptions and handlers, e.g.
+C++ and even C (Microsoft's Structured Exceptions).
+
+The issue is: should cancelation of a thread in, say,
+a C++ application cause object destructors and C++ exception
+handlers to be invoked as the stack unwinds during thread
+exit, or not?
+
+There seems to be more opinion in favour of using the
+standard C version of the library (no EH) with C++ applications
+since this appears to be the assumption commercial pthreads
+implementations make. Therefore, if you use an EH version
+of pthreads-win32 then you may be under the illusion that
+your application will be portable, when in fact it is likely to
+behave very differently linked with other pthreads libraries.
+
+Now you may be asking: why have you kept the EH versions of
+the library?
+
+There are a couple of reasons:
+- there is division amongst the experts and so the code may
+ be needed in the future. (Yes, it's in the repository and we
+ can get it out anytime in the future, but ...)
+- pthreads-win32 is one of the few implementations, and possibly
+ the only freely available one, that has EH versions. It may be
+ useful to people who want to play with or study application
+ behaviour under these conditions.
+
+
+------------------------------------------------------------------------------
+
+Q 3 What is the library naming convention?
+---
+
+Because the library is being built using various exception
+handling schemes and compilers - and because the library
+may not work reliably if these are mixed in an application,
+each different version of the library has it's own name.
+
+Note 1: the incompatibility is really between EH implementations
+of the different compilers. It should be possible to use the
+standard C version from either compiler with C++ applications
+built with a different compiler. If you use an EH version of
+the library, then you must use the same compiler for the
+application. This is another complication and dependency that
+can be avoided by using only the standard C library version.
+
+Note 2: if you use a standard C pthread*.dll with a C++
+application, then any functions that you define that are
+intended to be called via pthread_cleanup_push() must be
+__cdecl.
+
+Note 3: the intention is to also name either the VC or GC
+version (it should be arbitrary) as pthread.dll, including
+pthread.lib and libpthread.a as appropriate.
+
+In general:
+ pthread[VG]{SE,CE,C}.dll
+ pthread[VG]{SE,CE,C}.lib
+
+where:
+ [VG] indicates the compiler
+ V - MS VC
+ G - GNU C
+
+ {SE,CE,C} indicates the exception handling scheme
+ SE - Structured EH
+ CE - C++ EH
+ C - no exceptions - uses setjmp/longjmp
+
+For example:
+ pthreadVSE.dll (MSVC/SEH)
+ pthreadGCE.dll (GNUC/C++ EH)
+ pthreadGC.dll (GNUC/not dependent on exceptions)
+
+The GNU library archive file names have changed to:
+
+ libpthreadGCE.a
+ libpthreadGC.a
+
+
+------------------------------------------------------------------------------
+
+Q 4 Cleanup code default style or: it used to work when I built
+--- the library myself, but now it doesn't - why?
+
+Up to and including snapshot 2001-07-12, if not defined, the cleanup
+style was determined automatically from the compiler used, and one
+of the following was defined accordingly:
+
+ __CLEANUP_SEH MSVC only
+ __CLEANUP_CXX C++, including MSVC++, GNU G++
+ __CLEANUP_C C, including GNU GCC, not MSVC
+
+These defines determine the style of cleanup (see pthread.h) and,
+most importantly, the way that cancelation and thread exit (via
+pthread_exit) is performed (see the routine ptw32_throw() in 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().
+
+After snapshot 2001-07-12, unless your build explicitly defines (e.g.
+via a compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then
+the build now ALWAYS defaults to __CLEANUP_C style cleanup. This style
+uses setjmp/longjmp in the cancelation and pthread_exit implementations,
+and therefore won't do stack unwinding even when linked to applications
+that have it (e.g. C++ apps). This is for consistency with most/all
+commercial Unix POSIX threads implementations.
+
+Although it was not clearly documented before, it is still necessary to
+build your application using the same __CLEANUP_* define as was
+used for the version of the library that you link with, so that the
+correct parts of pthread.h are included. That is, the possible
+defines require the following library versions:
+
+ __CLEANUP_SEH pthreadVSE.dll
+ __CLEANUP_CXX pthreadVCE.dll or pthreadGCE.dll
+ __CLEANUP_C pthreadVC.dll or pthreadGC.dll
+
+THE POINT OF ALL THIS IS: if you have not been defining one of these
+explicitly, then the defaults have been set according to the compiler
+and language you are using, as described at the top of this
+section.
+
+THIS NOW CHANGES, as has been explained above. For example:
+
+If you were building your application with MSVC++ i.e. using C++
+exceptions (rather than SEH) and not explicitly defining one of
+__CLEANUP_*, then __CLEANUP_C++ was 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
+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, nor when 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 local
+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.
+
+
+------------------------------------------------------------------------------
+
+Q 5 Why is the default library version now less exception-friendly?
+---
+
+Because most commercial Unix POSIX threads implementations don't allow you to
+choose to have stack unwinding. (Compaq's TRU64 Unix is possibly an exception.)
+
+Therefore, providing it in pthread-win32 as a default could be dangerous
+and non-portable. We still provide the choice but you must now consciously
+make it.
+
+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.)
+- 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.
+
+
+------------------------------------------------------------------------------
+
+Q 6 Should I use Cygwin or Mingw32 as a development environment?
+---
+
+Important: see Q7 also.
+
+Use Mingw32 with the MSVCRT library to build applications that use
+the pthreads DLL.
+
+Cygwin's own internal support for POSIX threads is growing.
+Consult that project's documentation for more information.
+
+------------------------------------------------------------------------------
+
+Q 7 Now that pthreads-win32 builds under Mingw32, why do I get
+--- memory access violations (segfaults)?
+
+The latest Mingw32 package has thread-safe exception handling (see Q10).
+Also, see Q6 above.
+
+------------------------------------------------------------------------------
+
+Q 8 How do I use pthread.dll for Win32 (Visual C++ 5.0)
+---
+
+>
+> I'm a "rookie" when it comes to your pthread implementation. I'm currently
+> desperately trying to install the prebuilt .dll file into my MSVC compiler.
+> Could you please provide me with explicit instructions on how to do this (or
+> direct me to a resource(s) where I can acquire such information)?
+>
+> Thank you,
+>
+
+You should have a .dll, .lib, .def, and three .h files. It is recommended
+that you use pthreadVC.dll, rather than pthreadVCE.dll or pthreadVSE.dll
+(see Q2 above).
+
+The .dll can go in any directory listed in your PATH environment
+variable, so putting it into C:\WINDOWS should work.
+
+The .lib file can go in any directory listed in your LIB environment
+variable.
+
+The .h files can go in any directory listed in your INCLUDE
+environment variable.
+
+Or you might prefer to put the .lib and .h files into a new directory
+and add its path to LIB and INCLUDE. You can probably do this easiest
+by editing the file:-
+
+C:\Program Files\DevStudio\vc\bin\vcvars32.bat
+
+The .def file isn't used by anything in the pre-compiled version but
+is included for information.
+
+Cheers.
+Ross
+
+------------------------------------------------------------------------------
+
+Q 9 Cancelation doesn't work for me, why?
+---
+
+> I'm investigating a problem regarding thread cancelation. The thread I want
+> to cancel has PTHREAD_CANCEL_ASYNCHRONOUS, however, this piece of code
+> blocks on the join():
+>
+> if ((retv = Pthread_cancel( recvThread )) == 0)
+> {
+> retv = Pthread_join( recvThread, 0 );
+> }
+>
+> Pthread_* are just macro's; they call pthread_*.
+>
+> The thread recvThread seems to block on a select() call. It doesn't get
+> cancelled.
+>
+> Two questions:
+>
+> 1) is this normal behaviour?
+>
+> 2) if not, how does the cancel mechanism work? I'm not very familliar to
+> win32 programming, so I don't really understand how the *Event() family of
+> calls work.
+
+The answer to your first question is, normal POSIX behaviour would
+be to asynchronously cancel the thread. However, even that doesn't
+guarantee cancelation as the standard only says it should be
+cancelled as soon as possible.
+
+Snapshot 99-11-02 or earlier only partially supports asynchronous cancellation.
+Snapshots since then simulate async cancelation by poking the address of
+a cancelation routine into the PC of the threads context. This requires
+the thread to be resumed in some way for the cancelation to actually
+proceed. This is not true async cancelation, but it is as close as we've
+been able to get to it.
+
+If the thread you're trying to cancel is blocked (for instance, it could be
+waiting for data from the network), it will only get cancelled when it unblocks
+(when the data arrives). For true pre-emptive cancelation in these cases,
+pthreads-win32 from snapshot 2004-05-16 can automatically recognise and use the
+QueueUserAPCEx package by Panagiotis E. Hadjidoukas. This package is available
+from the pthreads-win32 ftp site and is included in the pthreads-win32
+self-unpacking zip from 2004-05-16 onwards.
+
+Using deferred cancelation would normally be the way to go, however,
+even though the POSIX threads standard lists a number of C library
+functions that are defined as deferred cancelation points, there is
+no hookup between those which are provided by Windows and the
+pthreads-win32 library.
+
+Incidently, it's worth noting for code portability that the older POSIX
+threads standards cancelation point lists didn't include "select" because
+(as I read in Butenhof) it wasn't part of POSIX. However, it does appear in
+the SUSV3.
+
+Effectively, the only mandatory cancelation points that pthreads-win32
+recognises are those the library implements itself, ie.
+
+ pthread_testcancel
+ pthread_cond_wait
+ pthread_cond_timedwait
+ pthread_join
+ sem_wait
+ sem_timedwait
+ pthread_delay_np
+
+The following routines from the non-mandatory list in SUSV3 are
+cancelation points in pthreads-win32:
+
+ pthread_rwlock_wrlock
+ pthread_rwlock_timedwrlock
+
+The following routines from the non-mandatory list in SUSV3 are not
+cancelation points in pthreads-win32:
+
+ pthread_rwlock_rdlock
+ pthread_rwlock_timedrdlock
+
+Pthreads-win32 also provides two functions that allow you to create
+cancelation points within your application, but only for cases where
+a thread is going to block on a Win32 handle. These are:
+
+ pthreadCancelableWait(HANDLE waitHandle) /* Infinite wait */
+
+ pthreadCancelableTimedWait(HANDLE waitHandle, DWORD timeout)
+
+------------------------------------------------------------------------------
+
+
+Q 10 How do I create thread-safe applications using
+---- pthreadGCE.dll, libpthreadw32.a and Mingw32?
+
+This should not be a problem with recent versions of MinGW32.
+
+For early versions, see Thomas Pfaff's email at:
+http://sources.redhat.com/ml/pthreads-win32/2002/msg00000.html
+------------------------------------------------------------------------------
+
diff --git a/pthreads/GNUmakefile b/pthreads/GNUmakefile
new file mode 100644
index 000000000..6c48fd23c
--- /dev/null
+++ b/pthreads/GNUmakefile
@@ -0,0 +1,583 @@
+#
+# --------------------------------------------------------------------------
+#
+# 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=.
+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 \
+ 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
+
+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)
diff --git a/pthreads/MAINTAINERS b/pthreads/MAINTAINERS
new file mode 100644
index 000000000..d253c1f69
--- /dev/null
+++ b/pthreads/MAINTAINERS
@@ -0,0 +1,4 @@
+CVS Repository maintainers
+
+Ross Johnson rpj@ise.canberra.edu.au
+Ben Elliston bje@cygnus.com
diff --git a/pthreads/Makefile b/pthreads/Makefile
new file mode 100644
index 000000000..162a08e25
--- /dev/null
+++ b/pthreads/Makefile
@@ -0,0 +1,504 @@
+# This makefile is compatible with MS nmake and can be used as a
+# replacement for buildlib.bat. I've changed the target from an ordinary dll
+# (/LD) to a debugging dll (/LDd).
+#
+# The variables $DLLDEST and $LIBDEST hold the destination directories for the
+# dll and the lib, respectively. Probably all that needs to change is $DEVROOT.
+
+
+# DLL_VER:
+# See pthread.h and README - This number is computed as 'current - age'
+DLL_VER = 2
+DLL_VERD= $(DLL_VER)d
+
+DEVROOT = C:\pthreads
+
+DLLDEST = $(DEVROOT)\DLL
+LIBDEST = $(DEVROOT)\LIB
+HDRDEST = $(DEVROOT)\INCLUDE
+
+DLLS = pthreadVCE$(DLL_VER).dll pthreadVSE$(DLL_VER).dll pthreadVC$(DLL_VER).dll \
+ pthreadVCE$(DLL_VERD).dll pthreadVSE$(DLL_VERD).dll pthreadVC$(DLL_VERD).dll
+INLINED_STAMPS = pthreadVCE$(DLL_VER).stamp pthreadVSE$(DLL_VER).stamp pthreadVC$(DLL_VER).stamp \
+ pthreadVCE$(DLL_VERD).stamp pthreadVSE$(DLL_VERD).stamp pthreadVC$(DLL_VERD).stamp
+STATIC_STAMPS = pthreadVCE$(DLL_VER).static pthreadVSE$(DLL_VER).static pthreadVC$(DLL_VER).static \
+ pthreadVCE$(DLL_VERD).static pthreadVSE$(DLL_VERD).static pthreadVC$(DLL_VERD).static
+
+OPTIM = /O2 /Ob2
+OPTIMD =
+
+CFLAGS = /W3 /MD /nologo /Yd /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H
+CFLAGSD = /Zi $(CFLAGS)
+
+
+# Default cleanup style
+CLEANUP = __CLEANUP_C
+
+# C++ Exceptions
+VCEFLAGS = /GX /TP $(CFLAGS)
+VCEFLAGSD = /GX /TP $(CFLAGSD)
+#Structured Exceptions
+VSEFLAGS = $(CFLAGS)
+VSEFLAGSD = $(CFLAGSD)
+#C cleanup code
+VCFLAGS = $(CFLAGS)
+VCFLAGSD= $(CFLAGSD)
+
+DLL_INLINED_OBJS = \
+ pthread.obj \
+ version.res
+
+# Aggregate modules for inlinability
+DLL_OBJS = \
+ attr.obj \
+ barrier.obj \
+ cancel.obj \
+ cleanup.obj \
+ condvar.obj \
+ create.obj \
+ dll.obj \
+ errno.obj \
+ exit.obj \
+ fork.obj \
+ global.obj \
+ misc.obj \
+ mutex.obj \
+ nonportable.obj \
+ private.obj \
+ rwlock.obj \
+ sched.obj \
+ semaphore.obj \
+ signal.obj \
+ spin.obj \
+ sync.obj \
+ tsd.obj \
+ version.res
+
+# Separate modules for minimising the size of statically linked images
+SMALL_STATIC_OBJS = \
+ pthread_attr_init.obj \
+ pthread_attr_destroy.obj \
+ pthread_attr_getdetachstate.obj \
+ pthread_attr_setdetachstate.obj \
+ pthread_attr_getstackaddr.obj \
+ pthread_attr_setstackaddr.obj \
+ pthread_attr_getstacksize.obj \
+ pthread_attr_setstacksize.obj \
+ pthread_attr_getscope.obj \
+ pthread_attr_setscope.obj \
+ pthread_attr_setschedpolicy.obj \
+ pthread_attr_getschedpolicy.obj \
+ pthread_attr_setschedparam.obj \
+ pthread_attr_getschedparam.obj \
+ pthread_attr_setinheritsched.obj \
+ pthread_attr_getinheritsched.obj \
+ pthread_barrier_init.obj \
+ pthread_barrier_destroy.obj \
+ pthread_barrier_wait.obj \
+ pthread_barrierattr_init.obj \
+ pthread_barrierattr_destroy.obj \
+ pthread_barrierattr_setpshared.obj \
+ pthread_barrierattr_getpshared.obj \
+ pthread_setcancelstate.obj \
+ pthread_setcanceltype.obj \
+ pthread_testcancel.obj \
+ pthread_cancel.obj \
+ cleanup.obj \
+ pthread_condattr_destroy.obj \
+ pthread_condattr_getpshared.obj \
+ pthread_condattr_init.obj \
+ pthread_condattr_setpshared.obj \
+ pthread_cond_destroy.obj \
+ pthread_cond_init.obj \
+ pthread_cond_signal.obj \
+ pthread_cond_wait.obj \
+ create.obj \
+ dll.obj \
+ errno.obj \
+ pthread_exit.obj \
+ fork.obj \
+ global.obj \
+ pthread_mutex_init.obj \
+ pthread_mutex_destroy.obj \
+ pthread_mutexattr_init.obj \
+ pthread_mutexattr_destroy.obj \
+ pthread_mutexattr_getpshared.obj \
+ pthread_mutexattr_setpshared.obj \
+ pthread_mutexattr_settype.obj \
+ pthread_mutexattr_gettype.obj \
+ pthread_mutex_lock.obj \
+ pthread_mutex_timedlock.obj \
+ pthread_mutex_unlock.obj \
+ pthread_mutex_trylock.obj \
+ pthread_mutexattr_setkind_np.obj \
+ pthread_mutexattr_getkind_np.obj \
+ pthread_getw32threadhandle_np.obj \
+ pthread_delay_np.obj \
+ pthread_num_processors_np.obj \
+ pthread_win32_attach_detach_np.obj \
+ pthread_equal.obj \
+ pthread_getconcurrency.obj \
+ pthread_once.obj \
+ pthread_self.obj \
+ pthread_setconcurrency.obj \
+ pthread_rwlock_init.obj \
+ pthread_rwlock_destroy.obj \
+ pthread_rwlockattr_init.obj \
+ pthread_rwlockattr_destroy.obj \
+ pthread_rwlockattr_getpshared.obj \
+ pthread_rwlockattr_setpshared.obj \
+ pthread_rwlock_rdlock.obj \
+ pthread_rwlock_wrlock.obj \
+ pthread_rwlock_unlock.obj \
+ pthread_rwlock_tryrdlock.obj \
+ pthread_rwlock_trywrlock.obj \
+ pthread_setschedparam.obj \
+ pthread_getschedparam.obj \
+ pthread_timechange_handler_np.obj \
+ ptw32_is_attr.obj \
+ ptw32_processInitialize.obj \
+ ptw32_processTerminate.obj \
+ ptw32_threadStart.obj \
+ ptw32_threadDestroy.obj \
+ ptw32_tkAssocCreate.obj \
+ ptw32_tkAssocDestroy.obj \
+ ptw32_callUserDestroyRoutines.obj \
+ ptw32_timespec.obj \
+ ptw32_throw.obj \
+ ptw32_InterlockedCompareExchange.obj \
+ ptw32_getprocessors.obj \
+ ptw32_calloc.obj \
+ ptw32_new.obj \
+ ptw32_reuse.obj \
+ ptw32_rwlock_check_need_init.obj \
+ ptw32_cond_check_need_init.obj \
+ ptw32_mutex_check_need_init.obj \
+ ptw32_semwait.obj \
+ ptw32_relmillisecs.obj \
+ 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 wsock32.lib /out:$@
+
+$(INLINED_STAMPS): $(DLL_INLINED_OBJS)
+ cl /LDd /Zi /nologo $(DLL_INLINED_OBJS) \
+ /link /nodefaultlib:libcmt /implib:$*.lib \
+ msvcrt.lib wsock32.lib /out:$*.dll
+
+$(STATIC_STAMPS): $(DLL_INLINED_OBJS)
+ if exist $*.lib del $*.lib
+ lib $(DLL_INLINED_OBJS) /out:$*.lib
+
+.c.obj:
+ cl $(EHFLAGS) /D$(CLEANUP) -c $<
+
+.rc.res:
+ rc /dPTW32_RC_MSC /d$(CLEANUP) $<
+
+.c.i:
+ cl /P /O2 /Ob1 $(VCFLAGS) $<
+
+attr.obj: attr.c $(ATTR_SRCS) $(INCL)
+barrier.obj: barrier.c $(BARRIER_SRCS) $(INCL)
+cancel.obj: cancel.c $(CANCEL_SRCS) $(INCL)
+condvar.obj: condvar.c $(CONDVAR_SRCS) $(INCL)
+exit.obj: exit.c $(EXIT_SRCS) $(INCL)
+misc.obj: misc.c $(MISC_SRCS) $(INCL)
+mutex.obj: mutex.c $(MUTEX_SRCS) $(INCL)
+nonportable.obj: nonportable.c $(NONPORTABLE_SRCS) $(INCL)
+private.obj: private.c $(PRIVATE_SRCS) $(INCL)
+rwlock.obj: rwlock.c $(RWLOCK_SRCS) $(INCL)
+sched.obj: sched.c $(SCHED_SRCS) $(INCL)
+semaphore.obj: semaphore.c $(SEMAPHORE_SRCS) $(INCL)
+spin.obj: spin.c $(SPIN_SRCS) $(INCL)
+sync.obj: sync.c $(SYNC_SRCS) $(INCL)
+tsd.obj: tsd.c $(TSD_SRCS) $(INCL)
+version.res: version.rc $(INCL)
diff --git a/pthreads/NEWS b/pthreads/NEWS
new file mode 100644
index 000000000..18fe54325
--- /dev/null
+++ b/pthreads/NEWS
@@ -0,0 +1,1110 @@
+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 <RKubis at mc.com>
+
+* Various package omissions have been fixed.
+
+
+SNAPSHOT 2005-01-03
+-------------------
+Version 1.1.0
+
+Bug fixes
+---------
+
+* Unlocking recursive or errorcheck mutexes would sometimes
+unexpectedly return an EPERM error (bug introduced in
+snapshot-2004-11-03).
+- Konstantin Voronkov <beowinkle at yahoo.com>
+
+
+SNAPSHOT 2004-11-22
+-------------------
+Version 1.0.0
+
+This snapshot primarily fixes the condvar bug introduced in
+snapshot-2004-11-03. DLL versioning has also been included to allow
+applications to runtime check the Microsoft compatible DLL version
+information, and to extend the DLL naming system for ABI and major
+(non-backward compatible) API changes. See the README file for details.
+
+Bug fixes
+---------
+
+* Condition variables no longer deadlock (bug introduced in
+snapshot-2004-11-03).
+- Alexander Kotliarov and Nicolas at saintmac
+
+* DLL naming extended to avoid 'DLL hell' in the future, and to
+accommodate the ABI change introduced in snapshot-2004-11-03. Snapshot
+2004-11-03 will be removed from FTP sites.
+
+New features
+------------
+
+* A Microsoft-style version resource has been added to the DLL for
+applications that wish to check DLL compatibility at runtime.
+
+* Pthreads-win32 DLL naming has been extended to allow incompatible DLL
+versions to co-exist in the same filesystem. See the README file for details,
+but briefly: while the version information inside the DLL will change with
+each release from now on, the DLL version names will only change if the new
+DLL is not backward compatible with older applications.
+
+The versioning scheme has been borrowed from GNU Libtool, and the DLL
+naming scheme is from Cygwin. Provided the Libtool-style numbering rules are
+honoured, the Cygwin DLL naming scheme automatcally ensures that DLL name
+changes are minimal and that applications will not load an incompatible
+pthreads-win32 DLL.
+
+Those who use the pre-built DLLs will find that the DLL/LIB names have a new
+suffix (1) in this snapshot. E.g. pthreadVC1.dll etc.
+
+* The POSIX thread ID reuse uniqueness feature introduced in the last snapshot
+has been kept as default, but the behaviour can now be controlled when the DLL
+is built to effectively switch it off. This makes the library much more
+sensitive to applications that assume that POSIX thread IDs are unique, i.e.
+are not strictly compliant with POSIX. See the PTW32_THREAD_ID_REUSE_INCREMENT
+macro comments in config.h for details.
+
+Other changes
+-------------
+Certain POSIX macros have changed.
+
+These changes are intended to conform to the Single Unix Specification version 3,
+which states that, if set to 0 (zero) or not defined, then applications may use
+sysconf() to determine their values at runtime. Pthreads-win32 does not
+implement sysconf().
+
+The following macros are no longer undefined, but defined and set to -1
+(not implemented):
+
+ _POSIX_THREAD_ATTR_STACKADDR
+ _POSIX_THREAD_PRIO_INHERIT
+ _POSIX_THREAD_PRIO_PROTECT
+ _POSIX_THREAD_PROCESS_SHARED
+
+The following macros are defined and set to 200112L (implemented):
+
+ _POSIX_THREADS
+ _POSIX_THREAD_SAFE_FUNCTIONS
+ _POSIX_THREAD_ATTR_STACKSIZE
+ _POSIX_THREAD_PRIORITY_SCHEDULING
+ _POSIX_SEMAPHORES
+ _POSIX_READER_WRITER_LOCKS
+ _POSIX_SPIN_LOCKS
+ _POSIX_BARRIERS
+
+The following macros are defined and set to appropriate values:
+
+ _POSIX_THREAD_THREADS_MAX
+ _POSIX_SEM_VALUE_MAX
+ _POSIX_SEM_NSEMS_MAX
+ PTHREAD_DESTRUCTOR_ITERATIONS
+ PTHREAD_KEYS_MAX
+ PTHREAD_STACK_MIN
+ PTHREAD_THREADS_MAX
+
+
+SNAPSHOT 2004-11-03
+-------------------
+
+DLLs produced from this snapshot cannot be used with older applications without
+recompiling the application, due to a change to pthread_t to provide unique POSIX
+thread IDs.
+
+Although this snapshot passes the extended test suite, many of the changes are
+fairly major, and some applications may show different behaviour than previously,
+so adopt with care. Hopefully, any changed behaviour will be due to the library
+being better at it's job, not worse.
+
+Bug fixes
+---------
+
+* pthread_create() no longer accepts NULL as the thread reference arg.
+A segfault (memory access fault) will result, and no thread will be
+created.
+
+* pthread_barrier_wait() no longer acts as a cancelation point.
+
+* Fix potential race condition in pthread_once()
+- Tristan Savatier <tristan at mpegtv.com>
+
+* Changes to pthread_cond_destroy() exposed some coding weaknesses in several
+test suite mini-apps because pthread_cond_destroy() now returns EBUSY if the CV
+is still in use.
+
+New features
+------------
+
+* Added for compatibility:
+PTHREAD_RECURSIVE_MUTEX_INITIALIZER,
+PTHREAD_ERRORCHECK_MUTEX_INITIALIZER,
+PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
+PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+
+* Initial support for Digital Mars compiler
+- Anuj Goyal <anuj.goyal at gmail.com>
+
+* Faster Mutexes. These have been been rewritten following a model provided by
+Alexander Terekhov that reduces kernel space checks, and eliminates some additional
+critical sections used to manage a race between timedlock expiration and unlock.
+Please be aware that the new mutexes do not enforce strict absolute FIFO scheduling
+of mutexes, however any out-of-order lock acquisition should be very rare.
+
+* Faster semaphores. Following a similar model to mutexes above, these have been
+rewritten to use preliminary users space checks.
+
+* sem_getvalue() now returns the number of waiters.
+
+* The POSIX thread ID now has much stronger uniqueness characteristics. The library
+garrantees not to reuse the same thread ID for at least 2^(wordsize) thread
+destruction/creation cycles.
+
+New tests
+---------
+
+* semaphore4.c: Tests cancelation of the new sem_wait().
+
+* semaphore4t.c: Likewise for sem_timedwait().
+
+* rwlock8.c: Tests and times the slow execution paths of r/w locks, and the CVs,
+mutexes, and semaphores that they're built on.
+
+
+SNAPSHOT 2004-05-16
+-------------------
+
+Attempt to add Watcom to the list of compilers that can build the library.
+This failed in the end due to it's non-thread-aware errno. The library
+builds but the test suite fails. See README.Watcom for more details.
+
+Bug fixes
+---------
+* Bug and memory leak in sem_init()
+- Alex Blanco <Alex.Blanco at motorola.com>
+
+* ptw32_getprocessors() now returns CPU count of 1 for WinCE.
+- James Ewing <james.ewing at sveasoft.com>
+
+* pthread_cond_wait() could be canceled at a point where it should not
+be cancelable. Fixed.
+- Alexander Terekhov <TEREKHOV at de.ibm.com>
+
+* sem_timedwait() had an incorrect timeout calculation.
+- Philippe Di Cristo <philipped at voicebox.com>
+
+* Fix a memory leak left behind after threads are destroyed.
+- P. van Bruggen <pietvb at newbridges.nl>
+
+New features
+------------
+* Ported to AMD64.
+- Makoto Kato <raven at oldskool.jp>
+
+* True pre-emptive asynchronous cancelation of threads. This is optional
+and requires that Panagiotis E. Hadjidoukas's QueueUserAPCEx package be
+installed. This package is included in the pthreads-win32 self-unpacking
+Zip archive starting from this snapshot. See the README.txt file inside
+the package for installation details.
+
+Note: If you don't use async cancelation in your application, or don't need
+to cancel threads that are blocked on system resources such as network I/O,
+then the default non-preemptive async cancelation is probably good enough.
+However, pthreads-win32 auto-detects the availability of these components
+at run-time, so you don't need to rebuild the library from source if you
+change your mind later.
+
+All of the advice available in books and elsewhere on the undesirability
+of using async cancelation in any application still stands, but this
+feature is a welcome addition with respect to the library's conformance to
+the POSIX standard.
+
+SNAPSHOT 2003-09-18
+-------------------
+
+Cleanup of thread priority management. In particular, setting of thread
+priority now attempts to map invalid Win32 values within the range returned
+by sched_get_priority_min/max() to useful values. See README.NONPORTABLE
+under "Thread priority".
+
+Bug fixes
+---------
+* pthread_getschedparam() now returns the priority given by the most recent
+call to pthread_setschedparam() or established by pthread_create(), as
+required by the standard. Previously, pthread_getschedparam() incorrectly
+returned the running thread priority at the time of the call, which may have
+been adjusted or temporarily promoted/demoted.
+
+* sched_get_priority_min() and sched_get_priority_max() now return -1 on error
+and set errno. Previously, they incorrectly returned the error value directly.
+
+
+SNAPSHOT 2003-09-04
+-------------------
+
+Bug fixes
+---------
+* ptw32_cancelableWait() now allows cancelation of waiting implicit POSIX
+threads.
+
+New test
+--------
+* cancel8.c tests cancelation of Win32 threads waiting at a POSIX cancelation
+point.
+
+
+SNAPSHOT 2003-09-03
+-------------------
+
+Bug fixes
+---------
+* pthread_self() would free the newly created implicit POSIX thread handle if
+DuplicateHandle failed instead of recycle it (very unlikely).
+
+* pthread_exit() was neither freeing nor recycling the POSIX thread struct
+for implicit POSIX threads.
+
+New feature - Cancelation of/by Win32 (non-POSIX) threads
+---------------------------------------------------------
+Since John Bossom's original implementation, the library has allowed non-POSIX
+initialised threads (Win32 threads) to call pthreads-win32 routines and
+therefore interact with POSIX threads. This is done by creating an on-the-fly
+POSIX thread ID for the Win32 thread that, once created, allows fully
+reciprical interaction. This did not extend to thread cancelation (async or
+deferred). Now it does.
+
+Any thread can be canceled by any other thread (Win32 or POSIX) if the former
+thread's POSIX pthread_t value is known. It's TSD destructors and POSIX
+cleanup handlers will be run before the thread exits with an exit code of
+PTHREAD_CANCELED (retrieved with GetExitCodeThread()).
+
+This allows a Win32 thread to, for example, call POSIX CV routines in the same way
+that POSIX threads would/should, with pthread_cond_wait() cancelability and
+cleanup handlers (pthread_cond_wait() is a POSIX cancelation point).
+
+By adding cancelation, Win32 threads should now be able to call all POSIX
+threads routines that make sense including semaphores, mutexes, condition
+variables, read/write locks, barriers, spinlocks, tsd, cleanup push/pop,
+cancelation, pthread_exit, scheduling, etc.
+
+Note that these on-the-fly 'implicit' POSIX thread IDs are initialised as detached
+(not joinable) with deferred cancelation type. The POSIX thread ID will be created
+automatically by any POSIX routines that need a POSIX handle (unless the routine
+needs a pthread_t as a parameter of course). A Win32 thread can discover it's own
+POSIX thread ID by calling pthread_self(), which will create the handle if
+necessary and return the pthread_t value.
+
+New tests
+---------
+Test the above new feature.
+
+
+SNAPSHOT 2003-08-19
+-------------------
+
+This snapshot fixes some accidental corruption to new test case sources.
+There are no changes to the library source code.
+
+
+SNAPSHOT 2003-08-15
+-------------------
+
+Bug fixes
+---------
+
+* pthread.dsp now uses correct compile flags (/MD).
+- Viv <vcotirlea@hotmail.com>
+
+* pthread_win32_process_detach_np() fixed memory leak.
+- Steven Reddie <Steven.Reddie@ca.com>
+
+* pthread_mutex_destroy() fixed incorrect return code.
+- Nicolas Barry <boozai@yahoo.com>
+
+* pthread_spin_destroy() fixed memory leak.
+- Piet van Bruggen <pietvb@newbridges.nl>
+
+* Various changes to tighten arg checking, and to work with later versions of
+MinGW32 and MsysDTK.
+
+* pthread_getschedparam() etc, fixed dangerous thread validity checking.
+- Nicolas Barry <boozai@yahoo.com>
+
+* POSIX thread handles are now reused and their memory is not freed on thread exit.
+This allows for stronger thread validity checking.
+
+New standard routine
+--------------------
+
+* pthread_kill() added to provide thread validity checking to applications.
+It does not accept any non zero values for the signal arg.
+
+New test cases
+--------------
+
+* New test cases to confirm validity checking, pthread_kill(), and thread reuse.
+
+
+SNAPSHOT 2003-05-10
+-------------------
+
+Bug fixes
+---------
+
+* pthread_mutex_trylock() now returns correct error values.
+pthread_mutex_destroy() will no longer destroy a recursively locked mutex.
+pthread_mutex_lock() is no longer inadvertantly behaving as a cancelation point.
+- Thomas Pfaff <tpfaff@gmx.net>
+
+* pthread_mutex_timedlock() no longer occasionally sets incorrect mutex
+ownership, causing deadlocks in some applications.
+- Robert Strycek <strycek@posam.sk> and Alexander Terekhov <TEREKHOV@de.ibm.com>
+
+
+SNAPSHOT 2002-11-04
+-------------------
+
+Bug fixes
+---------
+
+* sem_getvalue() now returns the correct value under Win NT and WinCE.
+- Rob Fanner <rfanner@stonethree.com>
+
+* sem_timedwait() now uses tighter checks for unreasonable
+abstime values - that would result in unexpected timeout values.
+
+* ptw32_cond_wait_cleanup() no longer mysteriously consumes
+CV signals but may produce more spurious wakeups. It is believed
+that the sem_timedwait() call is consuming a CV signal that it
+shouldn't.
+- Alexander Terekhov <TEREKHOV@de.ibm.com>
+
+* Fixed a memory leak in ptw32_threadDestroy() for implicit threads.
+
+* Fixed potential for deadlock in pthread_cond_destroy().
+A deadlock could occur for statically declared CVs (PTHREAD_COND_INITIALIZER),
+when one thread is attempting to destroy the condition variable while another
+is attempting to dynamically initialize it.
+- Michael Johnson <michaelj@maine.rr.com>
+
+
+SNAPSHOT 2002-03-02
+-------------------
+
+Cleanup code default style. (IMPORTANT)
+----------------------------------------------------------------------
+Previously, if not defined, the cleanup style was determined automatically
+from the compiler/language, and one of the following was defined accordingly:
+
+ __CLEANUP_SEH MSVC only
+ __CLEANUP_CXX C++, including MSVC++, GNU G++
+ __CLEANUP_C C, including GNU GCC, not MSVC
+
+These defines determine the style of cleanup (see pthread.h) and,
+most importantly, the way that cancelation and thread exit (via
+pthread_exit) is performed (see the routine ptw32_throw() in private.c).
+
+In short, the exceptions versions of the library throw an exception
+when a thread is canceled or exits (via pthread_exit()), which is
+caught by a handler in the thread startup routine, so that the
+the correct stack unwinding occurs regardless of where the thread
+is when it's canceled or exits via pthread_exit().
+
+In this and future snapshots, unless the build explicitly defines (e.g.
+via a compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then
+the build NOW always defaults to __CLEANUP_C style cleanup. This style
+uses setjmp/longjmp in the cancelation and pthread_exit implementations,
+and therefore won't do stack unwinding even when linked to applications
+that have it (e.g. C++ apps). This is for consistency with most
+current commercial Unix POSIX threads implementations. Compaq's TRU64
+may be an exception (no pun intended) and possible future trend.
+
+Although it was not clearly documented before, it is still necessary to
+build your application using the same __CLEANUP_* define as was
+used for the version of the library that you link with, so that the
+correct parts of pthread.h are included. That is, the possible
+defines require the following library versions:
+
+ __CLEANUP_SEH pthreadVSE.dll
+ __CLEANUP_CXX pthreadVCE.dll or pthreadGCE.dll
+ __CLEANUP_C pthreadVC.dll or pthreadGC.dll
+
+E.g. regardless of whether your app is C or C++, if you link with
+pthreadVC.lib or libpthreadGC.a, then you must define __CLEANUP_C.
+
+
+THE POINT OF ALL THIS IS: if you have not been defining one of these
+explicitly, then the defaults as described at the top of this
+section were being used.
+
+THIS NOW CHANGES, as has been explained above, but to try to make this
+clearer here's an example:
+
+If you were building your application with MSVC++ i.e. using C++
+exceptions and not explicitly defining one of __CLEANUP_*, then
+__CLEANUP_C++ was automatically defined for you in pthread.h.
+You should have been linking with pthreadVCE.dll, which does
+stack unwinding.
+
+If you now build your application as you had before, pthread.h will now
+automatically set __CLEANUP_C as the default style, and you will need to
+link with pthreadVC.dll. Stack unwinding will now NOT occur when a thread
+is canceled, or the thread calls pthread_exit().
+
+Your application will now most likely behave differently to previous
+versions, and in non-obvious ways. Most likely is that locally
+instantiated objects may not be destroyed or cleaned up after a thread
+is canceled.
+
+If you want the same behaviour as before, then you must now define
+__CLEANUP_C++ explicitly using a compiler option and link with
+pthreadVCE.dll as you did before.
+
+
+WHY ARE WE MAKING THE DEFAULT STYLE LESS EXCEPTION-FRIENDLY?
+Because no commercial Unix POSIX threads implementation allows you to
+choose to have stack unwinding. Therefore, providing it in pthread-win32
+as a default is dangerous. We still provide the choice but unless
+you consciously choose to do otherwise, your pthreads applications will
+now run or crash in similar ways irrespective of the threads platform
+you use. Or at least this is the hope.
+
+
+WHY NOT REMOVE THE EXCEPTIONS VERSIONS OF THE LIBRARY ALTOGETHER?
+There are a few reasons:
+- because there are well respected POSIX threads people who believe
+ that POSIX threads implementations should be exceptions aware and
+ do the expected thing in that context. (There are equally respected
+ people who believe it should not be easily accessible, if it's there
+ at all, for unconditional conformity to other implementations.)
+- because pthreads-win32 is one of the few implementations that has
+ the choice, perhaps the only freely available one, and so offers
+ a laboratory to people who may want to explore the effects;
+- although the code will always be around somewhere for anyone who
+ wants it, once it's removed from the current version it will not be
+ nearly as visible to people who may have a use for it.
+
+
+Source module splitting
+-----------------------
+In order to enable smaller image sizes to be generated
+for applications that link statically with the library,
+most routines have been separated out into individual
+source code files.
+
+This is being done in such a way as to be backward compatible.
+The old source files are reused to congregate the individual
+routine files into larger translation units (via a bunch of
+# includes) so that the compiler can still optimise wherever
+possible, e.g. through inlining, which can only be done
+within the same translation unit.
+
+It is also possible to build the entire library by compiling
+the single file named "pthread.c", which just #includes all
+the secondary congregation source files. The compiler
+may be able to use this to do more inlining of routines.
+
+Although the GNU compiler is able to produce libraries with
+the necessary separation (the -ffunction-segments switch),
+AFAIK, the MSVC and other compilers don't have this feature.
+
+Finally, since I use makefiles and command-line compilation,
+I don't know what havoc this reorganisation may wreak amongst
+IDE project file users. You should be able to continue
+using your existing project files without modification.
+
+
+New non-portable functions
+--------------------------
+pthread_num_processors_np():
+ Returns the number of processors in the system that are
+ available to the process, as determined from the processor
+ affinity mask.
+
+pthread_timechange_handler_np():
+ To improve tolerance against operator or time service initiated
+ system clock changes.
+
+ This routine can be called by an application when it
+ receives a WM_TIMECHANGE message from the system. At present
+ it broadcasts all condition variables so that waiting threads
+ can wake up and re-evaluate their conditions and restart
+ their timed waits if required.
+ - Suggested by Alexander Terekhov
+
+
+Platform dependence
+-------------------
+As Win95 doesn't provide one, the library now contains
+it's own InterlockedCompareExchange() routine, which is used
+whenever Windows doesn't provide it. InterlockedCompareExchange()
+is used to implement spinlocks and barriers, and also in mutexes.
+This routine relies on the CMPXCHG machine instruction which
+is not available on i386 CPUs. This library (from snapshot
+20010712 onwards) is therefore no longer supported on i386
+processor platforms.
+
+
+New standard routines
+---------------------
+For source code portability only - rwlocks cannot be process shared yet.
+
+ pthread_rwlockattr_init()
+ pthread_rwlockattr_destroy()
+ pthread_rwlockattr_setpshared()
+ pthread_rwlockattr_getpshared()
+
+As defined in the new POSIX standard, and the Single Unix Spec version 3:
+
+ sem_timedwait()
+ pthread_mutex_timedlock() - Alexander Terekhov and Thomas Pfaff
+ pthread_rwlock_timedrdlock() - adapted from pthread_rwlock_rdlock()
+ pthread_rwlock_timedwrlock() - adapted from pthread_rwlock_wrlock()
+
+
+pthread.h no longer includes windows.h
+--------------------------------------
+[Not yet for G++]
+
+This was done to prevent conflicts.
+
+HANDLE, DWORD, and NULL are temporarily defined within pthread.h if
+they are not already.
+
+
+pthread.h, sched.h and semaphore.h now use dllexport/dllimport
+--------------------------------------------------------------
+Not only to avoid the need for the pthread.def file, but to
+improve performance. Apparently, declaring functions with dllimport
+generates a direct call to the function and avoids the overhead
+of a stub function call.
+
+Bug fixes
+---------
+* Fixed potential NULL pointer dereferences in pthread_mutexattr_init,
+pthread_mutexattr_getpshared, pthread_barrierattr_init,
+pthread_barrierattr_getpshared, and pthread_condattr_getpshared.
+- Scott McCaskill <scott@magruder.org>
+
+* Removed potential race condition in pthread_mutex_trylock and
+pthread_mutex_lock;
+- Alexander Terekhov <TEREKHOV@de.ibm.com>
+
+* The behaviour of pthread_mutex_trylock in relation to
+recursive mutexes was inconsistent with commercial implementations.
+Trylock would return EBUSY if the lock was owned already by the
+calling thread regardless of mutex type. Trylock now increments the
+recursion count and returns 0 for RECURSIVE mutexes, and will
+return EDEADLK rather than EBUSY for ERRORCHECK mutexes. This is
+consistent with Solaris.
+- Thomas Pfaff <tpfaff@gmx.net>
+
+* Found a fix for the library and workaround for applications for
+the known bug #2, i.e. where __CLEANUP_CXX or __CLEANUP_SEH is defined.
+See the "Known Bugs in this snapshot" section below.
+
+This could be made transparent to applications by replacing the macros that
+define the current C++ and SEH versions of pthread_cleanup_push/pop
+with the C version, but AFAIK cleanup handlers would not then run in the
+correct sequence with destructors and exception cleanup handlers when
+an exception occurs.
+
+* Cancelation once started in a thread cannot now be inadvertantly
+double canceled. That is, once a thread begins it's cancelation run,
+cancelation is disabled and a subsequent cancel request will
+return an error (ESRCH).
+
+* errno: An incorrect compiler directive caused a local version
+of errno to be used instead of the Win32 errno. Both instances are
+thread-safe but applications checking errno after a pthreads-win32
+call would be wrong. Fixing this also fixed a bad compiler
+option in the testsuite (/MT should have been /MD) which is
+needed to link with the correct library MSVCRT.LIB.
+
+
+SNAPSHOT 2001-07-12
+-------------------
+
+To be added
+
+
+SNAPSHOT 2001-07-03
+-------------------
+
+To be added
+
+
+SNAPSHOT 2000-08-13
+-------------------
+
+New:
+- Renamed DLL and LIB files:
+ pthreadVSE.dll (MS VC++/Structured EH)
+ pthreadVSE.lib
+ pthreadVCE.dll (MS VC++/C++ EH)
+ pthreadVCE.lib
+ pthreadGCE.dll (GNU G++/C++ EH)
+ libpthreadw32.a
+
+ Both your application and the pthread dll should use the
+ same exception handling scheme.
+
+Bugs fixed:
+- MSVC++ C++ exception handling.
+
+Some new tests have been added.
+
+
+SNAPSHOT 2000-08-10
+-------------------
+
+New:
+- asynchronous cancelation on X86 (Jason Nye)
+- Makefile compatible with MS nmake to replace
+ buildlib.bat
+- GNUmakefile for Mingw32
+- tests/Makefile for MS nmake replaces runall.bat
+- tests/GNUmakefile for Mingw32
+
+Bugs fixed:
+- kernel32 load/free problem
+- attempt to hide internel exceptions from application
+ exception handlers (__try/__except and try/catch blocks)
+- Win32 thread handle leakage bug
+ (David Baggett/Paul Redondo/Eyal Lebedinsky)
+
+Some new tests have been added.
+
+
+SNAPSHOT 1999-11-02
+-------------------
+
+Bugs fixed:
+- ctime_r macro had an incorrect argument (Erik Hensema),
+- threads were not being created
+ PTHREAD_CANCEL_DEFERRED. This should have
+ had little effect as deferred is the only
+ supported type. (Ross Johnson).
+
+Some compatibility improvements added, eg.
+- pthread_setcancelstate accepts NULL pointer
+ for the previous value argument. Ditto for
+ pthread_setcanceltype. This is compatible
+ with Solaris but should not affect
+ standard applications (Erik Hensema)
+
+Some new tests have been added.
+
+
+SNAPSHOT 1999-10-17
+-------------------
+
+Bug fix - Cancelation of threads waiting on condition variables
+now works properly (Lorin Hochstein and Peter Slacik)
+
+
+SNAPSHOT 1999-08-12
+-------------------
+
+Fixed exception stack cleanup if calling pthread_exit()
+- (Lorin Hochstein and John Bossom).
+
+Fixed bugs in condition variables - (Peter Slacik):
+ - additional contention checks
+ - properly adjust number of waiting threads after timed
+ condvar timeout.
+
+
+SNAPSHOT 1999-05-30
+-------------------
+
+Some minor bugs have been fixed. See the ChangeLog file for details.
+
+Some more POSIX 1b functions are now included but ony return an
+error (ENOSYS) if called. They are:
+
+ sem_open
+ sem_close
+ sem_unlink
+ sem_getvalue
+
+
+SNAPSHOT 1999-04-07
+-------------------
+
+Some POSIX 1b functions which were internally supported are now
+available as exported functions:
+
+ sem_init
+ sem_destroy
+ sem_wait
+ sem_trywait
+ sem_post
+ sched_yield
+ sched_get_priority_min
+ sched_get_priority_max
+
+Some minor bugs have been fixed. See the ChangeLog file for details.
+
+
+SNAPSHOT 1999-03-16
+-------------------
+
+Initial release.
+
diff --git a/pthreads/Nmakefile b/pthreads/Nmakefile
new file mode 100644
index 000000000..e6c74dd71
--- /dev/null
+++ b/pthreads/Nmakefile
@@ -0,0 +1,24 @@
+/*
+ * nmake file for uwin pthread library
+ */
+
+VERSION = -
+CCFLAGS = -V -g $(CC.DLL)
+HAVE_CONFIG_H == 1
+_MT == 1
+_timeb == timeb
+_ftime == ftime
+_errno == _ast_errno
+
+$(INCLUDEDIR) :INSTALLDIR: pthread.h sched.h
+
+pthread $(VERSION) :LIBRARY: attr.c barrier.c cancel.c cleanup.c condvar.c \
+ create.c dll.c exit.c fork.c global.c misc.c mutex.c private.c \
+ rwlock.c sched.c semaphore.c spin.c sync.c tsd.c nonportable.c
+
+:: ANNOUNCE CONTRIBUTORS COPYING.LIB ChangeLog FAQ GNUmakefile MAINTAINERS \
+ Makefile Makefile.in Makefile.vc NEWS PROGRESS README README.WinCE \
+ TODO WinCE-PORT install-sh errno.c tests tests.mk acconfig.h \
+ config.guess config.h.in config.sub configure configure.in signal.c \
+ README.CV README.NONPORTABLE pthread.dsp pthread.dsw
+
diff --git a/pthreads/Nmakefile.tests b/pthreads/Nmakefile.tests
new file mode 100644
index 000000000..203560b6c
--- /dev/null
+++ b/pthreads/Nmakefile.tests
@@ -0,0 +1,260 @@
+/* for running tests */
+CCFLAGS = -g
+_MT == 1
+_timeb == timeb
+_ftime == ftime
+
+.SOURCE: tests
+/*
+:PACKAGE: pthread
+*/
+
+set keepgoing
+
+":test:" : .MAKE .OPERATOR
+ local I
+ $(<:D:B:S=.pass) : .IMPLICIT $(>:D:B:S=.pass)
+ for I $(<) $(>)
+ $(I:D:B:S=.pass) : .VIRTUAL .FORCE $(I)
+ $(>)
+ end
+sizes:: sizes.c
+loadfree:: loadfree.c
+mutex1:: mutex1.c
+mutex1e:: mutex1e.c
+mutex1n:: mutex1n.c
+mutex1r:: mutex1r.c
+mutex2:: mutex2.c
+mutex2r:: mutex2r.c
+mutex2e:: mutex2e.c
+exit1:: exit1.c
+condvar1:: condvar1.c
+condvar1_1:: condvar1_1.c
+condvar1_2:: condvar1_2.c
+self1:: self1.c
+condvar2:: condvar2.c
+condvar2_1:: condvar2_1.c
+condvar3_1:: condvar3_1.c
+condvar3_2:: condvar3_2.c
+condvar3_3:: condvar3_3.c
+create1.:: create1.c
+create2.:: create2.c
+cancel1:: cancel1.c
+cancel2:: cancel2.c
+mutex3:: mutex3.c
+mutex3r:: mutex3r.c
+mutex3e:: mutex3e.c
+mutex4:: mutex4.c
+mutex5:: mutex5.c
+mutex6:: mutex6.c
+mutex6e:: mutex6e.c
+mutex6n:: mutex6n.c
+mutex6r:: mutex6r.c
+mutex7:: mutex7.c
+mutex6s:: mutex6s.c
+mutex6rs:: mutex6rs.c
+mutex6es:: mutex6es.c
+mutex7e:: mutex7e.c
+mutex7n:: mutex7n.c
+mutex7r:: mutex7r.c
+mutex8:: mutex8.c
+mutex8e:: mutex8e.c
+mutex8n:: mutex8n.c
+mutex8r:: mutex8r.c
+equal1:: equal1.c
+exit2:: exit2.c
+exit3:: exit3.c
+exit4:: exit4.c
+exit5:: exit5.c
+join0:: join0.c
+join1:: join1.c
+join2:: join2.c
+join3:: join3.c
+kill1:: kill1.c
+count1:: count1.c
+once1:: once1.c
+tsd1:: tsd1.c
+self2:: self2.c
+eyal1:: eyal1.c
+condvar3:: condvar3.c
+condvar4:: condvar4.c
+condvar5:: condvar5.c
+condvar6:: condvar6.c
+condvar7:: condvar7.c
+condvar8:: condvar8.c
+condvar9:: condvar9.c
+errno1:: errno1.c
+reuse1.:: reuse1.c
+reuse2.:: reuse2.c
+rwlock1:: rwlock1.c
+rwlock2:: rwlock2.c
+rwlock3:: rwlock3.c
+rwlock4:: rwlock4.c
+rwlock5:: rwlock5.c
+rwlock6:: rwlock6.c
+rwlock7:: rwlock7.c
+rwlock8:: rwlock8.c
+rwlock2_t:: rwlock2_t.c
+rwlock3_t:: rwlock3_t.c
+rwlock4_t:: rwlock4_t.c
+rwlock5_t:: rwlock5_t.c
+rwlock6_t:: rwlock6_t.c
+rwlock6_t2:: rwlock6_t2.c
+semaphore1:: semaphore1.c
+semaphore2:: semaphore2.c
+semaphore3:: semaphore3.c
+context1:: context1.c
+cancel3:: cancel3.c
+cancel4:: cancel4.c
+cancel5:: cancel5.c
+cancel6a:: cancel6a.c
+cancel6d:: cancel6d.c
+cancel7:: cancel7.c
+cleanup0:: cleanup0.c
+cleanup1:: cleanup1.c
+cleanup2:: cleanup2.c
+cleanup3:: cleanup3.c
+priority1:: priority1.c
+priority2:: priority2.c
+inherit1:: inherit1.c
+spin1:: spin1.c
+spin2:: spin2.c
+spin3:: spin3.c
+spin4:: spin4.c
+barrier1:: barrier1.c
+barrier2:: barrier2.c
+barrier3:: barrier3.c
+barrier4:: barrier4.c
+barrier5:: barrier5.c
+exception1:: exception1.c
+exception2:: exception2.c
+exception3:: exception3.c
+benchtest1:: benchtest1.c
+benchtest2:: benchtest2.c
+benchtest3:: benchtest3.c
+benchtest4:: benchtest4.c
+benchtest5:: benchtest5.c
+valid1:: valid1.c
+valid2:: valid2.c
+cancel9:: cancel9.c
+
+sizes: :test: sizes
+loadfree: :test:
+mutex5 :test: loadfree
+mutex1 :test: loadfree
+mutex1n :test: loadfree
+mutex1r :test: loadfree
+mutex1e :test: loadfree
+semaphore1 :test: loadfree
+semaphore2 :test: loadfree
+semaphore3 :test: loadfree
+mutex2 :test: loadfree
+mutex2r :test: loadfree
+mutex2e :test: loadfree
+exit1 :test: loadfree
+condvar1 :test: loadfree
+kill1 :test: loadfree
+condvar1_1 :test: condvar1
+condvar1_2 :test: join2
+self1 :test: loadfree
+condvar2 :test: condvar1
+condvar2_1 :test: condvar2
+create1 :test: mutex2
+create2 :test: create1
+reuse1 :test: create2
+reuse2 :test: reuse1
+cancel1 :test: create1
+cancel2 :test: cancel1
+mutex3 :test: create1
+mutex3r :test: create1
+mutex3e :test: create1
+mutex4 :test: mutex3
+mutex6 :test: mutex4
+mutex6n :test: mutex4
+mutex6e :test: mutex4
+mutex6r :test: mutex4
+mutex6s :test: mutex6
+mutex6rs :test: mutex6r
+mutex6es :test: mutex6e
+mutex7 :test: mutex6
+mutex7n :test: mutex6n
+mutex7e :test: mutex6e
+mutex7r :test: mutex6r
+mutex8 :test: mutex7
+mutex8n :test: mutex7n
+mutex8e :test: mutex7e
+mutex8r :test: mutex7r
+equal1 :test: create1
+exit2 :test: create1
+exit3 :test: create1
+exit4 :test: kill1
+exit5 :test: exit4
+join0 :test: create1
+join1 :test: create1
+join2 :test: create1
+join3 :test: join2
+count1 :test: join1
+once1 :test: create1
+tsd1 :test: join1
+self2 :test: create1
+eyal1 :test: tsd1
+condvar3 :test: create1
+condvar3_1 :test: condvar3
+condvar3_2 :test: condvar3_1
+condvar3_3 :test: condvar3_2
+condvar4 :test: create1
+condvar5 :test: condvar4
+condvar6 :test: condvar5
+condvar7 :test: condvar6 cleanup1
+condvar8 :test: condvar7
+condvar9 :test: condvar8
+errno1 :test: mutex3
+rwlock1 :test: condvar6
+rwlock2 :test: rwlock1
+rwlock3 :test: rwlock2
+rwlock4 :test: rwlock3
+rwlock5 :test: rwlock4
+rwlock6 :test: rwlock5
+rwlock7 :test: rwlock6
+rwlock8 :test: rwlock7
+rwlock2_t :test: rwlock2
+rwlock3_t :test: rwlock2_t
+rwlock4_t :test: rwlock3_t
+rwlock5_t :test: rwlock4_t
+rwlock6_t :test: rwlock5_t
+rwlock6_t2 :test: rwlock6_t
+context1 :test: cancel2
+cancel3 :test: context1
+cancel4 :test: cancel3
+cancel5 :test: cancel3
+cancel6a :test: cancel3
+cancel6d :test: cancel3
+cancel7 :test: kill1
+cleanup0 :test: cancel5
+cleanup1 :test: cleanup0
+cleanup2 :test: cleanup1
+cleanup3 :test: cleanup2
+priority1 :test: join1
+priority2 :test: priority1
+inherit1 :test: join1
+spin1 :test:
+spin2 :test: spin1.c
+spin3 :test: spin2.c
+spin4 :test: spin3.c
+barrier1 :test:
+barrier2 :test: barrier1.c
+barrier3 :test: barrier2.c
+barrier4 :test: barrier3.c
+barrier5 :test: barrier4.c
+benchtest1 :test: mutex3
+benchtest2 :test: benchtest1
+benchtest3 :test: benchtest2
+benchtest4 :test: benchtest3
+benchtest5 :test: benchtest4
+exception1 :test: cancel4
+exception2 :test: exception1
+exception3 :test: exception2
+exit4 :test: exit3
+valid1 :test: join1
+valid2 :test: valid1
+cancel9 :test: cancel8
diff --git a/pthreads/PROGRESS b/pthreads/PROGRESS
new file mode 100644
index 000000000..9abf0bca4
--- /dev/null
+++ b/pthreads/PROGRESS
@@ -0,0 +1,4 @@
+Please see the ANNOUNCE file "Level of Standards Conformance"
+or the web page:
+
+http://sources.redhat.com/pthreads-win32/conformance.html
diff --git a/pthreads/README b/pthreads/README
new file mode 100644
index 000000000..564933302
--- /dev/null
+++ b/pthreads/README
@@ -0,0 +1,593 @@
+PTHREADS-WIN32
+==============
+
+Pthreads-win32 is free software, distributed under the GNU Lesser
+General Public License (LGPL). See the file 'COPYING.LIB' for terms
+and conditions. Also see the file 'COPYING' for information
+specific to pthreads-win32, copyrights and the LGPL.
+
+
+What is it?
+-----------
+
+Pthreads-win32 is an Open Source Software implementation of the
+Threads component of the POSIX 1003.1c 1995 Standard (or later)
+for Microsoft's Win32 environment. Some functions from POSIX
+1003.1b are also supported including semaphores. Other related
+functions include the set of read-write lock functions. The
+library also supports some of the functionality of the Open
+Group's Single Unix specification, version 2, namely mutex types,
+plus some common and pthreads-win32 specific non-portable
+routines (see README.NONPORTABLE).
+
+See the file "ANNOUNCE" for more information including standards
+conformance details and the list of supported and unsupported
+routines.
+
+
+Prerequisites
+-------------
+MSVC or GNU C (MinGW32 MSys development kit)
+ To build from source.
+
+QueueUserAPCEx by Panagiotis E. Hadjidoukas
+ For true async cancelation of threads (including blocked threads).
+ This is a DLL and Windows driver that provides pre-emptive APC
+ by forcing threads into an alertable state when the APC is queued.
+ Both the DLL and driver are provided with the pthreads-win32.exe
+ self-unpacking ZIP, and on the pthreads-win32 FTP site (in source
+ and pre-built forms). Currently this is a separate LGPL package to
+ pthreads-win32. See the README in the QueueUserAPCEx folder for
+ installation instructions.
+
+ Pthreads-win32 will automatically detect if the QueueUserAPCEx DLL
+ QuserEx.DLL is available and whether the driver AlertDrv.sys is
+ loaded. If it is not available, pthreads-win32 will simulate async
+ cancelation, which means that it can async cancel only threads that
+ are runnable. The simulated async cancellation cannot cancel blocked
+ threads.
+
+
+Library naming
+--------------
+
+Because the library is being built using various exception
+handling schemes and compilers - and because the library
+may not work reliably if these are mixed in an application,
+each different version of the library has it's own name.
+
+Note 1: the incompatibility is really between EH implementations
+of the different compilers. It should be possible to use the
+standard C version from either compiler with C++ applications
+built with a different compiler. If you use an EH version of
+the library, then you must use the same compiler for the
+application. This is another complication and dependency that
+can be avoided by using only the standard C library version.
+
+Note 2: if you use a standard C pthread*.dll with a C++
+application, then any functions that you define that are
+intended to be called via pthread_cleanup_push() must be
+__cdecl.
+
+Note 3: the intention was to also name either the VC or GC
+version (it should be arbitrary) as pthread.dll, including
+pthread.lib and libpthread.a as appropriate. This is no longer
+likely to happen.
+
+Note 4: the compatibility number was added so that applications
+can differentiate between binary incompatible versions of the
+libs and dlls.
+
+In general:
+ pthread[VG]{SE,CE,C}c.dll
+ pthread[VG]{SE,CE,C}c.lib
+
+where:
+ [VG] indicates the compiler
+ V - MS VC, or
+ G - GNU C
+
+ {SE,CE,C} indicates the exception handling scheme
+ SE - Structured EH, or
+ CE - C++ EH, or
+ C - no exceptions - uses setjmp/longjmp
+
+ c - DLL compatibility number indicating ABI and API
+ compatibility with applications built against
+ any snapshot with the same compatibility number.
+ See 'Version numbering' below.
+
+The name may also be suffixed by a 'd' to indicate a debugging version
+of the library. E.g. pthreadVC2d.lib. Debugging versions contain
+additional information for debugging (symbols etc) and are often not
+optimised in any way (compiled with optimisation turned off).
+
+For example:
+ pthreadVSE.dll (MSVC/SEH)
+ pthreadGCE.dll (GNUC/C++ EH)
+ pthreadGC.dll (GNUC/not dependent on exceptions)
+ pthreadVC1.dll (MSVC/not dependent on exceptions - not binary
+ compatible with pthreadVC.dll)
+ pthreadVC2.dll (MSVC/not dependent on exceptions - not binary
+ compatible with pthreadVC1.dll or pthreadVC.dll)
+
+The GNU library archive file names have correspondingly changed to:
+
+ libpthreadGCEc.a
+ libpthreadGCc.a
+
+
+Versioning numbering
+--------------------
+
+Version numbering is separate from the snapshot dating system, and
+is the canonical version identification system embedded within the
+DLL using the Microsoft version resource system. The versioning
+system chosen follows the GNU Libtool system. See
+http://www.gnu.org/software/libtool/manual.html section 6.2.
+
+See the resource file 'version.rc'.
+
+Microsoft version numbers use 4 integers:
+
+ 0.0.0.0
+
+Pthreads-win32 uses the first 3 following the Libtool convention.
+The fourth is commonly used for the build number, but will be reserved
+for future use.
+
+ current.revision.age.0
+
+The numbers are changed as follows:
+
+1. If the library source code has changed at all since the last update,
+ then increment revision (`c:r:a' becomes `c:r+1:a').
+2. If any interfaces have been added, removed, or changed since the last
+ update, increment current, and set revision to 0.
+3. If any interfaces have been added since the last public release, then
+ increment age.
+4. If any interfaces have been removed or changed since the last public
+ release, then set age to 0.
+
+
+DLL compatibility numbering is an attempt to ensure that applications
+always load a compatible pthreads-win32 DLL by using a DLL naming system
+that is consistent with the version numbering system. It also allows
+older and newer DLLs to coexist in the same filesystem so that older
+applications can continue to be used. For pre .NET Windows systems,
+this inevitably requires incompatible versions of the same DLLs to have
+different names.
+
+Pthreads-win32 has adopted the Cygwin convention of appending a single
+integer number to the DLL name. The number used is based on the library
+version number and is computed as 'current' - 'age'.
+
+(See http://home.att.net/~perlspinr/libversioning.html for a nicely
+detailed explanation.)
+
+Using this method, DLL name/s will only change when the DLL's
+backwards compatibility changes. Note that the addition of new
+'interfaces' will not of itself change the DLL's compatibility for older
+applications.
+
+
+Which of the several dll versions to use?
+-----------------------------------------
+or,
+---
+What are all these pthread*.dll and pthread*.lib files?
+-------------------------------------------------------
+
+Simple, use either pthreadGCv.* if you use GCC, or pthreadVCv.* if you
+use MSVC - where 'v' is the DLL versioning (compatibility) number.
+
+Otherwise, you need to choose carefully and know WHY.
+
+The most important choice you need to make is whether to use a
+version that uses exceptions internally, or not. There are versions
+of the library that use exceptions as part of the thread
+cancelation and exit implementation. The default version uses
+setjmp/longjmp.
+
+There is some contension amongst POSIX threads experts as
+to how POSIX threads cancelation and exit should work
+with languages that use exceptions, e.g. C++ and even C
+(Microsoft's Structured Exceptions).
+
+The issue is: should cancelation of a thread in, say,
+a C++ application cause object destructors and C++ exception
+handlers to be invoked as the stack unwinds during thread
+exit, or not?
+
+There seems to be more opinion in favour of using the
+standard C version of the library (no EH) with C++ applications
+for the reason that this appears to be the assumption commercial
+pthreads implementations make. Therefore, if you use an EH version
+of pthreads-win32 then you may be under the illusion that
+your application will be portable, when in fact it is likely to
+behave differently when linked with other pthreads libraries.
+
+Now you may be asking: then why have you kept the EH versions of
+the library?
+
+There are a couple of reasons:
+- there is division amongst the experts and so the code may
+ be needed in the future. Yes, it's in the repository and we
+ can get it out anytime in the future, but it would be difficult
+ to find.
+- pthreads-win32 is one of the few implementations, and possibly
+ the only freely available one, that has EH versions. It may be
+ useful to people who want to play with or study application
+ behaviour under these conditions.
+
+Notes:
+
+[If you use either pthreadVCE or pthreadGCE]
+
+1. [See also the discussion in the FAQ file - Q2, Q4, and Q5]
+
+If your application contains catch(...) blocks in your POSIX
+threads then you will need to replace the "catch(...)" with the macro
+"PtW32Catch", eg.
+
+ #ifdef PtW32Catch
+ PtW32Catch {
+ ...
+ }
+ #else
+ catch(...) {
+ ...
+ }
+ #endif
+
+Otherwise neither pthreads cancelation nor pthread_exit() will work
+reliably when using versions of the library that use C++ exceptions
+for cancelation and thread exit.
+
+This is due to what is believed to be a C++ compliance error in VC++
+whereby you may not have multiple handlers for the same exception in
+the same try/catch block. GNU G++ doesn't have this restriction.
+
+
+Other name changes
+------------------
+
+All snapshots prior to and including snapshot 2000-08-13
+used "_pthread_" as the prefix to library internal
+functions, and "_PTHREAD_" to many library internal
+macros. These have now been changed to "ptw32_" and "PTW32_"
+respectively so as to not conflict with the ANSI standard's
+reservation of identifiers beginning with "_" and "__" for
+use by compiler implementations only.
+
+If you have written any applications and you are linking
+statically with the pthreads-win32 library then you may have
+included a call to _pthread_processInitialize. You will
+now have to change that to ptw32_processInitialize.
+
+
+Cleanup code default style
+--------------------------
+
+Previously, if not defined, the cleanup style was determined automatically
+from the compiler used, and one of the following was defined accordingly:
+
+ __CLEANUP_SEH MSVC only
+ __CLEANUP_CXX C++, including MSVC++, GNU G++
+ __CLEANUP_C C, including GNU GCC, not MSVC
+
+These defines determine the style of cleanup (see pthread.h) and,
+most importantly, the way that cancelation and thread exit (via
+pthread_exit) is performed (see the routine ptw32_throw()).
+
+In short, the exceptions versions of the library throw an exception
+when a thread is canceled, or exits via pthread_exit(). This exception is
+caught by a handler in the thread startup routine, so that the
+the correct stack unwinding occurs regardless of where the thread
+is when it's canceled or exits via pthread_exit().
+
+In this snapshot, unless the build explicitly defines (e.g. via a
+compiler option) __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then
+the build NOW always defaults to __CLEANUP_C style cleanup. This style
+uses setjmp/longjmp in the cancelation and pthread_exit implementations,
+and therefore won't do stack unwinding even when linked to applications
+that have it (e.g. C++ apps). This is for consistency with most/all
+commercial Unix POSIX threads implementations.
+
+Although it was not clearly documented before, it is still necessary to
+build your application using the same __CLEANUP_* define as was
+used for the version of the library that you link with, so that the
+correct parts of pthread.h are included. That is, the possible
+defines require the following library versions:
+
+ __CLEANUP_SEH pthreadVSE.dll
+ __CLEANUP_CXX pthreadVCE.dll or pthreadGCE.dll
+ __CLEANUP_C pthreadVC.dll or pthreadGC.dll
+
+It is recommended that you let pthread.h use it's default __CLEANUP_C
+for both library and application builds. That is, don't define any of
+the above, and then link with pthreadVC.lib (MSVC or MSVC++) and
+libpthreadGC.a (MinGW GCC or G++). The reason is explained below, but
+another reason is that the prebuilt pthreadVCE.dll is currently broken.
+Versions built with MSVC++ later than version 6 may not be broken, but I
+can't verify this yet.
+
+WHY ARE WE MAKING THE DEFAULT STYLE LESS EXCEPTION-FRIENDLY?
+Because no commercial Unix POSIX threads implementation allows you to
+choose to have stack unwinding. Therefore, providing it in pthread-win32
+as a default is dangerous. We still provide the choice but unless
+you consciously choose to do otherwise, your pthreads applications will
+now run or crash in similar ways irrespective of the pthreads platform
+you use. Or at least this is the hope.
+
+
+Building under VC++ using C++ EH, Structured EH, or just C
+----------------------------------------------------------
+
+From the source directory run nmake without any arguments to list
+help information. E.g.
+
+$ nmake
+
+Microsoft (R) Program Maintenance Utility Version 6.00.8168.0
+Copyright (C) Microsoft Corp 1988-1998. All rights reserved.
+
+Run one of the following command lines:
+nmake clean VCE (to build the MSVC dll with C++ exception handling)
+nmake clean VSE (to build the MSVC dll with structured exception handling)
+nmake clean VC (to build the MSVC dll with C cleanup code)
+nmake clean VCE-inlined (to build the MSVC inlined dll with C++ exception handling)
+nmake clean VSE-inlined (to build the MSVC inlined dll with structured exception handling)
+nmake clean VC-inlined (to build the MSVC inlined dll with C cleanup code)
+nmake clean VC-static (to build the MSVC static lib with C cleanup code)
+nmake clean VCE-debug (to build the debug MSVC dll with C++ exception handling)
+nmake clean VSE-debug (to build the debug MSVC dll with structured exception handling)
+nmake clean VC-debug (to build the debug MSVC dll with C cleanup code)
+nmake clean VCE-inlined-debug (to build the debug MSVC inlined dll with C++ exception handling)
+nmake clean VSE-inlined-debug (to build the debug MSVC inlined dll with structured exception handling)
+nmake clean VC-inlined-debug (to build the debug MSVC inlined dll with C cleanup code)
+nmake clean VC-static-debug (to build the debug MSVC static lib with C cleanup code)
+
+
+The pre-built dlls are normally built using the *-inlined targets.
+
+You can run the testsuite by changing to the "tests" directory and
+running nmake. E.g.:
+
+$ cd tests
+$ nmake
+
+Microsoft (R) Program Maintenance Utility Version 6.00.8168.0
+Copyright (C) Microsoft Corp 1988-1998. All rights reserved.
+
+Run one of the following command lines:
+nmake clean VC (to test using VC dll with VC (no EH) applications)
+nmake clean VCX (to test using VC dll with VC++ (EH) applications)
+nmake clean VCE (to test using the VCE dll with VC++ EH applications)
+nmake clean VSE (to test using VSE dll with VC (SEH) applications)
+nmake clean VC-bench (to benchtest using VC dll with C bench app)
+nmake clean VCX-bench (to benchtest using VC dll with C++ bench app)
+nmake clean VCE-bench (to benchtest using VCE dll with C++ bench app)
+nmake clean VSE-bench (to benchtest using VSE dll with SEH bench app)
+nmake clean VC-static (to test using VC static lib with VC (no EH) applications)
+
+
+Building under Mingw32
+----------------------
+
+The dll can be built easily with recent versions of Mingw32.
+(The distributed versions are built using Mingw32 and MsysDTK
+from www.mingw32.org.)
+
+From the source directory, run make for help information. E.g.:
+
+$ make
+Run one of the following command lines:
+make clean GC (to build the GNU C dll with C cleanup code)
+make clean GCE (to build the GNU C dll with C++ exception handling)
+make clean GC-inlined (to build the GNU C inlined dll with C cleanup code)
+make clean GCE-inlined (to build the GNU C inlined dll with C++ exception handling)
+make clean GC-static (to build the GNU C inlined static lib with C cleanup code)
+make clean GC-debug (to build the GNU C debug dll with C cleanup code)
+make clean GCE-debug (to build the GNU C debug dll with C++ exception handling)
+make clean GC-inlined-debug (to build the GNU C inlined debug dll with C cleanup code)
+make clean GCE-inlined-debug (to build the GNU C inlined debug dll with C++ exception handling)
+make clean GC-static-debug (to build the GNU C inlined static debug lib with C cleanup code)
+
+
+The pre-built dlls are normally built using the *-inlined targets.
+
+You can run the testsuite by changing to the "tests" directory and
+running make for help information. E.g.:
+
+$ cd tests
+$ make
+Run one of the following command lines:
+make clean GC (to test using GC dll with C (no EH) applications)
+make clean GCX (to test using GC dll with C++ (EH) applications)
+make clean GCE (to test using GCE dll with C++ (EH) applications)
+make clean GC-bench (to benchtest using GNU C dll with C cleanup code)
+make clean GCE-bench (to benchtest using GNU C dll with C++ exception handling)
+make clean GC-static (to test using GC static lib with C (no EH) applications)
+
+
+Building under Linux using the Mingw32 cross development tools
+--------------------------------------------------------------
+
+You can build the library without leaving Linux by using the Mingw32 cross
+development toolchain. See http://www.libsdl.org/extras/win32/cross/ for
+tools and info. The GNUmakefile contains some support for this, for example:
+
+make CROSS=i386-mingw32msvc- clean GC-inlined
+
+will build pthreadGCn.dll and libpthreadGCn.a (n=version#), provided your
+cross-tools/bin directory is in your PATH (or use the cross-make.sh script
+at the URL above).
+
+
+Building the library as a statically linkable library
+-----------------------------------------------------
+
+General: PTW32_STATIC_LIB must be defined for both the library build and the
+application build. The makefiles supplied and used by the following 'make'
+command lines will define this for you.
+
+MSVC (creates pthreadVCn.lib as a static link lib):
+
+nmake clean VC-static
+
+
+MinGW32 (creates libpthreadGCn.a as a static link lib):
+
+make clean GC-static
+
+
+Define PTW32_STATIC_LIB when building your application. Also, your
+application must call a two non-portable routines to initialise the
+some state on startup and cleanup before exit. One other routine needs
+to be called to cleanup after any Win32 threads have called POSIX API
+routines. See README.NONPORTABLE or the html reference manual pages for
+details on these routines:
+
+BOOL pthread_win32_process_attach_np (void);
+BOOL pthread_win32_process_detach_np (void);
+BOOL pthread_win32_thread_attach_np (void); // Currently a no-op
+BOOL pthread_win32_thread_detach_np (void);
+
+
+The tests makefiles have the same targets but only check that the
+static library is statically linkable. They don't run the full
+testsuite. To run the full testsuite, build the dlls and run the
+dll test targets.
+
+
+Building the library under Cygwin
+---------------------------------
+
+Cygwin is implementing it's own POSIX threads routines and these
+will be the ones to use if you develop using Cygwin.
+
+
+Ready to run binaries
+---------------------
+
+For convenience, the following ready-to-run files can be downloaded
+from the FTP site (see under "Availability" below):
+
+ pthread.h
+ semaphore.h
+ sched.h
+ pthreadVC.dll - built with MSVC compiler using C setjmp/longjmp
+ pthreadVC.lib
+ pthreadVCE.dll - built with MSVC++ compiler using C++ EH
+ pthreadVCE.lib
+ pthreadVSE.dll - built with MSVC compiler using SEH
+ pthreadVSE.lib
+ pthreadGC.dll - built with Mingw32 GCC
+ libpthreadGC.a - derived from pthreadGC.dll
+ pthreadGCE.dll - built with Mingw32 G++
+ libpthreadGCE.a - derived from pthreadGCE.dll
+
+As of August 2003 pthreads-win32 pthreadG* versions are built and tested
+using the MinGW + MsysDTK environment current as of that date or later.
+The following file MAY be needed for older MinGW environments.
+
+ gcc.dll - needed to build and run applications that use
+ pthreadGCE.dll.
+
+
+Building applications with GNU compilers
+----------------------------------------
+
+If you're using pthreadGC.dll:
+
+With the three header files, pthreadGC.dll and libpthreadGC.a in the
+same directory as your application myapp.c, you could compile, link
+and run myapp.c under Mingw32 as follows:
+
+ gcc -o myapp.exe myapp.c -I. -L. -lpthreadGC
+ myapp
+
+Or put pthreadGC.dll in an appropriate directory in your PATH,
+put libpthreadGC.a in your system lib directory, and
+put the three header files in your system include directory,
+then use:
+
+ gcc -o myapp.exe myapp.c -lpthreadGC
+ myapp
+
+
+If you're using pthreadGCE.dll:
+
+With the three header files, pthreadGCE.dll, gcc.dll and libpthreadGCE.a
+in the same directory as your application myapp.c, you could compile,
+link and run myapp.c under Mingw32 as follows:
+
+ gcc -x c++ -o myapp.exe myapp.c -I. -L. -lpthreadGCE
+ myapp
+
+Or put pthreadGCE.dll and gcc.dll in an appropriate directory in
+your PATH, put libpthreadGCE.a in your system lib directory, and
+put the three header files in your system include directory,
+then use:
+
+ gcc -x c++ -o myapp.exe myapp.c -lpthreadGCE
+ myapp
+
+
+Availability
+------------
+
+The complete source code in either unbundled, self-extracting
+Zip file, or tar/gzipped format can be found at:
+
+ ftp://sources.redhat.com/pub/pthreads-win32
+
+The pre-built DLL, export libraries and matching pthread.h can
+be found at:
+
+ ftp://sources.redhat.com/pub/pthreads-win32/dll-latest
+
+Home page:
+
+ http://sources.redhat.com/pthreads-win32/
+
+
+Mailing list
+------------
+
+There is a mailing list for discussing pthreads on Win32.
+To join, send email to:
+
+ pthreads-win32-subscribe@sources.redhat.com
+
+Unsubscribe by sending mail to:
+
+ pthreads-win32-unsubscribe@sources.redhat.com
+
+
+Acknowledgements
+----------------
+
+See the ANNOUNCE file for acknowledgements.
+See the 'CONTRIBUTORS' file for the list of contributors.
+
+As much as possible, the ChangeLog file attributes
+contributions and patches that have been incorporated
+in the library to the individuals responsible.
+
+Finally, thanks to all those who work on and contribute to the
+POSIX and Single Unix Specification standards. The maturity of an
+industry can be measured by it's open standards.
+
+----
+Ross Johnson
+<rpj@callisto.canberra.edu.au>
+
+
+
+
+
+
+
+
diff --git a/pthreads/README.Borland b/pthreads/README.Borland
new file mode 100644
index 000000000..a130d2bd2
--- /dev/null
+++ b/pthreads/README.Borland
@@ -0,0 +1,57 @@
+In ptw32_InterlockedCompareExchange.c, I've added a section for
+Borland's compiler; it's identical to that for the MS compiler except
+that it uses /* ... */ comments instead of ; comments.
+
+[RPJ: need to define HAVE_TASM32 in config.h to use the above.]
+
+
+The other file is a makefile suitable for use with Borland's compiler
+(run "make -fBmakefile" in the directory). It builds a single version
+of the library, pthreadBC.dll and the corresponding pthreadBC.lib
+import library, which is comparable to the pthreadVC version; I can't
+personally see any demand for the versions that include structured or
+C++ exception cancellation handling so I haven't attempted to build
+those versions of the library. (I imagine a static version might be
+of use to some, but we can't legally use that on my commercial
+projects so I can't try that out, unfortunately.)
+
+[RPJ: Added tests\Bmakefile as well.]
+
+Borland C++ doesn't define the ENOSYS constant used by pthreads-win32;
+rather than make more extensive patches to the pthreads-win32 source I
+have a mostly-arbitrary constant for it in the makefile. However this
+doesn't make it visible to the application using the library, so if
+anyone actually wants to use this constant in their apps (why?)
+someone might like to make a seperate NEED_BCC_something define to add
+this stuff.
+
+The makefile also #defines EDEADLK as EDEADLOCK, _timeb as timeb, and
+_ftime as ftime, to deal with the minor differences between the two
+RTLs' naming conventions, and sets the compiler flags as required to
+get a normal compile of the library.
+
+[RPJ: Moved errno values and _timeb etc to pthread.h, so apps will also
+use them.]
+
+(While I'm on the subject, the reason Borland users should recompile
+the library, rather than using the impdef/implib technique suggested
+previously on the mailing list, is that a) the errno constants are
+different, so the results returned by the pthread_* functions can be
+meaningless, and b) the errno variable/pseudo-variable itself is
+different in the MS & BCC runtimes, so you can't access the
+pthreadVC's errno from a Borland C++-compiled host application
+correctly - I imagine there are other potential problems from the RTL
+mismatch too.)
+
+[RPJ: Make sure you use the same RTL in both dll and application builds.
+The dll and tests Bmakefiles use cw32mti.lib. Having some trouble with
+memory read exceptions running the test suite using BCC55.]
+
+Best regards,
+Will
+
+--
+Will Bryant
+Systems Architect, eCOSM Limited
+Cell +64 21 655 443, office +64 3 365 4176
+http://www.ecosm.com/
diff --git a/pthreads/README.CV b/pthreads/README.CV
new file mode 100644
index 000000000..698728b95
--- /dev/null
+++ b/pthreads/README.CV
@@ -0,0 +1,3036 @@
+README.CV -- Condition Variables
+--------------------------------
+
+The original implementation of condition variables in
+pthreads-win32 was based on a discussion paper:
+
+"Strategies for Implementing POSIX Condition Variables
+on Win32": http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+
+The changes suggested below were made on Feb 6 2001. This
+file is included in the package for the benefit of anyone
+interested in understanding the pthreads-win32 implementation
+of condition variables and the (sometimes subtle) issues that
+it attempts to resolve.
+
+Thanks go to the individuals whose names appear throughout
+the following text.
+
+Ross Johnson
+
+--------------------------------------------------------------------
+
+fyi.. (more detailed problem description/demos + possible fix/patch)
+
+regards,
+alexander.
+
+
+Alexander Terekhov
+31.01.2001 17:43
+
+To: ace-bugs@cs.wustl.edu
+cc:
+From: Alexander Terekhov/Germany/IBM@IBMDE
+Subject: Implementation of POSIX CVs: spur.wakeups/lost
+ signals/deadlocks/unfairness
+
+
+
+ ACE VERSION:
+
+ 5.1.12 (pthread-win32 snapshot 2000-12-29)
+
+ HOST MACHINE and OPERATING SYSTEM:
+
+ IBM IntelliStation Z Pro, 2 x XEON 1GHz, Win2K
+
+ TARGET MACHINE and OPERATING SYSTEM, if different from HOST:
+ COMPILER NAME AND VERSION (AND PATCHLEVEL):
+
+ Microsoft Visual C++ 6.0
+
+ AREA/CLASS/EXAMPLE AFFECTED:
+
+ Implementation of POSIX condition variables - OS.cpp/.h
+
+ DOES THE PROBLEM AFFECT:
+
+ EXECUTION? YES!
+
+ SYNOPSIS:
+
+ a) spurious wakeups (minor problem)
+ b) lost signals
+ c) broadcast deadlock
+ d) unfairness (minor problem)
+
+ DESCRIPTION:
+
+ Please see attached copy of discussion thread
+ from comp.programming.threads for more details on
+ some reported problems. (i've also posted a "fyi"
+ message to ace-users a week or two ago but
+ unfortunately did not get any response so far).
+
+ It seems that current implementation suffers from
+ two essential problems:
+
+ 1) cond.waiters_count does not accurately reflect
+ number of waiters blocked on semaphore - w/o
+ proper synchronisation that could result (in the
+ time window when counter is not accurate)
+ in spurious wakeups organised by subsequent
+ _signals and _broadcasts.
+
+ 2) Always having (with no e.g. copy_and_clear/..)
+ the same queue in use (semaphore+counter)
+ neither signal nor broadcast provide 'atomic'
+ behaviour with respect to other threads/subsequent
+ calls to signal/broadcast/wait.
+
+ Each problem and combination of both could produce
+ various nasty things:
+
+ a) spurious wakeups (minor problem)
+
+ it is possible that waiter(s) which was already
+ unblocked even so is still counted as blocked
+ waiter. signal and broadcast will release
+ semaphore which will produce a spurious wakeup
+ for a 'real' waiter coming later.
+
+ b) lost signals
+
+ signalling thread ends up consuming its own
+ signal. please see demo/discussion below.
+
+ c) broadcast deadlock
+
+ last_waiter processing code does not correctly
+ handle the case with multiple threads
+ waiting for the end of broadcast.
+ please see demo/discussion below.
+
+ d) unfairness (minor problem)
+
+ without SignalObjectAndWait some waiter(s)
+ may end up consuming broadcasted signals
+ multiple times (spurious wakeups) because waiter
+ thread(s) can be preempted before they call
+ semaphore wait (but after count++ and mtx.unlock).
+
+ REPEAT BY:
+
+ See below... run problem demos programs (tennis.cpp and
+ tennisb.cpp) number of times concurrently (on multiprocessor)
+ and in multiple sessions or just add a couple of "Sleep"s
+ as described in the attached copy of discussion thread
+ from comp.programming.threads
+
+ SAMPLE FIX/WORKAROUND:
+
+ See attached patch to pthread-win32.. well, I can not
+ claim that it is completely bug free but at least my
+ test and tests provided by pthreads-win32 seem to work.
+ Perhaps that will help.
+
+ regards,
+ alexander.
+
+
+>> Forum: comp.programming.threads
+>> Thread: pthread_cond_* implementation questions
+.
+.
+.
+David Schwartz <davids@webmaster.com> wrote:
+
+> terekhov@my-deja.com wrote:
+>
+>> BTW, could you please also share your view on other perceived
+>> "problems" such as nested broadcast deadlock, spurious wakeups
+>> and (the latest one) lost signals??
+>
+>I'm not sure what you mean. The standard allows an implementation
+>to do almost whatever it likes. In fact, you could implement
+>pthread_cond_wait by releasing the mutex, sleeping a random
+>amount of time, and then reacquiring the mutex. Of course,
+>this would be a pretty poor implementation, but any code that
+>didn't work under that implementation wouldn't be strictly
+>compliant.
+
+The implementation you suggested is indeed correct
+one (yes, now I see it :). However it requires from
+signal/broadcast nothing more than to "{ return 0; }"
+That is not the case for pthread-win32 and ACE
+implementations. I do think that these implementations
+(basically the same implementation) have some serious
+problems with wait/signal/broadcast calls. I am looking
+for help to clarify whether these problems are real
+or not. I think that I can demonstrate what I mean
+using one or two small sample programs.
+.
+.
+.
+==========
+tennis.cpp
+==========
+
+#include "ace/Synch.h"
+#include "ace/Thread.h"
+
+enum GAME_STATE {
+
+ START_GAME,
+ PLAYER_A, // Player A playes the ball
+ PLAYER_B, // Player B playes the ball
+ GAME_OVER,
+ ONE_PLAYER_GONE,
+ BOTH_PLAYERS_GONE
+
+};
+
+enum GAME_STATE eGameState;
+ACE_Mutex* pmtxGameStateLock;
+ACE_Condition< ACE_Mutex >* pcndGameStateChange;
+
+void*
+ playerA(
+ void* pParm
+ )
+{
+
+ // For access to game state variable
+ pmtxGameStateLock->acquire();
+
+ // Play loop
+ while ( eGameState < GAME_OVER ) {
+
+ // Play the ball
+ cout << endl << "PLAYER-A" << endl;
+
+ // Now its PLAYER-B's turn
+ eGameState = PLAYER_B;
+
+ // Signal to PLAYER-B that now it is his turn
+ pcndGameStateChange->signal();
+
+ // Wait until PLAYER-B finishes playing the ball
+ do {
+
+ pcndGameStateChange->wait();
+
+ if ( PLAYER_B == eGameState )
+ cout << endl << "----PLAYER-A: SPURIOUS WAKEUP!!!" << endl;
+
+ } while ( PLAYER_B == eGameState );
+
+ }
+
+ // PLAYER-A gone
+ eGameState = (GAME_STATE)(eGameState+1);
+ cout << endl << "PLAYER-A GONE" << endl;
+
+ // No more access to state variable needed
+ pmtxGameStateLock->release();
+
+ // Signal PLAYER-A gone event
+ pcndGameStateChange->broadcast();
+
+ return 0;
+
+}
+
+void*
+ playerB(
+ void* pParm
+ )
+{
+
+ // For access to game state variable
+ pmtxGameStateLock->acquire();
+
+ // Play loop
+ while ( eGameState < GAME_OVER ) {
+
+ // Play the ball
+ cout << endl << "PLAYER-B" << endl;
+
+ // Now its PLAYER-A's turn
+ eGameState = PLAYER_A;
+
+ // Signal to PLAYER-A that now it is his turn
+ pcndGameStateChange->signal();
+
+ // Wait until PLAYER-A finishes playing the ball
+ do {
+
+ pcndGameStateChange->wait();
+
+ if ( PLAYER_A == eGameState )
+ cout << endl << "----PLAYER-B: SPURIOUS WAKEUP!!!" << endl;
+
+ } while ( PLAYER_A == eGameState );
+
+ }
+
+ // PLAYER-B gone
+ eGameState = (GAME_STATE)(eGameState+1);
+ cout << endl << "PLAYER-B GONE" << endl;
+
+ // No more access to state variable needed
+ pmtxGameStateLock->release();
+
+ // Signal PLAYER-B gone event
+ pcndGameStateChange->broadcast();
+
+ return 0;
+
+}
+
+
+int
+main (int, ACE_TCHAR *[])
+{
+
+ pmtxGameStateLock = new ACE_Mutex();
+ pcndGameStateChange = new ACE_Condition< ACE_Mutex >( *pmtxGameStateLock
+);
+
+ // Set initial state
+ eGameState = START_GAME;
+
+ // Create players
+ ACE_Thread::spawn( playerA );
+ ACE_Thread::spawn( playerB );
+
+ // Give them 5 sec. to play
+ Sleep( 5000 );//sleep( 5 );
+
+ // Set game over state
+ pmtxGameStateLock->acquire();
+ eGameState = GAME_OVER;
+
+ // Let them know
+ pcndGameStateChange->broadcast();
+
+ // Wait for players to stop
+ do {
+
+ pcndGameStateChange->wait();
+
+ } while ( eGameState < BOTH_PLAYERS_GONE );
+
+ // Cleanup
+ cout << endl << "GAME OVER" << endl;
+ pmtxGameStateLock->release();
+ delete pcndGameStateChange;
+ delete pmtxGameStateLock;
+
+ return 0;
+
+}
+
+===========
+tennisb.cpp
+===========
+#include "ace/Synch.h"
+#include "ace/Thread.h"
+
+enum GAME_STATE {
+
+ START_GAME,
+ PLAYER_A, // Player A playes the ball
+ PLAYER_B, // Player B playes the ball
+ GAME_OVER,
+ ONE_PLAYER_GONE,
+ BOTH_PLAYERS_GONE
+
+};
+
+enum GAME_STATE eGameState;
+ACE_Mutex* pmtxGameStateLock;
+ACE_Condition< ACE_Mutex >* pcndGameStateChange;
+
+void*
+ playerA(
+ void* pParm
+ )
+{
+
+ // For access to game state variable
+ pmtxGameStateLock->acquire();
+
+ // Play loop
+ while ( eGameState < GAME_OVER ) {
+
+ // Play the ball
+ cout << endl << "PLAYER-A" << endl;
+
+ // Now its PLAYER-B's turn
+ eGameState = PLAYER_B;
+
+ // Signal to PLAYER-B that now it is his turn
+ pcndGameStateChange->broadcast();
+
+ // Wait until PLAYER-B finishes playing the ball
+ do {
+
+ pcndGameStateChange->wait();
+
+ if ( PLAYER_B == eGameState )
+ cout << endl << "----PLAYER-A: SPURIOUS WAKEUP!!!" << endl;
+
+ } while ( PLAYER_B == eGameState );
+
+ }
+
+ // PLAYER-A gone
+ eGameState = (GAME_STATE)(eGameState+1);
+ cout << endl << "PLAYER-A GONE" << endl;
+
+ // No more access to state variable needed
+ pmtxGameStateLock->release();
+
+ // Signal PLAYER-A gone event
+ pcndGameStateChange->broadcast();
+
+ return 0;
+
+}
+
+void*
+ playerB(
+ void* pParm
+ )
+{
+
+ // For access to game state variable
+ pmtxGameStateLock->acquire();
+
+ // Play loop
+ while ( eGameState < GAME_OVER ) {
+
+ // Play the ball
+ cout << endl << "PLAYER-B" << endl;
+
+ // Now its PLAYER-A's turn
+ eGameState = PLAYER_A;
+
+ // Signal to PLAYER-A that now it is his turn
+ pcndGameStateChange->broadcast();
+
+ // Wait until PLAYER-A finishes playing the ball
+ do {
+
+ pcndGameStateChange->wait();
+
+ if ( PLAYER_A == eGameState )
+ cout << endl << "----PLAYER-B: SPURIOUS WAKEUP!!!" << endl;
+
+ } while ( PLAYER_A == eGameState );
+
+ }
+
+ // PLAYER-B gone
+ eGameState = (GAME_STATE)(eGameState+1);
+ cout << endl << "PLAYER-B GONE" << endl;
+
+ // No more access to state variable needed
+ pmtxGameStateLock->release();
+
+ // Signal PLAYER-B gone event
+ pcndGameStateChange->broadcast();
+
+ return 0;
+
+}
+
+
+int
+main (int, ACE_TCHAR *[])
+{
+
+ pmtxGameStateLock = new ACE_Mutex();
+ pcndGameStateChange = new ACE_Condition< ACE_Mutex >( *pmtxGameStateLock
+);
+
+ // Set initial state
+ eGameState = START_GAME;
+
+ // Create players
+ ACE_Thread::spawn( playerA );
+ ACE_Thread::spawn( playerB );
+
+ // Give them 5 sec. to play
+ Sleep( 5000 );//sleep( 5 );
+
+ // Make some noise
+ pmtxGameStateLock->acquire();
+ cout << endl << "---Noise ON..." << endl;
+ pmtxGameStateLock->release();
+ for ( int i = 0; i < 100000; i++ )
+ pcndGameStateChange->broadcast();
+ cout << endl << "---Noise OFF" << endl;
+
+ // Set game over state
+ pmtxGameStateLock->acquire();
+ eGameState = GAME_OVER;
+ cout << endl << "---Stopping the game..." << endl;
+
+ // Let them know
+ pcndGameStateChange->broadcast();
+
+ // Wait for players to stop
+ do {
+
+ pcndGameStateChange->wait();
+
+ } while ( eGameState < BOTH_PLAYERS_GONE );
+
+ // Cleanup
+ cout << endl << "GAME OVER" << endl;
+ pmtxGameStateLock->release();
+ delete pcndGameStateChange;
+ delete pmtxGameStateLock;
+
+ return 0;
+
+}
+.
+.
+.
+David Schwartz <davids@webmaster.com> wrote:
+>> > It's compliant
+>>
+>> That is really good.
+>
+>> Tomorrow (I have to go urgently now) I will try to
+>> demonstrate the lost-signal "problem" of current
+>> pthread-win32 and ACE-(variant w/o SingleObjectAndWait)
+>> implementations: players start suddenly drop their balls :-)
+>> (with no change in source code).
+>
+>Signals aren't lost, they're going to the main thread,
+>which isn't coded correctly to handle them. Try this:
+>
+> // Wait for players to stop
+> do {
+>
+> pthread_cond_wait( &cndGameStateChange,&mtxGameStateLock );
+>printf("Main thread stole a signal\n");
+>
+> } while ( eGameState < BOTH_PLAYERS_GONE );
+>
+>I bet everytime you thing a signal is lost, you'll see that printf.
+>The signal isn't lost, it was stolen by another thread.
+
+well, you can probably loose your bet.. it was indeed stolen
+by "another" thread but not the one you seem to think of.
+
+I think that what actually happens is the following:
+
+H:\SA\UXX\pt\PTHREADS\TESTS>tennis3.exe
+
+PLAYER-A
+
+PLAYER-B
+
+----PLAYER-B: SPURIOUS WAKEUP!!!
+
+PLAYER-A GONE
+
+PLAYER-B GONE
+
+GAME OVER
+
+H:\SA\UXX\pt\PTHREADS\TESTS>
+
+here you can see that PLAYER-B after playing his first
+ball (which came via signal from PLAYER-A) just dropped
+it down. What happened is that his signal to player A
+was consumed as spurious wakeup by himself (player B).
+
+The implementation has a problem:
+
+================
+waiting threads:
+================
+
+{ /** Critical Section
+
+ inc cond.waiters_count
+
+}
+
+ /*
+ /* Atomic only if using Win32 SignalObjectAndWait
+ /*
+ cond.mtx.release
+
+ /*** ^^-- A THREAD WHICH DID SIGNAL MAY ACQUIRE THE MUTEX,
+ /*** GO INTO WAIT ON THE SAME CONDITION AND OVERTAKE
+ /*** ORIGINAL WAITER(S) CONSUMING ITS OWN SIGNAL!
+
+ cond.sem.wait
+
+Player-A after playing game's initial ball went into
+wait (called _wait) but was pre-empted before reaching
+wait semaphore. He was counted as waiter but was not
+actually waiting/blocked yet.
+
+===============
+signal threads:
+===============
+
+{ /** Critical Section
+
+ waiters_count = cond.waiters_count
+
+}
+
+ if ( waiters_count != 0 )
+
+ sem.post 1
+
+ endif
+
+Player-B after he received signal/ball from Player A
+called _signal. The _signal did see that there was
+one waiter blocked on the condition (Player-A) and
+released the semaphore.. (but it did not unblock
+Player-A because he was not actually blocked).
+Player-B thread continued its execution, called _wait,
+was counted as second waiter BUT was allowed to slip
+through opened semaphore gate (which was opened for
+Player-B) and received his own signal. Player B remained
+blocked followed by Player A. Deadlock happened which
+lasted until main thread came in and said game over.
+
+It seems to me that the implementation fails to
+correctly implement the following statement
+from specification:
+
+http://www.opengroup.org/
+onlinepubs/007908799/xsh/pthread_cond_wait.html
+
+"These functions atomically release mutex and cause
+the calling thread to block on the condition variable
+cond; atomically here means "atomically with respect
+to access by another thread to the mutex and then the
+condition variable". That is, if another thread is
+able to acquire the mutex after the about-to-block
+thread has released it, then a subsequent call to
+pthread_cond_signal() or pthread_cond_broadcast()
+in that thread behaves as if it were issued after
+the about-to-block thread has blocked."
+
+Question: Am I right?
+
+(I produced the program output above by simply
+adding ?Sleep( 1 )?:
+
+================
+waiting threads:
+================
+
+{ /** Critical Section
+
+ inc cond.waiters_count
+
+}
+
+ /*
+ /* Atomic only if using Win32 SignalObjectAndWait
+ /*
+ cond.mtx.release
+
+Sleep( 1 ); // Win32
+
+ /*** ^^-- A THREAD WHICH DID SIGNAL MAY ACQUIRE THE MUTEX,
+ /*** GO INTO WAIT ON THE SAME CONDITION AND OVERTAKE
+ /*** ORIGINAL WAITER(S) CONSUMING ITS OWN SIGNAL!
+
+ cond.sem.wait
+
+to the source code of pthread-win32 implementation:
+
+http://sources.redhat.com/cgi-bin/cvsweb.cgi/pthreads/
+condvar.c?rev=1.36&content-type=text/
+x-cvsweb-markup&cvsroot=pthreads-win32
+
+
+ /*
+ * We keep the lock held just long enough to increment the count of
+ * waiters by one (above).
+ * Note that we can't keep it held across the
+ * call to sem_wait since that will deadlock other calls
+ * to pthread_cond_signal
+ */
+ cleanup_args.mutexPtr = mutex;
+ cleanup_args.cv = cv;
+ cleanup_args.resultPtr = &result;
+
+ pthread_cleanup_push (ptw32_cond_wait_cleanup, (void *)
+&cleanup_args);
+
+ if ((result = pthread_mutex_unlock (mutex)) == 0)
+ {((result
+Sleep( 1 ); // @AT
+
+ /*
+ * Wait to be awakened by
+ * pthread_cond_signal, or
+ * pthread_cond_broadcast, or
+ * a timeout
+ *
+ * Note:
+ * ptw32_sem_timedwait is a cancelation point,
+ * hence providing the
+ * mechanism for making pthread_cond_wait a cancelation
+ * point. We use the cleanup mechanism to ensure we
+ * re-lock the mutex and decrement the waiters count
+ * if we are canceled.
+ */
+ if (ptw32_sem_timedwait (&(cv->sema), abstime) == -1) {
+ result = errno;
+ }
+ }
+
+ pthread_cleanup_pop (1); /* Always cleanup */
+
+
+BTW, on my system (2 CPUs) I can manage to get
+signals lost even without any source code modification
+if I run the tennis program many times in different
+shell sessions.
+.
+.
+.
+David Schwartz <davids@webmaster.com> wrote:
+>terekhov@my-deja.com wrote:
+>
+>> well, it might be that the program is in fact buggy.
+>> but you did not show me any bug.
+>
+>You're right. I was close but not dead on. I was correct, however,
+>that the code is buggy because it uses 'pthread_cond_signal' even
+>though not any thread waiting on the condition variable can do the
+>job. I was wrong in which thread could be waiting on the cv but
+>unable to do the job.
+
+Okay, lets change 'pthread_cond_signal' to 'pthread_cond_broadcast'
+but also add some noise from main() right before declaring the game
+to be over (I need it in order to demonstrate another problem of
+pthread-win32/ACE implementations - broadcast deadlock)...
+.
+.
+.
+It is my understanding of POSIX conditions,
+that on correct implementation added noise
+in form of unnecessary broadcasts from main,
+should not break the tennis program. The
+only 'side effect' of added noise on correct
+implementation would be 'spurious wakeups' of
+players (in fact they are not spurious,
+players just see them as spurious) unblocked,
+not by another player but by main before
+another player had a chance to acquire the
+mutex and change the game state variable:
+.
+.
+.
+
+PLAYER-B
+
+PLAYER-A
+
+---Noise ON...
+
+PLAYER-B
+
+PLAYER-A
+
+.
+.
+.
+
+PLAYER-B
+
+PLAYER-A
+
+----PLAYER-A: SPURIOUS WAKEUP!!!
+
+PLAYER-B
+
+PLAYER-A
+
+---Noise OFF
+
+PLAYER-B
+
+---Stopping the game...
+
+PLAYER-A GONE
+
+PLAYER-B GONE
+
+GAME OVER
+
+H:\SA\UXX\pt\PTHREADS\TESTS>
+
+On pthread-win32/ACE implementations the
+program could stall:
+
+.
+.
+.
+
+PLAYER-A
+
+PLAYER-B
+
+PLAYER-A
+
+PLAYER-B
+
+PLAYER-A
+
+PLAYER-B
+
+PLAYER-A
+
+PLAYER-B
+
+---Noise ON...
+
+PLAYER-A
+
+---Noise OFF
+^C
+H:\SA\UXX\pt\PTHREADS\TESTS>
+
+
+The implementation has problems:
+
+================
+waiting threads:
+================
+
+{ /** Critical Section
+
+ inc cond.waiters_count
+
+}
+
+ /*
+ /* Atomic only if using Win32 SignalObjectAndWait
+ /*
+ cond.mtx.release
+ cond.sem.wait
+
+ /*** ^^-- WAITER CAN BE PREEMPTED AFTER BEING UNBLOCKED...
+
+{ /** Critical Section
+
+ dec cond.waiters_count
+
+ /*** ^^- ...AND BEFORE DECREMENTING THE COUNT (1)
+
+ last_waiter = ( cond.was_broadcast &&
+ cond.waiters_count == 0 )
+
+ if ( last_waiter )
+
+ cond.was_broadcast = FALSE
+
+ endif
+
+}
+
+ if ( last_waiter )
+
+ /*
+ /* Atomic only if using Win32 SignalObjectAndWait
+ /*
+ cond.auto_reset_event_or_sem.post /* Event for Win32
+ cond.mtx.acquire
+
+ /*** ^^-- ...AND BEFORE CALL TO mtx.acquire (2)
+
+ /*** ^^-- NESTED BROADCASTS RESULT IN A DEADLOCK
+
+
+ else
+
+ cond.mtx.acquire
+
+ /*** ^^-- ...AND BEFORE CALL TO mtx.acquire (3)
+
+ endif
+
+
+==================
+broadcast threads:
+==================
+
+{ /** Critical Section
+
+ waiters_count = cond.waiters_count
+
+ if ( waiters_count != 0 )
+
+ cond.was_broadcast = TRUE
+
+ endif
+
+}
+
+if ( waiters_count != 0 )
+
+ cond.sem.post waiters_count
+
+ /*** ^^^^^--- SPURIOUS WAKEUPS DUE TO (1)
+
+ cond.auto_reset_event_or_sem.wait /* Event for Win32
+
+ /*** ^^^^^--- DEADLOCK FOR FURTHER BROADCASTS IF THEY
+ HAPPEN TO GO INTO WAIT WHILE PREVIOUS
+ BROADCAST IS STILL IN PROGRESS/WAITING
+
+endif
+
+a) cond.waiters_count does not accurately reflect
+number of waiters blocked on semaphore - that could
+result (in the time window when counter is not accurate)
+in spurios wakeups organised by subsequent _signals
+and _broadcasts. From standard compliance point of view
+that is OK but that could be a real problem from
+performance/efficiency point of view.
+
+b) If subsequent broadcast happen to go into wait on
+cond.auto_reset_event_or_sem before previous
+broadcast was unblocked from cond.auto_reset_event_or_sem
+by its last waiter, one of two blocked threads will
+remain blocked because last_waiter processing code
+fails to unblock both threads.
+
+In the situation with tennisb.c the Player-B was put
+in a deadlock by noise (broadcast) coming from main
+thread. And since Player-B holds the game state
+mutex when it calls broadcast, the whole program
+stalled: Player-A was deadlocked on mutex and
+main thread after finishing with producing the noise
+was deadlocked on mutex too (needed to declare the
+game over)
+
+(I produced the program output above by simply
+adding ?Sleep( 1 )?:
+
+==================
+broadcast threads:
+==================
+
+{ /** Critical Section
+
+ waiters_count = cond.waiters_count
+
+ if ( waiters_count != 0 )
+
+ cond.was_broadcast = TRUE
+
+ endif
+
+}
+
+if ( waiters_count != 0 )
+
+Sleep( 1 ); //Win32
+
+ cond.sem.post waiters_count
+
+ /*** ^^^^^--- SPURIOUS WAKEUPS DUE TO (1)
+
+ cond.auto_reset_event_or_sem.wait /* Event for Win32
+
+ /*** ^^^^^--- DEADLOCK FOR FURTHER BROADCASTS IF THEY
+ HAPPEN TO GO INTO WAIT WHILE PREVIOUS
+ BROADCAST IS STILL IN PROGRESS/WAITING
+
+endif
+
+to the source code of pthread-win32 implementation:
+
+http://sources.redhat.com/cgi-bin/cvsweb.cgi/pthreads/
+condvar.c?rev=1.36&content-type=text/
+x-cvsweb-markup&cvsroot=pthreads-win32
+
+ if (wereWaiters)
+ {(wereWaiters)sroot=pthreads-win32eb.cgi/pthreads/Yem...m
+ /*
+ * Wake up all waiters
+ */
+
+Sleep( 1 ); //@AT
+
+#ifdef NEED_SEM
+
+ result = (ptw32_increase_semaphore( &cv->sema, cv->waiters )
+ ? 0
+ : EINVAL);
+
+#else /* NEED_SEM */
+
+ result = (ReleaseSemaphore( cv->sema, cv->waiters, NULL )
+ ? 0
+ : EINVAL);
+
+#endif /* NEED_SEM */
+
+ }
+
+ (void) pthread_mutex_unlock(&(cv->waitersLock));
+
+ if (wereWaiters && result == 0)
+ {(wereWaiters
+ /*
+ * Wait for all the awakened threads to acquire their part of
+ * the counting semaphore
+ */
+
+ if (WaitForSingleObject (cv->waitersDone, INFINITE)
+ == WAIT_OBJECT_0)
+ {
+ result = 0;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ }
+
+ return (result);
+
+}
+
+BTW, on my system (2 CPUs) I can manage to get
+the program stalled even without any source code
+modification if I run the tennisb program many
+times in different shell sessions.
+
+===================
+pthread-win32 patch
+===================
+struct pthread_cond_t_ {
+ long nWaitersBlocked; /* Number of threads blocked
+*/
+ long nWaitersUnblocked; /* Number of threads unblocked
+*/
+ 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
+*/
+}; /* Opt*) for _timedwait and
+cancellation*/
+
+int
+pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr)
+ int result = EAGAIN;
+ pthread_cond_t cv = NULL;
+
+ if (cond == NULL)
+ {(cond
+ return EINVAL;
+ }
+
+ if ((attr != NULL && *attr != NULL) &&
+ ((*attr)->pshared == PTHREAD_PROCESS_SHARED))
+ {
+ /*
+ * Creating condition variable that can be shared between
+ * processes.
+ */
+ result = ENOSYS;
+
+ goto FAIL0;
+ }
+
+ cv = (pthread_cond_t) calloc (1, sizeof (*cv));
+
+ if (cv == NULL)
+ {(cv
+ result = ENOMEM;
+ goto FAIL0;
+ }
+
+ cv->nWaitersBlocked = 0;
+ cv->nWaitersUnblocked = 0;
+ cv->nWaitersToUnblock = 0;
+
+ if (sem_init (&(cv->semBlockLock), 0, 1) != 0)
+ {(sem_init
+ goto FAIL0;
+ }
+
+ if (sem_init (&(cv->semBlockQueue), 0, 0) != 0)
+ {(sem_init
+ goto FAIL1;
+ }
+
+ if (pthread_mutex_init (&(cv->mtxUnblockLock), 0) != 0)
+ {(pthread_mutex_init
+ goto FAIL2;
+ }
+
+
+ result = 0;
+
+ goto DONE;
+
+ /*
+ * -------------
+ * Failed...
+ * -------------
+ */
+FAIL2:
+ (void) sem_destroy (&(cv->semBlockQueue));
+
+FAIL1:
+ (void) sem_destroy (&(cv->semBlockLock));
+
+FAIL0:
+DONE:
+ *cond = cv;
+
+ return (result);
+
+} /* pthread_cond_init */
+
+int
+pthread_cond_destroy (pthread_cond_t * cond)
+{
+ int result = 0;
+ pthread_cond_t cv;
+
+ /*
+ * Assuming any race condition here is harmless.
+ */
+ if (cond == NULL
+ || *cond == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (*cond != (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
+ {(*cond
+ cv = *cond;
+
+ /*
+ * Synchronize access to waiters blocked count (LEVEL-1)
+ */
+ if (sem_wait(&(cv->semBlockLock)) != 0)
+ {(sem_wait(&(cv->semBlockLock))
+ return errno;
+ }
+
+ /*
+ * Synchronize access to waiters (to)unblock(ed) counts (LEVEL-2)
+ */
+ if ((result = pthread_mutex_lock(&(cv->mtxUnblockLock))) != 0)
+ {((result
+ (void) sem_post(&(cv->semBlockLock));
+ return result;
+ }
+
+ /*
+ * Check whether cv is still busy (still has waiters blocked)
+ */
+ if (cv->nWaitersBlocked - cv->nWaitersUnblocked > 0)
+ {(cv->nWaitersBlocked
+ (void) sem_post(&(cv->semBlockLock));
+ (void) pthread_mutex_unlock(&(cv->mtxUnblockLock));
+ return EBUSY;
+ }
+
+ /*
+ * Now it is safe to destroy
+ */
+ (void) sem_destroy (&(cv->semBlockLock));
+ (void) sem_destroy (&(cv->semBlockQueue));
+ (void) pthread_mutex_unlock (&(cv->mtxUnblockLock));
+ (void) pthread_mutex_destroy (&(cv->mtxUnblockLock));
+
+ free(cv);
+ *cond = NULL;
+ }
+ else
+ {
+ /*
+ * See notes in ptw32_cond_check_need_init() above also.
+ */
+ EnterCriticalSection(&ptw32_cond_test_init_lock);
+
+ /*
+ * Check again.
+ */
+ if (*cond == (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
+ {(*cond
+ /*
+ * 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.
+ */
+ *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);
+}
+
+/*
+ * Arguments for cond_wait_cleanup, since we can only pass a
+ * single void * to it.
+ */
+typedef struct {
+ pthread_mutex_t * mutexPtr;
+ pthread_cond_t cv;
+ int * resultPtr;
+} ptw32_cond_wait_cleanup_args_t;
+
+static void
+ptw32_cond_wait_cleanup(void * args)
+{
+ ptw32_cond_wait_cleanup_args_t * cleanup_args =
+(ptw32_cond_wait_cleanup_args_t *) args;
+ pthread_cond_t cv = cleanup_args->cv;
+ int * resultPtr = cleanup_args->resultPtr;
+ int eLastSignal; /* enum: 1=yes 0=no -1=cancelled/timedout w/o signal(s)
+*/
+ int result;
+
+ /*
+ * Whether we got here as a result of signal/broadcast or because of
+ * timeout on wait or thread cancellation we indicate that we are no
+ * longer waiting. The waiter is responsible for adjusting waiters
+ * (to)unblock(ed) counts (protected by unblock lock).
+ * Unblock lock/Sync.LEVEL-2 supports _timedwait and cancellation.
+ */
+ if ((result = pthread_mutex_lock(&(cv->mtxUnblockLock))) != 0)
+ {((result
+ *resultPtr = result;
+ return;
+ }
+
+ cv->nWaitersUnblocked++;
+
+ eLastSignal = (cv->nWaitersToUnblock == 0) ?
+ -1 : (--cv->nWaitersToUnblock == 0);
+
+ /*
+ * No more LEVEL-2 access to waiters (to)unblock(ed) counts needed
+ */
+ if ((result = pthread_mutex_unlock(&(cv->mtxUnblockLock))) != 0)
+ {((result
+ *resultPtr = result;
+ return;
+ }
+
+ /*
+ * If last signal...
+ */
+ if (eLastSignal == 1)
+ {(eLastSignal
+ /*
+ * ...it means that we have end of 'atomic' signal/broadcast
+ */
+ if (sem_post(&(cv->semBlockLock)) != 0)
+ {(sem_post(&(cv->semBlockLock))
+ *resultPtr = errno;
+ return;
+ }
+ }
+ /*
+ * If not last signal and not timed out/cancelled wait w/o signal...
+ */
+ else if (eLastSignal == 0)
+ {
+ /*
+ * ...it means that next waiter can go through semaphore
+ */
+ if (sem_post(&(cv->semBlockQueue)) != 0)
+ {(sem_post(&(cv->semBlockQueue))
+ *resultPtr = errno;
+ return;
+ }
+ }
+
+ /*
+ * XSH: Upon successful return, the mutex has been locked and is owned
+ * by the calling thread
+ */
+ if ((result = pthread_mutex_lock(cleanup_args->mutexPtr)) != 0)
+ {((result
+ *resultPtr = result;
+ }
+
+} /* ptw32_cond_wait_cleanup */
+
+static int
+ptw32_cond_timedwait (pthread_cond_t * cond,
+ pthread_mutex_t * mutex,
+ const struct timespec *abstime)
+{
+ int result = 0;
+ pthread_cond_t cv;
+ ptw32_cond_wait_cleanup_args_t cleanup_args;
+
+ if (cond == NULL || *cond == NULL)
+ {(cond
+ return EINVAL;
+ }
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static condition variable. We check
+ * again inside the guarded section of ptw32_cond_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*cond == (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
+ {(*cond
+ result = ptw32_cond_check_need_init(cond);
+ }
+
+ if (result != 0 && result != EBUSY)
+ {(result
+ return result;
+ }
+
+ cv = *cond;
+
+ /*
+ * Synchronize access to waiters blocked count (LEVEL-1)
+ */
+ if (sem_wait(&(cv->semBlockLock)) != 0)
+ {(sem_wait(&(cv->semBlockLock))
+ return errno;
+ }
+
+ cv->nWaitersBlocked++;
+
+ /*
+ * Thats it. Counted means waiting, no more access needed
+ */
+ if (sem_post(&(cv->semBlockLock)) != 0)
+ {(sem_post(&(cv->semBlockLock))
+ return errno;
+ }
+
+ /*
+ * Setup this waiter cleanup handler
+ */
+ cleanup_args.mutexPtr = mutex;
+ cleanup_args.cv = cv;
+ cleanup_args.resultPtr = &result;
+
+ pthread_cleanup_push (ptw32_cond_wait_cleanup, (void *) &cleanup_args);
+
+ /*
+ * Now we can release 'mutex' and...
+ */
+ if ((result = pthread_mutex_unlock (mutex)) == 0)
+ {((result
+
+ /*
+ * ...wait to be awakened by
+ * pthread_cond_signal, or
+ * pthread_cond_broadcast, or
+ * timeout, or
+ * thread cancellation
+ *
+ * Note:
+ *
+ * ptw32_sem_timedwait is a cancellation point,
+ * hence providing the mechanism for making
+ * pthread_cond_wait a cancellation point.
+ * We use the cleanup mechanism to ensure we
+ * re-lock the mutex and adjust (to)unblock(ed) waiters
+ * counts if we are cancelled, timed out or signalled.
+ */
+ if (ptw32_sem_timedwait (&(cv->semBlockQueue), abstime) != 0)
+ {(ptw32_sem_timedwait
+ result = errno;
+ }
+ }
+
+ /*
+ * Always cleanup
+ */
+ pthread_cleanup_pop (1);
+
+
+ /*
+ * "result" can be modified by the cleanup handler.
+ */
+ return (result);
+
+} /* ptw32_cond_timedwait */
+
+
+static int
+ptw32_cond_unblock (pthread_cond_t * cond,
+ int unblockAll)
+{
+ int result;
+ pthread_cond_t cv;
+
+ if (cond == NULL || *cond == NULL)
+ {(cond
+ return EINVAL;
+ }
+
+ cv = *cond;
+
+ /*
+ * No-op if the CV is static and hasn't been initialised yet.
+ * Assuming that any race condition is harmless.
+ */
+ if (cv == (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
+ {(cv
+ return 0;
+ }
+
+ /*
+ * Synchronize access to waiters blocked count (LEVEL-1)
+ */
+ if (sem_wait(&(cv->semBlockLock)) != 0)
+ {(sem_wait(&(cv->semBlockLock))
+ return errno;
+ }
+
+ /*
+ * Synchronize access to waiters (to)unblock(ed) counts (LEVEL-2)
+ * This sync.level supports _timedwait and cancellation
+ */
+ if ((result = pthread_mutex_lock(&(cv->mtxUnblockLock))) != 0)
+ {((result
+ return result;
+ }
+
+ /*
+ * Adjust waiters blocked and unblocked counts (collect garbage)
+ */
+ if (cv->nWaitersUnblocked != 0)
+ {(cv->nWaitersUnblocked
+ cv->nWaitersBlocked -= cv->nWaitersUnblocked;
+ cv->nWaitersUnblocked = 0;
+ }
+
+ /*
+ * If (after adjustment) there are still some waiters blocked counted...
+ */
+ if ( cv->nWaitersBlocked > 0)
+ {(
+ /*
+ * We will unblock first waiter and leave semBlockLock/LEVEL-1 locked
+ * LEVEL-1 access is left disabled until last signal/unblock
+completes
+ */
+ cv->nWaitersToUnblock = (unblockAll) ? cv->nWaitersBlocked : 1;
+
+ /*
+ * No more LEVEL-2 access to waiters (to)unblock(ed) counts needed
+ * This sync.level supports _timedwait and cancellation
+ */
+ if ((result = pthread_mutex_unlock(&(cv->mtxUnblockLock))) != 0)
+ {((result
+ return result;
+ }
+
+
+ /*
+ * Now, with LEVEL-2 lock released let first waiter go through
+semaphore
+ */
+ if (sem_post(&(cv->semBlockQueue)) != 0)
+ {(sem_post(&(cv->semBlockQueue))
+ return errno;
+ }
+ }
+ /*
+ * No waiter blocked - no more LEVEL-1 access to blocked count needed...
+ */
+ else if (sem_post(&(cv->semBlockLock)) != 0)
+ {
+ return errno;
+ }
+ /*
+ * ...and no more LEVEL-2 access to waiters (to)unblock(ed) counts needed
+too
+ * This sync.level supports _timedwait and cancellation
+ */
+ else
+ {
+ result = pthread_mutex_unlock(&(cv->mtxUnblockLock));
+ }
+
+ return(result);
+
+} /* ptw32_cond_unblock */
+
+int
+pthread_cond_wait (pthread_cond_t * cond,
+ pthread_mutex_t * mutex)
+{
+ /* The NULL abstime arg means INFINITE waiting. */
+ return(ptw32_cond_timedwait(cond, mutex, NULL));
+} /* pthread_cond_wait */
+
+
+int
+pthread_cond_timedwait (pthread_cond_t * cond,
+ pthread_mutex_t * mutex,
+ const struct timespec *abstime)
+{
+ if (abstime == NULL)
+ {(abstime
+ return EINVAL;
+ }
+
+ return(ptw32_cond_timedwait(cond, mutex, abstime));
+} /* pthread_cond_timedwait */
+
+
+int
+pthread_cond_signal (pthread_cond_t * cond)
+{
+ /* The '0'(FALSE) unblockAll arg means unblock ONE waiter. */
+ return(ptw32_cond_unblock(cond, 0));
+} /* pthread_cond_signal */
+
+int
+pthread_cond_broadcast (pthread_cond_t * cond)
+{
+ /* The '1'(TRUE) unblockAll arg means unblock ALL waiters. */
+ return(ptw32_cond_unblock(cond, 1));
+} /* pthread_cond_broadcast */
+
+
+
+
+TEREKHOV@de.ibm.com on 17.01.2001 01:00:57
+
+Please respond to TEREKHOV@de.ibm.com
+
+To: pthreads-win32@sourceware.cygnus.com
+cc: schmidt@uci.edu
+Subject: win32 conditions: sem+counter+event = broadcast_deadlock +
+ spur.wakeup/unfairness/incorrectness ??
+
+
+
+
+
+
+
+Hi,
+
+Problem 1: broadcast_deadlock
+
+It seems that current implementation does not provide "atomic"
+broadcasts. That may lead to "nested" broadcasts... and it seems
+that nested case is not handled correctly -> producing a broadcast
+DEADLOCK as a result.
+
+Scenario:
+
+N (>1) waiting threads W1..N are blocked (in _wait) on condition's
+semaphore.
+
+Thread B1 calls pthread_cond_broadcast, which results in "releasing" N
+W threads via incrementing semaphore counter by N (stored in
+cv->waiters) BUT cv->waiters counter does not change!! The caller
+thread B1 remains blocked on cv->waitersDone event (auto-reset!!) BUT
+condition is not protected from starting another broadcast (when called
+on another thread) while still waiting for the "old" broadcast to
+complete on thread B1.
+
+M (>=0, <N) W threads are fast enough to go thru their _wait call and
+decrement cv->waiters counter.
+
+L (N-M) "late" waiter W threads are a) still blocked/not returned from
+their semaphore wait call or b) were preempted after sem_wait but before
+lock( &cv->waitersLock ) or c) are blocked on cv->waitersLock.
+
+cv->waiters is still > 0 (= L).
+
+Another thread B2 (or some W thread from M group) calls
+pthread_cond_broadcast and gains access to counter... neither a) nor b)
+prevent thread B2 in pthread_cond_broadcast from gaining access to
+counter and starting another broadcast ( for c) - it depends on
+cv->waitersLock scheduling rules: FIFO=OK, PRTY=PROBLEM,... )
+
+That call to pthread_cond_broadcast (on thread B2) will result in
+incrementing semaphore by cv->waiters (=L) which is INCORRECT (all
+W1..N were in fact already released by thread B1) and waiting on
+_auto-reset_ event cv->waitersDone which is DEADLY WRONG (produces a
+deadlock)...
+
+All late W1..L threads now have a chance to complete their _wait call.
+Last W_L thread sets an auto-reselt event cv->waitersDone which will
+release either B1 or B2 leaving one of B threads in a deadlock.
+
+Problem 2: spur.wakeup/unfairness/incorrectness
+
+It seems that:
+
+a) because of the same problem with counter which does not reflect the
+actual number of NOT RELEASED waiters, the signal call may increment
+a semaphore counter w/o having a waiter blocked on it. That will result
+in (best case) spurious wake ups - performance degradation due to
+unnecessary context switches and predicate re-checks and (in worth case)
+unfairness/incorrectness problem - see b)
+
+b) neither signal nor broadcast prevent other threads - "new waiters"
+(and in the case of signal, the caller thread as well) from going into
+_wait and overtaking "old" waiters (already released but still not returned
+from sem_wait on condition's semaphore). Win semaphore just [API DOC]:
+"Maintains a count between zero and some maximum value, limiting the number
+of threads that are simultaneously accessing a shared resource." Calling
+ReleaseSemaphore does not imply (at least not documented) that on return
+from ReleaseSemaphore all waiters will in fact become released (returned
+from their Wait... call) and/or that new waiters calling Wait... afterwards
+will become less importance. It is NOT documented to be an atomic release
+of
+waiters... And even if it would be there is still a problem with a thread
+being preempted after Wait on semaphore and before Wait on cv->waitersLock
+and scheduling rules for cv->waitersLock itself
+(??WaitForMultipleObjects??)
+That may result in unfairness/incorrectness problem as described
+for SetEvent impl. in "Strategies for Implementing POSIX Condition
+Variables
+on Win32": http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+
+Unfairness -- The semantics of the POSIX pthread_cond_broadcast function is
+to wake up all threads currently blocked in wait calls on the condition
+variable. The awakened threads then compete for the external_mutex. To
+ensure
+fairness, all of these threads should be released from their
+pthread_cond_wait calls and allowed to recheck their condition expressions
+before other threads can successfully complete a wait on the condition
+variable.
+
+Unfortunately, the SetEvent implementation above does not guarantee that
+all
+threads sleeping on the condition variable when cond_broadcast is called
+will
+acquire the external_mutex and check their condition expressions. Although
+the Pthreads specification does not mandate this degree of fairness, the
+lack of fairness can cause starvation.
+
+To illustrate the unfairness problem, imagine there are 2 threads, C1 and
+C2,
+that are blocked in pthread_cond_wait on condition variable not_empty_ that
+is guarding a thread-safe message queue. Another thread, P1 then places two
+messages onto the queue and calls pthread_cond_broadcast. If C1 returns
+from
+pthread_cond_wait, dequeues and processes the message, and immediately
+waits
+again then it and only it may end up acquiring both messages. Thus, C2 will
+never get a chance to dequeue a message and run.
+
+The following illustrates the sequence of events:
+
+1. Thread C1 attempts to dequeue and waits on CV non_empty_
+2. Thread C2 attempts to dequeue and waits on CV non_empty_
+3. Thread P1 enqueues 2 messages and broadcasts to CV not_empty_
+4. Thread P1 exits
+5. Thread C1 wakes up from CV not_empty_, dequeues a message and runs
+6. Thread C1 waits again on CV not_empty_, immediately dequeues the 2nd
+ message and runs
+7. Thread C1 exits
+8. Thread C2 is the only thread left and blocks forever since
+ not_empty_ will never be signaled
+
+Depending on the algorithm being implemented, this lack of fairness may
+yield
+concurrent programs that have subtle bugs. Of course, application
+developers
+should not rely on the fairness semantics of pthread_cond_broadcast.
+However,
+there are many cases where fair implementations of condition variables can
+simplify application code.
+
+Incorrectness -- A variation on the unfairness problem described above
+occurs
+when a third consumer thread, C3, is allowed to slip through even though it
+was not waiting on condition variable not_empty_ when a broadcast occurred.
+
+To illustrate this, we will use the same scenario as above: 2 threads, C1
+and
+C2, are blocked dequeuing messages from the message queue. Another thread,
+P1
+then places two messages onto the queue and calls pthread_cond_broadcast.
+C1
+returns from pthread_cond_wait, dequeues and processes the message. At this
+time, C3 acquires the external_mutex, calls pthread_cond_wait and waits on
+the events in WaitForMultipleObjects. Since C2 has not had a chance to run
+yet, the BROADCAST event is still signaled. C3 then returns from
+WaitForMultipleObjects, and dequeues and processes the message in the
+queue.
+Thus, C2 will never get a chance to dequeue a message and run.
+
+The following illustrates the sequence of events:
+
+1. Thread C1 attempts to dequeue and waits on CV non_empty_
+2. Thread C2 attempts to dequeue and waits on CV non_empty_
+3. Thread P1 enqueues 2 messages and broadcasts to CV not_empty_
+4. Thread P1 exits
+5. Thread C1 wakes up from CV not_empty_, dequeues a message and runs
+6. Thread C1 exits
+7. Thread C3 waits on CV not_empty_, immediately dequeues the 2nd
+ message and runs
+8. Thread C3 exits
+9. Thread C2 is the only thread left and blocks forever since
+ not_empty_ will never be signaled
+
+In the above case, a thread that was not waiting on the condition variable
+when a broadcast occurred was allowed to proceed. This leads to incorrect
+semantics for a condition variable.
+
+
+COMMENTS???
+
+regards,
+alexander.
+
+-----------------------------------------------------------------------------
+
+Subject: RE: FYI/comp.programming.threads/Re: pthread_cond_*
+ implementation questions
+Date: Wed, 21 Feb 2001 11:54:47 +0100
+From: TEREKHOV@de.ibm.com
+To: lthomas@arbitrade.com
+CC: rpj@ise.canberra.edu.au, Thomas Pfaff <tpfaff@gmx.net>,
+ Nanbor Wang <nanbor@cs.wustl.edu>
+
+Hi Louis,
+
+generation number 8..
+
+had some time to revisit timeouts/spurious wakeup problem..
+found some bugs (in 7.b/c/d) and something to improve
+(7a - using IPC semaphores but it should speedup Win32
+version as well).
+
+regards,
+alexander.
+
+---------- Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL ------
+given:
+semBlockLock - bin.semaphore
+semBlockQueue - semaphore
+mtxExternal - mutex or CS
+mtxUnblockLock - mutex or CS
+nWaitersGone - int
+nWaitersBlocked - int
+nWaitersToUnblock - int
+
+wait( timeout ) {
+
+ [auto: register int result ] // error checking omitted
+ [auto: register int nSignalsWasLeft ]
+ [auto: register int nWaitersWasGone ]
+
+ sem_wait( semBlockLock );
+ nWaitersBlocked++;
+ sem_post( semBlockLock );
+
+ unlock( mtxExternal );
+ bTimedOut = sem_wait( semBlockQueue,timeout );
+
+ lock( mtxUnblockLock );
+ if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
+ if ( bTimeout ) { // timeout (or canceled)
+ if ( 0 != nWaitersBlocked ) {
+ nWaitersBlocked--;
+ }
+ else {
+ nWaitersGone++; // count spurious wakeups
+ }
+ }
+ if ( 0 == --nWaitersToUnblock ) {
+ if ( 0 != nWaitersBlocked ) {
+ sem_post( semBlockLock ); // open the gate
+ nSignalsWasLeft = 0; // do not open the gate below
+again
+ }
+ else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
+ nWaitersGone = 0;
+ }
+ }
+ }
+ else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or spurious
+semaphore :-)
+ sem_wait( semBlockLock );
+ nWaitersBlocked -= nWaitersGone; // something is going on here -
+test of timeouts? :-)
+ sem_post( semBlockLock );
+ nWaitersGone = 0;
+ }
+ unlock( mtxUnblockLock );
+
+ if ( 1 == nSignalsWasLeft ) {
+ if ( 0 != nWaitersWasGone ) {
+ // sem_adjust( -nWaitersWasGone );
+ while ( nWaitersWasGone-- ) {
+ sem_wait( semBlockLock ); // better now than spurious
+later
+ }
+ }
+ sem_post( semBlockLock ); // open the gate
+ }
+
+ lock( mtxExternal );
+
+ return ( bTimedOut ) ? ETIMEOUT : 0;
+}
+
+signal(bAll) {
+
+ [auto: register int result ]
+ [auto: register int nSignalsToIssue]
+
+ lock( mtxUnblockLock );
+
+ if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
+ if ( 0 == nWaitersBlocked ) { // NO-OP
+ return unlock( mtxUnblockLock );
+ }
+ if (bAll) {
+ nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
+ nWaitersBlocked = 0;
+ }
+ else {
+ nSignalsToIssue = 1;
+ nWaitersToUnblock++;
+ nWaitersBlocked--;
+ }
+ }
+ else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+ sem_wait( semBlockLock ); // close the gate
+ if ( 0 != nWaitersGone ) {
+ nWaitersBlocked -= nWaitersGone;
+ nWaitersGone = 0;
+ }
+ if (bAll) {
+ nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
+ nWaitersBlocked = 0;
+ }
+ else {
+ nSignalsToIssue = nWaitersToUnblock = 1;
+ nWaitersBlocked--;
+ }
+ }
+ else { // NO-OP
+ return unlock( mtxUnblockLock );
+ }
+
+ unlock( mtxUnblockLock );
+ sem_post( semBlockQueue,nSignalsToIssue );
+ return result;
+}
+
+---------- Algorithm 8b / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ONEBYONE
+------
+given:
+semBlockLock - bin.semaphore
+semBlockQueue - bin.semaphore
+mtxExternal - mutex or CS
+mtxUnblockLock - mutex or CS
+nWaitersGone - int
+nWaitersBlocked - int
+nWaitersToUnblock - int
+
+wait( timeout ) {
+
+ [auto: register int result ] // error checking omitted
+ [auto: register int nWaitersWasGone ]
+ [auto: register int nSignalsWasLeft ]
+
+ sem_wait( semBlockLock );
+ nWaitersBlocked++;
+ sem_post( semBlockLock );
+
+ unlock( mtxExternal );
+ bTimedOut = sem_wait( semBlockQueue,timeout );
+
+ lock( mtxUnblockLock );
+ if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
+ if ( bTimeout ) { // timeout (or canceled)
+ if ( 0 != nWaitersBlocked ) {
+ nWaitersBlocked--;
+ nSignalsWasLeft = 0; // do not unblock next waiter
+below (already unblocked)
+ }
+ else {
+ nWaitersGone = 1; // spurious wakeup pending!!
+ }
+ }
+ if ( 0 == --nWaitersToUnblock &&
+ if ( 0 != nWaitersBlocked ) {
+ sem_post( semBlockLock ); // open the gate
+ nSignalsWasLeft = 0; // do not open the gate below
+again
+ }
+ else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
+ nWaitersGone = 0;
+ }
+ }
+ }
+ else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or spurious
+semaphore :-)
+ sem_wait( semBlockLock );
+ nWaitersBlocked -= nWaitersGone; // something is going on here -
+test of timeouts? :-)
+ sem_post( semBlockLock );
+ nWaitersGone = 0;
+ }
+ unlock( mtxUnblockLock );
+
+ if ( 1 == nSignalsWasLeft ) {
+ if ( 0 != nWaitersWasGone ) {
+ // sem_adjust( -1 );
+ sem_wait( semBlockQueue ); // better now than spurious
+later
+ }
+ sem_post( semBlockLock ); // open the gate
+ }
+ else if ( 0 != nSignalsWasLeft ) {
+ sem_post( semBlockQueue ); // unblock next waiter
+ }
+
+ lock( mtxExternal );
+
+ return ( bTimedOut ) ? ETIMEOUT : 0;
+}
+
+signal(bAll) {
+
+ [auto: register int result ]
+
+ lock( mtxUnblockLock );
+
+ if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
+ if ( 0 == nWaitersBlocked ) { // NO-OP
+ return unlock( mtxUnblockLock );
+ }
+ if (bAll) {
+ nWaitersToUnblock += nWaitersBlocked;
+ nWaitersBlocked = 0;
+ }
+ else {
+ nWaitersToUnblock++;
+ nWaitersBlocked--;
+ }
+ unlock( mtxUnblockLock );
+ }
+ else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+ sem_wait( semBlockLock ); // close the gate
+ if ( 0 != nWaitersGone ) {
+ nWaitersBlocked -= nWaitersGone;
+ nWaitersGone = 0;
+ }
+ if (bAll) {
+ nWaitersToUnblock = nWaitersBlocked;
+ nWaitersBlocked = 0;
+ }
+ else {
+ nWaitersToUnblock = 1;
+ nWaitersBlocked--;
+ }
+ unlock( mtxUnblockLock );
+ sem_post( semBlockQueue );
+ }
+ else { // NO-OP
+ unlock( mtxUnblockLock );
+ }
+
+ return result;
+}
+
+---------- Algorithm 8c / IMPL_EVENT,UNBLOCK_STRATEGY == UNBLOCK_ONEBYONE
+---------
+given:
+hevBlockLock - auto-reset event
+hevBlockQueue - auto-reset event
+mtxExternal - mutex or CS
+mtxUnblockLock - mutex or CS
+nWaitersGone - int
+nWaitersBlocked - int
+nWaitersToUnblock - int
+
+wait( timeout ) {
+
+ [auto: register int result ] // error checking omitted
+ [auto: register int nSignalsWasLeft ]
+ [auto: register int nWaitersWasGone ]
+
+ wait( hevBlockLock,INFINITE );
+ nWaitersBlocked++;
+ set_event( hevBlockLock );
+
+ unlock( mtxExternal );
+ bTimedOut = wait( hevBlockQueue,timeout );
+
+ lock( mtxUnblockLock );
+ if ( 0 != (SignalsWasLeft = nWaitersToUnblock) ) {
+ if ( bTimeout ) { // timeout (or canceled)
+ if ( 0 != nWaitersBlocked ) {
+ nWaitersBlocked--;
+ nSignalsWasLeft = 0; // do not unblock next waiter
+below (already unblocked)
+ }
+ else {
+ nWaitersGone = 1; // spurious wakeup pending!!
+ }
+ }
+ if ( 0 == --nWaitersToUnblock )
+ if ( 0 != nWaitersBlocked ) {
+ set_event( hevBlockLock ); // open the gate
+ nSignalsWasLeft = 0; // do not open the gate below
+again
+ }
+ else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
+ nWaitersGone = 0;
+ }
+ }
+ }
+ else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or spurious
+event :-)
+ wait( hevBlockLock,INFINITE );
+ nWaitersBlocked -= nWaitersGone; // something is going on here -
+test of timeouts? :-)
+ set_event( hevBlockLock );
+ nWaitersGone = 0;
+ }
+ unlock( mtxUnblockLock );
+
+ if ( 1 == nSignalsWasLeft ) {
+ if ( 0 != nWaitersWasGone ) {
+ reset_event( hevBlockQueue ); // better now than spurious
+later
+ }
+ set_event( hevBlockLock ); // open the gate
+ }
+ else if ( 0 != nSignalsWasLeft ) {
+ set_event( hevBlockQueue ); // unblock next waiter
+ }
+
+ lock( mtxExternal );
+
+ return ( bTimedOut ) ? ETIMEOUT : 0;
+}
+
+signal(bAll) {
+
+ [auto: register int result ]
+
+ lock( mtxUnblockLock );
+
+ if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
+ if ( 0 == nWaitersBlocked ) { // NO-OP
+ return unlock( mtxUnblockLock );
+ }
+ if (bAll) {
+ nWaitersToUnblock += nWaitersBlocked;
+ nWaitersBlocked = 0;
+ }
+ else {
+ nWaitersToUnblock++;
+ nWaitersBlocked--;
+ }
+ unlock( mtxUnblockLock );
+ }
+ else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+ wait( hevBlockLock,INFINITE ); // close the gate
+ if ( 0 != nWaitersGone ) {
+ nWaitersBlocked -= nWaitersGone;
+ nWaitersGone = 0;
+ }
+ if (bAll) {
+ nWaitersToUnblock = nWaitersBlocked;
+ nWaitersBlocked = 0;
+ }
+ else {
+ nWaitersToUnblock = 1;
+ nWaitersBlocked--;
+ }
+ unlock( mtxUnblockLock );
+ set_event( hevBlockQueue );
+ }
+ else { // NO-OP
+ unlock( mtxUnblockLock );
+ }
+
+ return result;
+}
+
+---------- Algorithm 8d / IMPL_EVENT,UNBLOCK_STRATEGY == UNBLOCK_ALL ------
+given:
+hevBlockLock - auto-reset event
+hevBlockQueueS - auto-reset event // for signals
+hevBlockQueueB - manual-reset even // for broadcasts
+mtxExternal - mutex or CS
+mtxUnblockLock - mutex or CS
+eBroadcast - int // 0: no broadcast, 1: broadcast, 2:
+broadcast after signal(s)
+nWaitersGone - int
+nWaitersBlocked - int
+nWaitersToUnblock - int
+
+wait( timeout ) {
+
+ [auto: register int result ] // error checking omitted
+ [auto: register int eWasBroadcast ]
+ [auto: register int nSignalsWasLeft ]
+ [auto: register int nWaitersWasGone ]
+
+ wait( hevBlockLock,INFINITE );
+ nWaitersBlocked++;
+ set_event( hevBlockLock );
+
+ unlock( mtxExternal );
+ bTimedOut = waitformultiple( hevBlockQueueS,hevBlockQueueB,timeout,ONE );
+
+ lock( mtxUnblockLock );
+ if ( 0 != (SignalsWasLeft = nWaitersToUnblock) ) {
+ if ( bTimeout ) { // timeout (or canceled)
+ if ( 0 != nWaitersBlocked ) {
+ nWaitersBlocked--;
+ nSignalsWasLeft = 0; // do not unblock next waiter
+below (already unblocked)
+ }
+ else if ( 1 != eBroadcast ) {
+ nWaitersGone = 1;
+ }
+ }
+ if ( 0 == --nWaitersToUnblock ) {
+ if ( 0 != nWaitersBlocked ) {
+ set_event( hevBlockLock ); // open the gate
+ nSignalsWasLeft = 0; // do not open the gate below
+again
+ }
+ else {
+ if ( 0 != (eWasBroadcast = eBroadcast) ) {
+ eBroadcast = 0;
+ }
+ if ( 0 != (nWaitersWasGone = nWaitersGone ) {
+ nWaitersGone = 0;
+ }
+ }
+ }
+ else if ( 0 != eBroadcast ) {
+ nSignalsWasLeft = 0; // do not unblock next waiter
+below (already unblocked)
+ }
+ }
+ else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or spurious
+event :-)
+ wait( hevBlockLock,INFINITE );
+ nWaitersBlocked -= nWaitersGone; // something is going on here -
+test of timeouts? :-)
+ set_event( hevBlockLock );
+ nWaitersGone = 0;
+ }
+ unlock( mtxUnblockLock );
+
+ if ( 1 == nSignalsWasLeft ) {
+ if ( 0 != eWasBroadcast ) {
+ reset_event( hevBlockQueueB );
+ }
+ if ( 0 != nWaitersWasGone ) {
+ reset_event( hevBlockQueueS ); // better now than spurious
+later
+ }
+ set_event( hevBlockLock ); // open the gate
+ }
+ else if ( 0 != nSignalsWasLeft ) {
+ set_event( hevBlockQueueS ); // unblock next waiter
+ }
+
+ lock( mtxExternal );
+
+ return ( bTimedOut ) ? ETIMEOUT : 0;
+}
+
+signal(bAll) {
+
+ [auto: register int result ]
+ [auto: register HANDLE hevBlockQueue ]
+
+ lock( mtxUnblockLock );
+
+ if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
+ if ( 0 == nWaitersBlocked ) { // NO-OP
+ return unlock( mtxUnblockLock );
+ }
+ if (bAll) {
+ nWaitersToUnblock += nWaitersBlocked;
+ nWaitersBlocked = 0;
+ eBroadcast = 2;
+ hevBlockQueue = hevBlockQueueB;
+ }
+ else {
+ nWaitersToUnblock++;
+ nWaitersBlocked--;
+ return unlock( mtxUnblockLock );
+ }
+ }
+ else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+ wait( hevBlockLock,INFINITE ); // close the gate
+ if ( 0 != nWaitersGone ) {
+ nWaitersBlocked -= nWaitersGone;
+ nWaitersGone = 0;
+ }
+ if (bAll) {
+ nWaitersToUnblock = nWaitersBlocked;
+ nWaitersBlocked = 0;
+ eBroadcast = 1;
+ hevBlockQueue = hevBlockQueueB;
+ }
+ else {
+ nWaitersToUnblock = 1;
+ nWaitersBlocked--;
+ hevBlockQueue = hevBlockQueueS;
+ }
+ }
+ else { // NO-OP
+ return unlock( mtxUnblockLock );
+ }
+
+ unlock( mtxUnblockLock );
+ set_event( hevBlockQueue );
+ return result;
+}
+---------------------- Forwarded by Alexander Terekhov/Germany/IBM on
+02/21/2001 09:13 AM ---------------------------
+
+Alexander Terekhov
+02/20/2001 04:33 PM
+
+To: Louis Thomas <lthomas@arbitrade.com>
+cc:
+
+From: Alexander Terekhov/Germany/IBM@IBMDE
+Subject: RE: FYI/comp.programming.threads/Re: pthread_cond_* implementatio
+ n questions
+Importance: Normal
+
+>Sorry, gotta take a break and work on something else for a while.
+>Real work
+>calls, unfortunately. I'll get back to you in two or three days.
+
+ok. no problem. here is some more stuff for pauses you might have
+in between :)
+
+---------- Algorithm 7d / IMPL_EVENT,UNBLOCK_STRATEGY == UNBLOCK_ALL ------
+given:
+hevBlockLock - auto-reset event
+hevBlockQueueS - auto-reset event // for signals
+hevBlockQueueB - manual-reset even // for broadcasts
+mtxExternal - mutex or CS
+mtxUnblockLock - mutex or CS
+bBroadcast - int
+nWaitersGone - int
+nWaitersBlocked - int
+nWaitersToUnblock - int
+
+wait( timeout ) {
+
+ [auto: register int result ] // error checking omitted
+ [auto: register int bWasBroadcast ]
+ [auto: register int nSignalsWasLeft ]
+
+ wait( hevBlockLock,INFINITE );
+ nWaitersBlocked++;
+ set_event( hevBlockLock );
+
+ unlock( mtxExternal );
+ bTimedOut = waitformultiple( hevBlockQueueS,hevBlockQueueB,timeout,ONE );
+
+ lock( mtxUnblockLock );
+ if ( 0 != (SignalsWasLeft = nWaitersToUnblock) ) {
+ if ( bTimeout ) { // timeout (or canceled)
+ if ( 0 != nWaitersBlocked ) {
+ nWaitersBlocked--;
+ nSignalsWasLeft = 0; // do not unblock next waiter
+below (already unblocked)
+ }
+ else if ( !bBroadcast ) {
+ wait( hevBlockQueueS,INFINITE ); // better now than spurious
+later
+ }
+ }
+ if ( 0 == --nWaitersToUnblock ) {
+ if ( 0 != nWaitersBlocked ) {
+ if ( bBroadcast ) {
+ reset_event( hevBlockQueueB );
+ bBroadcast = false;
+ }
+ set_event( hevBlockLock ); // open the gate
+ nSignalsWasLeft = 0; // do not open the gate below
+again
+ }
+ else if ( false != (bWasBroadcast = bBroadcast) ) {
+ bBroadcast = false;
+ }
+ }
+ else {
+ bWasBroadcast = bBroadcast;
+ }
+ }
+ else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or spurious
+event :-)
+ wait( hevBlockLock,INFINITE );
+ nWaitersBlocked -= nWaitersGone; // something is going on here -
+test of timeouts? :-)
+ set_event( hevBlockLock );
+ nWaitersGone = 0;
+ }
+ unlock( mtxUnblockLock );
+
+ if ( 1 == nSignalsWasLeft ) {
+ if ( bWasBroadcast ) {
+ reset_event( hevBlockQueueB );
+ }
+ set_event( hevBlockLock ); // open the gate
+ }
+ else if ( 0 != nSignalsWasLeft && !bWasBroadcast ) {
+ set_event( hevBlockQueueS ); // unblock next waiter
+ }
+
+ lock( mtxExternal );
+
+ return ( bTimedOut ) ? ETIMEOUT : 0;
+}
+
+signal(bAll) {
+
+ [auto: register int result ]
+ [auto: register HANDLE hevBlockQueue ]
+
+ lock( mtxUnblockLock );
+
+ if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
+ if ( 0 == nWaitersBlocked ) { // NO-OP
+ return unlock( mtxUnblockLock );
+ }
+ if (bAll) {
+ nWaitersToUnblock += nWaitersBlocked;
+ nWaitersBlocked = 0;
+ bBroadcast = true;
+ hevBlockQueue = hevBlockQueueB;
+ }
+ else {
+ nWaitersToUnblock++;
+ nWaitersBlocked--;
+ return unlock( mtxUnblockLock );
+ }
+ }
+ else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+ wait( hevBlockLock,INFINITE ); // close the gate
+ if ( 0 != nWaitersGone ) {
+ nWaitersBlocked -= nWaitersGone;
+ nWaitersGone = 0;
+ }
+ if (bAll) {
+ nWaitersToUnblock = nWaitersBlocked;
+ nWaitersBlocked = 0;
+ bBroadcast = true;
+ hevBlockQueue = hevBlockQueueB;
+ }
+ else {
+ nWaitersToUnblock = 1;
+ nWaitersBlocked--;
+ hevBlockQueue = hevBlockQueueS;
+ }
+ }
+ else { // NO-OP
+ return unlock( mtxUnblockLock );
+ }
+
+ unlock( mtxUnblockLock );
+ set_event( hevBlockQueue );
+ return result;
+}
+
+
+----------------------------------------------------------------------------
+
+Subject: RE: FYI/comp.programming.threads/Re: pthread_cond_* implementatio
+ n questions
+Date: Mon, 26 Feb 2001 22:20:12 -0600
+From: Louis Thomas <lthomas@arbitrade.com>
+To: "'TEREKHOV@de.ibm.com'" <TEREKHOV@de.ibm.com>
+CC: rpj@ise.canberra.edu.au, Thomas Pfaff <tpfaff@gmx.net>,
+ Nanbor Wang
+ <nanbor@cs.wustl.edu>
+
+Sorry all. Busy week.
+
+> this insures the fairness
+> which POSIX does not (e.g. two subsequent broadcasts - the gate does
+insure
+> that first wave waiters will start the race for the mutex before waiters
+> from the second wave - Linux pthreads process/unblock both waves
+> concurrently...)
+
+I'm not sure how we are any more fair about this than Linux. We certainly
+don't guarantee that the threads released by the first broadcast will get
+the external mutex before the threads of the second wave. In fact, it is
+possible that those threads will never get the external mutex if there is
+enough contention for it.
+
+> e.g. i was thinking about implementation with a pool of
+> N semaphores/counters [...]
+
+I considered that too. The problem is as you mentioned in a). You really
+need to assign threads to semaphores once you know how you want to wake them
+up, not when they first begin waiting which is the only time you can assign
+them.
+
+> well, i am not quite sure that i've fully understood your scenario,
+
+Hmm. Well, it think it's an important example, so I'll try again. First, we
+have thread A which we KNOW is waiting on a condition. As soon as it becomes
+unblocked for any reason, we will know because it will set a flag. Since the
+flag is not set, we are 100% confident that thread A is waiting on the
+condition. We have another thread, thread B, which has acquired the mutex
+and is about to wait on the condition. Thus it is pretty clear that at any
+point, either just A is waiting, or A and B are waiting. Now thread C comes
+along. C is about to do a broadcast on the condition. A broadcast is
+guaranteed to unblock all threads currently waiting on a condition, right?
+Again, we said that either just A is waiting, or A and B are both waiting.
+So, when C does its broadcast, depending upon whether B has started waiting
+or not, thread C will unblock A or unblock A and B. Either way, C must
+unblock A, right?
+
+Now, you said anything that happens is correct so long as a) "a signal is
+not lost between unlocking the mutex and waiting on the condition" and b) "a
+thread must not steal a signal it sent", correct? Requirement b) is easy to
+satisfy: in this scenario, thread C will never wait on the condition, so it
+won't steal any signals. Requirement a) is not hard either. The only way we
+could fail to meet requirement a) in this scenario is if thread B was
+started waiting but didn't wake up because a signal was lost. This will not
+happen.
+
+Now, here is what happens. Assume thread C beats thread B. Thread C looks to
+see how many threads are waiting on the condition. Thread C sees just one
+thread, thread A, waiting. It does a broadcast waking up just one thread
+because just one thread is waiting. Next, before A can become unblocked,
+thread B begins waiting. Now there are two threads waiting, but only one
+will be unblocked. Suppose B wins. B will become unblocked. A will not
+become unblocked, because C only unblocked one thread (sema_post cond, 1).
+So at the end, B finishes and A remains blocked.
+
+We have met both of your requirements, so by your rules, this is an
+acceptable outcome. However, I think that the spec says this is an
+unacceptable outcome! We know for certain that A was waiting and that C did
+a broadcast, but A did not become unblocked! Yet, the spec says that a
+broadcast wakes up all waiting threads. This did not happen. Do you agree
+that this shows your rules are not strict enough?
+
+> and what about N2? :) this one does allow almost everything.
+
+Don't get me started about rule #2. I'll NEVER advocate an algorithm that
+uses rule 2 as an excuse to suck!
+
+> but it is done (decrement)under mutex protection - this is not a subject
+> of a race condition.
+
+You are correct. My mistake.
+
+> i would remove "_bTimedOut=false".. after all, it was a real timeout..
+
+I disagree. A thread that can't successfully retract its waiter status can't
+really have timed out. If a thread can't return without executing extra code
+to deal with the fact that someone tried to unblock it, I think it is a poor
+idea to pretend we
+didn't realize someone was trying to signal us. After all, a signal is more
+important than a time out.
+
+> when nSignaled != 0, it is possible to update nWaiters (--) and do not
+> touch nGone
+
+I realize this, but I was thinking that writing it the other ways saves
+another if statement.
+
+> adjust only if nGone != 0 and save one cache memory write - probably much
+slower than 'if'
+
+Hmm. You are probably right.
+
+> well, in a strange (e.g. timeout test) program you may (theoretically)
+> have an overflow of nWaiters/nGone counters (with waiters repeatedly
+timing
+> out and no signals at all).
+
+Also true. Not only that, but you also have the possibility that one could
+overflow the number of waiters as well! However, considering the limit you
+have chosen for nWaitersGone, I suppose it is unlikely that anyone would be
+able to get INT_MAX/2 threads waiting on a single condition. :)
+
+Analysis of 8a:
+
+It looks correct to me.
+
+What are IPC semaphores?
+
+In the line where you state, "else if ( nWaitersBlocked > nWaitersGone ) {
+// HARMLESS RACE CONDITION!" there is no race condition for nWaitersGone
+because nWaitersGone is never modified without holding mtxUnblockLock. You
+are correct that there is a harmless race on nWaitersBlocked, which can
+increase and make the condition become true just after we check it. If this
+happens, we interpret it as the wait starting after the signal.
+
+I like your optimization of this. You could improve Alg. 6 as follows:
+---------- Algorithm 6b ----------
+signal(bAll) {
+ _nSig=0
+ lock counters
+ // this is safe because nWaiting can only be decremented by a thread that
+ // owns counters and nGone can only be changed by a thread that owns
+counters.
+ if (nWaiting>nGone) {
+ if (0==nSignaled) {
+ sema_wait gate // close gate if not already closed
+ }
+ if (nGone>0) {
+ nWaiting-=nGone
+ nGone=0
+ }
+ _nSig=bAll?nWaiting:1
+ nSignaled+=_nSig
+ nWaiting-=_nSig
+ }
+ unlock counters
+ if (0!=_nSig) {
+ sema_post queue, _nSig
+ }
+}
+---------- ---------- ----------
+I guess this wouldn't apply to Alg 8a because nWaitersGone changes meanings
+depending upon whether the gate is open or closed.
+
+In the loop "while ( nWaitersWasGone-- ) {" you do a sema_wait on
+semBlockLock. Perhaps waiting on semBlockQueue would be a better idea.
+
+What have you gained by making the last thread to be signaled do the waits
+for all the timed out threads, besides added complexity? It took me a long
+time to figure out what your objective was with this, to realize you were
+using nWaitersGone to mean two different things, and to verify that you
+hadn't introduced any bug by doing this. Even now I'm not 100% sure.
+
+What has all this playing about with nWaitersGone really gained us besides a
+lot of complexity (it is much harder to verify that this solution is
+correct), execution overhead (we now have a lot more if statements to
+evaluate), and space overhead (more space for the extra code, and another
+integer in our data)? We did manage to save a lock/unlock pair in an
+uncommon case (when a time out occurs) at the above mentioned expenses in
+the common cases.
+
+As for 8b, c, and d, they look ok though I haven't studied them thoroughly.
+What would you use them for?
+
+ Later,
+ -Louis! :)
+
+-----------------------------------------------------------------------------
+
+Subject: RE: FYI/comp.programming.threads/Re: pthread_cond_* implementatio
+ n questions
+Date: Tue, 27 Feb 2001 15:51:28 +0100
+From: TEREKHOV@de.ibm.com
+To: Louis Thomas <lthomas@arbitrade.com>
+CC: rpj@ise.canberra.edu.au, Thomas Pfaff <tpfaff@gmx.net>,
+ Nanbor Wang <nanbor@cs.wustl.edu>
+
+Hi Louis,
+
+>> that first wave waiters will start the race for the mutex before waiters
+>> from the second wave - Linux pthreads process/unblock both waves
+>> concurrently...)
+>
+>I'm not sure how we are any more fair about this than Linux. We certainly
+>don't guarantee that the threads released by the first broadcast will get
+>the external mutex before the threads of the second wave. In fact, it is
+>possible that those threads will never get the external mutex if there is
+>enough contention for it.
+
+correct. but gate is nevertheless more fair than Linux because of the
+barrier it establishes between two races (1st and 2nd wave waiters) for
+the mutex which under 'normal' circumstances (e.g. all threads of equal
+priorities,..) will 'probably' result in fair behaviour with respect to
+mutex ownership.
+
+>> well, i am not quite sure that i've fully understood your scenario,
+>
+>Hmm. Well, it think it's an important example, so I'll try again. ...
+
+ok. now i seem to understand this example. well, now it seems to me
+that the only meaningful rule is just:
+
+a) "a signal is not lost between unlocking the mutex and waiting on the
+condition"
+
+and that the rule
+
+b) "a thread must not steal a signal it sent"
+
+is not needed at all because a thread which violates b) also violates a).
+
+i'll try to explain..
+
+i think that the most important thing is how POSIX defines waiter's
+visibility:
+
+"if another thread is able to acquire the mutex after the about-to-block
+thread
+has released it, then a subsequent call to pthread_cond_signal() or
+pthread_cond_broadcast() in that thread behaves as if it were issued after
+the about-to-block thread has blocked. "
+
+my understanding is the following:
+
+1) there is no guarantees whatsoever with respect to whether
+signal/broadcast
+will actually unblock any 'waiter' if it is done w/o acquiring the mutex
+first
+(note that a thread may release it before signal/broadcast - it does not
+matter).
+
+2) it is guaranteed that waiters become 'visible' - eligible for unblock as
+soon
+as signalling thread acquires the mutex (but not before!!)
+
+so..
+
+>So, when C does its broadcast, depending upon whether B has started
+waiting
+>or not, thread C will unblock A or unblock A and B. Either way, C must
+>unblock A, right?
+
+right. but only if C did acquire the mutex prior to broadcast (it may
+release it before broadcast as well).
+
+implementation will violate waiters visibility rule (signal will become
+lost)
+if C will not unblock A.
+
+>Now, here is what happens. Assume thread C beats thread B. Thread C looks
+to
+>see how many threads are waiting on the condition. Thread C sees just one
+>thread, thread A, waiting. It does a broadcast waking up just one thread
+>because just one thread is waiting. Next, before A can become unblocked,
+>thread B begins waiting. Now there are two threads waiting, but only one
+>will be unblocked. Suppose B wins. B will become unblocked. A will not
+>become unblocked, because C only unblocked one thread (sema_post cond, 1).
+>So at the end, B finishes and A remains blocked.
+
+thread C did acquire the mutex ("Thread C sees just one thread, thread A,
+waiting"). beginning from that moment it is guaranteed that subsequent
+broadcast will unblock A. Otherwise we will have a lost signal with respect
+to A. I do think that it does not matter whether the signal was physically
+(completely) lost or was just stolen by another thread (B) - in both cases
+it was simply lost with respect to A.
+
+>..Do you agree that this shows your rules are not strict enough?
+
+probably the opposite.. :-) i think that it shows that the only meaningful
+rule is
+
+a) "a signal is not lost between unlocking the mutex and waiting on the
+condition"
+
+with clarification of waiters visibility as defined by POSIX above.
+
+>> i would remove "_bTimedOut=false".. after all, it was a real timeout..
+>
+>I disagree. A thread that can't successfully retract its waiter status
+can't
+>really have timed out. If a thread can't return without executing extra
+code
+>to deal with the fact that someone tried to unblock it, I think it is a
+poor
+>idea to pretend we
+>didn't realize someone was trying to signal us. After all, a signal is
+more
+>important than a time out.
+
+a) POSIX does allow timed out thread to consume a signal (cancelled is
+not).
+b) ETIMEDOUT status just says that: "The time specified by abstime to
+pthread_cond_timedwait() has passed."
+c) it seem to me that hiding timeouts would violate "The
+pthread_cond_timedwait()
+function is the same as pthread_cond_wait() except that an error is
+returned if
+the absolute time specified by abstime passes (that is, system time equals
+or
+exceeds abstime) before the condition cond is signaled or broadcasted"
+because
+the abs. time did really pass before cond was signaled (waiter was
+released via semaphore). however, if it really matters, i could imaging
+that we
+can save an abs. time of signal/broadcast and compare it with timeout after
+unblock to find out whether it was a 'real' timeout or not. absent this
+check
+i do think that hiding timeouts would result in technical violation of
+specification.. but i think that this check is not important and we can
+simply
+trust timeout error code provided by wait since we are not trying to make
+'hard' realtime implementation.
+
+>What are IPC semaphores?
+
+<sys/sem.h>
+int semctl(int, int, int, ...);
+int semget(key_t, int, int);
+int semop(int, struct sembuf *, size_t);
+
+they support adjustment of semaphore counter (semvalue)
+in one single call - imaging Win32 ReleaseSemaphore( hsem,-N )
+
+>In the line where you state, "else if ( nWaitersBlocked > nWaitersGone ) {
+>// HARMLESS RACE CONDITION!" there is no race condition for nWaitersGone
+>because nWaitersGone is never modified without holding mtxUnblockLock. You
+>are correct that there is a harmless race on nWaitersBlocked, which can
+>increase and make the condition become true just after we check it. If
+this
+>happens, we interpret it as the wait starting after the signal.
+
+well, the reason why i've asked on comp.programming.threads whether this
+race
+condition is harmless or not is that in order to be harmless it should not
+violate the waiters visibility rule (see above). Fortunately, we increment
+the counter under protection of external mutex.. so that any (signalling)
+thread which will acquire the mutex next, should see the updated counter
+(in signal) according to POSIX memory visibility rules and mutexes
+(memory barriers). But i am not so sure how it actually works on
+Win32/INTEL
+which does not explicitly define any memory visibility rules :(
+
+>I like your optimization of this. You could improve Alg. 6 as follows:
+>---------- Algorithm 6b ----------
+>signal(bAll) {
+> _nSig=0
+> lock counters
+> // this is safe because nWaiting can only be decremented by a thread
+that
+> // owns counters and nGone can only be changed by a thread that owns
+>counters.
+> if (nWaiting>nGone) {
+> if (0==nSignaled) {
+> sema_wait gate // close gate if not already closed
+> }
+> if (nGone>0) {
+> nWaiting-=nGone
+> nGone=0
+> }
+> _nSig=bAll?nWaiting:1
+> nSignaled+=_nSig
+> nWaiting-=_nSig
+> }
+> unlock counters
+> if (0!=_nSig) {
+> sema_post queue, _nSig
+> }
+>}
+>---------- ---------- ----------
+>I guess this wouldn't apply to Alg 8a because nWaitersGone changes
+meanings
+>depending upon whether the gate is open or closed.
+
+agree.
+
+>In the loop "while ( nWaitersWasGone-- ) {" you do a sema_wait on
+>semBlockLock. Perhaps waiting on semBlockQueue would be a better idea.
+
+you are correct. my mistake.
+
+>What have you gained by making the last thread to be signaled do the waits
+>for all the timed out threads, besides added complexity? It took me a long
+>time to figure out what your objective was with this, to realize you were
+>using nWaitersGone to mean two different things, and to verify that you
+>hadn't introduced any bug by doing this. Even now I'm not 100% sure.
+>
+>What has all this playing about with nWaitersGone really gained us besides
+a
+>lot of complexity (it is much harder to verify that this solution is
+>correct), execution overhead (we now have a lot more if statements to
+>evaluate), and space overhead (more space for the extra code, and another
+>integer in our data)? We did manage to save a lock/unlock pair in an
+>uncommon case (when a time out occurs) at the above mentioned expenses in
+>the common cases.
+
+well, please consider the following:
+
+1) with multiple waiters unblocked (but some timed out) the trick with
+counter
+seem to ensure potentially higher level of concurrency by not delaying
+most of unblocked waiters for semaphore cleanup - only the last one
+will be delayed but all others would already contend/acquire/release
+the external mutex - the critical section protected by mtxUnblockLock is
+made smaller (increment + couple of IFs is faster than system/kernel call)
+which i think is good in general. however, you are right, this is done
+at expense of 'normal' waiters..
+
+2) some semaphore APIs (e.g. POSIX IPC sems) do allow to adjust the
+semaphore counter in one call => less system/kernel calls.. imagine:
+
+if ( 1 == nSignalsWasLeft ) {
+ if ( 0 != nWaitersWasGone ) {
+ ReleaseSemaphore( semBlockQueue,-nWaitersWasGone ); // better now
+than spurious later
+ }
+ sem_post( semBlockLock ); // open the gate
+ }
+
+3) even on win32 a single thread doing multiple cleanup calls (to wait)
+will probably result in faster execution (because of processor caching)
+than multiple threads each doing a single call to wait.
+
+>As for 8b, c, and d, they look ok though I haven't studied them
+thoroughly.
+>What would you use them for?
+
+8b) for semaphores which do not allow to unblock multiple waiters
+in a single call to post/release (e.g. POSIX realtime semaphores -
+<semaphore.h>)
+
+8c/8d) for WinCE prior to 3.0 (WinCE 3.0 does have semaphores)
+
+ok. so, which one is the 'final' algorithm(s) which we should use in
+pthreads-win32??
+
+regards,
+alexander.
+
+----------------------------------------------------------------------------
+
+Louis Thomas <lthomas@arbitrade.com> on 02/27/2001 05:20:12 AM
+
+Please respond to Louis Thomas <lthomas@arbitrade.com>
+
+To: Alexander Terekhov/Germany/IBM@IBMDE
+cc: rpj@ise.canberra.edu.au, Thomas Pfaff <tpfaff@gmx.net>, Nanbor Wang
+ <nanbor@cs.wustl.edu>
+Subject: RE: FYI/comp.programming.threads/Re: pthread_cond_* implementatio
+ n questions
+
+Sorry all. Busy week.
+
+> this insures the fairness
+> which POSIX does not (e.g. two subsequent broadcasts - the gate does
+insure
+> that first wave waiters will start the race for the mutex before waiters
+> from the second wave - Linux pthreads process/unblock both waves
+> concurrently...)
+
+I'm not sure how we are any more fair about this than Linux. We certainly
+don't guarantee that the threads released by the first broadcast will get
+the external mutex before the threads of the second wave. In fact, it is
+possible that those threads will never get the external mutex if there is
+enough contention for it.
+
+> e.g. i was thinking about implementation with a pool of
+> N semaphores/counters [...]
+
+I considered that too. The problem is as you mentioned in a). You really
+need to assign threads to semaphores once you know how you want to wake
+them
+up, not when they first begin waiting which is the only time you can assign
+them.
+
+> well, i am not quite sure that i've fully understood your scenario,
+
+Hmm. Well, it think it's an important example, so I'll try again. First, we
+have thread A which we KNOW is waiting on a condition. As soon as it
+becomes
+unblocked for any reason, we will know because it will set a flag. Since
+the
+flag is not set, we are 100% confident that thread A is waiting on the
+condition. We have another thread, thread B, which has acquired the mutex
+and is about to wait on the condition. Thus it is pretty clear that at any
+point, either just A is waiting, or A and B are waiting. Now thread C comes
+along. C is about to do a broadcast on the condition. A broadcast is
+guaranteed to unblock all threads currently waiting on a condition, right?
+Again, we said that either just A is waiting, or A and B are both waiting.
+So, when C does its broadcast, depending upon whether B has started waiting
+or not, thread C will unblock A or unblock A and B. Either way, C must
+unblock A, right?
+
+Now, you said anything that happens is correct so long as a) "a signal is
+not lost between unlocking the mutex and waiting on the condition" and b)
+"a
+thread must not steal a signal it sent", correct? Requirement b) is easy to
+satisfy: in this scenario, thread C will never wait on the condition, so it
+won't steal any signals. Requirement a) is not hard either. The only way
+we
+could fail to meet requirement a) in this scenario is if thread B was
+started waiting but didn't wake up because a signal was lost. This will not
+happen.
+
+Now, here is what happens. Assume thread C beats thread B. Thread C looks
+to
+see how many threads are waiting on the condition. Thread C sees just one
+thread, thread A, waiting. It does a broadcast waking up just one thread
+because just one thread is waiting. Next, before A can become unblocked,
+thread B begins waiting. Now there are two threads waiting, but only one
+will be unblocked. Suppose B wins. B will become unblocked. A will not
+become unblocked, because C only unblocked one thread (sema_post cond, 1).
+So at the end, B finishes and A remains blocked.
+
+We have met both of your requirements, so by your rules, this is an
+acceptable outcome. However, I think that the spec says this is an
+unacceptable outcome! We know for certain that A was waiting and that C did
+a broadcast, but A did not become unblocked! Yet, the spec says that a
+broadcast wakes up all waiting threads. This did not happen. Do you agree
+that this shows your rules are not strict enough?
+
+> and what about N2? :) this one does allow almost everything.
+
+Don't get me started about rule #2. I'll NEVER advocate an algorithm that
+uses rule 2 as an excuse to suck!
+
+> but it is done (decrement)under mutex protection - this is not a subject
+> of a race condition.
+
+You are correct. My mistake.
+
+> i would remove "_bTimedOut=false".. after all, it was a real timeout..
+
+I disagree. A thread that can't successfully retract its waiter status
+can't
+really have timed out. If a thread can't return without executing extra
+code
+to deal with the fact that someone tried to unblock it, I think it is a
+poor
+idea to pretend we
+didn't realize someone was trying to signal us. After all, a signal is more
+important than a time out.
+
+> when nSignaled != 0, it is possible to update nWaiters (--) and do not
+> touch nGone
+
+I realize this, but I was thinking that writing it the other ways saves
+another if statement.
+
+> adjust only if nGone != 0 and save one cache memory write - probably much
+slower than 'if'
+
+Hmm. You are probably right.
+
+> well, in a strange (e.g. timeout test) program you may (theoretically)
+> have an overflow of nWaiters/nGone counters (with waiters repeatedly
+timing
+> out and no signals at all).
+
+Also true. Not only that, but you also have the possibility that one could
+overflow the number of waiters as well! However, considering the limit you
+have chosen for nWaitersGone, I suppose it is unlikely that anyone would be
+able to get INT_MAX/2 threads waiting on a single condition. :)
+
+Analysis of 8a:
+
+It looks correct to me.
+
+What are IPC semaphores?
+
+In the line where you state, "else if ( nWaitersBlocked > nWaitersGone ) {
+// HARMLESS RACE CONDITION!" there is no race condition for nWaitersGone
+because nWaitersGone is never modified without holding mtxUnblockLock. You
+are correct that there is a harmless race on nWaitersBlocked, which can
+increase and make the condition become true just after we check it. If this
+happens, we interpret it as the wait starting after the signal.
+
+I like your optimization of this. You could improve Alg. 6 as follows:
+---------- Algorithm 6b ----------
+signal(bAll) {
+ _nSig=0
+ lock counters
+ // this is safe because nWaiting can only be decremented by a thread that
+ // owns counters and nGone can only be changed by a thread that owns
+counters.
+ if (nWaiting>nGone) {
+ if (0==nSignaled) {
+ sema_wait gate // close gate if not already closed
+ }
+ if (nGone>0) {
+ nWaiting-=nGone
+ nGone=0
+ }
+ _nSig=bAll?nWaiting:1
+ nSignaled+=_nSig
+ nWaiting-=_nSig
+ }
+ unlock counters
+ if (0!=_nSig) {
+ sema_post queue, _nSig
+ }
+}
+---------- ---------- ----------
+I guess this wouldn't apply to Alg 8a because nWaitersGone changes meanings
+depending upon whether the gate is open or closed.
+
+In the loop "while ( nWaitersWasGone-- ) {" you do a sema_wait on
+semBlockLock. Perhaps waiting on semBlockQueue would be a better idea.
+
+What have you gained by making the last thread to be signaled do the waits
+for all the timed out threads, besides added complexity? It took me a long
+time to figure out what your objective was with this, to realize you were
+using nWaitersGone to mean two different things, and to verify that you
+hadn't introduced any bug by doing this. Even now I'm not 100% sure.
+
+What has all this playing about with nWaitersGone really gained us besides
+a
+lot of complexity (it is much harder to verify that this solution is
+correct), execution overhead (we now have a lot more if statements to
+evaluate), and space overhead (more space for the extra code, and another
+integer in our data)? We did manage to save a lock/unlock pair in an
+uncommon case (when a time out occurs) at the above mentioned expenses in
+the common cases.
+
+As for 8b, c, and d, they look ok though I haven't studied them thoroughly.
+What would you use them for?
+
+ Later,
+ -Louis! :)
+
diff --git a/pthreads/README.NONPORTABLE b/pthreads/README.NONPORTABLE
new file mode 100644
index 000000000..aa43297e1
--- /dev/null
+++ b/pthreads/README.NONPORTABLE
@@ -0,0 +1,285 @@
+This file documents non-portable functions and other issues.
+
+Non-portable functions included in pthreads-win32
+-------------------------------------------------
+
+BOOL
+pthread_win32_test_features_np(int mask)
+
+ This routine allows an application to check which
+ run-time auto-detected features are available within
+ the library.
+
+ The possible features are:
+
+ PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE
+ Return TRUE if the native version of
+ InterlockedCompareExchange() is being used.
+ PTW32_ALERTABLE_ASYNC_CANCEL
+ Return TRUE is the QueueUserAPCEx package
+ QUSEREX.DLL is available and the AlertDrv.sys
+ driver is loaded into Windows, providing
+ alertable (pre-emptive) asyncronous threads
+ cancelation. If this feature returns FALSE
+ then the default async cancel scheme is in
+ use, which cannot cancel blocked threads.
+
+ Features may be Or'ed into the mask parameter, in which case
+ the routine returns TRUE if any of the Or'ed features would
+ return TRUE. At this stage it doesn't make sense to Or features
+ but it may some day.
+
+
+void *
+pthread_timechange_handler_np(void *)
+
+ 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.
+
+ It has the same return type and argument type as a
+ thread routine so that it may be called directly
+ through pthread_create(), i.e. as a separate thread.
+
+ Parameters
+
+ Although a parameter must be supplied, it is ignored.
+ The value NULL can be used.
+
+ Return values
+
+ It can return an error EAGAIN to indicate that not
+ all condition variables were broadcast for some reason.
+ Otherwise, 0 is returned.
+
+ If run as a thread, the return value is returned
+ through pthread_join().
+
+ The return value should be cast to an integer.
+
+
+HANDLE
+pthread_getw32threadhandle_np(pthread_t thread);
+
+ Returns the win32 thread handle that the POSIX
+ thread "thread" is running as.
+
+ Applications can use the win32 handle to set
+ win32 specific attributes of the thread.
+
+
+int
+pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, int kind)
+
+int
+pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, int *kind)
+
+ These two routines are included for Linux compatibility
+ and are direct equivalents to the standard routines
+ pthread_mutexattr_settype
+ pthread_mutexattr_gettype
+
+ pthread_mutexattr_setkind_np accepts the following
+ mutex kinds:
+ PTHREAD_MUTEX_FAST_NP
+ PTHREAD_MUTEX_ERRORCHECK_NP
+ PTHREAD_MUTEX_RECURSIVE_NP
+
+ These are really just equivalent to (respectively):
+ PTHREAD_MUTEX_NORMAL
+ PTHREAD_MUTEX_ERRORCHECK
+ PTHREAD_MUTEX_RECURSIVE
+
+int
+pthread_delay_np (const struct timespec *interval);
+
+ This routine causes a thread to delay execution for a specific period of time.
+ This period ends at the current time plus the specified interval. The routine
+ will not return before the end of the period is reached, but may return an
+ arbitrary amount of time after the period has gone by. This can be due to
+ system load, thread priorities, and system timer granularity.
+
+ Specifying an interval of zero (0) seconds and zero (0) nanoseconds is
+ allowed and can be used to force the thread to give up the processor or to
+ deliver a pending cancelation request.
+
+ This routine is a cancelation point.
+
+ The timespec structure contains the following two fields:
+
+ tv_sec is an integer number of seconds.
+ tv_nsec is an integer number of nanoseconds.
+
+ Return Values
+
+ If an error condition occurs, this routine returns an integer value
+ indicating the type of error. Possible return values are as follows:
+
+ 0 Successful completion.
+ [EINVAL] The value specified by interval is invalid.
+
+int
+pthread_num_processors_np
+
+ This routine (found on HPUX systems) returns the number of processors
+ in the system. This implementation actually returns the number of
+ processors available to the process, which can be a lower number
+ than the system's number, depending on the process's affinity mask.
+
+BOOL
+pthread_win32_process_attach_np (void);
+
+BOOL
+pthread_win32_process_detach_np (void);
+
+BOOL
+pthread_win32_thread_attach_np (void);
+
+BOOL
+pthread_win32_thread_detach_np (void);
+
+ These functions contain the code normally run via dllMain
+ when the library is used as a dll but which need to be
+ called explicitly by an application when the library
+ is statically linked.
+
+ You will need to call pthread_win32_process_attach_np() before
+ you can call any pthread routines when statically linking.
+ You should call pthread_win32_process_detach_np() before
+ exiting your application to clean up.
+
+ pthread_win32_thread_attach_np() is currently a no-op, but
+ pthread_win32_thread_detach_np() is needed to clean up
+ the implicit pthread handle that is allocated to a Win32 thread if
+ it calls certain pthreads routines. Call this routine when the
+ Win32 thread exits.
+
+ These functions invariably return TRUE except for
+ pthread_win32_process_attach_np() which will return FALSE
+ if pthreads-win32 initialisation fails.
+
+int
+pthreadCancelableWait (HANDLE waitHandle);
+
+int
+pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout);
+
+ These two functions provide hooks into the pthread_cancel
+ mechanism that will allow you to wait on a Windows handle
+ and make it a cancellation point. Both functions block
+ until either the given w32 handle is signaled, or
+ pthread_cancel has been called. It is implemented using
+ WaitForMultipleObjects on 'waitHandle' and a manually
+ reset w32 event used to implement pthread_cancel.
+
+
+Non-portable issues
+-------------------
+
+Thread priority
+
+ POSIX defines a single contiguous range of numbers that determine a
+ thread's priority. Win32 defines priority classes and priority
+ levels relative to these classes. Classes are simply priority base
+ levels that the defined priority levels are relative to such that,
+ changing a process's priority class will change the priority of all
+ of it's threads, while the threads retain the same relativity to each
+ other.
+
+ A Win32 system defines a single contiguous monotonic range of values
+ that define system priority levels, just like POSIX. However, Win32
+ restricts individual threads to a subset of this range on a
+ per-process basis.
+
+ The following table shows the base priority levels for combinations
+ of priority class and priority value in Win32.
+
+ Process Priority Class Thread Priority Level
+ -----------------------------------------------------------------
+ 1 IDLE_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ 1 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ 1 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ 1 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ 1 HIGH_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ 2 IDLE_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ 3 IDLE_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ 4 IDLE_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ 4 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ 5 IDLE_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ 5 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ 5 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ 6 IDLE_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ 6 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ 6 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ 7 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ 7 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ 7 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ 8 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ 8 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ 8 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ 8 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ 9 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ 9 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ 9 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ 10 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ 10 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ 11 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ 11 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ 11 HIGH_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ 12 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ 12 HIGH_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ 13 HIGH_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ 14 HIGH_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ 15 HIGH_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ 15 HIGH_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ 15 IDLE_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ 15 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ 15 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ 15 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ 16 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ 17 REALTIME_PRIORITY_CLASS -7
+ 18 REALTIME_PRIORITY_CLASS -6
+ 19 REALTIME_PRIORITY_CLASS -5
+ 20 REALTIME_PRIORITY_CLASS -4
+ 21 REALTIME_PRIORITY_CLASS -3
+ 22 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ 23 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ 24 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ 25 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ 26 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ 27 REALTIME_PRIORITY_CLASS 3
+ 28 REALTIME_PRIORITY_CLASS 4
+ 29 REALTIME_PRIORITY_CLASS 5
+ 30 REALTIME_PRIORITY_CLASS 6
+ 31 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+
+ Windows NT: Values -7, -6, -5, -4, -3, 3, 4, 5, and 6 are not supported.
+
+
+ As you can see, the real priority levels available to any individual
+ Win32 thread are non-contiguous.
+
+ An application using pthreads-win32 should not make assumptions about
+ the numbers used to represent thread priority levels, except that they
+ are monotonic between the values returned by sched_get_priority_min()
+ and sched_get_priority_max(). E.g. Windows 95, 98, NT, 2000, XP make
+ available a non-contiguous range of numbers between -15 and 15, while
+ at least one version of WinCE (3.0) defines the minimum priority
+ (THREAD_PRIORITY_LOWEST) as 5, and the maximum priority
+ (THREAD_PRIORITY_HIGHEST) as 1.
+
+ Internally, pthreads-win32 maps any priority levels between
+ THREAD_PRIORITY_IDLE and THREAD_PRIORITY_LOWEST to THREAD_PRIORITY_LOWEST,
+ or between THREAD_PRIORITY_TIME_CRITICAL and THREAD_PRIORITY_HIGHEST to
+ THREAD_PRIORITY_HIGHEST. Currently, this also applies to
+ REALTIME_PRIORITY_CLASSi even if levels -7, -6, -5, -4, -3, 3, 4, 5, and 6
+ are supported.
+
+ If it wishes, a Win32 application using pthreads-win32 can use the Win32
+ defined priority macros THREAD_PRIORITY_IDLE through
+ THREAD_PRIORITY_TIME_CRITICAL.
diff --git a/pthreads/README.Watcom b/pthreads/README.Watcom
new file mode 100644
index 000000000..2974928a3
--- /dev/null
+++ b/pthreads/README.Watcom
@@ -0,0 +1,62 @@
+Watcom compiler notes
+=====================
+
+Status
+------
+Not yet usable. Although the library builds under Watcom it
+substantially fails the test suite.
+
+There is a working Wmakefile for wmake for the library build.
+
+invoke as any of:
+wmake -f Wmakefile clean WC
+wmake -f Wmakefile clean WC-inlined
+wmake -f Wmakefile clean WCE
+wmake -f Wmakefile clean WCE-inlined
+
+These build pthreadWC.dll and pthreadWCE.dll.
+
+There is a working Wmakefile for wmake for the test suite.
+
+invoke as any of:
+wmake -f Wmakefile clean WC
+wmake -f Wmakefile clean WCX
+wmake -f Wmakefile clean WCE
+wmake -f Wmakefile clean WC-bench
+wmake -f Wmakefile clean WCX-bench
+wmake -f Wmakefile clean WCE-bench
+
+
+Current known problems
+----------------------
+
+Library build:
+The Watcom compiler uses a different default call convention to MS C or GNU C and so
+applications are not compatible with pthreadVC.dll etc using pre 2003-10-14 versions
+of pthread.h, sched.h, or semaphore.h. The cdecl attribute can be used on exposed
+function prototypes to force compatibility with MS C built DLLs.
+
+However, there appear to be other incompatibilities. Errno.h, for example, defines
+different values for the standard C and POSIX errors to those defined by the MS C
+errno.h. It may be that references to Watcom's threads compatible 'errno' do set
+and return translated numbers consistently, but I have not verified this.
+
+Watcom defines errno as a dereferenced pointer returned by the function
+_get_errno_ptr(). This is similar to both the MS and GNU C environments for
+multithreaded use. However, the Watcom version appears to have a number of problems:
+
+- different threads return the same pointer value. Compare with the MS and GNU C
+versions which correctly return different values (since each thread must maintain
+a thread specific errno value).
+
+- an errno value set within the DLL appears as zero in the application even though
+both share the same thread.
+
+Therefore applications built using the Watcom compiler may need to use
+a Watcom built version of the library (pthreadWC.dll). If this is the case, then
+the cdecl function attribute should not be required.
+
+Application builds:
+The test suite fails with the Watcom compiler.
+
+Test semaphore1.c fails for pthreadWC.dll because errno returns 0 instead of EAGAIN.
diff --git a/pthreads/README.WinCE b/pthreads/README.WinCE
new file mode 100644
index 000000000..a2cd8c213
--- /dev/null
+++ b/pthreads/README.WinCE
@@ -0,0 +1,6 @@
+WinCE port
+----------
+(See the file WinCE-PORT for a detailed explanation.)
+
+Make sure you define "WINCE" amongst your compiler flags (eg. -DWINCE).
+The config.h file will define all the necessary defines for you.
diff --git a/pthreads/TODO b/pthreads/TODO
new file mode 100644
index 000000000..fa9efc46e
--- /dev/null
+++ b/pthreads/TODO
@@ -0,0 +1,7 @@
+ Things that aren't done yet
+ ---------------------------
+
+1. Implement PTHREAD_PROCESS_SHARED for semaphores, mutexes,
+ condition variables, read/write locks, barriers.
+
+
diff --git a/pthreads/WinCE-PORT b/pthreads/WinCE-PORT
new file mode 100644
index 000000000..f5981a9db
--- /dev/null
+++ b/pthreads/WinCE-PORT
@@ -0,0 +1,217 @@
+NOTE: The comments in this file relate to the original WinCE port
+done by Tristan Savatier. The semaphore routines have been
+completely rewritten since (2005-04-25), having been progressively
+broken more and more by changes to the library. All of the semaphore
+routines implemented for W9x/WNT/2000 and up should now also work for
+WinCE. Also, pthread_mutex_timedlock should now work. [RPJ]
+
+----
+
+Some interesting news:
+
+I have been able to port pthread-win32 to Windows-CE,
+which uses a subset of the WIN32 API.
+
+Since we intend to keep using pthread-win32 for our
+Commercial WinCE developments, I would be very interested
+if WinCE support could be added to the main source tree
+of pthread-win32. Also, I would like to be credited
+for this port :-)
+
+Now, here is the story...
+
+The port was performed and tested on a Casio "Cassiopeia"
+PalmSize PC, which runs a MIP processor. The OS in the
+Casio is WinCE version 2.11, but I used VC++ 6.0 with
+the WinCE SDK for version 2.01.
+
+I used pthread-win32 to port a heavily multithreaded
+commercial application (real-time MPEG video player)
+from Linux to WinCE. I consider the changes that
+I have done to be quite well tested.
+
+Overall the modifications that we had to do are minor.
+
+The WinCE port were based on pthread-win32-snap-1999-05-30,
+but I am certain that they can be integrated very easiely
+to more recent versions of the source.
+
+I have attached the modified source code:
+pthread-win32-snap-1999-05-30-WinCE.
+
+All the changes do not affect the code compiled on non-WinCE
+environment, provided that the macros used for WinCE compilation
+are not used, of course!
+
+Overall description of the WinCE port:
+-------------------------------------
+
+Most of the changes had to be made in areas where
+pthread-win32 was relying on some standard-C librairies
+(e.g. _ftime, calloc, errno), which are not available
+on WinCE. We have changed the code to use native Win32
+API instead (or in some cases we made wrappers).
+
+The Win32 Semaphores are not available,
+so we had to re-implement Semaphores using mutexes
+and events.
+
+Limitations / known problems of the WinCE port:
+----------------------------------------------
+
+Not all the semaphore routines have been ported
+(semaphores are defined by Posix but are not part
+pf pthread). I have just done enough to make
+pthread routines (that rely internally on semaphores)
+work, like signal conditions.
+
+I noticed that the Win32 threads work slightly
+differently on WinCE. This may have some impact
+on some tricky parts of pthread-win32, but I have
+not really investigated. For example, on WinCE,
+the process is killed if the main thread falls off
+the bottom (or calls pthread_exit), regardless
+of the existence of any other detached thread.
+Microsoft manual indicates that this behavior is
+deffirent from that of Windows Threads for other
+Win32 platforms.
+
+
+Detailed descriptions of the changes and rationals:
+
+------------------------------------
+- use a new macro NEED_ERRNO.
+
+If defined, the code in errno.c that defines a reentrant errno
+is compiled, regardless of _MT and _REENTRANT.
+
+Rational: On WinCE, there is no support for <stdio.h>, <errno.h> or
+any other standard C library, i.e. even if _MT or _REENTRANT
+is defined, errno is not provided by any library. NEED_ERRNO
+must be set to compile for WinCE.
+
+------------------------------------
+- In implement.h, change #include <semaphore.h> to #include "semaphore.h".
+
+Rational: semaphore.h is provided in pthread-win32 and should not
+be searched in the systems standard include. would not compile.
+This change does not seem to create problems on "classic" win32
+(e.g. win95).
+
+------------------------------------
+- use a new macro NEED_CALLOC.
+
+If defined, some code in misc.c will provide a replacement
+for calloc, which is not available on Win32.
+
+
+------------------------------------
+- use a new macro NEED_CREATETHREAD.
+
+If defined, implement.h defines the macro _beginthreadex
+and _endthreadex.
+
+Rational: On WinCE, the wrappers _beginthreadex and _endthreadex
+do not exist. The native Win32 routines must be used.
+
+------------------------------------
+- in misc.c:
+
+#ifdef NEED_DUPLICATEHANDLE
+ /* DuplicateHandle does not exist on WinCE */
+ self->threadH = GetCurrentThread();
+#else
+ if( !DuplicateHandle(
+ GetCurrentProcess(),
+ GetCurrentThread(),
+ GetCurrentProcess(),
+ &self->threadH,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS ) )
+ {
+ free( self );
+ return (NULL);
+ }
+#endif
+
+Rational: On WinCE, DuplicateHandle does not exist. I could not understand
+why DuplicateHandle must be used. It seems to me that getting the current
+thread handle with GetCurrentThread() is sufficient, and it seems to work
+perfectly fine, so maybe DuplicateHandle was just plain useless to begin with ?
+
+------------------------------------
+- In private.c, added some code at the beginning of ptw32_processInitialize
+to detect the case of multiple calls to ptw32_processInitialize.
+
+Rational: In order to debug pthread-win32, it is easier to compile
+it as a regular library (it is not possible to debug DLL's on winCE).
+In that case, the application must call ptw32_rocessInitialize()
+explicitely, to initialize pthread-win32. It is safer in this circumstance
+to handle the case where ptw32_processInitialize() is called on
+an already initialized library:
+
+int
+ptw32_processInitialize (void)
+{
+ if (ptw32_processInitialized) {
+ /*
+ * ignore if already initialized. this is useful for
+ * programs that uses a non-dll pthread
+ * library. such programs must call ptw32_processInitialize() explicitely,
+ * since this initialization routine is automatically called only when
+ * the dll is loaded.
+ */
+ return TRUE;
+ }
+ ptw32_processInitialized = TRUE;
+ [...]
+}
+
+------------------------------------
+- in private.c, if macro NEED_FTIME is defined, add routines to
+convert timespec_to_filetime and filetime_to_timespec, and modified
+code that was using _ftime() to use Win32 API instead.
+
+Rational: _ftime is not available on WinCE. It is necessary to use
+the native Win32 time API instead.
+
+Note: the routine timespec_to_filetime is provided as a convenience and a mean
+to test that filetime_to_timespec works, but it is not used by the library.
+
+------------------------------------
+- in semaphore.c, if macro NEED_SEM is defined, add code for the routines
+_increase_semaphore and _decrease_semaphore, and modify significantly
+the implementation of the semaphores so that it does not use CreateSemaphore.
+
+Rational: CreateSemaphore is not available on WinCE. I had to re-implement
+semaphores using mutexes and Events.
+
+Note: Only the semaphore routines that are used by pthread are implemented
+(i.e. signal conditions rely on a subset of the semaphores routines, and
+this subset works). Some other semaphore routines (e.g. sem_trywait) are
+not yet supported on my WinCE port (and since I don't need them, I am not
+planning to do anything about them).
+
+------------------------------------
+- in tsd.c, changed the code that defines TLS_OUT_OF_INDEXES
+
+/* TLS_OUT_OF_INDEXES not defined on WinCE */
+#ifndef TLS_OUT_OF_INDEXES
+#define TLS_OUT_OF_INDEXES 0xffffffff
+#endif
+
+Rational: TLS_OUT_OF_INDEXES is not defined in any standard include file
+on WinCE.
+
+------------------------------------
+- added file need_errno.h
+
+Rational: On WinCE, there is no errno.h file. need_errno.h is just a
+copy of windows version of errno.h, with minor modifications due to the fact
+that some of the error codes are defined by the WinCE socket library.
+In pthread.h, if NEED_ERRNO is defined, the file need_errno.h is
+included (instead of <errno.h>).
+
+
+-- eof
diff --git a/pthreads/attr.c b/pthreads/attr.c
new file mode 100644
index 000000000..a9d55f4a4
--- /dev/null
+++ b/pthreads/attr.c
@@ -0,0 +1,53 @@
+/*
+ * attr.c
+ *
+ * Description:
+ * This translation unit agregates operations on thread attribute objects.
+ * It is used for inline optimisation.
+ *
+ * The included modules are used separately when static executable sizes
+ * must be minimised.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "pthread_attr_init.c"
+#include "pthread_attr_destroy.c"
+#include "pthread_attr_getdetachstate.c"
+#include "pthread_attr_setdetachstate.c"
+#include "pthread_attr_getstackaddr.c"
+#include "pthread_attr_setstackaddr.c"
+#include "pthread_attr_getstacksize.c"
+#include "pthread_attr_setstacksize.c"
+#include "pthread_attr_getscope.c"
+#include "pthread_attr_setscope.c"
diff --git a/pthreads/barrier.c b/pthreads/barrier.c
new file mode 100644
index 000000000..41b950cd1
--- /dev/null
+++ b/pthreads/barrier.c
@@ -0,0 +1,47 @@
+/*
+ * barrier.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"
+
+
+#include "pthread_barrier_init.c"
+#include "pthread_barrier_destroy.c"
+#include "pthread_barrier_wait.c"
+#include "pthread_barrierattr_init.c"
+#include "pthread_barrierattr_destroy.c"
+#include "pthread_barrierattr_getpshared.c"
+#include "pthread_barrierattr_setpshared.c"
diff --git a/pthreads/builddmc.bat b/pthreads/builddmc.bat
new file mode 100644
index 000000000..3edbaebb3
--- /dev/null
+++ b/pthreads/builddmc.bat
@@ -0,0 +1,9 @@
+; Build the pthreads library with the Digital Mars Compiler
+;
+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
+
+; 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
diff --git a/pthreads/cancel.c b/pthreads/cancel.c
new file mode 100644
index 000000000..1bd14ebe6
--- /dev/null
+++ b/pthreads/cancel.c
@@ -0,0 +1,44 @@
+/*
+ * 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 "pthread_setcancelstate.c"
+#include "pthread_setcanceltype.c"
+#include "pthread_testcancel.c"
+#include "pthread_cancel.c"
diff --git a/pthreads/cleanup.c b/pthreads/cleanup.c
new file mode 100644
index 000000000..381d1e87c
--- /dev/null
+++ b/pthreads/cleanup.c
@@ -0,0 +1,148 @@
+/*
+ * cleanup.c
+ *
+ * Description:
+ * This translation unit implements routines associated
+ * with cleaning up threads.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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"
+
+
+/*
+ * The functions ptw32_pop_cleanup and ptw32_push_cleanup
+ * are implemented here for applications written in C with no
+ * SEH or C++ destructor support.
+ */
+
+ptw32_cleanup_t *
+ptw32_pop_cleanup (int execute)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function pops the most recently pushed cleanup
+ * handler. If execute is nonzero, then the cleanup handler
+ * is executed if non-null.
+ *
+ * PARAMETERS
+ * execute
+ * if nonzero, execute the cleanup handler
+ *
+ *
+ * DESCRIPTION
+ * This function pops the most recently pushed cleanup
+ * handler. If execute is nonzero, then the cleanup handler
+ * is executed if non-null.
+ * NOTE: specify 'execute' as nonzero to avoid duplication
+ * of common cleanup code.
+ *
+ * RESULTS
+ * N/A
+ *
+ * ------------------------------------------------------
+ */
+{
+ ptw32_cleanup_t *cleanup;
+
+ cleanup = (ptw32_cleanup_t *) pthread_getspecific (ptw32_cleanupKey);
+
+ if (cleanup != NULL)
+ {
+ if (execute && (cleanup->routine != NULL))
+ {
+
+ (*cleanup->routine) (cleanup->arg);
+
+ }
+
+ pthread_setspecific (ptw32_cleanupKey, (void *) cleanup->prev);
+
+ }
+
+ return (cleanup);
+
+} /* ptw32_pop_cleanup */
+
+
+void
+ptw32_push_cleanup (ptw32_cleanup_t * cleanup,
+ ptw32_cleanup_callback_t routine, void *arg)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function pushes a new cleanup handler onto the thread's stack
+ * of cleanup handlers. Each cleanup handler pushed onto the stack is
+ * popped and invoked with the argument 'arg' when
+ * a) the thread exits by calling 'pthread_exit',
+ * b) when the thread acts on a cancellation request,
+ * c) or when the thread calls pthread_cleanup_pop with a nonzero
+ * 'execute' argument
+ *
+ * PARAMETERS
+ * cleanup
+ * a pointer to an instance of pthread_cleanup_t,
+ *
+ * routine
+ * pointer to a cleanup handler,
+ *
+ * arg
+ * parameter to be passed to the cleanup handler
+ *
+ *
+ * DESCRIPTION
+ * This function pushes a new cleanup handler onto the thread's stack
+ * of cleanup handlers. Each cleanup handler pushed onto the stack is
+ * popped and invoked with the argument 'arg' when
+ * a) the thread exits by calling 'pthread_exit',
+ * b) when the thread acts on a cancellation request,
+ * c) or when the thrad calls pthread_cleanup_pop with a nonzero
+ * 'execute' argument
+ * NOTE: pthread_push_cleanup, ptw32_pop_cleanup must be paired
+ * in the same lexical scope.
+ *
+ * RESULTS
+ * pthread_cleanup_t *
+ * pointer to the previous cleanup
+ *
+ * ------------------------------------------------------
+ */
+{
+ cleanup->routine = routine;
+ cleanup->arg = arg;
+
+ cleanup->prev = (ptw32_cleanup_t *) pthread_getspecific (ptw32_cleanupKey);
+
+ pthread_setspecific (ptw32_cleanupKey, (void *) cleanup);
+
+} /* ptw32_push_cleanup */
diff --git a/pthreads/condvar.c b/pthreads/condvar.c
new file mode 100644
index 000000000..704f4d793
--- /dev/null
+++ b/pthreads/condvar.c
@@ -0,0 +1,50 @@
+/*
+ * condvar.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"
+
+#include "ptw32_cond_check_need_init.c"
+#include "pthread_condattr_init.c"
+#include "pthread_condattr_destroy.c"
+#include "pthread_condattr_getpshared.c"
+#include "pthread_condattr_setpshared.c"
+#include "pthread_cond_init.c"
+#include "pthread_cond_destroy.c"
+#include "pthread_cond_wait.c"
+#include "pthread_cond_signal.c"
diff --git a/pthreads/config.h b/pthreads/config.h
new file mode 100644
index 000000000..d6638dfaf
--- /dev/null
+++ b/pthreads/config.h
@@ -0,0 +1,134 @@
+/* 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 <signal.h> 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
+
+/*
+# ----------------------------------------------------------------------
+# 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
+#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
diff --git a/pthreads/create.c b/pthreads/create.c
new file mode 100644
index 000000000..9e9388b20
--- /dev/null
+++ b/pthreads/create.c
@@ -0,0 +1,305 @@
+/*
+ * 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"
+#ifndef _UWIN
+#include <process.h>
+#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 */
diff --git a/pthreads/dll.c b/pthreads/dll.c
new file mode 100644
index 000000000..c1cd4e96e
--- /dev/null
+++ b/pthreads/dll.c
@@ -0,0 +1,92 @@
+/*
+ * dll.c
+ *
+ * Description:
+ * This translation unit implements DLL initialisation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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_STATIC_LIB
+
+#include "pthread.h"
+#include "implement.h"
+
+#ifdef _MSC_VER
+/*
+ * lpvReserved yields an unreferenced formal parameter;
+ * ignore it
+ */
+#pragma warning( disable : 4100 )
+#endif
+
+#ifdef __cplusplus
+/*
+ * Dear c++: Please don't mangle this name. -thanks
+ */
+extern "C"
+#endif /* __cplusplus */
+ BOOL WINAPI
+DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
+{
+ BOOL result = PTW32_TRUE;
+
+ switch (fdwReason)
+ {
+
+ case DLL_PROCESS_ATTACH:
+ result = pthread_win32_process_attach_np ();
+ break;
+
+ case DLL_THREAD_ATTACH:
+ /*
+ * A thread is being created
+ */
+ result = pthread_win32_thread_attach_np ();
+ break;
+
+ case DLL_THREAD_DETACH:
+ /*
+ * A thread is exiting cleanly
+ */
+ result = pthread_win32_thread_detach_np ();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ (void) pthread_win32_thread_detach_np ();
+ result = pthread_win32_process_detach_np ();
+ break;
+ }
+
+ return (result);
+
+} /* DllMain */
+
+#endif /* PTW32_STATIC_LIB */
diff --git a/pthreads/errno.c b/pthreads/errno.c
new file mode 100644
index 000000000..9998bb8d5
--- /dev/null
+++ b/pthreads/errno.c
@@ -0,0 +1,94 @@
+/*
+ * errno.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
+ */
+
+#if defined(NEED_ERRNO)
+
+#include "pthread.h"
+#include "implement.h"
+
+static int reallyBad = ENOMEM;
+
+/*
+ * Re-entrant errno.
+ *
+ * Each thread has it's own errno variable in pthread_t.
+ *
+ * The benefit of using the pthread_t structure
+ * instead of another TSD key is TSD keys are limited
+ * on Win32 to 64 per process. Secondly, to implement
+ * it properly without using pthread_t you'd need
+ * to dynamically allocate an int on starting the thread
+ * and store it manually into TLS and then ensure that you free
+ * it on thread termination. We get all that for free
+ * by simply storing the errno on the pthread_t structure.
+ *
+ * MSVC and Mingw32 already have their own thread-safe errno.
+ *
+ * #if defined( _REENTRANT ) || defined( _MT )
+ * #define errno *_errno()
+ *
+ * int *_errno( void );
+ * #else
+ * extern int errno;
+ * #endif
+ *
+ */
+
+int *
+_errno (void)
+{
+ pthread_t self;
+ int *result;
+
+ if ((self = pthread_self ()) == NULL)
+ {
+ /*
+ * Yikes! unable to allocate a thread!
+ * Throw an exception? return an error?
+ */
+ result = &reallyBad;
+ }
+ else
+ {
+ result = &(self->ptErrno);
+ }
+
+ return (result);
+
+} /* _errno */
+
+#endif /* (NEED_ERRNO) */
diff --git a/pthreads/exit.c b/pthreads/exit.c
new file mode 100644
index 000000000..7eb9671bb
--- /dev/null
+++ b/pthreads/exit.c
@@ -0,0 +1,44 @@
+/*
+ * 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 <process.h>
+#endif
+
+#include "pthread_exit.c"
diff --git a/pthreads/fork.c b/pthreads/fork.c
new file mode 100644
index 000000000..8a29550ca
--- /dev/null
+++ b/pthreads/fork.c
@@ -0,0 +1,39 @@
+/*
+ * fork.c
+ *
+ * Description:
+ * Implementation of fork() for POSIX threads.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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"
diff --git a/pthreads/global.c b/pthreads/global.c
new file mode 100644
index 000000000..2b5542298
--- /dev/null
+++ b/pthreads/global.c
@@ -0,0 +1,115 @@
+/*
+ * global.c
+ *
+ * Description:
+ * This translation unit instantiates data associated with the implementation
+ * as a whole.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 ptw32_processInitialized = PTW32_FALSE;
+ptw32_thread_t * ptw32_threadReuseTop = PTW32_THREAD_REUSE_EMPTY;
+ptw32_thread_t * ptw32_threadReuseBottom = PTW32_THREAD_REUSE_EMPTY;
+pthread_key_t ptw32_selfThreadKey = NULL;
+pthread_key_t ptw32_cleanupKey = NULL;
+pthread_cond_t ptw32_cond_list_head = NULL;
+pthread_cond_t ptw32_cond_list_tail = NULL;
+
+int ptw32_concurrency = 0;
+
+/* What features have been auto-detaected */
+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.
+ */
+PTW32_INTERLOCKED_LONG
+ (WINAPI * ptw32_interlocked_compare_exchange) (PTW32_INTERLOCKED_LPLONG,
+ PTW32_INTERLOCKED_LONG,
+ PTW32_INTERLOCKED_LONG) =
+ NULL;
+
+/*
+ * Function pointer to QueueUserAPCEx if it exists, otherwise
+ * it will be set at runtime to a substitute routine which cannot unblock
+ * blocked threads.
+ */
+DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD) = NULL;
+
+/*
+ * Global lock for managing pthread_t struct reuse.
+ */
+CRITICAL_SECTION ptw32_thread_reuse_lock;
+
+/*
+ * Global lock for testing internal state of statically declared mutexes.
+ */
+CRITICAL_SECTION ptw32_mutex_test_init_lock;
+
+/*
+ * Global lock for testing internal state of PTHREAD_COND_INITIALIZER
+ * created condition variables.
+ */
+CRITICAL_SECTION ptw32_cond_test_init_lock;
+
+/*
+ * Global lock for testing internal state of PTHREAD_RWLOCK_INITIALIZER
+ * created read/write locks.
+ */
+CRITICAL_SECTION ptw32_rwlock_test_init_lock;
+
+/*
+ * Global lock for testing internal state of PTHREAD_SPINLOCK_INITIALIZER
+ * created spin locks.
+ */
+CRITICAL_SECTION ptw32_spinlock_test_init_lock;
+
+/*
+ * 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;
+
+#ifdef _UWIN
+/*
+ * Keep a count of the number of threads.
+ */
+int pthread_count = 0;
+#endif
diff --git a/pthreads/implement.h b/pthreads/implement.h
new file mode 100644
index 000000000..3d9648365
--- /dev/null
+++ b/pthreads/implement.h
@@ -0,0 +1,710 @@
+/*
+ * implement.h
+ *
+ * Definitions that don't need to be public.
+ *
+ * Keeps all the internals out of pthread.h
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef _IMPLEMENT_H
+#define _IMPLEMENT_H
+
+#ifdef _WIN32_WINNT
+#undef _WIN32_WINNT
+#endif
+#define _WIN32_WINNT 0x400
+
+#include <windows.h>
+
+/*
+ * In case windows.h doesn't define it (e.g. WinCE perhaps)
+ */
+#ifdef WINCE
+typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam);
+#endif
+
+/*
+ * note: ETIMEDOUT is correctly defined in winsock.h
+ */
+#include <winsock.h>
+
+/*
+ * In case ETIMEDOUT hasn't been defined above somehow.
+ */
+#ifndef ETIMEDOUT
+# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
+#endif
+
+#if !defined(malloc)
+#include <malloc.h>
+#endif
+
+#if !defined(INT_MAX)
+#include <limits.h>
+#endif
+
+/* use local include files during development */
+#include "semaphore.h"
+#include "sched.h"
+
+#if defined(HAVE_C_INLINE) || defined(__cplusplus)
+#define INLINE inline
+#else
+#define INLINE
+#endif
+
+#if defined (__MINGW32__) || (_MSC_VER >= 1300)
+#define PTW32_INTERLOCKED_LONG long
+#define PTW32_INTERLOCKED_LPLONG long*
+#else
+#define PTW32_INTERLOCKED_LONG PVOID
+#define PTW32_INTERLOCKED_LPLONG PVOID*
+#endif
+
+#if defined(__MINGW32__)
+#include <stdint.h>
+#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;
+};
+
+struct pthread_barrier_t_
+{
+ unsigned int nCurrentBarrierHeight;
+ unsigned int nInitialBarrierHeight;
+ int iStep;
+ int pshared;
+ sem_t semBarrierBreeched[2];
+};
+
+struct pthread_barrierattr_t_
+{
+ int pshared;
+};
+
+struct pthread_key_t_
+{
+ DWORD key;
+ void (*destructor) (void *);
+ pthread_mutex_t keyLock;
+ void *threads;
+};
+
+
+typedef struct ThreadParms ThreadParms;
+typedef struct ThreadKeyAssoc ThreadKeyAssoc;
+
+struct ThreadParms
+{
+ pthread_t tid;
+ void *(*start) (void *);
+ void *arg;
+};
+
+
+struct pthread_cond_t_
+{
+ long nWaitersBlocked; /* Number of threads blocked */
+ long nWaitersGone; /* Number of threads timed out */
+ long nWaitersToUnblock; /* Number of threads to unblock */
+ sem_t semBlockQueue; /* Queue up threads waiting for the */
+ /* condition to become signalled */
+ sem_t semBlockLock; /* Semaphore that guards access to */
+ /* | waiters blocked count/block queue */
+ /* +-> Mandatory Sync.LEVEL-1 */
+ pthread_mutex_t mtxUnblockLock; /* Mutex that guards access to */
+ /* | waiters (to)unblock(ed) counts */
+ /* +-> Optional* Sync.LEVEL-2 */
+ pthread_cond_t next; /* Doubly linked list */
+ pthread_cond_t prev;
+};
+
+
+struct pthread_condattr_t_
+{
+ int pshared;
+};
+
+#define PTW32_RWLOCK_MAGIC 0xfacade2
+
+struct pthread_rwlock_t_
+{
+ pthread_mutex_t mtxExclusiveAccess;
+ pthread_mutex_t mtxSharedAccessCompleted;
+ pthread_cond_t cndSharedAccessCompleted;
+ int nSharedAccessCount;
+ int nExclusiveAccessCount;
+ int nCompletedSharedAccessCount;
+ int nMagic;
+};
+
+struct pthread_rwlockattr_t_
+{
+ int pshared;
+};
+
+/*
+ * 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 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: before the lock handle can
+ * be released - both the key must be deleted and the thread
+ * must have called the destructor. The two-lock arrangement
+ * allows the resources to be freed as soon as either thread or
+ * key is concluded.
+ *
+ * To avoid deadlock: whenever both locks are required, the key
+ * and thread locks are always acquired in the order: key lock
+ * then thread lock. An exception to this exists when a thread
+ * calls the destructors, however this is done carefully 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 assoctiations that runs through the
+ * nextThreads link. This chain provides the 1 to many
+ * relationship between a pthread_key_t and all the
+ * PThreads that have called pthread_setspecific for
+ * this pthread_key_t.
+ *
+ * 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 layed out as follows:
+ *
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +---+-+-+-----------------------+-------------------------------+
+ * |Sev|C|R| Facility | Code |
+ * +---+-+-+-----------------------+-------------------------------+
+ *
+ * Severity Values:
+ */
+#define SE_SUCCESS 0x00
+#define SE_INFORMATION 0x01
+#define SE_WARNING 0x02
+#define SE_ERROR 0x03
+
+#define MAKE_SOFTWARE_EXCEPTION( _severity, _facility, _exception ) \
+( (DWORD) ( ( (_severity) << 30 ) | /* Severity code */ \
+ ( 1 << 29 ) | /* MS=0, User=1 */ \
+ ( 0 << 28 ) | /* Reserved */ \
+ ( (_facility) << 16 ) | /* Facility Code */ \
+ ( (_exception) << 0 ) /* Exception Code */ \
+ ) )
+
+/*
+ * We choose one specific Facility/Error code combination to
+ * identify our software exceptions vs. WIN32 exceptions.
+ * We store our actual component and error code within
+ * the optional information array.
+ */
+#define EXCEPTION_PTW32_SERVICES \
+ MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \
+ PTW32_SERVICES_FACILITY, \
+ PTW32_SERVICES_ERROR )
+
+#define PTW32_SERVICES_FACILITY 0xBAD
+#define PTW32_SERVICES_ERROR 0xDEED
+
+#endif /* __CLEANUP_SEH */
+
+/*
+ * Services available through EXCEPTION_PTW32_SERVICES
+ * and also used [as parameters to ptw32_throw()] as
+ * generic exception selectors.
+ */
+
+#define PTW32_EPS_EXIT (1)
+#define PTW32_EPS_CANCEL (2)
+
+
+/* Useful macros */
+#define PTW32_MAX(a,b) ((a)<(b)?(b):(a))
+#define PTW32_MIN(a,b) ((a)>(b)?(b):(a))
+
+
+/* Declared in global.c */
+extern PTW32_INTERLOCKED_LONG (WINAPI *
+ ptw32_interlocked_compare_exchange)
+ (PTW32_INTERLOCKED_LPLONG, PTW32_INTERLOCKED_LONG, PTW32_INTERLOCKED_LONG);
+
+/* Declared in pthread_cancel.c */
+extern DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD);
+
+/* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */
+#define PTW32_THREAD_REUSE_EMPTY ((ptw32_thread_t *) 1)
+
+extern int ptw32_processInitialized;
+extern ptw32_thread_t * ptw32_threadReuseTop;
+extern ptw32_thread_t * ptw32_threadReuseBottom;
+extern pthread_key_t ptw32_selfThreadKey;
+extern pthread_key_t ptw32_cleanupKey;
+extern pthread_cond_t ptw32_cond_list_head;
+extern pthread_cond_t ptw32_cond_list_tail;
+
+extern int ptw32_mutex_default_kind;
+
+extern int ptw32_concurrency;
+
+extern int ptw32_features;
+
+extern BOOL ptw32_smp_system; /* True: SMP system, False: Uni-processor system */
+
+extern CRITICAL_SECTION ptw32_thread_reuse_lock;
+extern CRITICAL_SECTION ptw32_mutex_test_init_lock;
+extern CRITICAL_SECTION ptw32_cond_list_lock;
+extern CRITICAL_SECTION ptw32_cond_test_init_lock;
+extern CRITICAL_SECTION ptw32_rwlock_test_init_lock;
+extern CRITICAL_SECTION ptw32_spinlock_test_init_lock;
+
+#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);
+
+ void ptw32_mcs_lock_release (ptw32_mcs_local_node_t * 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 <process.h>
+#endif
+
+
+/*
+ * Defaults. Could be overridden when building the inlined version of the dll.
+ * See ptw32_InterlockedCompareExchange.c
+ */
+#ifndef PTW32_INTERLOCKED_COMPARE_EXCHANGE
+#define PTW32_INTERLOCKED_COMPARE_EXCHANGE ptw32_interlocked_compare_exchange
+#endif
+
+#ifndef PTW32_INTERLOCKED_EXCHANGE
+#define PTW32_INTERLOCKED_EXCHANGE InterlockedExchange
+#endif
+
+
+/*
+ * Check for old and new versions of cygwin. See the FAQ file:
+ *
+ * Question 1 - How do I get pthreads-win32 to link under Cygwin or Mingw32?
+ *
+ * Patch by Anders Norlander <anorland@hem2.passagen.se>
+ */
+#if defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(NEED_CREATETHREAD)
+
+/*
+ * Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE
+ * in order to avoid warnings because of return type
+ */
+
+#define _beginthreadex(security, \
+ stack_size, \
+ start_proc, \
+ arg, \
+ flags, \
+ pid) \
+ CreateThread(security, \
+ stack_size, \
+ (LPTHREAD_START_ROUTINE) start_proc, \
+ arg, \
+ flags, \
+ pid)
+
+#define _endthreadex ExitThread
+
+#endif /* __CYGWIN32__ || __CYGWIN__ || NEED_CREATETHREAD */
+
+
+#endif /* _IMPLEMENT_H */
diff --git a/pthreads/manual/ChangeLog b/pthreads/manual/ChangeLog
new file mode 100644
index 000000000..c07cdd702
--- /dev/null
+++ b/pthreads/manual/ChangeLog
@@ -0,0 +1,62 @@
+2005-05-06 Ross Johnson <ross at callisto.canberra.edu.au>
+
+ * 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 <ross at callisto.canberra.edu.au>
+
+ * 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/PortabilityIssues.html b/pthreads/manual/PortabilityIssues.html
new file mode 100644
index 000000000..376a5f00e
--- /dev/null
+++ b/pthreads/manual/PortabilityIssues.html
@@ -0,0 +1,718 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PORTABILITYISSUES manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;322600">
+ <META NAME="CHANGED" CONTENT="20050506;11580000">
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<H4><A HREF="#toc">Table of Contents</A></H4>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P STYLE="font-weight: medium">Portability issues</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>Thread priority</B></P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<H3>Thread priority</H3>
+<P STYLE="margin-left: 2cm">POSIX defines a single contiguous range
+of numbers that determine a thread's priority. Win32 defines priority
+classes - and priority levels relative to these classes. Classes are
+simply priority base levels that the defined priority levels are
+relative to such that, changing a process's priority class will
+change the priority of all of it's threads, while the threads retain
+the same relativity to each other.</P>
+<P STYLE="margin-left: 2cm">A Win32 system defines a single
+contiguous monotonic range of values that define system priority
+levels, just like POSIX. However, Win32 restricts individual threads
+to a subset of this range on a per-process basis.</P>
+<P STYLE="margin-left: 2cm">The following table shows the base
+priority levels for combinations of priority class and priority value
+in Win32.</P>
+<DL>
+ <DL>
+ <DD>
+ <TABLE WIDTH=742 BORDER=0 CELLPADDING=0 CELLSPACING=0 STYLE="page-break-inside: avoid">
+ <COL WIDTH=50>
+ <COL WIDTH=356>
+ <COL WIDTH=336>
+ <THEAD>
+ <TR VALIGN=TOP>
+ <TD WIDTH=50>
+ <P ALIGN=CENTER><BR>
+ </P>
+ </TD>
+ <TD WIDTH=356>
+ <P ALIGN=LEFT><B>Process Priority Class</B></P>
+ </TD>
+ <TD WIDTH=336>
+ <P ALIGN=LEFT><B>Thread Priority Level</B></P>
+ </TD>
+ </TR>
+ </THEAD>
+ <TBODY>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="1" SDNUM="3081;">
+ <P ALIGN=CENTER>1</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_IDLE</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="1" SDNUM="3081;">
+ <P ALIGN=CENTER>1</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_IDLE</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="1" SDNUM="3081;">
+ <P ALIGN=CENTER>1</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_IDLE</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="1" SDNUM="3081;">
+ <P ALIGN=CENTER>1</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_IDLE</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="1" SDNUM="3081;">
+ <P ALIGN=CENTER>1</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_IDLE</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="2" SDNUM="3081;">
+ <P ALIGN=CENTER>2</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="3" SDNUM="3081;">
+ <P ALIGN=CENTER>3</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="4" SDNUM="3081;">
+ <P ALIGN=CENTER>4</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="4" SDNUM="3081;">
+ <P ALIGN=CENTER>4</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="5" SDNUM="3081;">
+ <P ALIGN=CENTER>5</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="5" SDNUM="3081;">
+ <P ALIGN=CENTER>5</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="5" SDNUM="3081;">
+ <P ALIGN=CENTER>5</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>Background NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="6" SDNUM="3081;">
+ <P ALIGN=CENTER>6</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="6" SDNUM="3081;">
+ <P ALIGN=CENTER>6</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="6" SDNUM="3081;">
+ <P ALIGN=CENTER>6</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>Background NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="7" SDNUM="3081;">
+ <P ALIGN=CENTER>7</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="7" SDNUM="3081;">
+ <P ALIGN=CENTER>7</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>Background NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="7" SDNUM="3081;">
+ <P ALIGN=CENTER>7</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>Foreground NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="8" SDNUM="3081;">
+ <P ALIGN=CENTER>8</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="8" SDNUM="3081;">
+ <P ALIGN=CENTER>8</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="8" SDNUM="3081;">
+ <P ALIGN=CENTER>8</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>Foreground NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="8" SDNUM="3081;">
+ <P ALIGN=CENTER>8</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="9" SDNUM="3081;">
+ <P ALIGN=CENTER>9</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="9" SDNUM="3081;">
+ <P ALIGN=CENTER>9</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>Foreground NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="9" SDNUM="3081;">
+ <P ALIGN=CENTER>9</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="10" SDNUM="3081;">
+ <P ALIGN=CENTER>10</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>Foreground NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="10" SDNUM="3081;">
+ <P ALIGN=CENTER>10</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="11" SDNUM="3081;">
+ <P ALIGN=CENTER>11</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>Foreground NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="11" SDNUM="3081;">
+ <P ALIGN=CENTER>11</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="11" SDNUM="3081;">
+ <P ALIGN=CENTER>11</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="12" SDNUM="3081;">
+ <P ALIGN=CENTER>12</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="12" SDNUM="3081;">
+ <P ALIGN=CENTER>12</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="13" SDNUM="3081;">
+ <P ALIGN=CENTER>13</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="14" SDNUM="3081;">
+ <P ALIGN=CENTER>14</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="15" SDNUM="3081;">
+ <P ALIGN=CENTER>15</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="15" SDNUM="3081;">
+ <P ALIGN=CENTER>15</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>HIGH_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_TIME_CRITICAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="15" SDNUM="3081;">
+ <P ALIGN=CENTER>15</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>IDLE_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_TIME_CRITICAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="15" SDNUM="3081;">
+ <P ALIGN=CENTER>15</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>BELOW_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_TIME_CRITICAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="15" SDNUM="3081;">
+ <P ALIGN=CENTER>15</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_TIME_CRITICAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="15" SDNUM="3081;">
+ <P ALIGN=CENTER>15</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>ABOVE_NORMAL_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_TIME_CRITICAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="16" SDNUM="3081;">
+ <P ALIGN=CENTER>16</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_IDLE</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="17" SDNUM="3081;">
+ <P ALIGN=CENTER>17</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=BOTTOM SDVAL="-7" SDNUM="3081;">
+ <P ALIGN=LEFT>-7</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="18" SDNUM="3081;">
+ <P ALIGN=CENTER>18</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=BOTTOM SDVAL="-6" SDNUM="3081;">
+ <P ALIGN=LEFT>-6</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="19" SDNUM="3081;">
+ <P ALIGN=CENTER>19</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=BOTTOM SDVAL="-5" SDNUM="3081;">
+ <P ALIGN=LEFT>-5</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="20" SDNUM="3081;">
+ <P ALIGN=CENTER>20</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=BOTTOM SDVAL="-4" SDNUM="3081;">
+ <P ALIGN=LEFT>-4</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="21" SDNUM="3081;">
+ <P ALIGN=CENTER>21</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=BOTTOM SDVAL="-3" SDNUM="3081;">
+ <P ALIGN=LEFT>-3</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="22" SDNUM="3081;">
+ <P ALIGN=CENTER>22</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_LOWEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="23" SDNUM="3081;">
+ <P ALIGN=CENTER>23</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_BELOW_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="24" SDNUM="3081;">
+ <P ALIGN=CENTER>24</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="25" SDNUM="3081;">
+ <P ALIGN=CENTER>25</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_ABOVE_NORMAL</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="26" SDNUM="3081;">
+ <P ALIGN=CENTER>26</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_HIGHEST</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="27" SDNUM="3081;">
+ <P ALIGN=CENTER>27</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=BOTTOM SDVAL="3" SDNUM="3081;">
+ <P ALIGN=LEFT>3</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="28" SDNUM="3081;">
+ <P ALIGN=CENTER>28</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=BOTTOM SDVAL="4" SDNUM="3081;">
+ <P ALIGN=LEFT>4</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="29" SDNUM="3081;">
+ <P ALIGN=CENTER>29</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=BOTTOM SDVAL="5" SDNUM="3081;">
+ <P ALIGN=LEFT>5</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="30" SDNUM="3081;">
+ <P ALIGN=CENTER>30</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=BOTTOM SDVAL="6" SDNUM="3081;">
+ <P ALIGN=LEFT>6</P>
+ </TD>
+ </TR>
+ <TR>
+ <TD WIDTH=50 VALIGN=BOTTOM SDVAL="31" SDNUM="3081;">
+ <P ALIGN=CENTER>31</P>
+ </TD>
+ <TD WIDTH=356 VALIGN=TOP>
+ <P ALIGN=LEFT>REALTIME_PRIORITY_CLASS</P>
+ </TD>
+ <TD WIDTH=336 VALIGN=TOP>
+ <P ALIGN=LEFT>THREAD_PRIORITY_TIME_CRITICAL</P>
+ </TD>
+ </TR>
+ </TBODY>
+ </TABLE>
+ </DL>
+</DL>
+<P STYLE="margin-left: 2cm">Windows NT: Values -7, -6, -5, -4, -3, 3,
+4, 5, and 6 are not supported.</P>
+<P STYLE="margin-left: 2cm">As you can see, the real priority levels
+available to any individual Win32 thread are non-contiguous.</P>
+<P STYLE="margin-left: 2cm">An application using Pthreads-w32 should
+not make assumptions about the numbers used to represent thread
+priority levels, except that they are monotonic between the values
+returned by sched_get_priority_min() and sched_get_priority_max().
+E.g. Windows 95, 98, NT, 2000, XP make available a non-contiguous
+range of numbers between -15 and 15, while at least one version of
+WinCE (3.0) defines the minimum priority (THREAD_PRIORITY_LOWEST) as
+5, and the maximum priority (THREAD_PRIORITY_HIGHEST) as 1.</P>
+<P STYLE="margin-left: 2cm">Internally, pthreads-win32 maps any
+priority levels between THREAD_PRIORITY_IDLE and
+THREAD_PRIORITY_LOWEST to THREAD_PRIORITY_LOWEST, or between
+THREAD_PRIORITY_TIME_CRITICAL and THREAD_PRIORITY_HIGHEST to
+THREAD_PRIORITY_HIGHEST. Currently, this also applies to
+REALTIME_PRIORITY_CLASS even if levels -7, -6, -5, -4, -3, 3, 4, 5,
+and 6 are supported.</P>
+<P STYLE="margin-left: 2cm">If it wishes, a Win32 application using
+pthreads-w32 can use the Win32 defined priority macros
+THREAD_PRIORITY_IDLE through THREAD_PRIORITY_TIME_CRITICAL.</P>
+<H2><A HREF="#toc3" NAME="sect3">Author</A></H2>
+<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc4" NAME="sect4">See also</A></H2>
+<P><BR><BR>
+</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Author</A>
+ </P>
+ <LI><P><A HREF="#sect4" NAME="toc4">See also</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/index.html b/pthreads/manual/index.html
new file mode 100644
index 000000000..a209dc01a
--- /dev/null
+++ b/pthreads/manual/index.html
@@ -0,0 +1,146 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE></TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;17350500">
+ <META NAME="CHANGED" CONTENT="20050506;12240700">
+</HEAD>
+<BODY LANG="en-GB" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<H3>Table of Contents</H3>
+<P STYLE="margin-left: 2cm"><A HREF="#sect1" NAME="toc1">POSIX
+threads API reference</A><BR><A HREF="#sect2" NAME="toc2">Miscellaneous
+POSIX thread safe routines provided by Pthreads-w32</A><BR><A HREF="#sect3" NAME="toc3">Non-portable
+Pthreads-w32 routines</A><BR><A HREF="#sect4" NAME="toc4">Other</A></P>
+<H2><A HREF="#toc1" NAME="sect1">POSIX threads API reference</A></H2>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_init.html"><B>pthread_attr_destroy</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_init.html"><B>pthread_attr_getdetachstate</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_init.html"><B>pthread_attr_getinheritsched</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_init.html"><B>pthread_attr_getschedparam</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_init.html"><B>pthread_attr_getschedpolicy</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_init.html"><B>pthread_attr_getscope</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_setstackaddr.html"><B>pthread_attr_getstackaddr</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_setstacksize.html"><B>pthread_attr_getstacksize</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_init.html"><B>pthread_attr_init</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_init.html"><B>pthread_attr_setdetachstate</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_init.html"><B>pthread_attr_setinheritsched</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_init.html"><B>pthread_attr_setschedparam</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_init.html"><B>pthread_attr_setschedpolicy</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_init.html"><B>pthread_attr_setscope</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_setstackaddr.html"><B>pthread_attr_setstackaddr</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_attr_setstacksize.html"><B>pthread_attr_setstacksize</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_barrierattr_init.html"><B>pthread_barrierattr_destroy</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_barrierattr_setpshared.html"><B>pthread_barrierattr_getpshared</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_barrierattr_init.html"><B>pthread_barrierattr_init</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_barrierattr_setpshared.html"><B>pthread_barrierattr_setpshared</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_barrier_init.html"><B>pthread_barrier_destroy</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_barrier_init.html"><B>pthread_barrier_init</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_cancel.html"><B>pthread_cancel</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_cleanup_push.html"><B>pthread_cleanup_pop</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_cleanup_push.html"><B>pthread_cleanup_push</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_condattr_init.html"><B>pthread_condattr_destroy</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_condattr_setpshared.html"><B>pthread_condattr_getpshared</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_condattr_init.html"><B>pthread_condattr_init</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_condattr_setpshared.html"><B>pthread_condattr_setpshared</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_cond_init.html"><B>pthread_cond_broadcast</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_cond_init.html"><B>pthread_cond_destroy</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_cond_init.html"><B>pthread_cond_init</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_cond_init.html"><B>pthread_cond_signal</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_cond_init.html"><B>pthread_cond_timedwait</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_cond_init.html"><B>pthread_cond_wait</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_create.html"><B>pthread_create</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_detach.html"><B>pthread_detach</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_equal.html"><B>pthread_equal</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_exit.html"><B>pthread_exit</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_setconcurrency.html"><B>pthread_getconcurrency</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_setschedparam.html"><B>pthread_getschedparam</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_key_create.html"><B>pthread_getspecific</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_join.html"><B>pthread_join</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_key_create.html"><B>pthread_key_create</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_key_create.html"><B>pthread_key_delete</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_kill.html"><B>pthread_kill</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_destroy</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_getkind_np</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutexattr_setpshared.html"><B>pthread_mutexattr_getpshared</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_gettype</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_init</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_setkind_np</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutexattr_setpshared.html"><B>pthread_mutexattr_setpshared</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_settype</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutex_init.html"><B>pthread_mutex_destroy</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutex_init.html"><B>pthread_mutex_init</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutex_init.html"><B>pthread_mutex_lock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutex_init.html"><B>pthread_mutex_timedlock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutex_init.html"><B>pthread_mutex_trylock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_mutex_init.html"><B>pthread_mutex_unlock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_once.html"><B>pthread_once</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_rwlockattr_init.html"><B>pthread_rwlockattr_destroy</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_rwlockattr_setpshared.html"><B>pthread_rwlockattr_getpshared</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_rwlockattr_init.html"><B>pthread_rwlockattr_init</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_rwlockattr_setpshared.html"><B>pthread_rwlockattr_setpshared</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_init</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_rwlock_timedrdlock.html"><B>pthread_rwlock_timedrdlock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_rwlock_timedwrlock.html"><B>pthread_rwlock_timedwrlock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_tryrdlock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_trywrlock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_self.html"><B>pthread_self</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_cancel.html"><B>pthread_setcancelstate</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_cancel.html"><B>pthread_setcanceltype</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_setconcurrency.html"><B>pthread_setconcurrency</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_setschedparam.html"><B>pthread_setschedparam</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_key_create.html"><B>pthread_setspecific</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_kill.html"><B>pthread_sigmask</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_spin_init.html"><B>pthread_spin_destroy</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_spin_init.html"><B>pthread_spin_init</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_spin_lock.html"><B>pthread_spin_lock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_spin_lock.html"><B>pthread_spin_trylock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_spin_unlock.html"><B>pthread_spin_unlock</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_cancel.html"><B>pthread_testcancel</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="sched_get_priority_max.html"><B>sched_get_priority_max</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="sched_get_priority_max.html"><B>sched_get_priority_min</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="sched_getscheduler.html"><B>sched_getscheduler</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="sched_setscheduler.html"><B>sched_setscheduler</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="sched_yield.html"><B>sched_yield</B></A></P>
+<P STYLE="margin-left: 2cm"><B>sem_close</B></P>
+<P STYLE="margin-left: 2cm"><A HREF="sem_init.html"><B>sem_destroy</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="sem_init.html"><B>sem_getvalue</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="sem_init.html"><B>sem_init</B></A></P>
+<P STYLE="margin-left: 2cm"><B>sem_open</B></P>
+<P STYLE="margin-left: 2cm"><A HREF="sem_init.html"><B>sem_post</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="sem_init.html"><B>sem_post_multiple</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="sem_init.html"><B>sem_timedwait</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="sem_init.html"><B>sem_trywait</B></A></P>
+<P STYLE="margin-left: 2cm"><B>sem_unlink</B></P>
+<P STYLE="margin-left: 2cm"><A HREF="sem_init.html"><B>sem_wait</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_kill.html"><B>sigwait</B></A></P>
+<H2><A HREF="#toc2" NAME="sect2">Miscellaneous POSIX thread safe
+routines provided by Pthreads-w32</A></H2>
+<P STYLE="margin-left: 2cm"><B>asctime_r</B></P>
+<P STYLE="margin-left: 2cm"><B>ctime_r</B></P>
+<P STYLE="margin-left: 2cm"><B>gmtime_r</B></P>
+<P STYLE="margin-left: 2cm"><B>localtime_r</B></P>
+<P STYLE="margin-left: 2cm"><B>rand_r</B></P>
+<H2><A HREF="#toc3" NAME="sect3">Non-portable Pthreads-w32 routines</A></H2>
+<P STYLE="margin-left: 2cm"><A HREF="pthreadCancelableWait.html"><B>pthreadCancelableTimedWait</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthreadCancelableWait.html"><B>pthreadCancelableWait</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_delay_np.html"><B>pthread_delay_np</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_getw32threadhandle_np.html"><B>pthread_getw32threadhandle_np</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_num_processors_np.html"><B>pthread_num_processors_np</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_win32_test_features_np.html"><B>pthread_win32_test_features_np</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_timechange_handler_np.html"><B>pthread_timechange_handler_np</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_win32_attach_detach_np.html"><B>pthread_win32_process_attach_np</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_win32_attach_detach_np.html"><B>pthread_win32_process_detach_np</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_win32_attach_detach_np.html"><B>pthread_win32_thread_attach_np</B></A></P>
+<P STYLE="margin-left: 2cm"><A HREF="pthread_win32_attach_detach_np.html"><B>pthread_win32_thread_detach_np</B></A></P>
+<H2><A HREF="#toc4" NAME="sect4">Other</A></H2>
+<P STYLE="margin-left: 2cm"><A HREF="PortabilityIssues.html"><B>Portability
+issues</B></A></P>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthreadCancelableWait.html b/pthreads/manual/pthreadCancelableWait.html
new file mode 100644
index 000000000..9d7c1a458
--- /dev/null
+++ b/pthreads/manual/pthreadCancelableWait.html
@@ -0,0 +1,86 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREADCANCELLABLEWAIT manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;322600">
+ <META NAME="CHANGED" CONTENT="20050505;23242300">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P STYLE="font-weight: medium">pthreadCancelableTimedWait,
+pthreadCancelableWait ā€“ provide cancellation hooks for user Win32
+routines</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthreadCancelableTimedWait (HANDLE </B><I>waitHandle</I><B>,
+DWORD </B><I>timeout</I><B>);</B></P>
+<P><B>int pthreadCancelableWait (HANDLE </B><I>waitHandle</I><B>);</B></P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>These two functions provide hooks into the <A HREF="pthread_cancel.html"><B>pthread_cancel</B></A>()
+mechanism that will allow you to wait on a Windows handle and make it
+a cancellation point. Both functions block until either the given
+Win32 <B>HANDLE</B> is signalled, or <A HREF="pthread_cancel.html"><B>pthread_cancel</B></A>()
+has been called. They are implemented using <B>WaitForMultipleObjects</B>
+on <I>waitHandle</I> and the manually reset Win32 event handle that
+is the target of <A HREF="pthread_cancel.html"><B>pthread_cancel</B></A>().
+These routines may be called from Win32 native threads but
+<A HREF="pthread_cancel.html"><B>pthread_cancel</B></A>() will
+require that thread's POSIX thread ID that the thread must retrieve
+using <A HREF="pthread_self.html"><B>pthread_self</B></A>().</P>
+<P><B>pthreadCancelableTimedWait</B> is the timed version that will
+return with the code <B>ETIMEDOUT</B> if the interval <I>timeout</I>
+milliseconds elapses before <I>waitHandle</I> is signalled.</P>
+<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
+<P>These routines allow routines that block on Win32 HANDLEs to be
+cancellable via <A HREF="pthread_cancel.html"><B>pthread_cancel</B></A>().</P>
+<H2><A HREF="#toc4" NAME="sect4">Return Value</A></H2>
+<P><BR><BR>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
+<P>The <B>pthreadCancelableTimedWait</B> function returns the
+following error code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ETIMEDOUT</B>
+ </DT></DL>
+</DL>
+<P STYLE="margin-left: 2cm">
+The interval <I>timeout</I> milliseconds elapsed before <I>waitHandle</I>
+was signalled.</P>
+<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
+<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc7" NAME="sect7">See also</A></H2>
+<P><A HREF="pthread_cancel.html"><B>pthread_cancel()</B></A>,
+<A HREF="pthread_self.html"><B>pthread_self()</B></A></P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4"></A><A HREF="#sect4" NAME="toc4">Return
+ Value</A><A HREF="#sect4" NAME="toc4"></A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Author</A>
+ </P>
+ <LI><P><A HREF="#sect7" NAME="toc7">See also</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_attr_init.html b/pthreads/manual/pthread_attr_init.html
new file mode 100644
index 000000000..fa5ab5811
--- /dev/null
+++ b/pthreads/manual/pthread_attr_init.html
@@ -0,0 +1,280 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_ATTR_INIT(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;10092900">
+ <META NAME="CHANGED" CONTENT="20050505;16540200">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_attr_init, pthread_attr_destroy,
+pthread_attr_setdetachstate, pthread_attr_getdetachstate,
+pthread_attr_setschedparam, pthread_attr_getschedparam,
+pthread_attr_setschedpolicy, pthread_attr_getschedpolicy,
+pthread_attr_setinheritsched, pthread_attr_getinheritsched,
+pthread_attr_setscope, pthread_attr_getscope - thread creation
+attributes
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthread_attr_init(pthread_attr_t *</B><I>attr</I><B>);</B>
+</P>
+<P><B>int pthread_attr_destroy(pthread_attr_t *</B><I>attr</I><B>);</B>
+</P>
+<P><B>int pthread_attr_setdetachstate(pthread_attr_t *</B><I>attr</I><B>,
+int </B><I>detachstate</I><B>);</B>
+</P>
+<P><B>int pthread_attr_getdetachstate(const pthread_attr_t *</B><I>attr</I><B>,
+int *</B><I>detachstate</I><B>);</B>
+</P>
+<P><B>int pthread_attr_setschedpolicy(pthread_attr_t *</B><I>attr</I><B>,
+int </B><I>policy</I><B>);</B>
+</P>
+<P><B>int pthread_attr_getschedpolicy(const pthread_attr_t *</B><I>attr</I><B>,
+int *</B><I>policy</I><B>);</B>
+</P>
+<P><B>int pthread_attr_setschedparam(pthread_attr_t *</B><I>attr</I><B>,
+const struct sched_param *</B><I>param</I><B>);</B>
+</P>
+<P><B>int pthread_attr_getschedparam(const pthread_attr_t *</B><I>attr</I><B>,
+struct sched_param *</B><I>param</I><B>);</B>
+</P>
+<P><B>int pthread_attr_setinheritsched(pthread_attr_t *</B><I>attr</I><B>,
+int </B><I>inherit</I><B>);</B>
+</P>
+<P><B>int pthread_attr_getinheritsched(const pthread_attr_t *</B><I>attr</I><B>,
+int *</B><I>inherit</I><B>);</B>
+</P>
+<P><B>int pthread_attr_setscope(pthread_attr_t *</B><I>attr</I><B>,
+int </B><I>scope</I><B>);</B>
+</P>
+<P><B>int pthread_attr_getscope(const pthread_attr_t *</B><I>attr</I><B>,
+int *</B><I>scope</I><B>);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>Setting attributes for threads is achieved by filling a thread
+attribute object <I>attr</I> of type <B>pthread_attr_t</B>, then
+passing it as second argument to <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A>
+. Passing <B>NULL</B> is equivalent to passing a thread attribute
+object with all attributes set to their default values.
+</P>
+<P><B>pthread_attr_init</B> initializes the thread attribute object
+<I>attr</I> and fills it with default values for the attributes. (The
+default values are listed below for each attribute.)
+</P>
+<P>Each attribute <I>attrname</I> (see below for a list of all
+attributes) can be individually set using the function
+<B>pthread_attr_set</B><I>attrname</I> and retrieved using the
+function <B>pthread_attr_get</B><I>attrname.</I>
+</P>
+<P><B>pthread_attr_destroy</B> destroys a thread attribute object,
+which must not then be reused until it is reinitialized.
+</P>
+<P>Attribute objects are consulted only when creating a new thread.
+The same attribute object can be used for creating several threads.
+Modifying an attribute object after a call to <B>pthread_create</B>
+does not change the attributes of the thread previously created.
+</P>
+<P>The following thread attributes are supported:
+</P>
+<H3><A HREF="#toc3" NAME="sect3">detachstate</A></H3>
+<P>Control whether the thread is created in the joinable state (value
+<B>PTHREAD_CREATE_JOINABLE</B>) or in the detached state (
+<B>PTHREAD_CREATE_DETACHED</B>).
+</P>
+<P>Default value: <B>PTHREAD_CREATE_JOINABLE</B>.
+</P>
+<P>In the joinable state, another thread can synchronize on the
+thread termination and recover its termination code using
+<A HREF="pthread_join.html"><B>pthread_join</B>(3)</A> . When a
+joinable thread terminates, some of the thread resources are kept
+allocated, and released only when another thread performs
+<A HREF="pthread_join.html"><B>pthread_join</B>(3)</A> on that
+thread.
+</P>
+<P>In the detached state, the thread's resources are released
+immediately when it terminates. <A HREF="pthread_join.html"><B>pthread_join</B>(3)</A>
+cannot be used to synchronize on the thread termination.
+</P>
+<P>A thread created in the joinable state can later be put in the
+detached thread using <A HREF="pthread_detach.html"><B>pthread_detach</B>(3)</A>
+.
+</P>
+<H3><A HREF="#toc4" NAME="sect4">schedpolicy</A></H3>
+<P>Select the scheduling policy for the thread: one of <B>SCHED_OTHER</B>
+(regular, non-real-time scheduling), <B>SCHED_RR</B> (real-time,
+round-robin) or <B>SCHED_FIFO</B> (real-time, first-in first-out).
+</P>
+<P><B>Pthreads-w32</B> only supports <B>SCHED_OTHER</B> - attempting
+to set one of the other policies will return an error ENOTSUP.</P>
+<P>Default value: <B>SCHED_OTHER</B>.
+</P>
+<P><B>Pthreads-w32</B> only supports <B>SCHED_OTHER</B> - attempting
+to set one of the other policies will return an error ENOTSUP.</P>
+<P>The scheduling policy of a thread can be changed after creation
+with <A HREF="pthread_setschedparam.html"><B>pthread_setschedparam</B>(3)</A>
+.
+</P>
+<H3><A HREF="#toc5" NAME="sect5">schedparam</A></H3>
+<P>Contain the scheduling parameters (essentially, the scheduling
+priority) for the thread.</P>
+<P><B>Pthreads-w32</B> supports the priority levels defined by the
+Windows system it is running on. Under Windows, thread priorities are
+relative to the process priority class, which must be set via the
+Windows W32 API.</P>
+<P>Default value: priority is 0 (Win32 level <B>THREAD_PRIORITY_NORMAL</B>).
+</P>
+<P>The scheduling priority of a thread can be changed after creation
+with <A HREF="pthread_setschedparam.html"><B>pthread_setschedparam</B>(3)</A>
+.
+</P>
+<H3><A HREF="#toc6" NAME="sect6">inheritsched</A></H3>
+<P>Indicate whether the scheduling policy and scheduling parameters
+for the newly created thread are determined by the values of the
+<I>schedpolicy</I> and <I>schedparam</I> attributes (value
+<B>PTHREAD_EXPLICIT_SCHED</B>) or are inherited from the parent
+thread (value <B>PTHREAD_INHERIT_SCHED</B>).
+</P>
+<P>Default value: <B>PTHREAD_EXPLICIT_SCHED</B>.
+</P>
+<H3><A HREF="#toc7" NAME="sect7">scope</A></H3>
+<P>Define the scheduling contention scope for the created thread. The
+only value supported in the <B>Pthreads-w32</B> implementation is
+<B>PTHREAD_SCOPE_SYSTEM</B>, meaning that the threads contend for CPU
+time with all processes running on the machine. The other value
+specified by the standard, <B>PTHREAD_SCOPE_PROCESS</B>, means that
+scheduling contention occurs only between the threads of the running
+process.</P>
+<P><B>Pthreads-w32</B> only supports <B>PTHREAD_SCOPE_SYSTEM</B>.</P>
+<P>Default value: <B>PTHREAD_SCOPE_SYSTEM</B>.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Return Value</A></H2>
+<P>All functions return 0 on success and a non-zero error code on
+error. On success, the <B>pthread_attr_get</B><I>attrname</I>
+functions also store the current value of the attribute <I>attrname</I>
+in the location pointed to by their second argument.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">Errors</A></H2>
+<P>The <B>pthread_attr_setdetachstate</B> function returns the
+following error codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the specified <I>detachstate</I> is not one of
+ <B>PTHREAD_CREATE_JOINABLE</B> or <B>PTHREAD_CREATE_DETACHED</B>.
+ </DD></DL>
+</DL>
+<P>
+The <B>pthread_attr_setschedparam</B> function returns the following
+error codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the priority specified in <I>param</I> is outside the range of
+ allowed priorities for the scheduling policy currently in <I>attr</I>
+ (1 to 99 for <B>SCHED_FIFO</B> and <B>SCHED_RR</B>; 0 for
+ <B>SCHED_OTHER</B>).
+ </DD></DL>
+</DL>
+<P>
+The <B>pthread_attr_setschedpolicy</B> function returns the following
+error codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the specified <I>policy</I> is not one of <B>SCHED_OTHER</B>,
+ <B>SCHED_FIFO</B>, or <B>SCHED_RR</B>.
+ </DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <B>ENOTSUP</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <I>policy</I> is not <B>SCHED_OTHER</B>, the only value supported
+ by <B>Pthreads-w32</B>.</DD></DL>
+</DL>
+<P>
+The <B>pthread_attr_setinheritsched</B> function returns the
+following error codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the specified <I>inherit</I> is not one of <B>PTHREAD_INHERIT_SCHED</B>
+ or <B>PTHREAD_EXPLICIT_SCHED</B>.
+ </DD></DL>
+</DL>
+<P>
+The <B>pthread_attr_setscope</B> function returns the following error
+codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the specified <I>scope</I> is not one of <B>PTHREAD_SCOPE_SYSTEM</B>
+ or <B>PTHREAD_SCOPE_PROCESS</B>.
+ </DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <B>ENOTSUP</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the specified <I>scope</I> is <B>PTHREAD_SCOPE_PROCESS</B> (not
+ supported by <B>Pthreads-w32</B>).
+ </DD></DL>
+</DL>
+<H2>
+<A HREF="#toc10" NAME="sect10">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc11" NAME="sect11">See Also</A></H2>
+<P><A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> ,
+<A HREF="pthread_join.html"><B>pthread_join</B>(3)</A> ,
+<A HREF="pthread_detach.html"><B>pthread_detach</B>(3)</A> ,
+<A HREF="pthread_setschedparam.html"><B>pthread_setschedparam</B>(3)</A>
+.
+</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">detachstate</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">schedpolicy</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">schedparam</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">inheritsched</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">scope</A>
+ </P>
+ </UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect10" NAME="toc10">Author</A>
+ </P>
+ <LI><P><A HREF="#sect11" NAME="toc11">See Also</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_attr_setstackaddr.html b/pthreads/manual/pthread_attr_setstackaddr.html
new file mode 100644
index 000000000..868832c0a
--- /dev/null
+++ b/pthreads/manual/pthread_attr_setstackaddr.html
@@ -0,0 +1,158 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_ATTR_GETSTACKADDR&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;11025500">
+ <META NAME="CHANGED" CONTENT="20050505;17571400">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_attr_getstackaddr, pthread_attr_setstackaddr - get and set
+the stackaddr attribute
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_attr_getstackaddr(const pthread_attr_t *restrict</B>
+<I>attr</I><B>, void **restrict</B> <I>stackaddr</I><B>); <BR>int
+pthread_attr_setstackaddr(pthread_attr_t *</B><I>attr</I><B>, void
+*</B><I>stackaddr</I><B>); </B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_attr_getstackaddr</B> and <B>pthread_attr_setstackaddr</B>
+functions, respectively, shall get and set the thread creation
+<I>stackaddr</I> attribute in the <I>attr</I> object.
+</P>
+<P>The <I>stackaddr</I> attribute specifies the location of storage
+to be used for the created threadā€™s stack. The size of the storage
+shall be at least {PTHREAD_STACK_MIN}.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_THREAD_ATTR_STACKADDR</B> in
+pthread.h as -1 to indicate that these routines are implemented but
+cannot used to set or get the stack address. These routines always
+return the error ENOSYS when called.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>Upon successful completion, <B>pthread_attr_getstackaddr</B> and
+<B>pthread_attr_setstackaddr</B> shall return a value of 0;
+otherwise, an error number shall be returned to indicate the error.
+</P>
+<P>The <B>pthread_attr_getstackaddr</B> function stores the <I>stackaddr</I>
+attribute value in <I>stackaddr</I> if successful.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_attr_setstackaddr</B> function always returns the
+following error code:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ENOSYS</B></DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ The function is not supported.
+ </DD></DL>
+</DL>
+<P>
+The <B>pthread_attr_getstackaddr</B> function always returns the
+following error code:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ENOSYS</B></DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ The function is not supported.
+ </DD></DL>
+</DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>The specification of the <I>stackaddr</I> attribute presents
+several ambiguities that make portable use of these interfaces
+impossible. The description of the single address parameter as a
+&quot;stack&quot; does not specify a particular relationship between
+the address and the &quot;stack&quot; implied by that address. For
+example, the address may be taken as the low memory address of a
+buffer intended for use as a stack, or it may be taken as the address
+to be used as the initial stack pointer register value for the new
+thread. These two are not the same except for a machine on which the
+stack grows &quot;up&quot; from low memory to high, and on which a
+&quot;push&quot; operation first stores the value in memory and then
+increments the stack pointer register. Further, on a machine where
+the stack grows &quot;down&quot; from high memory to low,
+interpretation of the address as the &quot;low memory&quot; address
+requires a determination of the intended size of the stack.
+IEEE&nbsp;Std&nbsp;1003.1-2001 has introduced the new interfaces
+<A HREF="pthread_attr_setstack.html"><B>pthread_attr_setstack</B>(3)</A>
+and <A HREF="pthread_attr_getstack.html"><B>pthread_attr_getstack</B>(3)</A>
+to resolve these ambiguities.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_attr_init.html"><B>pthread_attr_destroy</B>(3)</A>
+, <A HREF="pthread_attr_init.html"><B>pthread_attr_getdetachstate</B>(3)</A>
+, <A HREF="pthread_attr_getstack.html"><B>pthread_attr_getstack</B>(3)</A>
+, <A HREF="pthread_attr_getstacksize.html"><B>pthread_attr_getstacksize</B>(3)</A>
+, <A HREF="pthread_attr_setstack.html"><B>pthread_attr_setstack</B>(3)</A>
+, <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> , the
+Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;limits.h&gt;</I>, <I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_attr_setstacksize.html b/pthreads/manual/pthread_attr_setstacksize.html
new file mode 100644
index 000000000..ae9d031f4
--- /dev/null
+++ b/pthreads/manual/pthread_attr_setstacksize.html
@@ -0,0 +1,127 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_ATTR_GETSTACKSIZE&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;11224900">
+ <META NAME="CHANGED" CONTENT="20050505;18003200">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_attr_getstacksize, pthread_attr_setstacksize - get and set
+the stacksize attribute
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_attr_getstacksize(const pthread_attr_t *restrict</B>
+<I>attr</I><B>, size_t *restrict</B> <I>stacksize</I><B>); <BR>int
+pthread_attr_setstacksize(pthread_attr_t *</B><I>attr</I><B>, size_t</B>
+<I>stacksize</I><B>); </B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_attr_getstacksize</B> and <B>pthread_attr_setstacksize</B>
+functions, respectively, shall get and set the thread creation
+<I>stacksize</I> attribute in the <I>attr</I> object.
+</P>
+<P>The <I>stacksize</I> attribute shall define the minimum stack size
+(in bytes) allocated for the created threads stack.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_THREAD_ATTR_STACKSIZE</B> in
+pthread.h to indicate that these routines are implemented and may be
+used to set or get the stack size.</P>
+<P>Default value: 0 (in Pthreads-w32 a value of 0 means the stack
+will grow as required)</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>Upon successful completion, <B>pthread_attr_getstacksize</B> and
+<B>pthread_attr_setstacksize</B> shall return a value of 0;
+otherwise, an error number shall be returned to indicate the error.
+</P>
+<P>The <B>pthread_attr_getstacksize</B> function stores the <I>stacksize</I>
+attribute value in <I>stacksize</I> if successful.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_attr_setstacksize</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value of <I>stacksize</I> is less than {PTHREAD_STACK_MIN} or
+ exceeds a system-imposed limit.
+ </DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_attr_init.html"><B>pthread_attr_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_attr_setstackaddr.html"><B>pthread_attr_getstackaddr</B>(3)</A>
+<B>,</B> <A HREF="pthread_attr_init.html"><B>pthread_attr_getdetachstate</B>(3)</A>
+<B>,</B> <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> <B>,</B>
+the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;limits.h&gt;</I>, <I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_barrier_init.html b/pthreads/manual/pthread_barrier_init.html
new file mode 100644
index 000000000..065c1296f
--- /dev/null
+++ b/pthreads/manual/pthread_barrier_init.html
@@ -0,0 +1,200 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_BARRIER_DESTROY&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.0 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;11372800">
+ <META NAME="CHANGEDBY" CONTENT="Ross Johnson">
+ <META NAME="CHANGED" CONTENT="20060408;9450100">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_barrier_destroy, pthread_barrier_init - destroy and
+initialize a barrier object (<B>ADVANCED REALTIME THREADS</B>)
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_barrier_destroy(pthread_barrier_t *</B><I>barrier</I><B>);
+<BR>int pthread_barrier_init(pthread_barrier_t *restrict</B> <I>barrier</I><B>,
+const pthread_barrierattr_t *restrict</B> <I>attr</I><B>, unsigned</B>
+<I>count</I><B>); </B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_barrier_destroy</B> function shall destroy the
+barrier referenced by <I>barrier</I> and release any resources used
+by the barrier. The effect of subsequent use of the barrier is
+undefined until the barrier is reinitialized by another call to
+<B>pthread_barrier_init</B> . An implementation may use this function
+to set <I>barrier</I> to an invalid value. The results are undefined
+if <B>pthread_barrier_destroy</B> is called when any thread is
+blocked on the barrier, or if this function is called with an
+uninitialized barrier.
+</P>
+<P>The <B>pthread_barrier_init</B> function shall allocate any
+resources required to use the barrier referenced by <I>barrier</I>
+and shall initialize the barrier with attributes referenced by <I>attr</I>.
+If <I>attr</I> is NULL, the default barrier attributes shall be used;
+the effect is the same as passing the address of a default barrier
+attributes object. The results are undefined if <B>pthread_barrier_init</B>
+is called when any thread is blocked on the barrier (that is, has not
+returned from the <A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A>
+call). The results are undefined if a barrier is used without first
+being initialized. The results are undefined if <B>pthread_barrier_init</B>
+is called specifying an already initialized barrier.
+</P>
+<P>The <I>count</I> argument specifies the number of threads that
+must call <A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A>
+before any of them successfully return from the call. The value
+specified by <I>count</I> must be greater than zero.
+</P>
+<P>If the <B>pthread_barrier_init</B> function fails, the barrier
+shall not be initialized and the contents of <I>barrier</I> are
+undefined.
+</P>
+<P>Only the object referenced by <I>barrier</I> may be used for
+performing synchronization. The result of referring to copies of that
+object in calls to <B>pthread_barrier_destroy</B> <B>or</B>
+<A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A>
+is undefined.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>Upon successful completion, these functions shall return zero;
+otherwise, an error number shall be returned to indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_barrier_destroy</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EBUSY</B>
+ </DT><DD>
+ The implementation has detected an attempt to destroy a barrier
+ while it is in use (for example, while being used in a
+ <A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A>
+ call) by another thread.
+ </DD><DT>
+ <B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>barrier</I> is invalid.
+ </DD></DL>
+<P>
+The <B>pthread_barrier_init</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>EAGAIN</B>
+ </DT><DD>
+ The system lacks the necessary resources to initialize another
+ barrier.
+ </DD><DT>
+ <B>EINVAL</B>
+ </DT><DD>
+ The value specified by <I>count</I> is equal to zero.
+ </DD><DT>
+ <B>ENOMEM</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ Insufficient memory exists to initialize the barrier.
+ </DD></DL>
+<P>
+The <B>pthread_barrier_init</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EBUSY</B>
+ </DT><DD>
+ The implementation has detected an attempt to reinitialize a barrier
+ while it is in use (for example, while being used in a
+ <A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A>
+ call) by another thread.
+ </DD><DT>
+ <B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>attr</I> is invalid.
+ </DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>The <B>pthread_barrier_destroy</B> and <B>pthread_barrier_init</B>
+functions are part of the Barriers option and need not be provided on
+all implementations.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_BARRIERS</B> to indicate
+that these routines are implemented and may be used.</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc11" NAME="sect11">Known Bugs</A></H2>
+<DL>
+ <DD STYLE="margin-left: 0cm; margin-bottom: 0.5cm">In
+ <B><SPAN LANG="en-GB"><SPAN LANG="en-GB">pthreads-win32</SPAN></SPAN></B>,
+ <A HREF="pthread_barrier_wait.html"></A><A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A><A HREF="pthread_barrier_wait.html"></A>
+ may deadlock if the number of running threads able to wait on the
+ barrier object exceeds the value given as the <I><SPAN LANG="en-GB"><SPAN LANG="en-GB">count</SPAN></SPAN></I>
+ parameter in <B>pthread_barrier_init</B>.
+ </DD></DL>
+<H2>
+<A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_barrier_wait.html"><B>pthread_barrier_wait</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect11" NAME="toc11">Known
+ Bugs</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/pthreads/manual/pthread_barrier_wait.html b/pthreads/manual/pthread_barrier_wait.html
new file mode 100644
index 000000000..693d8bd15
--- /dev/null
+++ b/pthreads/manual/pthread_barrier_wait.html
@@ -0,0 +1,167 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_BARRIER_WAIT&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.0 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;11484200">
+ <META NAME="CHANGEDBY" CONTENT="Ross Johnson">
+ <META NAME="CHANGED" CONTENT="20060408;9504600">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_barrier_wait - synchronize at a barrier (<B>ADVANCED
+REALTIME THREADS</B>)
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_barrier_wait(pthread_barrier_t *</B><I>barrier</I><B>);
+</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_barrier_wait</B> function shall synchronize
+participating threads at the barrier referenced by <I>barrier</I>.
+The calling thread shall block until the required number of threads
+have called <B>pthread_barrier_wait</B> specifying the barrier.
+</P>
+<P>When the required number of threads have called
+<B>pthread_barrier_wait</B> specifying the barrier, the constant
+<B>PTHREAD_BARRIER_SERIAL_THREAD</B> shall be returned to one
+unspecified thread and zero shall be returned to each of the
+remaining threads. At this point, the barrier shall be reset to the
+state it had as a result of the most recent <A HREF="pthread_barrier_init.html"><B>pthread_barrier_init</B>(3)</A>
+function that referenced it.
+</P>
+<P>The constant <B>PTHREAD_BARRIER_SERIAL_THREAD</B> is defined in
+<I>&lt;pthread.h&gt;</I> and its value shall be distinct from any
+other value returned by <B>pthread_barrier_wait</B> .
+</P>
+<P>The results are undefined if this function is called with an
+uninitialized barrier.
+</P>
+<P>If a signal is delivered to a thread blocked on a barrier, upon
+return from the signal handler the thread shall resume waiting at the
+barrier if the barrier wait has not completed (that is, if the
+required number of threads have not arrived at the barrier during the
+execution of the signal handler); otherwise, the thread shall
+continue as normal from the completed barrier wait. Until the thread
+in the signal handler returns from it, it is unspecified whether
+other threads may proceed past the barrier once they have all reached
+it.
+</P>
+<P>A thread that has blocked on a barrier shall not prevent any
+unblocked thread that is eligible to use the same processing
+resources from eventually making forward progress in its execution.
+Eligibility for processing resources shall be determined by the
+scheduling policy.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>Upon successful completion, the <B>pthread_barrier_wait</B>
+function shall return <B>PTHREAD_BARRIER_SERIAL_THREAD</B> for a
+single (arbitrary) thread synchronized at the barrier and zero for
+each of the other threads. Otherwise, an error number shall be
+returned to indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_barrier_wait</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>barrier</I> does not refer to an
+ initialized barrier object.
+ </DD></DL>
+<P>
+This function shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>Applications using this function may be subject to priority
+inversion, as discussed in the Base Definitions volume of
+IEEE&nbsp;Std&nbsp;1003.1-2001, Section 3.285, Priority Inversion.
+</P>
+<P>The <B>pthread_barrier_wait</B> function is part of the Barriers
+option and need not be provided on all implementations.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_BARRIERS</B> to indicate
+that this routine is implemented and may be used.</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc11" NAME="sect11">Known Bugs</A></H2>
+<DL>
+ <DD STYLE="margin-left: 0cm; margin-bottom: 0.5cm">In
+ <B><SPAN LANG="en-GB">pthreads-win32</SPAN></B>,
+ <B>pthread_barrier_wait</B> may deadlock if the number of running
+ threads able to wait on the barrier object exceeds the value given
+ as the <I><SPAN LANG="en-GB">count</SPAN></I> parameter in
+ <A HREF="pthread_barrier_init.html"><B>pthread_barrier_init(3)</B></A>.
+ </DD></DL>
+<H2>
+<A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_barrier_init.html"><B>pthread_barrier_destroy</B>(3)</A>,
+<A HREF="pthread_barrier_init.html"><B>pthread_barrier_init(3)</B></A>,
+the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect11" NAME="toc11">Known
+ Bugs</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/pthreads/manual/pthread_barrierattr_init.html b/pthreads/manual/pthread_barrierattr_init.html
new file mode 100644
index 000000000..a7c802735
--- /dev/null
+++ b/pthreads/manual/pthread_barrierattr_init.html
@@ -0,0 +1,142 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_BARRIERATTR_DESTROY&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;11502600">
+ <META NAME="CHANGED" CONTENT="20050505;18032300">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_barrierattr_destroy, pthread_barrierattr_init - destroy
+and initialize the barrier attributes object (<B>ADVANCED REALTIME
+THREADS</B>)
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P>i<B>nt pthread_barrierattr_destroy(pthread_barrierattr_t *</B><I>attr</I><B>);
+<BR>int pthread_barrierattr_init(pthread_barrierattr_t *</B><I>attr</I><B>);
+</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_barrierattr_destroy</B> function shall destroy a
+barrier attributes object. A destroyed <I>attr</I> attributes object
+can be reinitialized using <B>pthread_barrierattr_init</B> ; the
+results of otherwise referencing the object after it has been
+destroyed are undefined. An implementation may cause
+<B>pthread_barrierattr_destroy</B> to set the object referenced by
+<I>attr</I> to an invalid value.
+</P>
+<P>The <B>pthread_barrierattr_init</B> function shall initialize a
+barrier attributes object <I>attr</I> with the default value for all
+of the attributes defined by the implementation.
+</P>
+<P>Results are undefined if <B>pthread_barrierattr_init</B> is called
+specifying an already initialized <I>attr</I> attributes object.
+</P>
+<P>After a barrier attributes object has been used to initialize one
+or more barriers, any function affecting the attributes object
+(including destruction) shall not affect any previously initialized
+barrier.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>If successful, the <B>pthread_barrierattr_destroy</B> and
+<B>pthread_barrierattr_init</B> functions shall return zero;
+otherwise, an error number shall be returned to indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_barrierattr_destroy</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>attr</I> is invalid.
+ </DD></DL>
+<P>
+The <B>pthread_barrierattr_init</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>ENOMEM</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ Insufficient memory exists to initialize the barrier attributes
+ object.
+ </DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>The <B>pthread_barrierattr_destroy</B> and
+<B>pthread_barrierattr_init</B> functions are part of the Barriers
+option and need not be provided on all implementations.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_BARRIERS</B> to indicate
+that these routines are implemented and may be used.</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_barrierattr_setpshared.html"><B>pthread_barrierattr_getpshared</B>(3)</A>
+<B>,</B> <A HREF="pthread_barrierattr_setpshared.html"><B>pthread_barrierattr_setpshared</B>(3)</A>
+, the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>.
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_barrierattr_setpshared.html b/pthreads/manual/pthread_barrierattr_setpshared.html
new file mode 100644
index 000000000..2c62d3dce
--- /dev/null
+++ b/pthreads/manual/pthread_barrierattr_setpshared.html
@@ -0,0 +1,159 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_BARRIERATTR_GETPSHARED&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;11552100">
+ <META NAME="CHANGED" CONTENT="20050505;18080400">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_barrierattr_getpshared, pthread_barrierattr_setpshared -
+get and set the process-shared attribute of the barrier attributes
+object (<B>ADVANCED REALTIME THREADS</B>)
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_barrierattr_getpshared(const pthread_barrierattr_t
+* restrict</B> <I>attr</I><B>, int *restrict</B> <I>pshared</I><B>);
+<BR>int pthread_barrierattr_setpshared(pthread_barrierattr_t *</B><I>attr</I><B>,
+int</B> <I>pshared</I><B>); </B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_barrierattr_getpshared</B> function shall obtain
+the value of the <I>process-shared</I> attribute from the attributes
+object referenced by <I>attr</I>. The <B>pthread_barrierattr_setpshared</B>
+function shall set the <I>process-shared</I> attribute in an
+initialized attributes object referenced by <I>attr</I>.
+</P>
+<P>The <I>process-shared</I> attribute is set to
+PTHREAD_PROCESS_SHARED to permit a barrier to be operated upon by any
+thread that has access to the memory where the barrier is allocated.
+If the <I>process-shared</I> attribute is PTHREAD_PROCESS_PRIVATE,
+the barrier shall only be operated upon by threads created within the
+same process as the thread that initialized the barrier; if threads
+of different processes attempt to operate on such a barrier, the
+behavior is undefined. The default value of the attribute shall be
+PTHREAD_PROCESS_PRIVATE. Both constants PTHREAD_PROCESS_SHARED and
+PTHREAD_PROCESS_PRIVATE are defined in <I>&lt;pthread.h&gt;</I>.
+</P>
+<P><B>Pthreads-w32</B> defines _<B>POSIX_THREAD_PROCESS_SHARED</B> in
+pthread.h as -1 to indicate that these routines are implemented but
+that the process shared attribute is not supported.</P>
+<P>Additional attributes, their default values, and the names of the
+associated functions to get and set those attribute values are
+implementation-defined.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>If successful, the <B>pthread_barrierattr_getpshared</B> function
+shall return zero and store the value of the <I>process-shared</I>
+attribute of <I>attr</I> into the object referenced by the <I>pshared</I>
+parameter. Otherwise, an error number shall be returned to indicate
+the error.
+</P>
+<P>If successful, the <B>pthread_barrierattr_setpshared</B> function
+shall return zero; otherwise, an error number shall be returned to
+indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>These functions may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>attr</I> is invalid.
+ </DD><DT>
+ The <B>pthread_barrierattr_setpshared</B> function may fail if:
+ </DT><DT>
+ <B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The new value specified for the <I>process-shared</I> attribute is
+ not one of the legal values <B>PTHREAD_PROCESS_SHARED</B> or
+ <B>PTHREAD_PROCESS_PRIVATE</B>.
+ </DD><DT>
+ <B>ENOSYS</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>attr</I> was <B>PTHREAD_PROCESS_SHARED</B>
+ (Pthreads-w32).</DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>The <B>pthread_barrierattr_getpshared</B> and
+<B>pthread_barrierattr_setpshared</B> functions are part of the
+Barriers option and need not be provided on all implementations.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_BARRIERS</B> and
+<B>_POSIX_THREAD_PROCESS_SHARED</B> in pthread.h as -1 to indicate
+that these routines are implemented and may be used, but do not
+support the process shared option.</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_barrier_init.html"><B>pthread_barrier_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_barrierattr_init.html"><B>pthread_barrierattr_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_barrierattr_init.html"><B>pthread_barrierattr_init</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_cancel.html b/pthreads/manual/pthread_cancel.html
new file mode 100644
index 000000000..d9acd7727
--- /dev/null
+++ b/pthreads/manual/pthread_cancel.html
@@ -0,0 +1,205 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_CANCEL(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;12090500">
+ <META NAME="CHANGED" CONTENT="20050505;18220000">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_cancel, pthread_setcancelstate, pthread_setcanceltype,
+pthread_testcancel - thread cancellation
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthread_cancel(pthread_t </B><I>thread</I><B>);</B>
+</P>
+<P><B>int pthread_setcancelstate(int </B><I>state</I><B>, int
+*</B><I>oldstate</I><B>);</B>
+</P>
+<P><B>int pthread_setcanceltype(int </B><I>type</I><B>, int
+*</B><I>oldtype</I><B>);</B>
+</P>
+<P><B>void pthread_testcancel(void);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>Cancellation is the mechanism by which a thread can terminate the
+execution of another thread. More precisely, a thread can send a
+cancellation request to another thread. Depending on its settings,
+the target thread can then either ignore the request, honor it
+immediately, or defer it until it reaches a cancellation point.
+</P>
+<P>When a thread eventually honors a cancellation request, it
+performs as if <B>pthread_exit(PTHREAD_CANCELED)</B> has been called
+at that point: all cleanup handlers are executed in reverse order,
+destructor functions for thread-specific data are called, and finally
+the thread stops executing with the return value <B>PTHREAD_CANCELED</B>.
+See <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> for more
+information.
+</P>
+<P><B>pthread_cancel</B> sends a cancellation request to the thread
+denoted by the <I>thread</I> argument.
+</P>
+<P><B>pthread_setcancelstate</B> changes the cancellation state for
+the calling thread -- that is, whether cancellation requests are
+ignored or not. The <I>state</I> argument is the new cancellation
+state: either <B>PTHREAD_CANCEL_ENABLE</B> to enable cancellation, or
+<B>PTHREAD_CANCEL_DISABLE</B> to disable cancellation (cancellation
+requests are ignored). If <I>oldstate</I> is not <B>NULL</B>, the
+previous cancellation state is stored in the location pointed to by
+<I>oldstate</I>, and can thus be restored later by another call to
+<B>pthread_setcancelstate</B>.
+</P>
+<P><B>pthread_setcanceltype</B> changes the type of responses to
+cancellation requests for the calling thread: asynchronous
+(immediate) or deferred. The <I>type</I> argument is the new
+cancellation type: either <B>PTHREAD_CANCEL_ASYNCHRONOUS</B> to
+cancel the calling thread as soon as the cancellation request is
+received, or <B>PTHREAD_CANCEL_DEFERRED</B> to keep the cancellation
+request pending until the next cancellation point. If <I>oldtype</I>
+is not <B>NULL</B>, the previous cancellation state is stored in the
+location pointed to by <I>oldtype</I>, and can thus be restored later
+by another call to <B>pthread_setcanceltype</B>.
+</P>
+<P><B>Pthreads-w32</B> provides two levels of support for
+<B>PTHREAD_CANCEL_ASYNCHRONOUS</B>: full and partial. Full support
+requires an additional DLL and driver be installed on the Windows
+system (see the See Also section below) that allows blocked threads
+to be cancelled immediately. Partial support means that the target
+thread will not cancel until it resumes execution naturally. Partial
+support is provided if either the DLL or the driver are not
+automatically detected by the pthreads-w32 library at run-time.</P>
+<P>Threads are always created by <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A>
+with cancellation enabled and deferred. That is, the initial
+cancellation state is <B>PTHREAD_CANCEL_ENABLE</B> and the initial
+type is <B>PTHREAD_CANCEL_DEFERRED</B>.
+</P>
+<P>Cancellation points are those points in the program execution
+where a test for pending cancellation requests is performed and
+cancellation is executed if positive. The following POSIX threads
+functions are cancellation points:
+</P>
+<P><A HREF="pthread_join.html"><B>pthread_join</B>(3)</A>
+<BR><A HREF="pthread_cond_init.html"><B>pthread_cond_wait</B>(3)</A>
+<BR><A HREF="pthread_cond_init.html"><B>pthread_cond_timedwait</B>(3)</A>
+<BR><A HREF=""><B>pthread_testcancel</B>(3)</A> <BR><A HREF="sem_init.html"><B>sem_wait</B>(3)</A>
+<BR><A HREF="sem_init.html"><B>sem_timedwait</B>(3)</A> <BR><A HREF="pthread_kill.html"><B>sigwait</B>(3)</A></P>
+<P><B>Pthreads-w32</B> provides two functions to enable additional
+cancellation points to be created in user functions that block on
+Win32 HANDLEs:</P>
+<P><A HREF="pthreadCancelableWait.html">pthreadCancelableWait()</A>
+<BR><A HREF="pthreadCancelableTimedWait.html">pthreadCancelableTimedWait()</A></P>
+<P>All other POSIX threads functions are guaranteed not to be
+cancellation points. That is, they never perform cancellation in
+deferred cancellation mode.
+</P>
+<P><B>pthread_testcancel</B> does nothing except testing for pending
+cancellation and executing it. Its purpose is to introduce explicit
+checks for cancellation in long sequences of code that do not call
+cancellation point functions otherwise.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P><B>pthread_cancel</B>, <B>pthread_setcancelstate</B> and
+<B>pthread_setcanceltype</B> return 0 on success and a non-zero error
+code on error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P><B>pthread_cancel</B> returns the following error code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ESRCH</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ no thread could be found corresponding to that specified by the
+ <I>thread</I> ID.
+ </DD></DL>
+</DL>
+<P>
+<B>pthread_setcancelstate</B> returns the following error code on
+error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the <I>state</I> argument is not
+ </DD></DL>
+</DL>
+<BLOCKQUOTE>
+<B>PTHREAD_CANCEL_ENABLE</B> nor <B>PTHREAD_CANCEL_DISABLE</B>
+</BLOCKQUOTE>
+<P><B>pthread_setcanceltype</B> returns the following error code on
+error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the <I>type</I> argument is not
+ </DD></DL>
+</DL>
+<BLOCKQUOTE>
+<B>PTHREAD_CANCEL_DEFERRED</B> nor <B>PTHREAD_CANCEL_ASYNCHRONOUS</B>
+</BLOCKQUOTE>
+<H2><A HREF="#toc5" NAME="sect5">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
+<P><A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> ,
+<A HREF="pthread_cleanup_push.html"><B>pthread_cleanup_push</B>(3)</A>
+, <A HREF="pthread_cleanup_pop.html"><B>pthread_cleanup_pop</B>(3)</A>
+, Pthreads-w32 package README file 'Prerequisites' section.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Bugs</A></H2>
+<P>POSIX specifies that a number of system calls (basically, all
+system calls that may block, such as <A HREF="read.html"><B>read</B>(2)</A>
+, <A HREF="write.html"><B>write</B>(2)</A> , <A HREF="wait.html"><B>wait</B>(2)</A>
+, etc.) and library functions that may call these system calls (e.g.
+<A HREF="fprintf.html"><B>fprintf</B>(3)</A> ) are cancellation
+points. <B>Pthreads-win32</B> is not integrated enough with the C
+library to implement this, and thus none of the C library functions
+is a cancellation point.
+</P>
+<P>A workaround for these calls is to temporarily switch to
+asynchronous cancellation (assuming full asynchronous cancellation
+support is installed). So, checking for cancellation during a <B>read</B>
+system call, for instance, can be achieved as follows:
+</P>
+<BLOCKQUOTE><BR><BR>
+</BLOCKQUOTE>
+<PRE STYLE="margin-left: 1cm; margin-right: 1cm">pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &amp;oldCancelType);
+read(fd, buffer, length);
+pthread_setcanceltype(oldCancelType, NULL);</PRE>
+<HR>
+<BLOCKQUOTE><A NAME="toc"></A><B>Table of Contents</B></BLOCKQUOTE>
+<UL>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">See
+ Also</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE><A HREF="#sect7" NAME="toc7">Bugs</A>
+ </BLOCKQUOTE>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_cleanup_push.html b/pthreads/manual/pthread_cleanup_push.html
new file mode 100644
index 000000000..0fc071e19
--- /dev/null
+++ b/pthreads/manual/pthread_cleanup_push.html
@@ -0,0 +1,140 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_CLEANUP(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;20152200">
+ <META NAME="CHANGED" CONTENT="20050505;18252600">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_cleanup_push, pthread_cleanup_pop - install and remove
+cleanup handlers
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>void pthread_cleanup_push(void (*</B><I>routine</I><B>) (void
+*), void *</B><I>arg</I><B>);</B>
+</P>
+<P><B>void pthread_cleanup_pop(int </B><I>execute</I><B>);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>Cleanup handlers are functions that get called when a thread
+terminates, either by calling <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A>
+or because of cancellation. Cleanup handlers are installed and
+removed following a stack-like discipline.
+</P>
+<P>The purpose of cleanup handlers is to free the resources that a
+thread may hold at the time it terminates. In particular, if a thread
+exits or is cancelled while it owns a locked mutex, the mutex will
+remain locked forever and prevent other threads from executing
+normally. The best way to avoid this is, just before locking the
+mutex, to install a cleanup handler whose effect is to unlock the
+mutex. Cleanup handlers can be used similarly to free blocks
+allocated with <A HREF="malloc.html"><B>malloc</B>(3)</A> or close
+file descriptors on thread termination.
+</P>
+<P><B>pthread_cleanup_push</B> installs the <I>routine</I> function
+with argument <I>arg</I> as a cleanup handler. From this point on to
+the matching <B>pthread_cleanup_pop</B>, the function <I>routine</I>
+will be called with arguments <I>arg</I> when the thread terminates,
+either through <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A>
+or by cancellation. If several cleanup handlers are active at that
+point, they are called in LIFO order: the most recently installed
+handler is called first.
+</P>
+<P><B>pthread_cleanup_pop</B> removes the most recently installed
+cleanup handler. If the <I>execute</I> argument is not 0, it also
+executes the handler, by calling the <I>routine</I> function with
+arguments <I>arg</I>. If the <I>execute</I> argument is 0, the
+handler is only removed but not executed.
+</P>
+<P>Matching pairs of <B>pthread_cleanup_push</B> and
+<B>pthread_cleanup_pop</B> must occur in the same function, at the
+same level of block nesting. Actually, <B>pthread_cleanup_push</B>
+and <B>pthread_cleanup_pop</B> are macros, and the expansion of
+<B>pthread_cleanup_push</B> introduces an open brace <B>{</B> with
+the matching closing brace <B>}</B> being introduced by the expansion
+of the matching <B>pthread_cleanup_pop</B>.
+</P>
+<H2 STYLE="margin-top: 0cm"><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">None.
+</BLOCKQUOTE>
+<H2 STYLE="margin-top: 0cm"><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">None.
+</BLOCKQUOTE>
+<H2 STYLE="margin-top: 0cm"><A HREF="#toc5" NAME="sect5">Author</A></H2>
+<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">Xavier Leroy
+&lt;Xavier.Leroy@inria.fr&gt;
+</BLOCKQUOTE>
+<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">Modified by
+Ross Johnson for use with Pthreads-w32.</BLOCKQUOTE>
+<H2 STYLE="margin-top: 0cm"><A HREF="#toc6" NAME="sect6">See Also</A></H2>
+<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm"><A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A>
+, <A HREF="pthread_cancel.html"><B>pthread_cancel</B>(3)</A> ,
+<A HREF="pthread_cancel.html"><B>pthread_setcanceltype</B>(3)</A> .
+</BLOCKQUOTE>
+<H2 STYLE="margin-top: 0cm"><A HREF="#toc7" NAME="sect7">Example</A></H2>
+<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">Here is how
+to lock a mutex <I>mut</I> in such a way that it will be unlocked if
+the thread is canceled while <I>mut</I> is locked:
+</BLOCKQUOTE>
+<PRE>pthread_cleanup_push(pthread_mutex_unlock, (void *) &amp;mut);
+pthread_mutex_lock(&amp;mut);
+/* do some work */
+pthread_mutex_unlock(&amp;mut);
+pthread_cleanup_pop(0);</PRE><BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">
+Equivalently, the last two lines can be replaced by
+</BLOCKQUOTE>
+<PRE STYLE="margin-bottom: 0.5cm">pthread_cleanup_pop(1);</PRE><BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">
+Notice that the code above is safe only in deferred cancellation mode
+(see <A HREF="pthread_cancel.html"><B>pthread_setcanceltype</B>(3)</A>
+). In asynchronous cancellation mode, a cancellation can occur
+between <B>pthread_cleanup_push</B> and <B>pthread_mutex_lock</B>, or
+between <B>pthread_mutex_unlock</B> and <B>pthread_cleanup_pop</B>,
+resulting in both cases in the thread trying to unlock a mutex not
+locked by the current thread. This is the main reason why
+asynchronous cancellation is difficult to use.
+</BLOCKQUOTE>
+<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">If the code
+above must also work in asynchronous cancellation mode, then it must
+switch to deferred mode for locking and unlocking the mutex:
+</BLOCKQUOTE>
+<PRE>pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &amp;oldtype);
+pthread_cleanup_push(pthread_mutex_unlock, (void *) &amp;mut);
+pthread_mutex_lock(&amp;mut);
+/* do some work */
+pthread_cleanup_pop(1);
+pthread_setcanceltype(oldtype, NULL);</PRE>
+<HR>
+<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm"><A NAME="toc"></A>
+<B>Table of Contents</B></BLOCKQUOTE>
+<UL>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">See
+ Also</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm"><A HREF="#sect7" NAME="toc7">Example</A>
+ </BLOCKQUOTE>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_cond_init.html b/pthreads/manual/pthread_cond_init.html
new file mode 100644
index 000000000..937e490a0
--- /dev/null
+++ b/pthreads/manual/pthread_cond_init.html
@@ -0,0 +1,313 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_COND(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;16454400">
+ <META NAME="CHANGED" CONTENT="20050505;19004700">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_cond_init, pthread_cond_destroy, pthread_cond_signal,
+pthread_cond_broadcast, pthread_cond_wait, pthread_cond_timedwait -
+operations on conditions
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>pthread_cond_t </B><I>cond</I> <B>= PTHREAD_COND_INITIALIZER;</B>
+</P>
+<P><B>int pthread_cond_init(pthread_cond_t *</B><I>cond</I><B>,
+pthread_condattr_t *</B><I>cond_attr</I><B>);</B>
+</P>
+<P><B>int pthread_cond_signal(pthread_cond_t *</B><I>cond</I><B>);</B>
+</P>
+<P><B>int pthread_cond_broadcast(pthread_cond_t *</B><I>cond</I><B>);</B>
+</P>
+<P><B>int pthread_cond_wait(pthread_cond_t *</B><I>cond</I><B>,
+pthread_mutex_t *</B><I>mutex</I><B>);</B>
+</P>
+<P><B>int pthread_cond_timedwait(pthread_cond_t *</B><I>cond</I><B>,
+pthread_mutex_t *</B><I>mutex</I><B>, const struct timespec
+*</B><I>abstime</I><B>);</B>
+</P>
+<P><B>int pthread_cond_destroy(pthread_cond_t *</B><I>cond</I><B>);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>A condition (short for ā€˜ā€˜condition variableā€™ā€™) is a
+synchronization device that allows threads to suspend execution and
+relinquish the processors until some predicate on shared data is
+satisfied. The basic operations on conditions are: signal the
+condition (when the predicate becomes true), and wait for the
+condition, suspending the thread execution until another thread
+signals the condition.
+</P>
+<P>A condition variable must always be associated with a mutex, to
+avoid the race condition where a thread prepares to wait on a
+condition variable and another thread signals the condition just
+before the first thread actually waits on it.
+</P>
+<P><B>pthread_cond_init</B> initializes the condition variable <I>cond</I>,
+using the condition attributes specified in <I>cond_attr</I>, or
+default attributes if <I>cond_attr</I> is <B>NULL</B>.
+</P>
+<P>Variables of type <B>pthread_cond_t</B> can also be initialized
+statically, using the constant <B>PTHREAD_COND_INITIALIZER</B>. In
+the <B>Pthreads-w32</B> implementation, an application should still
+call <B>pthread_cond_destroy</B> at some point to ensure that any
+resources consumed by the condition variable are released.</P>
+<P><B>pthread_cond_signal</B> restarts one of the threads that are
+waiting on the condition variable <I>cond</I>. If no threads are
+waiting on <I>cond</I>, nothing happens. If several threads are
+waiting on <I>cond</I>, exactly one is restarted, but it is not
+specified which.
+</P>
+<P><B>pthread_cond_broadcast</B> restarts all the threads that are
+waiting on the condition variable <I>cond</I>. Nothing happens if no
+threads are waiting on <I>cond</I>.
+</P>
+<P><B>pthread_cond_wait</B> atomically unlocks the <I>mutex</I> (as
+per <B>pthread_unlock_mutex</B>) and waits for the condition variable
+<I>cond</I> to be signalled. The thread execution is suspended and
+does not consume any CPU time until the condition variable is
+signalled. The <I>mutex</I> must be locked by the calling thread on
+entrance to <B>pthread_cond_wait</B>. Before returning to the calling
+thread, <B>pthread_cond_wait</B> re-acquires <I>mutex</I> (as per
+<B>pthread_lock_mutex</B>).
+</P>
+<P>Unlocking the mutex and suspending on the condition variable is
+done atomically. Thus, if all threads always acquire the mutex before
+signalling the condition, this guarantees that the condition cannot
+be signalled (and thus ignored) between the time a thread locks the
+mutex and the time it waits on the condition variable.
+</P>
+<P><B>pthread_cond_timedwait</B> atomically unlocks <I>mutex</I> and
+waits on <I>cond</I>, as <B>pthread_cond_wait</B> does, but it also
+bounds the duration of the wait. If <I>cond</I> has not been
+signalled within the amount of time specified by <I>abstime</I>, the
+mutex <I>mutex</I> is re-acquired and <B>pthread_cond_timedwait</B>
+returns the error <B>ETIMEDOUT</B>. The <I>abstime</I> parameter
+specifies an absolute time, with the same origin as <A HREF="time.html"><B>time</B>(2)</A>
+and <A HREF="gettimeofday.html"><B>gettimeofday</B>(2)</A>.
+</P>
+<P><B>pthread_cond_destroy</B> destroys a condition variable, freeing
+the resources it might hold. No threads must be waiting on the
+condition variable on entrance to <B>pthread_cond_destroy</B>.</P>
+<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
+<P><B>pthread_cond_wait</B> and <B>pthread_cond_timedwait</B> are
+cancellation points. If a thread is cancelled while suspended in one
+of these functions, the thread immediately resumes execution, then
+locks again the <I>mutex</I> argument to <B>pthread_cond_wait</B> and
+<B>pthread_cond_timedwait</B>, and finally executes the cancellation.
+Consequently, cleanup handlers are assured that <I>mutex</I> is
+locked when they are called.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Async-signal Safety</A></H2>
+<P>The condition functions are not async-signal safe, and should not
+be called from a signal handler. In particular, calling
+<B>pthread_cond_signal</B> or <B>pthread_cond_broadcast</B> from a
+signal handler may deadlock the calling thread.
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Return Value</A></H2>
+<P>All condition variable functions return 0 on success and a
+non-zero error code on error.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Errors</A></H2>
+<P><B>pthread_cond_init</B>, <B>pthread_cond_signal</B>,
+<B>pthread_cond_broadcast</B>, and <B>pthread_cond_wait</B> never
+return an error code.
+</P>
+<P>The <B>pthread_cond_init</B> function returns the following error
+codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ The <I>cond</I> argument is invalid.
+ </DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <B>ENOMEM</B>
+ </DT></DL>
+</DL>
+<BLOCKQUOTE STYLE="margin-left: 4cm">
+There was not enough memory to allocate the condition variable.
+</BLOCKQUOTE>
+<P>The <B>pthread_cond_signal</B> function returns the following
+error codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ The <I>cond</I> argument is invalid.
+ </DD></DL>
+</DL>
+<P>
+The <B>pthread_cond_broadcast</B> function returns the following
+error codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ The <I>cond</I> argument is invalid.
+ </DD></DL>
+</DL>
+<P>
+The <B>pthread_cond_wait</B> function returns the following error
+codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ The <I>cond</I> argument is invalid.
+ </DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <B>ENOMEM</B>
+ </DT></DL>
+</DL>
+<BLOCKQUOTE STYLE="margin-left: 4cm">
+There was not enough memory to allocate the statically initialised
+condition variable. Statically initialised condition variables are
+dynamically allocated by the first thread to wait on them.</BLOCKQUOTE>
+<P>The <B>pthread_cond_timedwait</B> function returns the following
+error codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT></DL>
+</DL>
+<P STYLE="margin-left: 2cm">
+The <I>cond</I> argument is invalid.
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ETIMEDOUT</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ The condition variable was not signalled before the timeout
+ specified by <I>abstime</I>
+ </DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <B>ENOMEM</B>
+ </DT></DL>
+</DL>
+<BLOCKQUOTE STYLE="margin-left: 4cm">
+There was not enough memory to allocate the statically initialised
+condition variable. Statically initialised condition variables are
+dynamically allocated by the first thread to wait on them.
+</BLOCKQUOTE>
+<P>The <B>pthread_cond_destroy</B> function returns the following
+error code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT></DL>
+</DL>
+<P STYLE="margin-left: 2cm; margin-right: 1cm">
+The <I>cond</I> argument is invalid.
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EBUSY</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ Some threads are currently waiting on <I>cond</I>.
+ </DD></DL>
+</DL>
+<H2>
+<A HREF="#toc7" NAME="sect7">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc8" NAME="sect8">See Also</A></H2>
+<P><A HREF="pthread_condattr_init.html"><B>pthread_condattr_init</B>(3)</A>
+, <A HREF="pthread_mutex_lock.html"><B>pthread_mutex_lock</B>(3)</A>
+, <A HREF="pthread_mutex_unlock.html"><B>pthread_mutex_unlock</B>(3)</A>
+, <A HREF="pthread_cancel.html"><B>pthread_cancel(3)</B></A>.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">Example</A></H2>
+<P>Consider two shared variables <I>x</I> and <I>y</I>, protected by
+the mutex <I>mut</I>, and a condition variable <I>cond</I> that is to
+be signaled whenever <I>x</I> becomes greater than <I>y</I>.
+</P>
+<PRE STYLE="margin-left: 1cm; margin-right: 1cm">int x,y;
+pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t cond = PTHREAD_COND_INITIALIZER;</PRE><BLOCKQUOTE>
+Waiting until <I>x</I> is greater than <I>y</I> is performed as
+follows:
+</BLOCKQUOTE>
+<PRE STYLE="margin-left: 1.01cm">pthread_mutex_lock(&amp;mut);
+while (x &lt;= y) {
+ pthread_cond_wait(&amp;cond, &amp;mut);
+}
+/* operate on x and y */
+pthread_mutex_unlock(&amp;mut);</PRE><BLOCKQUOTE STYLE="margin-left: 3.01cm">
+Modifications on <I>x</I> and <I>y</I> that may cause <I>x</I> to
+become greater than <I>y</I> should signal the condition if needed:
+</BLOCKQUOTE>
+<PRE STYLE="margin-left: 1.01cm">pthread_mutex_lock(&amp;mut);
+/* modify x and y */
+if (x &gt; y) pthread_cond_broadcast(&amp;cond);
+pthread_mutex_unlock(&amp;mut);</PRE><BLOCKQUOTE STYLE="margin-left: 3.01cm">
+If it can be proved that at most one waiting thread needs to be waken
+up (for instance, if there are only two threads communicating through
+<I>x</I> and <I>y</I>), <B>pthread_cond_signal</B> can be used as a
+slightly more efficient alternative to <B>pthread_cond_broadcast</B>.
+If in doubt, use <B>pthread_cond_broadcast</B>.
+</BLOCKQUOTE>
+<BLOCKQUOTE STYLE="margin-left: 3.01cm">To wait for <I>x</I> to
+become greater than <I>y</I> with a timeout of 5 seconds, do:
+</BLOCKQUOTE>
+<PRE STYLE="margin-left: 1.01cm">struct timeval now;
+struct timespec timeout;
+int retcode;
+pthread_mutex_lock(&amp;mut);
+gettimeofday(&amp;now);
+timeout.tv_sec = now.tv_sec + 5;
+timeout.tv_nsec = now.tv_usec * 1000;
+retcode = 0;
+while (x &lt;= y &amp;&amp; retcode != ETIMEDOUT) {
+ retcode = pthread_cond_timedwait(&amp;cond, &amp;mut, &amp;timeout);
+}
+if (retcode == ETIMEDOUT) {
+ /* timeout occurred */
+} else {
+ /* operate on x and y */
+}
+pthread_mutex_unlock(&amp;mut);</PRE>
+<HR>
+<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm"><A NAME="toc"></A>
+<B>Table of Contents</B></BLOCKQUOTE>
+<UL>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Async-signal
+ Safety</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Return
+ Value</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Errors</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Author</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm; margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">See
+ Also</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 0cm"><A HREF="#sect9" NAME="toc9">Example</A>
+ </BLOCKQUOTE>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_condattr_init.html b/pthreads/manual/pthread_condattr_init.html
new file mode 100644
index 000000000..8b8b2f2aa
--- /dev/null
+++ b/pthreads/manual/pthread_condattr_init.html
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_CONDATTR(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;16375600">
+ <META NAME="CHANGED" CONTENT="20050504;16570300">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_condattr_init, pthread_condattr_destroy - condition
+creation
+</P>
+<P>attributes
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthread_condattr_init(pthread_condattr_t *</B><I>attr</I><B>);</B>
+</P>
+<P><B>int pthread_condattr_destroy(pthread_condattr_t *</B><I>attr</I><B>);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>Condition attributes can be specified at condition creation time,
+by passing a condition attribute object as second argument to
+<A HREF="pthread_cond_init.html"><B>pthread_cond_init</B>(3)</A> .
+Passing <B>NULL</B> is equivalent to passing a condition attribute
+object with all attributes set to their default values.
+</P>
+<P><B>pthread_condattr_init</B> initializes the condition attribute
+object <I>attr</I> and fills it with default values for the
+attributes. <B>pthread_condattr_destroy</B> destroys a condition
+attribute object, which must not be reused until it is reinitialized.</P>
+<P><B>Pthreads-w32</B> defines _<B>POSIX_THREAD_PROCESS_SHARED</B> in
+pthread.h as -1 to indicate that the attribute routines are
+implemented but that the process shared attribute is not supported.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>All condition variable functions return 0 on success and a
+non-zero error code on error.</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_condattr_init</B> function returns the following
+error code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ENOMEM</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ The was insufficient memory to create the attribute.<SPAN STYLE="font-weight: medium">
+ </SPAN>
+ </DD></DL>
+</DL>
+<P>
+The <B>pthread_condattr_destroy</B> function returns the following
+error code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ The <I>attr</I> argument is not valid.<SPAN STYLE="font-weight: medium">
+ </SPAN>
+ </DD></DL>
+</DL>
+<H2>
+<A HREF="#toc5" NAME="sect5">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
+<P><A HREF="pthread_cond_init.html"><B>pthread_cond_init</B>(3)</A> .
+</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
+ </P>
+ <LI><P><A HREF="#sect6" NAME="toc6">See Also</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_condattr_setpshared.html b/pthreads/manual/pthread_condattr_setpshared.html
new file mode 100644
index 000000000..eda357e07
--- /dev/null
+++ b/pthreads/manual/pthread_condattr_setpshared.html
@@ -0,0 +1,153 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_CONDATTR_GETPSHARED&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;17542300">
+ <META NAME="CHANGED" CONTENT="20050505;18293100">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_condattr_getpshared, pthread_condattr_setpshared - get and
+set the process-shared condition variable attributes
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_condattr_getpshared(const pthread_condattr_t
+*restrict</B> <I>attr</I><B>, int *restrict</B> <I>pshared</I><B>);
+<BR>int pthread_condattr_setpshared(pthread_condattr_t *</B><I>attr</I><B>,
+int</B> <I>pshared</I><B>); </B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_condattr_getpshared</B> function shall obtain the
+value of the <I>process-shared</I> attribute from the attributes
+object referenced by <I>attr</I>. The <B>pthread_condattr_setpshared</B>
+function shall set the <I>process-shared</I> attribute in an
+initialized attributes object referenced by <I>attr</I>.
+</P>
+<P>The <I>process-shared</I> attribute is set to
+<B>PTHREAD_PROCESS_SHARED</B> to permit a condition variable to be
+operated upon by any thread that has access to the memory where the
+condition variable is allocated, even if the condition variable is
+allocated in memory that is shared by multiple processes. If the
+<I>process-shared</I> attribute is <B>PTHREAD_PROCESS_PRIVATE</B>,
+the condition variable shall only be operated upon by threads created
+within the same process as the thread that initialized the condition
+variable; if threads of differing processes attempt to operate on
+such a condition variable, the behavior is undefined. The default
+value of the attribute is <B>PTHREAD_PROCESS_PRIVATE</B>.
+</P>
+<P><B>Pthreads-w32</B> defines _<B>POSIX_THREAD_PROCESS_SHARED</B> in
+pthread.h as -1 to indicate that these routines are implemented but
+that the process shared attribute is not supported.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>If successful, the <B>pthread_condattr_setpshared</B> function
+shall return zero; otherwise, an error number shall be returned to
+indicate the error.
+</P>
+<P>If successful, the <B>pthread_condattr_getpshared</B> function
+shall return zero and store the value of the <I>process-shared</I>
+attribute of <I>attr</I> into the object referenced by the <I>pshared</I>
+parameter. Otherwise, an error number shall be returned to indicate
+the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_condattr_getpshared</B> and
+<B>pthread_condattr_setpshared</B> functions may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>attr</I> is invalid.
+ </DD></DL>
+<P>
+The <B>pthread_condattr_setpshared</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The new value specified for the attribute is outside the range of
+ legal values for that attribute.
+ </DD><DT>
+ <B>ENOSYS</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>attr</I> was <B>PTHREAD_PROCESS_SHARED</B>
+ (Pthreads-w32).</DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_THREAD_PROCESS_SHARED</B> in
+pthread.h as -1 to indicate that these routines are implemented and
+may be used, but do not support the process shared option.</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> <B>,</B>
+<A HREF="pthread_cond_init.html"><B>pthread_cond_destroy</B>(3)</A> <B>,</B>
+<A HREF="pthread_condattr_init.html"><B>pthread_condattr_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_mutex_init.html"><B>pthread_mutex_destroy</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_create.html b/pthreads/manual/pthread_create.html
new file mode 100644
index 000000000..d1ebbc3e1
--- /dev/null
+++ b/pthreads/manual/pthread_create.html
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_CREATE(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;19394700">
+ <META NAME="CHANGED" CONTENT="20050504;20140200">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_create - create a new thread
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthread_create(pthread_t * </B><I>thread</I><B>,
+pthread_attr_t * </B><I>attr</I><B>, void * (*</B><I>start_routine</I><B>)(void
+*), void * </B><I>arg</I><B>);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P><B>pthread_create</B> creates a new thread of control that
+executes concurrently with the calling thread. The new thread applies
+the function <I>start_routine</I> passing it <I>arg</I> as first
+argument. The new thread terminates either explicitly, by calling
+<A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> , or
+implicitly, by returning from the <I>start_routine</I> function. The
+latter case is equivalent to calling <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A>
+with the result returned by <I>start_routine</I> as exit code.
+</P>
+<P>The initial signal state of the new thread is inherited from it's
+creating thread and there are no pending signals. <B>Pthreads-w32</B>
+does not yet implement signals.</P>
+<P>The <I>attr</I> argument specifies thread attributes to be applied
+to the new thread. See <A HREF="pthread_attr_init.html"><B>pthread_attr_init</B>(3)</A>
+for a complete list of thread attributes. The <I>attr</I> argument
+can also be <B>NULL</B>, in which case default attributes are used:
+the created thread is joinable (not detached) and has default (non
+real-time) scheduling policy.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>On success, the identifier of the newly created thread is stored
+in the location pointed by the <I>thread</I> argument, and a 0 is
+returned. On error, a non-zero error code is returned.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<DL>
+ <DT><B>EAGAIN</B>
+ </DT><DL>
+ <DL>
+ <DT>
+ Not enough system resources to create a process for the new
+ thread, or<BR>more than <B>PTHREAD_THREADS_MAX</B> threads are
+ already active.
+ </DT></DL>
+ </DL>
+</DL>
+<H2>
+<A HREF="#toc5" NAME="sect5">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
+<P><A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> ,
+<A HREF="pthread_join.html"><B>pthread_join</B>(3)</A> ,
+<A HREF="pthread_detach.html"><B>pthread_detach</B>(3)</A> ,
+<A HREF="pthread_attr_init.html"><B>pthread_attr_init</B>(3)</A> .
+</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
+ </P>
+ <LI><P><A HREF="#sect6" NAME="toc6">See Also</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_delay_np.html b/pthreads/manual/pthread_delay_np.html
new file mode 100644
index 000000000..ce533e24e
--- /dev/null
+++ b/pthreads/manual/pthread_delay_np.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_DELAY_NP manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;322600">
+ <META NAME="CHANGED" CONTENT="20050505;21371500">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P STYLE="font-weight: medium">pthread_delay_np ā€“ suspend the
+thread for a specified period</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthread_delay_np (const struct timespec *</B>interval<B>);</B></P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P><B>pthread_delay_np</B> causes a thread to delay execution for a
+specific period of time. This period ends at the current time plus
+the specified interval. The routine will not return before the end of
+the period is reached, but may return an arbitrary amount of time
+after the period has gone by. This can be due to system load, thread
+priorities, and system timer granularity.</P>
+<P>Specifying an interval of zero (0) seconds and zero (0)
+nanoseconds is allowed and can be used to force the thread to give up
+the processor or to deliver a pending cancellation request.</P>
+<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
+<P><B>pthread_delay_np </B>is a cancellation point.</P>
+<H2><A HREF="#toc4" NAME="sect4">Return Value</A></H2>
+<P>If an error condition occurs, <B>pthread_delay_np</B> returns an
+integer value indicating the type of error.</P>
+<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
+<P>The <B>pthread_delay_np</B> function returns the following error
+code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT></DL>
+</DL>
+<P STYLE="margin-left: 2cm">
+The value specified by interval is invalid.</P>
+<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
+<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
+ </P>
+ <LI><P><A HREF="#sect6" NAME="toc6">Author</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_detach.html b/pthreads/manual/pthread_detach.html
new file mode 100644
index 000000000..252adb813
--- /dev/null
+++ b/pthreads/manual/pthread_detach.html
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_DETACH(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.0 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;18010700">
+ <META NAME="CHANGEDBY" CONTENT="Ross Johnson">
+ <META NAME="CHANGED" CONTENT="20060408;9255600">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_detach - put a running thread in the detached state
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthread_detach(pthread_t </B><I>th</I><B>);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P><B>pthread_detach</B> puts the thread <I>th</I> in the detached
+state. This guarantees that the resources consumed by <I>th</I> will
+be freed immediately when <I>th</I> terminates. However, this
+prevents other threads from synchronizing on the termination of <I>th</I>
+using <B>pthread_join</B>. If, when <B>pthread_detach</B> is called,
+<I>th</I> has already terminated, all of <I>th</I>'s remaining
+resources will be freed.</P>
+<P>A thread can be created initially in the detached state, using the
+<B>detachstate</B> attribute to <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A>
+. In contrast, <B>pthread_detach</B> applies to threads created in
+the joinable state, and which need to be put in the detached state
+later.
+</P>
+<P>After <B>pthread_detach</B> completes, subsequent attempts to
+perform <B>pthread_join</B> on <I>th</I> will fail. If another thread
+is already joining the thread <I>th</I> at the time <B>pthread_detach</B>
+is called, <I>th</I> will be detached and <B>pthread_join</B> will
+eventually return when <I>th</I> terminates but may not return with
+<I>th</I>'s correct return code.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>On success, 0 is returned. On error, a non-zero error code is
+returned.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<DL>
+ <DT><B>ESRCH</B>
+ </DT><DD>
+ No thread could be found corresponding to that specified by <I>th</I>
+ </DD><DT>
+ <B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ the thread <I>th</I> is already in the detached state
+ </DD></DL>
+<H2>
+<A HREF="#toc5" NAME="sect5">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with Pthreads-w32.</P>
+<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
+<P><A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> ,
+<A HREF="pthread_join.html"><B>pthread_join</B>(3)</A> ,
+<A HREF="pthread_attr_init.html"><B>pthread_attr_setdetachstate</B>(3)</A>
+</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
+ </P>
+ <LI><P><A HREF="#sect6" NAME="toc6">See Also</A>
+ </P>
+</UL>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/pthreads/manual/pthread_equal.html b/pthreads/manual/pthread_equal.html
new file mode 100644
index 000000000..6f610634e
--- /dev/null
+++ b/pthreads/manual/pthread_equal.html
@@ -0,0 +1,48 @@
+<!-- manual page source format generated by PolyglotMan v3.2, -->
+<!-- available at http://polyglotman.sourceforge.net/ -->
+
+<html>
+<head>
+<title>PTHREAD_EQUAL(3) manual page</title>
+</head>
+<body bgcolor='white'>
+<a href='#toc'>Table of Contents</a><p>
+
+<p>
+<h2><a name='sect0' href='#toc0'>Name</a></h2>
+pthread_equal - compare two thread identifiers
+<p>
+<h2><a name='sect1' href='#toc1'>Synopsis</a></h2>
+<b>#include &lt;pthread.h&gt;</b>
+
+<p> <b>int pthread_equal(pthread_t </b><i>thread1</i><b>, pthread_t </b><i>thread2</i><b>);</b>
+<p>
+<h2><a name='sect2' href='#toc2'>Description</a></h2>
+<b>pthread_equal</b>
+determines if two thread identifiers refer to the same thread.
+<p>
+<h2><a name='sect3' href='#toc3'>Return Value</a></h2>
+A
+non-zero value is returned if <i>thread1</i> and <i>thread2</i> refer to the same thread.
+Otherwise, 0 is returned.
+<p>
+<h2><a name='sect4' href='#toc4'>Author</a></h2>
+Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+<p>
+<h2><a name='sect5' href='#toc5'>See Also</a></h2>
+<a href='file:pthread_self.html'><b>pthread_self</b>(3)</a>
+.
+<p>
+
+<hr><p>
+<a name='toc'><b>Table of Contents</b></a><p>
+<ul>
+<li><a name='toc0' href='#sect0'>Name</a></li>
+<li><a name='toc1' href='#sect1'>Synopsis</a></li>
+<li><a name='toc2' href='#sect2'>Description</a></li>
+<li><a name='toc3' href='#sect3'>Return Value</a></li>
+<li><a name='toc4' href='#sect4'>Author</a></li>
+<li><a name='toc5' href='#sect5'>See Also</a></li>
+</ul>
+</body>
+</html>
diff --git a/pthreads/manual/pthread_exit.html b/pthreads/manual/pthread_exit.html
new file mode 100644
index 000000000..e97318f54
--- /dev/null
+++ b/pthreads/manual/pthread_exit.html
@@ -0,0 +1,59 @@
+<!-- manual page source format generated by PolyglotMan v3.2, -->
+<!-- available at http://polyglotman.sourceforge.net/ -->
+
+<html>
+<head>
+<title>PTHREAD_EXIT(3) manual page</title>
+</head>
+<body bgcolor='white'>
+<a href='#toc'>Table of Contents</a><p>
+
+<p>
+<h2><a name='sect0' href='#toc0'>Name</a></h2>
+pthread_exit - terminate the calling thread
+<p>
+<h2><a name='sect1' href='#toc1'>Synopsis</a></h2>
+<b>#include &lt;pthread.h&gt;</b>
+
+<p> <b>void pthread_exit(void *</b><i>retval</i><b>);</b>
+<p>
+<h2><a name='sect2' href='#toc2'>Description</a></h2>
+<b>pthread_exit</b> terminates the
+execution of the calling thread. All cleanup handlers that have been set
+for the calling thread with <a href='file:pthread_cleanup_push.html'><b>pthread_cleanup_push</b>(3)</a>
+ are executed in reverse
+order (the most recently pushed handler is executed first). Finalization
+functions for thread-specific data are then called for all keys that have
+non- <b>NULL</b> values associated with them in the calling thread (see <a href='file:pthread_key_create.html'><b>pthread_key_create</b>(3)</a>
+).
+Finally, execution of the calling thread is stopped.
+<p> The <i>retval</i> argument
+is the return value of the thread. It can be consulted from another thread
+using <a href='file:pthread_join.html'><b>pthread_join</b>(3)</a>
+.
+<p>
+<h2><a name='sect3' href='#toc3'>Return Value</a></h2>
+The <b>pthread_exit</b> function never returns.
+
+<p>
+<h2><a name='sect4' href='#toc4'>Author</a></h2>
+Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+<p>
+<h2><a name='sect5' href='#toc5'>See Also</a></h2>
+<a href='file:pthread_create.html'><b>pthread_create</b>(3)</a>
+, <a href='file:pthread_join.html'><b>pthread_join</b>(3)</a>
+.
+<p>
+
+<hr><p>
+<a name='toc'><b>Table of Contents</b></a><p>
+<ul>
+<li><a name='toc0' href='#sect0'>Name</a></li>
+<li><a name='toc1' href='#sect1'>Synopsis</a></li>
+<li><a name='toc2' href='#sect2'>Description</a></li>
+<li><a name='toc3' href='#sect3'>Return Value</a></li>
+<li><a name='toc4' href='#sect4'>Author</a></li>
+<li><a name='toc5' href='#sect5'>See Also</a></li>
+</ul>
+</body>
+</html>
diff --git a/pthreads/manual/pthread_getw32threadhandle_np.html b/pthreads/manual/pthread_getw32threadhandle_np.html
new file mode 100644
index 000000000..7e8de6438
--- /dev/null
+++ b/pthreads/manual/pthread_getw32threadhandle_np.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_GETW32THREADHANDLE_NP manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;322600">
+ <META NAME="CHANGED" CONTENT="20050505;21523500">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P STYLE="font-weight: medium">pthread_getw32threadhandle_np ā€“ get
+the Win32 thread handle associated with a thread</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>HANDLE pthread_getw32threadhandle_np(pthread_t</B> <I>thread</I><B>);</B></P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>Returns the Win32 native thread <B>HANDLE</B> that the POSIX
+thread <I>thread</I> is running as.</P>
+<P>Applications can use the Win32 handle to set Win32 specific
+attributes of the thread.</P>
+<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
+<P>None.</P>
+<H2><A HREF="#toc4" NAME="sect4">Return Value</A></H2>
+<P><B>pthread_getw32threadhandle_np</B> returns the Win32 native
+thread <B>HANDLE</B> for the specified POSIX thread <I>thread</I>.</P>
+<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
+<P>None.</P>
+<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
+<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
+ </P>
+ <LI><P><A HREF="#sect6" NAME="toc6">Author</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_join.html b/pthreads/manual/pthread_join.html
new file mode 100644
index 000000000..3e3f3b902
--- /dev/null
+++ b/pthreads/manual/pthread_join.html
@@ -0,0 +1,118 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_JOIN(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;18232700">
+ <META NAME="CHANGED" CONTENT="20050504;18421400">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_join - wait for termination of another thread
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthread_join(pthread_t </B><I>th</I><B>, void
+**</B><I>thread_return</I><B>);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P><B>pthread_join</B> suspends the execution of the calling thread
+until the thread identified by <I>th</I> terminates, either by
+calling <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> or by
+being cancelled.
+</P>
+<P>If <I>thread_return</I> is not <B>NULL</B>, the return value of <I>th</I>
+is stored in the location pointed to by <I>thread_return</I>. The
+return value of <I>th</I> is either the argument it gave to
+<A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> , or
+<B>PTHREAD_CANCELED</B> if <I>th</I> was cancelled.
+</P>
+<P>The joined thread <B>th</B> must be in the joinable state: it must
+not have been detached using <A HREF="pthread_detach.html"><B>pthread_detach</B>(3)</A>
+or the <B>PTHREAD_CREATE_DETACHED</B> attribute to <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A>
+.
+</P>
+<P>When a joinable thread terminates, its memory resources (thread
+descriptor and stack) are not deallocated until another thread
+performs <B>pthread_join</B> on it. Therefore, <B>pthread_join</B>
+must be called once for each joinable thread created to avoid memory
+leaks.
+</P>
+<P>At most one thread can wait for the termination of a given thread.
+Calling <B>pthread_join</B> on a thread <I>th</I> on which another
+thread is already waiting for termination returns an error.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
+<P><B>pthread_join</B> is a cancellation point. If a thread is
+cancelled while suspended in <B>pthread_join</B>, the thread
+execution resumes immediately and the cancellation is executed
+without waiting for the <I>th</I> thread to terminate. If
+cancellation occurs during <B>pthread_join</B>, the <I>th</I> thread
+remains not joined.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Return Value</A></H2>
+<P>On success, the return value of <I>th</I> is stored in the
+location pointed to by <I>thread_return</I>, and 0 is returned. On
+error, a non-zero error code is returned.
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
+<DL>
+ <DT><B>ESRCH</B>
+ </DT><DD>
+ No thread could be found corresponding to that specified by <I>th</I>.
+ </DD><DT>
+ <B>EINVAL</B>
+ </DT><DD>
+ The <I>th</I> thread has been detached.
+ </DD><DT>
+ <B>EINVAL</B>
+ </DT><DD>
+ Another thread is already waiting on termination of <I>th</I>.
+ </DD><DT>
+ <B>EDEADLK</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The <I>th</I> argument refers to the calling thread.
+ </DD></DL>
+<H2>
+<A HREF="#toc6" NAME="sect6">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<H2><A HREF="#toc7" NAME="sect7">See Also</A></H2>
+<P><A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> ,
+<A HREF="pthread_detach.html"><B>pthread_detach</B>(3)</A> ,
+<A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> ,
+<A HREF="pthread_attr_setdetachstate.html"><B>pthread_attr_setdetachstate</B>(3)</A>
+, <A HREF="pthread_cleanup_push.html"><B>pthread_cleanup_push</B>(3)</A>
+, <A HREF="pthread_key_create.html"><B>pthread_key_create</B>(3)</A>
+.
+</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Author</A>
+ </P>
+ <LI><P><A HREF="#sect7" NAME="toc7">See Also</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_key_create.html b/pthreads/manual/pthread_key_create.html
new file mode 100644
index 000000000..5ecca6995
--- /dev/null
+++ b/pthreads/manual/pthread_key_create.html
@@ -0,0 +1,211 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_SPECIFIC(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;18425400">
+ <META NAME="CHANGED" CONTENT="20050509;18220200">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_key_create, pthread_key_delete, pthread_setspecific,
+pthread_getspecific - management of thread-specific data
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthread_key_create(pthread_key_t *</B><I>key</I><B>, void
+(*</B><I>destr_function</I><B>) (void *));</B>
+</P>
+<P><B>int pthread_key_delete(pthread_key_t </B><I>key</I><B>);</B>
+</P>
+<P><B>int pthread_setspecific(pthread_key_t </B><I>key</I><B>, const
+void *</B><I>pointer</I><B>);</B>
+</P>
+<P><B>void * pthread_getspecific(pthread_key_t </B><I>key</I><B>);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>Programs often need global or static variables that have different
+values in different threads. Since threads share one memory space,
+this cannot be achieved with regular variables. Thread-specific data
+is the POSIX threads answer to this need.
+</P>
+<P>Each thread possesses a private memory block, the thread-specific
+data area, or TSD area for short. This area is indexed by TSD keys.
+The TSD area associates values of type <B>void *</B> to TSD keys. TSD
+keys are common to all threads, but the value associated with a given
+TSD key can be different in each thread.
+</P>
+<P>For concreteness, the TSD areas can be viewed as arrays of <B>void
+*</B> pointers, TSD keys as integer indices into these arrays, and
+the value of a TSD key as the value of the corresponding array
+element in the calling thread.
+</P>
+<P>When a thread is created, its TSD area initially associates <B>NULL</B>
+with all keys.
+</P>
+<P><B>pthread_key_create</B> allocates a new TSD key. The key is
+stored in the location pointed to by <I>key</I>. There is a limit of
+<B>PTHREAD_KEYS_MAX</B> on the number of keys allocated at a given
+time. The value initially associated with the returned key is <B>NULL</B>
+in all currently executing threads.
+</P>
+<P>The <I>destr_function</I> argument, if not <B>NULL</B>, specifies
+a destructor function associated with the key. When a thread
+terminates via <B>pthread_exit</B> or by cancellation, <I>destr_function</I>
+is called with arguments the value associated with the key in that
+thread. The <I>destr_function</I> is not called if that value is <B>NULL</B><SPAN STYLE="font-weight: medium">
+or the key has been deleted</SPAN>. The order in which destructor
+functions are called at thread termination time is unspecified.
+</P>
+<P>Before the destructor function is called, the <B>NULL</B> value is
+associated with the key in the current thread. A destructor function
+might, however, re-associate non- <B>NULL</B> values to that key or
+some other key. To deal with this, if after all the destructors have
+been called for all non- <B>NULL</B> values, there are still some
+non- <B>NULL</B> values with associated destructors, then the process
+is repeated.</P>
+<P><B>pthread_key_delete</B> deallocates a TSD key. It does not check
+whether non- <B>NULL</B> values are associated with that key in the
+currently executing threads, nor call the destructor function
+associated with the key.
+</P>
+<P><B>pthread_setspecific</B> changes the value associated with <I>key</I>
+in the calling thread, storing the given <I>pointer</I> instead.
+</P>
+<P><B>pthread_getspecific</B> returns the value currently associated
+with <I>key</I> in the calling thread.
+</P>
+<P>The routines <B>pthread_setspecific</B>, <B>pthread_getspecific</B>,
+and <B>pthread_key_delete</B> can be called from <I>destr_function</I>
+targeting any valid key including the key on which <I>destr_function</I>
+is currently operating. If <B>pthread_getspecific</B> is called on
+the key whose thread specific data is being destroyed, the value NULL
+is returned, unless <B>pthread_setspecific</B> was called previously
+on that key from within <I>destr_function</I> to set the value to
+non-NULL. For some implementations the effect of calling
+<B>pthread_setspecific</B> from within <I>destr_function</I> can be
+either memory leakage or infinite loops if <I>destr_function</I> has
+already been called at least <B>PTHREAD_DESTRUCTOR_ITERATIONS</B>
+times.</P>
+<P STYLE="font-weight: medium"><B>Pthreads-w32</B> stops running key
+<I>destr_function</I> routines after <B>PTHREAD_DESTRUCTOR_ITERATIONS</B>
+iterations, even if some non- <B>NULL</B> values with associated
+descriptors remain. If memory is allocated and associated with a key
+from within <I>destr_function</I>, that memory may not be reclaimed
+because that key's <I>destr_function</I>, may not run again.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P><B>pthread_key_create</B>, <B>pthread_key_delete</B>, and
+<B>pthread_setspecific</B> return 0 on success and a non-zero error
+code on failure. If successful, <B>pthread_key_create</B> stores the
+newly allocated key in the location pointed to by its <I>key</I>
+argument.
+</P>
+<P><B>pthread_getspecific</B> returns the value associated with <I>key</I>
+on success, and <B>NULL</B> on error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P><B>pthread_key_create</B> returns the following error code on
+error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EAGAIN</B>
+ </DT></DL>
+</DL>
+<BLOCKQUOTE STYLE="margin-left: 5cm">
+<B>PTHREAD_KEYS_MAX</B> keys are already allocated
+</BLOCKQUOTE>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ENOMEM</B>
+ </DT></DL>
+</DL>
+<BLOCKQUOTE STYLE="margin-left: 5cm">
+Insufficient memory to allocate the key.
+</BLOCKQUOTE>
+<P><B>pthread_key_delete</B> and <B>pthread_setspecific</B> return
+the following error code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <I>key</I> is not a valid, allocated TSD key
+ </DD></DL>
+</DL>
+<P>
+<B>pthread_getspecific</B> returns <B>NULL</B> if <I>key</I> is not a
+valid, allocated TSD key.
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
+<P><A HREF="pthread_create.html">pthread_create(3)</A> ,
+<A HREF="pthread_exit.html">pthread_exit(3)</A> ,
+<A HREF="pthread_cancel.html">pthread_testcancel(3)</A> .
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Example</A></H2>
+<P>The following code fragment allocates a thread-specific array of
+100 characters, with automatic reclamation at thread exit:
+</P>
+<BLOCKQUOTE><BR><BR>
+</BLOCKQUOTE>
+<PRE STYLE="margin-left: 1cm; margin-right: 1cm">/* Key for the thread-specific buffer */
+static pthread_key_t buffer_key;
+/* Once-only initialisation of the key */
+static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
+/* Allocate the thread-specific buffer */
+void buffer_alloc(void)
+{
+ pthread_once(&amp;buffer_key_once, buffer_key_alloc);
+ pthread_setspecific(buffer_key, malloc(100));
+}
+/* Return the thread-specific buffer */
+char * get_buffer(void)
+{
+ return (char *) pthread_getspecific(buffer_key);
+}
+/* Allocate the key */
+static void buffer_key_alloc()
+{
+ pthread_key_create(&amp;buffer_key, buffer_destroy);
+}
+/* Free the thread-specific buffer */
+static void buffer_destroy(void * buf)
+{
+ free(buf);
+}</PRE>
+<HR>
+<BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm"><A NAME="toc"></A>
+<B>Table of Contents</B></BLOCKQUOTE>
+<UL>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">See
+ Also</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE><A HREF="#sect7" NAME="toc7">Example</A>
+ </BLOCKQUOTE>
+</UL>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/pthreads/manual/pthread_kill.html b/pthreads/manual/pthread_kill.html
new file mode 100644
index 000000000..33d61b21c
--- /dev/null
+++ b/pthreads/manual/pthread_kill.html
@@ -0,0 +1,152 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_SIGNAL(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;18500100">
+ <META NAME="CHANGED" CONTENT="20050504;23005800">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_sigmask, pthread_kill, sigwait - handling of signals in
+threads
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B> <BR><B>#include &lt;signal.h&gt;</B>
+</P>
+<P><B>int pthread_sigmask(int </B><I>how</I><B>, const sigset_t
+*</B><I>newmask</I><B>, sigset_t *</B><I>oldmask</I><B>);</B>
+</P>
+<P><B>int pthread_kill(pthread_t </B><I>thread</I><B>, int </B><I>signo</I><B>);</B>
+</P>
+<P><B>int sigwait(const sigset_t *</B>set, <B>int</B> *sig);</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P><B>pthread_sigmask</B> changes the signal mask for the calling
+thread as described by the <I>how</I> and <I>newmask</I> arguments.
+If <I>oldmask</I> is not <B>NULL</B>, the previous signal mask is
+stored in the location pointed to by <I>oldmask</I>. <B>Pthreads-w32</B>
+implements this function but no other function uses the signal mask
+yet.</P>
+<P>The meaning of the <I>how</I> and <I>newmask</I> arguments is the
+same as for <B><SPAN STYLE="font-style: normal">sigprocmask</SPAN></B>(2).
+If <I>how</I> is <B>SIG_SETMASK</B>, the signal mask is set to
+<I>newmask</I>. If <I>how</I> is <B>SIG_BLOCK</B>, the signals
+specified to <I>newmask</I> are added to the current signal mask. If
+<I>how</I> is <B>SIG_UNBLOCK</B>, the signals specified to <I>newmask</I>
+are removed from the current signal mask.
+</P>
+<P>Recall that signal masks are set on a per-thread basis, but signal
+actions and signal handlers, as set with <B>sigaction</B>(2), are
+shared between all threads.
+</P>
+<P><B>pthread_kill</B> send signal number <I>signo</I> to the thread
+<I>thread</I>. <B>Pthreads-w32</B> only supports signal number 0,
+which does not send any signal but causes <B>pthread_kill</B> to
+return an error if <I>thread</I> is not valid.</P>
+<P><B>sigwait</B> suspends the calling thread until one of the
+signals in <I>set</I> is delivered to the calling thread. It then
+stores the number of the signal received in the location pointed to
+by <I>sig</I> and returns. The signals in <I>set</I> must be blocked
+and not ignored on entrance to <B>sigwait</B>. If the delivered
+signal has a signal handler function attached, that function is <I>not</I>
+called. <B>Pthreads-w32</B> implements this function as a
+cancellation point only - it does not wait for any signals and does
+not change the location pointed to by <I>sig</I>.</P>
+<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
+<P><B>sigwait</B> is a cancellation point.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Return Value</A></H2>
+<P>On success, 0 is returned. On failure, a non-zero error code is
+returned.
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
+<P>The <B>pthread_sigmask</B> function returns the following error
+codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <I>how</I> is not one of <B>SIG_SETMASK</B>, <B>SIG_BLOCK</B>, or
+ <B>SIG_UNBLOCK</B>
+ </DD></DL>
+</DL>
+<P>
+The <B>pthread_kill</B> function returns the following error codes on
+error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <I>signo</I> is not a valid signal number or is unsupported.</DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <B>ESRCH</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the thread <I>thread</I> does not exist (e.g. it has already
+ terminated)
+ </DD></DL>
+</DL>
+<P>
+The <B>sigwait</B> function never returns an error.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc7" NAME="sect7">See Also</A></H2>
+<P>
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Notes</A></H2>
+<P>In any implementation, for <B>sigwait</B> to work reliably, the
+signals being waited for must be blocked in all threads, not only in
+the calling thread, since otherwise the POSIX semantics for signal
+delivery do not guarantee that itā€™s the thread doing the <B>sigwait</B>
+that will receive the signal. The best way to achieve this is to
+block those signals before any threads are created, and never unblock
+them in the program other than by calling <B>sigwait</B>. This works
+because all threads inherit their initial sigmask from their creating
+thread.</P>
+<H2><A HREF="#toc9" NAME="sect9">Bugs</A></H2>
+<P><B>Pthreads-w32</B> does not implement signals yet and so these
+routines have almost no use except to prevent the compiler or linker
+from complaining. <B>pthread_kill</B> is useful in determining if the
+thread is a valid thread, but since many threads implementations
+reuse thread IDs, the valid thread may no longer be the thread you
+think it is, and so this method of determining thread validity is not
+portable, and very risky. <B>Pthreads-w32</B> from version 1.0.0
+onwards implements pseudo-unique thread IDs, so applications that use
+this technique (but really shouldn't) have some protection.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Author</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">See
+ Also</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Notes</A>
+ </P>
+ <LI><P><A HREF="#sect9" NAME="toc9">Bugs</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_mutex_init.html b/pthreads/manual/pthread_mutex_init.html
new file mode 100644
index 000000000..f9982cf61
--- /dev/null
+++ b/pthreads/manual/pthread_mutex_init.html
@@ -0,0 +1,277 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_MUTEX(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;5000">
+ <META NAME="CHANGED" CONTENT="20050505;19000600">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_mutex_init, pthread_mutex_lock, pthread_mutex_trylock,
+pthread_mutex_timedlock, pthread_mutex_unlock, pthread_mutex_destroy
+- operations on mutexes
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>#include &lt;time.h&gt;</B></P>
+<P><B>pthread_mutex_t </B><I>fastmutex</I> <B>=
+PTHREAD_MUTEX_INITIALIZER;</B>
+</P>
+<P><B>pthread_mutex_t </B><I>recmutex</I> <B>=
+PTHREAD_RECURSIVE_MUTEX_INITIALIZER;</B>
+</P>
+<P><B>pthread_mutex_t </B><I>errchkmutex</I> <B>=
+PTHREAD_ERRORCHECK_MUTEX_INITIALIZER;</B>
+</P>
+<P><B>pthread_mutex_t </B><I>recmutex</I> <B>=
+PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;</B>
+</P>
+<P><B>pthread_mutex_t </B><I>errchkmutex</I> <B>=
+PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;</B>
+</P>
+<P><B>int pthread_mutex_init(pthread_mutex_t *</B><I>mutex</I><B>,
+const pthread_mutexattr_t *</B><I>mutexattr</I><B>);</B>
+</P>
+<P><B>int pthread_mutex_lock(pthread_mutex_t *</B><I>mutex</I><B>);</B>
+</P>
+<P><B>int pthread_mutex_trylock(pthread_mutex_t *</B><I>mutex</I><B>);</B>
+</P>
+<P><B>int pthread_mutex_timedlock(pthread_mutex_t *</B><I>mutex,
+</I><B>const struct timespec *</B><I>abs_timeout</I><B>);</B>
+</P>
+<P><B>int pthread_mutex_unlock(pthread_mutex_t *</B><I>mutex</I><B>);</B>
+</P>
+<P><B>int pthread_mutex_destroy(pthread_mutex_t *</B><I>mutex</I><B>);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>A mutex is a MUTual EXclusion device, and is useful for protecting
+shared data structures from concurrent modifications, and
+implementing critical sections and monitors.
+</P>
+<P>A mutex has two possible states: unlocked (not owned by any
+thread), and locked (owned by one thread). A mutex can never be owned
+by two different threads simultaneously. A thread attempting to lock
+a mutex that is already locked by another thread is suspended until
+the owning thread unlocks the mutex first.
+</P>
+<P><B>pthread_mutex_init</B> initializes the mutex object pointed to
+by <I>mutex</I> according to the mutex attributes specified in
+<I>mutexattr</I>. If <I>mutexattr</I> is <B>NULL</B>, default
+attributes are used instead.
+</P>
+<P>The type of a mutex determines whether it can be locked again by a
+thread that already owns it. The default type is ā€œnormalā€. See
+<A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_init</B>(3)</A>
+for more information on mutex attributes.
+</P>
+<P>Variables of type <B>pthread_mutex_t</B> can also be initialized
+statically, using the constants <B>PTHREAD_MUTEX_INITIALIZER</B> (for
+normal ā€œfastā€ mutexes), <B>PTHREAD_RECURSIVE_MUTEX_INITIALIZER</B>
+(for recursive mutexes), and <B>PTHREAD_ERRORCHECK_MUTEX_INITIALIZER</B>
+(for error checking mutexes). <SPAN STYLE="font-weight: medium"> In
+the <B>Pthreads-w32</B> implementation, an application should still
+call <B>pthread_mutex_destroy</B> at some point to ensure that any
+resources consumed by the mutex are released.</SPAN></P>
+<P><B>pthread_mutex_lock</B> locks the given mutex. If the mutex is
+currently unlocked, it becomes locked and owned by the calling
+thread, and <B>pthread_mutex_lock</B> returns immediately. If the
+mutex is already locked by another thread, <B>pthread_mutex_lock</B>
+suspends the calling thread until the mutex is unlocked.
+</P>
+<P>If the mutex is already locked by the calling thread, the behavior
+of <B>pthread_mutex_lock</B> depends on the type of the mutex. If the
+mutex is of the ā€œnormalā€ type, the calling thread is suspended
+until the mutex is unlocked, thus effectively causing the calling
+thread to deadlock. If the mutex is of the ā€˜ā€˜error checkingā€™ā€™
+type, <B>pthread_mutex_lock</B> returns immediately with the error
+code <B>EDEADLK</B>. If the mutex is of the ā€˜ā€˜recursiveā€™ā€™
+type, <B>pthread_mutex_lock</B> succeeds and returns immediately,
+recording the number of times the calling thread has locked the
+mutex. An equal number of <B>pthread_mutex_unlock</B> operations must
+be performed before the mutex returns to the unlocked state.
+</P>
+<P><B>pthread_mutex_trylock</B> behaves identically to
+<B>pthread_mutex_lock</B>, 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,
+<B>pthread_mutex_trylock</B> returns immediately with the error code
+<B>EBUSY</B>.
+</P>
+<P><B>pthread_mutex_timedlock</B> behaves identically to
+<B>pthread_mutex_lock</B>, except that if it cannot acquire the lock
+before the <I>abs_timeout</I> time, the call returns with the error
+code <B>ETIMEDOUT</B>. If the mutex can be locked immediately it is,
+and the <B>abs_timeout</B> parameter is ignored.</P>
+<P><B>pthread_mutex_unlock</B> unlocks the given mutex. The mutex is
+assumed to be locked and owned by the calling thread on entrance to
+<B>pthread_mutex_unlock</B>. If the mutex is of the ā€œnormalā€
+type, <B>pthread_mutex_unlock</B> always returns it to the unlocked
+state. If it is of the ā€˜ā€˜recursiveā€™ā€™ type, it decrements the
+locking count of the mutex (number of <B>pthread_mutex_lock</B>
+operations performed on it by the calling thread), and only when this
+count reaches zero is the mutex actually unlocked.
+</P>
+<P>On ā€˜ā€˜error checkingā€™ā€™ mutexes, <B>pthread_mutex_unlock</B>
+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
+<B>pthread_mutex_unlock</B>. 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.</P>
+<P><B>pthread_mutex_destroy</B> destroys a mutex object, freeing the
+resources it might hold. The mutex must be unlocked on entrance.</P>
+<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
+<P>None of the mutex functions is a cancellation point, not even
+<B>pthread_mutex_lock</B>, in spite of the fact that it can suspend a
+thread for arbitrary durations. This way, the status of mutexes at
+cancellation points is predictable, allowing cancellation handlers to
+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.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Async-signal Safety</A></H2>
+<P>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 <B>pthread_mutex_lock</B> or <B>pthread_mutex_unlock</B> from
+a signal handler may deadlock the calling thread.
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Return Value</A></H2>
+<P><B>pthread_mutex_init</B> always returns 0. The other mutex
+functions return 0 on success and a non-zero error code on error.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Errors</A></H2>
+<P>The <B>pthread_mutex_lock</B> function returns the following error
+code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the mutex has not been properly initialized.
+ </DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <B>EDEADLK</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the mutex is already locked by the calling thread (ā€˜ā€˜error
+ checkingā€™ā€™ mutexes only).
+ </DD></DL>
+</DL>
+<P>
+The <B>pthread_mutex_trylock</B> function returns the following error
+codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EBUSY</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the mutex could not be acquired because it was currently locked.
+ </DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the mutex has not been properly initialized.
+ </DD></DL>
+</DL>
+<P>
+The <B>pthread_mutex_timedlock</B> function returns the following
+error codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ETIMEDOUT</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the mutex could not be acquired before the <I>abs_timeout</I> time
+ arrived.
+ </DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the mutex has not been properly initialized.
+ </DD></DL>
+</DL>
+<P>
+The <B>pthread_mutex_unlock</B> function returns the following error
+code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the mutex has not been properly initialized.
+ </DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <B>EPERM</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the calling thread does not own the mutex (ā€˜ā€˜error checkingā€™ā€™
+ mutexes only).
+ </DD></DL>
+</DL>
+<P>
+The <B>pthread_mutex_destroy</B> function returns the following error
+code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EBUSY</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the mutex is currently locked.
+ </DD></DL>
+</DL>
+<H2>
+<A HREF="#toc7" NAME="sect7">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc8" NAME="sect8">See Also</A></H2>
+<P><A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_init</B>(3)</A>
+, <A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_settype</B>(3)</A>
+, <A HREF="pthread_cancel.html"><B>pthread_cancel</B>(3)</A> .
+</P>
+<H2><A HREF="#toc9" NAME="sect9">Example</A></H2>
+<P>A shared global variable <I>x</I> can be protected by a mutex as
+follows:
+</P>
+<PRE STYLE="margin-left: 1cm; margin-right: 1cm">int x;
+pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;</PRE><BLOCKQUOTE STYLE="margin-left: 0cm; margin-right: 0cm">
+All accesses and modifications to <I>x</I> should be bracketed by
+calls to <B>pthread_mutex_lock</B> and <B>pthread_mutex_unlock</B> as
+follows:
+</BLOCKQUOTE>
+<PRE STYLE="margin-left: 1.03cm; margin-right: 2cm">pthread_mutex_lock(&amp;mut);
+/* operate on x */
+pthread_mutex_unlock(&amp;mut);</PRE>
+<HR>
+<BLOCKQUOTE STYLE="margin-right: 4cm"><A NAME="toc"></A><B>Table of
+Contents</B></BLOCKQUOTE>
+<UL>
+ <LI><BLOCKQUOTE STYLE="margin-right: 4cm; margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 4cm; margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 4cm; margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 4cm; margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 4cm; margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Async-signal
+ Safety</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 4cm; margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Return
+ Value</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 4cm; margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Errors</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 4cm; margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Author</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 4cm; margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">See
+ Also</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-right: 4cm"><A HREF="#sect9" NAME="toc9">Example</A>
+ </BLOCKQUOTE>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_mutexattr_init.html b/pthreads/manual/pthread_mutexattr_init.html
new file mode 100644
index 000000000..f3df9936d
--- /dev/null
+++ b/pthreads/manual/pthread_mutexattr_init.html
@@ -0,0 +1,157 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_MUTEXATTR(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;23040500">
+ <META NAME="CHANGED" CONTENT="20050505;18370400">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_mutexattr_init, pthread_mutexattr_destroy,
+pthread_mutexattr_settype, pthread_mutexattr_gettype - mutex creation
+attributes
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthread_mutexattr_init(pthread_mutexattr_t *</B><I>attr</I><B>);</B>
+</P>
+<P><B>int pthread_mutexattr_destroy(pthread_mutexattr_t *</B><I>attr</I><B>);</B>
+</P>
+<P><B>int pthread_mutexattr_settype(pthread_mutexattr_t *</B><I>attr</I><B>,
+int </B><I>type</I><B>);</B>
+</P>
+<P><B>int pthread_mutexattr_gettype(const pthread_mutexattr_t *</B><I>attr</I><B>,
+int *</B><I>type</I><B>);</B>
+</P>
+<P><B>int pthread_mutexattr_setkind_np(pthread_mutexattr_t *</B><I>attr</I><B>,
+int </B><I>type</I><B>);</B>
+</P>
+<P><B>int pthread_mutexattr_getkind_np(const pthread_mutexattr_t
+*</B><I>attr</I><B>, int *</B><I>type</I><B>);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>Mutex attributes can be specified at mutex creation time, by
+passing a mutex attribute object as second argument to
+<A HREF="pthread_mutex_init.html"><B>pthread_mutex_init</B>(3)</A> .
+Passing <B>NULL</B> is equivalent to passing a mutex attribute object
+with all attributes set to their default values.
+</P>
+<P><B>pthread_mutexattr_init</B> initializes the mutex attribute
+object <I>attr</I> and fills it with default values for the
+attributes.
+</P>
+<P><B>pthread_mutexattr_destroy</B> destroys a mutex attribute
+object, which must not be reused until it is reinitialized.</P>
+<P>The following mutex types are supported:</P>
+<P STYLE="margin-left: 2cm"><B>PTHREAD_MUTEX_NORMAL</B> - for
+ā€˜ā€˜fastā€™ā€™ mutexes.</P>
+<P STYLE="margin-left: 2cm"><B>PTHREAD_MUTEX_RECURSIVE</B> - for
+ā€˜ā€˜recursiveā€™ā€™ mutexes.</P>
+<P STYLE="margin-left: 2cm"><B>PTHREAD_MUTEX_ERRORCHECK</B> - for
+ā€˜ā€˜error checkingā€™ā€™ mutexes.</P>
+<P>The mutex type determines what happens if a thread attempts to
+lock a mutex it already owns with <A HREF="pthread_mutex_lock.html"><B>pthread_mutex_lock</B>(3)</A>
+. If the mutex is of the ā€œnormalā€ or ā€œfastā€ type,
+<A HREF="pthread_mutex_lock.html"><B>pthread_mutex_lock</B>(3)</A>
+simply suspends the calling thread forever. If the mutex is of the
+ā€˜ā€˜error checkingā€™ā€™ type, <A HREF="pthread_mutex_lock.html"><B>pthread_mutex_lock</B>(3)</A>
+returns immediately with the error code <B>EDEADLK</B>. If the mutex
+is of the ā€˜ā€˜recursiveā€™ā€™ type, the call to
+<A HREF="pthread_mutex_lock.html"><B>pthread_mutex_lock</B>(3)</A>
+returns immediately with a success return code. The number of times
+the thread owning the mutex has locked it is recorded in the mutex.
+The owning thread must call <A HREF="pthread_mutex_unlock.html"><B>pthread_mutex_unlock</B>(3)</A>
+the same number of times before the mutex returns to the unlocked
+state.
+</P>
+<P>The default mutex type is <B>PTHREAD_MUTEX_NORMAL</B></P>
+<P><B>Pthreads-w32</B> also recognises the following equivalent types
+that are used by Linux:</P>
+<P STYLE="margin-left: 2cm; font-weight: medium"><B>PTHREAD_MUTEX_FAST_NP</B>
+ā€“ equivalent to <B>PTHREAD_MUTEX_NORMAL</B></P>
+<P STYLE="margin-left: 2cm"><B>PTHREAD_MUTEX_RECURSIVE_NP</B></P>
+<P STYLE="margin-left: 2cm"><B>PTHREAD_MUTEX_ERRORCHECK_NP</B></P>
+<P><B>pthread_mutexattr_settype</B> sets the mutex type attribute in
+<I>attr</I> to the value specified by <I>type</I>.
+</P>
+<P><B>pthread_mutexattr_gettype</B> retrieves the current value of
+the mutex kind attribute in <I>attr</I> and stores it in the location
+pointed to by <I>type</I>.
+</P>
+<P><B>Pthreads-w32</B> also recognises the following equivalent
+functions that are used in Linux:</P>
+<P><B>pthread_mutexattr_setkind_np</B> is an alias for
+<B>pthread_mutexattr_settype</B>.
+</P>
+<P STYLE="font-weight: medium"><B>pthread_mutexattr_getkind_np</B> is
+an alias for <B>pthread_mutexattr_gettype</B>.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P><B>pthread_mutexattr_init</B>, <B>pthread_mutexattr_destroy</B>
+and <B>pthread_mutexattr_gettype</B> always return 0.
+</P>
+<P><B>pthread_mutexattr_settype</B> returns 0 on success and a
+non-zero error code on error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>On error, <B>pthread_mutexattr_settype</B> returns the following
+error code:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ <I>type</I> is none of:<BR><B>PTHREAD_MUTEX_NORMAL</B>,
+ <B>PTHREAD_MUTEX_FAST_NP</B>,<BR><B>PTHREAD_MUTEX_RECURSIVE</B>,
+ <B>PTHREAD_MUTEX_RECURSIVE_NP,<BR>PTHREAD_MUTEX_ERRORCHECK</B>,
+ <B>PTHREAD_MUTEX_ERRORCHECK_NP</B>
+ </DD></DL>
+<H2>
+<A HREF="#toc5" NAME="sect5">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
+<P><A HREF="pthread_mutex_init.html"><B>pthread_mutex_init</B>(3)</A>
+, <A HREF="pthread_mutex_lock.html"><B>pthread_mutex_lock</B>(3)</A>
+, <A HREF="pthread_mutex_unlock.html"><B>pthread_mutex_unlock</B>(3)</A>
+.
+</P>
+<H2><A HREF="#toc7" NAME="sect7"><U><FONT COLOR="#000080">Notes</FONT></U></A></H2>
+<P>For speed, <B>Pthreads-w32</B> never checks the thread ownership
+of mutexes of type <B>PTHREAD_MUTEX_NORMAL</B> (or
+<B>PTHREAD_MUTEX_FAST_NP</B>) when performing operations on the
+mutex. It is therefore possible for one thread to lock such a mutex
+and another to unlock it.</P>
+<P><SPAN STYLE="font-weight: medium">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.</SPAN></P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">See
+ Also</A></P>
+ <LI><P><A HREF="#sect7" NAME="toc7">Notes</A></P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_mutexattr_setpshared.html b/pthreads/manual/pthread_mutexattr_setpshared.html
new file mode 100644
index 000000000..25bf9f60b
--- /dev/null
+++ b/pthreads/manual/pthread_mutexattr_setpshared.html
@@ -0,0 +1,151 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_MUTEXATTR_GETPSHARED&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;23480600">
+ <META NAME="CHANGED" CONTENT="20050505;18381800">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_mutexattr_getpshared, pthread_mutexattr_setpshared - get
+and set the process-shared attribute
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_mutexattr_getpshared(const pthread_mutexattr_t *
+restrict</B> <I>attr</I><B>, int *restrict</B> <I>pshared</I><B>);
+<BR>int pthread_mutexattr_setpshared(pthread_mutexattr_t *</B><I>attr</I><B>,
+int</B> <I>pshared</I><B>); </B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_mutexattr_getpshared</B> function shall obtain the
+value of the <I>process-shared</I> attribute from the attributes
+object referenced by <I>attr</I>. The <B>pthread_mutexattr_setpshared</B>
+function shall set the <I>process-shared</I> attribute in an
+initialized attributes object referenced by <I>attr</I>.
+</P>
+<P>The <I>process-shared</I> attribute is set to
+<B>PTHREAD_PROCESS_SHARED</B> to permit a mutex to be operated upon
+by any thread that has access to the memory where the mutex is
+allocated, even if the mutex is allocated in memory that is shared by
+multiple processes. If the <I>process-shared</I> attribute is
+<B>PTHREAD_PROCESS_PRIVATE</B>, the mutex shall only be operated upon
+by threads created within the same process as the thread that
+initialized the mutex; if threads of differing processes attempt to
+operate on such a mutex, the behavior is undefined. The default value
+of the attribute shall be <B>PTHREAD_PROCESS_PRIVATE</B>.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_THREAD_PROCESS_SHARED</B> in
+pthread.h as -1 to indicate that these routines are implemented but
+the process shared option is not supported.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>Upon successful completion, <B>pthread_mutexattr_setpshared</B>
+shall return zero; otherwise, an error number shall be returned to
+indicate the error.
+</P>
+<P>Upon successful completion, <B>pthread_mutexattr_getpshared</B>
+shall return zero and store the value of the <I>process-shared</I>
+attribute of <I>attr</I> into the object referenced by the <I>pshared</I>
+parameter. Otherwise, an error number shall be returned to indicate
+the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_mutexattr_getpshared</B> and
+<B>pthread_mutexattr_setpshared</B> functions may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>attr</I> is invalid.
+ </DD></DL>
+<P>
+The <B>pthread_mutexattr_setpshared</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The new value specified for the attribute is outside the range of
+ legal values for that attribute.
+ </DD><DT>
+ <B>ENOTSUP</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The new value specified for the attribute is PTHREAD_PROCESS_SHARED.
+ </DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_cond_init.html"><B>pthread_cond_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A> <B>,</B>
+<A HREF="pthread_mutex_init.html"><B>pthread_mutex_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_mutexattr_init.html"><B>pthread_mutexattr_destroy</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_num_processors_np.html b/pthreads/manual/pthread_num_processors_np.html
new file mode 100644
index 000000000..050941065
--- /dev/null
+++ b/pthreads/manual/pthread_num_processors_np.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_NUM_PROCESSORS_NP manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;322600">
+ <META NAME="CHANGED" CONTENT="20050505;21514100">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P STYLE="font-weight: medium">pthread_num_processors_np ā€“ get the
+number of processors (CPUs) in use by the process</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthread_num_processors_np(void);</B></P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P><B>pthread_num_processors_np </B>returns the number of processors
+in the system. This implementation actually returns the number of
+processors available to the process, which can be a lower number than
+the system's number, depending on the process's affinity mask.</P>
+<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
+<P>None.</P>
+<H2><A HREF="#toc4" NAME="sect4"><FONT COLOR="#000080">Return Value</FONT></A></H2>
+<P><B>pthread_num_processors_np</B> returns the number of processors
+currently available to the process.</P>
+<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
+<P>None.</P>
+<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
+<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
+ </P>
+ <LI><P><A HREF="#sect6" NAME="toc6">Author</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_once.html b/pthreads/manual/pthread_once.html
new file mode 100644
index 000000000..856fb8653
--- /dev/null
+++ b/pthreads/manual/pthread_once.html
@@ -0,0 +1,83 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_ONCE(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;322600">
+ <META NAME="CHANGED" CONTENT="20050603;463100">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_once - once-only initialization
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>pthread_once_t </B><I>once_control</I> <B>= PTHREAD_ONCE_INIT;</B>
+</P>
+<P><B>int pthread_once(pthread_once_t *</B><I>once_control</I><B>,
+void (*</B><I>init_routine</I><B>) (void));</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The purpose of <B>pthread_once</B> is to ensure that a piece of
+initialization code is executed at most once. The <I>once_control</I>
+argument points to a static or extern variable statically initialized
+to <B>PTHREAD_ONCE_INIT</B>.
+</P>
+<P>The first time <B>pthread_once</B> is called with a given
+<I>once_control</I> argument, it calls <I>init_routine</I> with no
+argument and changes the value of the <I>once_control</I> variable to
+record that initialization has been performed. Subsequent calls to
+<B>pthread_once</B> with the same <B>once_control</B> argument do
+nothing.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
+<P>While <B>pthread_once</B> is not a cancellation point,
+<I>init_routine</I> can be. The effect on <I>once_control</I> of a
+cancellation inside the <I>init_routine</I> is to leave it as if
+<B>pthread_once</B> had not been called by the cancelled thread.</P>
+<H2><A HREF="#toc4" NAME="sect4">Return Value</A></H2>
+<P STYLE="text-decoration: none"><FONT COLOR="#000000"><B>pthread_once</B>
+returns 0 on success, or an error code on failure.</FONT></P>
+<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
+<P>The <B>pthread_once</B> function returns the following error code
+on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT></DL>
+</DL>
+<P STYLE="margin-left: 2cm">
+The once_control or init_routine parameter is NULL.</P>
+<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
+ </P>
+ <LI><P><A HREF="#sect6" NAME="toc6">Author</A>
+ </P>
+</UL>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/pthreads/manual/pthread_rwlock_init.html b/pthreads/manual/pthread_rwlock_init.html
new file mode 100644
index 000000000..530df93d4
--- /dev/null
+++ b/pthreads/manual/pthread_rwlock_init.html
@@ -0,0 +1,193 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_RWLOCK_DESTROY&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;10211800">
+ <META NAME="CHANGED" CONTENT="20050505;18563400">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_rwlock_destroy, pthread_rwlock_init - destroy and
+initialize a read-write lock object
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>pthread_wrlock_t </B><I>rwlock</I> <B>=
+PTHREAD_RWLOCK_INITIALIZER;</B></P>
+<P><B>int pthread_rwlock_destroy(pthread_rwlock_t *</B><I>rwlock</I><B>);
+<BR>int pthread_rwlock_init(pthread_rwlock_t *restrict</B> <I>rwlock</I><B>,
+const pthread_rwlockattr_t *restrict</B> <I>attr</I><B>); </B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_rwlock_destroy</B> function shall destroy the
+read-write lock object referenced by <I>rwlock</I> and release any
+resources used by the lock. The effect of subsequent use of the lock
+is undefined until the lock is reinitialized by another call to
+<B>pthread_rwlock_init</B>. An implementation may cause
+<B>pthread_rwlock_destroy</B> to set the object referenced by <I>rwlock</I>
+to an invalid value. Results are undefined if <B>pthread_rwlock_destroy</B>
+is called when any thread holds <I>rwlock</I>. Attempting to destroy
+an uninitialized read-write lock results in undefined behavior.
+</P>
+<P>The <B>pthread_rwlock_init</B> function shall allocate any
+resources required to use the read-write lock referenced by <I>rwlock</I>
+and initializes the lock to an unlocked state with attributes
+referenced by <I>attr</I>. If <I>attr</I> is NULL, the default
+read-write lock attributes shall be used; the effect is the same as
+passing the address of a default read-write lock attributes object.
+Once initialized, the lock can be used any number of times without
+being reinitialized. Results are undefined if <B>pthread_rwlock_init</B>
+is called specifying an already initialized read-write lock. Results
+are undefined if a read-write lock is used without first being
+initialized.
+</P>
+<P>If the <B>pthread_rwlock_init</B> function fails, <I>rwlock</I>
+shall not be initialized and the contents of <I>rwlock</I> are
+undefined.
+</P>
+<P><B>Pthreads-w32</B> supports statically initialized <I>rwlock</I>
+objects using <B>PTHREAD_RWLOCK_INITIALIZER</B>. <SPAN STYLE="font-weight: medium">
+An application should still call <B>pthread_rwlock_destroy</B> at
+some point to ensure that any resources consumed by the read/write
+lock are released.</SPAN></P>
+<P>Only the object referenced by <I>rwlock</I> may be used for
+performing synchronization. The result of referring to copies of that
+object in calls to <B>pthread_rwlock_destroy</B> ,
+<B>pthread_rwlock_rdlock</B> , <B>pthread_rwlock_timedrdlock</B> ,
+<B>pthread_rwlock_timedwrlock</B> , <B>pthread_rwlock_tryrdlock</B> ,
+<B>pthread_rwlock_trywrlock</B> , <B>pthread_rwlock_unlock</B> , or
+<B>pthread_rwlock_wrlock</B> is undefined.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
+pthread.h as 200112L to indicate that the reader/writer routines are
+implemented and may be used.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>If successful, the <B>pthread_rwlock_destroy</B> and
+<B>pthread_rwlock_init</B> functions shall return zero; otherwise, an
+error number shall be returned to indicate the error.
+</P>
+<P>The [EBUSY] and [EINVAL] error checks, if implemented, act as if
+they were performed immediately at the beginning of processing for
+the function and caused an error return prior to modifying the state
+of the read-write lock specified by <I>rwlock</I>.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_rwlock_destroy</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EBUSY</B>
+ </DT><DD>
+ The implementation has detected an attempt to destroy the object
+ referenced by <I>rwlock</I> while it is locked.
+ </DD><DT>
+ <B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>rwlock</I> is invalid.
+ </DD></DL>
+<P>
+The <B>pthread_rwlock_init</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>EAGAIN</B>
+ </DT><DD>
+ The system lacked the necessary resources (other than memory) to
+ initialize another read-write lock.
+ </DD><DT>
+ <B>ENOMEM</B>
+ </DT><DD>
+ Insufficient memory exists to initialize the read-write lock.
+ </DD><DD STYLE="margin-left: 0cm; margin-bottom: 0.5cm">
+ <BR><BR>
+ </DD></DL>
+<P>
+The <B>pthread_rwlock_init</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>attr</I> is invalid.
+ </DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>Applications using these and related read-write lock functions may
+be subject to priority inversion, as discussed in the Base
+Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001, Section 3.285,
+Priority Inversion.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_timedrdlock.html"><B>pthread_rwlock_timedrdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_timedwrlock.html"><B>pthread_rwlock_timedwrlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_tryrdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_trywrlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_rwlock_rdlock.html b/pthreads/manual/pthread_rwlock_rdlock.html
new file mode 100644
index 000000000..3b63f255c
--- /dev/null
+++ b/pthreads/manual/pthread_rwlock_rdlock.html
@@ -0,0 +1,168 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_RWLOCK_RDLOCK&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;10352600">
+ <META NAME="CHANGED" CONTENT="20050505;12554200">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_rwlock_rdlock, pthread_rwlock_tryrdlock - lock a
+read-write lock object for reading
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_rwlock_rdlock(pthread_rwlock_t <I>*</I></B><I>rwlock</I><B>);
+<BR></B>i<B>nt pthread_rwlock_tryrdlock(pthread_rwlock_t <I>*</I></B><I>rwlock</I><B>);
+</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_rwlock_rdlock</B> function shall apply a read lock
+to the read-write lock referenced by <I>rwlock</I>. The calling
+thread acquires the read lock if a writer does not hold the lock and
+there are no writers blocked on the lock.
+</P>
+<P><B>Pthreads-win32</B> does not prefer either writers or readers in
+acquiring the lock ā€“ all threads enter a single prioritised FIFO
+queue. While this may not be optimally efficient for some
+applications, it does ensure that one type does not starve the other.</P>
+<P>A thread may hold multiple concurrent read locks on <I>rwlock</I>
+(that is, successfully call the <B>pthread_rwlock_rdlock</B> function
+<I>n</I> times). If so, the application shall ensure that the thread
+performs matching unlocks (that is, it calls the
+<A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B>(3)</A>
+function <I>n</I> times).
+</P>
+<P>The <B>pthread_rwlock_tryrdlock</B> function shall apply a read
+lock as in the <B>pthread_rwlock_rdlock</B> function, with the
+exception that the function shall fail if the equivalent
+<B>pthread_rwlock_rdlock</B> call would have blocked the calling
+thread. In no case shall the <B>pthread_rwlock_tryrdlock</B> function
+ever block; it always either acquires the lock or fails and returns
+immediately.
+</P>
+<P>Results are undefined if any of these functions are called with an
+uninitialized read-write lock.
+</P>
+<P><B>Pthreads-w32</B> does not detect deadlock if the thread already
+owns the lock for writing.</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
+pthread.h as 200112L to indicate that the reader/writer routines are
+implemented and may be used.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>If successful, the <B>pthread_rwlock_rdlock</B> function shall
+return zero; otherwise, an error number shall be returned to indicate
+the error.
+</P>
+<P>The <B>pthread_rwlock_tryrdlock</B> function shall return zero if
+the lock for reading on the read-write lock object referenced by
+<I>rwlock</I> is acquired. Otherwise, an error number shall be
+returned to indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_rwlock_tryrdlock</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>EBUSY</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The read-write lock could not be acquired for reading because a
+ writer holds the lock or a writer with the appropriate priority was
+ blocked on it.
+ </DD></DL>
+<P>
+The <B>pthread_rwlock_rdlock</B> and <B>pthread_rwlock_tryrdlock</B>
+functions may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD>
+ The value specified by <I>rwlock</I> does not refer to an
+ initialized read-write lock object.
+ </DD><DT>
+ <B>EAGAIN</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The read lock could not be acquired because the maximum number of
+ read locks for <I>rwlock</I> has been exceeded.
+ </DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>Applications using these functions may be subject to priority
+inversion, as discussed in the Base Definitions volume of
+IEEE&nbsp;Std&nbsp;1003.1-2001, Section 3.285, Priority Inversion.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_timedrdlock.html"><B>pthread_rwlock_timedrdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_timedwrlock.html"><B>pthread_rwlock_timedwrlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_trywrlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_rwlock_timedrdlock.html b/pthreads/manual/pthread_rwlock_timedrdlock.html
new file mode 100644
index 000000000..1b9ca630f
--- /dev/null
+++ b/pthreads/manual/pthread_rwlock_timedrdlock.html
@@ -0,0 +1,156 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_RWLOCK_TIMEDRDLOCK&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;11101700">
+ <META NAME="CHANGED" CONTENT="20050505;12560000">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_rwlock_timedrdlock - lock a read-write lock for reading
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; <BR></B>#include &lt;time.h&gt;
+</P>
+<P><B>int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict</B>
+<I>rwlock</I><B>, const struct timespec *restrict</B> <I>abs_timeout</I><B>);
+</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_rwlock_timedrdlock</B> function shall apply a read
+lock to the read-write lock referenced by <I>rwlock</I> as in the
+<A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B>(3)</A>
+function. However, if the lock cannot be acquired without waiting for
+other threads to unlock the lock, this wait shall be terminated when
+the specified timeout expires. The timeout shall expire when the
+absolute time specified by <I>abs_timeout</I> passes, as measured by
+the clock on which timeouts are based (that is, when the value of
+that clock equals or exceeds <I>abs_timeout</I>), or if the absolute
+time specified by <I>abs_timeout</I> has already been passed at the
+time of the call.
+</P>
+<P>The <B>timespec</B> data type is defined in the <I>&lt;time.h&gt;</I>
+header. Under no circumstances shall the function fail with a timeout
+if the lock can be acquired immediately. The validity of the
+<I>abs_timeout</I> parameter need not be checked if the lock can be
+immediately acquired.
+</P>
+<P>The calling thread may deadlock if at the time the call is made it
+holds a write lock on <I>rwlock</I>. The results are undefined if
+this function is called with an uninitialized read-write lock.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
+pthread.h as 200112L to indicate that the reader/writer routines are
+implemented and may be used.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>The <B>pthread_rwlock_timedrdlock</B> function shall return zero
+if the lock for reading on the read-write lock object referenced by
+<I>rwlock</I> is acquired. Otherwise, an error number shall be
+returned to indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_rwlock_timedrdlock</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>ETIMEDOUT</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The lock could not be acquired before the specified timeout expired.
+ </DD></DL>
+<P>
+The <B>pthread_rwlock_timedrdlock</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EAGAIN</B>
+ </DT><DD>
+ The read lock could not be acquired because the maximum number of
+ read locks for lock would be exceeded.
+ </DD><DT>
+ <B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>rwlock</I> does not refer to an
+ initialized read-write lock object, or the <I>abs_timeout</I>
+ nanosecond value is less than zero or greater than or equal to 1000
+ million.
+ </DD></DL>
+<P>
+This function shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>Applications using this function may be subject to priority
+inversion, as discussed in the Base Definitions volume of
+IEEE&nbsp;Std&nbsp;1003.1-2001, Section 3.285, Priority Inversion.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_timedwrlock.html"><B>pthread_rwlock_timedwrlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_tryrdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_trywrlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>, <I>&lt;time.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_rwlock_timedwrlock.html b/pthreads/manual/pthread_rwlock_timedwrlock.html
new file mode 100644
index 000000000..0213bab40
--- /dev/null
+++ b/pthreads/manual/pthread_rwlock_timedwrlock.html
@@ -0,0 +1,150 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_RWLOCK_TIMEDWRLOCK&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;11172800">
+ <META NAME="CHANGED" CONTENT="20050505;12561600">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_rwlock_timedwrlock - lock a read-write lock for writing
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; <BR></B>#include &lt;time.h&gt;
+</P>
+<P><B>int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict</B>
+<I>rwlock</I><B>, const struct timespec *restrict</B> <I>abs_timeout</I><B>);
+</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_rwlock_timedwrlock</B> function shall apply a write
+lock to the read-write lock referenced by <I>rwlock</I> as in the
+<A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B>(3)</A>
+function. However, if the lock cannot be acquired without waiting for
+other threads to unlock the lock, this wait shall be terminated when
+the specified timeout expires. The timeout shall expire when the
+absolute time specified by <I>abs_timeout</I> passes, as measured by
+the clock on which timeouts are based (that is, when the value of
+that clock equals or exceeds <I>abs_timeout</I>), or if the absolute
+time specified by <I>abs_timeout</I> has already been passed at the
+time of the call.
+</P>
+<P>The <B>timespec</B> data type is defined in the <I>&lt;time.h&gt;</I>
+header. Under no circumstances shall the function fail with a timeout
+if the lock can be acquired immediately. The validity of the
+<I>abs_timeout</I> parameter need not be checked if the lock can be
+immediately acquired.
+</P>
+<P>The calling thread may deadlock if at the time the call is made it
+holds the read-write lock. The results are undefined if this function
+is called with an uninitialized read-write lock.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
+pthread.h as 200112L to indicate that the reader/writer routines are
+implemented and may be used.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>The <B>pthread_rwlock_timedwrlock</B> function shall return zero
+if the lock for writing on the read-write lock object referenced by
+<I>rwlock</I> is acquired. Otherwise, an error number shall be
+returned to indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_rwlock_timedwrlock</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>ETIMEDOUT</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The lock could not be acquired before the specified timeout expired.
+ </DD></DL>
+<P>
+The <B>pthread_rwlock_timedwrlock</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by rwlock does not refer to an initialized
+ read-write lock object, or the <I>abs_timeout</I> nanosecond value
+ is less than zero or greater than or equal to 1000 million.
+ </DD></DL>
+<P>
+This function shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>Applications using this function may be subject to priority
+inversion, as discussed in the Base Definitions volume of
+IEEE&nbsp;Std&nbsp;1003.1-2001, Section 3.285, Priority Inversion.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_timedrdlock.html"><B>pthread_rwlock_timedrdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_tryrdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_trywrlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>, <I>&lt;time.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_rwlock_unlock.html b/pthreads/manual/pthread_rwlock_unlock.html
new file mode 100644
index 000000000..09725cc3e
--- /dev/null
+++ b/pthreads/manual/pthread_rwlock_unlock.html
@@ -0,0 +1,141 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_RWLOCK_UNLOCK&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;11291100">
+ <META NAME="CHANGED" CONTENT="20050505;12562700">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_rwlock_unlock - unlock a read-write lock object
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P>in<B>t pthread_rwlock_unlock(pthread_rwlock_t <I>*</I></B><I>rwlock</I><B>);
+</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_rwlock_unlock</B> function shall release a lock
+held on the read-write lock object referenced by <I>rwlock</I>.
+Results are undefined if the read-write lock <I>rwlock</I> is not
+held by the calling thread.
+</P>
+<P>If this function is called to release a read lock from the
+read-write lock object and there are other read locks currently held
+on this read-write lock object, the read-write lock object remains in
+the read locked state. If this function releases the last read lock
+for this read-write lock object, the read-write lock object shall be
+put in the unlocked state with no owners.
+</P>
+<P>If this function is called to release a write lock for this
+read-write lock object, the read-write lock object shall be put in
+the unlocked state.
+</P>
+<P><B>Pthreads-win32</B> does not prefer either writers or readers in
+acquiring the lock ā€“ all threads enter a single prioritised FIFO
+queue. While this may not be optimally efficient for some
+applications, it does ensure that one type does not starve the other.</P>
+<P>Results are undefined if any of these functions are called with an
+uninitialized read-write lock.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
+pthread.h as 200112L to indicate that the reader/writer routines are
+implemented and may be used.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>If successful, the <B>pthread_rwlock_unlock</B> function shall
+return zero; otherwise, an error number shall be returned to indicate
+the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_rwlock_unlock</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD>
+ The value specified by <I>rwlock</I> does not refer to an
+ initialized read-write lock object.
+ </DD><DD STYLE="margin-left: 0cm; margin-bottom: 0.5cm">
+ <BR><BR>
+ </DD></DL>
+<P>
+The <B>pthread_rwlock_unlock</B> function shall not return an error
+code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_timedrdlock.html"><B>pthread_rwlock_timedrdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_timedwrlock.html"><B>pthread_rwlock_timedwrlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_tryrdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_trywrlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_wrlock.html"><B>pthread_rwlock_wrlock</B>(3)</A>
+, the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_rwlock_wrlock.html b/pthreads/manual/pthread_rwlock_wrlock.html
new file mode 100644
index 000000000..02b3a19ea
--- /dev/null
+++ b/pthreads/manual/pthread_rwlock_wrlock.html
@@ -0,0 +1,153 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_RWLOCK_TRYWRLOCK&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;11221900">
+ <META NAME="CHANGED" CONTENT="20050505;12563800">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_rwlock_trywrlock, pthread_rwlock_wrlock - lock a
+read-write lock object for writing
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_rwlock_trywrlock(pthread_rwlock_t <I>*</I></B><I>rwlock</I><B>);
+<BR>int pthread_rwlock_wrlock(pthread_rwlock_t <I>*</I></B><I>rwlock</I><B>);
+</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_rwlock_trywrlock</B> function shall apply a write
+lock like the <B>pthread_rwlock_wrlock</B> function, with the
+exception that the function shall fail if any thread currently holds
+<I>rwlock</I> (for reading or writing).
+</P>
+<P>The <B>pthread_rwlock_wrlock</B> function shall apply a write lock
+to the read-write lock referenced by <I>rwlock</I>. The calling
+thread acquires the write lock if no other thread (reader or writer)
+holds the read-write lock <I>rwlock</I>. Otherwise, the thread shall
+block until it can acquire the lock. The calling thread may deadlock
+if at the time the call is made it holds the read-write lock (whether
+a read or write lock).
+</P>
+<P><B>Pthreads-win32</B> does not prefer either writers or readers in
+acquiring the lock ā€“ all threads enter a single prioritised FIFO
+queue. While this may not be optimally efficient for some
+applications, it does ensure that one type does not starve the other.</P>
+<P>Results are undefined if any of these functions are called with an
+uninitialized read-write lock.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
+pthread.h as 200112L to indicate that the reader/writer routines are
+implemented and may be used.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>The <B>pthread_rwlock_trywrlock</B> function shall return zero if
+the lock for writing on the read-write lock object referenced by
+<I>rwlock</I> is acquired. Otherwise, an error number shall be
+returned to indicate the error.
+</P>
+<P>If successful, the <B>pthread_rwlock_wrlock</B> function shall
+return zero; otherwise, an error number shall be returned to indicate
+the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_rwlock_trywrlock</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>EBUSY</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The read-write lock could not be acquired for writing because it was
+ already locked for reading or writing.
+ </DD></DL>
+<P>
+The <B>pthread_rwlock_trywrlock</B> and <B>pthread_rwlock_wrlock</B>
+functions may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>rwlock</I> does not refer to an
+ initialized read-write lock object.
+ </DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>Applications using these functions may be subject to priority
+inversion, as discussed in the Base Definitions volume of
+IEEE&nbsp;Std&nbsp;1003.1-2001, Section 3.285, Priority Inversion.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_rdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_timedrdlock.html"><B>pthread_rwlock_timedrdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_timedwrlock.html"><B>pthread_rwlock_timedwrlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_rdlock.html"><B>pthread_rwlock_tryrdlock</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlock_unlock.html"><B>pthread_rwlock_unlock</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_rwlockattr_init.html b/pthreads/manual/pthread_rwlockattr_init.html
new file mode 100644
index 000000000..67da876cc
--- /dev/null
+++ b/pthreads/manual/pthread_rwlockattr_init.html
@@ -0,0 +1,141 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_RWLOCKATTR_DESTROY&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;504000">
+ <META NAME="CHANGED" CONTENT="20050505;18474200">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_rwlockattr_destroy, pthread_rwlockattr_init - destroy and
+initialize the read-write lock attributes object
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_rwlockattr_destroy(pthread_rwlockattr_t <I>*</I></B><I>attr</I><B>);
+<BR>int pthread_rwlockattr_init(pthread_rwlockattr_t <I>*</I></B><I>attr</I><B>);
+</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_rwlockattr_destroy</B> function shall destroy a
+read-write lock attributes object. A destroyed <I>attr</I> attributes
+object can be reinitialized using <B>pthread_rwlockattr_init</B> ;
+the results of otherwise referencing the object after it has been
+destroyed are undefined. An implementation may cause
+<B>pthread_rwlockattr_destroy</B> to set the object referenced by
+<I>attr</I> to an invalid value.
+</P>
+<P>The <B>pthread_rwlockattr_init</B> function shall initialize a
+read-write lock attributes object <I>attr</I> with the default value
+for all of the attributes defined by the implementation.
+</P>
+<P>Results are undefined if <B>pthread_rwlockattr_init</B> is called
+specifying an already initialized <I>attr</I> attributes object.
+</P>
+<P>After a read-write lock attributes object has been used to
+initialize one or more read-write locks, any function affecting the
+attributes object (including destruction) shall not affect any
+previously initialized read-write locks.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
+pthread.h as 200112L to indicate that the reader/writer routines are
+implemented and may be used.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>If successful, the <B>pthread_rwlockattr_destroy</B> and
+<B>pthread_rwlockattr_init</B> functions shall return zero;
+otherwise, an error number shall be returned to indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_rwlockattr_destroy</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>attr</I> is invalid.
+ </DD></DL>
+<P>
+The <B>pthread_rwlockattr_init</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>ENOMEM</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ Insufficient memory exists to initialize the read-write lock
+ attributes object.
+ </DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlockattr_setpshared.html"><B>pthread_rwlockattr_getpshared</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlockattr_setpshared.html"><B>pthread_rwlockattr_setpshared</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_rwlockattr_setpshared.html b/pthreads/manual/pthread_rwlockattr_setpshared.html
new file mode 100644
index 000000000..9db6f4cdc
--- /dev/null
+++ b/pthreads/manual/pthread_rwlockattr_setpshared.html
@@ -0,0 +1,160 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_RWLOCKATTR_GETPSHARED&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;10124400">
+ <META NAME="CHANGED" CONTENT="20050505;12572100">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_rwlockattr_getpshared, pthread_rwlockattr_setpshared - get
+and set the process-shared attribute of the read-write lock
+attributes object
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *
+restrict </B><I>attr</I><B>, int *restrict</B> <I>pshared</I><B>);
+<BR>int pthread_rwlockattr_setpshared(pthread_rwlockattr_t <I>*</I></B><I>attr</I><B>,
+int</B> <I>pshared</I><B>); </B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_rwlockattr_getpshared</B> function shall obtain the
+value of the <I>process-shared</I> attribute from the initialized
+attributes object referenced by <I>attr</I>. The
+<B>pthread_rwlockattr_setpshared</B> function shall set the
+<I>process-shared</I> attribute in an initialized attributes object
+referenced by <I>attr</I>.
+</P>
+<P>The <I>process-shared</I> attribute shall be set to
+<B>PTHREAD_PROCESS_SHARED</B> to permit a read-write lock to be
+operated upon by any thread that has access to the memory where the
+read-write lock is allocated, even if the read-write lock is
+allocated in memory that is shared by multiple processes. If the
+<I>process-shared</I> attribute is <B>PTHREAD_PROCESS_PRIVATE</B>,
+the read-write lock shall only be operated upon by threads created
+within the same process as the thread that initialized the read-write
+lock; if threads of differing processes attempt to operate on such a
+read-write lock, the behavior is undefined. The default value of the
+<I>process-shared</I> attribute shall be <B>PTHREAD_PROCESS_PRIVATE</B>.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_THREAD_PROCESS_SHARED</B> in
+pthread.h as -1 to indicate that these routines are implemented but
+they do not support the process shared option.</P>
+<P>Additional attributes, their default values, and the names of the
+associated functions to get and set those attribute values are
+implementation-defined.
+</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_READER_WRITER_LOCKS</B> in
+pthread.h as 200112L to indicate that the reader/writer routines are
+implemented and may be used.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>Upon successful completion, the <B>pthread_rwlockattr_getpshared</B>
+function shall return zero and store the value of the <I>process-shared</I>
+attribute of <I>attr</I> into the object referenced by the <I>pshared</I>
+parameter. Otherwise, an error number shall be returned to indicate
+the error.
+</P>
+<P>If successful, the <B>pthread_rwlockattr_setpshared</B> function
+shall return zero; otherwise, an error number shall be returned to
+indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_rwlockattr_getpshared</B> and
+<B>pthread_rwlockattr_setpshared</B> functions may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>attr</I> is invalid.
+ </DD></DL>
+<P>
+The <B>pthread_rwlockattr_setpshared</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The new value specified for the attribute is outside the range of
+ legal values for that attribute.
+ </DD><DT>
+ <B>ENOTSUP</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The new value specified for the attribute is <B>PTHREAD_PROCESS_SHARED</B>.
+ </DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_rwlock_init.html"><B>pthread_rwlock_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlockattr_init.html"><B>pthread_rwlockattr_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_rwlockattr_init.html"><B>pthread_rwlockattr_init</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_self.html b/pthreads/manual/pthread_self.html
new file mode 100644
index 000000000..82e16eaa7
--- /dev/null
+++ b/pthreads/manual/pthread_self.html
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_SELF(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;11361600">
+ <META NAME="CHANGED" CONTENT="20050505;11575700">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_self - return identifier of current thread
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>pthread_t pthread_self(void);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P><B>pthread_self</B> return the thread identifier for the calling
+thread.
+</P>
+<P><B>Pthreads-w32</B> also provides support for <B>Win32</B> native
+threads to interact with POSIX threads through the pthreads API.
+Whereas all threads created via a call to pthread_create have a POSIX
+thread ID and thread state, the library ensures that any Win32 native
+threads that interact through the Pthreads API also generate a POSIX
+thread ID and thread state when and if necessary. This provides full
+<SPAN LANG="en-GB">reciprocity</SPAN> between Win32 and POSIX
+threads. Win32 native threads that generate a POSIX thread ID and
+state are treated by the library as having been created with the
+<B>PTHREAD_CREATE_DETACHED</B> attribute.</P>
+<P>Any Win32 native thread may call <B>pthread_self</B> directly to
+return it's POSIX thread identifier. The ID and state will be
+generated if it does not already exist. Win32 native threads do not
+need to call <B>pthread_self</B> before calling Pthreads-w32 routines
+unless that routine requires a pthread_t parameter.</P>
+<H2><A HREF="#toc3" NAME="sect3">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc4" NAME="sect4">See Also</A></H2>
+<P><A HREF="pthread_equal.html"><B>pthread_equal</B>(3)</A> ,
+<A HREF="pthread_join.html"><B>pthread_join</B>(3)</A> ,
+<A HREF="pthread_detach.html"><B>pthread_detach</B>(3)</A> ,
+<A HREF="pthread_setschedparam.html"><B>pthread_setschedparam</B>(3)</A>
+, <A HREF="pthread_setschedparam.html"><B>pthread_getschedparam</B>(3)</A>
+.
+</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Author</A>
+ </P>
+ <LI><P><A HREF="#sect4" NAME="toc4">See Also</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_setcancelstate.html b/pthreads/manual/pthread_setcancelstate.html
new file mode 100644
index 000000000..3ce65c44d
--- /dev/null
+++ b/pthreads/manual/pthread_setcancelstate.html
@@ -0,0 +1,207 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_CANCEL(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;12090500">
+ <META NAME="CHANGED" CONTENT="20050504;16361300">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_cancel, pthread_setcancelstate, pthread_setcanceltype,
+pthread_testcancel - thread cancellation
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthread_cancel(pthread_t </B><I>thread</I><B>);</B>
+</P>
+<P><B>int pthread_setcancelstate(int </B><I>state</I><B>, int
+*</B><I>oldstate</I><B>);</B>
+</P>
+<P><B>int pthread_setcanceltype(int </B><I>type</I><B>, int
+*</B><I>oldtype</I><B>);</B>
+</P>
+<P><B>void pthread_testcancel(void);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>Cancellation is the mechanism by which a thread can terminate the
+execution of another thread. More precisely, a thread can send a
+cancellation request to another thread. Depending on its settings,
+the target thread can then either ignore the request, honor it
+immediately, or defer it until it reaches a cancellation point.
+</P>
+<P>When a thread eventually honors a cancellation request, it
+performs as if <B>pthread_exit(PTHREAD_CANCELED)</B> has been called
+at that point: all cleanup handlers are executed in reverse order,
+destructor functions for thread-specific data are called, and finally
+the thread stops executing with the return value <B>PTHREAD_CANCELED</B>.
+See <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> for more
+information.
+</P>
+<P><B>pthread_cancel</B> sends a cancellation request to the thread
+denoted by the <I>thread</I> argument.
+</P>
+<P><B>pthread_setcancelstate</B> changes the cancellation state for
+the calling thread -- that is, whether cancellation requests are
+ignored or not. The <I>state</I> argument is the new cancellation
+state: either <B>PTHREAD_CANCEL_ENABLE</B> to enable cancellation, or
+<B>PTHREAD_CANCEL_DISABLE</B> to disable cancellation (cancellation
+requests are ignored). If <I>oldstate</I> is not <B>NULL</B>, the
+previous cancellation state is stored in the location pointed to by
+<I>oldstate</I>, and can thus be restored later by another call to
+<B>pthread_setcancelstate</B>.
+</P>
+<P><B>pthread_setcanceltype</B> changes the type of responses to
+cancellation requests for the calling thread: asynchronous
+(immediate) or deferred. The <I>type</I> argument is the new
+cancellation type: either <B>PTHREAD_CANCEL_ASYNCHRONOUS</B> to
+cancel the calling thread as soon as the cancellation request is
+received, or <B>PTHREAD_CANCEL_DEFERRED</B> to keep the cancellation
+request pending until the next cancellation point. If <I>oldtype</I>
+is not <B>NULL</B>, the previous cancellation state is stored in the
+location pointed to by <I>oldtype</I>, and can thus be restored later
+by another call to <B>pthread_setcanceltype</B>.
+</P>
+<P><B>Pthreads-w32</B> provides two levels of support for
+<B>PTHREAD_CANCEL_ASYNCHRONOUS</B>: full and partial. Full support
+requires an additional DLL and driver be installed on the Windows
+system (see the See Also section below) that allows blocked threads
+to be cancelled immediately. Partial support means that the target
+thread will not cancel until it resumes execution naturally. Partial
+support is provided if either the DLL or the driver are not
+automatically detected by the pthreads-w32 library at run-time.</P>
+<P>Threads are always created by <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A>
+with cancellation enabled and deferred. That is, the initial
+cancellation state is <B>PTHREAD_CANCEL_ENABLE</B> and the initial
+type is <B>PTHREAD_CANCEL_DEFERRED</B>.
+</P>
+<P>Cancellation points are those points in the program execution
+where a test for pending cancellation requests is performed and
+cancellation is executed if positive. The following POSIX threads
+functions are cancellation points:
+</P>
+<P><A HREF="pthread_join.html"><B>pthread_join</B>(3)</A>
+<BR><A HREF="pthread_cond_wait.html"><B>pthread_cond_wait</B>(3)</A>
+<BR><A HREF="pthread_cond_timedwait.html"><B>pthread_cond_timedwait</B>(3)</A>
+<BR><A HREF="pthread_testcancel.html"><B>pthread_testcancel</B>(3)</A>
+<BR><A HREF="sem_wait.html"><B>sem_wait</B>(3)</A> <BR><A HREF="sem_timedwait.html"><B>sem_timedwait</B>(3)</A>
+<BR><A HREF="sigwait.html"><B>sigwait</B>(3)</A> (not supported under
+<B>Pthreads-w32</B>)</P>
+<P><B>Pthreads-w32</B> provides two functions to enable additional
+cancellation points to be created in user functions that block on
+Win32 HANDLEs:</P>
+<P><A HREF="pthreadCancelableWait.html">pthreadCancelableWait()</A>
+<BR><A HREF="pthreadCancelableTimedWait.html">pthreadCancelableTimedWait()</A></P>
+<P>All other POSIX threads functions are guaranteed not to be
+cancellation points. That is, they never perform cancellation in
+deferred cancellation mode.
+</P>
+<P><B>pthread_testcancel</B> does nothing except testing for pending
+cancellation and executing it. Its purpose is to introduce explicit
+checks for cancellation in long sequences of code that do not call
+cancellation point functions otherwise.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P><B>pthread_cancel</B>, <B>pthread_setcancelstate</B> and
+<B>pthread_setcanceltype</B> return 0 on success and a non-zero error
+code on error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P><B>pthread_cancel</B> returns the following error code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ESRCH</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ no thread could be found corresponding to that specified by the
+ <I>thread</I> ID.
+ </DD></DL>
+</DL>
+<P>
+<B>pthread_setcancelstate</B> returns the following error code on
+error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the <I>state</I> argument is not
+ </DD></DL>
+</DL>
+<BLOCKQUOTE>
+<B>PTHREAD_CANCEL_ENABLE</B> nor <B>PTHREAD_CANCEL_DISABLE</B>
+</BLOCKQUOTE>
+<P><B>pthread_setcanceltype</B> returns the following error code on
+error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the <I>type</I> argument is not
+ </DD></DL>
+</DL>
+<BLOCKQUOTE>
+<B>PTHREAD_CANCEL_DEFERRED</B> nor <B>PTHREAD_CANCEL_ASYNCHRONOUS</B>
+</BLOCKQUOTE>
+<H2><A HREF="#toc5" NAME="sect5">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
+<P><A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> ,
+<A HREF="pthread_cleanup_push.html"><B>pthread_cleanup_push</B>(3)</A>
+, <A HREF="pthread_cleanup_pop.html"><B>pthread_cleanup_pop</B>(3)</A>
+, Pthreads-w32 package README file 'Prerequisites' section.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Bugs</A></H2>
+<P>POSIX specifies that a number of system calls (basically, all
+system calls that may block, such as <A HREF="read.html"><B>read</B>(2)</A>
+, <A HREF="write.html"><B>write</B>(2)</A> , <A HREF="wait.html"><B>wait</B>(2)</A>
+, etc.) and library functions that may call these system calls (e.g.
+<A HREF="fprintf.html"><B>fprintf</B>(3)</A> ) are cancellation
+points. <B>Pthreads-win32</B> is not integrated enough with the C
+library to implement this, and thus none of the C library functions
+is a cancellation point.
+</P>
+<P>A workaround for these calls is to temporarily switch to
+asynchronous cancellation (assuming full asynchronous cancellation
+support is installed). So, checking for cancellation during a <B>read</B>
+system call, for instance, can be achieved as follows:
+</P>
+<BLOCKQUOTE><BR><BR>
+</BLOCKQUOTE>
+<PRE STYLE="margin-left: 1cm; margin-right: 1cm">pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &amp;oldCancelType);
+read(fd, buffer, length);
+pthread_setcanceltype(oldCancelType, NULL);</PRE>
+<HR>
+<BLOCKQUOTE><A NAME="toc"></A><B>Table of Contents</B></BLOCKQUOTE>
+<UL>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">See
+ Also</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE><A HREF="#sect7" NAME="toc7">Bugs</A>
+ </BLOCKQUOTE>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_setcanceltype.html b/pthreads/manual/pthread_setcanceltype.html
new file mode 100644
index 000000000..935ed822c
--- /dev/null
+++ b/pthreads/manual/pthread_setcanceltype.html
@@ -0,0 +1,207 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_CANCEL(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;12090500">
+ <META NAME="CHANGED" CONTENT="20050504;16362800">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_cancel, pthread_setcancelstate, pthread_setcanceltype,
+pthread_testcancel - thread cancellation
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthread_cancel(pthread_t </B><I>thread</I><B>);</B>
+</P>
+<P><B>int pthread_setcancelstate(int </B><I>state</I><B>, int
+*</B><I>oldstate</I><B>);</B>
+</P>
+<P><B>int pthread_setcanceltype(int </B><I>type</I><B>, int
+*</B><I>oldtype</I><B>);</B>
+</P>
+<P><B>void pthread_testcancel(void);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>Cancellation is the mechanism by which a thread can terminate the
+execution of another thread. More precisely, a thread can send a
+cancellation request to another thread. Depending on its settings,
+the target thread can then either ignore the request, honor it
+immediately, or defer it until it reaches a cancellation point.
+</P>
+<P>When a thread eventually honors a cancellation request, it
+performs as if <B>pthread_exit(PTHREAD_CANCELED)</B> has been called
+at that point: all cleanup handlers are executed in reverse order,
+destructor functions for thread-specific data are called, and finally
+the thread stops executing with the return value <B>PTHREAD_CANCELED</B>.
+See <A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> for more
+information.
+</P>
+<P><B>pthread_cancel</B> sends a cancellation request to the thread
+denoted by the <I>thread</I> argument.
+</P>
+<P><B>pthread_setcancelstate</B> changes the cancellation state for
+the calling thread -- that is, whether cancellation requests are
+ignored or not. The <I>state</I> argument is the new cancellation
+state: either <B>PTHREAD_CANCEL_ENABLE</B> to enable cancellation, or
+<B>PTHREAD_CANCEL_DISABLE</B> to disable cancellation (cancellation
+requests are ignored). If <I>oldstate</I> is not <B>NULL</B>, the
+previous cancellation state is stored in the location pointed to by
+<I>oldstate</I>, and can thus be restored later by another call to
+<B>pthread_setcancelstate</B>.
+</P>
+<P><B>pthread_setcanceltype</B> changes the type of responses to
+cancellation requests for the calling thread: asynchronous
+(immediate) or deferred. The <I>type</I> argument is the new
+cancellation type: either <B>PTHREAD_CANCEL_ASYNCHRONOUS</B> to
+cancel the calling thread as soon as the cancellation request is
+received, or <B>PTHREAD_CANCEL_DEFERRED</B> to keep the cancellation
+request pending until the next cancellation point. If <I>oldtype</I>
+is not <B>NULL</B>, the previous cancellation state is stored in the
+location pointed to by <I>oldtype</I>, and can thus be restored later
+by another call to <B>pthread_setcanceltype</B>.
+</P>
+<P><B>Pthreads-w32</B> provides two levels of support for
+<B>PTHREAD_CANCEL_ASYNCHRONOUS</B>: full and partial. Full support
+requires an additional DLL and driver be installed on the Windows
+system (see the See Also section below) that allows blocked threads
+to be cancelled immediately. Partial support means that the target
+thread will not cancel until it resumes execution naturally. Partial
+support is provided if either the DLL or the driver are not
+automatically detected by the pthreads-w32 library at run-time.</P>
+<P>Threads are always created by <A HREF="pthread_create.html"><B>pthread_create</B>(3)</A>
+with cancellation enabled and deferred. That is, the initial
+cancellation state is <B>PTHREAD_CANCEL_ENABLE</B> and the initial
+type is <B>PTHREAD_CANCEL_DEFERRED</B>.
+</P>
+<P>Cancellation points are those points in the program execution
+where a test for pending cancellation requests is performed and
+cancellation is executed if positive. The following POSIX threads
+functions are cancellation points:
+</P>
+<P><A HREF="pthread_join.html"><B>pthread_join</B>(3)</A>
+<BR><A HREF="pthread_cond_wait.html"><B>pthread_cond_wait</B>(3)</A>
+<BR><A HREF="pthread_cond_timedwait.html"><B>pthread_cond_timedwait</B>(3)</A>
+<BR><A HREF="pthread_testcancel.html"><B>pthread_testcancel</B>(3)</A>
+<BR><A HREF="sem_wait.html"><B>sem_wait</B>(3)</A> <BR><A HREF="sem_timedwait.html"><B>sem_timedwait</B>(3)</A>
+<BR><A HREF="sigwait.html"><B>sigwait</B>(3)</A> (not supported under
+<B>Pthreads-w32</B>)</P>
+<P><B>Pthreads-w32</B> provides two functions to enable additional
+cancellation points to be created in user functions that block on
+Win32 HANDLEs:</P>
+<P><A HREF="pthreadCancelableWait.html">pthreadCancelableWait()</A>
+<BR><A HREF="pthreadCancelableTimedWait.html">pthreadCancelableTimedWait()</A></P>
+<P>All other POSIX threads functions are guaranteed not to be
+cancellation points. That is, they never perform cancellation in
+deferred cancellation mode.
+</P>
+<P><B>pthread_testcancel</B> does nothing except testing for pending
+cancellation and executing it. Its purpose is to introduce explicit
+checks for cancellation in long sequences of code that do not call
+cancellation point functions otherwise.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P><B>pthread_cancel</B>, <B>pthread_setcancelstate</B> and
+<B>pthread_setcanceltype</B> return 0 on success and a non-zero error
+code on error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P><B>pthread_cancel</B> returns the following error code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ESRCH</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ no thread could be found corresponding to that specified by the
+ <I>thread</I> ID.
+ </DD></DL>
+</DL>
+<P>
+<B>pthread_setcancelstate</B> returns the following error code on
+error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the <I>state</I> argument is not
+ </DD></DL>
+</DL>
+<BLOCKQUOTE>
+<B>PTHREAD_CANCEL_ENABLE</B> nor <B>PTHREAD_CANCEL_DISABLE</B>
+</BLOCKQUOTE>
+<P><B>pthread_setcanceltype</B> returns the following error code on
+error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the <I>type</I> argument is not
+ </DD></DL>
+</DL>
+<BLOCKQUOTE>
+<B>PTHREAD_CANCEL_DEFERRED</B> nor <B>PTHREAD_CANCEL_ASYNCHRONOUS</B>
+</BLOCKQUOTE>
+<H2><A HREF="#toc5" NAME="sect5">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
+<P><A HREF="pthread_exit.html"><B>pthread_exit</B>(3)</A> ,
+<A HREF="pthread_cleanup_push.html"><B>pthread_cleanup_push</B>(3)</A>
+, <A HREF="pthread_cleanup_pop.html"><B>pthread_cleanup_pop</B>(3)</A>
+, Pthreads-w32 package README file 'Prerequisites' section.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Bugs</A></H2>
+<P>POSIX specifies that a number of system calls (basically, all
+system calls that may block, such as <A HREF="read.html"><B>read</B>(2)</A>
+, <A HREF="write.html"><B>write</B>(2)</A> , <A HREF="wait.html"><B>wait</B>(2)</A>
+, etc.) and library functions that may call these system calls (e.g.
+<A HREF="fprintf.html"><B>fprintf</B>(3)</A> ) are cancellation
+points. <B>Pthreads-win32</B> is not integrated enough with the C
+library to implement this, and thus none of the C library functions
+is a cancellation point.
+</P>
+<P>A workaround for these calls is to temporarily switch to
+asynchronous cancellation (assuming full asynchronous cancellation
+support is installed). So, checking for cancellation during a <B>read</B>
+system call, for instance, can be achieved as follows:
+</P>
+<BLOCKQUOTE><BR><BR>
+</BLOCKQUOTE>
+<PRE STYLE="margin-left: 1cm; margin-right: 1cm">pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &amp;oldCancelType);
+read(fd, buffer, length);
+pthread_setcanceltype(oldCancelType, NULL);</PRE>
+<HR>
+<BLOCKQUOTE><A NAME="toc"></A><B>Table of Contents</B></BLOCKQUOTE>
+<UL>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">See
+ Also</A>
+ </BLOCKQUOTE>
+ <LI><BLOCKQUOTE><A HREF="#sect7" NAME="toc7">Bugs</A>
+ </BLOCKQUOTE>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_setconcurrency.html b/pthreads/manual/pthread_setconcurrency.html
new file mode 100644
index 000000000..cdd4f5840
--- /dev/null
+++ b/pthreads/manual/pthread_setconcurrency.html
@@ -0,0 +1,155 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_GETCONCURRENCY&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;19162600">
+ <META NAME="CHANGED" CONTENT="20050505;19223800">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_getconcurrency, pthread_setconcurrency - get and set the
+level of concurrency
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_getconcurrency(void);</B> <BR><B>int
+pthread_setconcurrency(int</B> <I>new_level</I><B>); </B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>Unbound threads in a process may or may not be required to be
+simultaneously active. By default, the threads implementation ensures
+that a sufficient number of threads are active so that the process
+can continue to make progress. While this conserves system resources,
+it may not produce the most effective level of concurrency.
+</P>
+<P>The <B>pthread_setconcurrency</B> function allows an application
+to inform the threads implementation of its desired concurrency
+level, <I>new_level</I>. The actual level of concurrency provided by
+the implementation as a result of this function call is unspecified.
+</P>
+<P>If <I>new_level</I> is zero, it causes the implementation to
+maintain the concurrency level at its discretion as if
+<B>pthread_setconcurrency</B> had never been called.
+</P>
+<P>The <B>pthread_getconcurrency</B> function shall return the value
+set by a previous call to the <B>pthread_setconcurrency</B> function.
+If the <B>pthread_setconcurrency</B> function was not previously
+called, this function shall return zero to indicate that the
+implementation is maintaining the concurrency level.
+</P>
+<P>A call to <B>pthread_setconcurrency</B> shall inform the
+implementation of its desired concurrency level. The implementation
+shall use this as a hint, not a requirement.
+</P>
+<P>If an implementation does not support multiplexing of user threads
+on top of several kernel-scheduled entities, the
+<B>pthread_setconcurrency</B> and <B>pthread_getconcurrency</B>
+functions are provided for source code compatibility but they shall
+have no effect when called. To maintain the function semantics, the
+<I>new_level</I> parameter is saved when <B>pthread_setconcurrency</B>
+is called so that a subsequent call to <B>pthread_getconcurrency</B>
+shall return the same value.
+</P>
+<P><B>Pthreads-w32</B> provides these routines for source code
+compatibility only, as described in the previous paragraph.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>If successful, the <B>pthread_setconcurrency</B> function shall
+return zero; otherwise, an error number shall be returned to indicate
+the error.
+</P>
+<P>The <B>pthread_getconcurrency</B> function shall always return the
+concurrency level set by a previous call to <B>pthread_setconcurrency</B>
+. If the <B>pthread_setconcurrency</B> function has never been
+called, <B>pthread_getconcurrency</B> shall return zero.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_setconcurrency</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD>
+ The value specified by <I>new_level</I> is negative.
+ </DD><DT>
+ <B>EAGAIN</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specific by <I>new_level</I> would cause a system resource
+ to be exceeded.
+ </DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>Use of these functions changes the state of the underlying
+concurrency upon which the application depends. Library developers
+are advised to not use the <B>pthread_getconcurrency</B> and
+<B>pthread_setconcurrency</B> functions since their use may conflict
+with an applications use of these functions.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P>The Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_setschedparam.html b/pthreads/manual/pthread_setschedparam.html
new file mode 100644
index 000000000..920c20bab
--- /dev/null
+++ b/pthreads/manual/pthread_setschedparam.html
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_SETSCHEDPARAM(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050504;18110100">
+ <META NAME="CHANGED" CONTENT="20050614;14012300">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_setschedparam, pthread_getschedparam - control thread
+scheduling
+</P>
+<P>parameters
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>int pthread_setschedparam(pthread_t </B><I>target_thread</I><B>,
+int </B><I>policy</I><B>, const struct sched_param *</B><I>param</I><B>);</B>
+</P>
+<P><B>int pthread_getschedparam(pthread_t </B><I>target_thread</I><B>,
+int *</B><I>policy</I><B>, struct sched_param *</B><I>param</I><B>);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P><B>pthread_setschedparam</B> sets the scheduling parameters for
+the thread <I>target_thread</I> as indicated by <I>policy</I> and
+<I>param</I>. <I>policy</I> can be either <B>SCHED_OTHER</B>
+(regular, non-real-time scheduling), <B>SCHED_RR</B> (real-time,
+round-robin) or <B>SCHED_FIFO</B> (real-time, first-in first-out).
+<I>param</I> specifies the scheduling priority for the two real-time
+policies.</P>
+<P><B>Pthreads-w32</B> only supports SCHED_OTHER and does not support
+the real-time scheduling policies <B>SCHED_RR</B> and <B>SCHED_FIFO.</B>
+</P>
+<P><B>pthread_getschedparam</B> retrieves the scheduling policy and
+scheduling parameters for the thread <I>target_thread</I> and stores
+them in the locations pointed to by <I>policy</I> and <I>param</I>,
+respectively.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P><B>pthread_setschedparam</B> and <B>pthread_getschedparam</B>
+return 0 on success and a non-zero error code on error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>On error, <B>pthread_setschedparam</B> returns the following error
+codes:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ENOTSUP</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <I>policy</I> is not <B>SCHED_OTHER.</B></DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ One of the arguments is invalid, or the priority value specified by
+ <I>param</I> is not valid for the specified policy.</DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <B>ESRCH</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ The <I>target_thread</I> is invalid or has already terminated
+ </DD></DL>
+</DL>
+<P>
+On error, <B>pthread_getschedparam</B> returns the following error
+codes:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ESRCH</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ the <I>target_thread</I> is invalid or has already terminated
+ </DD></DL>
+</DL>
+<H2>
+<A HREF="#toc5" NAME="sect5">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc6" NAME="sect6">See Also</A></H2>
+<P><A HREF="sched_setscheduler.html"><B>sched_setscheduler</B>(2)</A>
+, <A HREF="sched_getscheduler.html"><B>sched_getscheduler</B>(2)</A>
+, <A HREF="sched_getparam.html"><B>sched_getparam</B>(2)</A> ,
+<A HREF="pthread_attr_setschedpolicy.html"><B>pthread_attr_setschedpolicy</B>(3)</A>
+, <A HREF="pthread_attr_setschedparam.html"><B>pthread_attr_setschedparam</B>(3)</A>
+.
+</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Author</A>
+ </P>
+ <LI><P><A HREF="#sect6" NAME="toc6">See Also</A>
+ </P>
+</UL>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/pthreads/manual/pthread_spin_init.html b/pthreads/manual/pthread_spin_init.html
new file mode 100644
index 000000000..35e657be4
--- /dev/null
+++ b/pthreads/manual/pthread_spin_init.html
@@ -0,0 +1,176 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_SPIN_DESTROY&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;12074100">
+ <META NAME="CHANGED" CONTENT="20050505;19014200">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_spin_destroy, pthread_spin_init - destroy or initialize a
+spin lock object (<B>ADVANCED REALTIME THREADS</B>)
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>pthread_spinlock_t</B> <I>lock</I> <B>=
+PTHREAD_SPINLOCK_INITIALIZER;</B></P>
+<P><B>int pthread_spin_destroy(pthread_spinlock_t *</B><I>lock</I><B>);
+<BR>int pthread_spin_init(pthread_spinlock_t *</B><I>lock</I><B>, int</B>
+<I>pshared</I><B>); </B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_spin_destroy</B> function shall destroy the spin
+lock referenced by <I>lock</I> and release any resources used by the
+lock. The effect of subsequent use of the lock is undefined until the
+lock is reinitialized by another call to <B>pthread_spin_init</B> .
+The results are undefined if <B>pthread_spin_destroy</B> is called
+when a thread holds the lock, or if this function is called with an
+uninitialized thread spin lock.
+</P>
+<P>The <B>pthread_spin_init</B> function shall allocate any resources
+required to use the spin lock referenced by <I>lock</I> and
+initialize the lock to an unlocked state.
+</P>
+<P><B>Pthreads-w32</B> supports single and multiple processor systems
+as well as process CPU affinity masking by checking the mask when the
+spin lock is initialized. If the process is using only a single
+processor at the time <B>pthread_spin_init</B> is called then the
+spin lock is initialized as a PTHREAD_MUTEX_NORMAL mutex object. A
+thread that calls <A HREF="pthread_spin_lock.html"><B>pthread_spin_lock(3)</B></A>
+will block rather than spin in this case. If the process CPU affinity
+mask is altered after the spin lock has been initialised, the spin
+lock is not modified, and may no longer be optimal for the number of
+CPUs available.</P>
+<P><B>Pthreads-w32</B> defines <B>_POSIX_THREAD_PROCESS_SHARED</B> in
+pthread.h as -1 to indicate that these routines do not support the
+<B>PTHREAD_PROCESS_SHARED</B> attribute. <B>pthread_spin_init</B>
+will return the error <B>ENOTSUP</B> if the value of <I>pshared</I>
+is not <B>PTHREAD_PROCESS_PRIVATE</B>.</P>
+<P>The results are undefined if <B>pthread_spin_init</B> is called
+specifying an already initialized spin lock. The results are
+undefined if a spin lock is used without first being initialized.
+</P>
+<P>If the <B>pthread_spin_init</B> function fails, the lock is not
+initialized and the contents of <I>lock</I> are undefined.
+</P>
+<P>Only the object referenced by <I>lock</I> may be used for
+performing synchronization.
+</P>
+<P>The result of referring to copies of that object in calls to
+<B>pthread_spin_destroy</B> , <A HREF="pthread_spin_lock.html"><B>pthread_spin_lock</B>(3)</A>
+, <A HREF="pthread_spin_lock.html"><B>pthread_spin_trylock</B>(3)</A>,
+or <A HREF="pthread_spin_unlock.html"><B>pthread_spin_unlock</B>(3)</A>
+is undefined.
+</P>
+<P><B>Pthreads-w32</B> supports statically initialized spin locks
+using <B>PTHREAD_SPINLOCK_INITIALIZER</B>. An application should
+still call <B>pthread_spin_destroy</B> at some point to ensure that
+any resources consumed by the spin lock are released.</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>Upon successful completion, these functions shall return zero;
+otherwise, an error number shall be returned to indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>These functions may fail if:
+</P>
+<DL>
+ <DT><B>EBUSY</B>
+ </DT><DD>
+ The implementation has detected an attempt to initialize or destroy
+ a spin lock while it is in use (for example, while being used in a
+ <A HREF="pthread_spin_lock.html"><B>pthread_spin_lock</B>(3)</A>
+ call) by another thread.
+ </DD><DT>
+ <B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>lock</I> is invalid.
+ </DD></DL>
+<P>
+The <B>pthread_spin_init</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>ENOTSUP</B>
+ </DT><DD>
+ The value of <I>pshared</I> is not <B>PTHREAD_PROCESS_PRIVATE</B>.</DD><DT>
+ <B>ENOMEM</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ Insufficient memory exists to initialize the lock.
+ </DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>The <B>pthread_spin_destroy</B> and <B>pthread_spin_init</B>
+functions are part of the Spin Locks option and need not be provided
+on all implementations.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_spin_lock.html"><B>pthread_spin_lock</B>(3)</A> <B>,</B>
+<A HREF="pthread_spin_unlock.html"><B>pthread_spin_unlock</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_spin_lock.html b/pthreads/manual/pthread_spin_lock.html
new file mode 100644
index 000000000..dd180ae6a
--- /dev/null
+++ b/pthreads/manual/pthread_spin_lock.html
@@ -0,0 +1,141 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_SPIN_LOCK&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;12202300">
+ <META NAME="CHANGED" CONTENT="20050505;19302300">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_spin_lock, pthread_spin_trylock - lock a spin lock object
+(<B>ADVANCED REALTIME THREADS</B>)
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_spin_lock(pthread_spinlock_t *</B><I>lock</I><B>);
+<BR>int pthread_spin_trylock(pthread_spinlock_t *</B><I>lock</I><B>);
+</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_spin_lock</B> function shall lock the spin lock
+referenced by <I>lock</I>. The calling thread shall acquire the lock
+if it is not held by another thread. Otherwise, the thread shall spin
+(that is, shall not return from the <B>pthread_spin_lock</B> call)
+until the lock becomes available. The results are undefined if the
+calling thread holds the lock at the time the call is made.</P>
+<P><B>Pthreads-w32</B> supports single and multiple processor systems
+as well as process CPU affinity masking by checking the mask when the
+spin lock is initialized. If the process is using only a single
+processor at the time <A HREF="pthread_spin_init.html"><B>pthread_spin_init</B>(3)</A>
+is called then the spin lock is initialized as a PTHREAD_MUTEX_NORMAL
+mutex object. A thread that calls <B>pthread_spin_lock</B> will block
+rather than spin in this case. If the process CPU affinity mask is
+altered after the spin lock has been initialised, the spin lock is
+not modified, and may no longer be optimal for the number of CPUs
+available.</P>
+<P>The <B>pthread_spin_trylock</B> function shall lock the spin lock
+referenced by <I>lock</I> if it is not held by any thread. Otherwise,
+the function shall fail.
+</P>
+<P>The results are undefined if any of these functions is called with
+an uninitialized spin lock.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>Upon successful completion, these functions shall return zero;
+otherwise, an error number shall be returned to indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>These functions may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value specified by <I>lock</I> does not refer to an initialized
+ spin lock object.
+ </DD></DL>
+<P>
+The <B>pthread_spin_trylock</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>EBUSY</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ A thread currently holds the lock.
+ </DD></DL>
+<P>
+These functions shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>Applications using this function may be subject to priority
+inversion, as discussed in the Base Definitions volume of
+IEEE&nbsp;Std&nbsp;1003.1-2001, Section 3.285, Priority Inversion.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_spin_init.html"><B>pthread_spin_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_spin_unlock.html"><B>pthread_spin_unlock</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_spin_unlock.html b/pthreads/manual/pthread_spin_unlock.html
new file mode 100644
index 000000000..221570058
--- /dev/null
+++ b/pthreads/manual/pthread_spin_unlock.html
@@ -0,0 +1,124 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;PTHREAD_SPIN_UNLOCK&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;12401400">
+ <META NAME="CHANGED" CONTENT="20050505;12462400">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>pthread_spin_unlock - unlock a spin lock object (<B>ADVANCED
+REALTIME THREADS</B>)
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt; </B>
+</P>
+<P><B>int pthread_spin_unlock(pthread_spinlock_t *</B><I>lock</I><B>);
+</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>pthread_spin_unlock</B> function shall release the spin
+lock referenced by <I>lock</I> which was locked via the
+<A HREF="pthread_spin_lock.html"><B>pthread_spin_lock</B>(3)</A> or
+<A HREF="pthread_spin_lock.html"><B>pthread_spin_trylock</B>(3)</A>
+functions. If there are threads spinning on the lock when
+<B>pthread_spin_unlock</B> is called, the lock becomes available and
+an unspecified spinning thread shall acquire the lock.
+</P>
+<P><B>Pthreads-w32</B> does not check ownership of the lock and it is
+therefore possible for a thread other than the locker to unlock the
+spin lock. This is not a feature that should be exploited.</P>
+<P>The results are undefined if this function is called with an
+uninitialized thread spin lock.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>Upon successful completion, the <B>pthread_spin_unlock</B>
+function shall return zero; otherwise, an error number shall be
+returned to indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>pthread_spin_unlock</B> function may fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD>
+ An invalid argument was specified.
+ </DD><DD STYLE="margin-left: -2cm">
+ <BR>
+ </DD></DL>
+<P>
+This function shall not return an error code of [EINTR].
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P><B>Pthreads-w32</B> does not check ownership of the lock and it is
+therefore possible for a thread other than the locker to unlock the
+spin lock. This is not a feature that should be exploited.</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="pthread_spin_init.html"><B>pthread_spin_destroy</B>(3)</A>
+<B>,</B> <A HREF="pthread_spin_lock.html"><B>pthread_spin_lock</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;pthread.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_timechange_handler_np.html b/pthreads/manual/pthread_timechange_handler_np.html
new file mode 100644
index 000000000..54226da7d
--- /dev/null
+++ b/pthreads/manual/pthread_timechange_handler_np.html
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_TIMECHANGE_HANDLER_NP manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;322600">
+ <META NAME="CHANGED" CONTENT="20050505;22110600">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P STYLE="font-weight: medium">pthread_timechange_handler_np ā€“
+alert timed waiting condition variables to system time changes.</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>void * pthread_timechange_handler_np(void * </B><I>dummy</I><B>);</B></P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>To improve tolerance against operator or time service initiated
+system clock changes.</P>
+<P><B>pthread_timechange_handler_np </B>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.</P>
+<P><B>pthread_timechange_handler_np </B>has the same return type and
+argument type as a thread routine so that it may be called directly
+through pthread_create(), i.e. as a separate thread. If run as a
+thread, the return code must be retrieved through <A HREF="pthread_join.html"><B>pthread_join</B>()</A>.</P>
+<P>Although the <I>dummy</I> parameter is required it is not used and
+any value including NULL can be given.</P>
+<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
+<P>None.</P>
+<H2><A HREF="#toc4" NAME="sect4"><FONT COLOR="#000080">Return Value</FONT></A></H2>
+<P><B>pthread_timechange_handler_np</B> returns 0 on success, or an
+error code.</P>
+<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
+<P>The <B>pthread_timechange_handler_np</B> function returns the
+following error code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EAGAIN</B>
+ </DT></DL>
+</DL>
+<P STYLE="margin-left: 2cm; margin-bottom: 0cm">
+To indicate that not all condition variables were signalled for some
+reason.</P>
+<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
+<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
+ </P>
+ <LI><P><A HREF="#sect6" NAME="toc6">Author</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_win32_attach_detach_np.html b/pthreads/manual/pthread_win32_attach_detach_np.html
new file mode 100644
index 000000000..57f0339a6
--- /dev/null
+++ b/pthreads/manual/pthread_win32_attach_detach_np.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_WIN32_ATTACH_DETACH_NP manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;322600">
+ <META NAME="CHANGED" CONTENT="20050505;22415600">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P STYLE="font-weight: medium">pthread_win32_process_attach_np,
+pthread_win32_process_detach_np, pthread_win32_thread_attach_np,
+pthread_win32_thread_detach_np ā€“ exposed versions of the
+pthreads-w32 DLL dllMain() switch functionality for use when
+statically linking the library.</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>BOOL pthread_win32_process_attach_np (void);</B></P>
+<P><B>BOOL pthread_win32_process_detach_np (void);</B></P>
+<P><B>BOOL pthread_win32_thread_attach_np (void);</B></P>
+<P><B>BOOL pthread_win32_thread_detach_np (void);</B></P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>These functions contain the code normally run via <B>dllMain</B>
+when the library is used as a dll but which need to be called
+explicitly by an application when the library is statically linked.</P>
+<P>You will need to call <B>pthread_win32_process_attach_np</B>
+before you can call any pthread routines when statically linking. You
+should call <B>pthread_win32_process_detach_np</B> before exiting
+your application to clean up.</P>
+<P><B>pthread_win32_thread_attach_np</B> is currently a no-op, but
+<B>pthread_win32_thread_detach_np</B> is needed to clean up the
+implicit pthread handle that is allocated to a Win32 thread if it
+calls certain pthreads routines. Call this routine when the Win32
+thread exits.</P>
+<P>These functions invariably return TRUE except for
+<B>pthread_win32_process_attach_np</B> which will return FALSE if
+pthreads-w32 initialisation fails.</P>
+<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
+<P>None.</P>
+<H2><A HREF="#toc4" NAME="sect4"><FONT COLOR="#000080">Return Value</FONT></A></H2>
+<P>These routines return TRUE (non-zero) on success, or FALSE (0) if
+they fail.</P>
+<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
+<P>None.</P>
+<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
+<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
+ </P>
+ <LI><P><A HREF="#sect6" NAME="toc6">Author</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/pthread_win32_test_features_np.html b/pthreads/manual/pthread_win32_test_features_np.html
new file mode 100644
index 000000000..1d8e11233
--- /dev/null
+++ b/pthreads/manual/pthread_win32_test_features_np.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>PTHREAD_WIN32_TEST_FEATURES_NP manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;322600">
+ <META NAME="CHANGED" CONTENT="20050510;17405600">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P STYLE="font-weight: medium">pthread_win32_test_features_np ā€“
+find out what features were detected at process attach time.</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;pthread.h&gt;</B>
+</P>
+<P><B>BOOL pthread_win32_test_features_np(int</B> <I>mask</I><B>);</B></P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P><B>pthread_win32_test_features_np</B> allows an application to
+check which run-time auto-detected features are available within the
+library.</P>
+<P>The possible features are:</P>
+<P><B>PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE</B></P>
+<P STYLE="margin-left: 2cm">Return TRUE if the Win32 version of
+InterlockedCompareExchange() is being used. On IA32 systems the
+library can use optimised and inlinable assembler versions of
+InterlockedExchange() and InterlockedCompareExchange().</P>
+<P><B>PTW32_ALERTABLE_ASYNC_CANCEL</B></P>
+<P STYLE="margin-left: 2cm">Return TRUE if the QueueUserAPCEx package
+QUSEREX.DLL and the AlertDrv.sys driver was detected. This package
+provides alertable (pre-emptive) asynchronous threads cancellation.
+If this feature returns FALSE then the default async cancel scheme is
+in use, which cannot cancel blocked threads.</P>
+<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
+<P>None.</P>
+<H2><A HREF="#toc4" NAME="sect4"><FONT COLOR="#000080">Return Value</FONT></A></H2>
+<P><B>pthread_win32_test_features_np</B> returns TRUE (non-zero) if
+the specified feature is present, and FALSE (0) otherwise.</P>
+<H2><A HREF="#toc5" NAME="sect5">Errors</A></H2>
+<P>None.</P>
+<H2><A HREF="#toc6" NAME="sect6">Author</A></H2>
+<P>Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Errors</A>
+ </P>
+ <LI><P><A HREF="#sect6" NAME="toc6">Author</A>
+ </P>
+</UL>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/pthreads/manual/sched_get_priority_max.html b/pthreads/manual/sched_get_priority_max.html
new file mode 100644
index 000000000..54869029b
--- /dev/null
+++ b/pthreads/manual/sched_get_priority_max.html
@@ -0,0 +1,115 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;SCHED_GET_PRIORITY_MAX&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;12575100">
+ <META NAME="CHANGED" CONTENT="20050510;12533300">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>sched_get_priority_max, sched_get_priority_min - get priority
+limits (<B>REALTIME</B>)
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;sched.h&gt; </B>
+</P>
+<P><B>int sched_get_priority_max(int</B> <I>policy</I><B>); <BR>int
+sched_get_priority_min(int</B> <I>policy</I><B>); </B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>sched_get_priority_max</B> and <B>sched_get_priority_min</B>
+functions shall return the appropriate maximum or minimum,
+respectively, for the scheduling policy specified by <I>policy</I>.
+</P>
+<P>The value of <I>policy</I> shall be one of the scheduling policy
+values defined in <I>&lt;sched.h&gt;</I>.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>If successful, the <B>sched_get_priority_max</B> and
+<B>sched_get_priority_min</B> functions shall return the appropriate
+maximum or minimum values, respectively. If unsuccessful, they shall
+return a value of -1 and set <I>errno</I> to indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>sched_get_priority_max</B> and <B>sched_get_priority_min</B>
+functions shall fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ The value of the <I>policy</I> parameter does not represent a
+ defined scheduling policy.
+ </DD></DL>
+<P>
+<I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="sched_getscheduler.html"><B>sched_getscheduler</B>(3)</A>
+<B>,</B> <A HREF="sched_setscheduler.html"><B>sched_setscheduler</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;sched.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/pthreads/manual/sched_getscheduler.html b/pthreads/manual/sched_getscheduler.html
new file mode 100644
index 000000000..0089e244f
--- /dev/null
+++ b/pthreads/manual/sched_getscheduler.html
@@ -0,0 +1,127 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;SCHED_GETSCHEDULER&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;13153500">
+ <META NAME="CHANGED" CONTENT="20050505;13202000">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>sched_getscheduler - get scheduling policy (<B>REALTIME</B>)
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;sched.h&gt; </B>
+</P>
+<P><B>int sched_getscheduler(pid_t</B> <I>pid</I><B>); </B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>sched_getscheduler</B> function shall return the scheduling
+policy of the process specified by <I>pid</I>. If the value of <I>pid</I>
+is negative, the behavior of the <B>sched_getscheduler</B> function
+is unspecified.
+</P>
+<P>The values that can be returned by <B>sched_getscheduler</B> are
+defined in the <I>&lt;sched.h&gt;</I> header.
+</P>
+<P><B>Pthreads-w32</B> only supports the <B>SCHED_OTHER</B> policy,
+which is the only value that can be returned. However, checks on <I>pid</I>
+and permissions are performed first so that the other useful side
+effects of this routine are retained.</P>
+<P>If a process specified by <I>pid</I> exists, and if the calling
+process has permission, the scheduling policy shall be returned for
+the process whose process ID is equal to <I>pid</I>.
+</P>
+<P>If <I>pid</I> is zero, the scheduling policy shall be returned for
+the calling process.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>Upon successful completion, the <B>sched_getscheduler</B> function
+shall return the scheduling policy of the specified process. If
+unsuccessful, the function shall return -1 and set <I>errno</I> to
+indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>sched_getscheduler</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>EPERM</B>
+ </DT><DD>
+ The requesting process does not have permission to determine the
+ scheduling policy of the specified process.
+ </DD><DT>
+ <B>ESRCH</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ No process can be found corresponding to that specified by <I>pid</I>.
+ </DD></DL>
+<P>
+<I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="sched_setscheduler.html"><B>sched_setscheduler</B>(3)</A>
+, the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;sched.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/sched_setscheduler.html b/pthreads/manual/sched_setscheduler.html
new file mode 100644
index 000000000..c6e62ae0d
--- /dev/null
+++ b/pthreads/manual/sched_setscheduler.html
@@ -0,0 +1,181 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;SCHED_SETSCHEDULER&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;13012200">
+ <META NAME="CHANGED" CONTENT="20050505;13193700">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>sched_setscheduler - set scheduling policy and parameters
+(<B>REALTIME</B>)
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;sched.h&gt; </B>
+</P>
+<P><B>int sched_setscheduler(pid_t</B> <I>pid</I><B>, int</B> <I>policy</I><B>,
+const struct sched_param *</B><I>param</I><B>); </B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>sched_setscheduler</B> function shall set the scheduling
+policy and scheduling parameters of the process specified by <I>pid</I>
+to <I>policy</I> and the parameters specified in the <B>sched_param</B>
+structure pointed to by <I>param</I>, respectively. The value of the
+<I>sched_priority</I> member in the <B>sched_param</B> structure
+shall be any integer within the inclusive priority range for the
+scheduling policy specified by <I>policy</I>. If the value of <I>pid</I>
+is negative, the behavior of the <B>sched_setscheduler</B> function
+is unspecified.
+</P>
+<P>The possible values for the <I>policy</I> parameter are defined in
+the <I>&lt;sched.h&gt;</I> header.
+</P>
+<P><B>Pthreads-w32</B> only supports the <B>SCHED_OTHER</B> policy.
+Any other value for <I>policy</I> will return failure with errno set
+to <B>ENOSYS</B>. However, checks on <I>pid</I> and permissions are
+performed first so that the other useful side effects of this routine
+are retained.</P>
+<P>If a process specified by <I>pid</I> exists, and if the calling
+process has permission, the scheduling policy and scheduling
+parameters shall be set for the process whose process ID is equal to
+<I>pid</I>.
+</P>
+<P>If <I>pid</I> is zero, the scheduling policy and scheduling
+parameters shall be set for the calling process.
+</P>
+<P>Implementations may require that the requesting process have
+permission to set its own scheduling parameters or those of another
+process. Additionally, implementation-defined restrictions may apply
+as to the appropriate privileges required to set a processā€™ own
+scheduling policy, or another processā€™ scheduling policy, to a
+particular value.
+</P>
+<P>The <B>sched_setscheduler</B> function shall be considered
+successful if it succeeds in setting the scheduling policy and
+scheduling parameters of the process specified by <I>pid</I> to the
+values specified by <I>policy</I> and the structure pointed to by
+<I>param</I>, respectively.
+</P>
+<P>The effect of this function on individual threads is dependent on
+the scheduling contention scope of the threads:
+</P>
+<DL>
+ <DT>*
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ For threads with system scheduling contention scope, these functions
+ shall have no effect on their scheduling.
+ </DD><DT>
+ *
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ For threads with process scheduling contention scope, the threadsā€™
+ scheduling policy and associated parameters shall not be affected.
+ However, the scheduling of these threads with respect to threads in
+ other processes may be dependent on the scheduling parameters of
+ their process, which are governed using these functions.
+ </DD></DL>
+<P>
+This function is not atomic with respect to other threads in the
+process. Threads may continue to execute while this function call is
+in the process of changing the scheduling policy and associated
+scheduling parameters for the underlying kernel-scheduled entities
+used by the process contention scope threads.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>Upon successful completion, the function shall return the former
+scheduling policy of the specified process. If the <B>sched_setscheduler</B>
+function fails to complete successfully, the policy and scheduling
+parameters shall remain unchanged, and the function shall return a
+value of -1 and set <I>errno</I> to indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>The <B>sched_setscheduler</B> function shall fail if:
+</P>
+<DL>
+ <DT><B>EINVAL</B>
+ </DT><DD>
+ The value of the <I>policy</I> parameter is invalid, or one or more
+ of the parameters contained in <I>param</I> is outside the valid
+ range for the specified scheduling policy.
+ </DD><DT>
+ <B>EPERM</B>
+ </DT><DD>
+ The requesting process does not have permission to set either or
+ both of the scheduling parameters or the scheduling policy of the
+ specified process.
+ </DD><DT>
+ <B>ESRCH</B>
+ </DT><DD STYLE="margin-bottom: 0.5cm">
+ No process can be found corresponding to that specified by <I>pid</I>.
+ </DD></DL>
+<P>
+<I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P><A HREF="sched_getscheduler.html"><B>sched_getscheduler</B>(3)</A>
+<B>,</B> the Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;sched.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/sched_yield.html b/pthreads/manual/sched_yield.html
new file mode 100644
index 000000000..fa5ed04d5
--- /dev/null
+++ b/pthreads/manual/sched_yield.html
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>&quot;SCHED_YIELD&quot;(P) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;14034600">
+ <META NAME="CHANGED" CONTENT="20050505;14050300">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>sched_yield - yield the processor
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;sched.h&gt; </B>
+</P>
+<P><B>int sched_yield(void);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>The <B>sched_yield</B> function shall force the running thread to
+relinquish the processor until it again becomes the head of its
+thread list. It takes no arguments.
+</P>
+<H2><A HREF="#toc3" NAME="sect3">Return Value</A></H2>
+<P>The <B>sched_yield</B> function shall return 0 if it completes
+successfully; otherwise, it shall return a value of -1 and set <I>errno</I>
+to indicate the error.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Errors</A></H2>
+<P>No errors are defined.
+</P>
+<P><I>The following sections are informative.</I>
+</P>
+<H2><A HREF="#toc5" NAME="sect5">Examples</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Application Usage</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc7" NAME="sect7">Rationale</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc8" NAME="sect8">Future Directions</A></H2>
+<P>None.
+</P>
+<H2><A HREF="#toc9" NAME="sect9">See Also</A></H2>
+<P>The Base Definitions volume of IEEE&nbsp;Std&nbsp;1003.1-2001,
+<I>&lt;sched.h&gt;</I>
+</P>
+<H2><A HREF="#toc10" NAME="sect10">Copyright</A></H2>
+<P>Portions of this text are reprinted and reproduced in electronic
+form from IEEE Std 1003.1, 2003 Edition, Standard for Information
+Technology -- Portable Operating System Interface (POSIX), The Open
+Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
+Institute of Electrical and Electronics Engineers, Inc and The Open
+Group. In the event of any discrepancy between this version and the
+original IEEE and The Open Group Standard, the original IEEE and The
+Open Group Standard is the referee document. The original Standard
+can be obtained online at <A HREF="http://www.opengroup.org/unix/online.html">http://www.opengroup.org/unix/online.html</A>
+.
+</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Examples</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Application
+ Usage</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Rationale</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect8" NAME="toc8">Future
+ Directions</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect9" NAME="toc9">See
+ Also</A>
+ </P>
+ <LI><P><A HREF="#sect10" NAME="toc10">Copyright</A>
+ </P>
+</UL>
+</BODY>
+</HTML>
diff --git a/pthreads/manual/sem_init.html b/pthreads/manual/sem_init.html
new file mode 100644
index 000000000..80e0580dc
--- /dev/null
+++ b/pthreads/manual/sem_init.html
@@ -0,0 +1,200 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
+ <TITLE>SEMAPHORES(3) manual page</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.3 (Linux)">
+ <META NAME="CREATED" CONTENT="20050505;14061900">
+ <META NAME="CHANGED" CONTENT="20050514;195200">
+ <!-- manual page source format generated by PolyglotMan v3.2, -->
+ <!-- available at http://polyglotman.sourceforge.net/ -->
+</HEAD>
+<BODY LANG="en-GB" BGCOLOR="#ffffff" DIR="LTR">
+<H4>POSIX Threads for Windows ā€“ REFERENCE - <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A></H4>
+<P><A HREF="index.html">Reference Index</A></P>
+<P><A HREF="#toc">Table of Contents</A></P>
+<H2><A HREF="#toc0" NAME="sect0">Name</A></H2>
+<P>sem_init, sem_wait, sem_trywait, sem_post, sem_getvalue,
+sem_destroy - operations on semaphores
+</P>
+<H2><A HREF="#toc1" NAME="sect1">Synopsis</A></H2>
+<P><B>#include &lt;semaphore.h&gt;</B>
+</P>
+<P><B>int sem_init(sem_t *</B><I>sem</I><B>, int </B><I>pshared</I><B>,
+unsigned int </B><I>value</I><B>);</B>
+</P>
+<P><B>int sem_wait(sem_t * </B><I>sem</I><B>);</B>
+</P>
+<P><B>int sem_timedwait(sem_t * </B><I>sem</I>, <B>const struct
+timespec *</B><I>abstime</I><B>);</B>
+</P>
+<P><B>int sem_trywait(sem_t * </B><I>sem</I><B>);</B>
+</P>
+<P><B>int sem_post(sem_t * </B><I>sem</I><B>);</B>
+</P>
+<P><B>int sem_post_multiple(sem_t * </B><I>sem, </I><B>int</B>
+<I>number</I><B>);</B>
+</P>
+<P><B>int sem_getvalue(sem_t * </B><I>sem</I><B>, int * </B><I>sval</I><B>);</B>
+</P>
+<P><B>int sem_destroy(sem_t * </B><I>sem</I><B>);</B>
+</P>
+<H2><A HREF="#toc2" NAME="sect2">Description</A></H2>
+<P>Semaphores are counters for resources shared between threads. The
+basic operations on semaphores are: increment the counter atomically,
+and wait until the counter is non-null and decrement it atomically.
+</P>
+<P><B>sem_init</B> initializes the semaphore object pointed to by
+<I>sem</I>. The count associated with the semaphore is set initially
+to <I>value</I>. The <I>pshared</I> argument indicates whether the
+semaphore is local to the current process ( <I>pshared</I> is zero)
+or is to be shared between several processes ( <I>pshared</I> is not
+zero).</P>
+<P><B>Pthreads-w32</B> currently does not support process-shared
+semaphores, thus <B>sem_init</B> always returns with error <B>EPERM</B>
+if <I>pshared</I> is not zero.
+</P>
+<P><B>sem_wait</B> atomically decrements <I>sem</I>'s count if it is
+greater than 0 and returns immediately or it suspends the calling
+thread until it can resume following a call to <B>sem_post</B> or
+<B>sem_post_multiple</B>.</P>
+<P><B>sem_timedwait</B> atomically decrements <I>sem</I>'s count if
+it is greater than 0 and returns immediately, or it suspends the
+calling thread. If <I>abstime</I> time arrives before the thread can
+resume following a call to <B>sem_post</B> or <B>sem_post_multiple</B>,
+then <B>sem_timedwait</B> returns with a return code of -1 after
+having set <B>errno</B> to <B>ETIMEDOUT</B>. If the call can return
+without suspending then <I>abstime</I> is not checked.</P>
+<P><B>sem_trywait</B> atomically decrements <I>sem</I>'s count if it
+is greater than 0 and returns immediately, or it returns immediately
+with a return code of -1 after having set <B>errno</B> to <B>EAGAIN</B>.
+<B>sem_trywait</B> never blocks.</P>
+<P><B>sem_post</B> either releases one thread if there are any
+waiting on <I>sem</I>, or it atomically increments <I>sem</I>'s
+count.</P>
+<P><B>sem_post_multiple</B> either releases multiple threads if there
+are any waiting on <I>sem</I> and/or it atomically increases <I>sem</I>'s
+count. If there are currently <I>n</I> waiters, where <I>n</I> the
+largest number less than or equal to <I>number</I>, then <I>n</I>
+waiters are released and <I>sem</I>'s count is incremented by <I>number</I>
+minus <I>n</I>.</P>
+<P><B>sem_getvalue</B> stores in the location pointed to by <I>sval</I>
+the current count of the semaphore <I>sem</I>. In the <B>Pthreads-w32</B>
+implementation: if the value returned in <I>sval</I> is greater than
+or equal to 0 it was the <I>sem</I>'s count at some point during the
+call to <B>sem_getvalue</B>. If the value returned in <I>sval</I> is
+less than 0 then it's absolute value represents the number of threads
+waiting on <I>sem</I> at some point during the call to <B>sem_getvalue.
+</B>POSIX does not require an implementation of <B>sem_getvalue</B>
+to return a value in <I>sval</I> that is less than 0, but if it does
+then it's absolute value must represent the number of waiters.</P>
+<P><B>sem_destroy</B> destroys a semaphore object, freeing the
+resources it might hold. No threads should be waiting on the
+semaphore at the time <B>sem_destroy</B> is called.</P>
+<H2><A HREF="#toc3" NAME="sect3">Cancellation</A></H2>
+<P><B>sem_wait</B> and <B>sem_timedwait</B> are cancellation points.
+</P>
+<H2><A HREF="#toc4" NAME="sect4">Async-signal Safety</A></H2>
+<P>These routines are not async-cancel safe.</P>
+<H2><A HREF="#toc5" NAME="sect5">Return Value</A></H2>
+<P>All semaphore functions return 0 on success, or -1 on error in
+which case they write an error code in <B>errno</B>.
+</P>
+<H2><A HREF="#toc6" NAME="sect6">Errors</A></H2>
+<P>The <B>sem_init</B> function sets <B>errno</B> to the following
+codes on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EINVAL</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <I>value</I> exceeds the maximal counter value <B>SEM_VALUE_MAX</B>
+ </DD><DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ <B>ENOSYS</B>
+ </DT></DL>
+</DL>
+<BLOCKQUOTE STYLE="margin-left: 3cm">
+<I>pshared</I> is not zero
+</BLOCKQUOTE>
+<P>The <B>sem_timedwait</B> function sets <B>errno</B> to the
+following error code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ETIMEDOUT</B>
+ </DT></DL>
+</DL>
+<BLOCKQUOTE STYLE="margin-left: 3cm">
+if <I>abstime</I> arrives before the waiting thread can resume
+following a call to <B>sem_post</B> or <B>sem_post_multiple</B>.
+</BLOCKQUOTE>
+<P>The <B>sem_trywait</B> function sets <B>errno</B> to the following
+error code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EAGAIN</B>
+ </DT></DL>
+</DL>
+<BLOCKQUOTE STYLE="margin-left: 3cm">
+if the semaphore count is currently 0
+</BLOCKQUOTE>
+<P>The <B>sem_post</B> and <B>sem_post_multiple</B> functions set
+<B>errno</B> to the following error code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>ERANGE</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ if after incrementing, the semaphore count would exceed
+ <B>SEM_VALUE_MAX</B> (the semaphore count is left unchanged in this
+ case)
+ </DD></DL>
+</DL>
+<P>
+The <B>sem_destroy</B> function sets <B>errno</B> to the following
+error code on error:
+</P>
+<DL>
+ <DL>
+ <DT STYLE="margin-right: 1cm; margin-bottom: 0.5cm"><B>EBUSY</B>
+ </DT><DD STYLE="margin-right: 1cm; margin-bottom: 0.5cm">
+ if some threads are currently blocked waiting on the semaphore.
+ </DD></DL>
+</DL>
+<H2>
+<A HREF="#toc7" NAME="sect7">Author</A></H2>
+<P>Xavier Leroy &lt;Xavier.Leroy@inria.fr&gt;
+</P>
+<P>Modified by Ross Johnson for use with <A HREF="http://sources.redhat.com/pthreads-win32">Pthreads-w32</A>.</P>
+<H2><A HREF="#toc8" NAME="sect8">See Also</A></H2>
+<P><A HREF="pthread_mutex_init.html"><B>pthread_mutex_init</B>(3)</A>
+, <A HREF="pthread_cond_init.html"><B>pthread_cond_init</B>(3)</A> ,
+<A HREF="pthread_cancel.html"><B>pthread_cancel</B>(3)</A> .
+</P>
+<HR>
+<P><A NAME="toc"></A><B>Table of Contents</B></P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect0" NAME="toc0">Name</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect1" NAME="toc1">Synopsis</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect2" NAME="toc2">Description</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect3" NAME="toc3">Cancellation</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect4" NAME="toc4">Async-signal
+ Safety</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect5" NAME="toc5">Return
+ Value</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect6" NAME="toc6">Errors</A>
+ </P>
+ <LI><P STYLE="margin-bottom: 0cm"><A HREF="#sect7" NAME="toc7">Author</A>
+ </P>
+ <LI><P><A HREF="#sect8" NAME="toc8">See Also</A>
+ </P>
+</UL>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/pthreads/misc.c b/pthreads/misc.c
new file mode 100644
index 000000000..06d1d2137
--- /dev/null
+++ b/pthreads/misc.c
@@ -0,0 +1,50 @@
+/*
+ * misc.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"
+
+
+#include "pthread_kill.c"
+#include "pthread_once.c"
+#include "pthread_self.c"
+#include "pthread_equal.c"
+#include "pthread_setconcurrency.c"
+#include "pthread_getconcurrency.c"
+#include "ptw32_new.c"
+#include "ptw32_calloc.c"
+#include "ptw32_reuse.c"
+#include "w32_CancelableWait.c"
diff --git a/pthreads/mutex.c b/pthreads/mutex.c
new file mode 100644
index 000000000..2e60dabe4
--- /dev/null
+++ b/pthreads/mutex.c
@@ -0,0 +1,59 @@
+/*
+ * 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
+ */
+
+#ifndef _UWIN
+# include <process.h>
+#endif
+#ifndef NEED_FTIME
+#include <sys/timeb.h>
+#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"
diff --git a/pthreads/need_errno.h b/pthreads/need_errno.h
new file mode 100644
index 000000000..2609f8d6b
--- /dev/null
+++ b/pthreads/need_errno.h
@@ -0,0 +1,132 @@
+/***
+* 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 <winsock.h>
+
+#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
+
+
+/* declare reference to errno */
+
+#if (defined(_MT) || defined(_MD) || defined(_DLL)) && !defined(_MAC)
+_CRTIMP extern 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 */
diff --git a/pthreads/nonportable.c b/pthreads/nonportable.c
new file mode 100644
index 000000000..6c2a990aa
--- /dev/null
+++ b/pthreads/nonportable.c
@@ -0,0 +1,46 @@
+/*
+ * nonportable.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"
+
+#include "pthread_mutexattr_setkind_np.c"
+#include "pthread_mutexattr_getkind_np.c"
+#include "pthread_getw32threadhandle_np.c"
+#include "pthread_delay_np.c"
+#include "pthread_num_processors_np.c"
+#include "pthread_win32_attach_detach_np.c"
+#include "pthread_timechange_handler_np.c"
diff --git a/pthreads/private.c b/pthreads/private.c
new file mode 100644
index 000000000..7e311b10e
--- /dev/null
+++ b/pthreads/private.c
@@ -0,0 +1,57 @@
+/*
+ * private.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/* Must be first to define HAVE_INLINABLE_INTERLOCKED_CMPXCHG */
+#include "ptw32_InterlockedCompareExchange.c"
+
+#include "ptw32_MCS_lock.c"
+#include "ptw32_is_attr.c"
+#include "ptw32_processInitialize.c"
+#include "ptw32_processTerminate.c"
+#include "ptw32_threadStart.c"
+#include "ptw32_threadDestroy.c"
+#include "ptw32_tkAssocCreate.c"
+#include "ptw32_tkAssocDestroy.c"
+#include "ptw32_callUserDestroyRoutines.c"
+#include "ptw32_semwait.c"
+#include "ptw32_timespec.c"
+#include "ptw32_relmillisecs.c"
+#include "ptw32_throw.c"
+#include "ptw32_getprocessors.c"
diff --git a/pthreads/pthread.c b/pthreads/pthread.c
new file mode 100644
index 000000000..660c25459
--- /dev/null
+++ b/pthreads/pthread.c
@@ -0,0 +1,65 @@
+/*
+ * pthread.c
+ *
+ * Description:
+ * This translation unit agregates pthreads-win32 translation units.
+ * It is used for inline optimisation of the library,
+ * maximising for speed at the expense of size.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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"
+
+/* The following are ordered for inlining */
+
+#include "private.c"
+#include "attr.c"
+#include "barrier.c"
+#include "cancel.c"
+#include "cleanup.c"
+#include "condvar.c"
+#include "create.c"
+#include "dll.c"
+#include "errno.c"
+#include "exit.c"
+#include "fork.c"
+#include "global.c"
+#include "misc.c"
+#include "mutex.c"
+#include "nonportable.c"
+#include "rwlock.c"
+#include "sched.c"
+#include "semaphore.c"
+#include "signal.c"
+#include "spin.c"
+#include "sync.c"
+#include "tsd.c"
diff --git a/pthreads/pthread.dsp b/pthreads/pthread.dsp
new file mode 100644
index 000000000..112bff72a
--- /dev/null
+++ b/pthreads/pthread.dsp
@@ -0,0 +1,142 @@
+# Microsoft Developer Studio Project File - Name="pthread" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=pthread - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "pthread.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "pthread.mak" CFG="pthread - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "pthread - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "pthread - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "pthread - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "."
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "__CLEANUP_C" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /c
+# SUBTRACT CPP /u
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x409 /i "." /d "NDEBUG" /d "PTW32_RC_MSC"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib ws2_32.lib /nologo /dll /pdb:none /machine:I386 /out:".\pthreadVC2.dll"
+
+!ELSEIF "$(CFG)" == "pthread - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "."
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "__CLEANUP_C" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PTW32_BUILD" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x409 /i "." /d "_DEBUG" /d "PTW32_RC_MSC"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib ws2_32.lib /nologo /dll /map /debug /machine:I386 /out:".\pthreadVC2.dll" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "pthread - Win32 Release"
+# Name "pthread - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\pthread.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\implement.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\pthread.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\sched.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\semaphore.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\version.rc
+
+!IF "$(CFG)" == "pthread - Win32 Release"
+
+# ADD BASE RSC /l 0xc09
+# ADD RSC /l 0x409 /i "." /d "PTW32_RC_MSC"
+
+!ELSEIF "$(CFG)" == "pthread - Win32 Debug"
+
+# ADD BASE RSC /l 0xc09
+# ADD RSC /l 0x409 /i "." /d "PTW32_RC_MSC"
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/pthreads/pthread.dsw b/pthreads/pthread.dsw
new file mode 100644
index 000000000..815a67872
--- /dev/null
+++ b/pthreads/pthread.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "pthread"=.\pthread.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/pthreads/pthread.h b/pthreads/pthread.h
new file mode 100644
index 000000000..f3d2dac96
--- /dev/null
+++ b/pthreads/pthread.h
@@ -0,0 +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,8,0,0
+#define PTW32_VERSION_STRING "2, 8, 0, 0\0"
+
+/* There are three implementations of cancel cleanup.
+ * Note that pthread.h is included in both application
+ * compilation units and also internally for the library.
+ * The code here and within the library aims to work
+ * for all reasonable combinations of environments.
+ *
+ * The three implementations are:
+ *
+ * WIN32 SEH
+ * C
+ * C++
+ *
+ * Please note that exiting a push/pop block via
+ * "return", "exit", "break", or "continue" will
+ * lead to different behaviour amongst applications
+ * depending upon whether the library was built
+ * using SEH, C++, or C. For example, a library built
+ * with SEH will call the cleanup routine, while both
+ * C++ and C built versions will not.
+ */
+
+/*
+ * Define defaults for cleanup code.
+ * Note: Unless the build explicitly defines one of the following, then
+ * we default to standard C style cleanup. This style uses setjmp/longjmp
+ * in the cancelation and thread exit implementations and therefore won't
+ * do stack unwinding if linked to applications that have it (e.g.
+ * C++ apps). This is currently consistent with most/all commercial Unix
+ * POSIX threads implementations.
+ */
+#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C )
+# define __CLEANUP_C
+#endif
+
+#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC))
+#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler.
+#endif
+
+/*
+ * Stop here if we are being included by the resource compiler.
+ */
+#ifndef RC_INVOKED
+
+#undef PTW32_LEVEL
+
+#if defined(_POSIX_SOURCE)
+#define PTW32_LEVEL 0
+/* Early POSIX */
+#endif
+
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
+#undef PTW32_LEVEL
+#define PTW32_LEVEL 1
+/* Include 1b, 1c and 1d */
+#endif
+
+#if defined(INCLUDE_NP)
+#undef PTW32_LEVEL
+#define PTW32_LEVEL 2
+/* Include Non-Portable extensions */
+#endif
+
+#define PTW32_LEVEL_MAX 3
+
+#if !defined(PTW32_LEVEL)
+#define PTW32_LEVEL PTW32_LEVEL_MAX
+/* Include everything */
+#endif
+
+#ifdef _UWIN
+# define HAVE_STRUCT_TIMESPEC 1
+# define HAVE_SIGNAL_H 1
+# undef HAVE_CONFIG_H
+# pragma comment(lib, "pthread")
+#endif
+
+/*
+ * -------------------------------------------------------------
+ *
+ *
+ * Module: pthread.h
+ *
+ * Purpose:
+ * Provides an implementation of PThreads based upon the
+ * standard:
+ *
+ * POSIX 1003.1-2001
+ * and
+ * The Single Unix Specification version 3
+ *
+ * (these two are equivalent)
+ *
+ * in order to enhance code portability between Windows,
+ * various commercial Unix implementations, and Linux.
+ *
+ * See the ANNOUNCE file for a full list of conforming
+ * routines and defined constants, and a list of missing
+ * routines and constants not defined in this implementation.
+ *
+ * Authors:
+ * There have been many contributors to this library.
+ * The initial implementation was contributed by
+ * John Bossom, and several others have provided major
+ * sections or revisions of parts of the implementation.
+ * Often significant effort has been contributed to
+ * find and fix important bugs and other problems to
+ * improve the reliability of the library, which sometimes
+ * is not reflected in the amount of code which changed as
+ * result.
+ * As much as possible, the contributors are acknowledged
+ * in the ChangeLog file in the source code distribution
+ * where their changes are noted in detail.
+ *
+ * Contributors are listed in the CONTRIBUTORS file.
+ *
+ * As usual, all bouquets go to the contributors, and all
+ * brickbats go to the project maintainer.
+ *
+ * Maintainer:
+ * The code base for this project is coordinated and
+ * eventually pre-tested, packaged, and made available by
+ *
+ * Ross Johnson <rpj@callisto.canberra.edu.au>
+ *
+ * QA Testers:
+ * Ultimately, the library is tested in the real world by
+ * a host of competent and demanding scientists and
+ * engineers who report bugs and/or provide solutions
+ * which are then fixed or incorporated into subsequent
+ * versions of the library. Each time a bug is fixed, a
+ * test case is written to prove the fix and ensure
+ * that later changes to the code don't reintroduce the
+ * same error. The number of test cases is slowly growing
+ * and therefore so is the code reliability.
+ *
+ * Compliance:
+ * See the file ANNOUNCE for the list of implemented
+ * and not-implemented routines and defined options.
+ * Of course, these are all defined is this file as well.
+ *
+ * Web site:
+ * The source code and other information about this library
+ * are available from
+ *
+ * http://sources.redhat.com/pthreads-win32/
+ *
+ * -------------------------------------------------------------
+ */
+
+/* Try to avoid including windows.h */
+#if defined(__MINGW32__) && defined(__cplusplus)
+#define PTW32_INCLUDE_WINDOWS_H
+#endif
+
+#ifdef PTW32_INCLUDE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__)
+/*
+ * VC++6.0 or early compiler's header has no DWORD_PTR type.
+ */
+typedef unsigned long DWORD_PTR;
+#endif
+/*
+ * -----------------
+ * autoconf switches
+ * -----------------
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifndef NEED_FTIME
+#include <time.h>
+#else /* NEED_FTIME */
+/* use native WIN32 time API */
+#endif /* NEED_FTIME */
+
+#if HAVE_SIGNAL_H
+#include <signal.h>
+#endif /* HAVE_SIGNAL_H */
+
+#include <setjmp.h>
+#include <limits.h>
+
+/*
+ * Boolean values to make us independent of system includes.
+ */
+enum {
+ PTW32_FALSE = 0,
+ PTW32_TRUE = (! PTW32_FALSE)
+};
+
+/*
+ * This is a duplicate of what is in the autoconf config.h,
+ * which is only used when building the pthread-win32 libraries.
+ */
+
+#ifndef PTW32_CONFIG_H
+# if defined(WINCE)
+# define NEED_ERRNO
+# define NEED_SEM
+# endif
+# if defined(_UWIN) || defined(__MINGW32__)
+# define HAVE_MODE_T
+# endif
+#endif
+
+/*
+ *
+ */
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+#ifdef NEED_ERRNO
+#include "need_errno.h"
+#else
+#include <errno.h>
+#endif
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+/*
+ * Several systems don't define some error numbers.
+ */
+#ifndef ENOTSUP
+# define ENOTSUP 48 /* This is the value in Solaris. */
+#endif
+
+#ifndef ETIMEDOUT
+# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
+#endif
+
+#ifndef ENOSYS
+# define ENOSYS 140 /* Semi-arbitrary value */
+#endif
+
+#ifndef EDEADLK
+# ifdef EDEADLOCK
+# define EDEADLK EDEADLOCK
+# else
+# define EDEADLK 36 /* This is the value in MSVC. */
+# endif
+#endif
+
+#include <sched.h>
+
+/*
+ * To avoid including windows.h we define only those things that we
+ * actually need from it.
+ */
+#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 {
+ long tv_sec;
+ long tv_nsec;
+};
+#endif /* HAVE_STRUCT_TIMESPEC */
+
+#ifndef SIG_BLOCK
+#define SIG_BLOCK 0
+#endif /* SIG_BLOCK */
+
+#ifndef SIG_UNBLOCK
+#define SIG_UNBLOCK 1
+#endif /* SIG_UNBLOCK */
+
+#ifndef SIG_SETMASK
+#define SIG_SETMASK 2
+#endif /* SIG_SETMASK */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*
+ * -------------------------------------------------------------
+ *
+ * POSIX 1003.1-2001 Options
+ * =========================
+ *
+ * Options are normally set in <unistd.h>, which is not provided
+ * with pthreads-win32.
+ *
+ * For conformance with the Single Unix Specification (version 3), all of the
+ * options below are defined, and have a value of either -1 (not supported)
+ * or 200112L (supported).
+ *
+ * These options can neither be left undefined nor have a value of 0, because
+ * either indicates that sysconf(), which is not implemented, may be used at
+ * runtime to check the status of the option.
+ *
+ * _POSIX_THREADS (== 200112L)
+ * If == 200112L, you can use threads
+ *
+ * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L)
+ * If == 200112L, you can control the size of a thread's
+ * stack
+ * pthread_attr_getstacksize
+ * pthread_attr_setstacksize
+ *
+ * _POSIX_THREAD_ATTR_STACKADDR (== -1)
+ * If == 200112L, you can allocate and control a thread's
+ * stack. If not supported, the following functions
+ * will return ENOSYS, indicating they are not
+ * supported:
+ * pthread_attr_getstackaddr
+ * pthread_attr_setstackaddr
+ *
+ * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1)
+ * If == 200112L, you can use realtime scheduling.
+ * This option indicates that the behaviour of some
+ * implemented functions conforms to the additional TPS
+ * requirements in the standard. E.g. rwlocks favour
+ * writers over readers when threads have equal priority.
+ *
+ * _POSIX_THREAD_PRIO_INHERIT (== -1)
+ * If == 200112L, you can create priority inheritance
+ * mutexes.
+ * pthread_mutexattr_getprotocol +
+ * pthread_mutexattr_setprotocol +
+ *
+ * _POSIX_THREAD_PRIO_PROTECT (== -1)
+ * If == 200112L, you can create priority ceiling mutexes
+ * Indicates the availability of:
+ * pthread_mutex_getprioceiling
+ * pthread_mutex_setprioceiling
+ * pthread_mutexattr_getprioceiling
+ * pthread_mutexattr_getprotocol +
+ * pthread_mutexattr_setprioceiling
+ * pthread_mutexattr_setprotocol +
+ *
+ * _POSIX_THREAD_PROCESS_SHARED (== -1)
+ * If set, you can create mutexes and condition
+ * variables that can be shared with another
+ * process.If set, indicates the availability
+ * of:
+ * pthread_mutexattr_getpshared
+ * pthread_mutexattr_setpshared
+ * pthread_condattr_getpshared
+ * pthread_condattr_setpshared
+ *
+ * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L)
+ * If == 200112L you can use the special *_r library
+ * functions that provide thread-safe behaviour
+ *
+ * _POSIX_READER_WRITER_LOCKS (== 200112L)
+ * If == 200112L, you can use read/write locks
+ *
+ * _POSIX_SPIN_LOCKS (== 200112L)
+ * If == 200112L, you can use spin locks
+ *
+ * _POSIX_BARRIERS (== 200112L)
+ * If == 200112L, you can use barriers
+ *
+ * + These functions provide both 'inherit' and/or
+ * 'protect' protocol, based upon these macro
+ * settings.
+ *
+ * -------------------------------------------------------------
+ */
+
+/*
+ * POSIX Options
+ */
+#undef _POSIX_THREADS
+#define _POSIX_THREADS 200112L
+
+#undef _POSIX_READER_WRITER_LOCKS
+#define _POSIX_READER_WRITER_LOCKS 200112L
+
+#undef _POSIX_SPIN_LOCKS
+#define _POSIX_SPIN_LOCKS 200112L
+
+#undef _POSIX_BARRIERS
+#define _POSIX_BARRIERS 200112L
+
+#undef _POSIX_THREAD_SAFE_FUNCTIONS
+#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L
+
+#undef _POSIX_THREAD_ATTR_STACKSIZE
+#define _POSIX_THREAD_ATTR_STACKSIZE 200112L
+
+/*
+ * The following options are not supported
+ */
+#undef _POSIX_THREAD_ATTR_STACKADDR
+#define _POSIX_THREAD_ATTR_STACKADDR -1
+
+#undef _POSIX_THREAD_PRIO_INHERIT
+#define _POSIX_THREAD_PRIO_INHERIT -1
+
+#undef _POSIX_THREAD_PRIO_PROTECT
+#define _POSIX_THREAD_PRIO_PROTECT -1
+
+/* TPS is not fully supported. */
+#undef _POSIX_THREAD_PRIORITY_SCHEDULING
+#define _POSIX_THREAD_PRIORITY_SCHEDULING -1
+
+#undef _POSIX_THREAD_PROCESS_SHARED
+#define _POSIX_THREAD_PROCESS_SHARED -1
+
+
+/*
+ * POSIX 1003.1-2001 Limits
+ * ===========================
+ *
+ * These limits are normally set in <limits.h>, which is not provided with
+ * pthreads-win32.
+ *
+ * PTHREAD_DESTRUCTOR_ITERATIONS
+ * Maximum number of attempts to destroy
+ * a thread's thread-specific data on
+ * termination (must be at least 4)
+ *
+ * PTHREAD_KEYS_MAX
+ * Maximum number of thread-specific data keys
+ * available per process (must be at least 128)
+ *
+ * PTHREAD_STACK_MIN
+ * Minimum supported stack size for a thread
+ *
+ * PTHREAD_THREADS_MAX
+ * Maximum number of threads supported per
+ * process (must be at least 64).
+ *
+ * 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 DLL code, you should define PTW32_BUILD so that
+ * the variables/functions are exported correctly. When using the DLL,
+ * do NOT define PTW32_BUILD, and then the variables/functions will
+ * be imported correctly.
+ */
+#ifndef PTW32_STATIC_LIB
+# ifdef PTW32_BUILD
+# define PTW32_DLLPORT __declspec (dllexport)
+# else
+# define PTW32_DLLPORT __declspec (dllimport)
+# endif
+#else
+# define PTW32_DLLPORT
+#endif
+
+/*
+ * The Open Watcom C/C++ compiler uses a non-standard calling convention
+ * that passes function args in registers unless __cdecl is explicitly specified
+ * in exposed function prototypes.
+ *
+ * We force all calls to cdecl even though this could slow Watcom code down
+ * slightly. If you know that the Watcom compiler will be used to build both
+ * the DLL and application, then you can probably define this as a null string.
+ * Remember that pthread.h (this file) is used for both the DLL and application builds.
+ */
+#define PTW32_CDECL __cdecl
+
+#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX
+# include <sys/types.h>
+#else
+/*
+ * Generic handle type - intended to extend uniqueness beyond
+ * that available with a simple pointer. It should scale for either
+ * IA-32 or IA-64.
+ */
+typedef struct {
+ void * p; /* Pointer to actual object */
+ unsigned int x; /* Extra information - reuse count etc */
+} ptw32_handle_t;
+
+typedef ptw32_handle_t pthread_t;
+typedef struct pthread_attr_t_ * pthread_attr_t;
+typedef struct pthread_once_t_ pthread_once_t;
+typedef struct pthread_key_t_ * pthread_key_t;
+typedef struct pthread_mutex_t_ * pthread_mutex_t;
+typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t;
+typedef struct pthread_cond_t_ * pthread_cond_t;
+typedef struct pthread_condattr_t_ * pthread_condattr_t;
+#endif
+typedef struct pthread_rwlock_t_ * pthread_rwlock_t;
+typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t;
+typedef struct pthread_spinlock_t_ * pthread_spinlock_t;
+typedef struct pthread_barrier_t_ * pthread_barrier_t;
+typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t;
+
+/*
+ * ====================
+ * ====================
+ * POSIX Threads
+ * ====================
+ * ====================
+ */
+
+enum {
+/*
+ * pthread_attr_{get,set}detachstate
+ */
+ PTHREAD_CREATE_JOINABLE = 0, /* Default */
+ PTHREAD_CREATE_DETACHED = 1,
+
+/*
+ * pthread_attr_{get,set}inheritsched
+ */
+ PTHREAD_INHERIT_SCHED = 0,
+ PTHREAD_EXPLICIT_SCHED = 1, /* Default */
+
+/*
+ * pthread_{get,set}scope
+ */
+ PTHREAD_SCOPE_PROCESS = 0,
+ PTHREAD_SCOPE_SYSTEM = 1, /* Default */
+
+/*
+ * pthread_setcancelstate paramters
+ */
+ PTHREAD_CANCEL_ENABLE = 0, /* Default */
+ PTHREAD_CANCEL_DISABLE = 1,
+
+/*
+ * pthread_setcanceltype parameters
+ */
+ PTHREAD_CANCEL_ASYNCHRONOUS = 0,
+ PTHREAD_CANCEL_DEFERRED = 1, /* Default */
+
+/*
+ * pthread_mutexattr_{get,set}pshared
+ * pthread_condattr_{get,set}pshared
+ */
+ PTHREAD_PROCESS_PRIVATE = 0,
+ PTHREAD_PROCESS_SHARED = 1,
+
+/*
+ * pthread_barrier_wait
+ */
+ PTHREAD_BARRIER_SERIAL_THREAD = -1
+};
+
+/*
+ * ====================
+ * ====================
+ * Cancelation
+ * ====================
+ * ====================
+ */
+#define PTHREAD_CANCELED ((void *) -1)
+
+
+/*
+ * ====================
+ * ====================
+ * Once Key
+ * ====================
+ * ====================
+ */
+#define PTHREAD_ONCE_INIT { 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 (pthread_attr_t *,
+ int *);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr,
+ int inheritsched);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(pthread_attr_t * attr,
+ int * inheritsched);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *,
+ int);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *,
+ int *);
+
+/*
+ * PThread Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,
+ const pthread_attr_t * attr,
+ void *(*start) (void *),
+ void *arg);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1,
+ pthread_t t2);
+
+PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread,
+ void **value_ptr);
+
+PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state,
+ int *oldstate);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type,
+ int *oldtype);
+
+PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control,
+ void (*init_routine) (void));
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute);
+
+PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup,
+ void (*routine) (void *),
+ void *arg);
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+/*
+ * Thread Specific Data Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key,
+ void (*destructor) (void *));
+
+PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key,
+ const void *value);
+
+PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key);
+
+
+/*
+ * Mutex Attribute Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t
+ * attr,
+ int *pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,
+ int pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind);
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind);
+
+/*
+ * Barrier Attribute Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t
+ * attr,
+ int *pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr,
+ int pshared);
+
+/*
+ * Mutex Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex,
+ const pthread_mutexattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t *mutex,
+ const struct timespec *abstime);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex);
+
+/*
+ * Spinlock Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock);
+
+/*
+ * Barrier Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier,
+ const pthread_barrierattr_t * attr,
+ unsigned int count);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier);
+
+/*
+ * Condition Variable Attribute Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr,
+ int *pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr,
+ int pshared);
+
+/*
+ * Condition Variable Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond,
+ const pthread_condattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond,
+ pthread_mutex_t * mutex);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond,
+ pthread_mutex_t * mutex,
+ const struct timespec *abstime);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond);
+
+/*
+ * Scheduling
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread,
+ int policy,
+ const struct sched_param *param);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread,
+ int *policy,
+ struct sched_param *param);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void);
+
+/*
+ * Read-Write Lock Functions
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock,
+ const pthread_rwlockattr_t *attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock,
+ const struct timespec *abstime);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock,
+ const struct timespec *abstime);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
+ int *pshared);
+
+PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr,
+ int pshared);
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1
+
+/*
+ * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32
+ * already have signal.h that don't define these.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig);
+
+/*
+ * Non-portable functions
+ */
+
+/*
+ * Compatibility with Linux.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr,
+ int kind);
+PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr,
+ int *kind);
+
+/*
+ * Possibly supported by other POSIX threads implementations
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval);
+PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void);
+
+/*
+ * Useful if an application wants to statically link
+ * the lib rather than load the DLL at run-time.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void);
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void);
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void);
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void);
+
+/*
+ * Features that are auto-detected at load/run time.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int);
+enum ptw32_features {
+ PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */
+ PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */
+};
+
+/*
+ * Register a system time change with the library.
+ * Causes the library to perform various functions
+ * in response to the change. Should be called whenever
+ * the application's top level window receives a
+ * WM_TIMECHANGE message. It can be passed directly to
+ * pthread_create() as a new thread if desired.
+ */
+PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *);
+
+#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+
+/*
+ * Returns the Win32 HANDLE for the POSIX thread.
+ */
+PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread);
+
+
+/*
+ * Protected Methods
+ *
+ * This function blocks until the given WIN32 handle
+ * is signaled or pthread_cancel had been called.
+ * This function allows the caller to hook into the
+ * PThreads cancel mechanism. It is implemented using
+ *
+ * WaitForMultipleObjects
+ *
+ * on 'waitHandle' and a manually reset WIN32 Event
+ * used to implement pthread_cancel. The 'timeout'
+ * argument to TimedWait is simply passed to
+ * WaitForMultipleObjects.
+ */
+PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle);
+PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle,
+ DWORD timeout);
+
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+/*
+ * Thread-Safe C Runtime Library Mappings.
+ */
+#ifndef _UWIN
+# if defined(NEED_ERRNO)
+ PTW32_DLLPORT int * PTW32_CDECL _errno( void );
+# else
+# ifndef errno
+# if (defined(_MT) || defined(_DLL))
+ __declspec(dllimport) extern int * __cdecl _errno(void);
+# define errno (*_errno())
+# endif
+# endif
+# endif
+#endif
+
+/*
+ * WIN32 C runtime library had been made thread-safe
+ * without affecting the user interface. Provide
+ * mappings from the UNIX thread-safe versions to
+ * the standard C runtime library calls.
+ * Only provide function mappings for functions that
+ * actually exist on WIN32.
+ */
+
+#if !defined(__MINGW32__)
+#define strtok_r( _s, _sep, _lasts ) \
+ ( *(_lasts) = strtok( (_s), (_sep) ) )
+#endif /* !__MINGW32__ */
+
+#define asctime_r( _tm, _buf ) \
+ ( strcpy( (_buf), asctime( (_tm) ) ), \
+ (_buf) )
+
+#define ctime_r( _clock, _buf ) \
+ ( strcpy( (_buf), ctime( (_clock) ) ), \
+ (_buf) )
+
+#define gmtime_r( _clock, _result ) \
+ ( *(_result) = *gmtime( (_clock) ), \
+ (_result) )
+
+#define localtime_r( _clock, _result ) \
+ ( *(_result) = *localtime( (_clock) ), \
+ (_result) )
+
+#define rand_r( _seed ) \
+ ( _seed == _seed? rand() : rand() )
+
+
+/*
+ * Some compiler environments don't define some things.
+ */
+#if defined(__BORLANDC__)
+# define _ftime ftime
+# define _timeb timeb
+#endif
+
+#ifdef __cplusplus
+
+/*
+ * Internal exceptions
+ */
+class ptw32_exception {};
+class ptw32_exception_cancel : public ptw32_exception {};
+class ptw32_exception_exit : public ptw32_exception {};
+
+#endif
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+
+/* FIXME: This is only required if the library was built using SEH */
+/*
+ * Get internal SEH tag
+ */
+PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void);
+
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+#ifndef PTW32_BUILD
+
+#ifdef __CLEANUP_SEH
+
+/*
+ * Redefine the SEH __except keyword to ensure that applications
+ * propagate our internal exceptions up to the library's internal handlers.
+ */
+#define __except( E ) \
+ __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \
+ ? EXCEPTION_CONTINUE_SEARCH : ( E ) )
+
+#endif /* __CLEANUP_SEH */
+
+#ifdef __CLEANUP_CXX
+
+/*
+ * Redefine the C++ catch keyword to ensure that applications
+ * propagate our internal exceptions up to the library's internal handlers.
+ */
+#ifdef _MSC_VER
+ /*
+ * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'
+ * if you want Pthread-Win32 cancelation and pthread_exit to work.
+ */
+
+#ifndef PtW32NoCatchWarn
+
+#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.")
+#pragma message("------------------------------------------------------------------")
+#pragma message("When compiling applications with MSVC++ and C++ exception handling:")
+#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads")
+#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread")
+#pragma message(" cancelation and pthread_exit to work. For example:")
+#pragma message("")
+#pragma message(" #ifdef PtW32CatchAll")
+#pragma message(" PtW32CatchAll")
+#pragma message(" #else")
+#pragma message(" catch(...)")
+#pragma message(" #endif")
+#pragma message(" {")
+#pragma message(" /* Catchall block processing */")
+#pragma message(" }")
+#pragma message("------------------------------------------------------------------")
+
+#endif
+
+#define PtW32CatchAll \
+ catch( ptw32_exception & ) { throw; } \
+ catch( ... )
+
+#else /* _MSC_VER */
+
+#define catch( E ) \
+ catch( ptw32_exception & ) { throw; } \
+ catch( E )
+
+#endif /* _MSC_VER */
+
+#endif /* __CLEANUP_CXX */
+
+#endif /* ! PTW32_BUILD */
+
+#ifdef __cplusplus
+} /* End of extern "C" */
+#endif /* __cplusplus */
+
+#ifdef PTW32__HANDLE_DEF
+# undef HANDLE
+#endif
+#ifdef PTW32__DWORD_DEF
+# undef DWORD
+#endif
+
+#undef PTW32_LEVEL
+#undef PTW32_LEVEL_MAX
+
+#endif /* ! RC_INVOKED */
+
+#endif /* PTHREAD_H */
diff --git a/pthreads/pthread_attr_destroy.c b/pthreads/pthread_attr_destroy.c
new file mode 100644
index 000000000..8b3e04c53
--- /dev/null
+++ b/pthreads/pthread_attr_destroy.c
@@ -0,0 +1,79 @@
+/*
+ * pthread_attr_destroy.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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_attr_destroy (pthread_attr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Destroys a thread attributes object.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ *
+ * DESCRIPTION
+ * Destroys a thread attributes object.
+ *
+ * NOTES:
+ * 1) Does not affect threads created with 'attr'.
+ *
+ * RESULTS
+ * 0 successfully destroyed attr,
+ * EINVAL 'attr' is invalid.
+ *
+ * ------------------------------------------------------
+ */
+{
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ /*
+ * Set the attribute object to a specific invalid value.
+ */
+ (*attr)->valid = 0;
+ free (*attr);
+ *attr = NULL;
+
+ return 0;
+}
diff --git a/pthreads/pthread_attr_getdetachstate.c b/pthreads/pthread_attr_getdetachstate.c
new file mode 100644
index 000000000..978f28849
--- /dev/null
+++ b/pthreads/pthread_attr_getdetachstate.c
@@ -0,0 +1,87 @@
+/*
+ * pthread_attr_getdetachstate.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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_attr_getdetachstate (const pthread_attr_t * attr, int *detachstate)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function determines whether threads created with
+ * 'attr' will run detached.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ * detachstate
+ * pointer to an integer into which is returned one
+ * of:
+ *
+ * PTHREAD_CREATE_JOINABLE
+ * Thread ID is valid, must be joined
+ *
+ * PTHREAD_CREATE_DETACHED
+ * Thread ID is invalid, cannot be joined,
+ * canceled, or modified
+ *
+ *
+ * DESCRIPTION
+ * This function determines whether threads created with
+ * 'attr' will run detached.
+ *
+ * NOTES:
+ * 1) You cannot join or cancel detached threads.
+ *
+ * RESULTS
+ * 0 successfully retrieved detach state,
+ * EINVAL 'attr' is invalid
+ *
+ * ------------------------------------------------------
+ */
+{
+ if (ptw32_is_attr (attr) != 0 || detachstate == NULL)
+ {
+ *detachstate = PTHREAD_CREATE_DETACHED;
+ return EINVAL;
+ }
+
+ *detachstate = (*attr)->detachstate;
+ return 0;
+}
diff --git a/pthreads/pthread_attr_getinheritsched.c b/pthreads/pthread_attr_getinheritsched.c
new file mode 100644
index 000000000..5085077a6
--- /dev/null
+++ b/pthreads/pthread_attr_getinheritsched.c
@@ -0,0 +1,51 @@
+/*
+ * pthread_attr_getinheritsched.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+int
+pthread_attr_getinheritsched (pthread_attr_t * attr, int *inheritsched)
+{
+ if (ptw32_is_attr (attr) != 0 || inheritsched == NULL)
+ {
+ return EINVAL;
+ }
+
+ *inheritsched = (*attr)->inheritsched;
+ return 0;
+}
diff --git a/pthreads/pthread_attr_getschedparam.c b/pthreads/pthread_attr_getschedparam.c
new file mode 100644
index 000000000..ab89b2241
--- /dev/null
+++ b/pthreads/pthread_attr_getschedparam.c
@@ -0,0 +1,52 @@
+/*
+ * pthread_attr_getschedparam.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+int
+pthread_attr_getschedparam (const pthread_attr_t * attr,
+ struct sched_param *param)
+{
+ if (ptw32_is_attr (attr) != 0 || param == NULL)
+ {
+ return EINVAL;
+ }
+
+ memcpy (param, &(*attr)->param, sizeof (*param));
+ return 0;
+}
diff --git a/pthreads/pthread_attr_getschedpolicy.c b/pthreads/pthread_attr_getschedpolicy.c
new file mode 100644
index 000000000..04adbd5c6
--- /dev/null
+++ b/pthreads/pthread_attr_getschedpolicy.c
@@ -0,0 +1,61 @@
+/*
+ * pthread_attr_getschedpolicy.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+int
+pthread_attr_getschedpolicy (pthread_attr_t * attr, int *policy)
+{
+ if (ptw32_is_attr (attr) != 0 || policy == NULL)
+ {
+ return EINVAL;
+ }
+
+ /*
+ * Validate the policy arg.
+ * Check that a policy constant wasn't passed rather than &policy.
+ */
+ if (policy <= (int *) SCHED_MAX)
+ {
+ return EINVAL;
+ }
+
+ *policy = SCHED_OTHER;
+
+ return 0;
+}
diff --git a/pthreads/pthread_attr_getscope.c b/pthreads/pthread_attr_getscope.c
new file mode 100644
index 000000000..3c863821e
--- /dev/null
+++ b/pthreads/pthread_attr_getscope.c
@@ -0,0 +1,54 @@
+/*
+ * pthread_attr_getscope.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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"
+
+/* ignore warning "unreferenced formal parameter" */
+#ifdef _MSC_VER
+#pragma warning( disable : 4100 )
+#endif
+
+int
+pthread_attr_getscope (const pthread_attr_t * attr, int *contentionscope)
+{
+#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
+ *contentionscope = (*attr)->contentionscope;
+ return 0;
+#else
+ return ENOSYS;
+#endif
+}
diff --git a/pthreads/pthread_attr_getstackaddr.c b/pthreads/pthread_attr_getstackaddr.c
new file mode 100644
index 000000000..9b5595928
--- /dev/null
+++ b/pthreads/pthread_attr_getstackaddr.c
@@ -0,0 +1,97 @@
+/*
+ * pthread_attr_getstackaddr.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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"
+
+/* ignore warning "unreferenced formal parameter" */
+#ifdef _MSC_VER
+#pragma warning( disable : 4100 )
+#endif
+
+int
+pthread_attr_getstackaddr (const pthread_attr_t * attr, void **stackaddr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function determines the address of the stack
+ * on which threads created with 'attr' will run.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ * stackaddr
+ * pointer into which is returned the stack address.
+ *
+ *
+ * DESCRIPTION
+ * This function determines the address of the stack
+ * on which threads created with 'attr' will run.
+ *
+ * NOTES:
+ * 1) Function supported only if this macro is
+ * defined:
+ *
+ * _POSIX_THREAD_ATTR_STACKADDR
+ *
+ * 2) Create only one thread for each stack
+ * address..
+ *
+ * RESULTS
+ * 0 successfully retreived stack address,
+ * EINVAL 'attr' is invalid
+ * ENOSYS function not supported
+ *
+ * ------------------------------------------------------
+ */
+{
+#if defined( _POSIX_THREAD_ATTR_STACKADDR )
+
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ *stackaddr = (*attr)->stackaddr;
+ return 0;
+
+#else
+
+ return ENOSYS;
+
+#endif /* _POSIX_THREAD_ATTR_STACKADDR */
+}
diff --git a/pthreads/pthread_attr_getstacksize.c b/pthreads/pthread_attr_getstacksize.c
new file mode 100644
index 000000000..da8db636c
--- /dev/null
+++ b/pthreads/pthread_attr_getstacksize.c
@@ -0,0 +1,100 @@
+/*
+ * pthread_attr_getstacksize.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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"
+
+/* ignore warning "unreferenced formal parameter" */
+#ifdef _MSC_VER
+#pragma warning( disable : 4100 )
+#endif
+
+int
+pthread_attr_getstacksize (const pthread_attr_t * attr, size_t * stacksize)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function determines the size of the stack on
+ * which threads created with 'attr' will run.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ * stacksize
+ * pointer to size_t into which is returned the
+ * stack size, in bytes.
+ *
+ *
+ * DESCRIPTION
+ * This function determines the size of the stack on
+ * which threads created with 'attr' will run.
+ *
+ * NOTES:
+ * 1) Function supported only if this macro is
+ * defined:
+ *
+ * _POSIX_THREAD_ATTR_STACKSIZE
+ *
+ * 2) Use on newly created attributes object to
+ * find the default stack size.
+ *
+ * RESULTS
+ * 0 successfully retrieved stack size,
+ * EINVAL 'attr' is invalid
+ * ENOSYS function not supported
+ *
+ * ------------------------------------------------------
+ */
+{
+#ifdef _POSIX_THREAD_ATTR_STACKSIZE
+
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ /* Everything is okay. */
+ *stacksize = (*attr)->stacksize;
+ return 0;
+
+#else
+
+ return ENOSYS;
+
+#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
+
+}
diff --git a/pthreads/pthread_attr_init.c b/pthreads/pthread_attr_init.c
new file mode 100644
index 000000000..6c10bd3e7
--- /dev/null
+++ b/pthreads/pthread_attr_init.c
@@ -0,0 +1,117 @@
+/*
+ * pthread_attr_init.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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_attr_init (pthread_attr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Initializes a thread attributes object with default
+ * attributes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ *
+ * DESCRIPTION
+ * Initializes a thread attributes object with default
+ * attributes.
+ *
+ * NOTES:
+ * 1) Used to define thread attributes
+ *
+ * RESULTS
+ * 0 successfully initialized attr,
+ * ENOMEM insufficient memory for attr.
+ *
+ * ------------------------------------------------------
+ */
+{
+ pthread_attr_t attr_result;
+
+ if (attr == NULL)
+ {
+ /* This is disallowed. */
+ return EINVAL;
+ }
+
+ attr_result = (pthread_attr_t) malloc (sizeof (*attr_result));
+
+ if (attr_result == NULL)
+ {
+ return ENOMEM;
+ }
+
+#ifdef _POSIX_THREAD_ATTR_STACKSIZE
+ /*
+ * Default to zero size. Unless changed explicitly this
+ * will allow Win32 to set the size to that of the
+ * main thread.
+ */
+ attr_result->stacksize = 0;
+#endif
+
+#ifdef _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
+ memset (&(attr_result->sigmask), 0, sizeof (sigset_t));
+#endif /* HAVE_SIGSET_T */
+
+ /*
+ * Win32 sets new threads to THREAD_PRIORITY_NORMAL and
+ * not to that of the parent thread. We choose to default to
+ * this arrangement.
+ */
+ attr_result->param.sched_priority = THREAD_PRIORITY_NORMAL;
+ attr_result->inheritsched = PTHREAD_EXPLICIT_SCHED;
+ attr_result->contentionscope = PTHREAD_SCOPE_SYSTEM;
+
+ attr_result->valid = PTW32_ATTR_VALID;
+
+ *attr = attr_result;
+
+ return 0;
+}
diff --git a/pthreads/pthread_attr_setdetachstate.c b/pthreads/pthread_attr_setdetachstate.c
new file mode 100644
index 000000000..784642a80
--- /dev/null
+++ b/pthreads/pthread_attr_setdetachstate.c
@@ -0,0 +1,91 @@
+/*
+ * pthread_attr_setdetachstate.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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_attr_setdetachstate (pthread_attr_t * attr, int detachstate)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function specifies whether threads created with
+ * 'attr' will run detached.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ * detachstate
+ * an integer containing one of:
+ *
+ * PTHREAD_CREATE_JOINABLE
+ * Thread ID is valid, must be joined
+ *
+ * PTHREAD_CREATE_DETACHED
+ * Thread ID is invalid, cannot be joined,
+ * canceled, or modified
+ *
+ *
+ * DESCRIPTION
+ * This function specifies whether threads created with
+ * 'attr' will run detached.
+ *
+ * NOTES:
+ * 1) You cannot join or cancel detached threads.
+ *
+ * RESULTS
+ * 0 successfully set detach state,
+ * EINVAL 'attr' or 'detachstate' is invalid
+ *
+ * ------------------------------------------------------
+ */
+{
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ if (detachstate != PTHREAD_CREATE_JOINABLE &&
+ detachstate != PTHREAD_CREATE_DETACHED)
+ {
+ return EINVAL;
+ }
+
+ (*attr)->detachstate = detachstate;
+ return 0;
+}
diff --git a/pthreads/pthread_attr_setinheritsched.c b/pthreads/pthread_attr_setinheritsched.c
new file mode 100644
index 000000000..e0a407a3b
--- /dev/null
+++ b/pthreads/pthread_attr_setinheritsched.c
@@ -0,0 +1,57 @@
+/*
+ * pthread_attr_setinheritsched.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+int
+pthread_attr_setinheritsched (pthread_attr_t * attr, int inheritsched)
+{
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ if (PTHREAD_INHERIT_SCHED != inheritsched
+ && PTHREAD_EXPLICIT_SCHED != inheritsched)
+ {
+ return EINVAL;
+ }
+
+ (*attr)->inheritsched = inheritsched;
+ return 0;
+}
diff --git a/pthreads/pthread_attr_setschedparam.c b/pthreads/pthread_attr_setschedparam.c
new file mode 100644
index 000000000..f246bfae7
--- /dev/null
+++ b/pthreads/pthread_attr_setschedparam.c
@@ -0,0 +1,63 @@
+/*
+ * pthread_attr_setschedparam.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+int
+pthread_attr_setschedparam (pthread_attr_t * attr,
+ const struct sched_param *param)
+{
+ int priority;
+
+ if (ptw32_is_attr (attr) != 0 || param == NULL)
+ {
+ return EINVAL;
+ }
+
+ priority = param->sched_priority;
+
+ /* Validate priority level. */
+ if (priority < sched_get_priority_min (SCHED_OTHER) ||
+ priority > sched_get_priority_max (SCHED_OTHER))
+ {
+ return EINVAL;
+ }
+
+ memcpy (&(*attr)->param, param, sizeof (*param));
+ return 0;
+}
diff --git a/pthreads/pthread_attr_setschedpolicy.c b/pthreads/pthread_attr_setschedpolicy.c
new file mode 100644
index 000000000..45ff16597
--- /dev/null
+++ b/pthreads/pthread_attr_setschedpolicy.c
@@ -0,0 +1,55 @@
+/*
+ * pthread_attr_setschedpolicy.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+int
+pthread_attr_setschedpolicy (pthread_attr_t * attr, int policy)
+{
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ if (policy != SCHED_OTHER)
+ {
+ return ENOTSUP;
+ }
+
+ return 0;
+}
diff --git a/pthreads/pthread_attr_setscope.c b/pthreads/pthread_attr_setscope.c
new file mode 100644
index 000000000..9cef423b2
--- /dev/null
+++ b/pthreads/pthread_attr_setscope.c
@@ -0,0 +1,62 @@
+/*
+ * pthread_attr_setscope.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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"
+
+/* ignore warning "unreferenced formal parameter" */
+#ifdef _MSC_VER
+#pragma warning( disable : 4100 )
+#endif
+
+int
+pthread_attr_setscope (pthread_attr_t * attr, int contentionscope)
+{
+#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
+ switch (contentionscope)
+ {
+ case PTHREAD_SCOPE_SYSTEM:
+ (*attr)->contentionscope = contentionscope;
+ return 0;
+ case PTHREAD_SCOPE_PROCESS:
+ return ENOTSUP;
+ default:
+ return EINVAL;
+ }
+#else
+ return ENOSYS;
+#endif
+}
diff --git a/pthreads/pthread_attr_setstackaddr.c b/pthreads/pthread_attr_setstackaddr.c
new file mode 100644
index 000000000..96a832097
--- /dev/null
+++ b/pthreads/pthread_attr_setstackaddr.c
@@ -0,0 +1,97 @@
+/*
+ * pthread_attr_setstackaddr.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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_attr_setstackaddr (pthread_attr_t * attr, void *stackaddr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Threads created with 'attr' will run on the stack
+ * starting at 'stackaddr'.
+ * Stack must be at least PTHREAD_STACK_MIN bytes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ * stacksize
+ * stack size, in bytes.
+ *
+ *
+ * DESCRIPTION
+ * Threads created with 'attr' will run on the stack
+ * starting at 'stackaddr'.
+ * Stack must be at least PTHREAD_STACK_MIN bytes.
+ *
+ * NOTES:
+ * 1) Function supported only if this macro is
+ * defined:
+ *
+ * _POSIX_THREAD_ATTR_STACKADDR
+ *
+ * 2) Create only one thread for each stack
+ * address..
+ *
+ * 3) Ensure that stackaddr is aligned.
+ *
+ * RESULTS
+ * 0 successfully set stack address,
+ * EINVAL 'attr' is invalid
+ * ENOSYS function not supported
+ *
+ * ------------------------------------------------------
+ */
+{
+#if defined( _POSIX_THREAD_ATTR_STACKADDR )
+
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ (*attr)->stackaddr = stackaddr;
+ return 0;
+
+#else
+
+ return ENOSYS;
+
+#endif /* _POSIX_THREAD_ATTR_STACKADDR */
+}
diff --git a/pthreads/pthread_attr_setstacksize.c b/pthreads/pthread_attr_setstacksize.c
new file mode 100644
index 000000000..9df46afc4
--- /dev/null
+++ b/pthreads/pthread_attr_setstacksize.c
@@ -0,0 +1,110 @@
+/*
+ * pthread_attr_setstacksize.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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_attr_setstacksize (pthread_attr_t * attr, size_t stacksize)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function specifies the size of the stack on
+ * which threads created with 'attr' will run.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_attr_t
+ *
+ * stacksize
+ * stack size, in bytes.
+ *
+ *
+ * DESCRIPTION
+ * This function specifies the size of the stack on
+ * which threads created with 'attr' will run.
+ *
+ * NOTES:
+ * 1) Function supported only if this macro is
+ * defined:
+ *
+ * _POSIX_THREAD_ATTR_STACKSIZE
+ *
+ * 2) Find the default first (using
+ * pthread_attr_getstacksize), then increase
+ * by multiplying.
+ *
+ * 3) Only use if thread needs more than the
+ * default.
+ *
+ * RESULTS
+ * 0 successfully set stack size,
+ * EINVAL 'attr' is invalid or stacksize too
+ * small or too big.
+ * ENOSYS function not supported
+ *
+ * ------------------------------------------------------
+ */
+{
+#ifdef _POSIX_THREAD_ATTR_STACKSIZE
+
+#if PTHREAD_STACK_MIN > 0
+
+ /* Verify that the stack size is within range. */
+ if (stacksize < PTHREAD_STACK_MIN)
+ {
+ return EINVAL;
+ }
+
+#endif
+
+ if (ptw32_is_attr (attr) != 0)
+ {
+ return EINVAL;
+ }
+
+ /* Everything is okay. */
+ (*attr)->stacksize = stacksize;
+ return 0;
+
+#else
+
+ return ENOSYS;
+
+#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
+
+}
diff --git a/pthreads/pthread_barrier_destroy.c b/pthreads/pthread_barrier_destroy.c
new file mode 100644
index 000000000..9302ba797
--- /dev/null
+++ b/pthreads/pthread_barrier_destroy.c
@@ -0,0 +1,67 @@
+/*
+ * 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;
+
+ if (barrier == NULL || *barrier == (pthread_barrier_t) PTW32_OBJECT_INVALID)
+ {
+ return EINVAL;
+ }
+
+ b = *barrier;
+ *barrier = NULL;
+
+ if (0 == (result = sem_destroy (&(b->semBarrierBreeched[0]))))
+ {
+ if (0 == (result = sem_destroy (&(b->semBarrierBreeched[1]))))
+ {
+ (void) free (b);
+ return 0;
+ }
+ (void) sem_init (&(b->semBarrierBreeched[0]), b->pshared, 0);
+ }
+
+ *barrier = b;
+ return (result);
+}
diff --git a/pthreads/pthread_barrier_init.c b/pthreads/pthread_barrier_init.c
new file mode 100644
index 000000000..dc1b50c6f
--- /dev/null
+++ b/pthreads/pthread_barrier_init.c
@@ -0,0 +1,81 @@
+/*
+ * pthread_barrier_init.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_init (pthread_barrier_t * barrier,
+ const pthread_barrierattr_t * attr, unsigned int count)
+{
+ pthread_barrier_t b;
+
+ if (barrier == NULL || count == 0)
+ {
+ return EINVAL;
+ }
+
+ if (NULL != (b = (pthread_barrier_t) calloc (1, sizeof (*b))))
+ {
+ b->pshared = (attr != NULL && *attr != NULL
+ ? (*attr)->pshared : PTHREAD_PROCESS_PRIVATE);
+
+ b->nCurrentBarrierHeight = b->nInitialBarrierHeight = count;
+ b->iStep = 0;
+
+ /*
+ * Two semaphores are used in the same way as two stepping
+ * stones might be used in crossing a stream. Once all
+ * threads are safely on one stone, the other stone can
+ * be moved ahead, and the threads can start moving to it.
+ * If some threads decide to eat their lunch before moving
+ * then the other threads have to wait.
+ */
+ if (0 == sem_init (&(b->semBarrierBreeched[0]), b->pshared, 0))
+ {
+ if (0 == sem_init (&(b->semBarrierBreeched[1]), b->pshared, 0))
+ {
+ *barrier = b;
+ return 0;
+ }
+ (void) sem_destroy (&(b->semBarrierBreeched[0]));
+ }
+ (void) free (b);
+ }
+
+ return ENOMEM;
+}
diff --git a/pthreads/pthread_barrier_wait.c b/pthreads/pthread_barrier_wait.c
new file mode 100644
index 000000000..01ae29766
--- /dev/null
+++ b/pthreads/pthread_barrier_wait.c
@@ -0,0 +1,99 @@
+/*
+ * 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;
+ int step;
+ pthread_barrier_t b;
+
+ if (barrier == NULL || *barrier == (pthread_barrier_t) PTW32_OBJECT_INVALID)
+ {
+ return EINVAL;
+ }
+
+ b = *barrier;
+ step = b->iStep;
+
+ if (0 == InterlockedDecrement ((long *) &(b->nCurrentBarrierHeight)))
+ {
+ /* Must be done before posting the semaphore. */
+ b->nCurrentBarrierHeight = b->nInitialBarrierHeight;
+
+ /*
+ * There is no race condition between the semaphore wait and post
+ * because we are using two alternating semas and all threads have
+ * entered barrier_wait and checked nCurrentBarrierHeight before this
+ * barrier's sema can be posted. Any threads that have not quite
+ * entered sem_wait below when the multiple_post has completed
+ * will nevertheless continue through the semaphore (barrier)
+ * and will not be left stranded.
+ */
+ result = (b->nInitialBarrierHeight > 1
+ ? sem_post_multiple (&(b->semBarrierBreeched[step]),
+ b->nInitialBarrierHeight - 1) : 0);
+ }
+ else
+ {
+ /*
+ * Use the non-cancelable version of sem_wait().
+ */
+ result = ptw32_semwait (&(b->semBarrierBreeched[step]));
+ }
+
+ /*
+ * The first thread across will be the PTHREAD_BARRIER_SERIAL_THREAD.
+ * This also sets up the alternate semaphore as the next barrier.
+ */
+ if (0 == result)
+ {
+ result = ((PTW32_INTERLOCKED_LONG) step ==
+ PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG)
+ & (b->iStep),
+ (PTW32_INTERLOCKED_LONG)
+ (1L - step),
+ (PTW32_INTERLOCKED_LONG)
+ step) ?
+ PTHREAD_BARRIER_SERIAL_THREAD : 0);
+ }
+
+ return (result);
+}
diff --git a/pthreads/pthread_barrierattr_destroy.c b/pthreads/pthread_barrierattr_destroy.c
new file mode 100644
index 000000000..5ab662e3f
--- /dev/null
+++ b/pthreads/pthread_barrierattr_destroy.c
@@ -0,0 +1,83 @@
+/*
+ * pthread_barrier_attr_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_barrierattr_destroy (pthread_barrierattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Destroys a barrier attributes object. The object can
+ * no longer be used.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_barrierattr_t
+ *
+ *
+ * DESCRIPTION
+ * Destroys a barrier attributes object. The object can
+ * no longer be used.
+ *
+ * NOTES:
+ * 1) Does not affect barrieres created using 'attr'
+ *
+ * RESULTS
+ * 0 successfully released attr,
+ * EINVAL 'attr' is invalid.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+
+ if (attr == NULL || *attr == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ pthread_barrierattr_t ba = *attr;
+
+ *attr = NULL;
+ free (ba);
+ }
+
+ return (result);
+} /* pthread_barrierattr_destroy */
diff --git a/pthreads/pthread_barrierattr_getpshared.c b/pthreads/pthread_barrierattr_getpshared.c
new file mode 100644
index 000000000..44c467e2b
--- /dev/null
+++ b/pthreads/pthread_barrierattr_getpshared.c
@@ -0,0 +1,95 @@
+/*
+ * pthread_barrier_attr_getpshared.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_barrierattr_getpshared (const pthread_barrierattr_t * attr,
+ int *pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Determine whether barriers created with 'attr' can be
+ * shared between processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_barrierattr_t
+ *
+ * pshared
+ * will be set to one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ *
+ * DESCRIPTION
+ * Mutexes creatd with 'attr' can be shared between
+ * processes if pthread_barrier_t variable is allocated
+ * in memory shared by these processes.
+ * NOTES:
+ * 1) pshared barriers MUST be allocated in shared
+ * memory.
+ * 2) The following macro is defined if shared barriers
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully retrieved attribute,
+ * EINVAL 'attr' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) && (pshared != NULL))
+ {
+ *pshared = (*attr)->pshared;
+ result = 0;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+} /* pthread_barrierattr_getpshared */
diff --git a/pthreads/pthread_barrierattr_init.c b/pthreads/pthread_barrierattr_init.c
new file mode 100644
index 000000000..342f8b0c6
--- /dev/null
+++ b/pthreads/pthread_barrierattr_init.c
@@ -0,0 +1,85 @@
+/*
+ * pthread_barrier_attr_init.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_barrierattr_init (pthread_barrierattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Initializes a barrier attributes object with default
+ * attributes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_barrierattr_t
+ *
+ *
+ * DESCRIPTION
+ * Initializes a barrier attributes object with default
+ * attributes.
+ *
+ * NOTES:
+ * 1) Used to define barrier types
+ *
+ * RESULTS
+ * 0 successfully initialized attr,
+ * ENOMEM insufficient memory for attr.
+ *
+ * ------------------------------------------------------
+ */
+{
+ pthread_barrierattr_t ba;
+ int result = 0;
+
+ ba = (pthread_barrierattr_t) calloc (1, sizeof (*ba));
+
+ if (ba == NULL)
+ {
+ result = ENOMEM;
+ }
+ else
+ {
+ ba->pshared = PTHREAD_PROCESS_PRIVATE;
+ }
+
+ *attr = ba;
+
+ return (result);
+} /* pthread_barrierattr_init */
diff --git a/pthreads/pthread_barrierattr_setpshared.c b/pthreads/pthread_barrierattr_setpshared.c
new file mode 100644
index 000000000..08c6fde30
--- /dev/null
+++ b/pthreads/pthread_barrierattr_setpshared.c
@@ -0,0 +1,119 @@
+/*
+ * pthread_barrier_attr_setpshared.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_barrierattr_setpshared (pthread_barrierattr_t * attr, int pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Barriers created with 'attr' can be shared between
+ * processes if pthread_barrier_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_barrierattr_t
+ *
+ * pshared
+ * must be one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ * DESCRIPTION
+ * Mutexes creatd with 'attr' can be shared between
+ * processes if pthread_barrier_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * NOTES:
+ * 1) pshared barriers MUST be allocated in shared
+ * memory.
+ *
+ * 2) The following macro is defined if shared barriers
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully set attribute,
+ * EINVAL 'attr' or pshared is invalid,
+ * ENOSYS PTHREAD_PROCESS_SHARED not supported,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) &&
+ ((pshared == PTHREAD_PROCESS_SHARED) ||
+ (pshared == PTHREAD_PROCESS_PRIVATE)))
+ {
+ if (pshared == PTHREAD_PROCESS_SHARED)
+ {
+
+#if !defined( _POSIX_THREAD_PROCESS_SHARED )
+
+ result = ENOSYS;
+ pshared = PTHREAD_PROCESS_PRIVATE;
+
+#else
+
+ result = 0;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+
+ }
+ else
+ {
+ result = 0;
+ }
+
+ (*attr)->pshared = pshared;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+
+} /* pthread_barrierattr_setpshared */
diff --git a/pthreads/pthread_cancel.c b/pthreads/pthread_cancel.c
new file mode 100644
index 000000000..1118977ee
--- /dev/null
+++ b/pthreads/pthread_cancel.c
@@ -0,0 +1,223 @@
+/*
+ * 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"
+
+#if defined(_M_IX86) || defined(_X86_)
+#define PTW32_PROGCTR(Context) ((Context).Eip)
+#endif
+
+#if defined (_M_IA64)
+#define PTW32_PROGCTR(Context) ((Context).StIIP)
+#endif
+
+#if 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_)
+#define PTW32_PROGCTR(Context) ((Context).Rip)
+#endif
+
+#if !defined(PTW32_PROGCTR)
+#error Module contains CPU-specific code; modify and recompile.
+#endif
+
+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;
+ };
+
+ /*
+ * FIXME!!
+ *
+ * Can a thread cancel itself?
+ *
+ * The standard doesn't
+ * specify an error to be returned if the target
+ * thread is itself.
+ *
+ * If it may, then we need to ensure that a thread can't
+ * deadlock itself trying to cancel itself asyncronously
+ * (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);
+}
diff --git a/pthreads/pthread_cond_destroy.c b/pthreads/pthread_cond_destroy.c
new file mode 100644
index 000000000..3d29ffc40
--- /dev/null
+++ b/pthreads/pthread_cond_destroy.c
@@ -0,0 +1,244 @@
+/*
+ * 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 (sem_wait (&(cv->semBlockLock)) != 0)
+ {
+ return errno;
+ }
+
+ /*
+ * !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));
+ 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));
+}
diff --git a/pthreads/pthread_cond_init.c b/pthreads/pthread_cond_init.c
new file mode 100644
index 000000000..d2de232f4
--- /dev/null
+++ b/pthreads/pthread_cond_init.c
@@ -0,0 +1,165 @@
+/*
+ * pthread_cond_init.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_init (pthread_cond_t * cond, const pthread_condattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function initializes a condition variable.
+ *
+ * PARAMETERS
+ * cond
+ * pointer to an instance of pthread_cond_t
+ *
+ * attr
+ * specifies optional creation attributes.
+ *
+ *
+ * DESCRIPTION
+ * This function initializes a condition variable.
+ *
+ * RESULTS
+ * 0 successfully created condition variable,
+ * EINVAL 'attr' is invalid,
+ * EAGAIN insufficient resources (other than
+ * memory,
+ * ENOMEM insufficient memory,
+ * EBUSY 'cond' is already initialized,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+ pthread_cond_t cv = NULL;
+
+ if (cond == NULL)
+ {
+ return EINVAL;
+ }
+
+ if ((attr != NULL && *attr != NULL) &&
+ ((*attr)->pshared == PTHREAD_PROCESS_SHARED))
+ {
+ /*
+ * Creating condition variable that can be shared between
+ * processes.
+ */
+ result = ENOSYS;
+ goto DONE;
+ }
+
+ cv = (pthread_cond_t) calloc (1, sizeof (*cv));
+
+ if (cv == NULL)
+ {
+ result = ENOMEM;
+ goto DONE;
+ }
+
+ cv->nWaitersBlocked = 0;
+ cv->nWaitersToUnblock = 0;
+ cv->nWaitersGone = 0;
+
+ if (sem_init (&(cv->semBlockLock), 0, 1) != 0)
+ {
+ result = errno;
+ goto FAIL0;
+ }
+
+ if (sem_init (&(cv->semBlockQueue), 0, 0) != 0)
+ {
+ result = errno;
+ goto FAIL1;
+ }
+
+ if ((result = pthread_mutex_init (&(cv->mtxUnblockLock), 0)) != 0)
+ {
+ goto FAIL2;
+ }
+
+ result = 0;
+
+ goto DONE;
+
+ /*
+ * -------------
+ * Failed...
+ * -------------
+ */
+FAIL2:
+ (void) sem_destroy (&(cv->semBlockQueue));
+
+FAIL1:
+ (void) sem_destroy (&(cv->semBlockLock));
+
+FAIL0:
+ (void) free (cv);
+ cv = NULL;
+
+DONE:
+ if (0 == result)
+ {
+ EnterCriticalSection (&ptw32_cond_list_lock);
+
+ cv->next = NULL;
+ cv->prev = ptw32_cond_list_tail;
+
+ if (ptw32_cond_list_tail != NULL)
+ {
+ ptw32_cond_list_tail->next = cv;
+ }
+
+ ptw32_cond_list_tail = cv;
+
+ if (ptw32_cond_list_head == NULL)
+ {
+ ptw32_cond_list_head = cv;
+ }
+
+ LeaveCriticalSection (&ptw32_cond_list_lock);
+ }
+
+ *cond = cv;
+
+ return result;
+
+} /* pthread_cond_init */
diff --git a/pthreads/pthread_cond_signal.c b/pthreads/pthread_cond_signal.c
new file mode 100644
index 000000000..2b4f6d4d4
--- /dev/null
+++ b/pthreads/pthread_cond_signal.c
@@ -0,0 +1,231 @@
+/*
+ * pthread_cond_signal.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
+ *
+ * -------------------------------------------------------------
+ * Algorithm:
+ * See the comments at the top of pthread_cond_wait.c.
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+static INLINE int
+ptw32_cond_unblock (pthread_cond_t * cond, int unblockAll)
+ /*
+ * Notes.
+ *
+ * Does not use the external mutex for synchronisation,
+ * therefore semBlockLock is needed.
+ * mtxUnblockLock is for LEVEL-2 synch. LEVEL-2 is the
+ * state where the external mutex is not necessarily locked by
+ * any thread, ie. between cond_wait unlocking and re-acquiring
+ * the lock after having been signaled or a timeout or
+ * cancellation.
+ *
+ * Uses the following CV elements:
+ * nWaitersBlocked
+ * nWaitersToUnblock
+ * nWaitersGone
+ * mtxUnblockLock
+ * semBlockLock
+ * semBlockQueue
+ */
+{
+ int result;
+ pthread_cond_t cv;
+ int nSignalsToIssue;
+
+ if (cond == NULL || *cond == NULL)
+ {
+ return EINVAL;
+ }
+
+ cv = *cond;
+
+ /*
+ * No-op if the CV is static and hasn't been initialised yet.
+ * Assuming that any race condition is harmless.
+ */
+ if (cv == PTHREAD_COND_INITIALIZER)
+ {
+ return 0;
+ }
+
+ if ((result = pthread_mutex_lock (&(cv->mtxUnblockLock))) != 0)
+ {
+ return result;
+ }
+
+ if (0 != cv->nWaitersToUnblock)
+ {
+ if (0 == cv->nWaitersBlocked)
+ {
+ return pthread_mutex_unlock (&(cv->mtxUnblockLock));
+ }
+ if (unblockAll)
+ {
+ cv->nWaitersToUnblock += (nSignalsToIssue = cv->nWaitersBlocked);
+ cv->nWaitersBlocked = 0;
+ }
+ else
+ {
+ nSignalsToIssue = 1;
+ cv->nWaitersToUnblock++;
+ cv->nWaitersBlocked--;
+ }
+ }
+ else if (cv->nWaitersBlocked > cv->nWaitersGone)
+ {
+ /* Use the non-cancellable version of sem_wait() */
+ if (ptw32_semwait (&(cv->semBlockLock)) != 0)
+ {
+ result = errno;
+ (void) pthread_mutex_unlock (&(cv->mtxUnblockLock));
+ return result;
+ }
+ if (0 != cv->nWaitersGone)
+ {
+ cv->nWaitersBlocked -= cv->nWaitersGone;
+ cv->nWaitersGone = 0;
+ }
+ if (unblockAll)
+ {
+ nSignalsToIssue = cv->nWaitersToUnblock = cv->nWaitersBlocked;
+ cv->nWaitersBlocked = 0;
+ }
+ else
+ {
+ nSignalsToIssue = cv->nWaitersToUnblock = 1;
+ cv->nWaitersBlocked--;
+ }
+ }
+ else
+ {
+ return pthread_mutex_unlock (&(cv->mtxUnblockLock));
+ }
+
+ if ((result = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0)
+ {
+ if (sem_post_multiple (&(cv->semBlockQueue), nSignalsToIssue) != 0)
+ {
+ result = errno;
+ }
+ }
+
+ return result;
+
+} /* ptw32_cond_unblock */
+
+int
+pthread_cond_signal (pthread_cond_t * cond)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function signals a condition variable, waking
+ * one waiting thread.
+ * If SCHED_FIFO or SCHED_RR policy threads are waiting
+ * the highest priority waiter is awakened; otherwise,
+ * an unspecified waiter is awakened.
+ *
+ * PARAMETERS
+ * cond
+ * pointer to an instance of pthread_cond_t
+ *
+ *
+ * DESCRIPTION
+ * This function signals a condition variable, waking
+ * one waiting thread.
+ * If SCHED_FIFO or SCHED_RR policy threads are waiting
+ * the highest priority waiter is awakened; otherwise,
+ * an unspecified waiter is awakened.
+ *
+ * NOTES:
+ *
+ * 1) Use when any waiter can respond and only one need
+ * respond (all waiters being equal).
+ *
+ * RESULTS
+ * 0 successfully signaled condition,
+ * EINVAL 'cond' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ /*
+ * The '0'(FALSE) unblockAll arg means unblock ONE waiter.
+ */
+ return (ptw32_cond_unblock (cond, 0));
+
+} /* pthread_cond_signal */
+
+int
+pthread_cond_broadcast (pthread_cond_t * cond)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function broadcasts the condition variable,
+ * waking all current waiters.
+ *
+ * PARAMETERS
+ * cond
+ * pointer to an instance of pthread_cond_t
+ *
+ *
+ * DESCRIPTION
+ * This function signals a condition variable, waking
+ * all waiting threads.
+ *
+ * NOTES:
+ *
+ * 1) Use when more than one waiter may respond to
+ * predicate change or if any waiting thread may
+ * not be able to respond
+ *
+ * RESULTS
+ * 0 successfully signalled condition to all
+ * waiting threads,
+ * EINVAL 'cond' is invalid
+ * ENOSPC a required resource has been exhausted,
+ *
+ * ------------------------------------------------------
+ */
+{
+ /*
+ * The TRUE unblockAll arg means unblock ALL waiters.
+ */
+ return (ptw32_cond_unblock (cond, PTW32_TRUE));
+
+} /* pthread_cond_broadcast */
diff --git a/pthreads/pthread_cond_wait.c b/pthreads/pthread_cond_wait.c
new file mode 100644
index 000000000..5511c5844
--- /dev/null
+++ b/pthreads/pthread_cond_wait.c
@@ -0,0 +1,567 @@
+/*
+ * pthread_cond_wait.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
+ *
+ * -------------------------------------------------------------
+ * Algorithm:
+ * The algorithm used in this implementation is that developed by
+ * Alexander Terekhov in colaboration with Louis Thomas. The bulk
+ * of the discussion is recorded in the file README.CV, which contains
+ * several generations of both colaborators original algorithms. The final
+ * algorithm used here is the one referred to as
+ *
+ * Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
+ *
+ * presented below in pseudo-code as it appeared:
+ *
+ *
+ * given:
+ * semBlockLock - bin.semaphore
+ * semBlockQueue - semaphore
+ * mtxExternal - mutex or CS
+ * mtxUnblockLock - mutex or CS
+ * nWaitersGone - int
+ * nWaitersBlocked - int
+ * nWaitersToUnblock - int
+ *
+ * wait( timeout ) {
+ *
+ * [auto: register int result ] // error checking omitted
+ * [auto: register int nSignalsWasLeft ]
+ * [auto: register int nWaitersWasGone ]
+ *
+ * sem_wait( semBlockLock );
+ * nWaitersBlocked++;
+ * sem_post( semBlockLock );
+ *
+ * unlock( mtxExternal );
+ * bTimedOut = sem_wait( semBlockQueue,timeout );
+ *
+ * lock( mtxUnblockLock );
+ * if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
+ * if ( bTimeout ) { // timeout (or canceled)
+ * if ( 0 != nWaitersBlocked ) {
+ * nWaitersBlocked--;
+ * }
+ * else {
+ * nWaitersGone++; // count spurious wakeups.
+ * }
+ * }
+ * if ( 0 == --nWaitersToUnblock ) {
+ * if ( 0 != nWaitersBlocked ) {
+ * sem_post( semBlockLock ); // open the gate.
+ * nSignalsWasLeft = 0; // do not open the gate
+ * // below again.
+ * }
+ * else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
+ * nWaitersGone = 0;
+ * }
+ * }
+ * }
+ * else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
+ * // spurious semaphore :-)
+ * sem_wait( semBlockLock );
+ * nWaitersBlocked -= nWaitersGone; // something is going on here
+ * // - test of timeouts? :-)
+ * sem_post( semBlockLock );
+ * nWaitersGone = 0;
+ * }
+ * unlock( mtxUnblockLock );
+ *
+ * if ( 1 == nSignalsWasLeft ) {
+ * if ( 0 != nWaitersWasGone ) {
+ * // sem_adjust( semBlockQueue,-nWaitersWasGone );
+ * while ( nWaitersWasGone-- ) {
+ * sem_wait( semBlockQueue ); // better now than spurious later
+ * }
+ * } sem_post( semBlockLock ); // open the gate
+ * }
+ *
+ * lock( mtxExternal );
+ *
+ * return ( bTimedOut ) ? ETIMEOUT : 0;
+ * }
+ *
+ * signal(bAll) {
+ *
+ * [auto: register int result ]
+ * [auto: register int nSignalsToIssue]
+ *
+ * lock( mtxUnblockLock );
+ *
+ * if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
+ * if ( 0 == nWaitersBlocked ) { // NO-OP
+ * return unlock( mtxUnblockLock );
+ * }
+ * if (bAll) {
+ * nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
+ * nWaitersBlocked = 0;
+ * }
+ * else {
+ * nSignalsToIssue = 1;
+ * nWaitersToUnblock++;
+ * nWaitersBlocked--;
+ * }
+ * }
+ * else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+ * sem_wait( semBlockLock ); // close the gate
+ * if ( 0 != nWaitersGone ) {
+ * nWaitersBlocked -= nWaitersGone;
+ * nWaitersGone = 0;
+ * }
+ * if (bAll) {
+ * nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
+ * nWaitersBlocked = 0;
+ * }
+ * else {
+ * nSignalsToIssue = nWaitersToUnblock = 1;
+ * nWaitersBlocked--;
+ * }
+ * }
+ * else { // NO-OP
+ * return unlock( mtxUnblockLock );
+ * }
+ *
+ * unlock( mtxUnblockLock );
+ * sem_post( semBlockQueue,nSignalsToIssue );
+ * return result;
+ * }
+ * -------------------------------------------------------------
+ *
+ * Algorithm 9 / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
+ *
+ * presented below in pseudo-code; basically 8a...
+ * ...BUT W/O "spurious wakes" prevention:
+ *
+ *
+ * given:
+ * semBlockLock - bin.semaphore
+ * semBlockQueue - semaphore
+ * mtxExternal - mutex or CS
+ * mtxUnblockLock - mutex or CS
+ * nWaitersGone - int
+ * nWaitersBlocked - int
+ * nWaitersToUnblock - int
+ *
+ * wait( timeout ) {
+ *
+ * [auto: register int result ] // error checking omitted
+ * [auto: register int nSignalsWasLeft ]
+ *
+ * sem_wait( semBlockLock );
+ * ++nWaitersBlocked;
+ * sem_post( semBlockLock );
+ *
+ * unlock( mtxExternal );
+ * bTimedOut = sem_wait( semBlockQueue,timeout );
+ *
+ * lock( mtxUnblockLock );
+ * if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
+ * --nWaitersToUnblock;
+ * }
+ * else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
+ * // spurious semaphore :-)
+ * sem_wait( semBlockLock );
+ * nWaitersBlocked -= nWaitersGone; // something is going on here
+ * // - test of timeouts? :-)
+ * sem_post( semBlockLock );
+ * nWaitersGone = 0;
+ * }
+ * unlock( mtxUnblockLock );
+ *
+ * if ( 1 == nSignalsWasLeft ) {
+ * sem_post( semBlockLock ); // open the gate
+ * }
+ *
+ * lock( mtxExternal );
+ *
+ * return ( bTimedOut ) ? ETIMEOUT : 0;
+ * }
+ *
+ * signal(bAll) {
+ *
+ * [auto: register int result ]
+ * [auto: register int nSignalsToIssue]
+ *
+ * lock( mtxUnblockLock );
+ *
+ * if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
+ * if ( 0 == nWaitersBlocked ) { // NO-OP
+ * return unlock( mtxUnblockLock );
+ * }
+ * if (bAll) {
+ * nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
+ * nWaitersBlocked = 0;
+ * }
+ * else {
+ * nSignalsToIssue = 1;
+ * ++nWaitersToUnblock;
+ * --nWaitersBlocked;
+ * }
+ * }
+ * else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+ * sem_wait( semBlockLock ); // close the gate
+ * if ( 0 != nWaitersGone ) {
+ * nWaitersBlocked -= nWaitersGone;
+ * nWaitersGone = 0;
+ * }
+ * if (bAll) {
+ * nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
+ * nWaitersBlocked = 0;
+ * }
+ * else {
+ * nSignalsToIssue = nWaitersToUnblock = 1;
+ * --nWaitersBlocked;
+ * }
+ * }
+ * else { // NO-OP
+ * return unlock( mtxUnblockLock );
+ * }
+ *
+ * unlock( mtxUnblockLock );
+ * sem_post( semBlockQueue,nSignalsToIssue );
+ * return result;
+ * }
+ * -------------------------------------------------------------
+ *
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/*
+ * Arguments for cond_wait_cleanup, since we can only pass a
+ * single void * to it.
+ */
+typedef struct
+{
+ pthread_mutex_t *mutexPtr;
+ pthread_cond_t cv;
+ int *resultPtr;
+} ptw32_cond_wait_cleanup_args_t;
+
+static void PTW32_CDECL
+ptw32_cond_wait_cleanup (void *args)
+{
+ ptw32_cond_wait_cleanup_args_t *cleanup_args =
+ (ptw32_cond_wait_cleanup_args_t *) args;
+ pthread_cond_t cv = cleanup_args->cv;
+ int *resultPtr = cleanup_args->resultPtr;
+ int nSignalsWasLeft;
+ int result;
+
+ /*
+ * Whether we got here as a result of signal/broadcast or because of
+ * timeout on wait or thread cancellation we indicate that we are no
+ * longer waiting. The waiter is responsible for adjusting waiters
+ * (to)unblock(ed) counts (protected by unblock lock).
+ */
+ if ((result = pthread_mutex_lock (&(cv->mtxUnblockLock))) != 0)
+ {
+ *resultPtr = result;
+ return;
+ }
+
+ if (0 != (nSignalsWasLeft = cv->nWaitersToUnblock))
+ {
+ --(cv->nWaitersToUnblock);
+ }
+ else if (INT_MAX / 2 == ++(cv->nWaitersGone))
+ {
+ /* Use the non-cancellable version of sem_wait() */
+ if (ptw32_semwait (&(cv->semBlockLock)) != 0)
+ {
+ *resultPtr = errno;
+ /*
+ * This is a fatal error for this CV,
+ * so we deliberately don't unlock
+ * cv->mtxUnblockLock before returning.
+ */
+ return;
+ }
+ cv->nWaitersBlocked -= cv->nWaitersGone;
+ if (sem_post (&(cv->semBlockLock)) != 0)
+ {
+ *resultPtr = errno;
+ /*
+ * This is a fatal error for this CV,
+ * so we deliberately don't unlock
+ * cv->mtxUnblockLock before returning.
+ */
+ return;
+ }
+ cv->nWaitersGone = 0;
+ }
+
+ if ((result = pthread_mutex_unlock (&(cv->mtxUnblockLock))) != 0)
+ {
+ *resultPtr = result;
+ return;
+ }
+
+ if (1 == nSignalsWasLeft)
+ {
+ if (sem_post (&(cv->semBlockLock)) != 0)
+ {
+ *resultPtr = errno;
+ return;
+ }
+ }
+
+ /*
+ * XSH: Upon successful return, the mutex has been locked and is owned
+ * by the calling thread.
+ */
+ if ((result = pthread_mutex_lock (cleanup_args->mutexPtr)) != 0)
+ {
+ *resultPtr = result;
+ }
+} /* ptw32_cond_wait_cleanup */
+
+static INLINE int
+ptw32_cond_timedwait (pthread_cond_t * cond,
+ pthread_mutex_t * mutex, const struct timespec *abstime)
+{
+ int result = 0;
+ pthread_cond_t cv;
+ ptw32_cond_wait_cleanup_args_t cleanup_args;
+
+ if (cond == NULL || *cond == NULL)
+ {
+ return EINVAL;
+ }
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static condition variable. We check
+ * again inside the guarded section of ptw32_cond_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*cond == PTHREAD_COND_INITIALIZER)
+ {
+ result = ptw32_cond_check_need_init (cond);
+ }
+
+ if (result != 0 && result != EBUSY)
+ {
+ return result;
+ }
+
+ cv = *cond;
+
+ /* Thread can be cancelled in sem_wait() but this is OK */
+ if (sem_wait (&(cv->semBlockLock)) != 0)
+ {
+ return errno;
+ }
+
+ ++(cv->nWaitersBlocked);
+
+ if (sem_post (&(cv->semBlockLock)) != 0)
+ {
+ return errno;
+ }
+
+ /*
+ * Setup this waiter cleanup handler
+ */
+ cleanup_args.mutexPtr = mutex;
+ cleanup_args.cv = cv;
+ cleanup_args.resultPtr = &result;
+
+#ifdef _MSC_VER
+#pragma inline_depth(0)
+#endif
+ pthread_cleanup_push (ptw32_cond_wait_cleanup, (void *) &cleanup_args);
+
+ /*
+ * Now we can release 'mutex' and...
+ */
+ if ((result = pthread_mutex_unlock (mutex)) == 0)
+ {
+
+ /*
+ * ...wait to be awakened by
+ * pthread_cond_signal, or
+ * pthread_cond_broadcast, or
+ * timeout, or
+ * thread cancellation
+ *
+ * Note:
+ *
+ * sem_timedwait is a cancellation point,
+ * hence providing the mechanism for making
+ * pthread_cond_wait a cancellation point.
+ * We use the cleanup mechanism to ensure we
+ * re-lock the mutex and adjust (to)unblock(ed) waiters
+ * counts if we are cancelled, timed out or signalled.
+ */
+ if (sem_timedwait (&(cv->semBlockQueue), abstime) != 0)
+ {
+ result = errno;
+ }
+ }
+
+ /*
+ * Always cleanup
+ */
+ pthread_cleanup_pop (1);
+#ifdef _MSC_VER
+#pragma inline_depth()
+#endif
+
+ /*
+ * "result" can be modified by the cleanup handler.
+ */
+ return result;
+
+} /* ptw32_cond_timedwait */
+
+
+int
+pthread_cond_wait (pthread_cond_t * cond, pthread_mutex_t * mutex)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function waits on a condition variable until
+ * awakened by a signal or broadcast.
+ *
+ * Caller MUST be holding the mutex lock; the
+ * lock is released and the caller is blocked waiting
+ * on 'cond'. When 'cond' is signaled, the mutex
+ * is re-acquired before returning to the caller.
+ *
+ * PARAMETERS
+ * cond
+ * pointer to an instance of pthread_cond_t
+ *
+ * mutex
+ * pointer to an instance of pthread_mutex_t
+ *
+ *
+ * DESCRIPTION
+ * This function waits on a condition variable until
+ * awakened by a signal or broadcast.
+ *
+ * NOTES:
+ *
+ * 1) The function must be called with 'mutex' LOCKED
+ * by the calling thread, or undefined behaviour
+ * will result.
+ *
+ * 2) This routine atomically releases 'mutex' and causes
+ * the calling thread to block on the condition variable.
+ * The blocked thread may be awakened by
+ * pthread_cond_signal or
+ * pthread_cond_broadcast.
+ *
+ * Upon successful completion, the 'mutex' has been locked and
+ * is owned by the calling thread.
+ *
+ *
+ * RESULTS
+ * 0 caught condition; mutex released,
+ * EINVAL 'cond' or 'mutex' is invalid,
+ * EINVAL different mutexes for concurrent waits,
+ * EINVAL mutex is not held by the calling thread,
+ *
+ * ------------------------------------------------------
+ */
+{
+ /*
+ * The NULL abstime arg means INFINITE waiting.
+ */
+ return (ptw32_cond_timedwait (cond, mutex, NULL));
+
+} /* pthread_cond_wait */
+
+
+int
+pthread_cond_timedwait (pthread_cond_t * cond,
+ pthread_mutex_t * mutex,
+ const struct timespec *abstime)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function waits on a condition variable either until
+ * awakened by a signal or broadcast; or until the time
+ * specified by abstime passes.
+ *
+ * PARAMETERS
+ * cond
+ * pointer to an instance of pthread_cond_t
+ *
+ * mutex
+ * pointer to an instance of pthread_mutex_t
+ *
+ * abstime
+ * pointer to an instance of (const struct timespec)
+ *
+ *
+ * DESCRIPTION
+ * This function waits on a condition variable either until
+ * awakened by a signal or broadcast; or until the time
+ * specified by abstime passes.
+ *
+ * NOTES:
+ * 1) The function must be called with 'mutex' LOCKED
+ * by the calling thread, or undefined behaviour
+ * will result.
+ *
+ * 2) This routine atomically releases 'mutex' and causes
+ * the calling thread to block on the condition variable.
+ * The blocked thread may be awakened by
+ * pthread_cond_signal or
+ * pthread_cond_broadcast.
+ *
+ *
+ * RESULTS
+ * 0 caught condition; mutex released,
+ * EINVAL 'cond', 'mutex', or abstime is invalid,
+ * EINVAL different mutexes for concurrent waits,
+ * EINVAL mutex is not held by the calling thread,
+ * ETIMEDOUT abstime ellapsed before cond was signaled.
+ *
+ * ------------------------------------------------------
+ */
+{
+ if (abstime == NULL)
+ {
+ return EINVAL;
+ }
+
+ return (ptw32_cond_timedwait (cond, mutex, abstime));
+
+} /* pthread_cond_timedwait */
diff --git a/pthreads/pthread_condattr_destroy.c b/pthreads/pthread_condattr_destroy.c
new file mode 100644
index 000000000..58a14828f
--- /dev/null
+++ b/pthreads/pthread_condattr_destroy.c
@@ -0,0 +1,86 @@
+/*
+ * condvar_attr_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_condattr_destroy (pthread_condattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Destroys a condition variable attributes object.
+ * The object can no longer be used.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_condattr_t
+ *
+ *
+ * DESCRIPTION
+ * Destroys a condition variable attributes object.
+ * The object can no longer be used.
+ *
+ * NOTES:
+ * 1) Does not affect condition variables created
+ * using 'attr'
+ *
+ * RESULTS
+ * 0 successfully released attr,
+ * EINVAL 'attr' is invalid.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+
+ if (attr == NULL || *attr == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ (void) free (*attr);
+
+ *attr = NULL;
+ result = 0;
+ }
+
+ return result;
+
+} /* pthread_condattr_destroy */
diff --git a/pthreads/pthread_condattr_getpshared.c b/pthreads/pthread_condattr_getpshared.c
new file mode 100644
index 000000000..a0ac6d882
--- /dev/null
+++ b/pthreads/pthread_condattr_getpshared.c
@@ -0,0 +1,97 @@
+/*
+ * pthread_condattr_getpshared.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_condattr_getpshared (const pthread_condattr_t * attr, int *pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Determine whether condition variables created with 'attr'
+ * can be shared between processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_condattr_t
+ *
+ * pshared
+ * will be set to one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ *
+ * DESCRIPTION
+ * Condition Variables created with 'attr' can be shared
+ * between processes if pthread_cond_t variable is allocated
+ * in memory shared by these processes.
+ * NOTES:
+ * 1) pshared condition variables MUST be allocated in
+ * shared memory.
+ *
+ * 2) The following macro is defined if shared mutexes
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully retrieved attribute,
+ * EINVAL 'attr' or 'pshared' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) && (pshared != NULL))
+ {
+ *pshared = (*attr)->pshared;
+ result = 0;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return result;
+
+} /* pthread_condattr_getpshared */
diff --git a/pthreads/pthread_condattr_init.c b/pthreads/pthread_condattr_init.c
new file mode 100644
index 000000000..5987878e0
--- /dev/null
+++ b/pthreads/pthread_condattr_init.c
@@ -0,0 +1,87 @@
+/*
+ * pthread_condattr_init.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_condattr_init (pthread_condattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Initializes a condition variable attributes object
+ * with default attributes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_condattr_t
+ *
+ *
+ * DESCRIPTION
+ * Initializes a condition variable attributes object
+ * with default attributes.
+ *
+ * NOTES:
+ * 1) Use to define condition variable types
+ * 2) It is up to the application to ensure
+ * that it doesn't re-init an attribute
+ * without destroying it first. Otherwise
+ * a memory leak is created.
+ *
+ * RESULTS
+ * 0 successfully initialized attr,
+ * ENOMEM insufficient memory for attr.
+ *
+ * ------------------------------------------------------
+ */
+{
+ pthread_condattr_t attr_result;
+ int result = 0;
+
+ attr_result = (pthread_condattr_t) calloc (1, sizeof (*attr_result));
+
+ if (attr_result == NULL)
+ {
+ result = ENOMEM;
+ }
+
+ *attr = attr_result;
+
+ return result;
+
+} /* pthread_condattr_init */
diff --git a/pthreads/pthread_condattr_setpshared.c b/pthreads/pthread_condattr_setpshared.c
new file mode 100644
index 000000000..954fb3829
--- /dev/null
+++ b/pthreads/pthread_condattr_setpshared.c
@@ -0,0 +1,117 @@
+/*
+ * pthread_condattr_setpshared.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_condattr_setpshared (pthread_condattr_t * attr, int pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Mutexes created with 'attr' can be shared between
+ * processes if pthread_mutex_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ * pshared
+ * must be one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ * DESCRIPTION
+ * Mutexes creatd with 'attr' can be shared between
+ * processes if pthread_mutex_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * NOTES:
+ * 1) pshared mutexes MUST be allocated in shared
+ * memory.
+ *
+ * 2) The following macro is defined if shared mutexes
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully set attribute,
+ * EINVAL 'attr' or pshared is invalid,
+ * ENOSYS PTHREAD_PROCESS_SHARED not supported,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL)
+ && ((pshared == PTHREAD_PROCESS_SHARED)
+ || (pshared == PTHREAD_PROCESS_PRIVATE)))
+ {
+ if (pshared == PTHREAD_PROCESS_SHARED)
+ {
+
+#if !defined( _POSIX_THREAD_PROCESS_SHARED )
+ result = ENOSYS;
+ pshared = PTHREAD_PROCESS_PRIVATE;
+#else
+ result = 0;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+
+ }
+ else
+ {
+ result = 0;
+ }
+
+ (*attr)->pshared = pshared;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return result;
+
+} /* pthread_condattr_setpshared */
diff --git a/pthreads/pthread_delay_np.c b/pthreads/pthread_delay_np.c
new file mode 100644
index 000000000..7fe9ae016
--- /dev/null
+++ b/pthreads/pthread_delay_np.c
@@ -0,0 +1,171 @@
+/*
+ * pthreads_delay_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"
+
+/*
+ * pthread_delay_np
+ *
+ * DESCRIPTION
+ *
+ * This routine causes a thread to delay execution for a specific period of time.
+ * This period ends at the current time plus the specified interval. The routine
+ * will not return before the end of the period is reached, but may return an
+ * arbitrary amount of time after the period has gone by. This can be due to
+ * system load, thread priorities, and system timer granularity.
+ *
+ * Specifying an interval of zero (0) seconds and zero (0) nanoseconds is
+ * allowed and can be used to force the thread to give up the processor or to
+ * deliver a pending cancelation request.
+ *
+ * The timespec structure contains the following two fields:
+ *
+ * tv_sec is an integer number of seconds.
+ * tv_nsec is an integer number of nanoseconds.
+ *
+ * Return Values
+ *
+ * If an error condition occurs, this routine returns an integer value indicating
+ * the type of error. Possible return values are as follows:
+ *
+ * 0
+ * Successful completion.
+ * [EINVAL]
+ * The value specified by interval is invalid.
+ *
+ * Example
+ *
+ * The following code segment would wait for 5 and 1/2 seconds
+ *
+ * struct timespec tsWait;
+ * int intRC;
+ *
+ * tsWait.tv_sec = 5;
+ * tsWait.tv_nsec = 500000000L;
+ * intRC = pthread_delay_np(&tsWait);
+ */
+int
+pthread_delay_np (struct timespec *interval)
+{
+ DWORD wait_time;
+ DWORD secs_in_millisecs;
+ DWORD millisecs;
+ DWORD status;
+ pthread_t self;
+ ptw32_thread_t * sp;
+
+ if (interval == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (interval->tv_sec == 0L && interval->tv_nsec == 0L)
+ {
+ pthread_testcancel ();
+ Sleep (0);
+ pthread_testcancel ();
+ return (0);
+ }
+
+ /* convert secs to millisecs */
+ secs_in_millisecs = interval->tv_sec * 1000L;
+
+ /* convert nanosecs to millisecs (rounding up) */
+ millisecs = (interval->tv_nsec + 999999L) / 1000000L;
+
+#if defined(__WATCOMC__)
+#pragma disable_message (124)
+#endif
+
+ /*
+ * Most compilers will issue a warning 'comparison always 0'
+ * because the variable type is unsigned, but we need to keep this
+ * for some reason I can't recall now.
+ */
+ if (0 > (wait_time = secs_in_millisecs + millisecs))
+ {
+ return EINVAL;
+ }
+
+#if defined(__WATCOMC__)
+#pragma enable_message (124)
+#endif
+
+ if (NULL == (self = pthread_self ()).p)
+ {
+ return ENOMEM;
+ }
+
+ sp = (ptw32_thread_t *) self.p;
+
+ if (sp->cancelState == PTHREAD_CANCEL_ENABLE)
+ {
+ /*
+ * Async cancelation won't catch us until wait_time is up.
+ * Deferred cancelation will cancel us immediately.
+ */
+ if (WAIT_OBJECT_0 ==
+ (status = WaitForSingleObject (sp->cancelEvent, wait_time)))
+ {
+ /*
+ * Canceling!
+ */
+ (void) pthread_mutex_lock (&sp->cancelLock);
+ if (sp->state < PThreadStateCanceling)
+ {
+ sp->state = PThreadStateCanceling;
+ sp->cancelState = PTHREAD_CANCEL_DISABLE;
+ (void) pthread_mutex_unlock (&sp->cancelLock);
+
+ ptw32_throw (PTW32_EPS_CANCEL);
+ }
+
+ (void) pthread_mutex_unlock (&sp->cancelLock);
+ return ESRCH;
+ }
+ else if (status != WAIT_TIMEOUT)
+ {
+ return EINVAL;
+ }
+ }
+ else
+ {
+ Sleep (wait_time);
+ }
+
+ return (0);
+}
diff --git a/pthreads/pthread_detach.c b/pthreads/pthread_detach.c
new file mode 100644
index 000000000..00fb6adfb
--- /dev/null
+++ b/pthreads/pthread_detach.c
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+#include <signal.h>
+
+
+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 */
diff --git a/pthreads/pthread_equal.c b/pthreads/pthread_equal.c
new file mode 100644
index 000000000..f96372edb
--- /dev/null
+++ b/pthreads/pthread_equal.c
@@ -0,0 +1,76 @@
+/*
+ * pthread_equal.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_equal (pthread_t t1, pthread_t t2)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function returns nonzero if t1 and t2 are equal, else
+ * returns nonzero
+ *
+ * PARAMETERS
+ * t1,
+ * t2
+ * thread IDs
+ *
+ *
+ * DESCRIPTION
+ * This function returns nonzero if t1 and t2 are equal, else
+ * returns zero.
+ *
+ * RESULTS
+ * non-zero if t1 and t2 refer to the same thread,
+ * 0 t1 and t2 do not refer to the same thread
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ /*
+ * We also accept NULL == NULL - treating NULL as a thread
+ * for this special case, because there is no error that we can return.
+ */
+ result = ( t1.p == t2.p && t1.x == t2.x );
+
+ return (result);
+
+} /* pthread_equal */
diff --git a/pthreads/pthread_exit.c b/pthreads/pthread_exit.c
new file mode 100644
index 000000000..a4903129b
--- /dev/null
+++ b/pthreads/pthread_exit.c
@@ -0,0 +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 <process.h>
+#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. */
+
+}
diff --git a/pthreads/pthread_getconcurrency.c b/pthreads/pthread_getconcurrency.c
new file mode 100644
index 000000000..cf9e9c85c
--- /dev/null
+++ b/pthreads/pthread_getconcurrency.c
@@ -0,0 +1,45 @@
+/*
+ * pthread_getconcurrency.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_getconcurrency (void)
+{
+ return ptw32_concurrency;
+}
diff --git a/pthreads/pthread_getschedparam.c b/pthreads/pthread_getschedparam.c
new file mode 100644
index 000000000..0afcfb74a
--- /dev/null
+++ b/pthreads/pthread_getschedparam.c
@@ -0,0 +1,75 @@
+/*
+ * sched_getschedparam.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+int
+pthread_getschedparam (pthread_t thread, int *policy,
+ struct sched_param *param)
+{
+ int result;
+
+ /* Validate the thread id. */
+ result = pthread_kill (thread, 0);
+ if (0 != result)
+ {
+ return result;
+ }
+
+ /*
+ * Validate the policy and param args.
+ * Check that a policy constant wasn't passed rather than &policy.
+ */
+ if (policy <= (int *) SCHED_MAX || param == NULL)
+ {
+ return EINVAL;
+ }
+
+ /* Fill out the policy. */
+ *policy = SCHED_OTHER;
+
+ /*
+ * This function must return the priority value set by
+ * the most recent pthread_setschedparam() or pthread_create()
+ * for the target thread. It must not return the actual thread
+ * priority as altered by any system priority adjustments etc.
+ */
+ param->sched_priority = ((ptw32_thread_t *)thread.p)->sched_priority;
+
+ return 0;
+}
diff --git a/pthreads/pthread_getspecific.c b/pthreads/pthread_getspecific.c
new file mode 100644
index 000000000..b05ff410a
--- /dev/null
+++ b/pthreads/pthread_getspecific.c
@@ -0,0 +1,84 @@
+/*
+ * pthread_getspecific.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"
+
+
+void *
+pthread_getspecific (pthread_key_t key)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function returns the current value of key in the
+ * calling thread. If no value has been set for 'key' in
+ * the thread, NULL is returned.
+ *
+ * PARAMETERS
+ * key
+ * an instance of pthread_key_t
+ *
+ *
+ * DESCRIPTION
+ * This function returns the current value of key in the
+ * calling thread. If no value has been set for 'key' in
+ * the thread, NULL is returned.
+ *
+ * RESULTS
+ * key value or NULL on failure
+ *
+ * ------------------------------------------------------
+ */
+{
+ void * ptr;
+
+ if (key == NULL)
+ {
+ ptr = NULL;
+ }
+ else
+ {
+ int lasterror = GetLastError ();
+ int lastWSAerror = WSAGetLastError ();
+
+ ptr = TlsGetValue (key->key);
+
+ SetLastError (lasterror);
+ WSASetLastError (lastWSAerror);
+ }
+
+ return ptr;
+}
diff --git a/pthreads/pthread_getw32threadhandle_np.c b/pthreads/pthread_getw32threadhandle_np.c
new file mode 100644
index 000000000..9d22def3b
--- /dev/null
+++ b/pthreads/pthread_getw32threadhandle_np.c
@@ -0,0 +1,53 @@
+/*
+ * pthread_getw32threadhandle_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"
+
+/*
+ * pthread_getw32threadhandle_np()
+ *
+ * Returns the win32 thread handle that the POSIX
+ * thread "thread" is running as.
+ *
+ * Applications can use the win32 handle to set
+ * win32 specific attributes of the thread.
+ */
+HANDLE
+pthread_getw32threadhandle_np (pthread_t thread)
+{
+ return ((ptw32_thread_t *)thread.p)->threadH;
+}
diff --git a/pthreads/pthread_join.c b/pthreads/pthread_join.c
new file mode 100644
index 000000000..8237b6cf7
--- /dev/null
+++ b/pthreads/pthread_join.c
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+#include <signal.h>
+
+
+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 */
diff --git a/pthreads/pthread_key_create.c b/pthreads/pthread_key_create.c
new file mode 100644
index 000000000..5e278c2ca
--- /dev/null
+++ b/pthreads/pthread_key_create.c
@@ -0,0 +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 multiple 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);
+}
diff --git a/pthreads/pthread_key_delete.c b/pthreads/pthread_key_delete.c
new file mode 100644
index 000000000..7da9b2fb6
--- /dev/null
+++ b/pthreads/pthread_key_delete.c
@@ -0,0 +1,133 @@
+/*
+ * 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(1); // Ugly.
+ }
+ }
+
+#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
new file mode 100644
index 000000000..7de3fe2aa
--- /dev/null
+++ b/pthreads/pthread_kill.c
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+#include <signal.h>
+
+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 */
diff --git a/pthreads/pthread_mutex_destroy.c b/pthreads/pthread_mutex_destroy.c
new file mode 100644
index 000000000..95509b3df
--- /dev/null
+++ b/pthreads/pthread_mutex_destroy.c
@@ -0,0 +1,146 @@
+/*
+ * pthread_mutex_destroy.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_mutex_destroy (pthread_mutex_t * mutex)
+{
+ int result = 0;
+ pthread_mutex_t mx;
+
+ /*
+ * Let the system deal with invalid pointers.
+ */
+
+ /*
+ * Check to see if we have something to delete.
+ */
+ if (*mutex < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+ {
+ mx = *mutex;
+
+ result = pthread_mutex_trylock (&mx);
+
+ /*
+ * If trylock succeeded and the mutex is not recursively locked it
+ * can be destroyed.
+ */
+ if (result == 0)
+ {
+ if (mx->kind != PTHREAD_MUTEX_RECURSIVE || 1 == mx->recursive_count)
+ {
+ /*
+ * FIXME!!!
+ * The mutex isn't held by another thread but we could still
+ * 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);
+
+ if (result == 0)
+ {
+ if (!CloseHandle (mx->event))
+ {
+ *mutex = mx;
+ result = EINVAL;
+ }
+ else
+ {
+ free (mx);
+ }
+ }
+ else
+ {
+ /*
+ * Restore the mutex before we return the error.
+ */
+ *mutex = mx;
+ }
+ }
+ else /* mx->recursive_count > 1 */
+ {
+ /*
+ * The mutex must be recursive and already locked by us (this thread).
+ */
+ mx->recursive_count--; /* Undo effect of pthread_mutex_trylock() above */
+ result = EBUSY;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * See notes in ptw32_mutex_check_need_init() above also.
+ */
+ EnterCriticalSection (&ptw32_mutex_test_init_lock);
+
+ /*
+ * Check again.
+ */
+ if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+ {
+ /*
+ * This is all we need to do to destroy a statically
+ * initialised mutex that has not yet been used (initialised).
+ * If we get to here, another thread
+ * waiting to initialise this mutex will get an EINVAL.
+ */
+ *mutex = NULL;
+ }
+ else
+ {
+ /*
+ * The mutex has been initialised while we were waiting
+ * so assume it's in use.
+ */
+ result = EBUSY;
+ }
+
+ LeaveCriticalSection (&ptw32_mutex_test_init_lock);
+ }
+
+ return (result);
+}
diff --git a/pthreads/pthread_mutex_init.c b/pthreads/pthread_mutex_init.c
new file mode 100644
index 000000000..cff8e5054
--- /dev/null
+++ b/pthreads/pthread_mutex_init.c
@@ -0,0 +1,104 @@
+/*
+ * pthread_mutex_init.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_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr)
+{
+ int result = 0;
+ pthread_mutex_t mx;
+
+ if (mutex == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (attr != NULL
+ && *attr != NULL && (*attr)->pshared == PTHREAD_PROCESS_SHARED)
+ {
+ /*
+ * Creating mutex that can be shared between
+ * processes.
+ */
+#if _POSIX_THREAD_PROCESS_SHARED >= 0
+
+ /*
+ * Not implemented yet.
+ */
+
+#error ERROR [__FILE__, line __LINE__]: Process shared mutexes are not supported yet.
+
+#else
+
+ return ENOSYS;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+
+ }
+
+ mx = (pthread_mutex_t) calloc (1, sizeof (*mx));
+
+ if (mx == NULL)
+ {
+ result = ENOMEM;
+ }
+ else
+ {
+ mx->lock_idx = 0;
+ mx->recursive_count = 0;
+ mx->kind = (attr == NULL || *attr == NULL
+ ? PTHREAD_MUTEX_DEFAULT : (*attr)->kind);
+ mx->ownerThread.p = NULL;
+
+ mx->event = CreateEvent (NULL, PTW32_FALSE, /* manual reset = No */
+ PTW32_FALSE, /* initial state = not signaled */
+ NULL); /* event name */
+
+ if (0 == mx->event)
+ {
+ result = ENOSPC;
+ free (mx);
+ mx = NULL;
+ }
+ }
+
+ *mutex = mx;
+
+ return (result);
+}
diff --git a/pthreads/pthread_mutex_lock.c b/pthreads/pthread_mutex_lock.c
new file mode 100644
index 000000000..4ca5c252f
--- /dev/null
+++ b/pthreads/pthread_mutex_lock.c
@@ -0,0 +1,139 @@
+/*
+ * 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 <process.h>
+#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);
+}
diff --git a/pthreads/pthread_mutex_timedlock.c b/pthreads/pthread_mutex_timedlock.c
new file mode 100644
index 000000000..a2385522d
--- /dev/null
+++ b/pthreads/pthread_mutex_timedlock.c
@@ -0,0 +1,196 @@
+/*
+ * pthread_mutex_timedlock.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+static INLINE int
+ptw32_timed_eventwait (HANDLE event, const struct timespec *abstime)
+ /*
+ * ------------------------------------------------------
+ * DESCRIPTION
+ * This function waits on an event until signaled or until
+ * abstime passes.
+ * If abstime has passed when this routine is called then
+ * it returns a result to indicate this.
+ *
+ * If 'abstime' is a NULL pointer then this function will
+ * block until it can successfully decrease the value or
+ * until interrupted by a signal.
+ *
+ * This routine is not a cancelation point.
+ *
+ * RESULTS
+ * 0 successfully signaled,
+ * ETIMEDOUT abstime passed
+ * EINVAL 'event' is not a valid event,
+ *
+ * ------------------------------------------------------
+ */
+{
+
+ DWORD milliseconds;
+ DWORD status;
+
+ if (event == NULL)
+ {
+ return EINVAL;
+ }
+ else
+ {
+ if (abstime == NULL)
+ {
+ milliseconds = INFINITE;
+ }
+ else
+ {
+ /*
+ * Calculate timeout as milliseconds from current system time.
+ */
+ milliseconds = ptw32_relmillisecs (abstime);
+ }
+
+ status = WaitForSingleObject (event, milliseconds);
+
+ if (status == WAIT_OBJECT_0)
+ {
+ return 0;
+ }
+ else if (status == WAIT_TIMEOUT)
+ {
+ return ETIMEDOUT;
+ }
+ else
+ {
+ return EINVAL;
+ }
+ }
+
+ return 0;
+
+} /* ptw32_timed_semwait */
+
+
+int
+pthread_mutex_timedlock (pthread_mutex_t * mutex,
+ const struct timespec *abstime)
+{
+ int result;
+ pthread_mutex_t mx;
+
+ /*
+ * Let the system deal with invalid pointers.
+ */
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static mutex. We check
+ * again inside the guarded section of ptw32_mutex_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+ {
+ if ((result = ptw32_mutex_check_need_init (mutex)) != 0)
+ {
+ return (result);
+ }
+ }
+
+ mx = *mutex;
+
+ if (mx->kind == PTHREAD_MUTEX_NORMAL)
+ {
+ if ((LONG) PTW32_INTERLOCKED_EXCHANGE(
+ (LPLONG) &mx->lock_idx,
+ (LONG) 1) != 0)
+ {
+ while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
+ (LPLONG) &mx->lock_idx,
+ (LONG) -1) != 0)
+ {
+ if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
+ {
+ return result;
+ }
+ }
+ }
+ }
+ else
+ {
+ pthread_t self = pthread_self();
+
+ if ((PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE(
+ (PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1,
+ (PTW32_INTERLOCKED_LONG) 0) == 0)
+ {
+ mx->recursive_count = 1;
+ mx->ownerThread = self;
+ }
+ else
+ {
+ if (pthread_equal (mx->ownerThread, self))
+ {
+ if (mx->kind == PTHREAD_MUTEX_RECURSIVE)
+ {
+ mx->recursive_count++;
+ }
+ else
+ {
+ return EDEADLK;
+ }
+ }
+ else
+ {
+ while ((LONG) PTW32_INTERLOCKED_EXCHANGE(
+ (LPLONG) &mx->lock_idx,
+ (LONG) -1) != 0)
+ {
+ if (0 != (result = ptw32_timed_eventwait (mx->event, abstime)))
+ {
+ return result;
+ }
+ }
+
+ mx->recursive_count = 1;
+ mx->ownerThread = self;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/pthreads/pthread_mutex_trylock.c b/pthreads/pthread_mutex_trylock.c
new file mode 100644
index 000000000..50e8bc65c
--- /dev/null
+++ b/pthreads/pthread_mutex_trylock.c
@@ -0,0 +1,92 @@
+/*
+ * pthread_mutex_trylock.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_mutex_trylock (pthread_mutex_t * mutex)
+{
+ int result = 0;
+ pthread_mutex_t mx;
+
+ /*
+ * Let the system deal with invalid pointers.
+ */
+
+ /*
+ * We do a quick check to see if we need to do more work
+ * to initialise a static mutex. We check
+ * again inside the guarded section of ptw32_mutex_check_need_init()
+ * to avoid race conditions.
+ */
+ if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+ {
+ if ((result = ptw32_mutex_check_need_init (mutex)) != 0)
+ {
+ return (result);
+ }
+ }
+
+ mx = *mutex;
+
+ if (0 == (LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE (
+ (PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1,
+ (PTW32_INTERLOCKED_LONG) 0))
+ {
+ if (mx->kind != PTHREAD_MUTEX_NORMAL)
+ {
+ mx->recursive_count = 1;
+ mx->ownerThread = pthread_self ();
+ }
+ }
+ else
+ {
+ if (mx->kind == PTHREAD_MUTEX_RECURSIVE &&
+ pthread_equal (mx->ownerThread, pthread_self ()))
+ {
+ mx->recursive_count++;
+ }
+ else
+ {
+ result = EBUSY;
+ }
+ }
+
+ return (result);
+}
diff --git a/pthreads/pthread_mutex_unlock.c b/pthreads/pthread_mutex_unlock.c
new file mode 100644
index 000000000..9ebe4e378
--- /dev/null
+++ b/pthreads/pthread_mutex_unlock.c
@@ -0,0 +1,119 @@
+/*
+ * pthread_mutex_unlock.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_mutex_unlock (pthread_mutex_t * mutex)
+{
+ int result = 0;
+ pthread_mutex_t mx;
+
+ /*
+ * Let the system deal with invalid pointers.
+ */
+
+ mx = *mutex;
+
+ /*
+ * If the thread calling us holds the mutex then there is no
+ * race condition. If another thread holds the
+ * lock then we shouldn't be in here.
+ */
+ if (mx < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+ {
+ if (mx->kind == PTHREAD_MUTEX_NORMAL)
+ {
+ LONG idx;
+
+ idx = (LONG) PTW32_INTERLOCKED_EXCHANGE ((LPLONG) &mx->lock_idx,
+ (LONG) 0);
+ if (idx != 0)
+ {
+ 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;
+
+ if ((LONG) PTW32_INTERLOCKED_EXCHANGE ((LPLONG) &mx->lock_idx,
+ (LONG) 0) < 0)
+ {
+ /* Someone may be waiting on that mutex */
+ if (SetEvent (mx->event) == 0)
+ {
+ result = EINVAL;
+ }
+ }
+ }
+ }
+ else
+ {
+ result = EPERM;
+ }
+ }
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+}
diff --git a/pthreads/pthread_mutexattr_destroy.c b/pthreads/pthread_mutexattr_destroy.c
new file mode 100644
index 000000000..9d424bfa2
--- /dev/null
+++ b/pthreads/pthread_mutexattr_destroy.c
@@ -0,0 +1,83 @@
+/*
+ * pthread_mutexattr_destroy.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_destroy (pthread_mutexattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Destroys a mutex attributes object. The object can
+ * no longer be used.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ *
+ * DESCRIPTION
+ * Destroys a mutex attributes object. The object can
+ * no longer be used.
+ *
+ * NOTES:
+ * 1) Does not affect mutexes created using 'attr'
+ *
+ * RESULTS
+ * 0 successfully released attr,
+ * EINVAL 'attr' is invalid.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+
+ if (attr == NULL || *attr == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ pthread_mutexattr_t ma = *attr;
+
+ *attr = NULL;
+ free (ma);
+ }
+
+ return (result);
+} /* pthread_mutexattr_destroy */
diff --git a/pthreads/pthread_mutexattr_getkind_np.c b/pthreads/pthread_mutexattr_getkind_np.c
new file mode 100644
index 000000000..2d82ec6bc
--- /dev/null
+++ b/pthreads/pthread_mutexattr_getkind_np.c
@@ -0,0 +1,44 @@
+/*
+ * pthread_mutexattr_getkind_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"
+
+int
+pthread_mutexattr_getkind_np (pthread_mutexattr_t * attr, int *kind)
+{
+ return pthread_mutexattr_gettype (attr, kind);
+}
diff --git a/pthreads/pthread_mutexattr_getpshared.c b/pthreads/pthread_mutexattr_getpshared.c
new file mode 100644
index 000000000..42f9589c5
--- /dev/null
+++ b/pthreads/pthread_mutexattr_getpshared.c
@@ -0,0 +1,95 @@
+/*
+ * pthread_mutexattr_getpshared.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_getpshared (const pthread_mutexattr_t * attr, int *pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Determine whether mutexes created with 'attr' can be
+ * shared between processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ * pshared
+ * will be set to one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ *
+ * DESCRIPTION
+ * Mutexes creatd with 'attr' can be shared between
+ * processes if pthread_mutex_t variable is allocated
+ * in memory shared by these processes.
+ * NOTES:
+ * 1) pshared mutexes MUST be allocated in shared
+ * memory.
+ * 2) The following macro is defined if shared mutexes
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully retrieved attribute,
+ * EINVAL 'attr' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) && (pshared != NULL))
+ {
+ *pshared = (*attr)->pshared;
+ result = 0;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+
+} /* pthread_mutexattr_getpshared */
diff --git a/pthreads/pthread_mutexattr_gettype.c b/pthreads/pthread_mutexattr_gettype.c
new file mode 100644
index 000000000..b60ca30bf
--- /dev/null
+++ b/pthreads/pthread_mutexattr_gettype.c
@@ -0,0 +1,56 @@
+/*
+ * pthread_mutexattr_gettype.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_gettype (pthread_mutexattr_t * attr, int *kind)
+{
+ int result = 0;
+
+ if (attr != NULL && *attr != NULL && kind != NULL)
+ {
+ *kind = (*attr)->kind;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+}
diff --git a/pthreads/pthread_mutexattr_init.c b/pthreads/pthread_mutexattr_init.c
new file mode 100644
index 000000000..d2797ff24
--- /dev/null
+++ b/pthreads/pthread_mutexattr_init.c
@@ -0,0 +1,86 @@
+/*
+ * pthread_mutexattr_init.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_init (pthread_mutexattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Initializes a mutex attributes object with default
+ * attributes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ *
+ * DESCRIPTION
+ * Initializes a mutex attributes object with default
+ * attributes.
+ *
+ * NOTES:
+ * 1) Used to define mutex types
+ *
+ * RESULTS
+ * 0 successfully initialized attr,
+ * ENOMEM insufficient memory for attr.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ pthread_mutexattr_t ma;
+
+ ma = (pthread_mutexattr_t) calloc (1, sizeof (*ma));
+
+ if (ma == NULL)
+ {
+ result = ENOMEM;
+ }
+ else
+ {
+ ma->pshared = PTHREAD_PROCESS_PRIVATE;
+ ma->kind = PTHREAD_MUTEX_DEFAULT;
+ }
+
+ *attr = ma;
+
+ return (result);
+} /* pthread_mutexattr_init */
diff --git a/pthreads/pthread_mutexattr_setkind_np.c b/pthreads/pthread_mutexattr_setkind_np.c
new file mode 100644
index 000000000..faa936658
--- /dev/null
+++ b/pthreads/pthread_mutexattr_setkind_np.c
@@ -0,0 +1,44 @@
+/*
+ * pthread_mutexattr_setkind_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"
+
+int
+pthread_mutexattr_setkind_np (pthread_mutexattr_t * attr, int kind)
+{
+ return pthread_mutexattr_settype (attr, kind);
+}
diff --git a/pthreads/pthread_mutexattr_setpshared.c b/pthreads/pthread_mutexattr_setpshared.c
new file mode 100644
index 000000000..cfa6f7199
--- /dev/null
+++ b/pthreads/pthread_mutexattr_setpshared.c
@@ -0,0 +1,119 @@
+/*
+ * pthread_mutexattr_setpshared.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_setpshared (pthread_mutexattr_t * attr, int pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Mutexes created with 'attr' can be shared between
+ * processes if pthread_mutex_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ * pshared
+ * must be one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ * DESCRIPTION
+ * Mutexes creatd with 'attr' can be shared between
+ * processes if pthread_mutex_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * NOTES:
+ * 1) pshared mutexes MUST be allocated in shared
+ * memory.
+ *
+ * 2) The following macro is defined if shared mutexes
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully set attribute,
+ * EINVAL 'attr' or pshared is invalid,
+ * ENOSYS PTHREAD_PROCESS_SHARED not supported,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) &&
+ ((pshared == PTHREAD_PROCESS_SHARED) ||
+ (pshared == PTHREAD_PROCESS_PRIVATE)))
+ {
+ if (pshared == PTHREAD_PROCESS_SHARED)
+ {
+
+#if !defined( _POSIX_THREAD_PROCESS_SHARED )
+
+ result = ENOSYS;
+ pshared = PTHREAD_PROCESS_PRIVATE;
+
+#else
+
+ result = 0;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+
+ }
+ else
+ {
+ result = 0;
+ }
+
+ (*attr)->pshared = pshared;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+
+} /* pthread_mutexattr_setpshared */
diff --git a/pthreads/pthread_mutexattr_settype.c b/pthreads/pthread_mutexattr_settype.c
new file mode 100644
index 000000000..8365daf65
--- /dev/null
+++ b/pthreads/pthread_mutexattr_settype.c
@@ -0,0 +1,143 @@
+/*
+ * pthread_mutexattr_settype.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_settype (pthread_mutexattr_t * attr, int kind)
+ /*
+ * ------------------------------------------------------
+ *
+ * DOCPUBLIC
+ * The pthread_mutexattr_settype() and
+ * pthread_mutexattr_gettype() functions respectively set and
+ * get the mutex type attribute. This attribute is set in the
+ * type parameter to these functions.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_mutexattr_t
+ *
+ * type
+ * must be one of:
+ *
+ * PTHREAD_MUTEX_DEFAULT
+ *
+ * PTHREAD_MUTEX_NORMAL
+ *
+ * PTHREAD_MUTEX_ERRORCHECK
+ *
+ * PTHREAD_MUTEX_RECURSIVE
+ *
+ * DESCRIPTION
+ * The pthread_mutexattr_settype() and
+ * pthread_mutexattr_gettype() functions respectively set and
+ * get the mutex type attribute. This attribute is set in the
+ * type parameter to these functions. The default value of the
+ * type attribute is PTHREAD_MUTEX_DEFAULT.
+ *
+ * The type of mutex is contained in the type attribute of the
+ * mutex attributes. Valid mutex types include:
+ *
+ * PTHREAD_MUTEX_NORMAL
+ * This type of mutex does not detect deadlock. A
+ * thread attempting to relock this mutex without
+ * first unlocking it will deadlock. Attempting to
+ * unlock a mutex locked by a different thread
+ * results in undefined behavior. Attempting to
+ * unlock an unlocked mutex results in undefined
+ * behavior.
+ *
+ * PTHREAD_MUTEX_ERRORCHECK
+ * This type of mutex provides error checking. A
+ * thread attempting to relock this mutex without
+ * first unlocking it will return with an error. A
+ * thread attempting to unlock a mutex which another
+ * thread has locked will return with an error. A
+ * thread attempting to unlock an unlocked mutex will
+ * return with an error.
+ *
+ * PTHREAD_MUTEX_DEFAULT
+ * Same as PTHREAD_MUTEX_NORMAL.
+ *
+ * PTHREAD_MUTEX_RECURSIVE
+ * A thread attempting to relock this mutex without
+ * first unlocking it will succeed in locking the
+ * mutex. The relocking deadlock which can occur with
+ * mutexes of type PTHREAD_MUTEX_NORMAL cannot occur
+ * with this type of mutex. Multiple locks of this
+ * mutex require the same number of unlocks to
+ * release the mutex before another thread can
+ * acquire the mutex. A thread attempting to unlock a
+ * mutex which another thread has locked will return
+ * with an error. A thread attempting to unlock an
+ * unlocked mutex will return with an error. This
+ * type of mutex is only supported for mutexes whose
+ * process shared attribute is
+ * PTHREAD_PROCESS_PRIVATE.
+ *
+ * RESULTS
+ * 0 successfully set attribute,
+ * EINVAL 'attr' or 'type' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+
+ if ((attr != NULL && *attr != NULL))
+ {
+ switch (kind)
+ {
+ case PTHREAD_MUTEX_FAST_NP:
+ case PTHREAD_MUTEX_RECURSIVE_NP:
+ case PTHREAD_MUTEX_ERRORCHECK_NP:
+ (*attr)->kind = kind;
+ break;
+ default:
+ result = EINVAL;
+ break;
+ }
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+} /* pthread_mutexattr_settype */
diff --git a/pthreads/pthread_num_processors_np.c b/pthreads/pthread_num_processors_np.c
new file mode 100644
index 000000000..3067d117d
--- /dev/null
+++ b/pthreads/pthread_num_processors_np.c
@@ -0,0 +1,56 @@
+/*
+ * pthread_num_processors_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"
+
+/*
+ * pthread_num_processors_np()
+ *
+ * Get the number of CPUs available to the process.
+ */
+int
+pthread_num_processors_np (void)
+{
+ int count;
+
+ if (ptw32_getprocessors (&count) != 0)
+ {
+ count = 1;
+ }
+
+ return (count);
+}
diff --git a/pthreads/pthread_once.c b/pthreads/pthread_once.c
new file mode 100644
index 000000000..96d45f297
--- /dev/null
+++ b/pthreads/pthread_once.c
@@ -0,0 +1,86 @@
+/*
+ * 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 initting 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 */
diff --git a/pthreads/pthread_rwlock_destroy.c b/pthreads/pthread_rwlock_destroy.c
new file mode 100644
index 000000000..5a747ede0
--- /dev/null
+++ b/pthreads/pthread_rwlock_destroy.c
@@ -0,0 +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 <errno.h>
+#include <limits.h>
+
+#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));
+}
diff --git a/pthreads/pthread_rwlock_init.c b/pthreads/pthread_rwlock_init.c
new file mode 100644
index 000000000..3e3f448c0
--- /dev/null
+++ b/pthreads/pthread_rwlock_init.c
@@ -0,0 +1,110 @@
+/*
+ * pthread_rwlock_init.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 <errno.h>
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_init (pthread_rwlock_t * rwlock,
+ const pthread_rwlockattr_t * attr)
+{
+ int result;
+ pthread_rwlock_t rwl = 0;
+
+ if (rwlock == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (attr != NULL && *attr != NULL)
+ {
+ result = EINVAL; /* Not supported */
+ goto DONE;
+ }
+
+ rwl = (pthread_rwlock_t) calloc (1, sizeof (*rwl));
+
+ if (rwl == NULL)
+ {
+ result = ENOMEM;
+ goto DONE;
+ }
+
+ rwl->nSharedAccessCount = 0;
+ rwl->nExclusiveAccessCount = 0;
+ rwl->nCompletedSharedAccessCount = 0;
+
+ result = pthread_mutex_init (&rwl->mtxExclusiveAccess, NULL);
+ if (result != 0)
+ {
+ goto FAIL0;
+ }
+
+ result = pthread_mutex_init (&rwl->mtxSharedAccessCompleted, NULL);
+ if (result != 0)
+ {
+ goto FAIL1;
+ }
+
+ result = pthread_cond_init (&rwl->cndSharedAccessCompleted, NULL);
+ if (result != 0)
+ {
+ goto FAIL2;
+ }
+
+ rwl->nMagic = PTW32_RWLOCK_MAGIC;
+
+ result = 0;
+ goto DONE;
+
+FAIL2:
+ (void) pthread_mutex_destroy (&(rwl->mtxSharedAccessCompleted));
+
+FAIL1:
+ (void) pthread_mutex_destroy (&(rwl->mtxExclusiveAccess));
+
+FAIL0:
+ (void) free (rwl);
+ rwl = NULL;
+
+DONE:
+ *rwlock = rwl;
+
+ return result;
+}
diff --git a/pthreads/pthread_rwlock_rdlock.c b/pthreads/pthread_rwlock_rdlock.c
new file mode 100644
index 000000000..dba63ddfb
--- /dev/null
+++ b/pthreads/pthread_rwlock_rdlock.c
@@ -0,0 +1,103 @@
+/*
+ * pthread_rwlock_rdlock.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 <errno.h>
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_rdlock (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 (++rwl->nSharedAccessCount == INT_MAX)
+ {
+ if ((result =
+ pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+
+ rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
+ rwl->nCompletedSharedAccessCount = 0;
+
+ if ((result =
+ pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+ }
+
+ return (pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)));
+}
diff --git a/pthreads/pthread_rwlock_timedrdlock.c b/pthreads/pthread_rwlock_timedrdlock.c
new file mode 100644
index 000000000..93489502e
--- /dev/null
+++ b/pthreads/pthread_rwlock_timedrdlock.c
@@ -0,0 +1,110 @@
+/*
+ * pthread_rwlock_timedrdlock.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 <errno.h>
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_timedrdlock (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 (++rwl->nSharedAccessCount == INT_MAX)
+ {
+ if ((result =
+ pthread_mutex_timedlock (&(rwl->mtxSharedAccessCompleted),
+ abstime)) != 0)
+ {
+ if (result == ETIMEDOUT)
+ {
+ ++rwl->nCompletedSharedAccessCount;
+ }
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+
+ rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
+ rwl->nCompletedSharedAccessCount = 0;
+
+ if ((result =
+ pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+ }
+
+ return (pthread_mutex_unlock (&(rwl->mtxExclusiveAccess)));
+}
diff --git a/pthreads/pthread_rwlock_timedwrlock.c b/pthreads/pthread_rwlock_timedwrlock.c
new file mode 100644
index 000000000..e7d1be257
--- /dev/null
+++ b/pthreads/pthread_rwlock_timedwrlock.c
@@ -0,0 +1,140 @@
+/*
+ * 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 <errno.h>
+#include <limits.h>
+
+#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;
+}
diff --git a/pthreads/pthread_rwlock_tryrdlock.c b/pthreads/pthread_rwlock_tryrdlock.c
new file mode 100644
index 000000000..308900d14
--- /dev/null
+++ b/pthreads/pthread_rwlock_tryrdlock.c
@@ -0,0 +1,103 @@
+/*
+ * pthread_rwlock_tryrdlock.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 <errno.h>
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_tryrdlock (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_trylock (&(rwl->mtxExclusiveAccess))) != 0)
+ {
+ return result;
+ }
+
+ if (++rwl->nSharedAccessCount == INT_MAX)
+ {
+ if ((result =
+ pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+
+ rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
+ rwl->nCompletedSharedAccessCount = 0;
+
+ if ((result =
+ pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+ }
+
+ return (pthread_mutex_unlock (&rwl->mtxExclusiveAccess));
+}
diff --git a/pthreads/pthread_rwlock_trywrlock.c b/pthreads/pthread_rwlock_trywrlock.c
new file mode 100644
index 000000000..8ba8b5dad
--- /dev/null
+++ b/pthreads/pthread_rwlock_trywrlock.c
@@ -0,0 +1,123 @@
+/*
+ * pthread_rwlock_trywrlock.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 <errno.h>
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_trywrlock (pthread_rwlock_t * rwlock)
+{
+ int result, result1;
+ 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_trylock (&(rwl->mtxExclusiveAccess))) != 0)
+ {
+ return result;
+ }
+
+ if ((result =
+ pthread_mutex_trylock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return ((result1 != 0) ? result1 : result);
+ }
+
+ if (rwl->nExclusiveAccessCount == 0)
+ {
+ if (rwl->nCompletedSharedAccessCount > 0)
+ {
+ rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount;
+ rwl->nCompletedSharedAccessCount = 0;
+ }
+
+ if (rwl->nSharedAccessCount > 0)
+ {
+ if ((result =
+ pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+ return result;
+ }
+
+ if ((result =
+ pthread_mutex_unlock (&(rwl->mtxExclusiveAccess))) == 0)
+ {
+ result = EBUSY;
+ }
+ }
+ else
+ {
+ rwl->nExclusiveAccessCount = 1;
+ }
+ }
+ else
+ {
+ result = EBUSY;
+ }
+
+ return result;
+}
diff --git a/pthreads/pthread_rwlock_unlock.c b/pthreads/pthread_rwlock_unlock.c
new file mode 100644
index 000000000..776c996fe
--- /dev/null
+++ b/pthreads/pthread_rwlock_unlock.c
@@ -0,0 +1,94 @@
+/*
+ * pthread_rwlock_unlock.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 <errno.h>
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlock_unlock (pthread_rwlock_t * rwlock)
+{
+ int result, result1;
+ pthread_rwlock_t rwl;
+
+ if (rwlock == NULL || *rwlock == NULL)
+ {
+ return (EINVAL);
+ }
+
+ if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
+ {
+ /*
+ * Assume any race condition here is harmless.
+ */
+ return 0;
+ }
+
+ rwl = *rwlock;
+
+ if (rwl->nMagic != PTW32_RWLOCK_MAGIC)
+ {
+ return EINVAL;
+ }
+
+ if (rwl->nExclusiveAccessCount == 0)
+ {
+ if ((result =
+ pthread_mutex_lock (&(rwl->mtxSharedAccessCompleted))) != 0)
+ {
+ return result;
+ }
+
+ if (++rwl->nCompletedSharedAccessCount == 0)
+ {
+ result = pthread_cond_signal (&(rwl->cndSharedAccessCompleted));
+ }
+
+ result1 = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted));
+ }
+ else
+ {
+ rwl->nExclusiveAccessCount--;
+
+ result = pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted));
+ result1 = pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+
+ }
+
+ return ((result != 0) ? result : result1);
+}
diff --git a/pthreads/pthread_rwlock_wrlock.c b/pthreads/pthread_rwlock_wrlock.c
new file mode 100644
index 000000000..a09704044
--- /dev/null
+++ b/pthreads/pthread_rwlock_wrlock.c
@@ -0,0 +1,134 @@
+/*
+ * 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 <errno.h>
+#include <limits.h>
+
+#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;
+}
diff --git a/pthreads/pthread_rwlockattr_destroy.c b/pthreads/pthread_rwlockattr_destroy.c
new file mode 100644
index 000000000..0fcbe8405
--- /dev/null
+++ b/pthreads/pthread_rwlockattr_destroy.c
@@ -0,0 +1,85 @@
+/*
+ * pthread_rwlockattr_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 <errno.h>
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Destroys a rwlock attributes object. The object can
+ * no longer be used.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_rwlockattr_t
+ *
+ *
+ * DESCRIPTION
+ * Destroys a rwlock attributes object. The object can
+ * no longer be used.
+ *
+ * NOTES:
+ * 1) Does not affect rwlockss created using 'attr'
+ *
+ * RESULTS
+ * 0 successfully released attr,
+ * EINVAL 'attr' is invalid.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+
+ if (attr == NULL || *attr == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ pthread_rwlockattr_t rwa = *attr;
+
+ *attr = NULL;
+ free (rwa);
+ }
+
+ return (result);
+} /* pthread_rwlockattr_destroy */
diff --git a/pthreads/pthread_rwlockattr_getpshared.c b/pthreads/pthread_rwlockattr_getpshared.c
new file mode 100644
index 000000000..abfe63f25
--- /dev/null
+++ b/pthreads/pthread_rwlockattr_getpshared.c
@@ -0,0 +1,98 @@
+/*
+ * pthread_rwlockattr_getpshared.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 <errno.h>
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
+ int *pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Determine whether rwlocks created with 'attr' can be
+ * shared between processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_rwlockattr_t
+ *
+ * pshared
+ * will be set to one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ *
+ * DESCRIPTION
+ * Rwlocks creatd with 'attr' can be shared between
+ * processes if pthread_rwlock_t variable is allocated
+ * in memory shared by these processes.
+ * NOTES:
+ * 1) pshared rwlocks MUST be allocated in shared
+ * memory.
+ * 2) The following macro is defined if shared rwlocks
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully retrieved attribute,
+ * EINVAL 'attr' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) && (pshared != NULL))
+ {
+ *pshared = (*attr)->pshared;
+ result = 0;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+
+} /* pthread_rwlockattr_getpshared */
diff --git a/pthreads/pthread_rwlockattr_init.c b/pthreads/pthread_rwlockattr_init.c
new file mode 100644
index 000000000..feb8e9407
--- /dev/null
+++ b/pthreads/pthread_rwlockattr_init.c
@@ -0,0 +1,84 @@
+/*
+ * pthread_rwlockattr_init.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 <errno.h>
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlockattr_init (pthread_rwlockattr_t * attr)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Initializes a rwlock attributes object with default
+ * attributes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_rwlockattr_t
+ *
+ *
+ * DESCRIPTION
+ * Initializes a rwlock attributes object with default
+ * attributes.
+ *
+ * RESULTS
+ * 0 successfully initialized attr,
+ * ENOMEM insufficient memory for attr.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ pthread_rwlockattr_t rwa;
+
+ rwa = (pthread_rwlockattr_t) calloc (1, sizeof (*rwa));
+
+ if (rwa == NULL)
+ {
+ result = ENOMEM;
+ }
+ else
+ {
+ rwa->pshared = PTHREAD_PROCESS_PRIVATE;
+ }
+
+ *attr = rwa;
+
+ return (result);
+} /* pthread_rwlockattr_init */
diff --git a/pthreads/pthread_rwlockattr_setpshared.c b/pthreads/pthread_rwlockattr_setpshared.c
new file mode 100644
index 000000000..316532cb2
--- /dev/null
+++ b/pthreads/pthread_rwlockattr_setpshared.c
@@ -0,0 +1,121 @@
+/*
+ * pthread_rwlockattr_setpshared.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 <errno.h>
+#include <limits.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, int pshared)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Rwlocks created with 'attr' can be shared between
+ * processes if pthread_rwlock_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * PARAMETERS
+ * attr
+ * pointer to an instance of pthread_rwlockattr_t
+ *
+ * pshared
+ * must be one of:
+ *
+ * PTHREAD_PROCESS_SHARED
+ * May be shared if in shared memory
+ *
+ * PTHREAD_PROCESS_PRIVATE
+ * Cannot be shared.
+ *
+ * DESCRIPTION
+ * Rwlocks creatd with 'attr' can be shared between
+ * processes if pthread_rwlock_t variable is allocated
+ * in memory shared by these processes.
+ *
+ * NOTES:
+ * 1) pshared rwlocks MUST be allocated in shared
+ * memory.
+ *
+ * 2) The following macro is defined if shared rwlocks
+ * are supported:
+ * _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ * 0 successfully set attribute,
+ * EINVAL 'attr' or pshared is invalid,
+ * ENOSYS PTHREAD_PROCESS_SHARED not supported,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result;
+
+ if ((attr != NULL && *attr != NULL) &&
+ ((pshared == PTHREAD_PROCESS_SHARED) ||
+ (pshared == PTHREAD_PROCESS_PRIVATE)))
+ {
+ if (pshared == PTHREAD_PROCESS_SHARED)
+ {
+
+#if !defined( _POSIX_THREAD_PROCESS_SHARED )
+
+ result = ENOSYS;
+ pshared = PTHREAD_PROCESS_PRIVATE;
+
+#else
+
+ result = 0;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+
+ }
+ else
+ {
+ result = 0;
+ }
+
+ (*attr)->pshared = pshared;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return (result);
+
+} /* pthread_rwlockattr_setpshared */
diff --git a/pthreads/pthread_self.c b/pthreads/pthread_self.c
new file mode 100644
index 000000000..d72a0971d
--- /dev/null
+++ b/pthreads/pthread_self.c
@@ -0,0 +1,138 @@
+/*
+ * pthread_self.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"
+
+pthread_t
+pthread_self (void)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function returns a reference to the current running
+ * thread.
+ *
+ * PARAMETERS
+ * N/A
+ *
+ *
+ * DESCRIPTION
+ * This function returns a reference to the current running
+ * thread.
+ *
+ * RESULTS
+ * pthread_t reference to the current thread
+ *
+ * ------------------------------------------------------
+ */
+{
+ pthread_t self;
+ pthread_t nil = {NULL, 0};
+ ptw32_thread_t * sp;
+
+#ifdef _UWIN
+ if (!ptw32_selfThreadKey)
+ return nil;
+#endif
+
+ sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
+
+ if (sp != NULL)
+ {
+ self = sp->ptHandle;
+ }
+ else
+ {
+ /*
+ * Need to create an implicit 'self' for the currently
+ * executing thread.
+ */
+ self = ptw32_new ();
+ sp = (ptw32_thread_t *) self.p;
+
+ if (sp != NULL)
+ {
+ /*
+ * This is a non-POSIX thread which has chosen to call
+ * a POSIX threads function for some reason. We assume that
+ * it isn't joinable, but we do assume that it's
+ * (deferred) cancelable.
+ */
+ sp->implicit = 1;
+ sp->detachState = PTHREAD_CREATE_DETACHED;
+ sp->thread = GetCurrentThreadId ();
+
+#ifdef NEED_DUPLICATEHANDLE
+ /*
+ * DuplicateHandle does not exist on WinCE.
+ *
+ * NOTE:
+ * GetCurrentThread only returns a pseudo-handle
+ * which is only valid in the current thread context.
+ * Therefore, you should not pass the handle to
+ * other threads for whatever purpose.
+ */
+ sp->threadH = GetCurrentThread ();
+#else
+ if (!DuplicateHandle (GetCurrentProcess (),
+ GetCurrentThread (),
+ GetCurrentProcess (),
+ &sp->threadH,
+ 0, FALSE, DUPLICATE_SAME_ACCESS))
+ {
+ /*
+ * Should not do this, but we have no alternative if
+ * we can't get a Win32 thread handle.
+ * Thread structs are never freed.
+ */
+ ptw32_threadReusePush (self);
+ return nil;
+ }
+#endif
+
+ /*
+ * No need to explicitly serialise access to sched_priority
+ * because the new handle is not yet public.
+ */
+ sp->sched_priority = GetThreadPriority (sp->threadH);
+
+ pthread_setspecific (ptw32_selfThreadKey, (void *) sp);
+ }
+ }
+
+ return (self);
+
+} /* pthread_self */
diff --git a/pthreads/pthread_setcancelstate.c b/pthreads/pthread_setcancelstate.c
new file mode 100644
index 000000000..002cfe5e4
--- /dev/null
+++ b/pthreads/pthread_setcancelstate.c
@@ -0,0 +1,124 @@
+/*
+ * pthread_setcancelstate.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"
+
+
+int
+pthread_setcancelstate (int state, int *oldstate)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function atomically sets the calling thread's
+ * cancelability state to 'state' and returns the previous
+ * cancelability state at the location referenced by
+ * 'oldstate'
+ *
+ * PARAMETERS
+ * state,
+ * oldstate
+ * PTHREAD_CANCEL_ENABLE
+ * cancellation is enabled,
+ *
+ * PTHREAD_CANCEL_DISABLE
+ * cancellation is disabled
+ *
+ *
+ * DESCRIPTION
+ * This function atomically sets the calling thread's
+ * cancelability state to 'state' and returns the previous
+ * cancelability state at the location referenced by
+ * 'oldstate'.
+ *
+ * NOTES:
+ * 1) Use to disable cancellation around 'atomic' code that
+ * includes cancellation points
+ *
+ * COMPATIBILITY ADDITIONS
+ * If 'oldstate' is NULL then the previous state is not returned
+ * but the function still succeeds. (Solaris)
+ *
+ * RESULTS
+ * 0 successfully set cancelability type,
+ * EINVAL 'state' is invalid
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ pthread_t self = pthread_self ();
+ ptw32_thread_t * sp = (ptw32_thread_t *) self.p;
+
+ if (sp == NULL
+ || (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE))
+ {
+ return EINVAL;
+ }
+
+ /*
+ * Lock for async-cancel safety.
+ */
+ (void) pthread_mutex_lock (&sp->cancelLock);
+
+ if (oldstate != NULL)
+ {
+ *oldstate = sp->cancelState;
+ }
+
+ sp->cancelState = state;
+
+ /*
+ * Check if there is a pending asynchronous cancel
+ */
+ if (state == PTHREAD_CANCEL_ENABLE
+ && sp->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS
+ && WaitForSingleObject (sp->cancelEvent, 0) == WAIT_OBJECT_0)
+ {
+ sp->state = PThreadStateCanceling;
+ sp->cancelState = PTHREAD_CANCEL_DISABLE;
+ ResetEvent (sp->cancelEvent);
+ (void) pthread_mutex_unlock (&sp->cancelLock);
+ ptw32_throw (PTW32_EPS_CANCEL);
+
+ /* Never reached */
+ }
+
+ (void) pthread_mutex_unlock (&sp->cancelLock);
+
+ return (result);
+
+} /* pthread_setcancelstate */
diff --git a/pthreads/pthread_setcanceltype.c b/pthreads/pthread_setcanceltype.c
new file mode 100644
index 000000000..3fb3f0e49
--- /dev/null
+++ b/pthreads/pthread_setcanceltype.c
@@ -0,0 +1,125 @@
+/*
+ * pthread_setcanceltype.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"
+
+
+int
+pthread_setcanceltype (int type, int *oldtype)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function atomically sets the calling thread's
+ * cancelability type to 'type' and returns the previous
+ * cancelability type at the location referenced by
+ * 'oldtype'
+ *
+ * PARAMETERS
+ * type,
+ * oldtype
+ * PTHREAD_CANCEL_DEFERRED
+ * only deferred cancelation is allowed,
+ *
+ * PTHREAD_CANCEL_ASYNCHRONOUS
+ * Asynchronous cancellation is allowed
+ *
+ *
+ * DESCRIPTION
+ * This function atomically sets the calling thread's
+ * cancelability type to 'type' and returns the previous
+ * cancelability type at the location referenced by
+ * 'oldtype'
+ *
+ * NOTES:
+ * 1) Use with caution; most code is not safe for use
+ * with asynchronous cancelability.
+ *
+ * COMPATIBILITY ADDITIONS
+ * If 'oldtype' is NULL then the previous type is not returned
+ * but the function still succeeds. (Solaris)
+ *
+ * RESULTS
+ * 0 successfully set cancelability type,
+ * EINVAL 'type' is invalid
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ pthread_t self = pthread_self ();
+ ptw32_thread_t * sp = (ptw32_thread_t *) self.p;
+
+ if (sp == NULL
+ || (type != PTHREAD_CANCEL_DEFERRED
+ && type != PTHREAD_CANCEL_ASYNCHRONOUS))
+ {
+ return EINVAL;
+ }
+
+ /*
+ * Lock for async-cancel safety.
+ */
+ (void) pthread_mutex_lock (&sp->cancelLock);
+
+ if (oldtype != NULL)
+ {
+ *oldtype = sp->cancelType;
+ }
+
+ sp->cancelType = type;
+
+ /*
+ * Check if there is a pending asynchronous cancel
+ */
+ if (sp->cancelState == PTHREAD_CANCEL_ENABLE
+ && type == PTHREAD_CANCEL_ASYNCHRONOUS
+ && WaitForSingleObject (sp->cancelEvent, 0) == WAIT_OBJECT_0)
+ {
+ sp->state = PThreadStateCanceling;
+ sp->cancelState = PTHREAD_CANCEL_DISABLE;
+ ResetEvent (sp->cancelEvent);
+ (void) pthread_mutex_unlock (&sp->cancelLock);
+ ptw32_throw (PTW32_EPS_CANCEL);
+
+ /* Never reached */
+ }
+
+ (void) pthread_mutex_unlock (&sp->cancelLock);
+
+ return (result);
+
+} /* pthread_setcanceltype */
diff --git a/pthreads/pthread_setconcurrency.c b/pthreads/pthread_setconcurrency.c
new file mode 100644
index 000000000..f62346f8e
--- /dev/null
+++ b/pthreads/pthread_setconcurrency.c
@@ -0,0 +1,53 @@
+/*
+ * pthread_setconcurrency.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_setconcurrency (int level)
+{
+ if (level < 0)
+ {
+ return EINVAL;
+ }
+ else
+ {
+ ptw32_concurrency = level;
+ return 0;
+ }
+}
diff --git a/pthreads/pthread_setschedparam.c b/pthreads/pthread_setschedparam.c
new file mode 100644
index 000000000..a122eaca6
--- /dev/null
+++ b/pthreads/pthread_setschedparam.c
@@ -0,0 +1,125 @@
+/*
+ * sched_setschedparam.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+int
+pthread_setschedparam (pthread_t thread, int policy,
+ const struct sched_param *param)
+{
+ int result;
+
+ /* Validate the thread id. */
+ result = pthread_kill (thread, 0);
+ if (0 != result)
+ {
+ return result;
+ }
+
+ /* Validate the scheduling policy. */
+ if (policy < SCHED_MIN || policy > SCHED_MAX)
+ {
+ return EINVAL;
+ }
+
+ /* Ensure the policy is SCHED_OTHER. */
+ if (policy != SCHED_OTHER)
+ {
+ return ENOTSUP;
+ }
+
+ return (ptw32_setthreadpriority (thread, policy, param->sched_priority));
+}
+
+
+int
+ptw32_setthreadpriority (pthread_t thread, int policy, int priority)
+{
+ int prio;
+ int result;
+ ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
+
+ prio = priority;
+
+ /* Validate priority level. */
+ if (prio < sched_get_priority_min (policy) ||
+ prio > sched_get_priority_max (policy))
+ {
+ return EINVAL;
+ }
+
+#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
+/* WinCE */
+#else
+/* Everything else */
+
+ if (THREAD_PRIORITY_IDLE < prio && THREAD_PRIORITY_LOWEST > prio)
+ {
+ prio = THREAD_PRIORITY_LOWEST;
+ }
+ else if (THREAD_PRIORITY_TIME_CRITICAL > prio
+ && THREAD_PRIORITY_HIGHEST < prio)
+ {
+ prio = THREAD_PRIORITY_HIGHEST;
+ }
+
+#endif
+
+ result = pthread_mutex_lock (&tp->threadLock);
+
+ if (0 == result)
+ {
+ /* 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);
+ }
+
+ return result;
+}
diff --git a/pthreads/pthread_setspecific.c b/pthreads/pthread_setspecific.c
new file mode 100644
index 000000000..f06b69616
--- /dev/null
+++ b/pthreads/pthread_setspecific.c
@@ -0,0 +1,168 @@
+/*
+ * 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 */
diff --git a/pthreads/pthread_spin_destroy.c b/pthreads/pthread_spin_destroy.c
new file mode 100644
index 000000000..8fe22674d
--- /dev/null
+++ b/pthreads/pthread_spin_destroy.c
@@ -0,0 +1,112 @@
+/*
+ * pthread_spin_destroy.c
+ *
+ * Description:
+ * This translation unit implements spin 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 "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_spin_destroy (pthread_spinlock_t * lock)
+{
+ register pthread_spinlock_t s;
+ int result = 0;
+
+ if (lock == NULL || *lock == NULL)
+ {
+ return EINVAL;
+ }
+
+ if ((s = *lock) != PTHREAD_SPINLOCK_INITIALIZER)
+ {
+ if (s->interlock == PTW32_SPIN_USE_MUTEX)
+ {
+ 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))
+ {
+ result = EINVAL;
+ }
+
+ if (0 == result)
+ {
+ /*
+ * We are relying on the application to ensure that all other threads
+ * have finished with the spinlock before destroying it.
+ */
+ *lock = NULL;
+ (void) free (s);
+ }
+ }
+ else
+ {
+ /*
+ * See notes in ptw32_spinlock_check_need_init() above also.
+ */
+ EnterCriticalSection (&ptw32_spinlock_test_init_lock);
+
+ /*
+ * Check again.
+ */
+ if (*lock == PTHREAD_SPINLOCK_INITIALIZER)
+ {
+ /*
+ * This is all we need to do to destroy a statically
+ * initialised spinlock that has not yet been used (initialised).
+ * If we get to here, another thread
+ * waiting to initialise this mutex will get an EINVAL.
+ */
+ *lock = NULL;
+ }
+ else
+ {
+ /*
+ * The spinlock has been initialised while we were waiting
+ * so assume it's in use.
+ */
+ result = EBUSY;
+ }
+
+ LeaveCriticalSection (&ptw32_spinlock_test_init_lock);
+ }
+
+ return (result);
+}
diff --git a/pthreads/pthread_spin_init.c b/pthreads/pthread_spin_init.c
new file mode 100644
index 000000000..553af7eac
--- /dev/null
+++ b/pthreads/pthread_spin_init.c
@@ -0,0 +1,123 @@
+/*
+ * pthread_spin_init.c
+ *
+ * Description:
+ * This translation unit implements spin 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 "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_spin_init (pthread_spinlock_t * lock, int pshared)
+{
+ pthread_spinlock_t s;
+ int cpus = 0;
+ int result = 0;
+
+ if (lock == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (0 != ptw32_getprocessors (&cpus))
+ {
+ cpus = 1;
+ }
+
+ if (cpus > 1)
+ {
+ if (pshared == PTHREAD_PROCESS_SHARED)
+ {
+ /*
+ * Creating spinlock that can be shared between
+ * processes.
+ */
+#if _POSIX_THREAD_PROCESS_SHARED >= 0
+
+ /*
+ * Not implemented yet.
+ */
+
+#error ERROR [__FILE__, line __LINE__]: Process shared spin locks are not supported yet.
+
+#else
+
+ return ENOSYS;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+
+ }
+ }
+
+ s = (pthread_spinlock_t) calloc (1, sizeof (*s));
+
+ if (s == NULL)
+ {
+ return ENOMEM;
+ }
+
+ if (cpus > 1)
+ {
+ s->u.cpus = cpus;
+ s->interlock = PTW32_SPIN_UNLOCKED;
+ }
+ else
+ {
+ pthread_mutexattr_t ma;
+ result = pthread_mutexattr_init (&ma);
+
+ if (0 == result)
+ {
+ ma->pshared = pshared;
+ result = pthread_mutex_init (&(s->u.mutex), &ma);
+ if (0 == result)
+ {
+ s->interlock = PTW32_SPIN_USE_MUTEX;
+ }
+ }
+ (void) pthread_mutexattr_destroy (&ma);
+ }
+
+ if (0 == result)
+ {
+ *lock = s;
+ }
+ else
+ {
+ (void) free (s);
+ *lock = NULL;
+ }
+
+ return (result);
+}
diff --git a/pthreads/pthread_spin_lock.c b/pthreads/pthread_spin_lock.c
new file mode 100644
index 000000000..90b3abee4
--- /dev/null
+++ b/pthreads/pthread_spin_lock.c
@@ -0,0 +1,83 @@
+/*
+ * pthread_spin_lock.c
+ *
+ * Description:
+ * This translation unit implements spin 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 "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_spin_lock (pthread_spinlock_t * lock)
+{
+ register pthread_spinlock_t s;
+
+ if (NULL == lock || NULL == *lock)
+ {
+ return (EINVAL);
+ }
+
+ if (*lock == PTHREAD_SPINLOCK_INITIALIZER)
+ {
+ int result;
+
+ if ((result = ptw32_spinlock_check_need_init (lock)) != 0)
+ {
+ return (result);
+ }
+ }
+
+ 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))
+ {
+ }
+
+ if (s->interlock == PTW32_SPIN_LOCKED)
+ {
+ return 0;
+ }
+ else if (s->interlock == PTW32_SPIN_USE_MUTEX)
+ {
+ return pthread_mutex_lock (&(s->u.mutex));
+ }
+
+ return EINVAL;
+}
diff --git a/pthreads/pthread_spin_trylock.c b/pthreads/pthread_spin_trylock.c
new file mode 100644
index 000000000..c601a191f
--- /dev/null
+++ b/pthreads/pthread_spin_trylock.c
@@ -0,0 +1,80 @@
+/*
+ * pthread_spin_trylock.c
+ *
+ * Description:
+ * This translation unit implements spin 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 "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_spin_trylock (pthread_spinlock_t * lock)
+{
+ register pthread_spinlock_t s;
+
+ if (NULL == lock || NULL == *lock)
+ {
+ return (EINVAL);
+ }
+
+ if (*lock == PTHREAD_SPINLOCK_INITIALIZER)
+ {
+ int result;
+
+ if ((result = ptw32_spinlock_check_need_init (lock)) != 0)
+ {
+ return (result);
+ }
+ }
+
+ 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))
+ {
+ case PTW32_SPIN_UNLOCKED:
+ return 0;
+ case PTW32_SPIN_LOCKED:
+ return EBUSY;
+ case PTW32_SPIN_USE_MUTEX:
+ return pthread_mutex_trylock (&(s->u.mutex));
+ }
+
+ return EINVAL;
+}
diff --git a/pthreads/pthread_spin_unlock.c b/pthreads/pthread_spin_unlock.c
new file mode 100644
index 000000000..67bc2c218
--- /dev/null
+++ b/pthreads/pthread_spin_unlock.c
@@ -0,0 +1,75 @@
+/*
+ * pthread_spin_unlock.c
+ *
+ * Description:
+ * This translation unit implements spin 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 "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_spin_unlock (pthread_spinlock_t * lock)
+{
+ register pthread_spinlock_t s;
+
+ if (NULL == lock || NULL == *lock)
+ {
+ return (EINVAL);
+ }
+
+ s = *lock;
+
+ if (s == PTHREAD_SPINLOCK_INITIALIZER)
+ {
+ return EPERM;
+ }
+
+ switch ((long)
+ PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG) &
+ (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;
+ case PTW32_SPIN_USE_MUTEX:
+ return pthread_mutex_unlock (&(s->u.mutex));
+ }
+
+ return EINVAL;
+}
diff --git a/pthreads/pthread_testcancel.c b/pthreads/pthread_testcancel.c
new file mode 100644
index 000000000..ad7cdb994
--- /dev/null
+++ b/pthreads/pthread_testcancel.c
@@ -0,0 +1,102 @@
+/*
+ * 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;
+ (void) pthread_mutex_unlock (&sp->cancelLock);
+ sp->cancelState = PTHREAD_CANCEL_DISABLE;
+ (void) pthread_mutex_unlock (&sp->cancelLock);
+ ptw32_throw (PTW32_EPS_CANCEL);
+ }
+
+ (void) pthread_mutex_unlock (&sp->cancelLock);
+} /* pthread_testcancel */
diff --git a/pthreads/pthread_timechange_handler_np.c b/pthreads/pthread_timechange_handler_np.c
new file mode 100644
index 000000000..7d8170a3f
--- /dev/null
+++ b/pthreads/pthread_timechange_handler_np.c
@@ -0,0 +1,107 @@
+/*
+ * pthread_timechange_handler_np.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"
+
+/*
+ * Notes on handling system time adjustments (especially negative ones).
+ * ---------------------------------------------------------------------
+ *
+ * This solution was suggested by Alexander Terekhov, but any errors
+ * in the implementation are mine - [Ross Johnson]
+ *
+ * 1) The problem: threads doing a timedwait on a CV may expect to timeout
+ * at a specific absolute time according to a system timer. If the
+ * system clock is adjusted backwards then those threads sleep longer than
+ * expected. Also, pthreads-win32 converts absolute times to intervals in
+ * order to make use of the underlying Win32, and so waiting threads may
+ * awake before their proper abstimes.
+ *
+ * 2) We aren't able to distinquish between threads on timed or untimed waits,
+ * so we wake them all at the time of the adjustment so that they can
+ * re-evaluate their conditions and re-compute their timeouts.
+ *
+ * 3) We rely on correctly written applications for this to work. Specifically,
+ * they must be able to deal properly with spurious wakeups. That is,
+ * they must re-test their condition upon wakeup and wait again if
+ * the condition is not satisfied.
+ */
+
+void *
+pthread_timechange_handler_np (void *arg)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * Broadcasts all CVs to force re-evaluation and
+ * new timeouts if required.
+ *
+ * PARAMETERS
+ * NONE
+ *
+ *
+ * DESCRIPTION
+ * Broadcasts all CVs to force re-evaluation and
+ * new timeouts if required.
+ *
+ * This routine may be passed directly to pthread_create()
+ * as a new thread in order to run asynchronously.
+ *
+ *
+ * RESULTS
+ * 0 successfully broadcast all CVs
+ * EAGAIN Not all CVs were broadcast
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ pthread_cond_t cv;
+
+ EnterCriticalSection (&ptw32_cond_list_lock);
+
+ cv = ptw32_cond_list_head;
+
+ while (cv != NULL && 0 == result)
+ {
+ result = pthread_cond_broadcast (&cv);
+ cv = cv->next;
+ }
+
+ LeaveCriticalSection (&ptw32_cond_list_lock);
+
+ return (void *) (result != 0 ? EAGAIN : 0);
+}
diff --git a/pthreads/pthread_win32_attach_detach_np.c b/pthreads/pthread_win32_attach_detach_np.c
new file mode 100644
index 000000000..2f0bc373a
--- /dev/null
+++ b/pthreads/pthread_win32_attach_detach_np.c
@@ -0,0 +1,303 @@
+/*
+ * 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 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;
+ }
+
+ /*
+ * 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);
+}
diff --git a/pthreads/ptw32_InterlockedCompareExchange.c b/pthreads/ptw32_InterlockedCompareExchange.c
new file mode 100644
index 000000000..0094635f6
--- /dev/null
+++ b/pthreads/ptw32_InterlockedCompareExchange.c
@@ -0,0 +1,303 @@
+/*
+ * 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
+ */
+
+#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.
+ */
+
+ result = 0;
+
+#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(), which is much faster than
+ * using the an inlined 'xchg' instruction, so it's 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.
+ */
+
+ result = 0;
+
+#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
diff --git a/pthreads/ptw32_MCS_lock.c b/pthreads/ptw32_MCS_lock.c
new file mode 100644
index 000000000..1a143ea14
--- /dev/null
+++ b/pthreads/ptw32_MCS_lock.c
@@ -0,0 +1,210 @@
+/*
+ * 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((LPLONG)lock,
+ (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, 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);
+}
diff --git a/pthreads/ptw32_callUserDestroyRoutines.c b/pthreads/ptw32_callUserDestroyRoutines.c
new file mode 100644
index 000000000..a583f188d
--- /dev/null
+++ b/pthreads/ptw32_callUserDestroyRoutines.c
@@ -0,0 +1,220 @@
+/*
+ * ptw32_callUserDestroyRoutines.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"
+
+#ifdef __cplusplus
+# if ! defined (_MSC_VER) && ! (defined(__GNUC__) && __GNUC__ < 3) && ! defined(__WATCOMC__)
+using
+ std::terminate;
+# endif
+#endif
+
+void
+ptw32_callUserDestroyRoutines (pthread_t thread)
+ /*
+ * -------------------------------------------------------------------
+ * DOCPRIVATE
+ *
+ * This the routine runs through all thread keys and calls
+ * the destroy routines on the user's data for the current thread.
+ * It simulates the behaviour of POSIX Threads.
+ *
+ * PARAMETERS
+ * thread
+ * an instance of pthread_t
+ *
+ * RETURNS
+ * N/A
+ * -------------------------------------------------------------------
+ */
+{
+ ThreadKeyAssoc * assoc;
+
+ if (thread.p != NULL)
+ {
+ int assocsRemaining;
+ int iterations = 0;
+ ptw32_thread_t * sp = (ptw32_thread_t *) thread.p;
+
+ /*
+ * Run through all Thread<-->Key associations
+ * for the current thread.
+ *
+ * Do this process at most PTHREAD_DESTRUCTOR_ITERATIONS times.
+ */
+ do
+ {
+ assocsRemaining = 0;
+ iterations++;
+
+ (void) pthread_mutex_lock(&(sp->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
+ * if it deletes this assoc. This can happen if we fail to acquire
+ * both locks below, and are forced to release all of our locks,
+ * leaving open the opportunity for pthread_key_delete to get in
+ * before us.
+ */
+ sp->nextAssoc = sp->keys;
+ (void) pthread_mutex_unlock(&(sp->threadLock));
+
+ for (;;)
+ {
+ void * value;
+ pthread_key_t k;
+ void (*destructor) (void *);
+
+ /*
+ * First we need to serialise with pthread_key_delete by locking
+ * 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));
+
+ if ((assoc = (ThreadKeyAssoc *)sp->nextAssoc) == NULL)
+ {
+ /* Finished */
+ pthread_mutex_unlock(&(sp->threadLock));
+ break;
+ }
+ else
+ {
+ /*
+ * assoc->key must be valid because assoc can't change or be
+ * removed from our chain while we hold at least one lock. If
+ * the assoc was on our key chain then the key has not been
+ * deleted yet.
+ *
+ * Now try to acquire the second lock without deadlocking.
+ * 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)
+ {
+ pthread_mutex_unlock(&(sp->threadLock));
+ Sleep(1); // Ugly but necessary to avoid priority effects.
+ /*
+ * Go around again.
+ * If pthread_key_delete has removed this assoc in the meantime,
+ * sp->nextAssoc will point to a new assoc.
+ */
+ continue;
+ }
+ }
+
+ /* We now hold both locks */
+
+ sp->nextAssoc = assoc->nextKey;
+
+ /*
+ * Key still active; pthread_key_delete
+ * will block on these same mutexes before
+ * it can release actual key; therefore,
+ * key is valid and we can call the destroy
+ * routine;
+ */
+ k = assoc->key;
+ destructor = k->destructor;
+ value = TlsGetValue(k->key);
+ TlsSetValue (k->key, NULL);
+
+ // Every assoc->key exists and has a destructor
+ if (value != NULL && iterations <= PTHREAD_DESTRUCTOR_ITERATIONS)
+ {
+ /*
+ * Unlock both locks before the destructor runs.
+ * POSIX says pthread_key_delete can be run from destructors,
+ * and that probably includes with this key as target.
+ * 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));
+
+ assocsRemaining++;
+
+#ifdef __cplusplus
+
+ try
+ {
+ /*
+ * Run the caller's cleanup routine.
+ */
+ destructor (value);
+ }
+ catch (...)
+ {
+ /*
+ * A system unexpected exception has occurred
+ * running the user's destructor.
+ * We get control back within this block in case
+ * the application has set up it's own terminate
+ * handler. Since we are leaving the thread we
+ * should not get any internal pthreads
+ * exceptions.
+ */
+ terminate ();
+ }
+
+#else /* __cplusplus */
+
+ /*
+ * Run the caller's cleanup routine.
+ */
+ destructor (value);
+
+#endif /* __cplusplus */
+
+ }
+ else
+ {
+ /*
+ * Remove association from both the key and thread chains
+ * and reclaim it's memory resources.
+ */
+ ptw32_tkAssocDestroy (assoc);
+ (void) pthread_mutex_unlock(&(sp->threadLock));
+ (void) pthread_mutex_unlock(&(k->keyLock));
+ }
+ }
+ }
+ while (assocsRemaining);
+ }
+} /* ptw32_callUserDestroyRoutines */
diff --git a/pthreads/ptw32_calloc.c b/pthreads/ptw32_calloc.c
new file mode 100644
index 000000000..eea7c7482
--- /dev/null
+++ b/pthreads/ptw32_calloc.c
@@ -0,0 +1,56 @@
+/*
+ * ptw32_calloc.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"
+
+
+#ifdef NEED_CALLOC
+void *
+ptw32_calloc (size_t n, size_t s)
+{
+ unsigned int m = n * s;
+ void *p;
+
+ p = malloc (m);
+ if (p == NULL)
+ return NULL;
+
+ memset (p, 0, m);
+
+ return p;
+}
+#endif
diff --git a/pthreads/ptw32_cond_check_need_init.c b/pthreads/ptw32_cond_check_need_init.c
new file mode 100644
index 000000000..31359ad3f
--- /dev/null
+++ b/pthreads/ptw32_cond_check_need_init.c
@@ -0,0 +1,94 @@
+/*
+ * ptw32_cond_check_need_init.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"
+
+
+INLINE int
+ptw32_cond_check_need_init (pthread_cond_t * cond)
+{
+ int result = 0;
+
+ /*
+ * 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);
+
+ /*
+ * We got here possibly under race
+ * conditions. Check again inside the critical section.
+ * If a static cv has been destroyed, the application can
+ * re-initialise it only by calling pthread_cond_init()
+ * explicitly.
+ */
+ if (*cond == PTHREAD_COND_INITIALIZER)
+ {
+ result = pthread_cond_init (cond, NULL);
+ }
+ else if (*cond == NULL)
+ {
+ /*
+ * The cv has been destroyed while we were waiting to
+ * initialise it, so the operation that caused the
+ * auto-initialisation should fail.
+ */
+ result = EINVAL;
+ }
+
+ LeaveCriticalSection (&ptw32_cond_test_init_lock);
+
+ return result;
+}
diff --git a/pthreads/ptw32_getprocessors.c b/pthreads/ptw32_getprocessors.c
new file mode 100644
index 000000000..e60c3143f
--- /dev/null
+++ b/pthreads/ptw32_getprocessors.c
@@ -0,0 +1,91 @@
+/*
+ * ptw32_getprocessors.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_getprocessors()
+ *
+ * Get the number of CPUs available to the process.
+ *
+ * If the available number of CPUs is 1 then pthread_spin_lock()
+ * will block rather than spin if the lock is already owned.
+ *
+ * pthread_spin_init() calls this routine when initialising
+ * a spinlock. If the number of available processors changes
+ * (after a call to SetProcessAffinityMask()) then only
+ * newly initialised spinlocks will notice.
+ */
+int
+ptw32_getprocessors (int *count)
+{
+ DWORD_PTR vProcessCPUs;
+ DWORD_PTR vSystemCPUs;
+ int result = 0;
+
+#if defined(NEED_PROCESS_AFFINITY_MASK)
+
+ *count = 1;
+
+#else
+
+ if (GetProcessAffinityMask (GetCurrentProcess (),
+ &vProcessCPUs, &vSystemCPUs))
+ {
+ DWORD_PTR bit;
+ int CPUs = 0;
+
+ for (bit = 1; bit != 0; bit <<= 1)
+ {
+ if (vProcessCPUs & bit)
+ {
+ CPUs++;
+ }
+ }
+ *count = CPUs;
+ }
+ else
+ {
+ result = EAGAIN;
+ }
+
+#endif
+
+ return (result);
+}
diff --git a/pthreads/ptw32_is_attr.c b/pthreads/ptw32_is_attr.c
new file mode 100644
index 000000000..36395f81f
--- /dev/null
+++ b/pthreads/ptw32_is_attr.c
@@ -0,0 +1,47 @@
+/*
+ * ptw32_is_attr.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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
+ptw32_is_attr (const pthread_attr_t * attr)
+{
+ /* Return 0 if the attr object is valid, non-zero otherwise. */
+
+ return (attr == NULL ||
+ *attr == NULL || (*attr)->valid != PTW32_ATTR_VALID);
+}
diff --git a/pthreads/ptw32_mutex_check_need_init.c b/pthreads/ptw32_mutex_check_need_init.c
new file mode 100644
index 000000000..35ec366bd
--- /dev/null
+++ b/pthreads/ptw32_mutex_check_need_init.c
@@ -0,0 +1,112 @@
+/*
+ * ptw32_mutex_check_need_init.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+static struct pthread_mutexattr_t_ ptw32_recursive_mutexattr_s =
+ {PTHREAD_PROCESS_PRIVATE, PTHREAD_MUTEX_RECURSIVE};
+static struct pthread_mutexattr_t_ ptw32_errorcheck_mutexattr_s =
+ {PTHREAD_PROCESS_PRIVATE, PTHREAD_MUTEX_ERRORCHECK};
+static pthread_mutexattr_t ptw32_recursive_mutexattr = &ptw32_recursive_mutexattr_s;
+static pthread_mutexattr_t ptw32_errorcheck_mutexattr = &ptw32_errorcheck_mutexattr_s;
+
+
+INLINE int
+ptw32_mutex_check_need_init (pthread_mutex_t * mutex)
+{
+ register int result = 0;
+ register pthread_mutex_t mtx;
+
+ /*
+ * 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);
+
+ /*
+ * We got here possibly under race
+ * conditions. Check again inside the critical section
+ * and only initialise if the mutex is valid (not been destroyed).
+ * If a static mutex has been destroyed, the application can
+ * re-initialise it only by calling pthread_mutex_init()
+ * explicitly.
+ */
+ mtx = *mutex;
+
+ if (mtx == PTHREAD_MUTEX_INITIALIZER)
+ {
+ result = pthread_mutex_init (mutex, NULL);
+ }
+ else if (mtx == PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
+ {
+ result = pthread_mutex_init (mutex, &ptw32_recursive_mutexattr);
+ }
+ else if (mtx == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+ {
+ result = pthread_mutex_init (mutex, &ptw32_errorcheck_mutexattr);
+ }
+ else if (mtx == NULL)
+ {
+ /*
+ * The mutex has been destroyed while we were waiting to
+ * initialise it, so the operation that caused the
+ * auto-initialisation should fail.
+ */
+ result = EINVAL;
+ }
+
+ LeaveCriticalSection (&ptw32_mutex_test_init_lock);
+
+ return (result);
+}
diff --git a/pthreads/ptw32_new.c b/pthreads/ptw32_new.c
new file mode 100644
index 000000000..281256741
--- /dev/null
+++ b/pthreads/ptw32_new.c
@@ -0,0 +1,91 @@
+/*
+ * ptw32_new.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"
+
+
+pthread_t
+ptw32_new (void)
+{
+ pthread_t t;
+ pthread_t nil = {NULL, 0};
+ ptw32_thread_t * tp;
+
+ /*
+ * If there's a reusable pthread_t then use it.
+ */
+ t = ptw32_threadReusePop ();
+
+ if (NULL != t.p)
+ {
+ tp = (ptw32_thread_t *) t.p;
+ }
+ else
+ {
+ /* No reuse threads available */
+ tp = (ptw32_thread_t *) calloc (1, sizeof(ptw32_thread_t));
+
+ if (tp == NULL)
+ {
+ return nil;
+ }
+
+ /* ptHandle.p needs to point to it's parent ptw32_thread_t. */
+ t.p = tp->ptHandle.p = tp;
+ t.x = tp->ptHandle.x = 0;
+ }
+
+ /* Set default state. */
+ 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->cancelEvent = CreateEvent (0, (int) PTW32_TRUE, /* manualReset */
+ (int) PTW32_FALSE, /* setSignaled */
+ NULL);
+
+ if (tp->cancelEvent == NULL)
+ {
+ ptw32_threadReusePush (tp->ptHandle);
+ return nil;
+ }
+
+ return t;
+
+}
diff --git a/pthreads/ptw32_processInitialize.c b/pthreads/ptw32_processInitialize.c
new file mode 100644
index 000000000..d13b0226f
--- /dev/null
+++ b/pthreads/ptw32_processInitialize.c
@@ -0,0 +1,102 @@
+/*
+ * ptw32_processInitialize.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"
+
+
+int
+ptw32_processInitialize (void)
+ /*
+ * ------------------------------------------------------
+ * DOCPRIVATE
+ * This function performs process wide initialization for
+ * the pthread library.
+ *
+ * PARAMETERS
+ * N/A
+ *
+ * DESCRIPTION
+ * This function performs process wide initialization for
+ * the pthread library.
+ * If successful, this routine sets the global variable
+ * ptw32_processInitialized to TRUE.
+ *
+ * RESULTS
+ * TRUE if successful,
+ * FALSE otherwise
+ *
+ * ------------------------------------------------------
+ */
+{
+ if (ptw32_processInitialized)
+ {
+ /*
+ * Ignore if already initialized. this is useful for
+ * programs that uses a non-dll pthread
+ * library. Such programs must call ptw32_processInitialize() explicitly,
+ * since this initialization routine is automatically called only when
+ * the dll is loaded.
+ */
+ return PTW32_TRUE;
+ }
+
+ ptw32_processInitialized = PTW32_TRUE;
+
+ /*
+ * Initialize Keys
+ */
+ if ((pthread_key_create (&ptw32_selfThreadKey, NULL) != 0) ||
+ (pthread_key_create (&ptw32_cleanupKey, NULL) != 0))
+ {
+
+ 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
new file mode 100644
index 000000000..d2dfa7a24
--- /dev/null
+++ b/pthreads/ptw32_processTerminate.c
@@ -0,0 +1,114 @@
+/*
+ * ptw32_processTerminate.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"
+
+
+void
+ptw32_processTerminate (void)
+ /*
+ * ------------------------------------------------------
+ * DOCPRIVATE
+ * This function performs process wide termination for
+ * the pthread library.
+ *
+ * PARAMETERS
+ * N/A
+ *
+ * DESCRIPTION
+ * This function performs process wide termination for
+ * the pthread library.
+ * This routine sets the global variable
+ * ptw32_processInitialized to FALSE
+ *
+ * RESULTS
+ * N/A
+ *
+ * ------------------------------------------------------
+ */
+{
+ if (ptw32_processInitialized)
+ {
+ ptw32_thread_t * tp, * tpNext;
+
+ if (ptw32_selfThreadKey != NULL)
+ {
+ /*
+ * Release ptw32_selfThreadKey
+ */
+ pthread_key_delete (ptw32_selfThreadKey);
+
+ ptw32_selfThreadKey = NULL;
+ }
+
+ if (ptw32_cleanupKey != NULL)
+ {
+ /*
+ * Release ptw32_cleanupKey
+ */
+ pthread_key_delete (ptw32_cleanupKey);
+
+ ptw32_cleanupKey = NULL;
+ }
+
+ EnterCriticalSection (&ptw32_thread_reuse_lock);
+
+ tp = ptw32_threadReuseTop;
+ while (tp != PTW32_THREAD_REUSE_EMPTY)
+ {
+ tpNext = tp->prevReuse;
+ free (tp);
+ 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_processInitialized = PTW32_FALSE;
+ }
+
+} /* processTerminate */
diff --git a/pthreads/ptw32_relmillisecs.c b/pthreads/ptw32_relmillisecs.c
new file mode 100644
index 000000000..f3e7b769f
--- /dev/null
+++ b/pthreads/ptw32_relmillisecs.c
@@ -0,0 +1,120 @@
+/*
+ * ptw32_relmillisecs.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef _UWIN
+//#include <process.h>
+#endif
+#include "pthread.h"
+#include "implement.h"
+#ifndef NEED_FTIME
+#include <sys/timeb.h>
+#endif
+
+
+INLINE DWORD
+ptw32_relmillisecs (const struct timespec * abstime)
+{
+ const int64_t NANOSEC_PER_MILLISEC = 1000000;
+ const int64_t MILLISEC_PER_SEC = 1000;
+ DWORD milliseconds;
+ int64_t tmpAbsMilliseconds;
+ int64_t tmpCurrMilliseconds;
+#ifdef NEED_FTIME
+ struct timespec currSysTime;
+ FILETIME ft;
+ SYSTEMTIME st;
+#else /* ! NEED_FTIME */
+ struct _timeb currSysTime;
+#endif /* NEED_FTIME */
+
+
+ /*
+ * Calculate timeout as milliseconds from current system time.
+ */
+
+ /*
+ * subtract current system time from abstime in a way that checks
+ * that abstime is never in the past, or is never equivalent to the
+ * defined INFINITE value (0xFFFFFFFF).
+ *
+ * Assume all integers are unsigned, i.e. cannot test if less than 0.
+ */
+ tmpAbsMilliseconds = (int64_t)abstime->tv_sec * MILLISEC_PER_SEC;
+ tmpAbsMilliseconds += ((int64_t)abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC;
+
+ /* get current system time */
+
+#ifdef NEED_FTIME
+
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &ft);
+ /*
+ * GetSystemTimeAsFileTime(&ft); would be faster,
+ * but it does not exist on WinCE
+ */
+
+ ptw32_filetime_to_timespec(&ft, &currSysTime);
+
+ tmpCurrMilliseconds = (int64_t)currSysTime.tv_sec * MILLISEC_PER_SEC;
+ tmpCurrMilliseconds += ((int64_t)currSysTime.tv_nsec + (NANOSEC_PER_MILLISEC/2))
+ / NANOSEC_PER_MILLISEC;
+
+#else /* ! NEED_FTIME */
+
+ _ftime(&currSysTime);
+
+ tmpCurrMilliseconds = (int64_t) currSysTime.time * MILLISEC_PER_SEC;
+ tmpCurrMilliseconds += (int64_t) currSysTime.millitm;
+
+#endif /* NEED_FTIME */
+
+ if (tmpAbsMilliseconds > tmpCurrMilliseconds)
+ {
+ milliseconds = (DWORD) (tmpAbsMilliseconds - tmpCurrMilliseconds);
+ if (milliseconds == INFINITE)
+ {
+ /* Timeouts must be finite */
+ milliseconds--;
+ }
+ }
+ else
+ {
+ /* The abstime given is in the past */
+ milliseconds = 0;
+ }
+
+ return milliseconds;
+}
diff --git a/pthreads/ptw32_reuse.c b/pthreads/ptw32_reuse.c
new file mode 100644
index 000000000..0e8698496
--- /dev/null
+++ b/pthreads/ptw32_reuse.c
@@ -0,0 +1,147 @@
+/*
+ * ptw32_threadReuse.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"
+
+
+/*
+ * How it works:
+ * A pthread_t is a struct (2x32 bit scalar types on IA-32, 2x64 bit on IA-64)
+ * which is normally passed/returned by value to/from pthreads routines.
+ * Applications are therefore storing a copy of the struct as it is at that
+ * time.
+ *
+ * The original pthread_t struct plus all copies of it contain the address of
+ * the thread state struct ptw32_thread_t_ (p), plus a reuse counter (x). Each
+ * ptw32_thread_t contains the original copy of it's pthread_t.
+ * Once malloced, a ptw32_thread_t_ struct is not freed until the process exits.
+ *
+ * The thread reuse stack is a simple LILO stack managed through a singly
+ * linked list element in the ptw32_thread_t.
+ *
+ * Each time a thread is destroyed, the ptw32_thread_t address is pushed onto the
+ * reuse stack after it's ptHandle's reuse counter has been incremented.
+ *
+ * The following can now be said from this:
+ * - two pthread_t's are identical if their ptw32_thread_t reference pointers
+ * are equal and their reuse counters are equal. That is,
+ *
+ * equal = (a.p == b.p && a.x == b.x)
+ *
+ * - a pthread_t copy refers to a destroyed thread if the reuse counter in
+ * the copy is not equal to the reuse counter in the original.
+ *
+ * threadDestroyed = (copy.x != ((ptw32_thread_t *)copy.p)->ptHandle.x)
+ *
+ */
+
+/*
+ * Pop a clean pthread_t struct off the reuse stack.
+ */
+pthread_t
+ptw32_threadReusePop (void)
+{
+ pthread_t t = {NULL, 0};
+
+ EnterCriticalSection (&ptw32_thread_reuse_lock);
+
+ if (PTW32_THREAD_REUSE_EMPTY != ptw32_threadReuseTop)
+ {
+ ptw32_thread_t * tp;
+
+ tp = ptw32_threadReuseTop;
+
+ ptw32_threadReuseTop = tp->prevReuse;
+
+ if (PTW32_THREAD_REUSE_EMPTY == ptw32_threadReuseTop)
+ {
+ ptw32_threadReuseBottom = PTW32_THREAD_REUSE_EMPTY;
+ }
+
+ tp->prevReuse = NULL;
+
+ t = tp->ptHandle;
+ }
+
+ LeaveCriticalSection (&ptw32_thread_reuse_lock);
+
+ return t;
+
+}
+
+/*
+ * Push a clean pthread_t struct onto the reuse stack.
+ * Must be re-initialised when reused.
+ * All object elements (mutexes, events etc) must have been either
+ * detroyed before this, or never initialised.
+ */
+void
+ptw32_threadReusePush (pthread_t thread)
+{
+ ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
+ pthread_t t;
+
+ EnterCriticalSection (&ptw32_thread_reuse_lock);
+
+ t = tp->ptHandle;
+ memset(tp, 0, sizeof(ptw32_thread_t));
+
+ /* Must restore the original POSIX handle that we just wiped. */
+ tp->ptHandle = t;
+
+ /* Bump the reuse counter now */
+#ifdef PTW32_THREAD_ID_REUSE_INCREMENT
+ tp->ptHandle.x += PTW32_THREAD_ID_REUSE_INCREMENT;
+#else
+ tp->ptHandle.x++;
+#endif
+
+ tp->prevReuse = PTW32_THREAD_REUSE_EMPTY;
+
+ if (PTW32_THREAD_REUSE_EMPTY != ptw32_threadReuseBottom)
+ {
+ ptw32_threadReuseBottom->prevReuse = tp;
+ }
+ else
+ {
+ ptw32_threadReuseTop = tp;
+ }
+
+ ptw32_threadReuseBottom = tp;
+
+ LeaveCriticalSection (&ptw32_thread_reuse_lock);
+}
diff --git a/pthreads/ptw32_rwlock_cancelwrwait.c b/pthreads/ptw32_rwlock_cancelwrwait.c
new file mode 100644
index 000000000..a057bd1d7
--- /dev/null
+++ b/pthreads/ptw32_rwlock_cancelwrwait.c
@@ -0,0 +1,50 @@
+/*
+ * ptw32_rwlock_cancelwrwait.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 "pthread.h"
+#include "implement.h"
+
+void
+ptw32_rwlock_cancelwrwait (void *arg)
+{
+ pthread_rwlock_t rwl = (pthread_rwlock_t) arg;
+
+ rwl->nSharedAccessCount = -rwl->nCompletedSharedAccessCount;
+ rwl->nCompletedSharedAccessCount = 0;
+
+ (void) pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted));
+ (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+}
diff --git a/pthreads/ptw32_rwlock_check_need_init.c b/pthreads/ptw32_rwlock_check_need_init.c
new file mode 100644
index 000000000..ea2561eef
--- /dev/null
+++ b/pthreads/ptw32_rwlock_check_need_init.c
@@ -0,0 +1,93 @@
+/*
+ * pthread_rwlock_check_need_init.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 "pthread.h"
+#include "implement.h"
+
+INLINE int
+ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock)
+{
+ int result = 0;
+
+ /*
+ * 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);
+
+ /*
+ * We got here possibly under race
+ * conditions. Check again inside the critical section
+ * and only initialise if the rwlock is valid (not been destroyed).
+ * If a static rwlock has been destroyed, the application can
+ * re-initialise it only by calling pthread_rwlock_init()
+ * explicitly.
+ */
+ if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
+ {
+ result = pthread_rwlock_init (rwlock, NULL);
+ }
+ else if (*rwlock == NULL)
+ {
+ /*
+ * The rwlock has been destroyed while we were waiting to
+ * initialise it, so the operation that caused the
+ * auto-initialisation should fail.
+ */
+ result = EINVAL;
+ }
+
+ LeaveCriticalSection (&ptw32_rwlock_test_init_lock);
+
+ return result;
+}
diff --git a/pthreads/ptw32_semwait.c b/pthreads/ptw32_semwait.c
new file mode 100644
index 000000000..8b23d11d6
--- /dev/null
+++ b/pthreads/ptw32_semwait.c
@@ -0,0 +1,118 @@
+/*
+ * ptw32_semwait.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef _UWIN
+//# include <process.h>
+#endif
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+ptw32_semwait (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DESCRIPTION
+ * This function waits on a POSIX semaphore. If the
+ * semaphore value is greater than zero, it decreases
+ * its value by one. If the semaphore value is zero, then
+ * the calling thread (or process) is blocked until it can
+ * successfully decrease the value.
+ *
+ * Unlike sem_wait(), this routine is non-cancelable.
+ *
+ * RESULTS
+ * 0 successfully decreased semaphore,
+ * -1 failed, error in errno.
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ * EINTR the function was interrupted by a signal,
+ * EDEADLK a deadlock condition was detected.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = *sem;
+
+ if (s == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ if ((result = pthread_mutex_lock (&s->lock)) == 0)
+ {
+ int v = --s->value;
+
+ (void) pthread_mutex_unlock (&s->lock);
+
+ if (v < 0)
+ {
+ /* Must wait */
+ if (WaitForSingleObject (s->sem, INFINITE) == WAIT_OBJECT_0)
+ {
+#ifdef NEED_SEM
+ if (pthread_mutex_lock (&s->lock) == 0)
+ {
+ if (s->leftToUnblock > 0)
+ {
+ --s->leftToUnblock;
+ SetEvent(s->sem);
+ }
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+#endif
+ return 0;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+} /* ptw32_semwait */
diff --git a/pthreads/ptw32_spinlock_check_need_init.c b/pthreads/ptw32_spinlock_check_need_init.c
new file mode 100644
index 000000000..bf45bc397
--- /dev/null
+++ b/pthreads/ptw32_spinlock_check_need_init.c
@@ -0,0 +1,81 @@
+/*
+ * ptw32_spinlock_check_need_init.c
+ *
+ * Description:
+ * This translation unit implements spin 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 "pthread.h"
+#include "implement.h"
+
+
+INLINE int
+ptw32_spinlock_check_need_init (pthread_spinlock_t * lock)
+{
+ int result = 0;
+
+ /*
+ * 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);
+
+ /*
+ * We got here possibly under race
+ * conditions. Check again inside the critical section
+ * and only initialise if the spinlock is valid (not been destroyed).
+ * If a static spinlock has been destroyed, the application can
+ * re-initialise it only by calling pthread_spin_init()
+ * explicitly.
+ */
+ if (*lock == PTHREAD_SPINLOCK_INITIALIZER)
+ {
+ result = pthread_spin_init (lock, PTHREAD_PROCESS_PRIVATE);
+ }
+ else if (*lock == NULL)
+ {
+ /*
+ * The spinlock has been destroyed while we were waiting to
+ * initialise it, so the operation that caused the
+ * auto-initialisation should fail.
+ */
+ result = EINVAL;
+ }
+
+ LeaveCriticalSection (&ptw32_spinlock_test_init_lock);
+
+ return (result);
+}
diff --git a/pthreads/ptw32_threadDestroy.c b/pthreads/ptw32_threadDestroy.c
new file mode 100644
index 000000000..eb9abfc61
--- /dev/null
+++ b/pthreads/ptw32_threadDestroy.c
@@ -0,0 +1,82 @@
+/*
+ * ptw32_threadDestroy.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"
+
+
+void
+ptw32_threadDestroy (pthread_t thread)
+{
+ ptw32_thread_t * tp = (ptw32_thread_t *) thread.p;
+ ptw32_thread_t threadCopy;
+
+ if (tp != NULL)
+ {
+ /*
+ * Copy thread state so that the thread can be atomically NULLed.
+ */
+ memcpy (&threadCopy, tp, sizeof (threadCopy));
+
+ /*
+ * Thread ID structs are never freed. They're NULLed and reused.
+ * This also sets the thread to PThreadStateInitial (invalid).
+ */
+ ptw32_threadReusePush (thread);
+
+ /* Now work on the copy. */
+ if (threadCopy.cancelEvent != NULL)
+ {
+ CloseHandle (threadCopy.cancelEvent);
+ }
+
+ (void) pthread_mutex_destroy(&threadCopy.cancelLock);
+ (void) pthread_mutex_destroy(&threadCopy.threadLock);
+
+#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__)
+ /*
+ * See documentation for endthread vs endthreadex.
+ */
+ if (threadCopy.threadH != 0)
+ {
+ CloseHandle (threadCopy.threadH);
+ }
+#endif
+
+ }
+} /* ptw32_threadDestroy */
+
diff --git a/pthreads/ptw32_threadStart.c b/pthreads/ptw32_threadStart.c
new file mode 100644
index 000000000..5c0fe0e85
--- /dev/null
+++ b/pthreads/ptw32_threadStart.c
@@ -0,0 +1,360 @@
+/*
+ * ptw32_threadStart.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"
+
+#ifdef __CLEANUP_SEH
+
+static DWORD
+ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei)
+{
+ switch (ep->ExceptionRecord->ExceptionCode)
+ {
+ case EXCEPTION_PTW32_SERVICES:
+ {
+ DWORD param;
+ DWORD numParams = ep->ExceptionRecord->NumberParameters;
+
+ numParams = (numParams > 3) ? 3 : numParams;
+
+ for (param = 0; param < numParams; param++)
+ {
+ ei[param] = ep->ExceptionRecord->ExceptionInformation[param];
+ }
+
+ return EXCEPTION_EXECUTE_HANDLER;
+ break;
+ }
+ default:
+ {
+ /*
+ * A system unexpected exception has occurred running the user's
+ * routine. We need to cleanup before letting the exception
+ * out of thread scope.
+ */
+ pthread_t self = pthread_self ();
+
+ (void) pthread_mutex_destroy (&((ptw32_thread_t *)self.p)->cancelLock);
+ ptw32_callUserDestroyRoutines (self);
+
+ return EXCEPTION_CONTINUE_SEARCH;
+ break;
+ }
+ }
+}
+
+#elif defined(__CLEANUP_CXX)
+
+#if defined(_MSC_VER)
+# include <eh.h>
+#elif defined(__WATCOMC__)
+# include <eh.h>
+# include <exceptio.h>
+typedef terminate_handler
+ terminate_function;
+#else
+# if defined(__GNUC__) && __GNUC__ < 3
+# include <new.h>
+# else
+# include <new>
+using
+ std::terminate_handler;
+using
+ std::terminate;
+using
+ std::set_terminate;
+# endif
+typedef terminate_handler
+ terminate_function;
+#endif
+
+static terminate_function
+ ptw32_oldTerminate;
+
+void
+ptw32_terminate ()
+{
+ set_terminate (ptw32_oldTerminate);
+ (void) pthread_win32_thread_detach_np ();
+ terminate ();
+}
+
+#endif
+
+#if ! defined (__MINGW32__) || (defined (__MSVCRT__) && ! defined (__DMC__))
+unsigned
+ __stdcall
+#else
+void
+#endif
+ptw32_threadStart (void *vthreadParms)
+{
+ ThreadParms * threadParms = (ThreadParms *) vthreadParms;
+ pthread_t self;
+ ptw32_thread_t * sp;
+ void *(*start) (void *);
+ void * arg;
+
+#ifdef __CLEANUP_SEH
+ DWORD
+ ei[] = { 0, 0, 0 };
+#endif
+
+#ifdef __CLEANUP_C
+ int setjmp_rc;
+#endif
+
+ void * status = (void *) 0;
+
+ self = threadParms->tid;
+ sp = (ptw32_thread_t *) self.p;
+ start = threadParms->start;
+ arg = threadParms->arg;
+
+ free (threadParms);
+
+#if 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
+ * 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
+
+ pthread_setspecific (ptw32_selfThreadKey, sp);
+
+ sp->state = PThreadStateRunning;
+
+#ifdef __CLEANUP_SEH
+
+ __try
+ {
+ /*
+ * Run the caller's routine;
+ */
+ status = sp->exitStatus = (*start) (arg);
+
+#ifdef _UWIN
+ if (--pthread_count <= 0)
+ exit (0);
+#endif
+
+ }
+ __except (ExceptionFilter (GetExceptionInformation (), ei))
+ {
+ switch (ei[0])
+ {
+ case PTW32_EPS_CANCEL:
+ status = sp->exitStatus = PTHREAD_CANCELED;
+#ifdef _UWIN
+ if (--pthread_count <= 0)
+ exit (0);
+#endif
+ break;
+ case PTW32_EPS_EXIT:
+ status = sp->exitStatus;
+ break;
+ default:
+ status = sp->exitStatus = PTHREAD_CANCELED;
+ break;
+ }
+ }
+
+#else /* __CLEANUP_SEH */
+
+#ifdef __CLEANUP_C
+
+ setjmp_rc = setjmp (sp->start_mark);
+
+ if (0 == setjmp_rc)
+ {
+
+ /*
+ * Run the caller's routine;
+ */
+ status = sp->exitStatus = (*start) (arg);
+ }
+ else
+ {
+ switch (setjmp_rc)
+ {
+ case PTW32_EPS_CANCEL:
+ status = sp->exitStatus = PTHREAD_CANCELED;
+ break;
+ case PTW32_EPS_EXIT:
+ status = sp->exitStatus;
+ break;
+ default:
+ status = sp->exitStatus = PTHREAD_CANCELED;
+ break;
+ }
+ }
+
+#else /* __CLEANUP_C */
+
+#ifdef __CLEANUP_CXX
+
+ ptw32_oldTerminate = set_terminate (&ptw32_terminate);
+
+ try
+ {
+ /*
+ * Run the caller's routine in a nested try block so that we
+ * can run the user's terminate function, which may call
+ * pthread_exit() or be canceled.
+ */
+ try
+ {
+ status = sp->exitStatus = (*start) (arg);
+ }
+ catch (ptw32_exception &)
+ {
+ /*
+ * Pass these through to the outer block.
+ */
+ throw;
+ }
+ catch (...)
+ {
+ /*
+ * We want to run the user's terminate function if supplied.
+ * That function may call pthread_exit() or be canceled, which will
+ * be handled by the outer try block.
+ *
+ * ptw32_terminate() will be called if there is no user
+ * supplied function.
+ */
+
+ terminate_function
+ term_func = set_terminate (0);
+ set_terminate (term_func);
+
+ if (term_func != 0)
+ {
+ term_func ();
+ }
+
+ throw;
+ }
+ }
+ catch (ptw32_exception_cancel &)
+ {
+ /*
+ * Thread was canceled.
+ */
+ status = sp->exitStatus = PTHREAD_CANCELED;
+ }
+ catch (ptw32_exception_exit &)
+ {
+ /*
+ * Thread was exited via pthread_exit().
+ */
+ status = sp->exitStatus;
+ }
+ catch (...)
+ {
+ /*
+ * 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.
+ */
+ 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);
+
+#else
+
+#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
+
+#endif /* __CLEANUP_CXX */
+#endif /* __CLEANUP_C */
+#endif /* __CLEANUP_SEH */
+
+#if defined(PTW32_STATIC_LIB)
+ /*
+ * We need to cleanup the pthread now if we have
+ * been statically linked, in which case the cleanup
+ * in dllMain won't get done. Joinable threads will
+ * only be partially cleaned up and must be fully cleaned
+ * up by pthread_join() or pthread_detach().
+ *
+ * Note: if this library has been statically linked,
+ * implicitly created pthreads (those created
+ * for Win32 threads which have called pthreads routines)
+ * must be cleaned up explicitly by the application
+ * (by calling pthread_win32_thread_detach_np()).
+ * For the dll, dllMain will do the cleanup automatically.
+ */
+ (void) pthread_win32_thread_detach_np ();
+#endif
+
+#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__)
+ _endthreadex ((unsigned) status);
+#else
+ _endthread ();
+#endif
+
+ /*
+ * Never reached.
+ */
+
+#if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__)
+ return (unsigned) status;
+#endif
+
+} /* ptw32_threadStart */
diff --git a/pthreads/ptw32_throw.c b/pthreads/ptw32_throw.c
new file mode 100644
index 000000000..493f4e4dc
--- /dev/null
+++ b/pthreads/ptw32_throw.c
@@ -0,0 +1,167 @@
+/*
+ * 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).
+ */
+ unsigned exitCode = 0;
+
+ switch (exception)
+ {
+ case PTW32_EPS_CANCEL:
+ exitCode = (unsigned) PTHREAD_CANCELED;
+ break;
+ case PTW32_EPS_EXIT:
+ exitCode = (unsigned) sp->exitStatus;;
+ break;
+ }
+
+#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
+}
diff --git a/pthreads/ptw32_timespec.c b/pthreads/ptw32_timespec.c
new file mode 100644
index 000000000..6a2cb565a
--- /dev/null
+++ b/pthreads/ptw32_timespec.c
@@ -0,0 +1,83 @@
+/*
+ * ptw32_timespec.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"
+
+
+#ifdef 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 )
+
+INLINE void
+ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft)
+ /*
+ * -------------------------------------------------------------------
+ * converts struct timespec
+ * where the time is expressed in seconds and nanoseconds from Jan 1, 1970.
+ * into FILETIME (as set by GetSystemTimeAsFileTime), where the time is
+ * expressed in 100 nanoseconds from Jan 1, 1601,
+ * -------------------------------------------------------------------
+ */
+{
+ *(LONGLONG *) ft = ts->tv_sec * 10000000
+ + (ts->tv_nsec + 50) / 100 + PTW32_TIMESPEC_TO_FILETIME_OFFSET;
+}
+
+INLINE void
+ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts)
+ /*
+ * -------------------------------------------------------------------
+ * converts FILETIME (as set by GetSystemTimeAsFileTime), where the time is
+ * expressed in 100 nanoseconds from Jan 1, 1601,
+ * into struct timespec
+ * where the time is expressed in seconds and nanoseconds from Jan 1, 1970.
+ * -------------------------------------------------------------------
+ */
+{
+ ts->tv_sec =
+ (int) ((*(LONGLONG *) 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);
+}
+
+#endif /* NEED_FTIME */
diff --git a/pthreads/ptw32_tkAssocCreate.c b/pthreads/ptw32_tkAssocCreate.c
new file mode 100644
index 000000000..5ba24bbf7
--- /dev/null
+++ b/pthreads/ptw32_tkAssocCreate.c
@@ -0,0 +1,118 @@
+/*
+ * ptw32_tkAssocCreate.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"
+
+
+int
+ptw32_tkAssocCreate (ptw32_thread_t * sp, pthread_key_t key)
+ /*
+ * -------------------------------------------------------------------
+ * This routine creates an association that
+ * is unique for the given (thread,key) combination.The association
+ * is referenced by both the thread and the key.
+ * This association allows us to determine what keys the
+ * current thread references and what threads a given key
+ * references.
+ * See the detailed description
+ * at the beginning of this file for further details.
+ *
+ * Notes:
+ * 1) New associations are pushed to the beginning of the
+ * chain so that the internal ptw32_selfThreadKey association
+ * is always last, thus allowing selfThreadExit to
+ * be implicitly called last by pthread_exit.
+ * 2)
+ *
+ * Parameters:
+ * thread
+ * current running thread.
+ * key
+ * key on which to create an association.
+ * Returns:
+ * 0 - if successful,
+ * ENOMEM - not enough memory to create assoc or other object
+ * EINVAL - an internal error occurred
+ * ENOSYS - an internal error occurred
+ * -------------------------------------------------------------------
+ */
+{
+ ThreadKeyAssoc *assoc;
+
+ /*
+ * Have to create an association and add it
+ * to both the key and the thread.
+ *
+ * Both key->keyLock and thread->threadLock are locked on
+ * entry to this routine.
+ */
+ assoc = (ThreadKeyAssoc *) calloc (1, sizeof (*assoc));
+
+ if (assoc == NULL)
+ {
+ return ENOMEM;
+ }
+
+ assoc->thread = sp;
+ assoc->key = key;
+
+ /*
+ * Register assoc with key
+ */
+ assoc->prevThread = NULL;
+ assoc->nextThread = (ThreadKeyAssoc *) key->threads;
+ if (assoc->nextThread != NULL)
+ {
+ assoc->nextThread->prevThread = assoc;
+ }
+ key->threads = (void *) assoc;
+
+ /*
+ * Register assoc with thread
+ */
+ assoc->prevKey = NULL;
+ assoc->nextKey = (ThreadKeyAssoc *) sp->keys;
+ if (assoc->nextKey != NULL)
+ {
+ assoc->nextKey->prevKey = assoc;
+ }
+ sp->keys = (void *) assoc;
+
+ return (0);
+
+} /* ptw32_tkAssocCreate */
diff --git a/pthreads/ptw32_tkAssocDestroy.c b/pthreads/ptw32_tkAssocDestroy.c
new file mode 100644
index 000000000..a7842ea87
--- /dev/null
+++ b/pthreads/ptw32_tkAssocDestroy.c
@@ -0,0 +1,114 @@
+/*
+ * ptw32_tkAssocDestroy.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"
+
+
+void
+ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc)
+ /*
+ * -------------------------------------------------------------------
+ * This routine releases all resources for the given ThreadKeyAssoc
+ * once it is no longer being referenced
+ * ie) either the key or thread has stopped referencing it.
+ *
+ * Parameters:
+ * assoc
+ * an instance of ThreadKeyAssoc.
+ * Returns:
+ * N/A
+ * -------------------------------------------------------------------
+ */
+{
+
+ /*
+ * Both key->keyLock and thread->threadLock are locked on
+ * entry to this routine.
+ */
+ if (assoc != NULL)
+ {
+ ThreadKeyAssoc * prev, * next;
+
+ /* Remove assoc from thread's keys chain */
+ prev = assoc->prevKey;
+ next = assoc->nextKey;
+ if (prev != NULL)
+ {
+ prev->nextKey = next;
+ }
+ if (next != NULL)
+ {
+ next->prevKey = prev;
+ }
+
+ if (assoc->thread->keys == assoc)
+ {
+ /* We're at the head of the thread's keys chain */
+ assoc->thread->keys = next;
+ }
+ if (assoc->thread->nextAssoc == assoc)
+ {
+ /*
+ * Thread is exiting and we're deleting the assoc to be processed next.
+ * Hand thread the assoc after this one.
+ */
+ assoc->thread->nextAssoc = next;
+ }
+
+ /* Remove assoc from key's threads chain */
+ prev = assoc->prevThread;
+ next = assoc->nextThread;
+ if (prev != NULL)
+ {
+ prev->nextThread = next;
+ }
+ if (next != NULL)
+ {
+ next->prevThread = prev;
+ }
+
+ if (assoc->key->threads == assoc)
+ {
+ /* We're at the head of the key's threads chain */
+ assoc->key->threads = next;
+ }
+
+ free (assoc);
+ }
+
+} /* ptw32_tkAssocDestroy */
diff --git a/pthreads/rwlock.c b/pthreads/rwlock.c
new file mode 100644
index 000000000..4a3cd2594
--- /dev/null
+++ b/pthreads/rwlock.c
@@ -0,0 +1,51 @@
+/*
+ * rwlock.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 "ptw32_rwlock_check_need_init.c"
+#include "ptw32_rwlock_cancelwrwait.c"
+#include "pthread_rwlock_init.c"
+#include "pthread_rwlock_destroy.c"
+#include "pthread_rwlockattr_init.c"
+#include "pthread_rwlockattr_destroy.c"
+#include "pthread_rwlockattr_getpshared.c"
+#include "pthread_rwlockattr_setpshared.c"
+#include "pthread_rwlock_rdlock.c"
+#include "pthread_rwlock_timedrdlock.c"
+#include "pthread_rwlock_wrlock.c"
+#include "pthread_rwlock_timedwrlock.c"
+#include "pthread_rwlock_unlock.c"
+#include "pthread_rwlock_tryrdlock.c"
+#include "pthread_rwlock_trywrlock.c"
diff --git a/pthreads/sched.c b/pthreads/sched.c
new file mode 100644
index 000000000..ed30ea7b2
--- /dev/null
+++ b/pthreads/sched.c
@@ -0,0 +1,53 @@
+/*
+ * sched.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+#include "pthread_attr_setschedpolicy.c"
+#include "pthread_attr_getschedpolicy.c"
+#include "pthread_attr_setschedparam.c"
+#include "pthread_attr_getschedparam.c"
+#include "pthread_attr_setinheritsched.c"
+#include "pthread_attr_getinheritsched.c"
+#include "pthread_setschedparam.c"
+#include "pthread_getschedparam.c"
+#include "sched_get_priority_max.c"
+#include "sched_get_priority_min.c"
+#include "sched_setscheduler.c"
+#include "sched_getscheduler.c"
+#include "sched_yield.c"
diff --git a/pthreads/sched.h b/pthreads/sched.h
new file mode 100644
index 000000000..dfb8e934a
--- /dev/null
+++ b/pthreads/sched.h
@@ -0,0 +1,178 @@
+/*
+ * 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(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 DLL code, you should define PTW32_BUILD so that
+ * the variables/functions are exported correctly. When using the DLL,
+ * do NOT define PTW32_BUILD, and then the variables/functions will
+ * be imported correctly.
+ */
+#ifndef PTW32_STATIC_LIB
+# ifdef PTW32_BUILD
+# define PTW32_DLLPORT __declspec (dllexport)
+# else
+# define PTW32_DLLPORT __declspec (dllimport)
+# endif
+#else
+# define PTW32_DLLPORT
+#endif
+
+/*
+ * This is a duplicate of what is in the autoconf config.h,
+ * which is only used when building the pthread-win32 libraries.
+ */
+
+#ifndef PTW32_CONFIG_H
+# if defined(WINCE)
+# define NEED_ERRNO
+# define NEED_SEM
+# endif
+# if defined(_UWIN) || defined(__MINGW32__)
+# define HAVE_MODE_T
+# endif
+#endif
+
+/*
+ *
+ */
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+#ifdef NEED_ERRNO
+#include "need_errno.h"
+#else
+#include <errno.h>
+#endif
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+#if defined(__MINGW32__) || defined(_UWIN)
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+/* For pid_t */
+# include <sys/types.h>
+/* Required by Unix 98 */
+# include <time.h>
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+#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 */
+
diff --git a/pthreads/sched_get_priority_max.c b/pthreads/sched_get_priority_max.c
new file mode 100644
index 000000000..cabf2320a
--- /dev/null
+++ b/pthreads/sched_get_priority_max.c
@@ -0,0 +1,134 @@
+/*
+ * sched_get_priority_max.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+/*
+ * On Windows98, THREAD_PRIORITY_LOWEST is (-2) and
+ * THREAD_PRIORITY_HIGHEST is 2, and everything works just fine.
+ *
+ * On WinCE 3.0, it so happen that THREAD_PRIORITY_LOWEST is 5
+ * and THREAD_PRIORITY_HIGHEST is 1 (yes, I know, it is funny:
+ * highest priority use smaller numbers) and the following happens:
+ *
+ * sched_get_priority_min() returns 5
+ * sched_get_priority_max() returns 1
+ *
+ * The following table shows the base priority levels for combinations
+ * of priority class and priority value in Win32.
+ *
+ * Process Priority Class Thread Priority Level
+ * -----------------------------------------------------------------
+ * 1 IDLE_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 HIGH_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 2 IDLE_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 3 IDLE_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 4 IDLE_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 4 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 5 IDLE_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 5 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 5 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 6 IDLE_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 6 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 6 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 7 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 7 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 7 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 8 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 8 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 8 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 8 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 9 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 9 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 9 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 10 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 10 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 11 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 11 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 11 HIGH_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 12 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 12 HIGH_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 13 HIGH_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 14 HIGH_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 15 HIGH_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 15 HIGH_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 IDLE_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 16 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 17 REALTIME_PRIORITY_CLASS -7
+ * 18 REALTIME_PRIORITY_CLASS -6
+ * 19 REALTIME_PRIORITY_CLASS -5
+ * 20 REALTIME_PRIORITY_CLASS -4
+ * 21 REALTIME_PRIORITY_CLASS -3
+ * 22 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 23 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 24 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 25 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 26 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 27 REALTIME_PRIORITY_CLASS 3
+ * 28 REALTIME_PRIORITY_CLASS 4
+ * 29 REALTIME_PRIORITY_CLASS 5
+ * 30 REALTIME_PRIORITY_CLASS 6
+ * 31 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ *
+ * Windows NT: Values -7, -6, -5, -4, -3, 3, 4, 5, and 6 are not supported.
+ */
+
+
+int
+sched_get_priority_max (int policy)
+{
+ if (policy < SCHED_MIN || policy > SCHED_MAX)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
+ /* WinCE? */
+ return PTW32_MAX (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
+#else
+ /* This is independent of scheduling policy in Win32. */
+ return PTW32_MAX (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+}
diff --git a/pthreads/sched_get_priority_min.c b/pthreads/sched_get_priority_min.c
new file mode 100644
index 000000000..9c4f8591e
--- /dev/null
+++ b/pthreads/sched_get_priority_min.c
@@ -0,0 +1,135 @@
+/*
+ * sched_get_priority_min.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+/*
+ * On Windows98, THREAD_PRIORITY_LOWEST is (-2) and
+ * THREAD_PRIORITY_HIGHEST is 2, and everything works just fine.
+ *
+ * On WinCE 3.0, it so happen that THREAD_PRIORITY_LOWEST is 5
+ * and THREAD_PRIORITY_HIGHEST is 1 (yes, I know, it is funny:
+ * highest priority use smaller numbers) and the following happens:
+ *
+ * sched_get_priority_min() returns 5
+ * sched_get_priority_max() returns 1
+ *
+ * The following table shows the base priority levels for combinations
+ * of priority class and priority value in Win32.
+ *
+ * Process Priority Class Thread Priority Level
+ * -----------------------------------------------------------------
+ * 1 IDLE_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 1 HIGH_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 2 IDLE_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 3 IDLE_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 4 IDLE_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 4 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 5 IDLE_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 5 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 5 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 6 IDLE_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 6 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 6 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 7 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 7 Background NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 7 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 8 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 8 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 8 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 8 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 9 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 9 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 9 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 10 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 10 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 11 Foreground NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 11 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 11 HIGH_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 12 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 12 HIGH_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 13 HIGH_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 14 HIGH_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 15 HIGH_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 15 HIGH_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 IDLE_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 BELOW_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 15 ABOVE_NORMAL_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ * 16 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_IDLE
+ * 17 REALTIME_PRIORITY_CLASS -7
+ * 18 REALTIME_PRIORITY_CLASS -6
+ * 19 REALTIME_PRIORITY_CLASS -5
+ * 20 REALTIME_PRIORITY_CLASS -4
+ * 21 REALTIME_PRIORITY_CLASS -3
+ * 22 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_LOWEST
+ * 23 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_BELOW_NORMAL
+ * 24 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_NORMAL
+ * 25 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_ABOVE_NORMAL
+ * 26 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_HIGHEST
+ * 27 REALTIME_PRIORITY_CLASS 3
+ * 28 REALTIME_PRIORITY_CLASS 4
+ * 29 REALTIME_PRIORITY_CLASS 5
+ * 30 REALTIME_PRIORITY_CLASS 6
+ * 31 REALTIME_PRIORITY_CLASS THREAD_PRIORITY_TIME_CRITICAL
+ *
+ * Windows NT: Values -7, -6, -5, -4, -3, 3, 4, 5, and 6 are not supported.
+ *
+ */
+
+
+int
+sched_get_priority_min (int policy)
+{
+ if (policy < SCHED_MIN || policy > SCHED_MAX)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+#if (THREAD_PRIORITY_LOWEST > THREAD_PRIORITY_NORMAL)
+ /* WinCE? */
+ return PTW32_MIN (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
+#else
+ /* This is independent of scheduling policy in Win32. */
+ return PTW32_MIN (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+}
diff --git a/pthreads/sched_getscheduler.c b/pthreads/sched_getscheduler.c
new file mode 100644
index 000000000..9bc819e47
--- /dev/null
+++ b/pthreads/sched_getscheduler.c
@@ -0,0 +1,69 @@
+/*
+ * sched_getscheduler.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+int
+sched_getscheduler (pid_t pid)
+{
+ /*
+ * Win32 only has one policy which we call SCHED_OTHER.
+ * However, we try to provide other valid side-effects
+ * such as EPERM and ESRCH errors.
+ */
+ if (0 != pid)
+ {
+ int selfPid = (int) GetCurrentProcessId ();
+
+ if (pid != selfPid)
+ {
+ HANDLE h =
+ OpenProcess (PROCESS_QUERY_INFORMATION, PTW32_FALSE, (DWORD) pid);
+
+ if (NULL == h)
+ {
+ errno =
+ (GetLastError () ==
+ (0xFF & ERROR_ACCESS_DENIED)) ? EPERM : ESRCH;
+ return -1;
+ }
+ }
+ }
+
+ return SCHED_OTHER;
+}
diff --git a/pthreads/sched_setscheduler.c b/pthreads/sched_setscheduler.c
new file mode 100644
index 000000000..4e060c7e5
--- /dev/null
+++ b/pthreads/sched_setscheduler.c
@@ -0,0 +1,81 @@
+/*
+ * sched_setscheduler.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+int
+sched_setscheduler (pid_t pid, int policy)
+{
+ /*
+ * Win32 only has one policy which we call SCHED_OTHER.
+ * However, we try to provide other valid side-effects
+ * such as EPERM and ESRCH errors. Choosing to check
+ * for a valid policy last allows us to get the most value out
+ * of this function.
+ */
+ if (0 != pid)
+ {
+ int selfPid = (int) GetCurrentProcessId ();
+
+ if (pid != selfPid)
+ {
+ HANDLE h =
+ OpenProcess (PROCESS_SET_INFORMATION, PTW32_FALSE, (DWORD) pid);
+
+ if (NULL == h)
+ {
+ errno =
+ (GetLastError () ==
+ (0xFF & ERROR_ACCESS_DENIED)) ? EPERM : ESRCH;
+ return -1;
+ }
+ }
+ }
+
+ if (SCHED_OTHER != policy)
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ /*
+ * Don't set anything because there is nothing to set.
+ * Just return the current (the only possible) value.
+ */
+ return SCHED_OTHER;
+}
diff --git a/pthreads/sched_yield.c b/pthreads/sched_yield.c
new file mode 100644
index 000000000..6ac5ed926
--- /dev/null
+++ b/pthreads/sched_yield.c
@@ -0,0 +1,71 @@
+/*
+ * sched_yield.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "sched.h"
+
+int
+sched_yield (void)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function indicates that the calling thread is
+ * willing to give up some time slices to other threads.
+ *
+ * PARAMETERS
+ * N/A
+ *
+ *
+ * DESCRIPTION
+ * This function indicates that the calling thread is
+ * willing to give up some time slices to other threads.
+ * NOTE: Since this is part of POSIX 1003.1b
+ * (realtime extensions), it is defined as returning
+ * -1 if an error occurs and sets errno to the actual
+ * error.
+ *
+ * RESULTS
+ * 0 successfully created semaphore,
+ * ENOSYS sched_yield not supported,
+ *
+ * ------------------------------------------------------
+ */
+{
+ Sleep (0);
+
+ return 0;
+}
diff --git a/pthreads/sem_close.c b/pthreads/sem_close.c
new file mode 100644
index 000000000..2f95c8785
--- /dev/null
+++ b/pthreads/sem_close.c
@@ -0,0 +1,58 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_close.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+/* ignore warning "unreferenced formal parameter" */
+#ifdef _MSC_VER
+#pragma warning( disable : 4100 )
+#endif
+
+int
+sem_close (sem_t * sem)
+{
+ errno = ENOSYS;
+ return -1;
+} /* sem_close */
diff --git a/pthreads/sem_destroy.c b/pthreads/sem_destroy.c
new file mode 100644
index 000000000..6c98e80b9
--- /dev/null
+++ b/pthreads/sem_destroy.c
@@ -0,0 +1,144 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_destroy.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+int
+sem_destroy (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function destroys an unnamed semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * DESCRIPTION
+ * This function destroys an unnamed semaphore.
+ *
+ * RESULTS
+ * 0 successfully destroyed semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ * EBUSY threads (or processes) are currently
+ * blocked on 'sem'
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = NULL;
+
+ if (sem == NULL || *sem == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ s = *sem;
+
+ if ((result = pthread_mutex_lock (&s->lock)) == 0)
+ {
+ if (s->value < 0)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ result = EBUSY;
+ }
+ else
+ {
+ /* There are no threads currently blocked on this semaphore. */
+
+ if (!CloseHandle (s->sem))
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ result = EINVAL;
+ }
+ else
+ {
+ /*
+ * Invalidate the semaphore handle when we have the lock.
+ * Other sema operations should test this after acquiring the lock
+ * to check that the sema is still valid, i.e. before performing any
+ * operations. This may only be necessary before the sema op routine
+ * returns so that the routine can return EINVAL - e.g. if setting
+ * s->value to SEM_VALUE_MAX below does force a fall-through.
+ */
+ *sem = NULL;
+
+ /* Prevent anyone else actually waiting on or posting this sema.
+ */
+ s->value = SEM_VALUE_MAX;
+
+ (void) pthread_mutex_unlock (&s->lock);
+
+ do
+ {
+ /* Give other threads a chance to run and exit any sema op
+ * routines. Due to the SEM_VALUE_MAX value, if sem_post or
+ * sem_wait were blocked by us they should fall through.
+ */
+ Sleep(0);
+ }
+ while (pthread_mutex_destroy (&s->lock) == EBUSY);
+ }
+ }
+ }
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ free (s);
+
+ return 0;
+
+} /* sem_destroy */
diff --git a/pthreads/sem_getvalue.c b/pthreads/sem_getvalue.c
new file mode 100644
index 000000000..baafb02cf
--- /dev/null
+++ b/pthreads/sem_getvalue.c
@@ -0,0 +1,110 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_getvalue.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of PThreads.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1-2001
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+int
+sem_getvalue (sem_t * sem, int *sval)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function stores the current count value of the
+ * semaphore.
+ * RESULTS
+ *
+ * Return value
+ *
+ * 0 sval has been set.
+ * -1 failed, error in errno
+ *
+ * in global errno
+ *
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS this function is not supported,
+ *
+ *
+ * PARAMETERS
+ *
+ * sem pointer to an instance of sem_t
+ *
+ * sval pointer to int.
+ *
+ * DESCRIPTION
+ * This function stores the current count value of the semaphore
+ * pointed to by sem in the int pointed to by sval.
+ */
+{
+ if (sem == NULL || *sem == NULL || sval == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ else
+ {
+ long value;
+ register sem_t s = *sem;
+ int result = 0;
+
+ if ((result = pthread_mutex_lock(&s->lock)) == 0)
+ {
+ /* See sem_destroy.c
+ */
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ errno = EINVAL;
+ return -1;
+ }
+
+ value = s->value;
+ (void) pthread_mutex_unlock(&s->lock);
+ *sval = value;
+ }
+
+ return result;
+ }
+
+} /* sem_getvalue */
diff --git a/pthreads/sem_init.c b/pthreads/sem_init.c
new file mode 100644
index 000000000..02acd90f1
--- /dev/null
+++ b/pthreads/sem_init.c
@@ -0,0 +1,169 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_init.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of PThreads.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1-2001
+ *
+ * -------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+int
+sem_init (sem_t * sem, int pshared, unsigned int value)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function initializes a semaphore. The
+ * initial value of the semaphore is 'value'
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * pshared
+ * if zero, this semaphore may only be shared between
+ * threads in the same process.
+ * if nonzero, the semaphore can be shared between
+ * processes
+ *
+ * value
+ * initial value of the semaphore counter
+ *
+ * DESCRIPTION
+ * This function initializes a semaphore. The
+ * initial value of the semaphore is set to 'value'.
+ *
+ * RESULTS
+ * 0 successfully created semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore, or
+ * 'value' >= SEM_VALUE_MAX
+ * ENOMEM out of memory,
+ * ENOSPC a required resource has been exhausted,
+ * ENOSYS semaphores are not supported,
+ * EPERM the process lacks appropriate privilege
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = NULL;
+
+ if (pshared != 0)
+ {
+ /*
+ * Creating a semaphore that can be shared between
+ * processes
+ */
+ result = EPERM;
+ }
+ else if (value > (unsigned int)SEM_VALUE_MAX)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ s = (sem_t) calloc (1, sizeof (*s));
+
+ if (NULL == s)
+ {
+ result = ENOMEM;
+ }
+ else
+ {
+
+ s->value = value;
+ if (pthread_mutex_init(&s->lock, NULL) == 0)
+ {
+
+#ifdef NEED_SEM
+
+ s->sem = CreateEvent (NULL,
+ PTW32_FALSE, /* auto (not manual) reset */
+ PTW32_FALSE, /* initial state is unset */
+ NULL);
+
+ if (0 == s->sem)
+ {
+ free (s);
+ (void) pthread_mutex_destroy(&s->lock);
+ result = ENOSPC;
+ }
+ else
+ {
+ s->leftToUnblock = 0;
+ }
+
+#else /* NEED_SEM */
+
+ if ((s->sem = CreateSemaphore (NULL, /* Always NULL */
+ (long) 0, /* Force threads to wait */
+ (long) SEM_VALUE_MAX, /* Maximum value */
+ NULL)) == 0) /* Name */
+ {
+ (void) pthread_mutex_destroy(&s->lock);
+ result = ENOSPC;
+ }
+
+#endif /* NEED_SEM */
+
+ }
+ else
+ {
+ result = ENOSPC;
+ }
+
+ if (result != 0)
+ {
+ free(s);
+ }
+ }
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ *sem = s;
+
+ return 0;
+
+} /* sem_init */
diff --git a/pthreads/sem_open.c b/pthreads/sem_open.c
new file mode 100644
index 000000000..bf48c831c
--- /dev/null
+++ b/pthreads/sem_open.c
@@ -0,0 +1,58 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_open.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+/* ignore warning "unreferenced formal parameter" */
+#ifdef _MSC_VER
+#pragma warning( disable : 4100 )
+#endif
+
+int
+sem_open (const char *name, int oflag, mode_t mode, unsigned int value)
+{
+ errno = ENOSYS;
+ return -1;
+} /* sem_open */
diff --git a/pthreads/sem_post.c b/pthreads/sem_post.c
new file mode 100644
index 000000000..c7a7a3cf9
--- /dev/null
+++ b/pthreads/sem_post.c
@@ -0,0 +1,128 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_post.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+int
+sem_post (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function posts a wakeup to a semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * DESCRIPTION
+ * This function posts a wakeup to a semaphore. If there
+ * are waiting threads (or processes), one is awakened;
+ * otherwise, the semaphore value is incremented by one.
+ *
+ * RESULTS
+ * 0 successfully posted semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ * ERANGE semaphore count is too big
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = *sem;
+
+ if (s == NULL)
+ {
+ result = EINVAL;
+ }
+ else if ((result = pthread_mutex_lock (&s->lock)) == 0)
+ {
+ /* See sem_destroy.c
+ */
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ result = EINVAL;
+ return -1;
+ }
+
+ if (s->value < SEM_VALUE_MAX)
+ {
+#ifdef NEED_SEM
+ if (++s->value <= 0
+ && !SetEvent(s->sem))
+ {
+ s->value--;
+ result = EINVAL;
+ }
+#else
+ if (++s->value <= 0
+ && !ReleaseSemaphore (s->sem, 1, NULL))
+ {
+ s->value--;
+ result = EINVAL;
+ }
+#endif /* NEED_SEM */
+ }
+ else
+ {
+ result = ERANGE;
+ }
+
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+} /* sem_post */
diff --git a/pthreads/sem_post_multiple.c b/pthreads/sem_post_multiple.c
new file mode 100644
index 000000000..3d1e4ef28
--- /dev/null
+++ b/pthreads/sem_post_multiple.c
@@ -0,0 +1,142 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_post_multiple.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+int
+sem_post_multiple (sem_t * sem, int count)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function posts multiple wakeups to a semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * count
+ * counter, must be greater than zero.
+ *
+ * DESCRIPTION
+ * This function posts multiple wakeups to a semaphore. If there
+ * are waiting threads (or processes), n <= count are awakened;
+ * the semaphore value is incremented by count - n.
+ *
+ * RESULTS
+ * 0 successfully posted semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore
+ * or count is less than or equal to zero.
+ * ERANGE semaphore count is too big
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ long waiters;
+ sem_t s = *sem;
+
+ if (s == NULL || count <= 0)
+ {
+ result = EINVAL;
+ }
+ else if ((result = pthread_mutex_lock (&s->lock)) == 0)
+ {
+ /* See sem_destroy.c
+ */
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ result = EINVAL;
+ return -1;
+ }
+
+ if (s->value <= (SEM_VALUE_MAX - count))
+ {
+ waiters = -s->value;
+ s->value += count;
+ if (waiters > 0)
+ {
+#ifdef NEED_SEM
+ if (SetEvent(s->sem))
+ {
+ waiters--;
+ s->leftToUnblock += count - 1;
+ if (s->leftToUnblock > waiters)
+ {
+ s->leftToUnblock = waiters;
+ }
+ }
+#else
+ if (ReleaseSemaphore (s->sem, (waiters<=count)?waiters:count, 0))
+ {
+ /* No action */
+ }
+#endif
+ else
+ {
+ s->value -= count;
+ result = EINVAL;
+ }
+ }
+ }
+ else
+ {
+ result = ERANGE;
+ }
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+} /* sem_post_multiple */
diff --git a/pthreads/sem_timedwait.c b/pthreads/sem_timedwait.c
new file mode 100644
index 000000000..52146b478
--- /dev/null
+++ b/pthreads/sem_timedwait.c
@@ -0,0 +1,238 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_timedwait.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+typedef struct {
+ sem_t sem;
+ int * resultPtr;
+} sem_timedwait_cleanup_args_t;
+
+
+static void PTW32_CDECL
+ptw32_sem_timedwait_cleanup (void * args)
+{
+ sem_timedwait_cleanup_args_t * a = (sem_timedwait_cleanup_args_t *)args;
+ sem_t s = a->sem;
+
+ if (pthread_mutex_lock (&s->lock) == 0)
+ {
+ /*
+ * We either timed out or were cancelled.
+ * If someone has posted between then and now we try to take the semaphore.
+ * Otherwise the semaphore count may be wrong after we
+ * return. In the case of a cancellation, it is as if we
+ * were cancelled just before we return (after taking the semaphore)
+ * which is ok.
+ */
+ if (WaitForSingleObject(s->sem, 0) == WAIT_OBJECT_0)
+ {
+ /* We got the semaphore on the second attempt */
+ *(a->resultPtr) = 0;
+ }
+ else
+ {
+ /* Indicate we're no longer waiting */
+ s->value++;
+#ifdef NEED_SEM
+ if (s->value > 0)
+ {
+ s->leftToUnblock = 0;
+ }
+#else
+ /*
+ * Don't release the W32 sema, it doesn't need adjustment
+ * because it doesn't record the number of waiters.
+ */
+#endif
+ }
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+}
+
+
+int
+sem_timedwait (sem_t * sem, const struct timespec *abstime)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function waits on a semaphore possibly until
+ * 'abstime' time.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * abstime
+ * pointer to an instance of struct timespec
+ *
+ * DESCRIPTION
+ * This function waits on a semaphore. If the
+ * semaphore value is greater than zero, it decreases
+ * its value by one. If the semaphore value is zero, then
+ * the calling thread (or process) is blocked until it can
+ * successfully decrease the value or until interrupted by
+ * a signal.
+ *
+ * If 'abstime' is a NULL pointer then this function will
+ * block until it can successfully decrease the value or
+ * until interrupted by a signal.
+ *
+ * RESULTS
+ * 0 successfully decreased semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ * EINTR the function was interrupted by a signal,
+ * EDEADLK a deadlock condition was detected.
+ * ETIMEDOUT abstime elapsed before success.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = *sem;
+
+ pthread_testcancel();
+
+ if (sem == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ DWORD milliseconds;
+
+ if (abstime == NULL)
+ {
+ milliseconds = INFINITE;
+ }
+ else
+ {
+ /*
+ * Calculate timeout as milliseconds from current system time.
+ */
+ milliseconds = ptw32_relmillisecs (abstime);
+ }
+
+ 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)
+ {
+#ifdef NEED_SEM
+ int timedout;
+#endif
+ sem_timedwait_cleanup_args_t cleanup_args;
+
+ cleanup_args.sem = s;
+ cleanup_args.resultPtr = &result;
+
+#ifdef _MSC_VER
+#pragma inline_depth(0)
+#endif
+ /* Must wait */
+ pthread_cleanup_push(ptw32_sem_timedwait_cleanup, (void *) &cleanup_args);
+#ifdef NEED_SEM
+ timedout =
+#endif
+ result = pthreadCancelableTimedWait (s->sem, milliseconds);
+ pthread_cleanup_pop(result);
+#ifdef _MSC_VER
+#pragma inline_depth()
+#endif
+
+#ifdef NEED_SEM
+
+ if (!timedout && pthread_mutex_lock (&s->lock) == 0)
+ {
+ if (*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 /* NEED_SEM */
+
+ }
+ }
+
+ }
+
+ if (result != 0)
+ {
+
+ errno = result;
+ return -1;
+
+ }
+
+ return 0;
+
+} /* sem_timedwait */
diff --git a/pthreads/sem_trywait.c b/pthreads/sem_trywait.c
new file mode 100644
index 000000000..63614ba2b
--- /dev/null
+++ b/pthreads/sem_trywait.c
@@ -0,0 +1,117 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_trywait.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+int
+sem_trywait (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function tries to wait on a semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * DESCRIPTION
+ * This function tries to wait on a semaphore. If the
+ * semaphore value is greater than zero, it decreases
+ * its value by one. If the semaphore value is zero, then
+ * this function returns immediately with the error EAGAIN
+ *
+ * RESULTS
+ * 0 successfully decreased semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EAGAIN the semaphore was already locked,
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOTSUP sem_trywait is not supported,
+ * EINTR the function was interrupted by a signal,
+ * EDEADLK a deadlock condition was detected.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = *sem;
+
+ if (s == NULL)
+ {
+ result = EINVAL;
+ }
+ else if ((result = pthread_mutex_lock (&s->lock)) == 0)
+ {
+ /* See sem_destroy.c
+ */
+ if (*sem == NULL)
+ {
+ (void) pthread_mutex_unlock (&s->lock);
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (s->value > 0)
+ {
+ s->value--;
+ }
+ else
+ {
+ result = EAGAIN;
+ }
+
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+} /* sem_trywait */
diff --git a/pthreads/sem_unlink.c b/pthreads/sem_unlink.c
new file mode 100644
index 000000000..a6c6f81b0
--- /dev/null
+++ b/pthreads/sem_unlink.c
@@ -0,0 +1,58 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_unlink.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+/* ignore warning "unreferenced formal parameter" */
+#ifdef _MSC_VER
+#pragma warning( disable : 4100 )
+#endif
+
+int
+sem_unlink (const char *name)
+{
+ errno = ENOSYS;
+ return -1;
+} /* sem_unlink */
diff --git a/pthreads/sem_wait.c b/pthreads/sem_wait.c
new file mode 100644
index 000000000..d39d2b4b6
--- /dev/null
+++ b/pthreads/sem_wait.c
@@ -0,0 +1,187 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: sem_wait.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+static void PTW32_CDECL
+ptw32_sem_wait_cleanup(void * sem)
+{
+ sem_t s = (sem_t) sem;
+
+ if (pthread_mutex_lock (&s->lock) == 0)
+ {
+ /*
+ * If sema is destroyed do nothing, otherwise:-
+ * If the sema is posted between us being cancelled and us locking
+ * the sema again above then we need to consume that post but cancel
+ * anyway. If we don't get the semaphore we indicate that we're no
+ * longer waiting.
+ */
+ if (*((sem_t *)sem) != NULL && !(WaitForSingleObject(s->sem, 0) == WAIT_OBJECT_0))
+ {
+ ++s->value;
+#ifdef NEED_SEM
+ if (s->value > 0)
+ {
+ s->leftToUnblock = 0;
+ }
+#else
+ /*
+ * Don't release the W32 sema, it doesn't need adjustment
+ * because it doesn't record the number of waiters.
+ */
+#endif /* NEED_SEM */
+ }
+ (void) pthread_mutex_unlock (&s->lock);
+ }
+}
+
+int
+sem_wait (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function waits on a semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * DESCRIPTION
+ * This function waits on a semaphore. If the
+ * semaphore value is greater than zero, it decreases
+ * its value by one. If the semaphore value is zero, then
+ * the calling thread (or process) is blocked until it can
+ * successfully decrease the value or until interrupted by
+ * a signal.
+ *
+ * RESULTS
+ * 0 successfully decreased semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ * EINTR the function was interrupted by a signal,
+ * EDEADLK a deadlock condition was detected.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s = *sem;
+
+ pthread_testcancel();
+
+ 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)
+ {
+#ifdef _MSC_VER
+#pragma inline_depth(0)
+#endif
+ /* Must wait */
+ pthread_cleanup_push(ptw32_sem_wait_cleanup, (void *) s);
+ result = pthreadCancelableWait (s->sem);
+ /* Cleanup if we're canceled or on any other error */
+ pthread_cleanup_pop(result);
+#ifdef _MSC_VER
+#pragma inline_depth()
+#endif
+ }
+#ifdef NEED_SEM
+
+ if (!result && 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 /* NEED_SEM */
+
+ }
+
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+} /* sem_wait */
diff --git a/pthreads/semaphore.c b/pthreads/semaphore.c
new file mode 100644
index 000000000..6b2b10e85
--- /dev/null
+++ b/pthreads/semaphore.c
@@ -0,0 +1,69 @@
+/*
+ * -------------------------------------------------------------
+ *
+ * Module: semaphore.c
+ *
+ * Purpose:
+ * Concatenated version of separate modules to allow
+ * inlining optimisation, which it is assumed can only
+ * be effective within a single module.
+ *
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef NEED_FTIME
+# include <sys/timeb.h>
+#endif
+
+#include <limits.h>
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+#include "sem_init.c"
+#include "sem_destroy.c"
+#include "sem_trywait.c"
+#include "sem_wait.c"
+#include "sem_timedwait.c"
+#include "sem_post.c"
+#include "sem_post_multiple.c"
+#include "sem_getvalue.c"
+#include "sem_open.c"
+#include "sem_close.c"
+#include "sem_unlink.c"
diff --git a/pthreads/semaphore.h b/pthreads/semaphore.h
new file mode 100644
index 000000000..a3330a638
--- /dev/null
+++ b/pthreads/semaphore.h
@@ -0,0 +1,166 @@
+/*
+ * 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 DLL code, you should define PTW32_BUILD so that
+ * the variables/functions are exported correctly. When using the DLL,
+ * do NOT define PTW32_BUILD, and then the variables/functions will
+ * be imported correctly.
+ */
+#ifndef PTW32_STATIC_LIB
+# ifdef PTW32_BUILD
+# define PTW32_DLLPORT __declspec (dllexport)
+# else
+# define PTW32_DLLPORT __declspec (dllimport)
+# endif
+#else
+# define PTW32_DLLPORT
+#endif
+
+/*
+ * This is a duplicate of what is in the autoconf config.h,
+ * which is only used when building the pthread-win32 libraries.
+ */
+
+#ifndef PTW32_CONFIG_H
+# if defined(WINCE)
+# define NEED_ERRNO
+# define NEED_SEM
+# endif
+# if defined(_UWIN) || defined(__MINGW32__)
+# define HAVE_MODE_T
+# endif
+#endif
+
+/*
+ *
+ */
+
+#if PTW32_LEVEL >= PTW32_LEVEL_MAX
+#ifdef NEED_ERRNO
+#include "need_errno.h"
+#else
+#include <errno.h>
+#endif
+#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
+
+#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 */
diff --git a/pthreads/signal.c b/pthreads/signal.c
new file mode 100644
index 000000000..8f56c48b5
--- /dev/null
+++ b/pthreads/signal.c
@@ -0,0 +1,179 @@
+/*
+ * signal.c
+ *
+ * Description:
+ * Thread-aware signal 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
+ */
+
+/*
+ * Possible future strategy for implementing pthread_kill()
+ * ========================================================
+ *
+ * Win32 does not implement signals.
+ * Signals are simply software interrupts.
+ * pthread_kill() asks the system to deliver a specified
+ * signal (interrupt) to a specified thread in the same
+ * process.
+ * Signals are always asynchronous (no deferred signals).
+ * Pthread-win32 has an async cancelation mechanism.
+ * A similar system can be written to deliver signals
+ * within the same process (on ix86 processors at least).
+ *
+ * Each thread maintains information about which
+ * signals it will respond to. Handler routines
+ * are set on a per-process basis - not per-thread.
+ * When signalled, a thread will check it's sigmask
+ * and, if the signal is not being ignored, call the
+ * handler routine associated with the signal. The
+ * thread must then (except for some signals) return to
+ * the point where it was interrupted.
+ *
+ * Ideally the system itself would check the target thread's
+ * mask before possibly needlessly bothering the thread
+ * itself. This could be done by pthread_kill(), that is,
+ * in the signaling thread since it has access to
+ * all pthread_t structures. It could also retrieve
+ * the handler routine address to minimise the target
+ * threads response overhead. This may also simplify
+ * serialisation of the access to the per-thread signal
+ * structures.
+ *
+ * pthread_kill() eventually calls a routine similar to
+ * ptw32_cancel_thread() which manipulates the target
+ * threads processor context to cause the thread to
+ * run the handler launcher routine. pthread_kill() must
+ * save the target threads current context so that the
+ * handler launcher routine can restore the context after
+ * the signal handler has returned. Some handlers will not
+ * return, eg. the default SIGKILL handler may simply
+ * call pthread_exit().
+ *
+ * The current context is saved in the target threads
+ * pthread_t structure.
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+#if HAVE_SIGSET_T
+
+static void
+ptw32_signal_thread ()
+{
+}
+
+static void
+ptw32_signal_callhandler ()
+{
+}
+
+int
+pthread_sigmask (int how, sigset_t const *set, sigset_t * oset)
+{
+ pthread_t thread = pthread_self ();
+
+ if (thread.p == NULL)
+ {
+ return ENOENT;
+ }
+
+ /* Validate the `how' argument. */
+ if (set != NULL)
+ {
+ switch (how)
+ {
+ case SIG_BLOCK:
+ break;
+ case SIG_UNBLOCK:
+ break;
+ case SIG_SETMASK:
+ break;
+ default:
+ /* Invalid `how' argument. */
+ return EINVAL;
+ }
+ }
+
+ /* Copy the old mask before modifying it. */
+ if (oset != NULL)
+ {
+ memcpy (oset, &(thread.p->sigmask), sizeof (sigset_t));
+ }
+
+ if (set != NULL)
+ {
+ unsigned int i;
+
+ /* FIXME: this code assumes that sigmask is an even multiple of
+ the size of a long integer. */
+
+ unsigned long *src = (unsigned long const *) set;
+ unsigned long *dest = (unsigned long *) &(thread.p->sigmask);
+
+ switch (how)
+ {
+ case SIG_BLOCK:
+ for (i = 0; i < (sizeof (sigset_t) / sizeof (unsigned long)); i++)
+ {
+ /* OR the bit field longword-wise. */
+ *dest++ |= *src++;
+ }
+ break;
+ case SIG_UNBLOCK:
+ for (i = 0; i < (sizeof (sigset_t) / sizeof (unsigned long)); i++)
+ {
+ /* XOR the bitfield longword-wise. */
+ *dest++ ^= *src++;
+ }
+ case SIG_SETMASK:
+ /* Replace the whole sigmask. */
+ memcpy (&(thread.p->sigmask), set, sizeof (sigset_t));
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int
+sigwait (const sigset_t * set, int *sig)
+{
+ /* This routine is a cancellation point */
+ pthread_test_cancel();
+}
+
+int
+sigaction (int signum, const struct sigaction *act, struct sigaction *oldact)
+{
+}
+
+#endif /* HAVE_SIGSET_T */
diff --git a/pthreads/spin.c b/pthreads/spin.c
new file mode 100644
index 000000000..41b5aa525
--- /dev/null
+++ b/pthreads/spin.c
@@ -0,0 +1,46 @@
+/*
+ * spin.c
+ *
+ * Description:
+ * This translation unit implements spin 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 "pthread.h"
+#include "implement.h"
+
+
+#include "ptw32_spinlock_check_need_init.c"
+#include "pthread_spin_init.c"
+#include "pthread_spin_destroy.c"
+#include "pthread_spin_lock.c"
+#include "pthread_spin_unlock.c"
+#include "pthread_spin_trylock.c"
diff --git a/pthreads/sync.c b/pthreads/sync.c
new file mode 100644
index 000000000..5e56fa9a1
--- /dev/null
+++ b/pthreads/sync.c
@@ -0,0 +1,43 @@
+/*
+ * sync.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"
+
+
+#include "pthread_detach.c"
+#include "pthread_join.c"
diff --git a/pthreads/tests/Bmakefile b/pthreads/tests/Bmakefile
new file mode 100644
index 000000000..9a2c2b4bb
--- /dev/null
+++ b/pthreads/tests/Bmakefile
@@ -0,0 +1,350 @@
+# Makefile for the pthreads test suite.
+# If all of the .pass files can be created, the test suite has passed.
+#
+# --------------------------------------------------------------------------
+#
+# Pthreads-win32 - POSIX Threads Library for Win32
+# Copyright(C) 1998 John E. Bossom
+# Copyright(C) 1999,2005 Pthreads-win32 contributors
+#
+# Contact Email: rpj@callisto.canberra.edu.au
+#
+# The current list of contributors is contained
+# in the file CONTRIBUTORS included with the source
+# code distribution. The list can also be seen at the
+# following World Wide Web location:
+# http://sources.redhat.com/pthreads-win32/contributors.html
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library in the file COPYING.LIB;
+# if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+#
+
+DLL_VER = 2
+
+CP = copy
+RM = erase
+CAT = type
+MKDIR = mkdir
+TOUCH = echo Passed >
+ECHO = @echo
+
+QAPC = ..\QueueUserAPCEx\User\quserex.dll
+
+CPHDR = pthread.h semaphore.h sched.h
+
+OPTIM = -O2
+
+XXLIBS = 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 \
+ 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
+
+help:
+ @ $(ECHO) Run one of the following command lines:
+ @ $(ECHO) make clean BC (to test using BC dll with VC (no EH) applications)
+ @ $(ECHO) make clean BCX (to test using BC dll with VC++ (EH) applications)
+ @ $(ECHO) make clean BCE (to test using the BCE dll with VC++ EH applications)
+ @ $(ECHO) make clean BC-bench (to benchtest using BC dll with C bench app)
+ @ $(ECHO) make clean BCX-bench (to benchtest using BC dll with C++ bench app)
+ @ $(ECHO) make clean BCE-bench (to benchtest using BCE dll with C++ bench app)
+
+all:
+ @ make clean BC
+ @ make clean BCX
+ @ make clean BCE
+ @ make clean BC-bench
+
+# This allows an individual test application to be made using the default lib.
+# e.g. make clean test cancel3.exe
+test: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC)
+
+tests: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC) sizes.pass $(PASSES)
+ @ $(ECHO) ALL TESTS PASSED! Congratulations!
+
+benchtests: $(CPLIB) $(CPDLL) $(CPHDR) $(BENCHRESULTS)
+ @ $(ECHO) ALL BENCH TESTS DONE.
+
+sizes.pass: sizes.exe
+ @ $(ECHO) ... Running $(TEST) test: $*.exe
+ @ .\$*.exe > SIZES.$(TEST)
+ @ $(CAT) SIZES.$(TEST)
+ @ $(ECHO) ...... Passed
+ @ $(TOUCH) $*.pass
+
+BCE:
+ @ make -f Bmakefile TEST="$@" CPLIB="$(BCELIB)" CPDLL="$(BCEDLL)" EHFLAGS="$(BCEFLAGS)" tests
+
+BC:
+ @ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCFLAGS)" tests
+
+BCX:
+ @ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCXFLAGS)" tests
+
+BCE-bench:
+ @ make -f Bmakefile TEST="$@" CPLIB="$(BCELIB)" CPDLL="$(BCEDLL)" EHFLAGS="$(BCEFLAGS)" XXLIBS="benchlib.o" benchtests
+
+BC-bench:
+ @ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCFLAGS)" XXLIBS="benchlib.o" benchtests
+
+BCX-bench:
+ @ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCXFLAGS)" XXLIBS="benchlib.o" benchtests
+
+.exe.pass:
+ @ $(ECHO) ... Running $(TEST) test: $<
+ @ .\$<
+ @ $(ECHO) ...... Passed
+ @ $(TOUCH) $@
+
+.exe.bench:
+ @ $(ECHO) ... Running $(TEST) benchtest: $<
+ @ .\$<
+ @ $(ECHO) ...... Done
+ @ $(TOUCH) $@
+
+.c.exe:
+ @ $(ECHO) $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< -e$@ $(LFLAGS) $(CPLIB) $(XXLIBS)
+ @ $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< -e$@ $(LFLAGS) $(CPLIB) $(XXLIBS)
+
+.c.o:
+ @ $(ECHO) $(CC) $(EHFLAGS) -c $(CFLAGS) $(INCLUDES) $< -o$@
+ @ $(CC) $(EHFLAGS) $(CFLAGS) -c $(INCLUDES) $< -o$@
+
+
+.c.i:
+ @ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $<
+
+$(COPYFILES):
+ @ $(ECHO) Copying $@
+ @ $(CP) $(BUILD_DIR)\$@ .
+
+pthread.dll: $(CPDLL)
+ @ $(CP) $(CPDLL) pthread.dll
+ @ $(CP) $(CPLIB) pthread.lib
+
+clean:
+ - $(RM) *.dll
+ - $(RM) *.lib
+ - $(RM) pthread.h
+ - $(RM) semaphore.h
+ - $(RM) sched.h
+ - $(RM) *.e
+ - $(RM) *.i
+ - $(RM) *.obj
+ - $(RM) *.tds
+ - $(RM) *.pdb
+ - $(RM) *.o
+ - $(RM) *.asm
+ - $(RM) *.exe
+ - $(RM) *.pass
+ - $(RM) *.bench
+ - $(RM) *.log
+
+benchtest1.bench:
+benchtest2.bench:
+benchtest3.bench:
+benchtest4.bench:
+benchtest5.bench:
+barrier1.pass: semaphore4.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
+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
diff --git a/pthreads/tests/ChangeLog b/pthreads/tests/ChangeLog
new file mode 100644
index 000000000..6b2c74250
--- /dev/null
+++ b/pthreads/tests/ChangeLog
@@ -0,0 +1,894 @@
+2005-06-12 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * 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 <rpj@callisto.canberra.edu.au>
+
+ * 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 <rpj@callisto.canberra.edu.au>
+
+ * 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 <rpj@callisto.canberra.edu.au>
+
+ * condvar3.c: Remove locks from around signalling calls - should not
+ be required for normal operation and only serve to mask deficiencies;
+ ensure that CV destruction is not premature after removing guards.
+ * condvar3_1.c: Likewise.
+ * condvar3_2.c: Likewise.
+ * condvar3_3.c: Likewise.
+ * condvar4.c: Likewise.
+ * condvar5.c: Likewise.
+ * condvar6.c: Likewise.
+ * condvar7.c: Likewise.
+ * condvar8.c: Likewise.
+ * condvar9.c: Likewise.
+
+2005-04-11 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * once4.c: New test; tries to test priority adjustments
+ in pthread_once(); set priority class to realtime so that
+ any failures can be seen.
+
+2005-04-06 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * cleanup0.c: Fix unguarded global variable accesses.
+ * cleanup1.c: Likewise.
+ * cleanup2.c: Likewise.
+ * cleanup3.c: Likewise.
+ * once2.c: Likewise.
+ * once3.c: Likewise.
+
+2005-04-01 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * GNUmakefile: Add target to test linking static link library.
+ * Makefile: Likewise.
+ * self1.c: Run process attach/detach routines when static linked.
+
+2005-03-16 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * mutex5.c: Prevent optimiser from removing asserts.
+
+2005-03-12 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * once3.c: New test.
+
+2005-03-08 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * once2.c: New test.
+
+2004-11-19 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * Bmakefile: New makefile for Borland.
+ * Makefile (DLL_VER): Added.
+ * GNUmakefile (DLL_VER): Added.
+ * Wmakefile (DLL_VER): Added.
+
+2004-10-29 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * semaphore4.c: New test.
+ * semaphore4t.c: New test.
+ * Debug.dsp (et al): Created MSVC Workspace project to aid debugging.
+ * All: Many tests have been modified to work with the new pthread
+ ID type; some other corrections were made after some library
+ functions were semantically strengthened. For example,
+ pthread_cond_destroy() no longer destroys a busy CV, which
+ required minor redesigns of some tests, including some where
+ the mutex associated with the CV was not locked during
+ signaling and broadcasting.
+
+2004-10-23 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * condvar3.c: Fixed mutex operations that were incorrectly
+ placed in relation to their condition variable operations.
+ The error became evident after sem_destroy() was rewritten
+ and conditions for destroing the semaphore were tightened.
+ As a result, pthread_cond_destroy() was not able to
+ destroy the cv queueing sempahore.
+ * condvar3_1.c: Likewise.
+ * condvar3_2.c: Likewise.
+ * condvar4.c: Likewise.
+ * condvar5.c: Likewise.
+ * condvar6.c: Likewise.
+ * condvar7.c: Likewise.
+ * condvar8.c: Likewise.
+ * condvar9.c: Likewise.
+
+2004-10-19 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * semaphore3.c: New test.
+
+2004-10-14 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * rwlock7.c (main): Tidy up statistics reporting; randomise
+ update accesses.
+ * rwlock8.c: New test.
+
+2004-09-08 Alexandre Girao <alexgirao@gmail.com>
+
+ * cancel7.c (main): Win98 wants a valid (non-NULL) location
+ for the last arg of _beginthreadex().
+ * cancel8.c (main): Likewise.
+ * exit4.c (main): Likewise.
+ * exit5.c (main): Likewise.
+
+2004-08-26 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * create3.c: New test.
+
+2004-06-21 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * mutex2r.c: New test.
+ * mutex2e.c: New test.
+ * mutex3r.c: New test.
+ * mutex3e.c: New test.
+ * mutex6s.c: New test.
+ * mutex6rs.c: New test.
+ * mutex6es.c: New test.
+
+2004-05-21 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * join3.c: New test.
+
+2004-05-16 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * condvar2.c (WIN32_WINNT): Define to avoid redefinition warning
+ from inclusion of implement.h.
+ * convar2_1.c: Likewise.
+ * condvar3_1.c: Likewise.
+ * condvar3_2.c: Likewise.
+ * context1.c: Likewise.
+ * sizes.c: Likewise.
+ * Makefile: Don't define _WIN32_WINNT on compiler command line.
+ * GNUmakefile: Likewise.
+ * priority1.c (main): Add column to output for actual win32
+ priority.
+
+2004-05-16 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * cancel9.c: New test.
+ * cancel3.c: Remove inappropriate conditional compilation;
+ GNU C version of test suite no longer quietly skips this test.
+ * cancel5.c: Likewise.
+ * GNUmakefile: Can now build individual test app using default
+ C version of library using 'make clean testname.c'.
+ * Makefile: Likewise for VC using 'nmake clean test testname.c'.
+
+2003-10-14 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * Wmakefile: New makefile for Watcom testing.
+
+2003-09-18 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * benchtest.h: Move old mutex code into benchlib.c.
+ * benchlib.c: New statically linked module to ensure that
+ bench apps don't inline the code and therefore have an unfair
+ advantage over the pthreads lib routines. Made little or no
+ difference.
+ * benchtest1.c: Minor change to avoid compiler warnings.
+ * benchtest5.c: Likewise.
+ * benchtest2.c: Fix misinformation in output report.
+ * README.BENCH: Add comments on results.
+
+2003-09-14 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * priority1.c: Reworked to comply with modified priority
+ management and provide additional output.
+ * priority2.c: Likewise.
+ * inherit1.c: Likewise.
+
+2003-09-03 Ross Johnson <rpj@callisto.canberra.edu.au>
+
+ * exit4.c: New test.
+ * exit5.c: New test.
+ * cancel7.c: New test.
+ * cancel8.c: New test.
+
+2003-08-13 Ross Johnson <rpj@ise.canberra.edu.au>
+
+ * reuse1.c: New test.
+ * reuse1.c: New test.
+ * valid1.c: New test.
+ * valid2.c: New test.
+ * kill1.c: New test.
+ * create2.c: Now included in test regime.
+
+2003-07-19 Ross Johnson <rpj@ise.canberra.edu.au>
+
+ * eyal1.c (waste_time): Make threads do more work to ensure that
+ all threads get to do some work.
+ * semaphore1.c: Make it clear that certain errors are expected.
+ * exception2.c (non_MSVC code sections): Change to include
+ C++ standard include file, i.e. change <new.h> to <exception>.
+ * exception3.c (non_MSVC code sections): Likewise; qualify std::
+ namespace entities where necessary.
+ * GNUmakefile: modified to work in the MsysDTK (newer MinGW)
+ environment; define CC as gcc or g++ as appropriate because
+ using gcc -x c++ doesn't link with required c++ libs by default,
+ but g++ does.
+
+2002-12-11 Ross Johnson <ross@special.ise.canberra.edu.au>
+
+ * mutex7e.c: Assert EBUSY return instead of EDEADLK.
+
+2002-06-03 Ross Johnson <rpj@digit.ise.canberra.edu.au>
+
+ * semaphore2.c: New test.
+
+2002-03-02 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * Makefile (CFLAGS): Changed /MT to /MD to link with
+ the correct library MSVCRT.LIB. Otherwise errno doesn't
+ work.
+
+2002-02-28 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * exception3.c: Correct recent change.
+
+ * semaphore1.c: New test.
+
+ * Makefile: Add rule to generate pre-processor output.
+
+2002-02-28 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * exception3.c (terminateFunction): For MSVC++, call
+ exit() rather than pthread_exit(). Add comments to explain
+ why.
+ * Notes from the MSVC++ manual:
+ * 1) A term_func() should call exit(), otherwise
+ * abort() will be called on return to the caller.
+ * abort() raises SIGABRT. The default signal handler
+ * for all signals terminates the calling program with
+ * exit code 3.
+ * 2) A term_func() must not throw an exception. Therefore
+ * term_func() should not call pthread_exit() if an
+ * an exception-using version of pthreads-win32 library
+ * is being used (i.e. either pthreadVCE or pthreadVSE).
+
+
+2002-02-23 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * rwlock2_t.c: New test.
+ * rwlock3_t.c: New test.
+ * rwlock4_t.c: New test.
+ * rwlock5_t.c: New test.
+ * rwlock6_t.c: New test.
+ * rwlock6_t2.c: New test.
+ * rwlock6.c (main): Swap thread and result variables
+ to correspond to actual thread functions.
+ * rwlock1.c: Change test description comment to correspond
+ to the actual test.
+
+ * condvar1_2.c: Loop over the test many times in the hope
+ of detecting any intermittent deadlocks. This is to
+ test a fixed problem in pthread_cond_destroy.c.
+
+ * spin4.c: Remove unused variable.
+
+2002-02-17 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * condvar1_1.c: New test.
+ * condvar1_2.c: New test.
+
+2002-02-07 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * delay1.c: New test.
+ * delay2.c: New test.
+ * exit4.c: New test.
+
+2002-02-02 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * mutex8: New test.
+ * mutex8n: New test.
+ * mutex8e: New test.
+ * mutex8r: New test.
+ * cancel6a: New test.
+ * cancel6d: New test.
+ * cleanup0.c: Add pragmas for inline optimisation control.
+ * cleanup1.c: Add pragmas for inline optimisation control.
+ * cleanup2.c: Add pragmas for inline optimisation control.
+ * cleanup3.c: Add pragmas for inline optimisation control.
+ * condvar7.c: Add pragmas for inline optimisation control.
+ * condvar8.c: Add pragmas for inline optimisation control.
+ * condvar9.c: Add pragmas for inline optimisation control.
+
+2002-01-30 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * cleanup1.c (): Must be declared __cdecl when compiled
+ as C++ AND testing the standard C library version.
+
+2002-01-16 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * spin4.c (main): Fix renamed function call.
+
+2002-01-14 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * exception3.c (main): Shorten wait time.
+
+2002-01-09 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * mutex7.c: New test.
+ * mutex7n.c: New test.
+ * mutex7e.c: New test.
+ * mutex7r.c: New test.
+ * mutex6.c: Modified to avoid leaving the locked mutex
+ around on exit.
+
+2001-10-25 Ross Johnson <rpj@setup1.ise.canberra.edu.au>
+
+ * condvar2.c: Remove reference to cv->nWaitersUnblocked.
+ * condvar2_1.c: Likewise; lower NUMTHREADS from 60 to 30.
+ * condvar3_1.c: Likewise.
+ * condvar3_2.c: Likewise.
+ * count1.c: lower NUMTHREADS from 60 to 30.
+ * inherit1.c: Determine valid priority values and then
+ assert values returned by POSIX routines are the same.
+ * priority1.c: Likewise.
+ * priority2.c: Likewise.
+
+2001-07-12 Ross Johnson <rpj@setup1.ise.canberra.edu.au>
+
+ * barrier5.c: Assert that precisely one thread receives
+ PTHREAD_BARRIER_SERIAL_THREAD at each barrier.
+
+2001-07-09 Ross Johnson <rpj@setup1.ise.canberra.edu.au>
+
+ * barrier3.c: Fixed.
+ * barrier4.c: Fixed.
+ * barrier5.c: New; proves that all threads in the group
+ reaching the barrier wait and then resume together. Repeats the test
+ using groups of 1 to 16 threads. Each group of threads must negotiate
+ a large number of barriers (10000).
+ * spin4.c: Fixed.
+ * test.h (error_string): Modified the success (0) value.
+
+2001-07-07 Ross Johnson <rpj@setup1.ise.canberra.edu.au>
+
+ * spin3.c: Changed test and fixed.
+ * spin4.c: Fixed.
+ * barrier3.c: Fixed.
+ * barrier4.c: Fixed.
+
+2001-07-05 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * spin1.c: New; testing spinlocks.
+ * spin2.c: New; testing spinlocks.
+ * spin3.c: New; testing spinlocks.
+ * spin4.c: New; testing spinlocks.
+ * barrier1.c: New; testing barriers.
+ * barrier2.c: New; testing barriers.
+ * barrier3.c: New; testing barriers.
+ * barrier4.c: New; testing barriers.
+ * GNUmakefile: Add new tests.
+ * Makefile: Add new tests.
+
+2001-07-01 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * benchtest3.c: New; timing mutexes.
+ * benchtest4.c: New; time mutexes.
+ * condvar3_1.c: Fixed bug - Alexander Terekhov
+ * condvar3_3.c: New test.
+
+2001-06-25 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * priority1.c: New test.
+ * priority2.c: New test.
+ * inherit1.c: New test.
+ * benchtest1.c: New; timing mutexes.
+ * benchtest2.c: New; timing mutexes.
+ * mutex4.c: Modified to test all mutex types.
+
+2001-06-8 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * mutex5.c: Insert inert change to quell compiler warnings.
+ * condvar3_2.c: Remove unused variable.
+
+2001-06-3 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * condvar2_1.c: New test.
+ * condvar3_1.c: New test.
+ * condvar3_2.c: New test.
+
+2001-05-30 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * mutex1n.c: New test.
+ * mutex1e.c: New test.
+ * mutex1r.c: New test.
+ * mutex4.c: Now locks and unlocks a mutex.
+ * mutex5.c: New test.
+ * mutex6.c: New test.
+ * mutex6n.c: New test.
+ * mutex6e.c: New test.
+ * mutex6r.c: New test.
+ * Makefile: Added new tests; reorganised.
+ * GNUmakefile: Likewise.
+ * rwlock6.c: Fix to properly prove read-while-write locking
+ and single writer locking.
+
+2001-05-29 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * Makefile: Reorganisation.
+ * GNUmakefile: Likewise.
+ - Thomas Pfaff <tpfaff@gmx.net>
+
+ * exception1.c: Add stdio.h include to define fprintf and stderr
+ in non-exception C version of main().
+ * exception2.c: Likewise.
+ * exception3.c: Likewise.
+
+ * Makefile (rwlock7): Add new test.
+ * GNUmakefile (rwlock7): Add new test.
+ * rwlock7.c: New test.
+ * rwlock6.c: Changed to test that writer has priority.
+
+ * eyal1.c (main): Unlock each mutex_start lock before destroying
+ it.
+
+2000-12-29 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * GNUmakefile: Add mutex4 test; ensure libpthreadw32.a is
+ removed for "clean" target.
+ * Makefile: Add mutex4 test.
+
+ * exception3.c: Remove SEH code; automatically pass the test
+ under SEH (which is an N/A environment).
+
+ * mutex4.c: New test.
+
+ * eyal1.c (do_work_unit): Add a dummy "if" to force the
+ optimiser to retain code; reduce thread work loads.
+
+ * condvar8.c (main): Add an additional "assert" for debugging;
+ increase pthread_cond_signal timeout.
+
+2000-12-28 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * eyal1.c: Increase thread work loads.
+ * exception2.c: New test.
+ * exception3.c: New test.
+ * Makefile: Add new tests exception2.c and exception3.c.
+ * GNUmakefile: Likewise.
+
+2000-12-11 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * cleanup3.c: Remove unused variable.
+ * cleanup2.c: Likewise.
+ * exception1.c: Throw an exception rather than use
+ a deliberate zero divide so that catch(...) will
+ handle it under Mingw32. Mingw32 now builds the
+ library correctly to pass all tests - see Thomas
+ Pfaff's detailed instructions re needed changes
+ to Mingw32 in the Pthreads-Win32 FAQ.
+
+2000-09-08 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * cancel5.c: New; tests calling pthread_cancel()
+ from the main thread without first creating a
+ POSIX thread struct for the non-POSIX main thread
+ - this forces pthread_cancel() to create one via
+ pthread_self().
+ * Makefile (cancel5): Add new test.
+ * GNUmakefile (cancel5): Likewise.
+
+2000-08-17 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * create2.c: New; Test that pthread_t contains
+ the W32 HANDLE before it calls the thread routine
+ proper.
+
+2000-08-13 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * condvar3.c: Minor change to eliminate compiler
+ warning.
+
+ * condvar4.c: ditto.
+
+ * condvar5.c: ditto.
+
+ * condvar6.c: ditto.
+
+ * condvar7.c: ditto.
+
+ * condvar8.c: ditto.
+
+ * condvar9.c: ditto.
+
+ * exit1.c: Function needed return statement.
+
+ * cleanup1.c: Remove unnecessary printf arg.
+
+ * cleanup2.c: Fix cast.
+
+ * rwlock6.c: Fix casts.
+
+ * exception1.c (PtW32CatchAll): Had the wrong name;
+ fix casts.
+
+ * cancel3.c: Remove unused waitLock variable.
+
+ * GNUmakefile: Change library/dll naming; add new tests;
+ general minor changes.
+
+ * Makefile: Change library/dll naming; add targets for
+ testing each of the two VC++ EH scheme versions;
+ default target now issues help message; compile warnings
+ now interpreted as errors to stop the make; add new
+ tests; restructure to remove prerequisites needed
+ otherwise.
+
+ * README: Updated.
+
+
+2000-08-10 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * eyal1.c (main): Change implicit cast to explicit
+ cast when passing "print_server" function pointer;
+ G++ no longer allows implicit func parameter casts.
+
+ * cleanup1.c: Remove unused "waitLock".
+ (main): Fix implicit parameter cast.
+
+ * cancel2.c (main): Fix implicit parameter cast.
+
+ * cancel4.c (main): Fix implicit parameter cast.
+
+ * cancel3.c (main): Fix implicit parameter cast.
+
+ * GNUmakefile: Renamed from Makefile; Add missing
+ cancel1 and cancel2 test targets.
+
+ * Makefile: Converted for use with MS nmake.
+
+2000-08-06 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * ccl.bat: Add /nologo to remove extraneous output.
+
+ * exception1.c (exceptionedThread): Init 'dummy';
+ put expression into if condition to prevent optimising away;
+ remove unused variable.
+
+ * cancel4.c (mythread): Cast return value to avoid warnings.
+
+ * cancel2.c (mythread): Missing #endif.
+
+ * condvar9.c (mythread): Cast return value to avoid warnings.
+
+ * condvar8.c (mythread): Cast return value to avoid warnings.
+
+ * condvar7.c (mythread): Cast return value to avoid warnings.
+
+ * cleanup3.c (mythread): Cast return value to avoid warnings.
+
+ * cleanup2.c (mythread): Cast return value to avoid warnings.
+
+ * cleanup1.c (mythread): Cast return value to avoid warnings.
+
+ * condvar5.c (mythread): Cast return value to avoid warnings.
+
+ * condvar3.c (mythread): Cast return value to avoid warnings.
+
+ * condvar6.c (mythread): Cast return value to avoid warnings.
+
+ * condvar4.c (mythread): Cast return value to avoid warnings.
+
+2000-08-05 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * cancel2.c: Use PtW32CatchAll macro if defined.
+
+ * exception1.c: Use PtW32CatchAll macro if defined.
+
+2000-08-02 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * tsd1.c: Fix typecasts of &result [g++ is now very fussy].
+
+ * test.h (assert): Return 0's explicitly to allay
+ g++ errors.
+
+ * join2.c: Add explicit typecasts.
+
+ * join1.c: Add explicit typecasts.
+
+ * join0.c: Add explicit typecasts.
+
+ * eyal1.c: Add explicit typecasts.
+
+ * count1.c (main): Add type cast to remove g++ parse warning
+ [gcc-2.95.2 seems to have tightened up on this].
+
+ * Makefile (GLANG): Use c++ explicitly.
+ Remove MSVC sections (was commented out).
+ Add target to generate cpp output.
+
+2000-07-25 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * runtest.bat: modified to work under W98.
+
+ * runall.bat: Add new tests; modified to work under W98.
+ It was ok under NT.
+
+ * Makefile: Add new tests.
+
+ * exception1.c: New; Test passing exceptions back to the
+ application and retaining library internal exceptions.
+
+ * join0.c: New; Test a single join.
+
+2000-01-06 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * cleanup1.c: New; Test cleanup handler executes (when thread is
+ canceled).
+
+ * cleanup2.c: New; Test cleanup handler executes (when thread is
+ not canceled).
+
+ * cleanup3.c: New; Test cleanup handler does not execute
+ (when thread is not canceled).
+
+2000-01-04 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * cancel4.c: New; Test cancelation does not occur in deferred
+ cancelation threads with no cancelation points.
+
+ * cancel3.c: New; Test asynchronous cancelation.
+
+ * context1.c: New; Test context switching method for async
+ cancelation.
+
+1999-11-23 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * test.h: Add header includes; include local header versions rather
+ than system versions; rearrange the assert macro defines.
+
+1999-11-07 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * loadfree.c: New. Test loading and freeing the library (DLL).
+
+1999-10-30 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * cancel1.c: New. Test pthread_setcancelstate and
+ pthread_setcanceltype functions.
+ * eyal1.c (waste_time): Change calculation to avoid FP exception
+ on Aplhas
+ - Rich Peters <rpeters@micro-magic.com>
+
+Oct 14 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * condvar7.c: New. Test broadcast after waiting thread is canceled.
+ * condvar8.c: New. Test multiple broadcasts.
+ * condvar9.c: New. Test multiple broadcasts with thread
+ cancelation.
+
+Sep 16 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * rwlock6.c: New test.
+
+Sep 15 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * rwlock1.c: New test.
+ * rwlock2.c: New test.
+ * rwlock3.c: New test.
+ * rwlock4.c: New test.
+ * rwlock5.c: New test.
+
+Aug 22 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * runall.bat (join2): Add test.
+
+Aug 19 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * join2.c: New test.
+
+Wed Aug 12 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * Makefile (LIBS): Add -L.
+
+Mon May 31 10:25:01 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * Makefile (GLANG): Add GCC language option.
+
+Sat May 29 23:29:04 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * runall.bat (condvar5): Add new test.
+
+ * runall.bat (condvar6): Add new test.
+
+ * Makefile (condvar5) : Add new test.
+
+ * Makefile (condvar6) : Add new test.
+
+ * condvar5.c: New test for pthread_cond_broadcast().
+
+ * condvar6.c: New test for pthread_cond_broadcast().
+
+Sun Apr 4 12:04:28 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * tsd1.c (mythread): Change Sleep(0) to sched_yield().
+ (sched.h): Include.
+
+ * condvar3.c (mythread): Remove redundant Sleep().
+
+ * runtest.bat: Re-organised to make more informative.
+
+Fri Mar 19 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * *.bat: redirect unwanted output to nul:
+
+ * runall.bat: new.
+
+ * cancel1.c: new. Not part of suite yet.
+
+Mon Mar 15 00:17:55 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * mutex1.c: only test mutex init and destroy; add assertions.
+
+ * count1.c: raise number of spawned threads to 60 (appears to
+ be the limit under Win98).
+
+Sun Mar 14 21:31:02 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * test.h (assert): add assertion trace option.
+ Use:
+ "#define ASSERT_TRACE 1" to turn it on,
+ "#define ASSERT_TRACE 0" to turn it off (default).
+
+ * condvar3.c (main): add more assertions.
+
+ * condvar4.c (main): add more assertions.
+
+ * condvar1.c (main): add more assertions.
+
+Fri Mar 12 08:34:15 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * condvar4.c (cvthing): switch the order of the INITIALIZERs.
+
+ * eyal1.c (main): Fix trylock loop; was not waiting for thread to lock
+ the "started" mutex.
+
+Wed Mar 10 10:41:52 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * tryentercs.c: Apply typo patch from bje.
+
+ * tryentercs2.c: Ditto.
+
+Sun Mar 7 10:41:52 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * Makefile (condvar3, condvar4): Add tests.
+
+ * condvar4.c (General): Reduce to simple test case; prerequisite
+ is condvar3.c; add description.
+
+ * condvar3.c (General): Reduce to simple test case; prerequisite
+ is condvar2.c; add description.
+
+ * condvar2.c (General): Reduce to simple test case; prerequisite
+ is condvar1.c; add description.
+
+ * condvar1.c (General): Reduce to simple test case; add
+ description.
+
+ * Template.c (Comments): Add generic test detail.
+
+1999-02-23 Ross Johnson <rpj@ise.canberra.edu.au>
+
+ * Template.c: Revamp.
+
+ * condvar1.c: Add.
+
+ * condvar2.c: Add.
+
+ * Makefile: Add condvar1 condvar2 tests.
+
+ * exit1.c, exit2.c, exit3.c: Cosmetic changes.
+
+1999-02-23 Ross Johnson <rpj@ise.canberra.edu.au>
+
+ * Makefile: Some refinement.
+
+ * *.c: More exhaustive checking through assertions; clean up;
+ add some more tests.
+
+ * Makefile: Now actually runs the tests.
+
+ * tests.h: Define our own assert macro. The Mingw32
+ version pops up a dialog but we want to run non-interactively.
+
+ * equal1.c: use assert a little more directly so that it
+ prints the actual call statement.
+
+ * exit1.c: Modify to return 0 on success, 1 on failure.
+
+1999-02-22 Ross Johnson <rpj@ise.canberra.edu.au>
+
+ * self2.c: Bring up to date.
+
+ * self3.c: Ditto.
+
+1999-02-21 Ben Elliston <bje@cygnus.com>
+
+ * README: Update.
+
+ * Makefile: New file. Run all tests automatically. Primitive tests
+ are run first; more complex tests are run last.
+
+ * count1.c: New test. Validate the thread count.
+
+ * exit2.c: Perform a simpler test.
+
+ * exit3.c: New test. Replaces exit2.c, since exit2.c needs to
+ perform simpler checking first.
+
+ * create1.c: Update to use the new testsuite exiting convention.
+
+ * equal1.c: Likewise.
+
+ * mutex1.c: Likewise.
+
+ * mutex2.c: Likewise.
+
+ * once1.c: Likewise.
+
+ * self2.c: Likewise.
+
+ * self3.c: Likewise.
+
+ * tsd1.c: Likewise.
+
+1999-02-20 Ross Johnson <rpj@ise.canberra.edu.au>
+
+ * mutex2.c: Test static mutex initialisation.
+
+ * test.h: New. Declares a table mapping error numbers to
+ error names.
+
+1999-01-17 Ross Johnson <rpj@ise.canberra.edu.au>
+
+ * runtest: New script to build and run a test in the tests directory.
+
+Wed Dec 30 11:22:44 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * tsd1.c: Re-written. See comments at start of file.
+ * Template.c: New. Contains skeleton code and comment template
+ intended to fully document the test.
+
+Fri Oct 16 17:59:49 1998 Ross Johnson <rpj@swan.canberra.edu.au>
+
+ * tsd1.c (destroy_key): Add function. Change diagnostics.
+
+Thu Oct 15 17:42:37 1998 Ross Johnson <rpj@swan.canberra.edu.au>
+
+ * tsd1.c (mythread): Fix some casts and add some message
+ output. Fix inverted conditional.
+
+Mon Oct 12 02:12:29 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * tsd1.c: New. Test TSD using 1 key and 2 threads.
+
+1998-09-13 Ben Elliston <bje@cygnus.com>
+
+ * eyal1.c: New file; contributed by Eyal Lebedinsky
+ <eyal@eyal.emu.id.au>.
+
+1998-09-12 Ben Elliston <bje@cygnus.com>
+
+ * exit2.c (func): Return a value.
+ (main): Call the right thread entry function.
+
+1998-07-22 Ben Elliston <bje@cygnus.com>
+
+ * exit2.c (main): Fix size of pthread_t array.
+
+1998-07-10 Ben Elliston <bje@cygnus.com>
+
+ * exit2.c: New file; test pthread_exit() harder.
+
+ * exit1.c: New file; test pthread_exit().
diff --git a/pthreads/tests/Debug.dsp b/pthreads/tests/Debug.dsp
new file mode 100644
index 000000000..191b97862
--- /dev/null
+++ b/pthreads/tests/Debug.dsp
@@ -0,0 +1,93 @@
+# Microsoft Developer Studio Project File - Name="Debug" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Debug - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Debug.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Debug.mak" CFG="Debug - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Debug - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "Debug - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Debug - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0xc09 /d "NDEBUG"
+# ADD RSC /l 0xc09 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "Debug - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /ZI /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "CLEANUP_C" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0xc09 /d "_DEBUG"
+# ADD RSC /l 0xc09 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib pthreadVC2d.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:".."
+
+!ENDIF
+
+# Begin Target
+
+# Name "Debug - Win32 Release"
+# Name "Debug - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\Debug.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\semaphore1.c
+# End Source File
+# End Target
+# End Project
diff --git a/pthreads/tests/Debug.dsw b/pthreads/tests/Debug.dsw
new file mode 100644
index 000000000..5fd6af3e5
--- /dev/null
+++ b/pthreads/tests/Debug.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Debug"=.\Debug.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/pthreads/tests/Debug.txt b/pthreads/tests/Debug.txt
new file mode 100644
index 000000000..5323874f4
--- /dev/null
+++ b/pthreads/tests/Debug.txt
@@ -0,0 +1,6 @@
+This project is used to debug individual test case programs.
+
+To build and debug a test case:
+- add the .c file to this project;
+- remove any .c files from other test cases from this project.
+- build and debug as usual. \ No newline at end of file
diff --git a/pthreads/tests/GNUmakefile b/pthreads/tests/GNUmakefile
new file mode 100644
index 000000000..1762b6c7c
--- /dev/null
+++ b/pthreads/tests/GNUmakefile
@@ -0,0 +1,375 @@
+# Makefile for the pthreads test suite.
+# If all of the .pass files can be created, the test suite has passed.
+#
+# --------------------------------------------------------------------------
+#
+# Pthreads-win32 - POSIX Threads Library for Win32
+# Copyright(C) 1998 John E. Bossom
+# Copyright(C) 1999,2005 Pthreads-win32 contributors
+#
+# Contact Email: rpj@callisto.canberra.edu.au
+#
+# The current list of contributors is contained
+# in the file CONTRIBUTORS included with the source
+# code distribution. The list can also be seen at the
+# following World Wide Web location:
+# http://sources.redhat.com/pthreads-win32/contributors.html
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library in the file COPYING.LIB;
+# if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+#
+
+DLL_VER = 2
+
+CP = cp -f
+MV = mv -f
+RM = rm -f
+CAT = cat
+#CP = copy
+#MV = rename
+#RM = erase
+#CAT = type
+MKDIR = mkdir
+TOUCH = echo Passed >
+ECHO = @echo
+MAKE = make
+
+#
+# Mingw32
+#
+XXCFLAGS =
+XXLIBS = -lws2_32
+#CFLAGS = -O3 -UNDEBUG -Wall $(XXCFLAGS)
+CFLAGS = -g -UNDEBUG -Wall $(XXCFLAGS)
+BUILD_DIR = ..
+INCLUDES = -I.
+
+
+TEST = GC
+
+# Default lib version
+GCX = $(TEST)$(DLL_VER)
+
+# Files we need to run the tests
+# - paths are relative to pthreads build dir.
+HDR = pthread.h semaphore.h sched.h
+LIB = libpthread$(GCX).a
+DLL = pthread$(GCX).dll
+QAPC = ../QueueUserAPCEx/User/quserex.dll
+
+COPYFILES = $(HDR) $(LIB) $(DLL) $(QAPC)
+
+# If a test case returns a non-zero exit code to the shell, make will
+# stop.
+
+TESTS = sizes loadfree \
+ self1 mutex5 mutex1 mutex1e mutex1n mutex1r \
+ semaphore1 semaphore2 semaphore3 \
+ condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 \
+ create1 create2 reuse1 reuse2 equal1 \
+ kill1 valid1 valid2 \
+ exit2 exit3 exit4 exit5 \
+ join0 join1 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 \
+ 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
+
+STRESSTESTS = \
+ stress1
+
+BENCHTESTS = \
+ benchtest1 benchtest2 benchtest3 benchtest4 benchtest5
+
+STATICTESTS = \
+ self1
+
+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="-D__CLEANUP_C" all-pass
+
+GCE:
+ $(MAKE) TEST=GCE CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" all-pass
+
+GCX:
+ $(MAKE) TEST=GC CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_C" all-pass
+
+GC-bench:
+ $(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" XXLIBS="benchlib.o" all-bench
+
+GCE-bench:
+ $(MAKE) TEST=GCE CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" XXLIBS="benchlib." all-bench
+
+GC-debug:
+ $(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" DLL_VER="$(DLL_VER)d" all-pass
+
+GC-static:
+ $(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C -DPTW32_STATIC_LIB" 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" all-stress
+
+GCE-stress:
+ $(MAKE) TEST=GCE CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" 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!
+ @ $(ECHO) Build and test the DLL to run all tests.
+ @ $(ECHO) This test only confirms that the static lib links correctly.
+
+benchtest1.bench:
+benchtest2.bench:
+benchtest3.bench:
+benchtest4.bench:
+benchtest5.bench:
+
+barrier1.pass: semaphore4.pass
+barrier2.pass: barrier1.pass
+barrier3.pass: barrier2.pass
+barrier4.pass: barrier3.pass
+barrier5.pass: barrier4.pass
+cancel1.pass: create1.pass
+cancel2.pass: cancel1.pass
+cancel2_1.pass: cancel2.pass
+cancel3.pass: context1.pass
+cancel4.pass: cancel3.pass
+cancel5.pass: cancel3.pass
+cancel6a.pass: cancel3.pass
+cancel6d.pass: cancel3.pass
+cancel7.pass: kill1.pass
+cancel8.pass: cancel7.pass
+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
+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 $@
+ @ $(CP) $(BUILD_DIR)/$@ .
+
+benchlib.o: benchlib.c
+ @ $(ECHO) Compiling $@
+ @ $(ECHO) $(CC) -c $(CFLAGS) $< $(INCLUDES)
+ @ $(CC) -c $(CFLAGS) $< $(INCLUDES)
+
+pthread.dll: $(DLL)
+ @ $(CP) $(DLL) $@
+
+clean:
+ - $(RM) *.dll
+ - $(RM) *.lib
+ - $(RM) pthread.h
+ - $(RM) semaphore.h
+ - $(RM) sched.h
+ - $(RM) *.a
+ - $(RM) *.e
+ - $(RM) *.i
+ - $(RM) *.o
+ - $(RM) *.obj
+ - $(RM) *.pdb
+ - $(RM) *.exe
+ - $(RM) *.pass
+ - $(RM) *.bench
+ - $(RM) *.static
+ - $(RM) *.log
diff --git a/pthreads/tests/Makefile b/pthreads/tests/Makefile
new file mode 100644
index 000000000..69dc39c07
--- /dev/null
+++ b/pthreads/tests/Makefile
@@ -0,0 +1,404 @@
+# Makefile for the pthreads test suite.
+# If all of the .pass files can be created, the test suite has passed.
+#
+# --------------------------------------------------------------------------
+#
+# Pthreads-win32 - POSIX Threads Library for Win32
+# Copyright(C) 1998 John E. Bossom
+# Copyright(C) 1999,2005 Pthreads-win32 contributors
+#
+# Contact Email: rpj@callisto.canberra.edu.au
+#
+# The current list of contributors is contained
+# in the file CONTRIBUTORS included with the source
+# code distribution. The list can also be seen at the
+# following World Wide Web location:
+# http://sources.redhat.com/pthreads-win32/contributors.html
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library in the file COPYING.LIB;
+# if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+#
+
+DLL_VER = 2
+
+CP = copy
+RM = erase
+CAT = type
+MKDIR = mkdir
+TOUCH = echo Passed >
+ECHO = @echo
+
+QAPC = ..\QueueUserAPCEx\User\quserex.dll
+
+CPHDR = pthread.h semaphore.h sched.h
+
+OPTIM = /O2 /Ob0
+
+XXLIBS = ws2_32.lib
+
+# C++ Exceptions
+VCEFLAGS = /GX /TP /DPtW32NoCatchWarn /D__CLEANUP_CXX
+VCELIB = pthreadVCE$(DLL_VER).lib
+VCEDLL = pthreadVCE$(DLL_VER).dll
+# Structured Exceptions
+VSEFLAGS = /D__CLEANUP_SEH
+VSELIB = pthreadVSE$(DLL_VER).lib
+VSEDLL = pthreadVSE$(DLL_VER).dll
+# C cleanup code
+VCFLAGS = /D__CLEANUP_C
+VCLIB = pthreadVC$(DLL_VER).lib
+VCDLL = pthreadVC$(DLL_VER).dll
+# C++ Exceptions in application - using VC version of pthreads dll
+VCXFLAGS = /GX /TP /D__CLEANUP_C
+
+# Defaults
+CPLIB = $(VCLIB)
+CPDLL = $(VCDLL)
+
+CFLAGS= $(OPTIM) /W3 /WX /MD /nologo /Yd /Zi
+LFLAGS= /INCREMENTAL:NO
+INCLUDES=-I.
+BUILD_DIR=..
+
+COPYFILES = $(CPHDR) $(CPLIB) $(CPDLL) $(QAPC)
+
+TEST =
+EHFLAGS =
+
+# If a test case returns a non-zero exit code to the shell, make will
+# stop.
+
+PASSES= sizes.pass loadfree.pass \
+ self1.pass mutex5.pass \
+ mutex1.pass mutex1n.pass mutex1e.pass mutex1r.pass \
+ semaphore1.pass semaphore2.pass semaphore3.pass \
+ mutex2.pass mutex3.pass \
+ mutex2r.pass mutex2e.pass mutex3r.pass mutex3e.pass \
+ condvar1.pass condvar1_1.pass condvar1_2.pass condvar2.pass condvar2_1.pass \
+ exit1.pass create1.pass create2.pass reuse1.pass reuse2.pass equal1.pass \
+ kill1.pass valid1.pass valid2.pass \
+ exit2.pass exit3.pass exit4.pass exit5.pass \
+ join0.pass join1.pass 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 \
+ 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
+
+STRESSRESULTS = \
+ stress1.stress
+
+STATICRESULTS = \
+ self1.pass
+
+help:
+ @ $(ECHO) Run one of the following command lines:
+ @ $(ECHO) nmake clean VC (to test using VC dll with VC (no EH) 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.
+ @ $(ECHO) Build and test the DLL to run all tests.
+ @ $(ECHO) The static test only confirms that the .lib links correctly.
+
+sizes.pass: sizes.exe
+ @ $(ECHO) ... Running $(TEST)$(DLL_VER) test: $*.exe
+ @ .\$*.exe > SIZES.$(TEST)
+ @ $(CAT) SIZES.$(TEST)
+ @ $(ECHO) ...... Passed
+ @ $(TOUCH) $*.pass
+
+$(PASSES): $*.exe
+ @ $(ECHO) ... Running $(TEST) test: $*.exe
+ @ .\$*.exe
+ @ $(ECHO) ...... Passed
+ @ $(TOUCH) $*.pass
+
+$(BENCHRESULTS): $*.exe
+ @ $(ECHO) ... Running $(TEST) benchtest: $*.exe
+ @ .\$*.exe
+ @ $(ECHO) ...... Done
+ @ $(TOUCH) $*.bench
+
+$(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 $@
+ @ $(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
+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
diff --git a/pthreads/tests/README b/pthreads/tests/README
new file mode 100644
index 000000000..a1b5646b9
--- /dev/null
+++ b/pthreads/tests/README
@@ -0,0 +1,44 @@
+Running test cases in this directory
+------------------------------------
+
+These make scripts expect to be able to copy the dll, library
+and header files from this directory's parent directory,
+which should be the pthreads-win32 source directory.
+
+MS VC nmake
+-------------
+
+Run the target corresponding to the DLL version being tested:
+
+nmake clean VC
+
+or:
+
+nmake clean VS
+
+
+GNU GCC make
+------------
+
+Run "make clean" and then "make". See the "Known bugs" section
+in ..\README.
+
+
+Writing Test Cases
+------------------
+
+Tests written in this test suite should behave in the following manner:
+
+ * If a test fails, leave main() with a result of 1.
+
+ * If a test succeeds, leave main() with a result of 0.
+
+ * No diagnostic output should appear when the test is succeeding.
+ Diagnostic output may be emitted if something in the test
+ fails, to help determine the cause of the test failure.
+
+Notes:
+------
+
+Many test cases use knowledge of implementation internals which are supposed
+to be opaque to portable applications.
diff --git a/pthreads/tests/README.BENCHTESTS b/pthreads/tests/README.BENCHTESTS
new file mode 100644
index 000000000..448570c1f
--- /dev/null
+++ b/pthreads/tests/README.BENCHTESTS
@@ -0,0 +1,74 @@
+
+------------
+Benchmarking
+------------
+There is a set a benchmarking programs in the
+"tests" directory. These should be runnable using the
+following command-lines corresponding to each of the possible
+library builds:
+
+MSVC:
+nmake clean VC-bench
+nmake clean VCE-bench
+nmake clean VSE-bench
+
+Mingw32:
+make clean GC-bench
+make clean GCE-bench
+
+UWIN:
+The benchtests are run as part of the testsuite.
+
+
+Mutex benchtests
+----------------
+
+benchtest1 - Lock plus unlock on an unlocked mutex.
+benchtest2 - Lock plus unlock on a locked mutex.
+benchtest3 - Trylock on a locked mutex.
+benchtest4 - Trylock plus unlock on an unlocked mutex.
+
+
+Each test times up to three alternate synchronisation
+implementations as a reference, and then times each of
+the four mutex types provided by the library. Each is
+described below:
+
+Simple Critical Section
+- uses a simple Win32 critical section. There is no
+additional overhead for this case as there is in the
+remaining cases.
+
+POSIX mutex implemented using a Critical Section
+- The old implementation which uses runtime adaptation
+depending on the Windows variant being run on. When
+the pthreads DLL was run on WinNT or higher then
+POSIX mutexes would use Win32 Critical Sections.
+
+POSIX mutex implemented using a Win32 Mutex
+- The old implementation which uses runtime adaptation
+depending on the Windows variant being run on. When
+the pthreads DLL was run on Win9x then POSIX mutexes
+would use Win32 Mutexes (because TryEnterCriticalSection
+is not implemented on Win9x).
+
+PTHREAD_MUTEX_DEFAULT
+PTHREAD_MUTEX_NORMAL
+PTHREAD_MUTEX_ERRORCHECK
+PTHREAD_MUTEX_RECURSIVE
+- The current implementation supports these mutex types.
+The underlying basis of POSIX mutexes is now the same
+irrespective of the Windows variant, and should therefore
+have consistent performance.
+
+
+Semaphore benchtests
+--------------------
+
+benchtest5 - Timing for various uncontended cases.
+
+
+In all benchtests, the operation is repeated a large
+number of times and an average is calculated. Loop
+overhead is measured and subtracted from all test times.
+
diff --git a/pthreads/tests/SIZES.GC b/pthreads/tests/SIZES.GC
new file mode 100644
index 000000000..ae09a84e6
--- /dev/null
+++ b/pthreads/tests/SIZES.GC
@@ -0,0 +1,20 @@
+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
+-------------------------------
+
diff --git a/pthreads/tests/SIZES.GCE b/pthreads/tests/SIZES.GCE
new file mode 100644
index 000000000..f36d0d2b1
--- /dev/null
+++ b/pthreads/tests/SIZES.GCE
@@ -0,0 +1,20 @@
+Sizes of pthreads-win32 structs
+-------------------------------
+ pthread_t_ 60
+ 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
+-------------------------------
+
diff --git a/pthreads/tests/SIZES.VC b/pthreads/tests/SIZES.VC
new file mode 100644
index 000000000..ae09a84e6
--- /dev/null
+++ b/pthreads/tests/SIZES.VC
@@ -0,0 +1,20 @@
+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
+-------------------------------
+
diff --git a/pthreads/tests/SIZES.VCE b/pthreads/tests/SIZES.VCE
new file mode 100644
index 000000000..edc642719
--- /dev/null
+++ b/pthreads/tests/SIZES.VCE
@@ -0,0 +1,19 @@
+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
+-------------------------------
diff --git a/pthreads/tests/SIZES.VSE b/pthreads/tests/SIZES.VSE
new file mode 100644
index 000000000..edc642719
--- /dev/null
+++ b/pthreads/tests/SIZES.VSE
@@ -0,0 +1,19 @@
+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
+-------------------------------
diff --git a/pthreads/tests/Wmakefile b/pthreads/tests/Wmakefile
new file mode 100644
index 000000000..83cd34bb2
--- /dev/null
+++ b/pthreads/tests/Wmakefile
@@ -0,0 +1,346 @@
+# Watcom makefile for the pthreads test suite.
+# If all of the .pass files can be created, the test suite has passed.
+#
+# --------------------------------------------------------------------------
+#
+# Pthreads-win32 - POSIX Threads Library for Win32
+# Copyright(C) 1998 John E. Bossom
+# Copyright(C) 1999,2005 Pthreads-win32 contributors
+#
+# Contact Email: rpj@callisto.canberra.edu.au
+#
+# The current list of contributors is contained
+# in the file CONTRIBUTORS included with the source
+# code distribution. The list can also be seen at the
+# following World Wide Web location:
+# http://sources.redhat.com/pthreads-win32/contributors.html
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library in the file COPYING.LIB;
+# if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+#
+
+
+DLL_VER = 2
+
+.EXTENSIONS:
+
+.EXTENSIONS: .pass .exe .obj .i .c
+
+CP = copy
+RM = erase
+CAT = type
+MKDIR = mkdir
+TOUCH = echo Passed >
+ECHO = @echo
+
+CPHDR = pthread.h semaphore.h sched.h
+
+OPTIM = -od
+
+XXLIBS =
+
+# C++ Exceptions
+WCEFLAGS = -xs -dPtW32NoCatchWarn -d__CLEANUP_CXX
+WCELIB = pthreadWCE$(DLL_VER).lib
+WCEDLL = pthreadWCE$(DLL_VER).dll
+# C cleanup code
+WCFLAGS = -d__CLEANUP_C
+WCLIB = pthreadWC$(DLL_VER).lib
+WCDLL = pthreadWC$(DLL_VER).dll
+# C++ Exceptions in application - using WC version of pthreads dll
+WCXFLAGS = -xs -d__CLEANUP_C
+
+CFLAGS= -w4 -e25 -d_WIN32_WINNT=0x400 -d_REENTRANT -zq -bm $(OPTIM) -5r -bt=nt -mf -d2
+
+LFLAGS=
+INCLUDES= -i=.
+BUILD_DIR=..
+
+COPYFILES = $(CPHDR) $(CPLIB) $(CPDLL)
+
+TEST =
+EHFLAGS =
+
+# If a test case returns a non-zero exit code to the shell, make will
+# stop.
+
+PASSES = sizes.pass loadfree.pass &
+ self1.pass mutex5.pass &
+ mutex1.pass mutex1n.pass mutex1e.pass mutex1r.pass &
+ semaphore1.pass semaphore2.pass semaphore3.pass &
+ mutex2.pass mutex3.pass &
+ mutex2r.pass mutex2e.pass mutex3r.pass mutex3e.pass &
+ condvar1.pass condvar1_1.pass condvar1_2.pass condvar2.pass condvar2_1.pass &
+ exit1.pass create1.pass create2.pass reuse1.pass reuse2.pass equal1.pass &
+ kill1.pass valid1.pass valid2.pass &
+ exit2.pass exit3.pass exit4 exit5 &
+ join0.pass join1.pass 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 $@
+ @ $(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
diff --git a/pthreads/tests/barrier1.c b/pthreads/tests/barrier1.c
new file mode 100644
index 000000000..76f78df66
--- /dev/null
+++ b/pthreads/tests/barrier1.c
@@ -0,0 +1,58 @@
+/*
+ * barrier1.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 a barrier object and then destroy it.
+ *
+ */
+
+#include "test.h"
+
+pthread_barrier_t barrier = NULL;
+
+int
+main()
+{
+ assert(barrier == NULL);
+
+ assert(pthread_barrier_init(&barrier, NULL, 1) == 0);
+
+ assert(barrier != NULL);
+
+ assert(pthread_barrier_destroy(&barrier) == 0);
+
+ assert(barrier == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/barrier2.c b/pthreads/tests/barrier2.c
new file mode 100644
index 000000000..28aa238c5
--- /dev/null
+++ b/pthreads/tests/barrier2.c
@@ -0,0 +1,55 @@
+/*
+ * barrier2.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a single barrier object, wait on it,
+ * and then destroy it.
+ *
+ */
+
+#include "test.h"
+
+pthread_barrier_t barrier = NULL;
+
+int
+main()
+{
+ assert(pthread_barrier_init(&barrier, NULL, 1) == 0);
+
+ assert(pthread_barrier_wait(&barrier) == PTHREAD_BARRIER_SERIAL_THREAD);
+
+ assert(pthread_barrier_destroy(&barrier) == 0);
+
+ return 0;
+}
diff --git a/pthreads/tests/barrier3.c b/pthreads/tests/barrier3.c
new file mode 100644
index 000000000..3e4009068
--- /dev/null
+++ b/pthreads/tests/barrier3.c
@@ -0,0 +1,71 @@
+/*
+ * barrier3.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a single barrier object with barrier attribute, wait on it,
+ * and then destroy it.
+ *
+ */
+
+#include "test.h"
+
+pthread_barrier_t barrier = NULL;
+static int result = 1;
+
+void * func(void * arg)
+{
+ return (void *) pthread_barrier_wait(&barrier);
+}
+
+int
+main()
+{
+ pthread_t t;
+ pthread_barrierattr_t ba;
+
+ assert(pthread_barrierattr_init(&ba) == 0);
+ assert(pthread_barrierattr_setpshared(&ba, PTHREAD_PROCESS_PRIVATE) == 0);
+ assert(pthread_barrier_init(&barrier, &ba, 1) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+
+ assert(pthread_join(t, (void **) &result) == 0);
+
+ assert(result == PTHREAD_BARRIER_SERIAL_THREAD);
+
+ assert(pthread_barrier_destroy(&barrier) == 0);
+ assert(pthread_barrierattr_destroy(&ba) == 0);
+
+ return 0;
+}
diff --git a/pthreads/tests/barrier4.c b/pthreads/tests/barrier4.c
new file mode 100644
index 000000000..042992dfd
--- /dev/null
+++ b/pthreads/tests/barrier4.c
@@ -0,0 +1,110 @@
+/*
+ * barrier4.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a single barrier object, multiple wait on it,
+ * and then destroy it.
+ *
+ */
+
+#include "test.h"
+
+enum {
+ NUMTHREADS = 16
+};
+
+pthread_barrier_t barrier = NULL;
+pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;
+static int serialThreadCount = 0;
+static int otherThreadCount = 0;
+
+void *
+func(void * arg)
+{
+ int result = pthread_barrier_wait(&barrier);
+
+ assert(pthread_mutex_lock(&mx) == 0);
+
+ if (result == PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ serialThreadCount++;
+ }
+ else if (0 == result)
+ {
+ otherThreadCount++;
+ }
+ else
+ {
+ printf("Barrier wait failed: error = %s\n", error_string[result]);
+ fflush(stdout);
+ return NULL;
+ }
+ assert(pthread_mutex_unlock(&mx) == 0);
+
+ return NULL;
+}
+
+int
+main()
+{
+ int i, j;
+ pthread_t t[NUMTHREADS + 1];
+
+ for (j = 1; j <= NUMTHREADS; j++)
+ {
+ printf("Barrier height = %d\n", j);
+
+ serialThreadCount = 0;
+
+ assert(pthread_barrier_init(&barrier, NULL, j) == 0);
+
+ for (i = 1; i <= j; i++)
+ {
+ assert(pthread_create(&t[i], NULL, func, NULL) == 0);
+ }
+
+ for (i = 1; i <= j; i++)
+ {
+ assert(pthread_join(t[i], NULL) == 0);
+ }
+
+ assert(serialThreadCount == 1);
+
+ assert(pthread_barrier_destroy(&barrier) == 0);
+ }
+
+ assert(pthread_mutex_destroy(&mx) == 0);
+
+ return 0;
+}
diff --git a/pthreads/tests/barrier5.c b/pthreads/tests/barrier5.c
new file mode 100644
index 000000000..5b598c9d9
--- /dev/null
+++ b/pthreads/tests/barrier5.c
@@ -0,0 +1,128 @@
+/*
+ * 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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a single barrier object, set up a sequence of
+ * barrier points to prove lockstepness, and then destroy it.
+ *
+ */
+
+#include "test.h"
+
+enum {
+ NUMTHREADS = 16,
+ BARRIERS = 10000
+};
+
+pthread_barrier_t barrier = NULL;
+pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;
+
+int barrierReleases[BARRIERS + 1];
+
+void *
+func(void * barrierHeight)
+{
+ int i;
+ int result;
+ int serialThreads = 0;
+
+ for (i = 1; i < BARRIERS; i++)
+ {
+ result = pthread_barrier_wait(&barrier);
+
+ assert(pthread_mutex_lock(&mx) == 0);
+ barrierReleases[i]++;
+ assert(pthread_mutex_unlock(&mx) == 0);
+ /*
+ * Confirm the correct number of releases from the previous
+ * barrier. We can't do the current barrier yet because there may
+ * still be threads waking up.
+ */
+ if (result == PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ serialThreads++;
+ assert(barrierReleases[i - 1] == (int) barrierHeight);
+ barrierReleases[i + 1] = 0;
+ }
+ 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;
+ pthread_t t[NUMTHREADS + 1];
+
+ for (j = 1; j <= NUMTHREADS; j++)
+ {
+ printf("Barrier height = %d\n", j);
+
+ barrierReleases[0] = j;
+ barrierReleases[1] = 0;
+
+ assert(pthread_barrier_init(&barrier, NULL, j) == 0);
+
+ for (i = 1; i <= j; i++)
+ {
+ assert(pthread_create(&t[i], NULL, func, (void *) j) == 0);
+ }
+
+ serialThreadsTotal = 0;
+ for (i = 1; i <= j; i++)
+ {
+ assert(pthread_join(t[i], (void **) &result) == 0);
+ serialThreadsTotal += result;
+ }
+
+ assert(serialThreadsTotal == BARRIERS - 1);
+ assert(barrierReleases[BARRIERS - 1] == j);
+ assert(barrierReleases[BARRIERS] == 0);
+
+ assert(pthread_barrier_destroy(&barrier) == 0);
+ }
+
+ assert(pthread_mutex_destroy(&mx) == 0);
+
+ return 0;
+}
diff --git a/pthreads/tests/benchlib.c b/pthreads/tests/benchlib.c
new file mode 100644
index 000000000..bf60ae515
--- /dev/null
+++ b/pthreads/tests/benchlib.c
@@ -0,0 +1,363 @@
+/*
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "../config.h"
+
+#include "pthread.h"
+#include "sched.h"
+#include "semaphore.h"
+#include <windows.h>
+#include <stdio.h>
+
+#ifdef __GNUC__
+#include <stdlib.h>
+#endif
+
+#include "benchtest.h"
+
+int old_mutex_use = OLD_WIN32CS;
+
+BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION) = NULL;
+HINSTANCE ptw32_h_kernel32;
+
+void
+dummy_call(int * a)
+{
+}
+
+void
+interlocked_inc_with_conditionals(int * a)
+{
+ if (a != NULL)
+ if (InterlockedIncrement((long *) a) == -1)
+ {
+ *a = 0;
+ }
+}
+
+void
+interlocked_dec_with_conditionals(int * a)
+{
+ if (a != NULL)
+ if (InterlockedDecrement((long *) a) == -1)
+ {
+ *a = 0;
+ }
+}
+
+int
+old_mutex_init(old_mutex_t *mutex, const old_mutexattr_t *attr)
+{
+ int result = 0;
+ old_mutex_t mx;
+
+ if (mutex == NULL)
+ {
+ return EINVAL;
+ }
+
+ mx = (old_mutex_t) calloc(1, sizeof(*mx));
+
+ if (mx == NULL)
+ {
+ result = ENOMEM;
+ goto FAIL0;
+ }
+
+ mx->mutex = 0;
+
+ if (attr != NULL
+ && *attr != NULL
+ && (*attr)->pshared == PTHREAD_PROCESS_SHARED
+ )
+ {
+ result = ENOSYS;
+ }
+ else
+ {
+ CRITICAL_SECTION cs;
+
+ /*
+ * Load KERNEL32 and try to get address of TryEnterCriticalSection
+ */
+ ptw32_h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL"));
+ ptw32_try_enter_critical_section = (BOOL (WINAPI *)(LPCRITICAL_SECTION))
+
+#if defined(NEED_UNICODE_CONSTS)
+ GetProcAddress(ptw32_h_kernel32,
+ (const TCHAR *)TEXT("TryEnterCriticalSection"));
+#else
+ GetProcAddress(ptw32_h_kernel32,
+ (LPCSTR) "TryEnterCriticalSection");
+#endif
+
+ if (ptw32_try_enter_critical_section != NULL)
+ {
+ InitializeCriticalSection(&cs);
+ if ((*ptw32_try_enter_critical_section)(&cs))
+ {
+ LeaveCriticalSection(&cs);
+ }
+ else
+ {
+ /*
+ * Not really supported (Win98?).
+ */
+ ptw32_try_enter_critical_section = NULL;
+ }
+ DeleteCriticalSection(&cs);
+ }
+
+ if (ptw32_try_enter_critical_section == NULL)
+ {
+ (void) FreeLibrary(ptw32_h_kernel32);
+ ptw32_h_kernel32 = 0;
+ }
+
+ if (old_mutex_use == OLD_WIN32CS)
+ {
+ InitializeCriticalSection(&mx->cs);
+ }
+ else if (old_mutex_use == OLD_WIN32MUTEX)
+ {
+ mx->mutex = CreateMutex (NULL,
+ FALSE,
+ NULL);
+
+ if (mx->mutex == 0)
+ {
+ result = EAGAIN;
+ }
+ }
+ else
+ {
+ result = EINVAL;
+ }
+ }
+
+ if (result != 0 && mx != NULL)
+ {
+ free(mx);
+ mx = NULL;
+ }
+
+FAIL0:
+ *mutex = mx;
+
+ return(result);
+}
+
+
+int
+old_mutex_lock(old_mutex_t *mutex)
+{
+ int result = 0;
+ old_mutex_t mx;
+
+ if (mutex == NULL || *mutex == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (*mutex == (old_mutex_t) PTW32_OBJECT_AUTO_INIT)
+ {
+ /*
+ * Don't use initialisers when benchtesting.
+ */
+ result = EINVAL;
+ }
+
+ mx = *mutex;
+
+ if (result == 0)
+ {
+ if (mx->mutex == 0)
+ {
+ EnterCriticalSection(&mx->cs);
+ }
+ else
+ {
+ result = (WaitForSingleObject(mx->mutex, INFINITE)
+ == WAIT_OBJECT_0)
+ ? 0
+ : EINVAL;
+ }
+ }
+
+ return(result);
+}
+
+int
+old_mutex_unlock(old_mutex_t *mutex)
+{
+ int result = 0;
+ old_mutex_t mx;
+
+ if (mutex == NULL || *mutex == NULL)
+ {
+ return EINVAL;
+ }
+
+ mx = *mutex;
+
+ if (mx != (old_mutex_t) PTW32_OBJECT_AUTO_INIT)
+ {
+ if (mx->mutex == 0)
+ {
+ LeaveCriticalSection(&mx->cs);
+ }
+ else
+ {
+ result = (ReleaseMutex (mx->mutex) ? 0 : EINVAL);
+ }
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ return(result);
+}
+
+
+int
+old_mutex_trylock(old_mutex_t *mutex)
+{
+ int result = 0;
+ old_mutex_t mx;
+
+ if (mutex == NULL || *mutex == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (*mutex == (old_mutex_t) PTW32_OBJECT_AUTO_INIT)
+ {
+ /*
+ * Don't use initialisers when benchtesting.
+ */
+ result = EINVAL;
+ }
+
+ mx = *mutex;
+
+ if (result == 0)
+ {
+ if (mx->mutex == 0)
+ {
+ if (ptw32_try_enter_critical_section == NULL)
+ {
+ result = 0;
+ }
+ else if ((*ptw32_try_enter_critical_section)(&mx->cs) != TRUE)
+ {
+ result = EBUSY;
+ }
+ }
+ else
+ {
+ DWORD status;
+
+ status = WaitForSingleObject (mx->mutex, 0);
+
+ if (status != WAIT_OBJECT_0)
+ {
+ result = ((status == WAIT_TIMEOUT)
+ ? EBUSY
+ : EINVAL);
+ }
+ }
+ }
+
+ return(result);
+}
+
+
+int
+old_mutex_destroy(old_mutex_t *mutex)
+{
+ int result = 0;
+ old_mutex_t mx;
+
+ if (mutex == NULL
+ || *mutex == NULL)
+ {
+ return EINVAL;
+ }
+
+ if (*mutex != (old_mutex_t) PTW32_OBJECT_AUTO_INIT)
+ {
+ mx = *mutex;
+
+ if ((result = old_mutex_trylock(&mx)) == 0)
+ {
+ *mutex = NULL;
+
+ (void) old_mutex_unlock(&mx);
+
+ if (mx->mutex == 0)
+ {
+ DeleteCriticalSection(&mx->cs);
+ }
+ else
+ {
+ result = (CloseHandle (mx->mutex) ? 0 : EINVAL);
+ }
+
+ if (result == 0)
+ {
+ mx->mutex = 0;
+ free(mx);
+ }
+ else
+ {
+ *mutex = mx;
+ }
+ }
+ }
+ else
+ {
+ result = EINVAL;
+ }
+
+ if (ptw32_try_enter_critical_section != NULL)
+ {
+ (void) FreeLibrary(ptw32_h_kernel32);
+ ptw32_h_kernel32 = 0;
+ }
+
+ return(result);
+}
+
+/****************************************************************************************/
diff --git a/pthreads/tests/benchtest.h b/pthreads/tests/benchtest.h
new file mode 100644
index 000000000..809057810
--- /dev/null
+++ b/pthreads/tests/benchtest.h
@@ -0,0 +1,70 @@
+/*
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 "../config.h"
+
+enum {
+ OLD_WIN32CS,
+ OLD_WIN32MUTEX
+};
+
+extern int old_mutex_use;
+
+struct old_mutex_t_ {
+ HANDLE mutex;
+ CRITICAL_SECTION cs;
+};
+
+typedef struct old_mutex_t_ * old_mutex_t;
+
+struct old_mutexattr_t_ {
+ int pshared;
+};
+
+typedef struct old_mutexattr_t_ * old_mutexattr_t;
+
+extern BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION);
+extern HINSTANCE ptw32_h_kernel32;
+
+#define PTW32_OBJECT_AUTO_INIT ((void *) -1)
+
+void dummy_call(int * a);
+void interlocked_inc_with_conditionals(int *a);
+void interlocked_dec_with_conditionals(int *a);
+int old_mutex_init(old_mutex_t *mutex, const old_mutexattr_t *attr);
+int old_mutex_lock(old_mutex_t *mutex);
+int old_mutex_unlock(old_mutex_t *mutex);
+int old_mutex_trylock(old_mutex_t *mutex);
+int old_mutex_destroy(old_mutex_t *mutex);
+/****************************************************************************************/
diff --git a/pthreads/tests/benchtest1.c b/pthreads/tests/benchtest1.c
new file mode 100644
index 000000000..116dad05e
--- /dev/null
+++ b/pthreads/tests/benchtest1.c
@@ -0,0 +1,249 @@
+/*
+ * benchtest1.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Measure time taken to complete an elementary operation.
+ *
+ * - Mutex
+ * Single thread iteration over lock/unlock for each mutex type.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+#ifdef __GNUC__
+#include <stdlib.h>
+#endif
+
+#include "benchtest.h"
+
+#define PTW32_MUTEX_TYPES
+#define ITERATIONS 10000000L
+
+pthread_mutex_t mx;
+pthread_mutexattr_t ma;
+struct _timeb currSysTimeStart;
+struct _timeb currSysTimeStop;
+long durationMilliSecs;
+long overHeadMilliSecs = 0;
+int one = 1;
+int zero = 0;
+
+#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \
+ - (_TStart.time*1000+_TStart.millitm))
+
+/*
+ * Dummy use of j, otherwise the loop may be removed by the optimiser
+ * when doing the overhead timing with an empty loop.
+ */
+#define TESTSTART \
+ { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++;
+
+#define TESTSTOP \
+ }; _ftime(&currSysTimeStop); if (j + k == i) j++; }
+
+
+void
+runTest (char * testNameString, int mType)
+{
+#ifdef PTW32_MUTEX_TYPES
+ assert(pthread_mutexattr_settype(&ma, mType) == 0);
+#endif
+ assert(pthread_mutex_init(&mx, &ma) == 0);
+
+ TESTSTART
+ assert(pthread_mutex_lock(&mx) == zero);
+ assert(pthread_mutex_unlock(&mx) == zero);
+ TESTSTOP
+
+ assert(pthread_mutex_destroy(&mx) == 0);
+
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+
+ printf( "%-45s %15ld %15.3f\n",
+ testNameString,
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int i = 0;
+ CRITICAL_SECTION cs;
+ old_mutex_t ox;
+ pthread_mutexattr_init(&ma);
+
+ printf( "=============================================================================\n");
+ printf( "\nLock plus unlock on an unlocked mutex.\n%ld iterations\n\n",
+ ITERATIONS);
+ printf( "%-45s %15s %15s\n",
+ "Test",
+ "Total(msec)",
+ "average(usec)");
+ printf( "-----------------------------------------------------------------------------\n");
+
+ /*
+ * Time the loop overhead so we can subtract it from the actual test times.
+ */
+
+ TESTSTART
+ assert(1 == one);
+ assert(1 == one);
+ TESTSTOP
+
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+ overHeadMilliSecs = durationMilliSecs;
+
+
+ TESTSTART
+ assert((dummy_call(&i), 1) == one);
+ assert((dummy_call(&i), 1) == one);
+ TESTSTOP
+
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+
+ printf( "%-45s %15ld %15.3f\n",
+ "Dummy call x 2",
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+
+
+ TESTSTART
+ assert((interlocked_inc_with_conditionals(&i), 1) == one);
+ assert((interlocked_dec_with_conditionals(&i), 1) == one);
+ TESTSTOP
+
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+
+ printf( "%-45s %15ld %15.3f\n",
+ "Dummy call -> Interlocked with cond x 2",
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+
+
+ TESTSTART
+ assert((InterlockedIncrement((LPLONG)&i), 1) == (LONG)one);
+ assert((InterlockedDecrement((LPLONG)&i), 1) == (LONG)one);
+ TESTSTOP
+
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+
+ printf( "%-45s %15ld %15.3f\n",
+ "InterlockedOp x 2",
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+
+
+ InitializeCriticalSection(&cs);
+
+ TESTSTART
+ assert((EnterCriticalSection(&cs), 1) == one);
+ assert((LeaveCriticalSection(&cs), 1) == one);
+ TESTSTOP
+
+ DeleteCriticalSection(&cs);
+
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+
+ printf( "%-45s %15ld %15.3f\n",
+ "Simple Critical Section",
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+
+
+ old_mutex_use = OLD_WIN32CS;
+ assert(old_mutex_init(&ox, NULL) == 0);
+
+ TESTSTART
+ assert(old_mutex_lock(&ox) == zero);
+ assert(old_mutex_unlock(&ox) == zero);
+ TESTSTOP
+
+ assert(old_mutex_destroy(&ox) == 0);
+
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+
+ printf( "%-45s %15ld %15.3f\n",
+ "Old PT Mutex using a Critical Section (WNT)",
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+
+
+ old_mutex_use = OLD_WIN32MUTEX;
+ assert(old_mutex_init(&ox, NULL) == 0);
+
+ TESTSTART
+ assert(old_mutex_lock(&ox) == zero);
+ assert(old_mutex_unlock(&ox) == zero);
+ TESTSTOP
+
+ assert(old_mutex_destroy(&ox) == 0);
+
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+
+ printf( "%-45s %15ld %15.3f\n",
+ "Old PT Mutex using a Win32 Mutex (W9x)",
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+
+ printf( ".............................................................................\n");
+
+ /*
+ * Now we can start the actual tests
+ */
+#ifdef PTW32_MUTEX_TYPES
+ runTest("PTHREAD_MUTEX_DEFAULT (W9x,WNT)", PTHREAD_MUTEX_DEFAULT);
+
+ runTest("PTHREAD_MUTEX_NORMAL (W9x,WNT)", PTHREAD_MUTEX_NORMAL);
+
+ runTest("PTHREAD_MUTEX_ERRORCHECK (W9x,WNT)", PTHREAD_MUTEX_ERRORCHECK);
+
+ runTest("PTHREAD_MUTEX_RECURSIVE (W9x,WNT)", PTHREAD_MUTEX_RECURSIVE);
+#else
+ runTest("Non-blocking lock", 0);
+#endif
+
+ printf( "=============================================================================\n");
+
+ /*
+ * End of tests.
+ */
+
+ pthread_mutexattr_destroy(&ma);
+
+ one = i; /* Dummy assignment to avoid 'variable unused' warning */
+ return 0;
+}
diff --git a/pthreads/tests/benchtest2.c b/pthreads/tests/benchtest2.c
new file mode 100644
index 000000000..d92bb3c1a
--- /dev/null
+++ b/pthreads/tests/benchtest2.c
@@ -0,0 +1,311 @@
+/*
+ * benchtest1.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Measure time taken to complete an elementary operation.
+ *
+ * - Mutex
+ * Two threads iterate over lock/unlock for each mutex type.
+ * The two threads are forced into lock-step using two mutexes,
+ * forcing the threads to block on each lock operation. The
+ * time measured is therefore the worst case senario.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+#ifdef __GNUC__
+#include <stdlib.h>
+#endif
+
+#include "benchtest.h"
+
+#define PTW32_MUTEX_TYPES
+#define ITERATIONS 100000L
+
+pthread_mutex_t gate1, gate2;
+old_mutex_t ox1, ox2;
+CRITICAL_SECTION cs1, cs2;
+pthread_mutexattr_t ma;
+long durationMilliSecs;
+long overHeadMilliSecs = 0;
+struct _timeb currSysTimeStart;
+struct _timeb currSysTimeStop;
+pthread_t worker;
+int running = 0;
+
+#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \
+ - (_TStart.time*1000+_TStart.millitm))
+
+/*
+ * Dummy use of j, otherwise the loop may be removed by the optimiser
+ * when doing the overhead timing with an empty loop.
+ */
+#define TESTSTART \
+ { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++;
+
+#define TESTSTOP \
+ }; _ftime(&currSysTimeStop); if (j + k == i) j++; }
+
+
+void *
+overheadThread(void * arg)
+{
+ do
+ {
+ sched_yield();
+ }
+ while (running);
+
+ return NULL;
+}
+
+
+void *
+oldThread(void * arg)
+{
+ do
+ {
+ (void) old_mutex_lock(&ox1);
+ (void) old_mutex_lock(&ox2);
+ (void) old_mutex_unlock(&ox1);
+ sched_yield();
+ (void) old_mutex_unlock(&ox2);
+ }
+ while (running);
+
+ return NULL;
+}
+
+void *
+workerThread(void * arg)
+{
+ do
+ {
+ (void) pthread_mutex_lock(&gate1);
+ (void) pthread_mutex_lock(&gate2);
+ (void) pthread_mutex_unlock(&gate1);
+ sched_yield();
+ (void) pthread_mutex_unlock(&gate2);
+ }
+ while (running);
+
+ return NULL;
+}
+
+void *
+CSThread(void * arg)
+{
+ do
+ {
+ EnterCriticalSection(&cs1);
+ EnterCriticalSection(&cs2);
+ LeaveCriticalSection(&cs1);
+ sched_yield();
+ LeaveCriticalSection(&cs2);
+ }
+ while (running);
+
+ return NULL;
+}
+
+void
+runTest (char * testNameString, int mType)
+{
+#ifdef PTW32_MUTEX_TYPES
+ assert(pthread_mutexattr_settype(&ma, mType) == 0);
+#endif
+ assert(pthread_mutex_init(&gate1, &ma) == 0);
+ assert(pthread_mutex_init(&gate2, &ma) == 0);
+ assert(pthread_mutex_lock(&gate1) == 0);
+ assert(pthread_mutex_lock(&gate2) == 0);
+ running = 1;
+ assert(pthread_create(&worker, NULL, workerThread, NULL) == 0);
+ TESTSTART
+ (void) pthread_mutex_unlock(&gate1);
+ sched_yield();
+ (void) pthread_mutex_unlock(&gate2);
+ (void) pthread_mutex_lock(&gate1);
+ (void) pthread_mutex_lock(&gate2);
+ TESTSTOP
+ running = 0;
+ assert(pthread_mutex_unlock(&gate2) == 0);
+ assert(pthread_mutex_unlock(&gate1) == 0);
+ assert(pthread_join(worker, NULL) == 0);
+ assert(pthread_mutex_destroy(&gate2) == 0);
+ assert(pthread_mutex_destroy(&gate1) == 0);
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+ printf( "%-45s %15ld %15.3f\n",
+ testNameString,
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS / 4 /* Four locks/unlocks per iteration */);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ assert(pthread_mutexattr_init(&ma) == 0);
+
+ printf( "=============================================================================\n");
+ printf( "\nLock plus unlock on a locked mutex.\n");
+ printf("%ld iterations, four locks/unlocks per iteration.\n\n", ITERATIONS);
+
+ printf( "%-45s %15s %15s\n",
+ "Test",
+ "Total(msec)",
+ "average(usec)");
+ printf( "-----------------------------------------------------------------------------\n");
+
+ /*
+ * Time the loop overhead so we can subtract it from the actual test times.
+ */
+
+ running = 1;
+ assert(pthread_create(&worker, NULL, overheadThread, NULL) == 0);
+ TESTSTART
+ sched_yield();
+ sched_yield();
+ TESTSTOP
+ running = 0;
+ assert(pthread_join(worker, NULL) == 0);
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+ overHeadMilliSecs = durationMilliSecs;
+
+
+ InitializeCriticalSection(&cs1);
+ InitializeCriticalSection(&cs2);
+ EnterCriticalSection(&cs1);
+ EnterCriticalSection(&cs2);
+ running = 1;
+ assert(pthread_create(&worker, NULL, CSThread, NULL) == 0);
+ TESTSTART
+ LeaveCriticalSection(&cs1);
+ sched_yield();
+ LeaveCriticalSection(&cs2);
+ EnterCriticalSection(&cs1);
+ EnterCriticalSection(&cs2);
+ TESTSTOP
+ running = 0;
+ LeaveCriticalSection(&cs2);
+ LeaveCriticalSection(&cs1);
+ assert(pthread_join(worker, NULL) == 0);
+ DeleteCriticalSection(&cs2);
+ DeleteCriticalSection(&cs1);
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+ printf( "%-45s %15ld %15.3f\n",
+ "Simple Critical Section",
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS / 4 );
+
+
+ old_mutex_use = OLD_WIN32CS;
+ assert(old_mutex_init(&ox1, NULL) == 0);
+ assert(old_mutex_init(&ox2, NULL) == 0);
+ assert(old_mutex_lock(&ox1) == 0);
+ assert(old_mutex_lock(&ox2) == 0);
+ running = 1;
+ assert(pthread_create(&worker, NULL, oldThread, NULL) == 0);
+ TESTSTART
+ (void) old_mutex_unlock(&ox1);
+ sched_yield();
+ (void) old_mutex_unlock(&ox2);
+ (void) old_mutex_lock(&ox1);
+ (void) old_mutex_lock(&ox2);
+ TESTSTOP
+ running = 0;
+ assert(old_mutex_unlock(&ox1) == 0);
+ assert(old_mutex_unlock(&ox2) == 0);
+ assert(pthread_join(worker, NULL) == 0);
+ assert(old_mutex_destroy(&ox2) == 0);
+ assert(old_mutex_destroy(&ox1) == 0);
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+ printf( "%-45s %15ld %15.3f\n",
+ "Old PT Mutex using a Critical Section (WNT)",
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS / 4);
+
+
+ old_mutex_use = OLD_WIN32MUTEX;
+ assert(old_mutex_init(&ox1, NULL) == 0);
+ assert(old_mutex_init(&ox2, NULL) == 0);
+ assert(old_mutex_lock(&ox1) == 0);
+ assert(old_mutex_lock(&ox2) == 0);
+ running = 1;
+ assert(pthread_create(&worker, NULL, oldThread, NULL) == 0);
+ TESTSTART
+ (void) old_mutex_unlock(&ox1);
+ sched_yield();
+ (void) old_mutex_unlock(&ox2);
+ (void) old_mutex_lock(&ox1);
+ (void) old_mutex_lock(&ox2);
+ TESTSTOP
+ running = 0;
+ assert(old_mutex_unlock(&ox1) == 0);
+ assert(old_mutex_unlock(&ox2) == 0);
+ assert(pthread_join(worker, NULL) == 0);
+ assert(old_mutex_destroy(&ox2) == 0);
+ assert(old_mutex_destroy(&ox1) == 0);
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+ printf( "%-45s %15ld %15.3f\n",
+ "Old PT Mutex using a Win32 Mutex (W9x)",
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS / 4);
+
+ printf( ".............................................................................\n");
+
+ /*
+ * Now we can start the actual tests
+ */
+#ifdef PTW32_MUTEX_TYPES
+ runTest("PTHREAD_MUTEX_DEFAULT (W9x,WNT)", PTHREAD_MUTEX_DEFAULT);
+
+ runTest("PTHREAD_MUTEX_NORMAL (W9x,WNT)", PTHREAD_MUTEX_NORMAL);
+
+ runTest("PTHREAD_MUTEX_ERRORCHECK (W9x,WNT)", PTHREAD_MUTEX_ERRORCHECK);
+
+ runTest("PTHREAD_MUTEX_RECURSIVE (W9x,WNT)", PTHREAD_MUTEX_RECURSIVE);
+#else
+ runTest("Blocking locks", 0);
+#endif
+
+ printf( "=============================================================================\n");
+ /*
+ * End of tests.
+ */
+
+ pthread_mutexattr_destroy(&ma);
+
+ return 0;
+}
diff --git a/pthreads/tests/benchtest3.c b/pthreads/tests/benchtest3.c
new file mode 100644
index 000000000..023460dfb
--- /dev/null
+++ b/pthreads/tests/benchtest3.c
@@ -0,0 +1,201 @@
+/*
+ * benchtest3.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Measure time taken to complete an elementary operation.
+ *
+ * - Mutex
+ * Single thread iteration over a trylock on a locked mutex for each mutex type.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+#ifdef __GNUC__
+#include <stdlib.h>
+#endif
+
+#include "benchtest.h"
+
+#define PTW32_MUTEX_TYPES
+#define ITERATIONS 10000000L
+
+pthread_mutex_t mx;
+old_mutex_t ox;
+pthread_mutexattr_t ma;
+struct _timeb currSysTimeStart;
+struct _timeb currSysTimeStop;
+long durationMilliSecs;
+long overHeadMilliSecs = 0;
+
+#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \
+ - (_TStart.time*1000+_TStart.millitm))
+
+/*
+ * Dummy use of j, otherwise the loop may be removed by the optimiser
+ * when doing the overhead timing with an empty loop.
+ */
+#define TESTSTART \
+ { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++;
+
+#define TESTSTOP \
+ }; _ftime(&currSysTimeStop); if (j + k == i) j++; }
+
+
+void *
+trylockThread (void * arg)
+{
+ TESTSTART
+ (void) pthread_mutex_trylock(&mx);
+ TESTSTOP
+
+ return NULL;
+}
+
+
+void *
+oldTrylockThread (void * arg)
+{
+ TESTSTART
+ (void) old_mutex_trylock(&ox);
+ TESTSTOP
+
+ return NULL;
+}
+
+
+void
+runTest (char * testNameString, int mType)
+{
+ pthread_t t;
+
+#ifdef PTW32_MUTEX_TYPES
+ (void) pthread_mutexattr_settype(&ma, mType);
+#endif
+ assert(pthread_mutex_init(&mx, &ma) == 0);
+ assert(pthread_mutex_lock(&mx) == 0);
+ assert(pthread_create(&t, NULL, trylockThread, 0) == 0);
+ assert(pthread_join(t, NULL) == 0);
+ assert(pthread_mutex_unlock(&mx) == 0);
+ assert(pthread_mutex_destroy(&mx) == 0);
+
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+
+ printf( "%-45s %15ld %15.3f\n",
+ testNameString,
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ pthread_t t;
+
+ assert(pthread_mutexattr_init(&ma) == 0);
+
+ printf( "=============================================================================\n");
+ printf( "\nTrylock on a locked mutex.\n");
+ printf( "%ld iterations.\n\n", ITERATIONS);
+ printf( "%-45s %15s %15s\n",
+ "Test",
+ "Total(msec)",
+ "average(usec)");
+ printf( "-----------------------------------------------------------------------------\n");
+
+ /*
+ * Time the loop overhead so we can subtract it from the actual test times.
+ */
+
+ TESTSTART
+ TESTSTOP
+
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+ overHeadMilliSecs = durationMilliSecs;
+
+
+ old_mutex_use = OLD_WIN32CS;
+ assert(old_mutex_init(&ox, NULL) == 0);
+ assert(old_mutex_lock(&ox) == 0);
+ assert(pthread_create(&t, NULL, oldTrylockThread, 0) == 0);
+ assert(pthread_join(t, NULL) == 0);
+ assert(old_mutex_unlock(&ox) == 0);
+ assert(old_mutex_destroy(&ox) == 0);
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+ printf( "%-45s %15ld %15.3f\n",
+ "Old PT Mutex using a Critical Section (WNT)",
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+
+ old_mutex_use = OLD_WIN32MUTEX;
+ assert(old_mutex_init(&ox, NULL) == 0);
+ assert(old_mutex_lock(&ox) == 0);
+ assert(pthread_create(&t, NULL, oldTrylockThread, 0) == 0);
+ assert(pthread_join(t, NULL) == 0);
+ assert(old_mutex_unlock(&ox) == 0);
+ assert(old_mutex_destroy(&ox) == 0);
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+ printf( "%-45s %15ld %15.3f\n",
+ "Old PT Mutex using a Win32 Mutex (W9x)",
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+
+ printf( ".............................................................................\n");
+
+ /*
+ * Now we can start the actual tests
+ */
+#ifdef PTW32_MUTEX_TYPES
+ runTest("PTHREAD_MUTEX_DEFAULT (W9x,WNT)", PTHREAD_MUTEX_DEFAULT);
+
+ runTest("PTHREAD_MUTEX_NORMAL (W9x,WNT)", PTHREAD_MUTEX_NORMAL);
+
+ runTest("PTHREAD_MUTEX_ERRORCHECK (W9x,WNT)", PTHREAD_MUTEX_ERRORCHECK);
+
+ runTest("PTHREAD_MUTEX_RECURSIVE (W9x,WNT)", PTHREAD_MUTEX_RECURSIVE);
+#else
+ runTest("Non-blocking lock", 0);
+#endif
+
+ printf( "=============================================================================\n");
+
+ /*
+ * End of tests.
+ */
+
+ pthread_mutexattr_destroy(&ma);
+
+ return 0;
+}
diff --git a/pthreads/tests/benchtest4.c b/pthreads/tests/benchtest4.c
new file mode 100644
index 000000000..772d10047
--- /dev/null
+++ b/pthreads/tests/benchtest4.c
@@ -0,0 +1,182 @@
+/*
+ * benchtest4.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Measure time taken to complete an elementary operation.
+ *
+ * - Mutex
+ * Single thread iteration over trylock/unlock for each mutex type.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+#ifdef __GNUC__
+#include <stdlib.h>
+#endif
+
+#include "benchtest.h"
+
+#define PTW32_MUTEX_TYPES
+#define ITERATIONS 10000000L
+
+pthread_mutex_t mx;
+old_mutex_t ox;
+pthread_mutexattr_t ma;
+struct _timeb currSysTimeStart;
+struct _timeb currSysTimeStop;
+long durationMilliSecs;
+long overHeadMilliSecs = 0;
+
+#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \
+ - (_TStart.time*1000+_TStart.millitm))
+
+/*
+ * Dummy use of j, otherwise the loop may be removed by the optimiser
+ * when doing the overhead timing with an empty loop.
+ */
+#define TESTSTART \
+ { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++;
+
+#define TESTSTOP \
+ }; _ftime(&currSysTimeStop); if (j + k == i) j++; }
+
+
+void
+oldRunTest (char * testNameString, int mType)
+{
+}
+
+
+void
+runTest (char * testNameString, int mType)
+{
+#ifdef PTW32_MUTEX_TYPES
+ pthread_mutexattr_settype(&ma, mType);
+#endif
+ pthread_mutex_init(&mx, &ma);
+
+ TESTSTART
+ (void) pthread_mutex_trylock(&mx);
+ (void) pthread_mutex_unlock(&mx);
+ TESTSTOP
+
+ pthread_mutex_destroy(&mx);
+
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+
+ printf( "%-45s %15ld %15.3f\n",
+ testNameString,
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ pthread_mutexattr_init(&ma);
+
+ printf( "=============================================================================\n");
+ printf( "Trylock plus unlock on an unlocked mutex.\n");
+ printf( "%ld iterations.\n\n", ITERATIONS);
+ printf( "%-45s %15s %15s\n",
+ "Test",
+ "Total(msec)",
+ "average(usec)");
+ printf( "-----------------------------------------------------------------------------\n");
+
+ /*
+ * Time the loop overhead so we can subtract it from the actual test times.
+ */
+
+ TESTSTART
+ TESTSTOP
+
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+ overHeadMilliSecs = durationMilliSecs;
+
+ old_mutex_use = OLD_WIN32CS;
+ assert(old_mutex_init(&ox, NULL) == 0);
+ TESTSTART
+ (void) old_mutex_trylock(&ox);
+ (void) old_mutex_unlock(&ox);
+ TESTSTOP
+ assert(old_mutex_destroy(&ox) == 0);
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+ printf( "%-45s %15ld %15.3f\n",
+ "Old PT Mutex using a Critical Section (WNT)",
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+
+ old_mutex_use = OLD_WIN32MUTEX;
+ assert(old_mutex_init(&ox, NULL) == 0);
+ TESTSTART
+ (void) old_mutex_trylock(&ox);
+ (void) old_mutex_unlock(&ox);
+ TESTSTOP
+ assert(old_mutex_destroy(&ox) == 0);
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+ printf( "%-45s %15ld %15.3f\n",
+ "Old PT Mutex using a Win32 Mutex (W9x)",
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+
+ printf( ".............................................................................\n");
+
+ /*
+ * Now we can start the actual tests
+ */
+#ifdef PTW32_MUTEX_TYPES
+ runTest("PTHREAD_MUTEX_DEFAULT (W9x,WNT)", PTHREAD_MUTEX_DEFAULT);
+
+ runTest("PTHREAD_MUTEX_NORMAL (W9x,WNT)", PTHREAD_MUTEX_NORMAL);
+
+ runTest("PTHREAD_MUTEX_ERRORCHECK (W9x,WNT)", PTHREAD_MUTEX_ERRORCHECK);
+
+ runTest("PTHREAD_MUTEX_RECURSIVE (W9x,WNT)", PTHREAD_MUTEX_RECURSIVE);
+#else
+ runTest("Non-blocking lock", 0);
+#endif
+
+ printf( "=============================================================================\n");
+
+ /*
+ * End of tests.
+ */
+
+ pthread_mutexattr_destroy(&ma);
+
+ return 0;
+}
diff --git a/pthreads/tests/benchtest5.c b/pthreads/tests/benchtest5.c
new file mode 100644
index 000000000..7700fdeaa
--- /dev/null
+++ b/pthreads/tests/benchtest5.c
@@ -0,0 +1,159 @@
+/*
+ * benchtest5.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Measure time taken to complete an elementary operation.
+ *
+ * - Semaphore
+ * Single thread iteration over post/wait for a semaphore.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+#ifdef __GNUC__
+#include <stdlib.h>
+#endif
+
+#include "benchtest.h"
+
+#define ITERATIONS 1000000L
+
+sem_t sema;
+HANDLE w32sema;
+
+struct _timeb currSysTimeStart;
+struct _timeb currSysTimeStop;
+long durationMilliSecs;
+long overHeadMilliSecs = 0;
+int one = 1;
+int zero = 0;
+
+#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \
+ - (_TStart.time*1000+_TStart.millitm))
+
+/*
+ * Dummy use of j, otherwise the loop may be removed by the optimiser
+ * when doing the overhead timing with an empty loop.
+ */
+#define TESTSTART \
+ { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++;
+
+#define TESTSTOP \
+ }; _ftime(&currSysTimeStop); if (j + k == i) j++; }
+
+
+void
+reportTest (char * testNameString)
+{
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+
+ printf( "%-45s %15ld %15.3f\n",
+ testNameString,
+ durationMilliSecs,
+ (float) durationMilliSecs * 1E3 / ITERATIONS);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ printf( "=============================================================================\n");
+ printf( "\nOperations on a semaphore.\n%ld iterations\n\n",
+ ITERATIONS);
+ printf( "%-45s %15s %15s\n",
+ "Test",
+ "Total(msec)",
+ "average(usec)");
+ printf( "-----------------------------------------------------------------------------\n");
+
+ /*
+ * Time the loop overhead so we can subtract it from the actual test times.
+ */
+
+ TESTSTART
+ assert(1 == one);
+ TESTSTOP
+
+ durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs;
+ overHeadMilliSecs = durationMilliSecs;
+
+
+ /*
+ * Now we can start the actual tests
+ */
+ assert((w32sema = CreateSemaphore(NULL, (long) 0, (long) ITERATIONS, NULL)) != 0);
+ TESTSTART
+ assert(ReleaseSemaphore(w32sema, 1, NULL) != zero);
+ TESTSTOP
+ assert(CloseHandle(w32sema) != 0);
+
+ reportTest("W32 Post with no waiters");
+
+
+ assert((w32sema = CreateSemaphore(NULL, (long) ITERATIONS, (long) ITERATIONS, NULL)) != 0);
+ TESTSTART
+ assert(WaitForSingleObject(w32sema, INFINITE) == WAIT_OBJECT_0);
+ TESTSTOP
+ assert(CloseHandle(w32sema) != 0);
+
+ reportTest("W32 Wait without blocking");
+
+
+ assert(sem_init(&sema, 0, 0) == 0);
+ TESTSTART
+ assert(sem_post(&sema) == zero);
+ TESTSTOP
+ assert(sem_destroy(&sema) == 0);
+
+ reportTest("POSIX Post with no waiters");
+
+
+ assert(sem_init(&sema, 0, ITERATIONS) == 0);
+ TESTSTART
+ assert(sem_wait(&sema) == zero);
+ TESTSTOP
+ assert(sem_destroy(&sema) == 0);
+
+ reportTest("POSIX Wait without blocking");
+
+
+ printf( "=============================================================================\n");
+
+ /*
+ * End of tests.
+ */
+
+ return 0;
+}
diff --git a/pthreads/tests/cancel1.c b/pthreads/tests/cancel1.c
new file mode 100644
index 000000000..be9b102a5
--- /dev/null
+++ b/pthreads/tests/cancel1.c
@@ -0,0 +1,179 @@
+/*
+ * File: cancel1.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 setting cancel state and cancel type.
+ * -
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * - pthread_setcancelstate function
+ * - pthread_setcanceltype function
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - pthread_create, pthread_self work.
+ *
+ * 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 = 2
+};
+
+typedef struct bag_t_ bag_t;
+struct bag_t_ {
+ int threadnum;
+ int started;
+ /* Add more per-thread state variables here */
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+void *
+mythread(void * arg)
+{
+ bag_t * bag = (bag_t *) arg;
+
+ assert(bag == &threadbag[bag->threadnum]);
+ assert(bag->started == 0);
+ bag->started = 1;
+
+ /* ... */
+ {
+ int oldstate;
+ int oldtype;
+
+ assert(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) == 0);
+ assert(oldstate == PTHREAD_CANCEL_ENABLE); /* Check default */
+ assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
+ assert(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) == 0);
+ assert(pthread_setcancelstate(oldstate, &oldstate) == 0);
+ assert(oldstate == PTHREAD_CANCEL_DISABLE); /* Check setting */
+
+ assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype) == 0);
+ assert(oldtype == PTHREAD_CANCEL_DEFERRED); /* Check default */
+ assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0);
+ assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
+ assert(pthread_setcanceltype(oldtype, &oldtype) == 0);
+ assert(oldtype == PTHREAD_CANCEL_ASYNCHRONOUS); /* Check setting */
+ }
+
+ return 0;
+}
+
+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.
+ */
+
+ /*
+ * Give threads time to run.
+ */
+ Sleep(NUMTHREADS * 1000);
+
+ /*
+ * Standard check that all threads started.
+ */
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ failed = !threadbag[i].started;
+
+ if (failed)
+ {
+ fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
+ }
+ }
+
+ assert(!failed);
+
+ /*
+ * Check any results here. Set "failed" and only print ouput on failure.
+ */
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ /* ... */
+ }
+
+ assert(!failed);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
diff --git a/pthreads/tests/cancel2.c b/pthreads/tests/cancel2.c
new file mode 100644
index 000000000..6ef2043e2
--- /dev/null
+++ b/pthreads/tests/cancel2.c
@@ -0,0 +1,251 @@
+/*
+ * File: cancel2.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 SEH or C++ cancel exception handling within
+ * application exception blocks.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#if defined(_MSC_VER) || defined(__cplusplus)
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+ NUMTHREADS = 1
+};
+
+typedef struct bag_t_ bag_t;
+struct bag_t_ {
+ int threadnum;
+ int started;
+ /* Add more per-thread state variables here */
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+static pthread_mutex_t waitLock = PTHREAD_MUTEX_INITIALIZER;
+
+void *
+mythread(void * arg)
+{
+ int result = 0;
+ 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);
+
+ switch (bag->threadnum % 2)
+ {
+ case 0:
+ assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
+ result = 0;
+ break;
+ case 1:
+ assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0);
+ result = 1;
+ break;
+ }
+
+#if defined(_MSC_VER) && !defined(__cplusplus)
+ __try
+#else
+ try
+#endif
+ {
+ /* Wait for go from main */
+ assert(pthread_mutex_lock(&waitLock) == 0);
+ assert(pthread_mutex_unlock(&waitLock) == 0);
+ sched_yield();
+
+ for (;;)
+ {
+ pthread_testcancel();
+ }
+ }
+#if defined(_MSC_VER) && !defined(__cplusplus)
+ __except(EXCEPTION_EXECUTE_HANDLER)
+#else
+#if defined(PtW32CatchAll)
+ PtW32CatchAll
+#else
+ catch(...)
+#endif
+#endif
+ {
+ /*
+ * Should not get into here.
+ */
+ result += 100;
+ }
+
+ /*
+ * Should not get to here either.
+ */
+ result += 1000;
+
+ return (void *) result;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ pthread_t t[NUMTHREADS + 1];
+
+ assert((t[0] = pthread_self()).p != NULL);
+ assert(pthread_mutex_lock(&waitLock) == 0);
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ threadbag[i].started = 0;
+ threadbag[i].threadnum = i;
+ assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
+ }
+
+ /*
+ * Code to control or munipulate child threads should probably go here.
+ */
+ Sleep(500);
+
+ assert(pthread_mutex_unlock(&waitLock) == 0);
+
+ 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;
+
+ assert(pthread_join(t[i], (void **) &result) == 0);
+ fail = (result != (int) PTHREAD_CANCELED);
+ if (fail)
+ {
+ fprintf(stderr, "Thread %d: started %d: location %d: cancel type %s\n",
+ i,
+ threadbag[i].started,
+ result,
+ ((result % 2) == 0) ? "ASYNCHRONOUS" : "DEFERRED");
+ }
+ failed |= fail;
+ }
+
+ assert(!failed);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
+
+#else /* defined(_MSC_VER) || defined(__cplusplus) */
+
+int
+main()
+{
+ return 0;
+}
+
+#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/pthreads/tests/cancel3.c b/pthreads/tests/cancel3.c
new file mode 100644
index 000000000..1560ccfd2
--- /dev/null
+++ b/pthreads/tests/cancel3.c
@@ -0,0 +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;
+}
diff --git a/pthreads/tests/cancel4.c b/pthreads/tests/cancel4.c
new file mode 100644
index 000000000..6d6d3dc7b
--- /dev/null
+++ b/pthreads/tests/cancel4.c
@@ -0,0 +1,203 @@
+/*
+ * File: cancel4.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 cancelation does not occur in deferred
+ * cancelation threads with no cancelation points.
+ *
+ * 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:
+ * - pthread_create
+ * pthread_self
+ * pthread_cancel
+ * pthread_join
+ * pthread_setcancelstate
+ * pthread_setcanceltype
+ *
+ * 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_DEFERRED, NULL) == 0);
+
+ /*
+ * We wait up to 2 seconds, waking every 0.1 seconds,
+ * for a cancelation to be applied to us.
+ */
+ for (bag->count = 0; bag->count < 20; 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 indicates that async
+ * cancelation occurred.
+ */
+ 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;
+}
diff --git a/pthreads/tests/cancel5.c b/pthreads/tests/cancel5.c
new file mode 100644
index 000000000..dd6cb8bae
--- /dev/null
+++ b/pthreads/tests/cancel5.c
@@ -0,0 +1,199 @@
+/*
+ * File: cancel5.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 calling pthread_cancel from the main thread
+ * without calling pthread_self() in main.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum
+{
+ NUMTHREADS = 4
+};
+
+typedef struct bag_t_ bag_t;
+struct bag_t_
+{
+ int threadnum;
+ int started;
+ /* Add more per-thread state variables here */
+ int count;
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+void *
+mythread (void *arg)
+{
+ int result = ((int) PTHREAD_CANCELED + 1);
+ bag_t *bag = (bag_t *) arg;
+
+ assert (bag == &threadbag[bag->threadnum]);
+ assert (bag->started == 0);
+ bag->started = 1;
+
+ /* Set to known state and type */
+
+ assert (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) == 0);
+
+ assert (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
+
+ /*
+ * We wait up to 10 seconds, waking every 0.1 seconds,
+ * for a cancelation to be applied to us.
+ */
+ for (bag->count = 0; bag->count < 100; bag->count++)
+ Sleep (100);
+
+ return (void *) result;
+}
+
+int
+main ()
+{
+ int failed = 0;
+ int i;
+ pthread_t t[NUMTHREADS + 1];
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ threadbag[i].started = 0;
+ threadbag[i].threadnum = i;
+ assert (pthread_create (&t[i], NULL, mythread, (void *) &threadbag[i])
+ == 0);
+ }
+
+ /*
+ * Code to control or munipulate child threads should probably go here.
+ */
+ Sleep (500);
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ assert (pthread_cancel (t[i]) == 0);
+ }
+
+ /*
+ * Give threads time to run.
+ */
+ Sleep (NUMTHREADS * 100);
+
+ /*
+ * Standard check that all threads started.
+ */
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ if (!threadbag[i].started)
+ {
+ failed |= !threadbag[i].started;
+ fprintf (stderr, "Thread %d: started %d\n", i,
+ threadbag[i].started);
+ }
+ }
+
+ assert (!failed);
+
+ /*
+ * Check any results here. Set "failed" and only print output on failure.
+ */
+ failed = 0;
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ int fail = 0;
+ int result = 0;
+
+ /*
+ * The thread does not contain any cancelation points, so
+ * a return value of PTHREAD_CANCELED confirms that async
+ * cancelation succeeded.
+ */
+ assert (pthread_join (t[i], (void **) &result) == 0);
+
+ fail = (result != (int) PTHREAD_CANCELED);
+
+ if (fail)
+ {
+ fprintf (stderr, "Thread %d: started %d: count %d\n",
+ i, threadbag[i].started, threadbag[i].count);
+ }
+ failed = (failed || fail);
+ }
+
+ assert (!failed);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
diff --git a/pthreads/tests/cancel6a.c b/pthreads/tests/cancel6a.c
new file mode 100644
index 000000000..644cd4a53
--- /dev/null
+++ b/pthreads/tests/cancel6a.c
@@ -0,0 +1,191 @@
+/*
+ * File: cancel6a.c
+ *
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright (C) 1998 Ben Elliston and Ross Johnson
+ * Copyright (C) 1999,2000,2001 Ross Johnson
+ *
+ * Contact Email: rpj@ise.canberra.edu.au
+ *
+ * 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.1 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis: Test double cancelation - asynchronous.
+ * Second attempt should fail (ESRCH).
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#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);
+ assert(pthread_cancel(t[i]) == ESRCH);
+ }
+
+ /*
+ * 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;
+}
diff --git a/pthreads/tests/cancel6d.c b/pthreads/tests/cancel6d.c
new file mode 100644
index 000000000..d0ad7ac2c
--- /dev/null
+++ b/pthreads/tests/cancel6d.c
@@ -0,0 +1,190 @@
+/*
+ * File: cancel6d.c
+ *
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright (C) 1998 Ben Elliston and Ross Johnson
+ * Copyright (C) 1999,2000,2001 Ross Johnson
+ *
+ * Contact Email: rpj@ise.canberra.edu.au
+ *
+ * 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.1 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis: Test double cancelation - deferred.
+ * Second attempt should succeed (unless the canceled thread has started
+ * cancelation already - not tested here).
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#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_DEFERRED, 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);
+ pthread_testcancel();
+ }
+
+ 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);
+ 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;
+
+ 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;
+}
diff --git a/pthreads/tests/cancel7.c b/pthreads/tests/cancel7.c
new file mode 100644
index 000000000..9fb2e6166
--- /dev/null
+++ b/pthreads/tests/cancel7.c
@@ -0,0 +1,216 @@
+/*
+ * File: cancel7.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 canceling a Win32 thread having created an
+ * implicit POSIX handle for it.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validate return value and that POSIX handle is created and destroyed.
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+#ifndef _UWIN
+#include <process.h>
+#endif
+
+/*
+ * 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;
+ pthread_t self;
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+unsigned __stdcall
+#else
+void
+#endif
+Win32thread(void * arg)
+{
+ int i;
+ bag_t * bag = (bag_t *) arg;
+
+ assert(bag == &threadbag[bag->threadnum]);
+ assert(bag->started == 0);
+ bag->started = 1;
+
+ assert((bag->self = pthread_self()).p != NULL);
+ assert(pthread_kill(bag->self, 0) == 0);
+
+ for (i = 0; i < 100; i++)
+ {
+ Sleep(100);
+ pthread_testcancel();
+ }
+
+ return 0;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ HANDLE h[NUMTHREADS + 1];
+ unsigned thrAddr; /* Dummy variable to pass a valid location to _beginthreadex (Win98). */
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ threadbag[i].started = 0;
+ threadbag[i].threadnum = i;
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+ h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, &thrAddr);
+#else
+ h[i] = (HANDLE) _beginthread(Win32thread, 0, (void *) &threadbag[i]);
+#endif
+ }
+
+ /*
+ * Code to control or munipulate child threads should probably go here.
+ */
+ Sleep(500);
+
+ /*
+ * Cancel all threads.
+ */
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ assert(pthread_kill(threadbag[i].self, 0) == 0);
+ assert(pthread_cancel(threadbag[i].self) == 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;
+
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+ assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE);
+#else
+ /*
+ * Can't get a result code.
+ */
+ result = (int) PTHREAD_CANCELED;
+#endif
+
+ assert(threadbag[i].self.p != NULL);
+ assert(pthread_kill(threadbag[i].self, 0) == ESRCH);
+
+ 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;
+}
+
diff --git a/pthreads/tests/cancel8.c b/pthreads/tests/cancel8.c
new file mode 100644
index 000000000..69eafe98e
--- /dev/null
+++ b/pthreads/tests/cancel8.c
@@ -0,0 +1,217 @@
+/*
+ * File: cancel8.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 cancelling a blocked Win32 thread having created an
+ * implicit POSIX handle for it.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validate return value and that POSIX handle is created and destroyed.
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+#ifndef _UWIN
+#include <process.h>
+#endif
+
+/*
+ * 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;
+ pthread_t self;
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+pthread_cond_t CV = PTHREAD_COND_INITIALIZER;
+pthread_mutex_t CVLock = PTHREAD_MUTEX_INITIALIZER;
+
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+unsigned __stdcall
+#else
+void
+#endif
+Win32thread(void * arg)
+{
+ bag_t * bag = (bag_t *) arg;
+
+ assert(bag == &threadbag[bag->threadnum]);
+ assert(bag->started == 0);
+ bag->started = 1;
+
+ assert((bag->self = pthread_self()).p != NULL);
+ assert(pthread_kill(bag->self, 0) == 0);
+
+ assert(pthread_mutex_lock(&CVLock) == 0);
+ pthread_cleanup_push(pthread_mutex_unlock, &CVLock);
+ pthread_cond_wait(&CV, &CVLock);
+ pthread_cleanup_pop(1);
+
+ return 0;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ HANDLE h[NUMTHREADS + 1];
+ unsigned thrAddr; /* Dummy variable to pass a valid location to _beginthreadex (Win98). */
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ threadbag[i].started = 0;
+ threadbag[i].threadnum = i;
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+ h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, &thrAddr);
+#else
+ h[i] = (HANDLE) _beginthread(Win32thread, 0, (void *) &threadbag[i]);
+#endif
+ }
+
+ /*
+ * Code to control or munipulate child threads should probably go here.
+ */
+ Sleep(500);
+
+ /*
+ * Cancel all threads.
+ */
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ assert(pthread_kill(threadbag[i].self, 0) == 0);
+ assert(pthread_cancel(threadbag[i].self) == 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;
+
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+ assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE);
+#else
+ /*
+ * Can't get a result code.
+ */
+ result = (int) PTHREAD_CANCELED;
+#endif
+
+ assert(threadbag[i].self.p != NULL);
+ assert(pthread_kill(threadbag[i].self, 0) == ESRCH);
+
+ 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;
+}
+
diff --git a/pthreads/tests/cancel9.c b/pthreads/tests/cancel9.c
new file mode 100644
index 000000000..b0091614a
--- /dev/null
+++ b/pthreads/tests/cancel9.c
@@ -0,0 +1,202 @@
+/*
+ * File: cancel9.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 true asynchronous cancelation with Alert driver.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * - Cancel threads, including those blocked on system recources
+ * such as network I/O.
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+#include <windows.h>
+
+
+void *
+test_udp (void *arg)
+{
+ struct sockaddr_in serverAddress;
+ struct sockaddr_in clientAddress;
+ SOCKET UDPSocket;
+ int addr_len;
+ int nbyte, bytes;
+ char buffer[4096];
+ WORD wsaVersion = MAKEWORD (2, 2);
+ WSADATA wsaData;
+
+ pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
+ pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+
+ if (WSAStartup (wsaVersion, &wsaData) != 0)
+ {
+ return NULL;
+ }
+
+ UDPSocket = socket (AF_INET, SOCK_DGRAM, 0);
+ if ((int)UDPSocket == -1)
+ {
+ printf ("Server: socket ERROR \n");
+ exit (-1);
+ }
+
+ serverAddress.sin_family = AF_INET;
+ serverAddress.sin_addr.s_addr = INADDR_ANY;
+ serverAddress.sin_port = htons (9003);
+
+ if (bind
+ (UDPSocket, (struct sockaddr *) &serverAddress,
+ sizeof (struct sockaddr_in)))
+ {
+ printf ("Server: ERROR can't bind UDPSocket");
+ exit (-1);
+ }
+
+ addr_len = sizeof (struct sockaddr);
+
+ nbyte = 512;
+
+ bytes =
+ recvfrom (UDPSocket, (char *) buffer, nbyte, 0,
+ (struct sockaddr *) &clientAddress, &addr_len);
+
+ closesocket (UDPSocket);
+ WSACleanup ();
+
+ return NULL;
+}
+
+
+void *
+test_sleep (void *arg)
+{
+ pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
+ pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+
+ Sleep (1000);
+ return NULL;
+
+}
+
+void *
+test_wait (void *arg)
+{
+ HANDLE hEvent;
+ DWORD dwEvent;
+
+ pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
+ pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+
+ hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+
+ dwEvent = WaitForSingleObject (hEvent, 1000); /* WAIT_IO_COMPLETION */
+
+ return NULL;
+}
+
+
+int
+main ()
+{
+ pthread_t t;
+ void *result;
+
+ if (pthread_win32_test_features_np (PTW32_ALERTABLE_ASYNC_CANCEL))
+ {
+ printf ("Cancel sleeping thread.\n");
+ assert (pthread_create (&t, NULL, test_sleep, NULL) == 0);
+ /* Sleep for a while; then cancel */
+ Sleep (100);
+ assert (pthread_cancel (t) == 0);
+ assert (pthread_join (t, &result) == 0);
+ assert (result == PTHREAD_CANCELED && "test_sleep" != NULL);
+
+ printf ("Cancel waiting thread.\n");
+ assert (pthread_create (&t, NULL, test_wait, NULL) == 0);
+ /* Sleep for a while; then cancel. */
+ Sleep (100);
+ assert (pthread_cancel (t) == 0);
+ assert (pthread_join (t, &result) == 0);
+ assert (result == PTHREAD_CANCELED && "test_wait");
+
+ printf ("Cancel blocked thread (blocked on network I/O).\n");
+ assert (pthread_create (&t, NULL, test_udp, NULL) == 0);
+ /* Sleep for a while; then cancel. */
+ Sleep (100);
+ assert (pthread_cancel (t) == 0);
+ assert (pthread_join (t, &result) == 0);
+ assert (result == PTHREAD_CANCELED && "test_udp" != NULL);
+ }
+ else
+ {
+ printf ("Alertable async cancel not available.\n");
+ }
+
+ /*
+ * Success.
+ */
+ return 0;
+}
diff --git a/pthreads/tests/cleanup0.c b/pthreads/tests/cleanup0.c
new file mode 100644
index 000000000..77626eb66
--- /dev/null
+++ b/pthreads/tests/cleanup0.c
@@ -0,0 +1,229 @@
+/*
+ * File: cleanup1.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 cleanup handler executes (when thread is not canceled).
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#if defined(_MSC_VER) || defined(__cplusplus)
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+ NUMTHREADS = 10
+};
+
+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];
+
+typedef struct {
+ int i;
+ CRITICAL_SECTION cs;
+} sharedInt_t;
+
+static sharedInt_t pop_count = {0, {0}};
+
+static void
+increment_pop_count(void * arg)
+{
+ sharedInt_t * sI = (sharedInt_t *) arg;
+
+ EnterCriticalSection(&sI->cs);
+ sI->i++;
+ LeaveCriticalSection(&sI->cs);
+}
+
+void *
+mythread(void * arg)
+{
+ int result = 0;
+ 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);
+
+#ifdef _MSC_VER
+#pragma inline_depth(0)
+#endif
+ pthread_cleanup_push(increment_pop_count, (void *) &pop_count);
+
+ Sleep(100);
+
+ pthread_cleanup_pop(1);
+#ifdef _MSC_VER
+#pragma inline_depth()
+#endif
+
+ return (void *) result;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ pthread_t t[NUMTHREADS + 1];
+
+ InitializeCriticalSection(&pop_count.cs);
+
+ 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);
+
+ /*
+ * 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;
+
+ assert(pthread_join(t[i], (void **) &result) == 0);
+
+ fail = (result == (int) PTHREAD_CANCELED);
+
+ if (fail)
+ {
+ fprintf(stderr, "Thread %d: started %d: result %d\n",
+ i,
+ threadbag[i].started,
+ result);
+ fflush(stderr);
+ }
+ failed = (failed || fail);
+ }
+
+ assert(!failed);
+
+ assert(pop_count.i == NUMTHREADS);
+
+ DeleteCriticalSection(&pop_count.cs);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
+
+#else /* defined(_MSC_VER) || defined(__cplusplus) */
+
+int
+main()
+{
+ return 0;
+}
+
+#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/pthreads/tests/cleanup1.c b/pthreads/tests/cleanup1.c
new file mode 100644
index 000000000..385aed959
--- /dev/null
+++ b/pthreads/tests/cleanup1.c
@@ -0,0 +1,242 @@
+/*
+ * File: cleanup1.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 cleanup handler executes (when thread is canceled).
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#if defined(_MSC_VER) || defined(__cplusplus)
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+ NUMTHREADS = 10
+};
+
+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];
+
+typedef struct {
+ int i;
+ CRITICAL_SECTION cs;
+} sharedInt_t;
+
+static sharedInt_t pop_count = {0, {0}};
+
+static void
+#ifdef __CLEANUP_C
+__cdecl
+#endif
+increment_pop_count(void * arg)
+{
+ sharedInt_t * sI = (sharedInt_t *) arg;
+
+ EnterCriticalSection(&sI->cs);
+ sI->i++;
+ LeaveCriticalSection(&sI->cs);
+}
+
+void *
+mythread(void * arg)
+{
+ int result = 0;
+ 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);
+
+#ifdef _MSC_VER
+#pragma inline_depth(0)
+#endif
+ pthread_cleanup_push(increment_pop_count, (void *) &pop_count);
+ /*
+ * We don't have true async cancelation - it relies on the thread
+ * at least re-entering the run state at some point.
+ * 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);
+
+ pthread_cleanup_pop(0);
+#ifdef _MSC_VER
+#pragma inline_depth()
+#endif
+
+ return (void *) result;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ pthread_t t[NUMTHREADS + 1];
+
+ InitializeCriticalSection(&pop_count.cs);
+
+ 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;
+
+ assert(pthread_join(t[i], (void **) &result) == 0);
+
+ fail = (result != (int) PTHREAD_CANCELED);
+
+ if (fail)
+ {
+ fprintf(stderr, "Thread %d: started %d: result %d\n",
+ i,
+ threadbag[i].started,
+ result);
+ }
+ failed = (failed || fail);
+ }
+
+ assert(!failed);
+
+ assert(pop_count.i == NUMTHREADS);
+
+ DeleteCriticalSection(&pop_count.cs);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
+
+#else /* defined(_MSC_VER) || defined(__cplusplus) */
+
+int
+main()
+{
+ return 0;
+}
+
+#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/pthreads/tests/cleanup2.c b/pthreads/tests/cleanup2.c
new file mode 100644
index 000000000..4c639181b
--- /dev/null
+++ b/pthreads/tests/cleanup2.c
@@ -0,0 +1,217 @@
+/*
+ * File: cleanup2.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 cleanup handler executes (when thread is not canceled).
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#if defined(_MSC_VER) || defined(__cplusplus)
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+ NUMTHREADS = 10
+};
+
+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];
+
+typedef struct {
+ int i;
+ CRITICAL_SECTION cs;
+} sharedInt_t;
+
+static sharedInt_t pop_count = {0, {0}};
+
+static void
+increment_pop_count(void * arg)
+{
+ sharedInt_t * sI = (sharedInt_t *) arg;
+
+ EnterCriticalSection(&sI->cs);
+ sI->i++;
+ LeaveCriticalSection(&sI->cs);
+}
+
+void *
+mythread(void * arg)
+{
+ int result = 0;
+ bag_t * bag = (bag_t *) arg;
+
+ assert(bag == &threadbag[bag->threadnum]);
+ assert(bag->started == 0);
+ bag->started = 1;
+
+#ifdef _MSC_VER
+#pragma inline_depth(0)
+#endif
+ pthread_cleanup_push(increment_pop_count, (void *) &pop_count);
+
+ sched_yield();
+
+ pthread_cleanup_pop(1);
+#ifdef _MSC_VER
+#pragma inline_depth()
+#endif
+
+ return (void *) result;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ pthread_t t[NUMTHREADS + 1];
+
+ InitializeCriticalSection(&pop_count.cs);
+
+ 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(1000);
+
+ /*
+ * 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;
+
+ assert(pthread_join(t[i], (void **) &result) == 0);
+
+ fail = (result != 0);
+
+ if (fail)
+ {
+ fprintf(stderr, "Thread %d: started %d: result: %d\n",
+ i,
+ threadbag[i].started,
+ result);
+ }
+ failed = (failed || fail);
+ }
+
+ assert(!failed);
+
+ assert(pop_count.i == NUMTHREADS);
+
+ DeleteCriticalSection(&pop_count.cs);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
+
+#else /* defined(_MSC_VER) || defined(__cplusplus) */
+
+int
+main()
+{
+ return 0;
+}
+
+#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/pthreads/tests/cleanup3.c b/pthreads/tests/cleanup3.c
new file mode 100644
index 000000000..b595ab43c
--- /dev/null
+++ b/pthreads/tests/cleanup3.c
@@ -0,0 +1,222 @@
+/*
+ * File: cleanup3.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 cleanup handler does not execute (when thread is
+ * not canceled).
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#if defined(_MSC_VER) || defined(__cplusplus)
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+ NUMTHREADS = 10
+};
+
+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];
+
+typedef struct {
+ int i;
+ CRITICAL_SECTION cs;
+} sharedInt_t;
+
+static sharedInt_t pop_count = {0, {0}};
+
+static void
+increment_pop_count(void * arg)
+{
+ sharedInt_t * sI = (sharedInt_t *) arg;
+
+ EnterCriticalSection(&sI->cs);
+ sI->i++;
+ LeaveCriticalSection(&sI->cs);
+}
+
+void *
+mythread(void * arg)
+{
+ int result = 0;
+ bag_t * bag = (bag_t *) arg;
+
+ assert(bag == &threadbag[bag->threadnum]);
+ assert(bag->started == 0);
+ bag->started = 1;
+
+#ifdef _MSC_VER
+#pragma inline_depth(0)
+#endif
+ pthread_cleanup_push(increment_pop_count, (void *) &pop_count);
+
+ sched_yield();
+
+ EnterCriticalSection(&pop_count.cs);
+ pop_count.i--;
+ LeaveCriticalSection(&pop_count.cs);
+
+ pthread_cleanup_pop(0);
+#ifdef _MSC_VER
+#pragma inline_depth()
+#endif
+
+ return (void *) result;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ pthread_t t[NUMTHREADS + 1];
+
+ InitializeCriticalSection(&pop_count.cs);
+
+ 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(1000);
+
+ /*
+ * 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;
+
+ assert(pthread_join(t[i], (void **) &result) == 0);
+
+ fail = (result != 0);
+
+ if (fail)
+ {
+ fprintf(stderr, "Thread %d: started %d: result: %d\n",
+ i,
+ threadbag[i].started,
+ result);
+ }
+ failed = (failed || fail);
+ }
+
+ assert(!failed);
+
+ assert(pop_count.i == -(NUMTHREADS));
+
+ DeleteCriticalSection(&pop_count.cs);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
+
+#else /* defined(_MSC_VER) || defined(__cplusplus) */
+
+int
+main()
+{
+ return 0;
+}
+
+#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/pthreads/tests/condvar1.c b/pthreads/tests/condvar1.c
new file mode 100644
index 000000000..380ab1aff
--- /dev/null
+++ b/pthreads/tests/condvar1.c
@@ -0,0 +1,97 @@
+/*
+ * File: condvar1.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 initialisation and destruction of a CV.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - Creates and then imediately destroys a CV. Does not
+ * test the CV.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - pthread_cond_init returns 0, and
+ * - pthread_cond_destroy returns 0.
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - pthread_cond_init returns non-zero, or
+ * - pthread_cond_destroy returns non-zero.
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+static pthread_cond_t cv = NULL;
+
+int
+main()
+{
+ assert(cv == NULL);
+
+ assert(pthread_cond_init(&cv, NULL) == 0);
+
+ assert(cv != NULL);
+
+ assert(pthread_cond_destroy(&cv) == 0);
+
+ assert(cv == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/condvar1_1.c b/pthreads/tests/condvar1_1.c
new file mode 100644
index 000000000..a05e113b9
--- /dev/null
+++ b/pthreads/tests/condvar1_1.c
@@ -0,0 +1,115 @@
+/*
+ * File: condvar1_1.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - Test CV linked list management.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation:
+ * Initiate and destroy several CVs in random order.
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - Creates and then imediately destroys a CV. Does not
+ * test the CV.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - All initialised CVs destroyed without segfault.
+ * - Successfully broadcasts all remaining CVs after
+ * each CV is removed.
+ *
+ * Fail Criteria:
+ */
+
+#include <stdlib.h>
+#include "test.h"
+
+enum {
+ NUM_CV = 100
+};
+
+static pthread_cond_t cv[NUM_CV];
+
+int
+main()
+{
+ int i, j;
+
+ for (i = 0; i < NUM_CV; i++)
+ {
+ /* Traverse the list before every init of a CV. */
+ assert(pthread_timechange_handler_np(NULL) == (void *) 0);
+ assert(pthread_cond_init(&cv[i], NULL) == 0);
+ }
+
+ j = NUM_CV;
+ (void) srand((unsigned)time(NULL));
+
+ do
+ {
+ i = (NUM_CV - 1) * rand() / RAND_MAX;
+ if (cv[i] != NULL)
+ {
+ j--;
+ assert(pthread_cond_destroy(&cv[i]) == 0);
+ /* Traverse the list every time we remove a CV. */
+ assert(pthread_timechange_handler_np(NULL) == (void *) 0);
+ }
+ }
+ while (j > 0);
+
+ return 0;
+}
diff --git a/pthreads/tests/condvar1_2.c b/pthreads/tests/condvar1_2.c
new file mode 100644
index 000000000..503e821b6
--- /dev/null
+++ b/pthreads/tests/condvar1_2.c
@@ -0,0 +1,124 @@
+/*
+ * File: condvar1_2.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - Test CV linked list management and serialisation.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation:
+ * Initiate and destroy several CVs in random order.
+ * Asynchronously traverse the CV list and broadcast.
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - Creates and then imediately destroys a CV. Does not
+ * test the CV.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - All initialised CVs destroyed without segfault.
+ * - Successfully broadcasts all remaining CVs after
+ * each CV is removed.
+ *
+ * Fail Criteria:
+ */
+
+#include <stdlib.h>
+#include "test.h"
+
+enum {
+ NUM_CV = 5,
+ NUM_LOOPS = 5
+};
+
+static pthread_cond_t cv[NUM_CV];
+
+int
+main()
+{
+ int i, j, k;
+ int result = -1;
+ pthread_t t;
+
+ for (k = 0; k < NUM_LOOPS; k++)
+ {
+ for (i = 0; i < NUM_CV; i++)
+ {
+ assert(pthread_cond_init(&cv[i], NULL) == 0);
+ }
+
+ j = NUM_CV;
+ (void) srand((unsigned)time(NULL));
+
+ /* Traverse the list asynchronously. */
+ assert(pthread_create(&t, NULL, pthread_timechange_handler_np, NULL) == 0);
+
+ do
+ {
+ i = (NUM_CV - 1) * rand() / RAND_MAX;
+ if (cv[i] != NULL)
+ {
+ j--;
+ assert(pthread_cond_destroy(&cv[i]) == 0);
+ }
+ }
+ while (j > 0);
+
+ assert(pthread_join(t, (void **) &result) == 0);
+ assert (result == 0);
+ }
+
+ return 0;
+}
diff --git a/pthreads/tests/condvar2.c b/pthreads/tests/condvar2.c
new file mode 100644
index 000000000..33f1d3f1d
--- /dev/null
+++ b/pthreads/tests/condvar2.c
@@ -0,0 +1,125 @@
+/*
+ * File: condvar2.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 timed wait on a CV.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - Because the CV is never signaled, we expect the wait to time out.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - pthread_cond_timedwait returns ETIMEDOUT.
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - pthread_cond_timedwait does not return ETIMEDOUT.
+ * - Process returns non-zero exit status.
+ */
+
+#define _WIN32_WINNT 0x400
+
+#include "test.h"
+#include <sys/timeb.h>
+
+pthread_cond_t cv;
+pthread_mutex_t mutex;
+
+#include "../implement.h"
+
+int
+main()
+{
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ assert(pthread_cond_init(&cv, NULL) == 0);
+
+ assert(pthread_mutex_init(&mutex, NULL) == 0);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ /* get current system time */
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 1;
+
+ assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == ETIMEDOUT);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ {
+ int result = pthread_cond_destroy(&cv);
+ if (result != 0)
+ {
+ fprintf(stderr, "Result = %s\n", error_string[result]);
+ fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked);
+ fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone);
+ fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock);
+ fflush(stderr);
+ }
+ assert(result == 0);
+ }
+
+ return 0;
+}
diff --git a/pthreads/tests/condvar2_1.c b/pthreads/tests/condvar2_1.c
new file mode 100644
index 000000000..92dddfd9a
--- /dev/null
+++ b/pthreads/tests/condvar2_1.c
@@ -0,0 +1,153 @@
+/*
+ * File: condvar2_1.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - Test timeout of multiple waits on a CV with no signal/broadcast.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - Because the CV is never signaled, we expect the waits to time out.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - pthread_cond_timedwait returns ETIMEDOUT.
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - pthread_cond_timedwait does not return ETIMEDOUT.
+ * - Process returns non-zero exit status.
+ */
+
+#define _WIN32_WINNT 0x400
+
+#include "test.h"
+#include <sys/timeb.h>
+
+static pthread_cond_t cv;
+static pthread_mutex_t mutex;
+static struct timespec abstime = { 0, 0 };
+
+enum {
+ NUMTHREADS = 30
+};
+
+void *
+mythread(void * arg)
+{
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == ETIMEDOUT);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ return arg;
+}
+
+#include "../implement.h"
+
+int
+main()
+{
+ int i;
+ pthread_t t[NUMTHREADS + 1];
+ int result = 0;
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ assert(pthread_cond_init(&cv, NULL) == 0);
+
+ assert(pthread_mutex_init(&mutex, NULL) == 0);
+
+ /* get current system time */
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 5;
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0);
+ }
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ assert(pthread_join(t[i], (void **) &result) == 0);
+ assert(result == i);
+ }
+
+ {
+ int result = pthread_cond_destroy(&cv);
+ if (result != 0)
+ {
+ fprintf(stderr, "Result = %s\n", error_string[result]);
+ fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked);
+ fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone);
+ fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock);
+ fflush(stderr);
+ }
+ assert(result == 0);
+ }
+
+ return 0;
+}
diff --git a/pthreads/tests/condvar3.c b/pthreads/tests/condvar3.c
new file mode 100644
index 000000000..e3a23f54f
--- /dev/null
+++ b/pthreads/tests/condvar3.c
@@ -0,0 +1,148 @@
+/*
+ * File: condvar3.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - Test basic function of a CV
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - The primary thread takes the lock before creating any threads.
+ * The secondary thread blocks on the lock allowing the primary
+ * thread to enter the cv wait state which releases the lock.
+ * The secondary thread then takes the lock and signals the waiting
+ * primary thread.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - pthread_cond_timedwait returns 0.
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - pthread_cond_timedwait returns ETIMEDOUT.
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+static pthread_cond_t cv;
+static pthread_mutex_t mutex;
+static int shared = 0;
+
+enum {
+ NUMTHREADS = 2 /* Including the primary thread. */
+};
+
+void *
+mythread(void * arg)
+{
+ int result = 0;
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+ shared++;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ if ((result = pthread_cond_signal(&cv)) != 0)
+ {
+ printf("Error = %s\n", error_string[result]);
+ }
+ assert(result == 0);
+
+
+ return (void *) 0;
+}
+
+int
+main()
+{
+ pthread_t t[NUMTHREADS];
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ assert((t[0] = pthread_self()).p != NULL);
+
+ assert(pthread_cond_init(&cv, NULL) == 0);
+
+ assert(pthread_mutex_init(&mutex, NULL) == 0);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ /* get current system time */
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0);
+
+ abstime.tv_sec += 5;
+
+ while (! (shared > 0))
+ assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == 0);
+
+ assert(shared > 0);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ assert(pthread_join(t[1], NULL) == 0);
+
+ assert(pthread_cond_destroy(&cv) == 0);
+
+ return 0;
+}
diff --git a/pthreads/tests/condvar3_1.c b/pthreads/tests/condvar3_1.c
new file mode 100644
index 000000000..25a50e4bb
--- /dev/null
+++ b/pthreads/tests/condvar3_1.c
@@ -0,0 +1,201 @@
+/*
+ * File: condvar3_1.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - Test timeout of multiple waits on a CV with some signaled.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - Because some CVs are never signaled, we expect their waits to time out.
+ * Some are signaled, the rest time out. Pthread_cond_destroy() will fail
+ * unless all are accounted for, either signaled or timedout.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - pthread_cond_timedwait returns ETIMEDOUT.
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - pthread_cond_timedwait does not return ETIMEDOUT.
+ * - Process returns non-zero exit status.
+ */
+
+#define _WIN32_WINNT 0x400
+
+#include "test.h"
+#include <sys/timeb.h>
+
+static pthread_cond_t cv;
+static pthread_cond_t cv1;
+static pthread_mutex_t mutex;
+static pthread_mutex_t mutex1;
+static struct timespec abstime = { 0, 0 };
+static int timedout = 0;
+static int signaled = 0;
+static int awoken = 0;
+static int waiting = 0;
+
+enum {
+ NUMTHREADS = 30
+};
+
+void *
+mythread(void * arg)
+{
+ int result;
+
+ assert(pthread_mutex_lock(&mutex1) == 0);
+ ++waiting;
+ assert(pthread_mutex_unlock(&mutex1) == 0);
+ assert(pthread_cond_signal(&cv1) == 0);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+ result = pthread_cond_timedwait(&cv, &mutex, &abstime);
+ if (result == ETIMEDOUT)
+ {
+ timedout++;
+ }
+ else
+ {
+ awoken++;
+ }
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ return arg;
+}
+
+#include "../implement.h"
+
+int
+main()
+{
+ int i;
+ pthread_t t[NUMTHREADS + 1];
+ int result = 0;
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ assert(pthread_cond_init(&cv, NULL) == 0);
+ assert(pthread_cond_init(&cv1, NULL) == 0);
+
+ assert(pthread_mutex_init(&mutex, NULL) == 0);
+ assert(pthread_mutex_init(&mutex1, NULL) == 0);
+
+ /* get current system time */
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 5;
+
+ assert(pthread_mutex_lock(&mutex1) == 0);
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0);
+ }
+
+ do {
+ assert(pthread_cond_wait(&cv1,&mutex1) == 0);
+ } while ( NUMTHREADS > waiting );
+
+ assert(pthread_mutex_unlock(&mutex1) == 0);
+
+ for (i = NUMTHREADS/3; i <= 2*NUMTHREADS/3; i++)
+ {
+// assert(pthread_mutex_lock(&mutex) == 0);
+ assert(pthread_cond_signal(&cv) == 0);
+// assert(pthread_mutex_unlock(&mutex) == 0);
+
+ signaled++;
+ }
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ assert(pthread_join(t[i], (void **) &result) == 0);
+ assert(result == i);
+ }
+
+ fprintf(stderr, "awk = %d\n", awoken);
+ fprintf(stderr, "sig = %d\n", signaled);
+ fprintf(stderr, "tot = %d\n", timedout);
+
+ assert(signaled == awoken);
+ assert(timedout == NUMTHREADS - signaled);
+
+ assert(pthread_cond_destroy(&cv1) == 0);
+
+ {
+ int result = pthread_cond_destroy(&cv);
+ if (result != 0)
+ {
+ fprintf(stderr, "Result = %s\n", error_string[result]);
+ fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked);
+ fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone);
+ fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock);
+ fflush(stderr);
+ }
+ assert(result == 0);
+ }
+
+ assert(pthread_mutex_destroy(&mutex1) == 0);
+ assert(pthread_mutex_destroy(&mutex) == 0);
+
+ return 0;
+}
diff --git a/pthreads/tests/condvar3_2.c b/pthreads/tests/condvar3_2.c
new file mode 100644
index 000000000..5ddcf5748
--- /dev/null
+++ b/pthreads/tests/condvar3_2.c
@@ -0,0 +1,193 @@
+/*
+ * File: condvar3_2.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - Test timeout of multiple waits on a CV with remainder broadcast awoken.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - Because some CVs are never signaled, we expect their waits to time out.
+ * Some time out, the rest are broadcast signaled. Pthread_cond_destroy() will fail
+ * unless all are accounted for, either signaled or timedout.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - pthread_cond_timedwait returns ETIMEDOUT.
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - pthread_cond_timedwait does not return ETIMEDOUT.
+ * - Process returns non-zero exit status.
+ */
+
+#define _WIN32_WINNT 0x400
+
+#include "test.h"
+#include <sys/timeb.h>
+
+static pthread_cond_t cv;
+static pthread_mutex_t mutex;
+static struct timespec abstime = { 0, 0 };
+static struct timespec abstime2 = { 0, 0 };
+static int timedout = 0;
+static int awoken = 0;
+
+enum {
+ NUMTHREADS = 30
+};
+
+void *
+mythread(void * arg)
+{
+ int result;
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ abstime2.tv_sec = abstime.tv_sec;
+
+ if ((int) arg % 3 == 0)
+ {
+ abstime2.tv_sec += 2;
+ }
+
+ result = pthread_cond_timedwait(&cv, &mutex, &abstime2);
+ assert(pthread_mutex_unlock(&mutex) == 0);
+ if (result == ETIMEDOUT)
+ {
+ InterlockedIncrement((LPLONG)&timedout);
+ }
+ else
+ {
+ InterlockedIncrement((LPLONG)&awoken);
+ }
+
+
+ return arg;
+}
+
+#include "../implement.h"
+
+int
+main()
+{
+ int i;
+ pthread_t t[NUMTHREADS + 1];
+ int result = 0;
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ assert(pthread_cond_init(&cv, NULL) == 0);
+
+ assert(pthread_mutex_init(&mutex, NULL) == 0);
+
+ /* get current system time */
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = abstime.tv_sec = currSysTime.time + 5;
+ abstime.tv_nsec = abstime2.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0);
+ }
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ assert(pthread_join(t[i], (void **) &result) == 0);
+ assert(result == i);
+ /*
+ * Approximately 2/3rds of the threads are expected to time out.
+ * Signal the remainder after some threads have woken up and exited
+ * and while some are still waking up after timeout.
+ * Also tests that redundant broadcasts don't return errors.
+ */
+
+// assert(pthread_mutex_lock(&mutex) == 0);
+
+ if (InterlockedExchangeAdd((LPLONG)&awoken, 0L) > NUMTHREADS/3)
+ {
+ assert(pthread_cond_broadcast(&cv) == 0);
+ }
+
+// assert(pthread_mutex_unlock(&mutex) == 0);
+
+ }
+
+ assert(awoken == NUMTHREADS - timedout);
+
+ {
+ int result = pthread_cond_destroy(&cv);
+ if (result != 0)
+ {
+ fprintf(stderr, "Result = %s\n", error_string[result]);
+ fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked);
+ fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone);
+ fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock);
+ fflush(stderr);
+ }
+ assert(result == 0);
+ }
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+
+ return 0;
+}
diff --git a/pthreads/tests/condvar3_3.c b/pthreads/tests/condvar3_3.c
new file mode 100644
index 000000000..fe6763249
--- /dev/null
+++ b/pthreads/tests/condvar3_3.c
@@ -0,0 +1,132 @@
+/*
+ * File: condvar3_3.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - Test timeouts and lost signals on a CV.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - pthread_cond_timedwait returns ETIMEDOUT.
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - pthread_cond_timedwait does not return ETIMEDOUT.
+ * - Process returns non-zero exit status.
+ */
+
+/* Timur Aydin (taydin@snet.net) */
+
+#include "test.h"
+
+#include <sys/timeb.h>
+
+pthread_cond_t cnd;
+pthread_mutex_t mtx;
+
+int main()
+{
+ int rc;
+
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ assert(pthread_cond_init(&cnd, 0) == 0);
+ assert(pthread_mutex_init(&mtx, 0) == 0);
+
+ /* get current system time */
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+ abstime.tv_sec += 1;
+
+ /* Here pthread_cond_timedwait should time out after one second. */
+
+ assert(pthread_mutex_lock(&mtx) == 0);
+
+ assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT);
+
+ assert(pthread_mutex_unlock(&mtx) == 0);
+
+ /* Here, the condition variable is signaled, but there are no
+ threads waiting on it. The signal should be lost and
+ the next pthread_cond_timedwait should time out too. */
+
+// assert(pthread_mutex_lock(&mtx) == 0);
+
+ assert((rc = pthread_cond_signal(&cnd)) == 0);
+
+// assert(pthread_mutex_unlock(&mtx) == 0);
+
+ assert(pthread_mutex_lock(&mtx) == 0);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+ abstime.tv_sec += 1;
+
+ assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT);
+
+ assert(pthread_mutex_unlock(&mtx) == 0);
+
+ return 0;
+}
diff --git a/pthreads/tests/condvar4.c b/pthreads/tests/condvar4.c
new file mode 100644
index 000000000..3babeeac5
--- /dev/null
+++ b/pthreads/tests/condvar4.c
@@ -0,0 +1,169 @@
+/*
+ * File: condvar4.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - Test PTHREAD_COND_INITIALIZER.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - Test basic CV function but starting with a static initialised
+ * CV.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - pthread_cond_timedwait returns 0.
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - pthread_cond_timedwait returns ETIMEDOUT.
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+typedef struct cvthing_t_ cvthing_t;
+
+struct cvthing_t_ {
+ pthread_cond_t notbusy;
+ pthread_mutex_t lock;
+ int shared;
+};
+
+static cvthing_t cvthing = {
+ PTHREAD_COND_INITIALIZER,
+ PTHREAD_MUTEX_INITIALIZER,
+ 0
+};
+
+enum {
+ NUMTHREADS = 2
+};
+
+void *
+mythread(void * arg)
+{
+ assert(pthread_mutex_lock(&cvthing.lock) == 0);
+ cvthing.shared++;
+ assert(pthread_mutex_unlock(&cvthing.lock) == 0);
+
+ assert(pthread_cond_signal(&cvthing.notbusy) == 0);
+
+ return (void *) 0;
+}
+
+int
+main()
+{
+ pthread_t t[NUMTHREADS];
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ cvthing.shared = 0;
+
+ assert((t[0] = pthread_self()).p != NULL);
+
+ assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
+
+ assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
+
+ assert(pthread_mutex_lock(&cvthing.lock) == 0);
+
+ assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER);
+
+ /* get current system time */
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 5;
+
+ assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT);
+
+ assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER);
+
+ assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0);
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 5;
+
+ while (! (cvthing.shared > 0))
+ assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
+
+ assert(cvthing.shared > 0);
+
+ assert(pthread_mutex_unlock(&cvthing.lock) == 0);
+
+ assert(pthread_join(t[1], NULL) == 0);
+
+ assert(pthread_mutex_destroy(&cvthing.lock) == 0);
+
+ assert(cvthing.lock == NULL);
+
+ assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
+
+ assert(cvthing.notbusy == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/condvar5.c b/pthreads/tests/condvar5.c
new file mode 100644
index 000000000..4d51f396a
--- /dev/null
+++ b/pthreads/tests/condvar5.c
@@ -0,0 +1,168 @@
+/*
+ * File: condvar5.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - Test pthread_cond_broadcast.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - Test broadcast with one waiting CV.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - pthread_cond_timedwait returns 0.
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - pthread_cond_timedwait returns ETIMEDOUT.
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+typedef struct cvthing_t_ cvthing_t;
+
+struct cvthing_t_ {
+ pthread_cond_t notbusy;
+ pthread_mutex_t lock;
+ int shared;
+};
+
+static cvthing_t cvthing = {
+ PTHREAD_COND_INITIALIZER,
+ PTHREAD_MUTEX_INITIALIZER,
+ 0
+};
+
+enum {
+ NUMTHREADS = 2
+};
+
+void *
+mythread(void * arg)
+{
+ assert(pthread_mutex_lock(&cvthing.lock) == 0);
+ cvthing.shared++;
+ assert(pthread_mutex_unlock(&cvthing.lock) == 0);
+
+ assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
+
+ return (void *) 0;
+}
+
+int
+main()
+{
+ pthread_t t[NUMTHREADS];
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ cvthing.shared = 0;
+
+ assert((t[0] = pthread_self()).p != NULL);
+
+ assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
+
+ assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
+
+ assert(pthread_mutex_lock(&cvthing.lock) == 0);
+
+ assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER);
+
+ /* get current system time */
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 5;
+
+ assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT);
+
+ assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER);
+
+ assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0);
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 5;
+
+ while (! (cvthing.shared > 0))
+ assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
+
+ assert(cvthing.shared > 0);
+
+ assert(pthread_mutex_unlock(&cvthing.lock) == 0);
+
+ assert(pthread_join(t[1], NULL) == 0);
+
+ assert(pthread_mutex_destroy(&cvthing.lock) == 0);
+
+ assert(cvthing.lock == NULL);
+
+ assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
+
+ assert(cvthing.notbusy == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/condvar6.c b/pthreads/tests/condvar6.c
new file mode 100644
index 000000000..e63132c5d
--- /dev/null
+++ b/pthreads/tests/condvar6.c
@@ -0,0 +1,242 @@
+/*
+ * File: condvar6.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - Test pthread_cond_broadcast.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - Test broadcast with NUMTHREADS (=5) waiting CVs.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+ NUMTHREADS = 5
+};
+
+typedef struct bag_t_ bag_t;
+struct bag_t_ {
+ int threadnum;
+ int started;
+ /* Add more per-thread state variables here */
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+typedef struct cvthing_t_ cvthing_t;
+
+struct cvthing_t_ {
+ pthread_cond_t notbusy;
+ pthread_mutex_t lock;
+ int shared;
+};
+
+static cvthing_t cvthing = {
+ PTHREAD_COND_INITIALIZER,
+ PTHREAD_MUTEX_INITIALIZER,
+ 0
+};
+
+static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER;
+
+static struct timespec abstime = { 0, 0 };
+
+static int awoken;
+
+void *
+mythread(void * arg)
+{
+ bag_t * bag = (bag_t *) arg;
+
+ assert(bag == &threadbag[bag->threadnum]);
+ assert(bag->started == 0);
+ bag->started = 1;
+
+ /* Wait for the start gun */
+ assert(pthread_mutex_lock(&start_flag) == 0);
+ assert(pthread_mutex_unlock(&start_flag) == 0);
+
+ assert(pthread_mutex_lock(&cvthing.lock) == 0);
+
+ while (! (cvthing.shared > 0))
+ assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
+
+ assert(cvthing.shared > 0);
+
+ awoken++;
+
+ assert(pthread_mutex_unlock(&cvthing.lock) == 0);
+
+ return (void *) 0;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ pthread_t t[NUMTHREADS + 1];
+
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ cvthing.shared = 0;
+
+ assert((t[0] = pthread_self()).p != NULL);
+
+ assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
+
+ assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
+
+ assert(pthread_mutex_lock(&start_flag) == 0);
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 5;
+
+ assert((t[0] = pthread_self()).p != NULL);
+
+ awoken = 0;
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ threadbag[i].started = 0;
+ threadbag[i].threadnum = i;
+ assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
+ }
+
+ /*
+ * Code to control or munipulate child threads should probably go here.
+ */
+
+ assert(pthread_mutex_unlock(&start_flag) == 0);
+
+ /*
+ * Give threads time to start.
+ */
+ Sleep(1000);
+
+ assert(pthread_mutex_lock(&cvthing.lock) == 0);
+ cvthing.shared++;
+ assert(pthread_mutex_unlock(&cvthing.lock) == 0);
+
+ assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
+
+ /*
+ * Give threads time to complete.
+ */
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ assert(pthread_join(t[i], NULL) == 0);
+ }
+
+ /*
+ * Cleanup the CV.
+ */
+
+ assert(pthread_mutex_destroy(&cvthing.lock) == 0);
+
+ assert(cvthing.lock == NULL);
+
+ assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
+
+ assert(cvthing.notbusy == NULL);
+
+ /*
+ * Standard check that all threads started.
+ */
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ failed = !threadbag[i].started;
+
+ if (failed)
+ {
+ fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
+ }
+ }
+
+ assert(!failed);
+
+ /*
+ * Check any results here.
+ */
+
+ assert(awoken == NUMTHREADS);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
+
+
diff --git a/pthreads/tests/condvar7.c b/pthreads/tests/condvar7.c
new file mode 100644
index 000000000..6d89f2ea9
--- /dev/null
+++ b/pthreads/tests/condvar7.c
@@ -0,0 +1,257 @@
+/*
+ * File: condvar7.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - Test pthread_cond_broadcast with thread cancelation.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - Test broadcast with NUMTHREADS (=5) waiting CVs, one is canceled while waiting.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+ NUMTHREADS = 5
+};
+
+typedef struct bag_t_ bag_t;
+struct bag_t_ {
+ int threadnum;
+ int started;
+ /* Add more per-thread state variables here */
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+typedef struct cvthing_t_ cvthing_t;
+
+struct cvthing_t_ {
+ pthread_cond_t notbusy;
+ pthread_mutex_t lock;
+ int shared;
+};
+
+static cvthing_t cvthing = {
+ PTHREAD_COND_INITIALIZER,
+ PTHREAD_MUTEX_INITIALIZER,
+ 0
+};
+
+static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER;
+
+static struct timespec abstime = { 0, 0 };
+
+static int awoken;
+
+void *
+mythread(void * arg)
+{
+ bag_t * bag = (bag_t *) arg;
+
+ assert(bag == &threadbag[bag->threadnum]);
+ assert(bag->started == 0);
+ bag->started = 1;
+
+ /* Wait for the start gun */
+ assert(pthread_mutex_lock(&start_flag) == 0);
+ assert(pthread_mutex_unlock(&start_flag) == 0);
+
+ assert(pthread_mutex_lock(&cvthing.lock) == 0);
+
+#ifdef _MSC_VER
+#pragma inline_depth(0)
+#endif
+ pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock);
+
+ while (! (cvthing.shared > 0))
+ assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
+
+ pthread_cleanup_pop(0);
+#ifdef _MSC_VER
+#pragma inline_depth()
+#endif
+
+ assert(cvthing.shared > 0);
+
+ awoken++;
+
+ assert(pthread_mutex_unlock(&cvthing.lock) == 0);
+
+ return (void *) 0;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ pthread_t t[NUMTHREADS + 1];
+
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ cvthing.shared = 0;
+
+ assert((t[0] = pthread_self()).p != NULL);
+
+ assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
+
+ assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
+
+ assert(pthread_mutex_lock(&start_flag) == 0);
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 10;
+
+ assert((t[0] = pthread_self()).p != NULL);
+
+ awoken = 0;
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ threadbag[i].started = 0;
+ threadbag[i].threadnum = i;
+ assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
+ }
+
+ /*
+ * Code to control or munipulate child threads should probably go here.
+ */
+
+ assert(pthread_mutex_unlock(&start_flag) == 0);
+
+ /*
+ * Give threads time to start.
+ */
+ Sleep(1000);
+
+ /*
+ * Cancel one of the threads.
+ */
+ assert(pthread_cancel(t[1]) == 0);
+ assert(pthread_join(t[1], NULL) == 0);
+
+ assert(pthread_mutex_lock(&cvthing.lock) == 0);
+ cvthing.shared++;
+ assert(pthread_mutex_unlock(&cvthing.lock) == 0);
+
+ /*
+ * Signal all remaining waiting threads.
+ */
+ assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
+
+ /*
+ * Wait for all threads to complete.
+ */
+ for (i = 2; i <= NUMTHREADS; i++)
+ assert(pthread_join(t[i], NULL) == 0);
+
+ /*
+ * Cleanup the CV.
+ */
+
+ assert(pthread_mutex_destroy(&cvthing.lock) == 0);
+
+ assert(cvthing.lock == NULL);
+
+ assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
+
+ assert(cvthing.notbusy == NULL);
+
+ /*
+ * Standard check that all threads started.
+ */
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ failed = !threadbag[i].started;
+
+ if (failed)
+ {
+ fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
+ }
+ }
+
+ assert(!failed);
+
+ /*
+ * Check any results here.
+ */
+
+ assert(awoken == (NUMTHREADS - 1));
+
+ /*
+ * Success.
+ */
+ return 0;
+}
diff --git a/pthreads/tests/condvar8.c b/pthreads/tests/condvar8.c
new file mode 100644
index 000000000..e384a1c9c
--- /dev/null
+++ b/pthreads/tests/condvar8.c
@@ -0,0 +1,258 @@
+/*
+ * File: condvar8.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - Test multiple pthread_cond_broadcasts.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - Make NUMTHREADS threads wait on CV, broadcast signal them, and then repeat.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+ NUMTHREADS = 5
+};
+
+typedef struct bag_t_ bag_t;
+struct bag_t_ {
+ int threadnum;
+ int started;
+ /* Add more per-thread state variables here */
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+typedef struct cvthing_t_ cvthing_t;
+
+struct cvthing_t_ {
+ pthread_cond_t notbusy;
+ pthread_mutex_t lock;
+ int shared;
+};
+
+static cvthing_t cvthing = {
+ PTHREAD_COND_INITIALIZER,
+ PTHREAD_MUTEX_INITIALIZER,
+ 0
+};
+
+static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER;
+
+static struct timespec abstime = { 0, 0 };
+
+static int awoken;
+
+static void *
+mythread(void * arg)
+{
+ bag_t * bag = (bag_t *) arg;
+
+ assert(bag == &threadbag[bag->threadnum]);
+ assert(bag->started == 0);
+ bag->started = 1;
+
+ /* Wait for the start gun */
+ assert(pthread_mutex_lock(&start_flag) == 0);
+ assert(pthread_mutex_unlock(&start_flag) == 0);
+
+ assert(pthread_mutex_lock(&cvthing.lock) == 0);
+
+#ifdef _MSC_VER
+#pragma inline_depth(0)
+#endif
+ pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock);
+
+ while (! (cvthing.shared > 0))
+ assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
+
+ pthread_cleanup_pop(0);
+#ifdef _MSC_VER
+#pragma inline_depth()
+#endif
+
+ assert(cvthing.shared > 0);
+
+ awoken++;
+
+ assert(pthread_mutex_unlock(&cvthing.lock) == 0);
+
+ return (void *) 0;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ int first, last;
+ pthread_t t[NUMTHREADS + 1];
+
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ assert((t[0] = pthread_self()).p != NULL);
+
+ assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
+
+ assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 10;
+
+ assert((t[0] = pthread_self()).p != NULL);
+
+ awoken = 0;
+
+ for (first = 1, last = NUMTHREADS / 2;
+ first < NUMTHREADS;
+ first = last + 1, last = NUMTHREADS)
+ {
+ assert(pthread_mutex_lock(&start_flag) == 0);
+
+ for (i = first; i <= last; i++)
+ {
+ threadbag[i].started = 0;
+ threadbag[i].threadnum = i;
+ assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
+ }
+
+ /*
+ * Code to control or munipulate child threads should probably go here.
+ */
+ cvthing.shared = 0;
+
+ assert(pthread_mutex_unlock(&start_flag) == 0);
+
+ /*
+ * Give threads time to start.
+ */
+ Sleep(100);
+
+ assert(pthread_mutex_lock(&cvthing.lock) == 0);
+ cvthing.shared++;
+ assert(pthread_mutex_unlock(&cvthing.lock) == 0);
+
+ assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
+
+ /*
+ * Give threads time to complete.
+ */
+ for (i = first; i <= last; i++)
+ {
+ assert(pthread_join(t[i], NULL) == 0);
+ }
+
+ assert(awoken == (i - 1));
+ }
+
+
+ /*
+ * Standard check that all threads started.
+ */
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ failed = !threadbag[i].started;
+
+ if (failed)
+ {
+ fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
+ }
+ }
+
+ /*
+ * Cleanup the CV.
+ */
+
+ assert(pthread_mutex_destroy(&cvthing.lock) == 0);
+
+ assert(cvthing.lock == NULL);
+
+ assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
+
+ assert(cvthing.notbusy == NULL);
+
+ assert(!failed);
+
+ /*
+ * Check any results here.
+ */
+
+ assert(awoken == NUMTHREADS);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
diff --git a/pthreads/tests/condvar9.c b/pthreads/tests/condvar9.c
new file mode 100644
index 000000000..c75127108
--- /dev/null
+++ b/pthreads/tests/condvar9.c
@@ -0,0 +1,267 @@
+/*
+ * File: condvar9.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - Test multiple pthread_cond_broadcasts with thread cancelation.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * - Make NUMTHREADS threads wait on CV, cancel one, broadcast signal them,
+ * and then repeat.
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+ NUMTHREADS = 9
+};
+
+typedef struct bag_t_ bag_t;
+struct bag_t_ {
+ int threadnum;
+ int started;
+ int finished;
+ /* Add more per-thread state variables here */
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+typedef struct cvthing_t_ cvthing_t;
+
+struct cvthing_t_ {
+ pthread_cond_t notbusy;
+ pthread_mutex_t lock;
+ int shared;
+};
+
+static cvthing_t cvthing = {
+ PTHREAD_COND_INITIALIZER,
+ PTHREAD_MUTEX_INITIALIZER,
+ 0
+};
+
+static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER;
+
+static struct timespec abstime = { 0, 0 };
+
+static int awoken;
+
+static void *
+mythread(void * arg)
+{
+ bag_t * bag = (bag_t *) arg;
+
+ assert(bag == &threadbag[bag->threadnum]);
+ assert(bag->started == 0);
+ bag->started = 1;
+
+ /* Wait for the start gun */
+ assert(pthread_mutex_lock(&start_flag) == 0);
+ assert(pthread_mutex_unlock(&start_flag) == 0);
+
+ assert(pthread_mutex_lock(&cvthing.lock) == 0);
+
+ /*
+ * pthread_cond_timedwait is a cancelation point and we're
+ * going to cancel some threads deliberately.
+ */
+#ifdef _MSC_VER
+#pragma inline_depth(0)
+#endif
+ pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock);
+
+ while (! (cvthing.shared > 0))
+ assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
+
+ pthread_cleanup_pop(0);
+#ifdef _MSC_VER
+#pragma inline_depth()
+#endif
+
+ assert(cvthing.shared > 0);
+
+ awoken++;
+ bag->finished = 1;
+
+ assert(pthread_mutex_unlock(&cvthing.lock) == 0);
+
+ return (void *) 0;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ int first, last;
+ int canceledThreads = 0;
+ pthread_t t[NUMTHREADS + 1];
+
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ assert((t[0] = pthread_self()).p != NULL);
+
+ assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
+
+ assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 5;
+
+ assert((t[0] = pthread_self()).p != NULL);
+
+ awoken = 0;
+
+ for (first = 1, last = NUMTHREADS / 2;
+ first < NUMTHREADS;
+ first = last + 1, last = NUMTHREADS)
+ {
+ int ct;
+
+ assert(pthread_mutex_lock(&start_flag) == 0);
+
+ for (i = first; i <= last; i++)
+ {
+ threadbag[i].started = threadbag[i].finished = 0;
+ threadbag[i].threadnum = i;
+ assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
+ }
+
+ /*
+ * Code to control or munipulate child threads should probably go here.
+ */
+ cvthing.shared = 0;
+
+ assert(pthread_mutex_unlock(&start_flag) == 0);
+
+ /*
+ * Give threads time to start.
+ */
+ Sleep(1000);
+
+ ct = (first + last) / 2;
+ assert(pthread_cancel(t[ct]) == 0);
+ canceledThreads++;
+ assert(pthread_join(t[ct], NULL) == 0);
+
+ assert(pthread_mutex_lock(&cvthing.lock) == 0);
+ cvthing.shared++;
+ assert(pthread_mutex_unlock(&cvthing.lock) == 0);
+
+ assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
+
+ /*
+ * Standard check that all threads started - and wait for them to finish.
+ */
+ for (i = first; i <= last; i++)
+ {
+ failed = !threadbag[i].started;
+
+ if (failed)
+ {
+ fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
+ }
+ else
+ {
+ assert(pthread_join(t[i], NULL) == 0 || threadbag[i].finished == 0);
+// fprintf(stderr, "Thread %d: finished %d\n", i, threadbag[i].finished);
+ }
+ }
+ }
+
+ /*
+ * Cleanup the CV.
+ */
+
+ assert(pthread_mutex_destroy(&cvthing.lock) == 0);
+
+ assert(cvthing.lock == NULL);
+
+ assert_e(pthread_cond_destroy(&cvthing.notbusy), ==, 0);
+
+ assert(cvthing.notbusy == NULL);
+
+ assert(!failed);
+
+ /*
+ * Check any results here.
+ */
+
+ assert(awoken == NUMTHREADS - canceledThreads);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
diff --git a/pthreads/tests/context1.c b/pthreads/tests/context1.c
new file mode 100644
index 000000000..090df9c9d
--- /dev/null
+++ b/pthreads/tests/context1.c
@@ -0,0 +1,144 @@
+/*
+ * File: context1.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 context switching method.
+ *
+ * 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:
+ * - pthread_create
+ * pthread_exit
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#define _WIN32_WINNT 0x400
+
+#include "test.h"
+#include "../implement.h"
+
+static int washere = 0;
+
+static void * func(void * arg)
+{
+ washere = 1;
+
+ Sleep(1000);
+
+ return 0;
+}
+
+static void
+anotherEnding ()
+{
+ /*
+ * Switched context
+ */
+ washere++;
+
+ pthread_exit(0);
+}
+
+int
+main()
+{
+ pthread_t t;
+ HANDLE hThread;
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+
+ hThread = ((ptw32_thread_t *)t.p)->threadH;
+
+ Sleep(500);
+
+ SuspendThread(hThread);
+
+ if (WaitForSingleObject(hThread, 0) == WAIT_TIMEOUT)
+ {
+ /*
+ * Ok, thread did not exit before we got to it.
+ */
+ CONTEXT context;
+
+ context.ContextFlags = CONTEXT_CONTROL;
+
+ GetThreadContext(hThread, &context);
+ /*
+ *_x86 only!!!
+ */
+ context.Eip = (DWORD) anotherEnding;
+ SetThreadContext(hThread, &context);
+ ResumeThread(hThread);
+ }
+ else
+ {
+ printf("Exited early\n");
+ fflush(stdout);
+ }
+
+ Sleep(1000);
+
+ assert(washere == 2);
+
+ return 0;
+}
+
diff --git a/pthreads/tests/count1.c b/pthreads/tests/count1.c
new file mode 100644
index 000000000..c2386b0e9
--- /dev/null
+++ b/pthreads/tests/count1.c
@@ -0,0 +1,90 @@
+/*
+ * count1.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Description:
+ * Test some basic assertions about the number of threads at runtime.
+ */
+
+#include "test.h"
+
+#define NUMTHREADS (30)
+
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t threads[NUMTHREADS];
+static unsigned numThreads = 0;
+
+void *
+myfunc(void *arg)
+{
+ pthread_mutex_lock(&lock);
+ numThreads++;
+ pthread_mutex_unlock(&lock);
+
+ Sleep(1000);
+ return 0;
+}
+int
+main()
+{
+ int i;
+ int maxThreads = sizeof(threads) / sizeof(pthread_t);
+
+ /*
+ * Spawn NUMTHREADS threads. Each thread should increment the
+ * numThreads variable, sleep for one second.
+ */
+ for (i = 0; i < maxThreads; i++)
+ {
+ assert(pthread_create(&threads[i], NULL, myfunc, 0) == 0);
+ }
+
+ /*
+ * Wait for all the threads to exit.
+ */
+ for (i = 0; i < maxThreads; i++)
+ {
+ assert(pthread_join(threads[i], NULL) == 0);
+ }
+
+ /*
+ * Check the number of threads created.
+ */
+ assert((int) numThreads == maxThreads);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
diff --git a/pthreads/tests/create1.c b/pthreads/tests/create1.c
new file mode 100644
index 000000000..8c630cb93
--- /dev/null
+++ b/pthreads/tests/create1.c
@@ -0,0 +1,66 @@
+/*
+ * create1.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Description:
+ * Create a thread and check that it ran.
+ *
+ * Depends on API functions: None.
+ */
+
+#include "test.h"
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ washere = 1;
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+
+ /* A dirty hack, but we cannot rely on pthread_join in this
+ primitive test. */
+ Sleep(2000);
+
+ assert(washere == 1);
+
+ return 0;
+}
diff --git a/pthreads/tests/create2.c b/pthreads/tests/create2.c
new file mode 100644
index 000000000..2ffb64e08
--- /dev/null
+++ b/pthreads/tests/create2.c
@@ -0,0 +1,108 @@
+/*
+ * File: create2.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 that threads have a Win32 handle when started.
+ *
+ * Test Method (Validation or Falsification):
+ * - Statistical, not absolute (depends on sample size).
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+enum {
+ NUMTHREADS = 10000
+};
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ washere = 1;
+ return (void *) 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+ pthread_attr_t attr;
+ void * result = NULL;
+ int i;
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+ for (i = 0; i < NUMTHREADS; i++)
+ {
+ washere = 0;
+ assert(pthread_create(&t, &attr, func, NULL) == 0);
+ pthread_join(t, &result);
+ assert(washere == 1);
+ }
+
+ return 0;
+}
diff --git a/pthreads/tests/create3.c b/pthreads/tests/create3.c
new file mode 100644
index 000000000..98bd5200e
--- /dev/null
+++ b/pthreads/tests/create3.c
@@ -0,0 +1,122 @@
+/*
+ * 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 <stdlib.h>
+#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/delay1.c b/pthreads/tests/delay1.c
new file mode 100644
index 000000000..83becd890
--- /dev/null
+++ b/pthreads/tests/delay1.c
@@ -0,0 +1,51 @@
+/*
+ * delay1.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Depends on API functions:
+ * pthread_delay_np
+ */
+
+#include "test.h"
+
+int
+main(int argc, char * argv[])
+{
+ struct timespec interval = {1L, 500000000L};
+
+ assert(pthread_delay_np(&interval) == 0);
+
+ return 0;
+}
+
diff --git a/pthreads/tests/delay2.c b/pthreads/tests/delay2.c
new file mode 100644
index 000000000..8ecaf0b94
--- /dev/null
+++ b/pthreads/tests/delay2.c
@@ -0,0 +1,82 @@
+/*
+ * delay1.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Depends on API functions:
+ * pthread_delay_np
+ */
+
+#include "test.h"
+
+pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;
+
+void *
+func(void * arg)
+{
+ struct timespec interval = {5, 500000000L};
+
+ assert(pthread_mutex_lock(&mx) == 0);
+
+#ifdef _MSC_VER
+#pragma inline_depth(0)
+#endif
+ pthread_cleanup_push(pthread_mutex_unlock, &mx);
+ assert(pthread_delay_np(&interval) == 0);
+ pthread_cleanup_pop(1);
+#ifdef _MSC_VER
+#pragma inline_depth()
+#endif
+
+ return (void *) 1;
+}
+
+int
+main(int argc, char * argv[])
+{
+ pthread_t t;
+ int result = 0;
+
+ assert(pthread_mutex_lock(&mx) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+ assert(pthread_cancel(t) == 0);
+
+ assert(pthread_mutex_unlock(&mx) == 0);
+
+ assert(pthread_join(t, (void **) &result) == 0);
+ assert(result == (int) PTHREAD_CANCELED);
+
+ return 0;
+}
+
diff --git a/pthreads/tests/detach1.c b/pthreads/tests/detach1.c
new file mode 100644
index 000000000..165c8c1d1
--- /dev/null
+++ b/pthreads/tests/detach1.c
@@ -0,0 +1,93 @@
+/*
+ * Test for pthread_detach().
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Depends on API functions: pthread_create(), pthread_detach(), pthread_exit().
+ */
+
+#include "test.h"
+
+
+enum {
+ NUMTHREADS = 100
+};
+
+void *
+func(void * arg)
+{
+ int i = (int) arg;
+
+ Sleep(i * 10);
+
+ pthread_exit(arg);
+
+ /* Never reached. */
+ exit(1);
+}
+
+int
+main(int argc, char * argv[])
+{
+ pthread_t id[NUMTHREADS];
+ int i;
+
+ /* Create a few threads and then exit. */
+ for (i = 0; i < NUMTHREADS; i++)
+ {
+ assert(pthread_create(&id[i], NULL, func, (void *) i) == 0);
+ }
+
+ /* Some threads will finish before they are detached, some after. */
+ Sleep(NUMTHREADS/2 * 10 + 50);
+
+ for (i = 0; i < NUMTHREADS; i++)
+ {
+ assert(pthread_detach(id[i]) == 0);
+ }
+
+ Sleep(NUMTHREADS * 10 + 100);
+
+ /*
+ * Check that all threads are now invalid.
+ * This relies on unique thread IDs - e.g. works with
+ * pthreads-w32 or Solaris, but may not work for Linux, BSD etc.
+ */
+ for (i = 0; i < NUMTHREADS; i++)
+ {
+ assert(pthread_kill(id[i], 0) == ESRCH);
+ }
+
+ /* Success. */
+ return 0;
+}
diff --git a/pthreads/tests/equal1.c b/pthreads/tests/equal1.c
new file mode 100644
index 000000000..8932bb2aa
--- /dev/null
+++ b/pthreads/tests/equal1.c
@@ -0,0 +1,66 @@
+/*
+ * Test for pthread_equal.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Depends on functions: pthread_create().
+ */
+
+#include "test.h"
+
+void * func(void * arg)
+{
+ Sleep(2000);
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t1, t2;
+
+ assert(pthread_create(&t1, NULL, func, (void *) 1) == 0);
+
+ assert(pthread_create(&t2, NULL, func, (void *) 2) == 0);
+
+ assert(pthread_equal(t1, t2) == 0);
+
+ assert(pthread_equal(t1,t1) != 0);
+
+ /* This is a hack. We don't want to rely on pthread_join
+ yet if we can help it. */
+ Sleep(4000);
+
+ /* Success. */
+ return 0;
+}
diff --git a/pthreads/tests/errno1.c b/pthreads/tests/errno1.c
new file mode 100644
index 000000000..70ce92802
--- /dev/null
+++ b/pthreads/tests/errno1.c
@@ -0,0 +1,177 @@
+/*
+ * File: errno1.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 thread-safety of errno
+ * -
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+ NUMTHREADS = 3
+};
+
+typedef struct bag_t_ bag_t;
+struct bag_t_ {
+ int threadnum;
+ int started;
+ /* Add more per-thread state variables here */
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+pthread_mutex_t stop_here = PTHREAD_MUTEX_INITIALIZER;
+
+void *
+mythread(void * arg)
+{
+ bag_t * bag = (bag_t *) arg;
+
+ assert(bag == &threadbag[bag->threadnum]);
+ assert(bag->started == 0);
+ bag->started = 1;
+
+ errno = bag->threadnum;
+
+ Sleep(1000);
+
+ pthread_mutex_lock(&stop_here);
+
+ assert(errno == bag->threadnum);
+
+ pthread_mutex_unlock(&stop_here);
+
+ Sleep(1000);
+
+ return 0;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ pthread_t t[NUMTHREADS + 1];
+
+ pthread_mutex_lock(&stop_here);
+ errno = 0;
+
+ 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(2000);
+ pthread_mutex_unlock(&stop_here);
+
+ /*
+ * Give threads time to run.
+ */
+ Sleep(NUMTHREADS * 1000);
+
+ /*
+ * Standard check that all threads started.
+ */
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ failed = !threadbag[i].started;
+
+ if (failed)
+ {
+ fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
+ }
+ }
+
+ assert(!failed);
+
+ /*
+ * Check any results here. Set "failed" and only print ouput on failure.
+ */
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ /* ... */
+ }
+
+ assert(!failed);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
diff --git a/pthreads/tests/exception1.c b/pthreads/tests/exception1.c
new file mode 100644
index 000000000..3f9f59578
--- /dev/null
+++ b/pthreads/tests/exception1.c
@@ -0,0 +1,263 @@
+/*
+ * File: exception1.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 passing of exceptions back to the application.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#if defined(_MSC_VER) || defined(__cplusplus)
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+ NUMTHREADS = 4
+};
+
+void *
+exceptionedThread(void * arg)
+{
+ int dummy = 0;
+ int result = ((int)PTHREAD_CANCELED + 1);
+ /* Set to async cancelable */
+
+ assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
+
+ assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
+
+ Sleep(100);
+
+#if defined(_MSC_VER) && !defined(__cplusplus)
+ __try
+ {
+ int zero = (int) arg; /* Passed in from arg to avoid compiler error */
+ int one = 1;
+ /*
+ * The deliberate exception condition (zero divide) is
+ * in an "if" to avoid being optimised out.
+ */
+ if (dummy == one/zero)
+ Sleep(0);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Should get into here. */
+ result = ((int)PTHREAD_CANCELED + 2);
+ }
+#elif defined(__cplusplus)
+ try
+ {
+ /*
+ * I had a zero divide exception here but it
+ * wasn't being caught by the catch(...)
+ * below under Mingw32. That could be a problem.
+ */
+ throw dummy;
+ }
+#if defined(PtW32CatchAll)
+ PtW32CatchAll
+#else
+ catch (...)
+#endif
+ {
+ /* Should get into here. */
+ result = ((int)PTHREAD_CANCELED + 2);
+ }
+#endif
+
+ return (void *) result;
+}
+
+void *
+canceledThread(void * arg)
+{
+ int result = ((int)PTHREAD_CANCELED + 1);
+ int count;
+
+ /* Set to async cancelable */
+
+ assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
+
+ assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
+
+#if defined(_MSC_VER) && !defined(__cplusplus)
+ __try
+ {
+ /*
+ * We wait up to 10 seconds, waking every 0.1 seconds,
+ * for a cancelation to be applied to us.
+ */
+ for (count = 0; count < 100; count++)
+ Sleep(100);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Should NOT get into here. */
+ result = ((int)PTHREAD_CANCELED + 2);
+ }
+#elif defined(__cplusplus)
+ try
+ {
+ /*
+ * We wait up to 10 seconds, waking every 0.1 seconds,
+ * for a cancelation to be applied to us.
+ */
+ for (count = 0; count < 100; count++)
+ Sleep(100);
+ }
+#if defined(PtW32CatchAll)
+ PtW32CatchAll
+#else
+ catch (...)
+#endif
+ {
+ /* Should NOT get into here. */
+ result = ((int)PTHREAD_CANCELED + 2);
+ }
+#endif
+
+ return (void *) result;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ pthread_t mt;
+ pthread_t et[NUMTHREADS];
+ pthread_t ct[NUMTHREADS];
+
+ assert((mt = pthread_self()).p != NULL);
+
+ for (i = 0; i < NUMTHREADS; i++)
+ {
+ assert(pthread_create(&et[i], NULL, exceptionedThread, (void *) 0) == 0);
+ assert(pthread_create(&ct[i], NULL, canceledThread, NULL) == 0);
+ }
+
+ /*
+ * Code to control or munipulate child threads should probably go here.
+ */
+ Sleep(1000);
+
+ for (i = 0; i < NUMTHREADS; i++)
+ {
+ assert(pthread_cancel(ct[i]) == 0);
+ }
+
+ /*
+ * Give threads time to run.
+ */
+ Sleep(NUMTHREADS * 1000);
+
+ /*
+ * Check any results here. Set "failed" and only print output on failure.
+ */
+ failed = 0;
+ for (i = 0; i < NUMTHREADS; i++)
+ {
+ int fail = 0;
+ int result = 0;
+
+ /* Canceled thread */
+ assert(pthread_join(ct[i], (void **) &result) == 0);
+ assert(!(fail = (result != (int) PTHREAD_CANCELED)));
+
+ failed = (failed || fail);
+
+ /* Exceptioned thread */
+ assert(pthread_join(et[i], (void **) &result) == 0);
+ assert(!(fail = (result != ((int) PTHREAD_CANCELED + 2))));
+
+ failed = (failed || fail);
+ }
+
+ assert(!failed);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
+
+#else /* defined(_MSC_VER) || defined(__cplusplus) */
+
+#include <stdio.h>
+
+int
+main()
+{
+ fprintf(stderr, "Test N/A for this compiler environment.\n");
+ return 0;
+}
+
+#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/pthreads/tests/exception2.c b/pthreads/tests/exception2.c
new file mode 100644
index 000000000..5c1856810
--- /dev/null
+++ b/pthreads/tests/exception2.c
@@ -0,0 +1,158 @@
+/*
+ * File: exception2.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 passing of exceptions out of thread scope.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+
+#if defined(_MSC_VER) || defined(__cplusplus)
+
+#if defined(_MSC_VER) && defined(__cplusplus)
+#include <eh.h>
+#elif defined(__cplusplus)
+#include <exception>
+#endif
+
+#ifdef __GNUC__
+#include <stdlib.h>
+#endif
+
+#include "test.h"
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+ NUMTHREADS = 1
+};
+
+
+void *
+exceptionedThread(void * arg)
+{
+ int dummy = 0x1;
+
+#if defined(_MSC_VER) && !defined(__cplusplus)
+
+ RaiseException(dummy, 0, 0, NULL);
+
+#elif defined(__cplusplus)
+
+ throw dummy;
+
+#endif
+
+ return (void *) 100;
+}
+
+int
+main(int argc, char argv[])
+{
+ int i;
+ pthread_t mt;
+ pthread_t et[NUMTHREADS];
+
+ if (argc <= 1)
+ {
+ int result;
+
+ printf("You should see an \"abnormal termination\" message\n");
+ fflush(stdout);
+ result = system("exception2.exe die");
+ exit(0);
+ }
+
+ assert((mt = pthread_self()).p != NULL);
+
+ for (i = 0; i < NUMTHREADS; i++)
+ {
+ assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0);
+ }
+
+ Sleep(1000);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
+
+#else /* defined(_MSC_VER) || defined(__cplusplus) */
+
+#include <stdio.h>
+
+int
+main()
+{
+ fprintf(stderr, "Test N/A for this compiler environment.\n");
+ return 0;
+}
+
+#endif /* defined(_MSC_VER) || defined(__cplusplus) */
diff --git a/pthreads/tests/exception3.c b/pthreads/tests/exception3.c
new file mode 100644
index 000000000..9a70a405a
--- /dev/null
+++ b/pthreads/tests/exception3.c
@@ -0,0 +1,196 @@
+/*
+ * File: exception3.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 running of user supplied terminate() function.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+#if defined(__cplusplus)
+
+#if defined(_MSC_VER)
+# include <eh.h>
+#else
+# if defined(__GNUC__) && __GNUC__ < 3
+# include <new.h>
+# else
+# include <new>
+ using std::set_terminate;
+# endif
+#endif
+
+/*
+ * Create NUMTHREADS threads in addition to the Main thread.
+ */
+enum {
+ NUMTHREADS = 1
+};
+
+int caught = 0;
+pthread_mutex_t caughtLock;
+
+void
+terminateFunction ()
+{
+ assert(pthread_mutex_lock(&caughtLock) == 0);
+ caught++;
+#if 1
+ {
+ FILE * fp = fopen("pthread.log", "a");
+ fprintf(fp, "Caught = %d\n", caught);
+ fclose(fp);
+ }
+#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
+ * 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).
+ */
+ exit(0);
+#endif
+}
+
+void *
+exceptionedThread(void * arg)
+{
+ int dummy = 0x1;
+
+ (void) set_terminate(&terminateFunction);
+
+ throw dummy;
+
+ return (void *) 0;
+}
+
+int
+main()
+{
+ int i;
+ pthread_t mt;
+ pthread_t et[NUMTHREADS];
+ pthread_mutexattr_t ma;
+
+ assert((mt = pthread_self()).p != NULL);
+
+ printf("See the notes inside of exception3.c re term_funcs.\n");
+
+ assert(pthread_mutexattr_init(&ma) == 0);
+ assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0);
+ assert(pthread_mutex_init(&caughtLock, &ma) == 0);
+ assert(pthread_mutexattr_destroy(&ma) == 0);
+
+ for (i = 0; i < NUMTHREADS; i++)
+ {
+ assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0);
+ }
+
+ Sleep(5000);
+
+ assert(caught == NUMTHREADS);
+
+ /*
+ * Success.
+ */
+ return 0;
+}
+
+#else /* defined(__cplusplus) */
+
+#include <stdio.h>
+
+int
+main()
+{
+ fprintf(stderr, "Test N/A for this compiler environment.\n");
+ return 0;
+}
+
+#endif /* defined(__cplusplus) */
diff --git a/pthreads/tests/exit1.c b/pthreads/tests/exit1.c
new file mode 100644
index 000000000..38f218211
--- /dev/null
+++ b/pthreads/tests/exit1.c
@@ -0,0 +1,50 @@
+/*
+ * Test for pthread_exit().
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Depends on API functions: None.
+ */
+
+#include "test.h"
+
+int
+main(int argc, char * argv[])
+{
+ /* A simple test first. */
+ pthread_exit((void *) 0);
+
+ /* Not reached */
+ assert(0);
+ return 0;
+}
diff --git a/pthreads/tests/exit2.c b/pthreads/tests/exit2.c
new file mode 100644
index 000000000..196139a9f
--- /dev/null
+++ b/pthreads/tests/exit2.c
@@ -0,0 +1,64 @@
+/*
+ * Test for pthread_exit().
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_exit()
+ */
+
+#include "test.h"
+
+void *
+func(void * arg)
+{
+ pthread_exit(arg);
+
+ /* Never reached. */
+ assert(0);
+
+ return NULL;
+}
+
+int
+main(int argc, char * argv[])
+{
+ pthread_t t;
+
+ assert(pthread_create(&t, NULL, func, (void *) NULL) == 0);
+
+ Sleep(1000);
+
+ return 0;
+}
diff --git a/pthreads/tests/exit3.c b/pthreads/tests/exit3.c
new file mode 100644
index 000000000..574a92df7
--- /dev/null
+++ b/pthreads/tests/exit3.c
@@ -0,0 +1,68 @@
+/*
+ * Test for pthread_exit().
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Depends on API functions: pthread_create().
+ */
+
+#include "test.h"
+
+void *
+func(void * arg)
+{
+ pthread_exit(arg);
+
+ /* Never reached. */
+ assert(0);
+
+ return NULL;
+}
+
+int
+main(int argc, char * argv[])
+{
+ pthread_t id[4];
+ int i;
+
+ /* Create a few threads and then exit. */
+ for (i = 0; i < 4; i++)
+ {
+ assert(pthread_create(&id[i], NULL, func, (void *) i) == 0);
+ }
+
+ Sleep(1000);
+
+ /* Success. */
+ return 0;
+}
diff --git a/pthreads/tests/exit4.c b/pthreads/tests/exit4.c
new file mode 100644
index 000000000..1ceca4e35
--- /dev/null
+++ b/pthreads/tests/exit4.c
@@ -0,0 +1,199 @@
+/*
+ * File: exit4.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 calling pthread_exit from a Win32 thread
+ * without having created an implicit POSIX handle for it.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+#ifndef _UWIN
+#include <process.h>
+#endif
+
+/*
+ * 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];
+
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+unsigned __stdcall
+#else
+void
+#endif
+Win32thread(void * arg)
+{
+ int result = 1;
+ bag_t * bag = (bag_t *) arg;
+
+ assert(bag == &threadbag[bag->threadnum]);
+ assert(bag->started == 0);
+ bag->started = 1;
+
+ /*
+ * Doesn't return and doesn't create an implicit POSIX handle.
+ */
+ pthread_exit((void *) result);
+
+ return 0;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ HANDLE h[NUMTHREADS + 1];
+ unsigned thrAddr; /* Dummy variable to pass a valid location to _beginthreadex (Win98). */
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ threadbag[i].started = 0;
+ threadbag[i].threadnum = i;
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+ h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, &thrAddr);
+#else
+ h[i] = (HANDLE) _beginthread(Win32thread, 0, (void *) &threadbag[i]);
+#endif
+ }
+
+ /*
+ * Code to control or munipulate child threads should probably go here.
+ */
+ Sleep(500);
+
+ /*
+ * 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;
+
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+ assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE);
+#else
+ /*
+ * Can't get a result code.
+ */
+ result = 1;
+#endif
+
+ fail = (result != 1);
+
+ 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/exit5.c b/pthreads/tests/exit5.c
new file mode 100644
index 000000000..450ed3bea
--- /dev/null
+++ b/pthreads/tests/exit5.c
@@ -0,0 +1,205 @@
+/*
+ * File: exit5.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 calling pthread_exit from a Win32 thread
+ * having created an implicit POSIX handle for it.
+ *
+ * Test Method (Validation or Falsification):
+ * - Validate return value and that POSIX handle is created and destroyed.
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
+ * pthread_testcancel, pthread_cancel, pthread_join
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+#ifndef _UWIN
+#include <process.h>
+#endif
+
+/*
+ * 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;
+ pthread_t self;
+};
+
+static bag_t threadbag[NUMTHREADS + 1];
+
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+unsigned __stdcall
+#else
+void
+#endif
+Win32thread(void * arg)
+{
+ int result = 1;
+ bag_t * bag = (bag_t *) arg;
+
+ assert(bag == &threadbag[bag->threadnum]);
+ assert(bag->started == 0);
+ bag->started = 1;
+
+ assert((bag->self = pthread_self()).p != NULL);
+ assert(pthread_kill(bag->self, 0) == 0);
+
+ /*
+ * Doesn't return.
+ */
+ pthread_exit((void *) result);
+
+ return 0;
+}
+
+int
+main()
+{
+ int failed = 0;
+ int i;
+ HANDLE h[NUMTHREADS + 1];
+ unsigned thrAddr; /* Dummy variable to pass a valid location to _beginthreadex (Win98). */
+
+ for (i = 1; i <= NUMTHREADS; i++)
+ {
+ threadbag[i].started = 0;
+ threadbag[i].threadnum = i;
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+ h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, &thrAddr);
+#else
+ h[i] = (HANDLE) _beginthread(Win32thread, 0, (void *) &threadbag[i]);
+#endif
+ }
+
+ /*
+ * Code to control or munipulate child threads should probably go here.
+ */
+ Sleep(500);
+
+ /*
+ * 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;
+
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+ assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE);
+#else
+ /*
+ * Can't get a result code.
+ */
+ result = 1;
+#endif
+
+ assert(threadbag[i].self.p != NULL && pthread_kill(threadbag[i].self, 0) == ESRCH);
+
+ fail = (result != 1);
+
+ 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/eyal1.c b/pthreads/tests/eyal1.c
new file mode 100644
index 000000000..72b5697e9
--- /dev/null
+++ b/pthreads/tests/eyal1.c
@@ -0,0 +1,367 @@
+/* Simple POSIX threads program.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Author: Eyal Lebedinsky eyal@eyal.emu.id.au
+ * Written: Sep 1998.
+ * Version Date: 12 Sep 1998
+ *
+ * Do we need to lock stdout or is it thread safe?
+ *
+ * Used:
+ * pthread_t
+ * pthread_attr_t
+ * pthread_create()
+ * pthread_join()
+ * pthread_mutex_t
+ * PTHREAD_MUTEX_INITIALIZER
+ * pthread_mutex_init() [not used now]
+ * pthread_mutex_destroy()
+ * pthread_mutex_lock()
+ * pthread_mutex_trylock()
+ * pthread_mutex_unlock()
+ *
+ * What this program does is establish a work queue (implemented using
+ * four mutexes for each thread). It then schedules work (by storing
+ * a number in 'todo') and releases the threads. When the work is done
+ * the threads will block. The program then repeats the same thing once
+ * more (just to test the logic) and when the work is done it destroyes
+ * the threads.
+ *
+ * The 'work' we do is simply burning CPU cycles in a loop.
+ * The 'todo' work queue is trivial - each threads pops one element
+ * off it by incrementing it, the poped number is the 'work' to do.
+ * When 'todo' reaches the limit (nwork) the queue is considered
+ * empty.
+ *
+ * The number displayed at the end is the amount of work each thread
+ * did, so we can see if the load was properly distributed.
+ *
+ * The program was written to test a threading setup (not seen here)
+ * rather than to demonstrate correct usage of the pthread facilities.
+ *
+ * Note how each thread is given access to a thread control structure
+ * (TC) which is used for communicating to/from the main program (e.g.
+ * the threads knows its 'id' and also filles in the 'work' done).
+*/
+
+#include "test.h"
+
+#include <stdlib.h>
+#include <math.h>
+
+struct thread_control {
+ int id;
+ pthread_t thread; /* thread id */
+ pthread_mutex_t mutex_start;
+ pthread_mutex_t mutex_started;
+ pthread_mutex_t mutex_end;
+ pthread_mutex_t mutex_ended;
+ long work; /* work done */
+ int stat; /* pthread_init status */
+};
+
+typedef struct thread_control TC;
+
+static TC *tcs = NULL;
+static int nthreads = 10;
+static int nwork = 100;
+static int quiet = 0;
+
+static int todo = -1;
+
+static pthread_mutex_t mutex_todo = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t mutex_stdout = PTHREAD_MUTEX_INITIALIZER;
+
+
+static void
+die (int ret)
+{
+ if (NULL != tcs)
+ {
+ free (tcs);
+ tcs = NULL;
+ }
+
+ if (ret)
+ exit (ret);
+}
+
+
+static double
+waste_time (int n)
+{
+ int i;
+ double f, g, h, s;
+
+ s = 0.0;
+
+ /*
+ * Useless work.
+ */
+ for (i = n*100; i > 0; --i)
+ {
+ f = rand ();
+ g = rand ();
+ h = rand ();
+ s += 2.0 * f * g / (h != 0.0 ? (h * h) : 1.0);
+ }
+ return s;
+}
+
+static int
+do_work_unit (int who, int n)
+{
+ int i;
+ static int nchars = 0;
+ double f = 0.0;
+
+ if (quiet)
+ i = 0;
+ else {
+ /*
+ * get lock on stdout
+ */
+ assert(pthread_mutex_lock (&mutex_stdout) == 0);
+
+ /*
+ * do our job
+ */
+ i = printf ("%c", "0123456789abcdefghijklmnopqrstuvwxyz"[who]);
+
+ if (!(++nchars % 50))
+ printf ("\n");
+
+ fflush (stdout);
+
+ /*
+ * release lock on stdout
+ */
+ assert(pthread_mutex_unlock (&mutex_stdout) == 0);
+ }
+
+ n = rand () % 10000; /* ignore incoming 'n' */
+ f = waste_time (n);
+
+ /* This prevents the statement above from being optimised out */
+ if (f > 0.0)
+ return(n);
+
+ return (n);
+}
+
+static int
+print_server (void *ptr)
+{
+ int mywork;
+ int n;
+ TC *tc = (TC *)ptr;
+
+ assert(pthread_mutex_lock (&tc->mutex_started) == 0);
+
+ for (;;)
+ {
+ assert(pthread_mutex_lock (&tc->mutex_start) == 0);
+ assert(pthread_mutex_unlock (&tc->mutex_start) == 0);
+ assert(pthread_mutex_lock (&tc->mutex_ended) == 0);
+ assert(pthread_mutex_unlock (&tc->mutex_started) == 0);
+
+ for (;;)
+ {
+
+ /*
+ * get lock on todo list
+ */
+ assert(pthread_mutex_lock (&mutex_todo) == 0);
+
+ mywork = todo;
+ if (todo >= 0)
+ {
+ ++todo;
+ if (todo >= nwork)
+ todo = -1;
+ }
+ assert(pthread_mutex_unlock (&mutex_todo) == 0);
+
+ if (mywork < 0)
+ break;
+
+ assert((n = do_work_unit (tc->id, mywork)) >= 0);
+ tc->work += n;
+ }
+
+ assert(pthread_mutex_lock (&tc->mutex_end) == 0);
+ assert(pthread_mutex_unlock (&tc->mutex_end) == 0);
+ assert(pthread_mutex_lock (&tc->mutex_started) == 0);
+ assert(pthread_mutex_unlock (&tc->mutex_ended) == 0);
+
+ if (-2 == mywork)
+ break;
+ }
+
+ assert(pthread_mutex_unlock (&tc->mutex_started) == 0);
+
+ return (0);
+}
+
+static void
+dosync (void)
+{
+ int i;
+
+ for (i = 0; i < nthreads; ++i)
+ {
+ assert(pthread_mutex_lock (&tcs[i].mutex_end) == 0);
+ assert(pthread_mutex_unlock (&tcs[i].mutex_start) == 0);
+ assert(pthread_mutex_lock (&tcs[i].mutex_started) == 0);
+ assert(pthread_mutex_unlock (&tcs[i].mutex_started) == 0);
+ }
+
+ /*
+ * Now threads do their work
+ */
+ for (i = 0; i < nthreads; ++i)
+ {
+ assert(pthread_mutex_lock (&tcs[i].mutex_start) == 0);
+ assert(pthread_mutex_unlock (&tcs[i].mutex_end) == 0);
+ assert(pthread_mutex_lock (&tcs[i].mutex_ended) == 0);
+ assert(pthread_mutex_unlock (&tcs[i].mutex_ended) == 0);
+ }
+}
+
+static void
+dowork (void)
+{
+ todo = 0;
+ dosync();
+
+ todo = 0;
+ dosync();
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ assert(NULL != (tcs = (TC *) calloc (nthreads, sizeof (*tcs))));
+
+ /*
+ * Launch threads
+ */
+ for (i = 0; i < nthreads; ++i)
+ {
+ tcs[i].id = i;
+
+ assert(pthread_mutex_init (&tcs[i].mutex_start, NULL) == 0);
+ assert(pthread_mutex_init (&tcs[i].mutex_started, NULL) == 0);
+ assert(pthread_mutex_init (&tcs[i].mutex_end, NULL) == 0);
+ assert(pthread_mutex_init (&tcs[i].mutex_ended, NULL) == 0);
+
+ tcs[i].work = 0;
+
+ assert(pthread_mutex_lock (&tcs[i].mutex_start) == 0);
+ assert((tcs[i].stat =
+ pthread_create (&tcs[i].thread,
+ NULL,
+ (void *(*)(void *))print_server,
+ (void *) &tcs[i])
+ ) == 0);
+
+ /*
+ * Wait for thread initialisation
+ */
+ {
+ int trylock = 0;
+
+ while (trylock == 0)
+ {
+ trylock = pthread_mutex_trylock(&tcs[i].mutex_started);
+ assert(trylock == 0 || trylock == EBUSY);
+
+ if (trylock == 0)
+ {
+ assert(pthread_mutex_unlock (&tcs[i].mutex_started) == 0);
+ }
+ }
+ }
+ }
+
+ dowork ();
+
+ /*
+ * Terminate threads
+ */
+ todo = -2; /* please terminate */
+ dosync();
+
+ for (i = 0; i < nthreads; ++i)
+ {
+ if (0 == tcs[i].stat)
+ assert(pthread_join (tcs[i].thread, NULL) == 0);
+ }
+
+ /*
+ * destroy locks
+ */
+ assert(pthread_mutex_destroy (&mutex_stdout) == 0);
+ assert(pthread_mutex_destroy (&mutex_todo) == 0);
+
+ /*
+ * Cleanup
+ */
+ printf ("\n");
+
+ /*
+ * Show results
+ */
+ for (i = 0; i < nthreads; ++i)
+ {
+ printf ("%2d ", i);
+ if (0 == tcs[i].stat)
+ printf ("%10ld\n", tcs[i].work);
+ else
+ printf ("failed %d\n", tcs[i].stat);
+
+ assert(pthread_mutex_unlock(&tcs[i].mutex_start) == 0);
+
+ assert(pthread_mutex_destroy (&tcs[i].mutex_start) == 0);
+ assert(pthread_mutex_destroy (&tcs[i].mutex_started) == 0);
+ assert(pthread_mutex_destroy (&tcs[i].mutex_end) == 0);
+ assert(pthread_mutex_destroy (&tcs[i].mutex_ended) == 0);
+ }
+
+ die (0);
+
+ return (0);
+}
diff --git a/pthreads/tests/inherit1.c b/pthreads/tests/inherit1.c
new file mode 100644
index 000000000..482a5a884
--- /dev/null
+++ b/pthreads/tests/inherit1.c
@@ -0,0 +1,177 @@
+/*
+ * File: inherit1.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 thread priority inheritance.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+enum {
+ PTW32TEST_THREAD_INIT_PRIO = 0,
+ PTW32TEST_MAXPRIORITIES = 512
+};
+
+int minPrio;
+int maxPrio;
+int validPriorities[PTW32TEST_MAXPRIORITIES];
+
+
+void * func(void * arg)
+{
+ int policy;
+ struct sched_param param;
+
+ assert(pthread_getschedparam(pthread_self(), &policy, &param) == 0);
+ return (void *) param.sched_priority;
+}
+
+
+void *
+getValidPriorities(void * arg)
+{
+ int prioSet;
+ pthread_t thread = pthread_self();
+ HANDLE threadH = pthread_getw32threadhandle_np(thread);
+ struct sched_param param;
+
+ for (prioSet = minPrio;
+ prioSet <= maxPrio;
+ prioSet++)
+ {
+ /*
+ * If prioSet is invalid then the threads priority is unchanged
+ * from the previous value. Make the previous value a known
+ * one so that we can check later.
+ */
+ param.sched_priority = prioSet;
+ assert(pthread_setschedparam(thread, SCHED_OTHER, &param) == 0);
+ validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)] = GetThreadPriority(threadH);
+ }
+
+ return (void *) 0;
+}
+
+
+int
+main()
+{
+ pthread_t t;
+ pthread_t mainThread = pthread_self();
+ pthread_attr_t attr;
+ void * result = NULL;
+ struct sched_param param;
+ struct sched_param mainParam;
+ int prio;
+ int policy;
+ int inheritsched = -1;
+ pthread_t threadID = pthread_self();
+ HANDLE threadH = pthread_getw32threadhandle_np(threadID);
+
+ assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1);
+ assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1);
+
+ assert(pthread_create(&t, NULL, getValidPriorities, NULL) == 0);
+ assert(pthread_join(t, &result) == 0);
+
+ assert(pthread_attr_init(&attr) == 0);
+ assert(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED) == 0);
+ assert(pthread_attr_getinheritsched(&attr, &inheritsched) == 0);
+ assert(inheritsched == PTHREAD_INHERIT_SCHED);
+
+ for (prio = minPrio; prio <= maxPrio; prio++)
+ {
+ mainParam.sched_priority = prio;
+
+ /* Set the thread's priority to a known initial value. */
+ SetThreadPriority(threadH, PTW32TEST_THREAD_INIT_PRIO);
+
+ /* Change the main thread priority */
+ assert(pthread_setschedparam(mainThread, SCHED_OTHER, &mainParam) == 0);
+ assert(pthread_getschedparam(mainThread, &policy, &mainParam) == 0);
+ assert(policy == SCHED_OTHER);
+ /* Priority returned below should be the level set by pthread_setschedparam(). */
+ assert(mainParam.sched_priority == prio);
+ assert(GetThreadPriority(threadH) ==
+ validPriorities[prio+(PTW32TEST_MAXPRIORITIES/2)]);
+
+ for (param.sched_priority = prio;
+ param.sched_priority <= maxPrio;
+ param.sched_priority++)
+ {
+ /* The new thread create should ignore this new priority */
+ assert(pthread_attr_setschedparam(&attr, &param) == 0);
+ assert(pthread_create(&t, &attr, func, NULL) == 0);
+ pthread_join(t, &result);
+ assert((int) result == mainParam.sched_priority);
+ }
+ }
+
+ return 0;
+}
diff --git a/pthreads/tests/join0.c b/pthreads/tests/join0.c
new file mode 100644
index 000000000..a6cb25dcc
--- /dev/null
+++ b/pthreads/tests/join0.c
@@ -0,0 +1,67 @@
+/*
+ * Test for pthread_join().
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Depends on API functions: pthread_create(), pthread_exit().
+ */
+
+#include "test.h"
+
+void *
+func(void * arg)
+{
+ Sleep(2000);
+
+ pthread_exit(arg);
+
+ /* Never reached. */
+ exit(1);
+}
+
+int
+main(int argc, char * argv[])
+{
+ pthread_t id;
+ int result;
+
+ /* 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(result == 123);
+
+ /* Success. */
+ return 0;
+}
diff --git a/pthreads/tests/join1.c b/pthreads/tests/join1.c
new file mode 100644
index 000000000..8b11e9503
--- /dev/null
+++ b/pthreads/tests/join1.c
@@ -0,0 +1,78 @@
+/*
+ * Test for pthread_join().
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Depends on API functions: pthread_create(), pthread_join(), pthread_exit().
+ */
+
+#include "test.h"
+
+void *
+func(void * arg)
+{
+ int i = (int) arg;
+
+ Sleep(i * 100);
+
+ pthread_exit(arg);
+
+ /* Never reached. */
+ exit(1);
+}
+
+int
+main(int argc, char * argv[])
+{
+ pthread_t id[4];
+ int i;
+ int result;
+
+ /* Create a few threads and then exit. */
+ for (i = 0; i < 4; i++)
+ {
+ assert(pthread_create(&id[i], NULL, func, (void *) i) == 0);
+ }
+
+ /* Some threads will finish before they are joined, some after. */
+ Sleep(2 * 100 + 50);
+
+ for (i = 0; i < 4; i++)
+ {
+ assert(pthread_join(id[i], (void **) &result) == 0);
+ assert(result == i);
+ }
+
+ /* Success. */
+ return 0;
+}
diff --git a/pthreads/tests/join2.c b/pthreads/tests/join2.c
new file mode 100644
index 000000000..4fa30129e
--- /dev/null
+++ b/pthreads/tests/join2.c
@@ -0,0 +1,69 @@
+/*
+ * Test for pthread_join() returning return value from threads.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Depends on API functions: pthread_create().
+ */
+
+#include "test.h"
+
+void *
+func(void * arg)
+{
+ Sleep(1000);
+ return arg;
+}
+
+int
+main(int argc, char * argv[])
+{
+ pthread_t id[4];
+ int i;
+ int result;
+
+ /* Create a few threads and then exit. */
+ for (i = 0; i < 4; i++)
+ {
+ assert(pthread_create(&id[i], NULL, func, (void *) i) == 0);
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ assert(pthread_join(id[i], (void **) &result) == 0);
+ assert(result == i);
+ }
+
+ /* Success. */
+ return 0;
+}
diff --git a/pthreads/tests/join3.c b/pthreads/tests/join3.c
new file mode 100644
index 000000000..70cf3e97f
--- /dev/null
+++ b/pthreads/tests/join3.c
@@ -0,0 +1,75 @@
+/*
+ * Test for pthread_join() returning return value from threads.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Depends on API functions: pthread_create().
+ */
+
+#include "test.h"
+
+void *
+func(void * arg)
+{
+ sched_yield();
+ return arg;
+}
+
+int
+main(int argc, char * argv[])
+{
+ pthread_t id[4];
+ int i;
+ int result;
+
+ /* Create a few threads and then exit. */
+ for (i = 0; i < 4; i++)
+ {
+ assert(pthread_create(&id[i], NULL, func, (void *) i) == 0);
+ }
+
+ /*
+ * Let threads exit before we join them.
+ * We should still retrieve the exit code for the threads.
+ */
+ Sleep(1000);
+
+ for (i = 0; i < 4; i++)
+ {
+ assert(pthread_join(id[i], (void **) &result) == 0);
+ assert(result == i);
+ }
+
+ /* Success. */
+ return 0;
+}
diff --git a/pthreads/tests/kill1.c b/pthreads/tests/kill1.c
new file mode 100644
index 000000000..fd1eaee2b
--- /dev/null
+++ b/pthreads/tests/kill1.c
@@ -0,0 +1,83 @@
+/*
+ * File: kill1.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:
+ * - pthread_kill() does not support non zero signals..
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+
+int
+main()
+{
+ assert(pthread_kill(pthread_self(), 1) == EINVAL);
+
+ return 0;
+}
diff --git a/pthreads/tests/loadfree.c b/pthreads/tests/loadfree.c
new file mode 100644
index 000000000..65bb15c7b
--- /dev/null
+++ b/pthreads/tests/loadfree.c
@@ -0,0 +1,70 @@
+/*
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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: Todd Owen <towen@lucidcalm.dropbear.id.au>
+ * To: pthreads-win32@sourceware.cygnus.com
+ * Subject: invalid page fault when using LoadLibrary/FreeLibrary
+ *
+ * hi,
+ * for me, pthread.dll consistently causes an "invalid page fault in
+ * kernel32.dll" when I load it "explicitly"...to be precise, loading (with
+ * LoadLibrary) isn't a problem, it gives the error when I call FreeLibrary.
+ * I guess that the dll's cleanup must be causing the error.
+ *
+ * Implicit linkage of the dll has never given me this problem. Here's a
+ * program (console application) that gives me the error.
+ *
+ * I compile with: mingw32 (gcc-2.95 release), with the MSVCRT add-on (not
+ * that the compiler should make much difference in this case).
+ * PTHREAD.DLL: is the precompiled 1999-11-02 one (I tried an older one as
+ * well, with the same result).
+ *
+ * Fascinatingly, if you have your own dll (mycode.dll) which implicitly
+ * loads pthread.dll, and then do LoadLibrary/FreeLibrary on _this_ dll, the
+ * same thing happens.
+ *
+ */
+
+#include "test.h"
+
+int main() {
+ HINSTANCE hinst;
+
+ assert((hinst = LoadLibrary("pthread")) != (HINSTANCE) 0);
+
+ Sleep(100);
+
+ FreeLibrary(hinst);
+ return 0;
+}
+
diff --git a/pthreads/tests/mutex1.c b/pthreads/tests/mutex1.c
new file mode 100644
index 000000000..918c90330
--- /dev/null
+++ b/pthreads/tests/mutex1.c
@@ -0,0 +1,68 @@
+/*
+ * mutex1.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 a simple mutex object, lock it, and then unlock it again.
+ * This is the simplest test of the pthread mutex family that we can do.
+ *
+ * Depends on API functions:
+ * pthread_mutex_init()
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
+ * pthread_mutex_destroy()
+ */
+
+#include "test.h"
+
+pthread_mutex_t mutex = NULL;
+
+int
+main()
+{
+ assert(mutex == NULL);
+
+ assert(pthread_mutex_init(&mutex, NULL) == 0);
+
+ assert(mutex != NULL);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+
+ assert(mutex == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/mutex1e.c b/pthreads/tests/mutex1e.c
new file mode 100644
index 000000000..e52810728
--- /dev/null
+++ b/pthreads/tests/mutex1e.c
@@ -0,0 +1,74 @@
+/*
+ * mutex1e.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * As for mutex1.c but with type set to PTHREAD_MUTEX_ERRORCHECK.
+ *
+ * Create a simple mutex object, lock it, unlock it, then destroy it.
+ * This is the simplest test of the pthread mutex family that we can do.
+ *
+ * Depends on API functions:
+ * pthread_mutexattr_settype()
+ * pthread_mutex_init()
+ * pthread_mutex_destroy()
+ */
+
+#include "test.h"
+
+pthread_mutex_t mutex = NULL;
+pthread_mutexattr_t mxAttr;
+
+int
+main()
+{
+ assert(pthread_mutexattr_init(&mxAttr) == 0);
+
+ assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0);
+
+ assert(mutex == NULL);
+
+ assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
+
+ assert(mutex != NULL);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+
+ assert(mutex == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/mutex1n.c b/pthreads/tests/mutex1n.c
new file mode 100644
index 000000000..74850d6c8
--- /dev/null
+++ b/pthreads/tests/mutex1n.c
@@ -0,0 +1,74 @@
+/*
+ * mutex1n.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * As for mutex1.c but with type set to PTHREAD_MUTEX_NORMAL.
+ *
+ * Create a simple mutex object, lock it, unlock it, then destroy it.
+ * This is the simplest test of the pthread mutex family that we can do.
+ *
+ * Depends on API functions:
+ * pthread_mutexattr_settype()
+ * pthread_mutex_init()
+ * pthread_mutex_destroy()
+ */
+
+#include "test.h"
+
+pthread_mutex_t mutex = NULL;
+pthread_mutexattr_t mxAttr;
+
+int
+main()
+{
+ assert(pthread_mutexattr_init(&mxAttr) == 0);
+
+ assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0);
+
+ assert(mutex == NULL);
+
+ assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
+
+ assert(mutex != NULL);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+
+ assert(mutex == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/mutex1r.c b/pthreads/tests/mutex1r.c
new file mode 100644
index 000000000..0666dec0d
--- /dev/null
+++ b/pthreads/tests/mutex1r.c
@@ -0,0 +1,74 @@
+/*
+ * mutex1r.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * As for mutex1.c but with type set to PTHREAD_MUTEX_RECURSIVE.
+ *
+ * Create a simple mutex object, lock it, unlock it, then destroy it.
+ * This is the simplest test of the pthread mutex family that we can do.
+ *
+ * Depends on API functions:
+ * pthread_mutexattr_settype()
+ * pthread_mutex_init()
+ * pthread_mutex_destroy()
+ */
+
+#include "test.h"
+
+pthread_mutex_t mutex = NULL;
+pthread_mutexattr_t mxAttr;
+
+int
+main()
+{
+ assert(pthread_mutexattr_init(&mxAttr) == 0);
+
+ assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0);
+
+ assert(mutex == NULL);
+
+ assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
+
+ assert(mutex != NULL);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+
+ assert(mutex == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/mutex2.c b/pthreads/tests/mutex2.c
new file mode 100644
index 000000000..377468e90
--- /dev/null
+++ b/pthreads/tests/mutex2.c
@@ -0,0 +1,66 @@
+/*
+ * mutex2.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static mutex object, lock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+int
+main()
+{
+ assert(mutex == PTHREAD_MUTEX_INITIALIZER);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ assert(mutex != PTHREAD_MUTEX_INITIALIZER);
+
+ assert(mutex != NULL);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+
+ assert(mutex == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/mutex2e.c b/pthreads/tests/mutex2e.c
new file mode 100644
index 000000000..7df6073d2
--- /dev/null
+++ b/pthreads/tests/mutex2e.c
@@ -0,0 +1,66 @@
+/*
+ * mutex2e.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static mutex object, lock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER;
+
+int
+main()
+{
+ assert(mutex == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ assert(mutex != PTHREAD_ERRORCHECK_MUTEX_INITIALIZER);
+
+ assert(mutex != NULL);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+
+ assert(mutex == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/mutex2r.c b/pthreads/tests/mutex2r.c
new file mode 100644
index 000000000..c96e366f1
--- /dev/null
+++ b/pthreads/tests/mutex2r.c
@@ -0,0 +1,66 @@
+/*
+ * mutex2r.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static mutex object, lock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+
+int
+main()
+{
+ assert(mutex == PTHREAD_RECURSIVE_MUTEX_INITIALIZER);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ assert(mutex != PTHREAD_RECURSIVE_MUTEX_INITIALIZER);
+
+ assert(mutex != NULL);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+
+ assert(mutex == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/mutex3.c b/pthreads/tests/mutex3.c
new file mode 100644
index 000000000..bc1429e0b
--- /dev/null
+++ b/pthreads/tests/mutex3.c
@@ -0,0 +1,75 @@
+/*
+ * mutex3.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static mutex object, lock it, trylock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_mutex_lock()
+ * pthread_mutex_trylock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ assert(pthread_mutex_trylock(&mutex1) == EBUSY);
+
+ washere = 1;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ assert(pthread_mutex_lock(&mutex1) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+ assert(pthread_join(t, NULL) == 0);
+
+ assert(pthread_mutex_unlock(&mutex1) == 0);
+
+ assert(washere == 1);
+
+ return 0;
+}
diff --git a/pthreads/tests/mutex3e.c b/pthreads/tests/mutex3e.c
new file mode 100644
index 000000000..66cfcb71c
--- /dev/null
+++ b/pthreads/tests/mutex3e.c
@@ -0,0 +1,75 @@
+/*
+ * mutex3e.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static mutex object, lock it, trylock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_mutex_lock()
+ * pthread_mutex_trylock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+pthread_mutex_t mutex1 = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER;
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ assert(pthread_mutex_trylock(&mutex1) == EBUSY);
+
+ washere = 1;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ assert(pthread_mutex_lock(&mutex1) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+ assert(pthread_join(t, NULL) == 0);
+
+ assert(pthread_mutex_unlock(&mutex1) == 0);
+
+ assert(washere == 1);
+
+ return 0;
+}
diff --git a/pthreads/tests/mutex3r.c b/pthreads/tests/mutex3r.c
new file mode 100644
index 000000000..8fa7f2547
--- /dev/null
+++ b/pthreads/tests/mutex3r.c
@@ -0,0 +1,75 @@
+/*
+ * mutex3r.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static mutex object, lock it, trylock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_mutex_lock()
+ * pthread_mutex_trylock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+pthread_mutex_t mutex1 = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ assert(pthread_mutex_trylock(&mutex1) == EBUSY);
+
+ washere = 1;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ assert(pthread_mutex_lock(&mutex1) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+ assert(pthread_join(t, NULL) == 0);
+
+ assert(pthread_mutex_unlock(&mutex1) == 0);
+
+ assert(washere == 1);
+
+ return 0;
+}
diff --git a/pthreads/tests/mutex4.c b/pthreads/tests/mutex4.c
new file mode 100644
index 000000000..547d9cb73
--- /dev/null
+++ b/pthreads/tests/mutex4.c
@@ -0,0 +1,111 @@
+/*
+ * mutex4.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 mutex - thread B tries to unlock.
+ *
+ * Depends on API functions:
+ * pthread_mutex_lock()
+ * pthread_mutex_trylock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+static int wasHere = 0;
+
+static pthread_mutex_t mutex1;
+
+void * unlocker(void * arg)
+{
+ int expectedResult = (int) arg;
+
+ wasHere++;
+ assert(pthread_mutex_unlock(&mutex1) == expectedResult);
+ wasHere++;
+ return NULL;
+}
+
+int
+main()
+{
+ pthread_t t;
+ pthread_mutexattr_t ma;
+
+ assert(pthread_mutexattr_init(&ma) == 0);
+
+ 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_join(t, NULL) == 0);
+ assert(pthread_mutex_unlock(&mutex1) == EPERM);
+ assert(wasHere == 2);
+
+ wasHere = 0;
+ assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_NORMAL) == 0);
+ assert(pthread_mutex_init(&mutex1, &ma) == 0);
+ assert(pthread_mutex_lock(&mutex1) == 0);
+ /*
+ * NORMAL (fast) mutexes don't check ownership.
+ */
+ assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0);
+ assert(pthread_join(t, NULL) == 0);
+ assert(pthread_mutex_unlock(&mutex1) == EPERM);
+ assert(wasHere == 2);
+
+ wasHere = 0;
+ assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0);
+ assert(pthread_mutex_init(&mutex1, &ma) == 0);
+ assert(pthread_mutex_lock(&mutex1) == 0);
+ assert(pthread_create(&t, NULL, unlocker, (void *) EPERM) == 0);
+ assert(pthread_join(t, NULL) == 0);
+ assert(pthread_mutex_unlock(&mutex1) == 0);
+ assert(wasHere == 2);
+
+ wasHere = 0;
+ assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE) == 0);
+ assert(pthread_mutex_init(&mutex1, &ma) == 0);
+ assert(pthread_mutex_lock(&mutex1) == 0);
+ assert(pthread_create(&t, NULL, unlocker, (void *) EPERM) == 0);
+ assert(pthread_join(t, NULL) == 0);
+ assert(pthread_mutex_unlock(&mutex1) == 0);
+ assert(wasHere == 2);
+
+ return 0;
+}
diff --git a/pthreads/tests/mutex5.c b/pthreads/tests/mutex5.c
new file mode 100644
index 000000000..a71f9d893
--- /dev/null
+++ b/pthreads/tests/mutex5.c
@@ -0,0 +1,67 @@
+/*
+ * mutex5.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Confirm the equality/inequality of the various mutex types,
+ * and the default not-set value.
+ */
+
+#include "test.h"
+
+static pthread_mutexattr_t mxAttr;
+
+/* Prevent optimiser from removing dead or obvious asserts. */
+int _optimiseFoil;
+#define FOIL(x) (_optimiseFoil = x)
+
+int
+main()
+{
+ int mxType = -1;
+
+ assert(FOIL(PTHREAD_MUTEX_DEFAULT) == PTHREAD_MUTEX_NORMAL);
+ assert(FOIL(PTHREAD_MUTEX_DEFAULT) != PTHREAD_MUTEX_ERRORCHECK);
+ assert(FOIL(PTHREAD_MUTEX_DEFAULT) != PTHREAD_MUTEX_RECURSIVE);
+ assert(FOIL(PTHREAD_MUTEX_RECURSIVE) != PTHREAD_MUTEX_ERRORCHECK);
+
+ assert(FOIL(PTHREAD_MUTEX_NORMAL) == PTHREAD_MUTEX_FAST_NP);
+ assert(FOIL(PTHREAD_MUTEX_RECURSIVE) == PTHREAD_MUTEX_RECURSIVE_NP);
+ assert(FOIL(PTHREAD_MUTEX_ERRORCHECK) == PTHREAD_MUTEX_ERRORCHECK_NP);
+
+ assert(pthread_mutexattr_init(&mxAttr) == 0);
+ assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
+ assert(mxType == PTHREAD_MUTEX_NORMAL);
+
+ return 0;
+}
diff --git a/pthreads/tests/mutex6.c b/pthreads/tests/mutex6.c
new file mode 100644
index 000000000..15649fc8d
--- /dev/null
+++ b/pthreads/tests/mutex6.c
@@ -0,0 +1,93 @@
+/*
+ * mutex6.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 the default (type not set) mutex type.
+ * Should be the same as PTHREAD_MUTEX_NORMAL.
+ * Thread locks mutex twice (recursive lock).
+ * Locking thread should deadlock on second attempt.
+ *
+ * Depends on API functions:
+ * pthread_mutex_lock()
+ * pthread_mutex_trylock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex;
+
+void * locker(void * arg)
+{
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+
+ /* Should wait here (deadlocked) */
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ assert(pthread_mutex_init(&mutex, NULL) == 0);
+
+ assert(pthread_create(&t, NULL, locker, NULL) == 0);
+
+ Sleep(1000);
+
+ 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);
+
+ Sleep (1000);
+
+ assert(lockCount == 2);
+
+ exit(0);
+
+ /* Never reached */
+ return 0;
+}
diff --git a/pthreads/tests/mutex6e.c b/pthreads/tests/mutex6e.c
new file mode 100644
index 000000000..8af9274f2
--- /dev/null
+++ b/pthreads/tests/mutex6e.c
@@ -0,0 +1,102 @@
+/*
+ * mutex6e.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Tests PTHREAD_MUTEX_ERRORCHECK mutex type.
+ * Thread locks mutex twice (recursive lock).
+ * This should fail with an EDEADLK error.
+ * The second unlock attempt should fail with an EPERM error.
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_join()
+ * pthread_mutexattr_init()
+ * pthread_mutexattr_destroy()
+ * pthread_mutexattr_settype()
+ * pthread_mutexattr_gettype()
+ * pthread_mutex_init()
+ * pthread_mutex_destroy()
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex;
+static pthread_mutexattr_t mxAttr;
+
+void * locker(void * arg)
+{
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_lock(&mutex) == EDEADLK);
+ lockCount++;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+ assert(pthread_mutex_unlock(&mutex) == EPERM);
+
+ return (void *) 555;
+}
+
+int
+main()
+{
+ pthread_t t;
+ int result = 0;
+ int mxType = -1;
+
+ assert(pthread_mutexattr_init(&mxAttr) == 0);
+ assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0);
+ assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
+ assert(mxType == PTHREAD_MUTEX_ERRORCHECK);
+
+ assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
+
+ assert(pthread_create(&t, NULL, locker, NULL) == 0);
+
+ assert(pthread_join(t, (void **) &result) == 0);
+ assert(result == 555);
+
+ assert(lockCount == 2);
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+ assert(pthread_mutexattr_destroy(&mxAttr) == 0);
+
+ exit(0);
+
+ /* Never reached */
+ return 0;
+}
+
diff --git a/pthreads/tests/mutex6es.c b/pthreads/tests/mutex6es.c
new file mode 100644
index 000000000..0d879c4ea
--- /dev/null
+++ b/pthreads/tests/mutex6es.c
@@ -0,0 +1,94 @@
+/*
+ * mutex6es.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Tests PTHREAD_MUTEX_ERRORCHECK static mutex type.
+ * Thread locks mutex twice (recursive lock).
+ * This should fail with an EDEADLK error.
+ * The second unlock attempt should fail with an EPERM error.
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_join()
+ * pthread_mutexattr_init()
+ * pthread_mutexattr_destroy()
+ * pthread_mutexattr_settype()
+ * pthread_mutexattr_gettype()
+ * pthread_mutex_init()
+ * pthread_mutex_destroy()
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER;
+
+void * locker(void * arg)
+{
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_lock(&mutex) == EDEADLK);
+ lockCount++;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+ assert(pthread_mutex_unlock(&mutex) == EPERM);
+
+ return (void *) 555;
+}
+
+int
+main()
+{
+ pthread_t t;
+ int result = 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(lockCount == 2);
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+
+ exit(0);
+
+ /* Never reached */
+ return 0;
+}
+
diff --git a/pthreads/tests/mutex6n.c b/pthreads/tests/mutex6n.c
new file mode 100644
index 000000000..9b4bbb920
--- /dev/null
+++ b/pthreads/tests/mutex6n.c
@@ -0,0 +1,104 @@
+/*
+ * mutex6n.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Tests PTHREAD_MUTEX_NORMAL mutex type.
+ * Thread locks mutex twice (recursive lock).
+ * The thread should deadlock.
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_mutexattr_init()
+ * pthread_mutexattr_settype()
+ * pthread_mutexattr_gettype()
+ * pthread_mutex_init()
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex;
+static pthread_mutexattr_t mxAttr;
+
+void * locker(void * arg)
+{
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+
+ /* Should wait here (deadlocked) */
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ return (void *) 555;
+}
+
+int
+main()
+{
+ pthread_t t;
+ int mxType = -1;
+
+ assert(pthread_mutexattr_init(&mxAttr) == 0);
+ assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0);
+ assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
+ assert(mxType == PTHREAD_MUTEX_NORMAL);
+
+ assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
+
+ assert(pthread_create(&t, NULL, locker, NULL) == 0);
+
+ Sleep(1000);
+
+ 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);
+
+ Sleep (1000);
+
+ assert(lockCount == 2);
+
+ exit(0);
+
+ /* Never reached */
+ return 0;
+}
+
diff --git a/pthreads/tests/mutex6r.c b/pthreads/tests/mutex6r.c
new file mode 100644
index 000000000..4bf853f8d
--- /dev/null
+++ b/pthreads/tests/mutex6r.c
@@ -0,0 +1,100 @@
+/*
+ * mutex6r.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Tests PTHREAD_MUTEX_RECURSIVE mutex type.
+ * Thread locks mutex twice (recursive lock).
+ * Both locks and unlocks should succeed.
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_join()
+ * pthread_mutexattr_init()
+ * pthread_mutexattr_destroy()
+ * pthread_mutexattr_settype()
+ * pthread_mutexattr_gettype()
+ * pthread_mutex_init()
+ * pthread_mutex_destroy()
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex;
+static pthread_mutexattr_t mxAttr;
+
+void * locker(void * arg)
+{
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ return (void *) 555;
+}
+
+int
+main()
+{
+ pthread_t t;
+ int result = 0;
+ int mxType = -1;
+
+ assert(pthread_mutexattr_init(&mxAttr) == 0);
+ assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0);
+ assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
+ assert(mxType == PTHREAD_MUTEX_RECURSIVE);
+
+ assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
+
+ assert(pthread_create(&t, NULL, locker, NULL) == 0);
+
+ assert(pthread_join(t, (void **) &result) == 0);
+ assert(result == 555);
+
+ assert(lockCount == 2);
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+ assert(pthread_mutexattr_destroy(&mxAttr) == 0);
+
+ exit(0);
+
+ /* Never reached */
+ return 0;
+}
diff --git a/pthreads/tests/mutex6rs.c b/pthreads/tests/mutex6rs.c
new file mode 100644
index 000000000..4ebe44ef0
--- /dev/null
+++ b/pthreads/tests/mutex6rs.c
@@ -0,0 +1,92 @@
+/*
+ * mutex6rs.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Tests PTHREAD_MUTEX_RECURSIVE static mutex type.
+ * Thread locks mutex twice (recursive lock).
+ * Both locks and unlocks should succeed.
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_join()
+ * pthread_mutexattr_init()
+ * pthread_mutexattr_destroy()
+ * pthread_mutexattr_settype()
+ * pthread_mutexattr_gettype()
+ * pthread_mutex_init()
+ * pthread_mutex_destroy()
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+
+void * locker(void * arg)
+{
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ return (void *) 555;
+}
+
+int
+main()
+{
+ pthread_t t;
+ int result = 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(lockCount == 2);
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+
+ exit(0);
+
+ /* Never reached */
+ return 0;
+}
diff --git a/pthreads/tests/mutex6s.c b/pthreads/tests/mutex6s.c
new file mode 100644
index 000000000..8b82dc3fa
--- /dev/null
+++ b/pthreads/tests/mutex6s.c
@@ -0,0 +1,93 @@
+/*
+ * mutex6s.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 the default (type not set) static mutex type.
+ * Should be the same as PTHREAD_MUTEX_NORMAL.
+ * Thread locks mutex twice (recursive lock).
+ * Locking thread should deadlock on second attempt.
+ *
+ * Depends on API functions:
+ * pthread_mutex_lock()
+ * pthread_mutex_trylock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void * locker(void * arg)
+{
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+
+ /* Should wait here (deadlocked) */
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ assert(mutex == PTHREAD_MUTEX_INITIALIZER);
+
+ assert(pthread_create(&t, NULL, locker, NULL) == 0);
+
+ Sleep(1000);
+
+ 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);
+
+ Sleep (1000);
+
+ assert(lockCount == 2);
+
+ exit(0);
+
+ /* Never reached */
+ return 0;
+}
diff --git a/pthreads/tests/mutex7.c b/pthreads/tests/mutex7.c
new file mode 100644
index 000000000..8772b9712
--- /dev/null
+++ b/pthreads/tests/mutex7.c
@@ -0,0 +1,82 @@
+/*
+ * mutex7.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 the default (type not set) mutex type.
+ * Should be the same as PTHREAD_MUTEX_NORMAL.
+ * Thread locks then trylocks mutex (attempted recursive lock).
+ * The thread should lock first time and EBUSY second time.
+ *
+ * Depends on API functions:
+ * pthread_mutex_lock()
+ * pthread_mutex_trylock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex;
+
+void * locker(void * arg)
+{
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_trylock(&mutex) == EBUSY);
+ lockCount++;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+ assert(pthread_mutex_unlock(&mutex) == EPERM);
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ assert(pthread_mutex_init(&mutex, NULL) == 0);
+
+ assert(pthread_create(&t, NULL, locker, NULL) == 0);
+
+ Sleep(1000);
+
+ assert(lockCount == 2);
+
+ exit(0);
+
+ /* Never reached */
+ return 0;
+}
diff --git a/pthreads/tests/mutex7e.c b/pthreads/tests/mutex7e.c
new file mode 100644
index 000000000..854789b9b
--- /dev/null
+++ b/pthreads/tests/mutex7e.c
@@ -0,0 +1,102 @@
+/*
+ * mutex7e.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Tests PTHREAD_MUTEX_ERRORCHECK mutex type.
+ * Thread locks and then trylocks mutex (attempted recursive lock).
+ * Trylock should fail with an EBUSY error.
+ * The second unlock attempt should fail with an EPERM error.
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_join()
+ * pthread_mutexattr_init()
+ * pthread_mutexattr_destroy()
+ * pthread_mutexattr_settype()
+ * pthread_mutexattr_gettype()
+ * pthread_mutex_init()
+ * pthread_mutex_destroy()
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex;
+static pthread_mutexattr_t mxAttr;
+
+void * locker(void * arg)
+{
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_trylock(&mutex) == EBUSY);
+ lockCount++;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+ assert(pthread_mutex_unlock(&mutex) == EPERM);
+
+ return (void *) 555;
+}
+
+int
+main()
+{
+ pthread_t t;
+ int result = 0;
+ int mxType = -1;
+
+ assert(pthread_mutexattr_init(&mxAttr) == 0);
+ assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0);
+ assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
+ assert(mxType == PTHREAD_MUTEX_ERRORCHECK);
+
+ assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
+
+ assert(pthread_create(&t, NULL, locker, NULL) == 0);
+
+ assert(pthread_join(t, (void **) &result) == 0);
+ assert(result == 555);
+
+ assert(lockCount == 2);
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+ assert(pthread_mutexattr_destroy(&mxAttr) == 0);
+
+ exit(0);
+
+ /* Never reached */
+ return 0;
+}
+
diff --git a/pthreads/tests/mutex7n.c b/pthreads/tests/mutex7n.c
new file mode 100644
index 000000000..174355fca
--- /dev/null
+++ b/pthreads/tests/mutex7n.c
@@ -0,0 +1,93 @@
+/*
+ * mutex7n.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Tests PTHREAD_MUTEX_NORMAL mutex type.
+ * Thread locks then trylocks mutex (attempted recursive lock).
+ * The thread should lock first time and EBUSY second time.
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_mutexattr_init()
+ * pthread_mutexattr_settype()
+ * pthread_mutexattr_gettype()
+ * pthread_mutex_init()
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex;
+static pthread_mutexattr_t mxAttr;
+
+void * locker(void * arg)
+{
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_trylock(&mutex) == EBUSY);
+ lockCount++;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+ assert(pthread_mutex_unlock(&mutex) == EPERM);
+
+ return (void *) 555;
+}
+
+int
+main()
+{
+ pthread_t t;
+ int mxType = -1;
+
+ assert(pthread_mutexattr_init(&mxAttr) == 0);
+ assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0);
+ assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
+ assert(mxType == PTHREAD_MUTEX_NORMAL);
+
+ assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
+
+ assert(pthread_create(&t, NULL, locker, NULL) == 0);
+
+ Sleep(1000);
+
+ assert(lockCount == 2);
+
+ exit(0);
+
+ /* Never reached */
+ return 0;
+}
+
diff --git a/pthreads/tests/mutex7r.c b/pthreads/tests/mutex7r.c
new file mode 100644
index 000000000..f9e5ff0e2
--- /dev/null
+++ b/pthreads/tests/mutex7r.c
@@ -0,0 +1,100 @@
+/*
+ * mutex7r.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Tests PTHREAD_MUTEX_RECURSIVE mutex type.
+ * Thread locks mutex then trylocks mutex (recursive lock twice).
+ * Both locks and unlocks should succeed.
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_join()
+ * pthread_mutexattr_init()
+ * pthread_mutexattr_destroy()
+ * pthread_mutexattr_settype()
+ * pthread_mutexattr_gettype()
+ * pthread_mutex_init()
+ * pthread_mutex_destroy()
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex;
+static pthread_mutexattr_t mxAttr;
+
+void * locker(void * arg)
+{
+ assert(pthread_mutex_lock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_trylock(&mutex) == 0);
+ lockCount++;
+ assert(pthread_mutex_unlock(&mutex) == 0);
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ return (void *) 555;
+}
+
+int
+main()
+{
+ pthread_t t;
+ int result = 0;
+ int mxType = -1;
+
+ assert(pthread_mutexattr_init(&mxAttr) == 0);
+ assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0);
+ assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
+ assert(mxType == PTHREAD_MUTEX_RECURSIVE);
+
+ assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
+
+ assert(pthread_create(&t, NULL, locker, NULL) == 0);
+
+ assert(pthread_join(t, (void **) &result) == 0);
+ assert(result == 555);
+
+ assert(lockCount == 2);
+
+ assert(pthread_mutex_destroy(&mutex) == 0);
+ assert(pthread_mutexattr_destroy(&mxAttr) == 0);
+
+ exit(0);
+
+ /* Never reached */
+ return 0;
+}
diff --git a/pthreads/tests/mutex8.c b/pthreads/tests/mutex8.c
new file mode 100644
index 000000000..5ca99822e
--- /dev/null
+++ b/pthreads/tests/mutex8.c
@@ -0,0 +1,82 @@
+/*
+ * mutex8.c
+ *
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright (C) 1998 Ben Elliston and Ross Johnson
+ * Copyright (C) 1999,2000,2001 Ross Johnson
+ *
+ * Contact Email: rpj@ise.canberra.edu.au
+ *
+ * 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.1 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test the default (type not set) mutex type exercising timedlock.
+ * Thread locks mutex, another thread timedlocks the mutex.
+ * Timed thread should timeout.
+ *
+ * Depends on API functions:
+ * pthread_mutex_lock()
+ * pthread_mutex_timedlock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex;
+
+void * locker(void * arg)
+{
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 1;
+
+ assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT);
+
+ lockCount++;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ assert(pthread_mutex_init(&mutex, NULL) == 0);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ assert(pthread_create(&t, NULL, locker, NULL) == 0);
+
+ Sleep(2000);
+
+ assert(lockCount == 1);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ return 0;
+}
diff --git a/pthreads/tests/mutex8e.c b/pthreads/tests/mutex8e.c
new file mode 100644
index 000000000..b99d24edd
--- /dev/null
+++ b/pthreads/tests/mutex8e.c
@@ -0,0 +1,97 @@
+/*
+ * mutex8e.c
+ *
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright (C) 1998 Ben Elliston and Ross Johnson
+ * Copyright (C) 1999,2000,2001 Ross Johnson
+ *
+ * Contact Email: rpj@ise.canberra.edu.au
+ *
+ * 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.1 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Tests PTHREAD_MUTEX_ERRORCHECK mutex type exercising timedlock.
+ * Thread locks mutex, another thread timedlocks the mutex.
+ * Timed thread should timeout.
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_mutexattr_init()
+ * pthread_mutexattr_destroy()
+ * pthread_mutexattr_settype()
+ * pthread_mutexattr_gettype()
+ * pthread_mutex_init()
+ * pthread_mutex_destroy()
+ * pthread_mutex_lock()
+ * pthread_mutex_timedlock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex;
+static pthread_mutexattr_t mxAttr;
+
+void * locker(void * arg)
+{
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 1;
+
+ assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT);
+
+ lockCount++;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+ int mxType = -1;
+
+ assert(pthread_mutexattr_init(&mxAttr) == 0);
+ assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0);
+ assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
+ assert(mxType == PTHREAD_MUTEX_ERRORCHECK);
+
+ assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ assert(pthread_create(&t, NULL, locker, NULL) == 0);
+
+ Sleep(2000);
+
+ assert(lockCount == 1);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ return 0;
+}
+
diff --git a/pthreads/tests/mutex8n.c b/pthreads/tests/mutex8n.c
new file mode 100644
index 000000000..3cfdae620
--- /dev/null
+++ b/pthreads/tests/mutex8n.c
@@ -0,0 +1,97 @@
+/*
+ * mutex8n.c
+ *
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright (C) 1998 Ben Elliston and Ross Johnson
+ * Copyright (C) 1999,2000,2001 Ross Johnson
+ *
+ * Contact Email: rpj@ise.canberra.edu.au
+ *
+ * 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.1 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Tests PTHREAD_MUTEX_NORMAL mutex type exercising timedlock.
+ * Thread locks mutex, another thread timedlocks the mutex.
+ * Timed thread should timeout.
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_mutexattr_init()
+ * pthread_mutexattr_destroy()
+ * pthread_mutexattr_settype()
+ * pthread_mutexattr_gettype()
+ * pthread_mutex_init()
+ * pthread_mutex_destroy()
+ * pthread_mutex_lock()
+ * pthread_mutex_timedlock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex;
+static pthread_mutexattr_t mxAttr;
+
+void * locker(void * arg)
+{
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 1;
+
+ assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT);
+
+ lockCount++;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+ int mxType = -1;
+
+ assert(pthread_mutexattr_init(&mxAttr) == 0);
+ assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0);
+ assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
+ assert(mxType == PTHREAD_MUTEX_NORMAL);
+
+ assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ assert(pthread_create(&t, NULL, locker, NULL) == 0);
+
+ Sleep(2000);
+
+ assert(lockCount == 1);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ return 0;
+}
+
diff --git a/pthreads/tests/mutex8r.c b/pthreads/tests/mutex8r.c
new file mode 100644
index 000000000..d1328cad9
--- /dev/null
+++ b/pthreads/tests/mutex8r.c
@@ -0,0 +1,97 @@
+/*
+ * mutex8r.c
+ *
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright (C) 1998 Ben Elliston and Ross Johnson
+ * Copyright (C) 1999,2000,2001 Ross Johnson
+ *
+ * Contact Email: rpj@ise.canberra.edu.au
+ *
+ * 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.1 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Tests PTHREAD_MUTEX_RECURSIVE mutex type exercising timedlock.
+ * Thread locks mutex, another thread timedlocks the mutex.
+ * Timed thread should timeout.
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_mutexattr_init()
+ * pthread_mutexattr_destroy()
+ * pthread_mutexattr_settype()
+ * pthread_mutexattr_gettype()
+ * pthread_mutex_init()
+ * pthread_mutex_destroy()
+ * pthread_mutex_lock()
+ * pthread_mutex_timedlock()
+ * pthread_mutex_unlock()
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+static int lockCount = 0;
+
+static pthread_mutex_t mutex;
+static pthread_mutexattr_t mxAttr;
+
+void * locker(void * arg)
+{
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 1;
+
+ assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT);
+
+ lockCount++;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+ int mxType = -1;
+
+ assert(pthread_mutexattr_init(&mxAttr) == 0);
+ assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0);
+ assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0);
+ assert(mxType == PTHREAD_MUTEX_RECURSIVE);
+
+ assert(pthread_mutex_init(&mutex, &mxAttr) == 0);
+
+ assert(pthread_mutex_lock(&mutex) == 0);
+
+ assert(pthread_create(&t, NULL, locker, NULL) == 0);
+
+ Sleep(2000);
+
+ assert(lockCount == 1);
+
+ assert(pthread_mutex_unlock(&mutex) == 0);
+
+ return 0;
+}
+
diff --git a/pthreads/tests/once1.c b/pthreads/tests/once1.c
new file mode 100644
index 000000000..daec112d7
--- /dev/null
+++ b/pthreads/tests/once1.c
@@ -0,0 +1,77 @@
+/*
+ * once1.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 a static pthread_once and test that it calls myfunc once.
+ *
+ * Depends on API functions:
+ * pthread_once()
+ * pthread_create()
+ */
+
+#include "test.h"
+
+pthread_once_t once = PTHREAD_ONCE_INIT;
+
+static int washere = 0;
+
+void
+myfunc(void)
+{
+ washere++;
+}
+
+void *
+mythread(void * arg)
+{
+ assert(pthread_once(&once, myfunc) == 0);
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t1, t2;
+
+ assert(pthread_create(&t1, NULL, mythread, NULL) == 0);
+
+ assert(pthread_create(&t2, NULL, mythread, NULL) == 0);
+
+ Sleep(2000);
+
+ assert(washere == 1);
+
+ return 0;
+}
diff --git a/pthreads/tests/once2.c b/pthreads/tests/once2.c
new file mode 100644
index 000000000..248ccb1a7
--- /dev/null
+++ b/pthreads/tests/once2.c
@@ -0,0 +1,109 @@
+/*
+ * once2.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 static pthread_once objects and channel several threads
+ * through each.
+ *
+ * Depends on API functions:
+ * pthread_once()
+ * pthread_create()
+ */
+
+#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++;
+ LeaveCriticalSection(&numOnce.cs);
+ /* Simulate slow once routine so that following threads pile up behind it */
+ Sleep(100);
+}
+
+void *
+mythread(void * arg)
+{
+ 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);
+
+ assert(numOnce.i == NUM_ONCE);
+ assert(numThreads.i == NUM_THREADS * NUM_ONCE);
+
+ DeleteCriticalSection(&numOnce.cs);
+ DeleteCriticalSection(&numThreads.cs);
+
+ return 0;
+}
diff --git a/pthreads/tests/once3.c b/pthreads/tests/once3.c
new file mode 100644
index 000000000..981bbf7d8
--- /dev/null
+++ b/pthreads/tests/once3.c
@@ -0,0 +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;
+}
diff --git a/pthreads/tests/once4.c b/pthreads/tests/once4.c
new file mode 100644
index 000000000..f5be64486
--- /dev/null
+++ b/pthreads/tests/once4.c
@@ -0,0 +1,191 @@
+/*
+ * once4.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Create several pthread_once objects and channel several threads
+ * through each. Make the init_routine cancelable and cancel them
+ * waiters waiting. Vary the priorities.
+ *
+ * Depends on API functions:
+ * pthread_once()
+ * pthread_create()
+ * pthread_testcancel()
+ * pthread_cancel()
+ * pthread_once()
+ */
+
+#include "test.h"
+
+#define NUM_THREADS 100 /* Targeting each once control */
+#define NUM_ONCE 10
+
+pthread_once_t o = PTHREAD_ONCE_INIT;
+pthread_once_t once[NUM_ONCE];
+
+typedef struct {
+ int i;
+ CRITICAL_SECTION cs;
+} sharedInt_t;
+
+static sharedInt_t numOnce = {0, {0}};
+static sharedInt_t numThreads = {0, {0}};
+
+typedef struct {
+ int threadnum;
+ int oncenum;
+ int myPrio;
+ HANDLE w32Thread;
+} bag_t;
+
+static bag_t threadbag[NUM_THREADS][NUM_ONCE];
+
+CRITICAL_SECTION print_lock;
+
+void
+mycleanupfunc(void * arg)
+{
+ bag_t * bag = (bag_t *) arg;
+ EnterCriticalSection(&print_lock);
+ /* once thrd prio error */
+ printf("%4d %4d %4d %4d\n",
+ bag->oncenum,
+ bag->threadnum,
+ bag->myPrio,
+ bag->myPrio - GetThreadPriority(bag->w32Thread));
+ LeaveCriticalSection(&print_lock);
+}
+
+void
+myinitfunc(void)
+{
+ EnterCriticalSection(&numOnce.cs);
+ numOnce.i++;
+ LeaveCriticalSection(&numOnce.cs);
+ /* Simulate slow once routine so that following threads pile up behind it */
+ Sleep(10);
+ /* test for cancelation late so we're sure to have waiters. */
+ pthread_testcancel();
+}
+
+void *
+mythread(void * arg)
+{
+ bag_t * bag = (bag_t *) arg;
+ struct sched_param param;
+
+ /*
+ * Cancel every thread. These threads are deferred cancelable only, so
+ * only the thread performing the init_routine will see it (there are
+ * no other cancelation points here). The result will be that every thread
+ * eventually cancels only when it becomes the new initter.
+ */
+ pthread_t self = pthread_self();
+ bag->w32Thread = pthread_getw32threadhandle_np(self);
+ /*
+ * Set priority between -2 and 2 inclusive.
+ */
+ bag->myPrio = (bag->threadnum % 5) - 2;
+ param.sched_priority = bag->myPrio;
+ pthread_setschedparam(self, SCHED_OTHER, &param);
+
+ /* Trigger a cancellation at the next cancellation point in this thread */
+ pthread_cancel(self);
+#if 0
+ pthread_cleanup_push(mycleanupfunc, arg);
+ assert(pthread_once(&once[bag->oncenum], myinitfunc) == 0);
+ pthread_cleanup_pop(1);
+#else
+ assert(pthread_once(&once[bag->oncenum], myinitfunc) == 0);
+#endif
+ EnterCriticalSection(&numThreads.cs);
+ numThreads.i++;
+ LeaveCriticalSection(&numThreads.cs);
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t[NUM_THREADS][NUM_ONCE];
+ int i, j;
+
+ InitializeCriticalSection(&print_lock);
+ InitializeCriticalSection(&numThreads.cs);
+ InitializeCriticalSection(&numOnce.cs);
+
+#if 0
+ /* once thrd prio change */
+ printf("once thrd prio error\n");
+#endif
+
+ /*
+ * Set the priority class to realtime - otherwise normal
+ * Windows random priority boosting will obscure any problems.
+ */
+ SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
+ /* Set main thread to lower prio than threads */
+ SetThreadPriority(GetCurrentThread(), -2);
+
+ for (j = 0; j < NUM_ONCE; j++)
+ {
+ once[j] = o;
+
+ for (i = 0; i < NUM_THREADS; i++)
+ {
+ bag_t * bag = &threadbag[i][j];
+ bag->threadnum = i;
+ bag->oncenum = j;
+ assert(pthread_create(&t[i][j], NULL, mythread, (void *) bag) == 0);
+ }
+ }
+
+ for (j = 0; j < NUM_ONCE; j++)
+ for (i = 0; i < NUM_THREADS; i++)
+ if (pthread_join(t[i][j], NULL) != 0)
+ printf("Join failed for [thread,once] = [%d,%d]\n", i, j);
+
+ /*
+ * All threads will cancel, none will return normally from
+ * pthread_once and so numThreads should never be incremented. However,
+ * numOnce should be incremented by every thread (NUM_THREADS*NUM_ONCE).
+ */
+ assert(numOnce.i == NUM_ONCE * NUM_THREADS);
+ assert(numThreads.i == 0);
+
+ DeleteCriticalSection(&numOnce.cs);
+ DeleteCriticalSection(&numThreads.cs);
+ DeleteCriticalSection(&print_lock);
+
+ return 0;
+}
diff --git a/pthreads/tests/priority1.c b/pthreads/tests/priority1.c
new file mode 100644
index 000000000..c270e998a
--- /dev/null
+++ b/pthreads/tests/priority1.c
@@ -0,0 +1,172 @@
+/*
+ * File: priority1.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 thread priority explicit setting using thread attribute.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+enum {
+ PTW32TEST_THREAD_INIT_PRIO = 0,
+ PTW32TEST_MAXPRIORITIES = 512
+};
+
+int minPrio;
+int maxPrio;
+int validPriorities[PTW32TEST_MAXPRIORITIES];
+
+void *
+func(void * arg)
+{
+ int policy;
+ struct sched_param param;
+ pthread_t threadID = pthread_self();
+
+ assert(pthread_getschedparam(threadID, &policy, &param) == 0);
+ assert(policy == SCHED_OTHER);
+ return (void *) (param.sched_priority);
+}
+
+void *
+getValidPriorities(void * arg)
+{
+ int prioSet;
+ pthread_t threadID = pthread_self();
+ HANDLE threadH = pthread_getw32threadhandle_np(threadID);
+
+ printf("Using GetThreadPriority\n");
+ printf("%10s %10s\n", "Set value", "Get value");
+
+ for (prioSet = minPrio;
+ prioSet <= maxPrio;
+ prioSet++)
+ {
+ /*
+ * If prioSet is invalid then the threads priority is unchanged
+ * from the previous value. Make the previous value a known
+ * one so that we can check later.
+ */
+ if (prioSet < 0)
+ SetThreadPriority(threadH, THREAD_PRIORITY_LOWEST);
+ else
+ SetThreadPriority(threadH, THREAD_PRIORITY_HIGHEST);
+ SetThreadPriority(threadH, prioSet);
+ validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)] = GetThreadPriority(threadH);
+ printf("%10d %10d\n", prioSet, validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)]);
+ }
+
+ return (void *) 0;
+}
+
+
+int
+main()
+{
+ pthread_t t;
+ pthread_attr_t attr;
+ void * result = NULL;
+ struct sched_param param;
+
+ assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1);
+ assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1);
+
+ assert(pthread_create(&t, NULL, getValidPriorities, NULL) == 0);
+ assert(pthread_join(t, &result) == 0);
+
+ assert(pthread_attr_init(&attr) == 0);
+ assert(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0);
+
+ /* Set the thread's priority to a known initial value. */
+ SetThreadPriority(pthread_getw32threadhandle_np(pthread_self()),
+ PTW32TEST_THREAD_INIT_PRIO);
+
+ printf("Using pthread_getschedparam\n");
+ printf("%10s %10s %10s\n", "Set value", "Get value", "Win priority");
+
+ for (param.sched_priority = minPrio;
+ param.sched_priority <= maxPrio;
+ param.sched_priority++)
+ {
+ int prio;
+
+ assert(pthread_attr_setschedparam(&attr, &param) == 0);
+ assert(pthread_create(&t, &attr, func, (void *) &attr) == 0);
+
+ assert((prio = GetThreadPriority(pthread_getw32threadhandle_np(t)))
+ == validPriorities[param.sched_priority+(PTW32TEST_MAXPRIORITIES/2)]);
+
+ assert(pthread_join(t, &result) == 0);
+
+ assert(param.sched_priority == (int) result);
+ printf("%10d %10d %10d\n", param.sched_priority, (int) result, prio);
+ }
+
+ return 0;
+}
diff --git a/pthreads/tests/priority2.c b/pthreads/tests/priority2.c
new file mode 100644
index 000000000..a5575abe9
--- /dev/null
+++ b/pthreads/tests/priority2.c
@@ -0,0 +1,169 @@
+/*
+ * File: priority2.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 thread priority setting after creation.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+enum {
+ PTW32TEST_THREAD_INIT_PRIO = 0,
+ PTW32TEST_MAXPRIORITIES = 512
+};
+
+int minPrio;
+int maxPrio;
+int validPriorities[PTW32TEST_MAXPRIORITIES];
+pthread_barrier_t startBarrier, endBarrier;
+
+void * func(void * arg)
+{
+ int policy;
+ int result;
+ struct sched_param param;
+
+ result = pthread_barrier_wait(&startBarrier);
+ assert(result == 0 || result == PTHREAD_BARRIER_SERIAL_THREAD);
+ assert(pthread_getschedparam(pthread_self(), &policy, &param) == 0);
+ assert(policy == SCHED_OTHER);
+ result = pthread_barrier_wait(&endBarrier);
+ assert(result == 0 || result == PTHREAD_BARRIER_SERIAL_THREAD);
+ return (void *) param.sched_priority;
+}
+
+
+void *
+getValidPriorities(void * arg)
+{
+ int prioSet;
+ pthread_t thread = pthread_self();
+ HANDLE threadH = pthread_getw32threadhandle_np(thread);
+ struct sched_param param;
+
+ for (prioSet = minPrio;
+ prioSet <= maxPrio;
+ prioSet++)
+ {
+ /*
+ * If prioSet is invalid then the threads priority is unchanged
+ * from the previous value. Make the previous value a known
+ * one so that we can check later.
+ */
+ param.sched_priority = prioSet;
+ assert(pthread_setschedparam(thread, SCHED_OTHER, &param) == 0);
+ validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)] = GetThreadPriority(threadH);
+ }
+
+ return (void *) 0;
+}
+
+
+int
+main()
+{
+ pthread_t t;
+ void * result = NULL;
+ int result2;
+ struct sched_param param;
+
+ assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1);
+ assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1);
+
+ assert(pthread_create(&t, NULL, getValidPriorities, NULL) == 0);
+ assert(pthread_join(t, &result) == 0);
+
+ assert(pthread_barrier_init(&startBarrier, NULL, 2) == 0);
+ assert(pthread_barrier_init(&endBarrier, NULL, 2) == 0);
+
+ /* Set the thread's priority to a known initial value.
+ * If the new priority is invalid then the threads priority
+ * is unchanged from the previous value.
+ */
+ SetThreadPriority(pthread_getw32threadhandle_np(pthread_self()),
+ PTW32TEST_THREAD_INIT_PRIO);
+
+ for (param.sched_priority = minPrio;
+ param.sched_priority <= maxPrio;
+ param.sched_priority++)
+ {
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+ assert(pthread_setschedparam(t, SCHED_OTHER, &param) == 0);
+ result2 = pthread_barrier_wait(&startBarrier);
+ assert(result2 == 0 || result2 == PTHREAD_BARRIER_SERIAL_THREAD);
+ result2 = pthread_barrier_wait(&endBarrier);
+ assert(result2 == 0 || result2 == PTHREAD_BARRIER_SERIAL_THREAD);
+ assert(GetThreadPriority(pthread_getw32threadhandle_np(t)) ==
+ validPriorities[param.sched_priority+(PTW32TEST_MAXPRIORITIES/2)]);
+ pthread_join(t, &result);
+ assert(param.sched_priority == (int)result);
+ }
+
+ return 0;
+}
diff --git a/pthreads/tests/reuse1.c b/pthreads/tests/reuse1.c
new file mode 100644
index 000000000..ae9efe400
--- /dev/null
+++ b/pthreads/tests/reuse1.c
@@ -0,0 +1,124 @@
+/*
+ * File: reuse1.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:
+ * - Confirm that thread reuse works for joined threads.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+enum {
+ NUMTHREADS = 100
+};
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ washere = 1;
+ return arg;
+}
+
+int
+main()
+{
+ pthread_t t,
+ last_t;
+ pthread_attr_t attr;
+ void * result = NULL;
+ int i;
+
+ assert(pthread_attr_init(&attr) == 0);;
+ assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == 0);
+
+ washere = 0;
+ assert(pthread_create(&t, &attr, func, NULL) == 0);
+ assert(pthread_join(t, &result) == 0);;
+ assert(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);
+ pthread_join(t, &result);
+ assert((int) result == i);
+ assert(washere == 1);
+ /* thread IDs should be unique */
+ assert(!pthread_equal(t, last_t));
+ /* thread struct pointers should be the same */
+ assert(t.p == last_t.p);
+ /* thread handle reuse counter should be different by one */
+ assert(t.x == last_t.x+1);
+ last_t = t;
+ }
+
+ return 0;
+}
diff --git a/pthreads/tests/reuse2.c b/pthreads/tests/reuse2.c
new file mode 100644
index 000000000..c4db81199
--- /dev/null
+++ b/pthreads/tests/reuse2.c
@@ -0,0 +1,167 @@
+/*
+ * File: reuse2.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 that thread reuse works for detached threads.
+ * - 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.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+/*
+ */
+
+enum {
+ NUMTHREADS = 10000
+};
+
+
+static long done = 0;
+
+void * func(void * arg)
+{
+ sched_yield();
+
+ InterlockedIncrement(&done);
+
+ return (void *) 0;
+}
+
+int
+main()
+{
+ pthread_t t[NUMTHREADS];
+ pthread_attr_t attr;
+ int i;
+ unsigned int notUnique = 0,
+ totalHandles = 0,
+ reuseMax = 0,
+ reuseMin = NUMTHREADS;
+
+ assert(pthread_attr_init(&attr) == 0);
+ assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0);
+
+ for (i = 0; i < NUMTHREADS; i++)
+ {
+ assert(pthread_create(&t[i], &attr, func, NULL) == 0);
+ }
+
+ while (NUMTHREADS > InterlockedExchangeAdd((LPLONG)&done, 0L))
+ Sleep(100);
+
+ Sleep(100);
+
+ /*
+ * Analyse reuse by computing min and max number of times pthread_create()
+ * returned the same pthread_t value.
+ */
+ for (i = 0; i < NUMTHREADS; i++)
+ {
+ if (t[i].p != NULL)
+ {
+ unsigned int j, thisMax;
+
+ thisMax = t[i].x;
+
+ for (j = i+1; j < NUMTHREADS; j++)
+ if (t[i].p == t[j].p)
+ {
+ if (t[i].x == t[j].x)
+ notUnique++;
+ if (thisMax < t[j].x)
+ thisMax = t[j].x;
+ t[j].p = NULL;
+ }
+
+ if (reuseMin > thisMax)
+ reuseMin = thisMax;
+
+ if (reuseMax < thisMax)
+ reuseMax = thisMax;
+ }
+ }
+
+ for (i = 0; i < NUMTHREADS; i++)
+ if (t[i].p != NULL)
+ totalHandles++;
+
+ /*
+ * pthread_t reuse counts start at 0, so we need to add 1
+ * to the max and min values derived above.
+ */
+ printf("For %d total threads:\n", NUMTHREADS);
+ printf("Non-unique IDs = %d\n", notUnique);
+ printf("Reuse maximum = %d\n", reuseMax + 1);
+ printf("Reuse minimum = %d\n", reuseMin + 1);
+ printf("Total handles = %d\n", totalHandles);
+
+ return 0;
+}
diff --git a/pthreads/tests/rwlock1.c b/pthreads/tests/rwlock1.c
new file mode 100644
index 000000000..3d08ac993
--- /dev/null
+++ b/pthreads/tests/rwlock1.c
@@ -0,0 +1,61 @@
+/*
+ * rwlock1.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 a simple rwlock object and then destroy it.
+ *
+ * Depends on API functions:
+ * pthread_rwlock_init()
+ * pthread_rwlock_destroy()
+ */
+
+#include "test.h"
+
+pthread_rwlock_t rwlock = NULL;
+
+int
+main()
+{
+ assert(rwlock == NULL);
+
+ assert(pthread_rwlock_init(&rwlock, NULL) == 0);
+
+ assert(rwlock != NULL);
+
+ assert(pthread_rwlock_destroy(&rwlock) == 0);
+
+ assert(rwlock == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/rwlock2.c b/pthreads/tests/rwlock2.c
new file mode 100644
index 000000000..07518ebde
--- /dev/null
+++ b/pthreads/tests/rwlock2.c
@@ -0,0 +1,66 @@
+/*
+ * rwlock2.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static rwlock object, lock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_rwlock_rdlock()
+ * pthread_rwlock_unlock()
+ */
+
+#include "test.h"
+
+pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
+
+int
+main()
+{
+ assert(rwlock == PTHREAD_RWLOCK_INITIALIZER);
+
+ assert(pthread_rwlock_rdlock(&rwlock) == 0);
+
+ assert(rwlock != PTHREAD_RWLOCK_INITIALIZER);
+
+ assert(rwlock != NULL);
+
+ assert(pthread_rwlock_unlock(&rwlock) == 0);
+
+ assert(pthread_rwlock_destroy(&rwlock) == 0);
+
+ assert(rwlock == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/rwlock2_t.c b/pthreads/tests/rwlock2_t.c
new file mode 100644
index 000000000..8e6ab6da0
--- /dev/null
+++ b/pthreads/tests/rwlock2_t.c
@@ -0,0 +1,78 @@
+/*
+ * rwlock2_t.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static rwlock object, timed-lock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_rwlock_timedrdlock()
+ * pthread_rwlock_unlock()
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
+
+int
+main()
+{
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 1;
+
+ assert(rwlock == PTHREAD_RWLOCK_INITIALIZER);
+
+ assert(pthread_rwlock_timedrdlock(&rwlock, &abstime) == 0);
+
+ assert(rwlock != PTHREAD_RWLOCK_INITIALIZER);
+
+ assert(rwlock != NULL);
+
+ assert(pthread_rwlock_unlock(&rwlock) == 0);
+
+ assert(pthread_rwlock_destroy(&rwlock) == 0);
+
+ assert(rwlock == NULL);
+
+ return 0;
+}
diff --git a/pthreads/tests/rwlock3.c b/pthreads/tests/rwlock3.c
new file mode 100644
index 000000000..4b22c5a16
--- /dev/null
+++ b/pthreads/tests/rwlock3.c
@@ -0,0 +1,76 @@
+/*
+ * rwlock3.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static rwlock object, wrlock it, trywrlock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_rwlock_wrlock()
+ * pthread_rwlock_trywrlock()
+ * pthread_rwlock_unlock()
+ */
+
+#include "test.h"
+
+pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY);
+
+ washere = 1;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ assert(pthread_rwlock_wrlock(&rwlock1) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+
+ Sleep(2000);
+
+ assert(pthread_rwlock_unlock(&rwlock1) == 0);
+
+ assert(washere == 1);
+
+ return 0;
+}
diff --git a/pthreads/tests/rwlock3_t.c b/pthreads/tests/rwlock3_t.c
new file mode 100644
index 000000000..bc45abc4d
--- /dev/null
+++ b/pthreads/tests/rwlock3_t.c
@@ -0,0 +1,87 @@
+/*
+ * rwlock3_t.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static rwlock object, timed-wrlock it, trywrlock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_rwlock_timedwrlock()
+ * pthread_rwlock_trywrlock()
+ * pthread_rwlock_unlock()
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY);
+
+ washere = 1;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 1;
+
+ assert(pthread_rwlock_timedwrlock(&rwlock1, &abstime) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+
+ Sleep(2000);
+
+ assert(pthread_rwlock_unlock(&rwlock1) == 0);
+
+ assert(washere == 1);
+
+ return 0;
+}
diff --git a/pthreads/tests/rwlock4.c b/pthreads/tests/rwlock4.c
new file mode 100644
index 000000000..edd9dc2c3
--- /dev/null
+++ b/pthreads/tests/rwlock4.c
@@ -0,0 +1,76 @@
+/*
+ * rwlock4.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static rwlock object, rdlock it, trywrlock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_rwlock_rdlock()
+ * pthread_rwlock_trywrlock()
+ * pthread_rwlock_unlock()
+ */
+
+#include "test.h"
+
+pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY);
+
+ washere = 1;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ assert(pthread_rwlock_rdlock(&rwlock1) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+
+ Sleep(2000);
+
+ assert(pthread_rwlock_unlock(&rwlock1) == 0);
+
+ assert(washere == 1);
+
+ return 0;
+}
diff --git a/pthreads/tests/rwlock4_t.c b/pthreads/tests/rwlock4_t.c
new file mode 100644
index 000000000..37ec34fa3
--- /dev/null
+++ b/pthreads/tests/rwlock4_t.c
@@ -0,0 +1,87 @@
+/*
+ * rwlock4_t.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static rwlock object, timed-rdlock it, trywrlock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_rwlock_timedrdlock()
+ * pthread_rwlock_trywrlock()
+ * pthread_rwlock_unlock()
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY);
+
+ washere = 1;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 1;
+
+ assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+
+ Sleep(2000);
+
+ assert(pthread_rwlock_unlock(&rwlock1) == 0);
+
+ assert(washere == 1);
+
+ return 0;
+}
diff --git a/pthreads/tests/rwlock5.c b/pthreads/tests/rwlock5.c
new file mode 100644
index 000000000..75b82f32a
--- /dev/null
+++ b/pthreads/tests/rwlock5.c
@@ -0,0 +1,78 @@
+/*
+ * rwlock5.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static rwlock object, rdlock it, tryrdlock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_rwlock_rdlock()
+ * pthread_rwlock_tryrdlock()
+ * pthread_rwlock_unlock()
+ */
+
+#include "test.h"
+
+pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ assert(pthread_rwlock_tryrdlock(&rwlock1) == 0);
+
+ assert(pthread_rwlock_unlock(&rwlock1) == 0);
+
+ washere = 1;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ assert(pthread_rwlock_rdlock(&rwlock1) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+
+ Sleep(2000);
+
+ assert(pthread_rwlock_unlock(&rwlock1) == 0);
+
+ assert(washere == 1);
+
+ return 0;
+}
diff --git a/pthreads/tests/rwlock5_t.c b/pthreads/tests/rwlock5_t.c
new file mode 100644
index 000000000..bf473a40e
--- /dev/null
+++ b/pthreads/tests/rwlock5_t.c
@@ -0,0 +1,89 @@
+/*
+ * rwlock5_t.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static rwlock object, timed-rdlock it, tryrdlock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_rwlock_timedrdlock()
+ * pthread_rwlock_tryrdlock()
+ * pthread_rwlock_unlock()
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ assert(pthread_rwlock_tryrdlock(&rwlock1) == 0);
+
+ assert(pthread_rwlock_unlock(&rwlock1) == 0);
+
+ washere = 1;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+ abstime.tv_sec += 1;
+
+ assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+
+ Sleep(2000);
+
+ assert(pthread_rwlock_unlock(&rwlock1) == 0);
+
+ assert(washere == 1);
+
+ return 0;
+}
diff --git a/pthreads/tests/rwlock6.c b/pthreads/tests/rwlock6.c
new file mode 100644
index 000000000..22d10db42
--- /dev/null
+++ b/pthreads/tests/rwlock6.c
@@ -0,0 +1,101 @@
+/*
+ * rwlock6.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Check writer and reader locking
+ *
+ * Depends on API functions:
+ * pthread_rwlock_rdlock()
+ * pthread_rwlock_wrlock()
+ * pthread_rwlock_unlock()
+ */
+
+#include "test.h"
+
+static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
+
+static int bankAccount = 0;
+
+void * wrfunc(void * arg)
+{
+ int ba;
+
+ assert(pthread_rwlock_wrlock(&rwlock1) == 0);
+ Sleep(2000);
+ bankAccount += 10;
+ ba = bankAccount;
+ assert(pthread_rwlock_unlock(&rwlock1) == 0);
+
+ return ((void *) ba);
+}
+
+void * rdfunc(void * arg)
+{
+ int ba;
+
+ assert(pthread_rwlock_rdlock(&rwlock1) == 0);
+ ba = bankAccount;
+ assert(pthread_rwlock_unlock(&rwlock1) == 0);
+
+ return ((void *) ba);
+}
+
+int
+main()
+{
+ pthread_t wrt1;
+ pthread_t wrt2;
+ pthread_t rdt;
+ int wr1Result = 0;
+ int wr2Result = 0;
+ int rdResult = 0;
+
+ bankAccount = 0;
+
+ assert(pthread_create(&wrt1, NULL, wrfunc, NULL) == 0);
+ Sleep(500);
+ assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0);
+ Sleep(500);
+ 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(wr1Result == 10);
+ assert(rdResult == 10);
+ assert(wr2Result == 20);
+
+ return 0;
+}
diff --git a/pthreads/tests/rwlock6_t.c b/pthreads/tests/rwlock6_t.c
new file mode 100644
index 000000000..aa38bf564
--- /dev/null
+++ b/pthreads/tests/rwlock6_t.c
@@ -0,0 +1,126 @@
+/*
+ * rwlock6_t.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Check writer and reader locking with reader timeouts
+ *
+ * Depends on API functions:
+ * pthread_rwlock_timedrdlock()
+ * pthread_rwlock_wrlock()
+ * pthread_rwlock_unlock()
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
+
+static int bankAccount = 0;
+
+void * wrfunc(void * arg)
+{
+ assert(pthread_rwlock_wrlock(&rwlock1) == 0);
+ Sleep(2000);
+ bankAccount += 10;
+ assert(pthread_rwlock_unlock(&rwlock1) == 0);
+
+ return ((void *) bankAccount);
+}
+
+void * rdfunc(void * arg)
+{
+ int ba = -1;
+ struct timespec abstime = { 0, 0 };
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = currSysTime.time;
+ abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+
+
+ if ((int) arg == 1)
+ {
+ abstime.tv_sec += 1;
+ assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == ETIMEDOUT);
+ ba = 0;
+ }
+ else if ((int) arg == 2)
+ {
+ abstime.tv_sec += 3;
+ assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0);
+ ba = bankAccount;
+ assert(pthread_rwlock_unlock(&rwlock1) == 0);
+ }
+
+ return ((void *) ba);
+}
+
+int
+main()
+{
+ pthread_t wrt1;
+ pthread_t wrt2;
+ pthread_t rdt1;
+ pthread_t rdt2;
+ int wr1Result = 0;
+ int wr2Result = 0;
+ int rd1Result = 0;
+ int rd2Result = 0;
+
+ bankAccount = 0;
+
+ assert(pthread_create(&wrt1, NULL, wrfunc, NULL) == 0);
+ Sleep(500);
+ assert(pthread_create(&rdt1, NULL, rdfunc, (void *) 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_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(wr1Result == 10);
+ assert(rd1Result == 0);
+ assert(wr2Result == 20);
+ assert(rd2Result == 20);
+
+ return 0;
+}
+
+
diff --git a/pthreads/tests/rwlock6_t2.c b/pthreads/tests/rwlock6_t2.c
new file mode 100644
index 000000000..58bfc3d94
--- /dev/null
+++ b/pthreads/tests/rwlock6_t2.c
@@ -0,0 +1,119 @@
+/*
+ * rwlock6_t2.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Check writer and reader timeouts.
+ *
+ * Depends on API functions:
+ * pthread_rwlock_timedrdlock()
+ * pthread_rwlock_timedwrlock()
+ * pthread_rwlock_unlock()
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER;
+
+static int bankAccount = 0;
+struct timespec abstime = { 0, 0 };
+
+void * wrfunc(void * arg)
+{
+ int result;
+
+ result = pthread_rwlock_timedwrlock(&rwlock1, &abstime);
+ if ((int) arg == 1)
+ {
+ assert(result == 0);
+ Sleep(2000);
+ bankAccount += 10;
+ assert(pthread_rwlock_unlock(&rwlock1) == 0);
+ return ((void *) bankAccount);
+ }
+ else if ((int) arg == 2)
+ {
+ assert(result == ETIMEDOUT);
+ return ((void *) 100);
+ }
+
+ return ((void *) -1);
+}
+
+void * rdfunc(void * arg)
+{
+ int ba = 0;
+
+ assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == ETIMEDOUT);
+
+ return ((void *) ba);
+}
+
+int
+main()
+{
+ pthread_t wrt1;
+ pthread_t wrt2;
+ pthread_t rdt;
+ int wr1Result = 0;
+ int wr2Result = 0;
+ int rdResult = 0;
+ struct _timeb currSysTime;
+ const DWORD NANOSEC_PER_MILLISEC = 1000000;
+
+ _ftime(&currSysTime);
+
+ abstime.tv_sec = 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);
+ Sleep(100);
+ assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0);
+ Sleep(100);
+ assert(pthread_create(&wrt2, NULL, wrfunc, (void *) 2) == 0);
+
+ assert(pthread_join(wrt1, (void **) &wr1Result) == 0);
+ assert(pthread_join(rdt, (void **) &rdResult) == 0);
+ assert(pthread_join(wrt2, (void **) &wr2Result) == 0);
+
+ assert(wr1Result == 10);
+ assert(rdResult == 0);
+ assert(wr2Result == 100);
+
+ return 0;
+}
diff --git a/pthreads/tests/rwlock7.c b/pthreads/tests/rwlock7.c
new file mode 100644
index 000000000..91466e4de
--- /dev/null
+++ b/pthreads/tests/rwlock7.c
@@ -0,0 +1,199 @@
+/*
+ * rwlock7.c
+ *
+ * Hammer on a bunch of rwlocks to test robustness and fairness.
+ * Printed stats should be roughly even for each thread.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+#ifdef __GNUC__
+#include <stdlib.h>
+#endif
+
+#define THREADS 5
+#define DATASIZE 7
+#define ITERATIONS 1000000
+
+/*
+ * Keep statistics for each thread.
+ */
+typedef struct thread_tag {
+ int thread_num;
+ pthread_t thread_id;
+ int updates;
+ int reads;
+ int changed;
+ int seed;
+} thread_t;
+
+/*
+ * Read-write lock and shared data
+ */
+typedef struct data_tag {
+ pthread_rwlock_t lock;
+ int data;
+ int updates;
+} data_t;
+
+static thread_t threads[THREADS];
+static data_t data[DATASIZE];
+
+/*
+ * Thread start routine that uses read-write locks
+ */
+void *thread_routine (void *arg)
+{
+ thread_t *self = (thread_t*)arg;
+ int iteration;
+ int element = 0;
+ int seed = self->seed;
+ int interval = 1 + rand_r (&seed) % 71;
+
+ self->changed = 0;
+
+ for (iteration = 0; iteration < ITERATIONS; iteration++)
+ {
+ if (iteration % (ITERATIONS / 10) == 0)
+ {
+ putchar('.');
+ fflush(stdout);
+ }
+ /*
+ * Each "self->interval" iterations, perform an
+ * update operation (write lock instead of read
+ * lock).
+ */
+ if ((iteration % interval) == 0)
+ {
+ assert(pthread_rwlock_wrlock (&data[element].lock) == 0);
+ data[element].data = self->thread_num;
+ data[element].updates++;
+ self->updates++;
+ interval = 1 + rand_r (&seed) % 71;
+ assert(pthread_rwlock_unlock (&data[element].lock) == 0);
+ } else {
+ /*
+ * Look at the current data element to see whether
+ * the current thread last updated it. Count the
+ * times, to report later.
+ */
+ assert(pthread_rwlock_rdlock (&data[element].lock) == 0);
+
+ self->reads++;
+
+ if (data[element].data != self->thread_num)
+ {
+ self->changed++;
+ interval = 1 + self->changed % 71;
+ }
+
+ assert(pthread_rwlock_unlock (&data[element].lock) == 0);
+ }
+
+ element = (element + 1) % DATASIZE;
+
+ }
+
+ return NULL;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int count;
+ int data_count;
+ int thread_updates = 0;
+ int data_updates = 0;
+ int seed = 1;
+
+ struct _timeb currSysTime1;
+ struct _timeb currSysTime2;
+
+ /*
+ * Initialize the shared data.
+ */
+ for (data_count = 0; data_count < DATASIZE; data_count++)
+ {
+ data[data_count].data = 0;
+ data[data_count].updates = 0;
+
+ assert(pthread_rwlock_init (&data[data_count].lock, NULL) == 0);
+ }
+
+ _ftime(&currSysTime1);
+
+ /*
+ * Create THREADS threads to access shared data.
+ */
+ for (count = 0; count < THREADS; count++)
+ {
+ threads[count].thread_num = count;
+ threads[count].updates = 0;
+ threads[count].reads = 0;
+ threads[count].seed = 1 + rand_r (&seed) % 71;
+
+ assert(pthread_create (&threads[count].thread_id,
+ NULL, thread_routine, (void*)&threads[count]) == 0);
+ }
+
+ /*
+ * Wait for all threads to complete, and collect
+ * statistics.
+ */
+ for (count = 0; count < THREADS; count++)
+ {
+ assert(pthread_join (threads[count].thread_id, NULL) == 0);
+ }
+
+ putchar('\n');
+ fflush(stdout);
+
+ for (count = 0; count < THREADS; count++)
+ {
+ if (threads[count].changed > 0)
+ {
+ printf ("Thread %d found changed elements %d times\n",
+ count, threads[count].changed);
+ }
+ }
+
+ putchar('\n');
+ fflush(stdout);
+
+ for (count = 0; count < THREADS; count++)
+ {
+ thread_updates += threads[count].updates;
+ printf ("%02d: seed %d, updates %d, reads %d\n",
+ count, threads[count].seed,
+ threads[count].updates, threads[count].reads);
+ }
+
+ putchar('\n');
+ fflush(stdout);
+
+ /*
+ * Collect statistics for the data.
+ */
+ for (data_count = 0; data_count < DATASIZE; data_count++)
+ {
+ data_updates += data[data_count].updates;
+ printf ("data %02d: value %d, %d updates\n",
+ data_count, data[data_count].data, data[data_count].updates);
+ assert(pthread_rwlock_destroy (&data[data_count].lock) == 0);
+ }
+
+ printf ("%d thread updates, %d data updates\n",
+ thread_updates, data_updates);
+
+ _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));
+
+ return 0;
+}
diff --git a/pthreads/tests/rwlock8.c b/pthreads/tests/rwlock8.c
new file mode 100644
index 000000000..c83a775ce
--- /dev/null
+++ b/pthreads/tests/rwlock8.c
@@ -0,0 +1,205 @@
+/*
+ * rwlock8.c
+ *
+ * Hammer on a bunch of rwlocks to test robustness and fairness.
+ * Printed stats should be roughly even for each thread.
+ *
+ * Yield during each access to exercise lock contention code paths
+ * more than rwlock7.c does (particularly on uni-processor systems).
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+#ifdef __GNUC__
+#include <stdlib.h>
+#endif
+
+#define THREADS 5
+#define DATASIZE 7
+#define ITERATIONS 100000
+
+/*
+ * Keep statistics for each thread.
+ */
+typedef struct thread_tag {
+ int thread_num;
+ pthread_t thread_id;
+ int updates;
+ int reads;
+ int changed;
+ int seed;
+} thread_t;
+
+/*
+ * Read-write lock and shared data
+ */
+typedef struct data_tag {
+ pthread_rwlock_t lock;
+ int data;
+ int updates;
+} data_t;
+
+static thread_t threads[THREADS];
+static data_t data[DATASIZE];
+
+/*
+ * Thread start routine that uses read-write locks
+ */
+void *thread_routine (void *arg)
+{
+ thread_t *self = (thread_t*)arg;
+ int iteration;
+ int element = 0;
+ int seed = self->seed;
+ int interval = 1 + rand_r (&seed) % 71;
+
+ self->changed = 0;
+
+ for (iteration = 0; iteration < ITERATIONS; iteration++)
+ {
+ if (iteration % (ITERATIONS / 10) == 0)
+ {
+ putchar('.');
+ fflush(stdout);
+ }
+ /*
+ * Each "self->interval" iterations, perform an
+ * update operation (write lock instead of read
+ * lock).
+ */
+ if ((iteration % interval) == 0)
+ {
+ assert(pthread_rwlock_wrlock (&data[element].lock) == 0);
+ data[element].data = self->thread_num;
+ data[element].updates++;
+ self->updates++;
+ interval = 1 + rand_r (&seed) % 71;
+ sched_yield();
+ assert(pthread_rwlock_unlock (&data[element].lock) == 0);
+ } else {
+ /*
+ * Look at the current data element to see whether
+ * the current thread last updated it. Count the
+ * times, to report later.
+ */
+ assert(pthread_rwlock_rdlock (&data[element].lock) == 0);
+
+ self->reads++;
+
+ if (data[element].data != self->thread_num)
+ {
+ self->changed++;
+ interval = 1 + self->changed % 71;
+ }
+
+ sched_yield();
+
+ assert(pthread_rwlock_unlock (&data[element].lock) == 0);
+ }
+
+ element = (element + 1) % DATASIZE;
+
+ }
+
+ return NULL;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int count;
+ int data_count;
+ int thread_updates = 0;
+ int data_updates = 0;
+ int seed = 1;
+
+ struct _timeb currSysTime1;
+ struct _timeb currSysTime2;
+
+ /*
+ * Initialize the shared data.
+ */
+ for (data_count = 0; data_count < DATASIZE; data_count++)
+ {
+ data[data_count].data = 0;
+ data[data_count].updates = 0;
+
+ assert(pthread_rwlock_init (&data[data_count].lock, NULL) == 0);
+ }
+
+ _ftime(&currSysTime1);
+
+ /*
+ * Create THREADS threads to access shared data.
+ */
+ for (count = 0; count < THREADS; count++)
+ {
+ threads[count].thread_num = count;
+ threads[count].updates = 0;
+ threads[count].reads = 0;
+ threads[count].seed = 1 + rand_r (&seed) % 71;
+
+ assert(pthread_create (&threads[count].thread_id,
+ NULL, thread_routine, (void*)&threads[count]) == 0);
+ }
+
+ /*
+ * Wait for all threads to complete, and collect
+ * statistics.
+ */
+ for (count = 0; count < THREADS; count++)
+ {
+ assert(pthread_join (threads[count].thread_id, NULL) == 0);
+ }
+
+ putchar('\n');
+ fflush(stdout);
+
+ for (count = 0; count < THREADS; count++)
+ {
+ if (threads[count].changed > 0)
+ {
+ printf ("Thread %d found changed elements %d times\n",
+ count, threads[count].changed);
+ }
+ }
+
+ putchar('\n');
+ fflush(stdout);
+
+ for (count = 0; count < THREADS; count++)
+ {
+ thread_updates += threads[count].updates;
+ printf ("%02d: seed %d, updates %d, reads %d\n",
+ count, threads[count].seed,
+ threads[count].updates, threads[count].reads);
+ }
+
+ putchar('\n');
+ fflush(stdout);
+
+ /*
+ * Collect statistics for the data.
+ */
+ for (data_count = 0; data_count < DATASIZE; data_count++)
+ {
+ data_updates += data[data_count].updates;
+ printf ("data %02d: value %d, %d updates\n",
+ data_count, data[data_count].data, data[data_count].updates);
+ assert(pthread_rwlock_destroy (&data[data_count].lock) == 0);
+ }
+
+ printf ("%d thread updates, %d data updates\n",
+ thread_updates, data_updates);
+
+ _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));
+
+ return 0;
+}
diff --git a/pthreads/tests/self1.c b/pthreads/tests/self1.c
new file mode 100644
index 000000000..59498d97e
--- /dev/null
+++ b/pthreads/tests/self1.c
@@ -0,0 +1,69 @@
+/*
+ * self1.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 for pthread_self().
+ *
+ * Depends on API functions:
+ * pthread_self()
+ *
+ * Implicitly depends on:
+ * pthread_getspecific()
+ * pthread_setspecific()
+ */
+
+#include "test.h"
+
+int
+main(int argc, char * argv[])
+{
+ /*
+ * This should always succeed unless the system has no
+ * resources (memory) left.
+ */
+ pthread_t self;
+
+#ifdef PTW32_STATIC_LIB
+ pthread_win32_process_attach_np();
+#endif
+
+ self = pthread_self();
+
+ assert(self.p != NULL);
+
+#ifdef PTW32_STATIC_LIB
+ pthread_win32_process_detach_np();
+#endif
+ return 0;
+}
diff --git a/pthreads/tests/self2.c b/pthreads/tests/self2.c
new file mode 100644
index 000000000..28e57252e
--- /dev/null
+++ b/pthreads/tests/self2.c
@@ -0,0 +1,73 @@
+/*
+ * self2.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 for pthread_self().
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_self()
+ *
+ * Implicitly depends on:
+ * pthread_getspecific()
+ * pthread_setspecific()
+ */
+
+#include "test.h"
+#include <string.h>
+
+static pthread_t me;
+
+void *
+entry(void * arg)
+{
+ me = pthread_self();
+
+ return arg;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ assert(pthread_create(&t, NULL, entry, NULL) == 0);
+
+ Sleep(100);
+
+ assert(pthread_equal(t, me) != 0);
+
+ /* Success. */
+ return 0;
+}
diff --git a/pthreads/tests/semaphore1.c b/pthreads/tests/semaphore1.c
new file mode 100644
index 000000000..f89a43081
--- /dev/null
+++ b/pthreads/tests/semaphore1.c
@@ -0,0 +1,161 @@
+/*
+ * File: semaphore1.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis: Verify trywait() returns -1 and sets EAGAIN.
+ * -
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+void *
+thr(void * arg)
+{
+ sem_t s;
+ int result;
+
+ assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0);
+
+ assert((result = sem_trywait(&s)) == -1);
+
+ if ( result == -1 )
+ {
+ int err = errno;
+ printf("thread: sem_trywait 1: expecting error %s: got %s\n",
+ error_string[EAGAIN], error_string[err]); fflush(stdout);
+ assert(err == EAGAIN);
+ }
+ else
+ {
+ printf("thread: ok 1\n");
+ }
+
+ assert((result = sem_post(&s)) == 0);
+
+ assert((result = sem_trywait(&s)) == 0);
+
+ if ( result == -1 )
+ {
+ perror("thread: sem_trywait 2");
+ }
+ else
+ {
+ printf("thread: ok 2\n");
+ }
+
+ assert(sem_post(&s) == 0);
+
+ return 0;
+}
+
+
+int
+main()
+{
+ pthread_t t;
+ sem_t s;
+ int result;
+
+ assert(pthread_create(&t, NULL, thr, NULL) == 0);
+ assert(pthread_join(t, (void **)&result) == 0);
+ assert(result == 0);
+
+ assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0);
+
+ assert((result = sem_trywait(&s)) == -1);
+
+ if ( result == -1 )
+ {
+ int err = errno;
+ printf("main: sem_trywait 1: expecting error %s: got %s\n",
+ error_string[EAGAIN], error_string[err]); fflush(stdout);
+ assert(err == EAGAIN);
+ }
+ else
+ {
+ printf("main: ok 1\n");
+ }
+
+ assert((result = sem_post(&s)) == 0);
+
+ assert((result = sem_trywait(&s)) == 0);
+
+ if ( result == -1 )
+ {
+ perror("main: sem_trywait 2");
+ }
+ else
+ {
+ printf("main: ok 2\n");
+ }
+
+ assert(sem_post(&s) == 0);
+
+ return 0;
+}
+
diff --git a/pthreads/tests/semaphore2.c b/pthreads/tests/semaphore2.c
new file mode 100644
index 000000000..af4d0ea70
--- /dev/null
+++ b/pthreads/tests/semaphore2.c
@@ -0,0 +1,108 @@
+/*
+ * File: semaphore2.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis: Verify sem_getvalue returns the correct value.
+ * -
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+#define MAX_COUNT 100
+
+int
+main()
+{
+ sem_t s;
+ int value = 0;
+ int i;
+
+ assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, MAX_COUNT) == 0);
+ assert(sem_getvalue(&s, &value) == 0);
+ assert(value == MAX_COUNT);
+// printf("Value = %ld\n", value);
+
+ for (i = MAX_COUNT - 1; i >= 0; i--)
+ {
+ assert(sem_wait(&s) == 0);
+ assert(sem_getvalue(&s, &value) == 0);
+// printf("Value = %ld\n", value);
+ assert(value == i);
+ }
+
+ for (i = 1; i <= MAX_COUNT; i++)
+ {
+ assert(sem_post(&s) == 0);
+ assert(sem_getvalue(&s, &value) == 0);
+// printf("Value = %ld\n", value);
+ assert(value == i);
+ }
+
+ return 0;
+}
+
diff --git a/pthreads/tests/semaphore3.c b/pthreads/tests/semaphore3.c
new file mode 100644
index 000000000..a0dfcb6f6
--- /dev/null
+++ b/pthreads/tests/semaphore3.c
@@ -0,0 +1,121 @@
+/*
+ * File: semaphore3.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis: Verify sem_getvalue returns the correct number of waiters.
+ * -
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+#define MAX_COUNT 100
+
+sem_t s;
+
+void *
+thr (void * arg)
+{
+ assert(sem_wait(&s) == 0);
+ assert(pthread_detach(pthread_self()) == 0);
+ return NULL;
+}
+
+int
+main()
+{
+ int value = 0;
+ int i;
+ pthread_t t[MAX_COUNT+1];
+
+ 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++)
+ {
+ assert(pthread_create(&t[i], NULL, thr, NULL) == 0);
+ do {
+ sched_yield();
+ assert(sem_getvalue(&s, &value) == 0);
+ } while (value != -i);
+// printf("Value = %d\n", value); fflush(stdout);
+ assert(-value == i);
+ }
+
+ for (i = MAX_COUNT - 1; i >= 0; i--)
+ {
+ assert(sem_post(&s) == 0);
+ assert(sem_getvalue(&s, &value) == 0);
+// printf("Value = %d\n", value); fflush(stdout);
+ assert(-value == i);
+ }
+
+ return 0;
+}
+
diff --git a/pthreads/tests/semaphore4.c b/pthreads/tests/semaphore4.c
new file mode 100644
index 000000000..37613ac39
--- /dev/null
+++ b/pthreads/tests/semaphore4.c
@@ -0,0 +1,138 @@
+/*
+ * File: semaphore4.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis: Verify sem_getvalue returns the correct number of waiters
+ * after threads are cancelled.
+ * -
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+#define MAX_COUNT 100
+
+sem_t s;
+
+void *
+thr (void * arg)
+{
+ assert(sem_wait(&s) == 0);
+ return NULL;
+}
+
+int
+main()
+{
+ int value = 0;
+ int i;
+ pthread_t t[MAX_COUNT+1];
+
+ 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++)
+ {
+ assert(pthread_create(&t[i], NULL, thr, NULL) == 0);
+ do {
+ 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);
+ }
+ 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);
+ }
+
+ for (i = 1; i <= MAX_COUNT; i++)
+ if (i != 50)
+ assert(pthread_join(t[i], NULL) == 0);
+
+ return 0;
+}
+
diff --git a/pthreads/tests/semaphore4t.c b/pthreads/tests/semaphore4t.c
new file mode 100644
index 000000000..14a46694c
--- /dev/null
+++ b/pthreads/tests/semaphore4t.c
@@ -0,0 +1,132 @@
+/*
+ * File: semaphore4t.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis: Verify sem_getvalue returns the correct number of waiters
+ * after threads are cancelled.
+ * -
+ *
+ * Test Method (Validation or Falsification):
+ * - Validation
+ *
+ * Requirements Tested:
+ * - sem_timedwait cancellation.
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+#define MAX_COUNT 100
+
+sem_t s;
+
+void *
+thr (void * arg)
+{
+ assert(sem_timedwait(&s, NULL) == 0);
+ return NULL;
+}
+
+int
+main()
+{
+ int value = 0;
+ int i;
+ pthread_t t[MAX_COUNT+1];
+
+ 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++)
+ {
+ assert(pthread_create(&t[i], NULL, thr, NULL) == 0);
+ do {
+ 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);
+ assert(pthread_cancel(t[50]) == 0);
+ assert(pthread_join(t[50], NULL) == 0);
+ assert(sem_getvalue(&s, &value) == 0);
+ 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);
+ }
+
+ for (i = 1; i <= MAX_COUNT; i++)
+ if (i != 50)
+ assert(pthread_join(t[i], NULL) == 0);
+
+ return 0;
+}
+
diff --git a/pthreads/tests/sizes.c b/pthreads/tests/sizes.c
new file mode 100644
index 000000000..73c726171
--- /dev/null
+++ b/pthreads/tests/sizes.c
@@ -0,0 +1,32 @@
+#define _WIN32_WINNT 0x400
+
+#include "test.h"
+#include "../implement.h"
+
+int
+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("-------------------------------\n");
+
+ return 0;
+}
diff --git a/pthreads/tests/spin1.c b/pthreads/tests/spin1.c
new file mode 100644
index 000000000..00ecd11b1
--- /dev/null
+++ b/pthreads/tests/spin1.c
@@ -0,0 +1,59 @@
+/*
+ * spin1.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 a simple spinlock object, lock it, and then unlock it again.
+ * This is the simplest test of the pthread mutex family that we can do.
+ *
+ */
+
+#include "test.h"
+
+pthread_spinlock_t lock;
+
+int
+main()
+{
+ assert(pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE) == 0);
+
+ assert(pthread_spin_lock(&lock) == 0);
+
+ assert(pthread_spin_unlock(&lock) == 0);
+
+ assert(pthread_spin_destroy(&lock) == 0);
+
+ assert(pthread_spin_lock(&lock) == EINVAL);
+
+ return 0;
+}
diff --git a/pthreads/tests/spin2.c b/pthreads/tests/spin2.c
new file mode 100644
index 000000000..b13c29c4e
--- /dev/null
+++ b/pthreads/tests/spin2.c
@@ -0,0 +1,75 @@
+/*
+ * spin2.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a spinlock object, lock it, trylock it,
+ * and then unlock it again.
+ *
+ */
+
+#include "test.h"
+
+pthread_spinlock_t lock = NULL;
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ assert(pthread_spin_trylock(&lock) == EBUSY);
+
+ washere = 1;
+
+ return 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ assert(pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE) == 0);
+
+ assert(pthread_spin_lock(&lock) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+ assert(pthread_join(t, NULL) == 0);
+
+ assert(pthread_spin_unlock(&lock) == 0);
+
+ assert(pthread_spin_destroy(&lock) == 0);
+
+ assert(washere == 1);
+
+ return 0;
+}
diff --git a/pthreads/tests/spin3.c b/pthreads/tests/spin3.c
new file mode 100644
index 000000000..8c0dae69f
--- /dev/null
+++ b/pthreads/tests/spin3.c
@@ -0,0 +1,72 @@
+/*
+ * spin3.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 spin - thread B tries to unlock.
+ * This should succeed, but it's undefined behaviour.
+ *
+ */
+
+#include "test.h"
+
+static int wasHere = 0;
+
+static pthread_spinlock_t spin;
+
+void * unlocker(void * arg)
+{
+ int expectedResult = (int) arg;
+
+ wasHere++;
+ assert(pthread_spin_unlock(&spin) == expectedResult);
+ wasHere++;
+ return NULL;
+}
+
+int
+main()
+{
+ pthread_t t;
+
+ 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_join(t, NULL) == 0);
+ assert(pthread_spin_unlock(&spin) == EPERM);
+ assert(pthread_spin_destroy(&spin) == 0);
+ assert(wasHere == 2);
+
+ return 0;
+}
diff --git a/pthreads/tests/spin4.c b/pthreads/tests/spin4.c
new file mode 100644
index 000000000..8386d0956
--- /dev/null
+++ b/pthreads/tests/spin4.c
@@ -0,0 +1,103 @@
+/*
+ * spin4.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Declare a static spinlock object, lock it, spin on it,
+ * and then unlock it again.
+ */
+
+#include "test.h"
+#include <sys/timeb.h>
+
+pthread_spinlock_t lock = PTHREAD_SPINLOCK_INITIALIZER;
+struct _timeb currSysTimeStart;
+struct _timeb currSysTimeStop;
+
+#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \
+ - (_TStart.time*1000+_TStart.millitm))
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ _ftime(&currSysTimeStart);
+ washere = 1;
+ assert(pthread_spin_lock(&lock) == 0);
+ assert(pthread_spin_unlock(&lock) == 0);
+ _ftime(&currSysTimeStop);
+
+ return (void *) GetDurationMilliSecs(currSysTimeStart, currSysTimeStop);
+}
+
+int
+main()
+{
+ long result = 0;
+ pthread_t t;
+ int CPUs;
+ struct _timeb sysTime;
+
+ if ((CPUs = pthread_num_processors_np()) == 1)
+ {
+ printf("Test not run - it requires multiple CPUs.\n");
+ exit(0);
+ }
+
+ assert(pthread_spin_lock(&lock) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+
+ while (washere == 0)
+ {
+ sched_yield();
+ }
+
+ do
+ {
+ sched_yield();
+ _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_spin_destroy(&lock) == 0);
+
+ assert(washere == 1);
+
+ return 0;
+}
diff --git a/pthreads/tests/stress1.c b/pthreads/tests/stress1.c
new file mode 100644
index 000000000..efaf44517
--- /dev/null
+++ b/pthreads/tests/stress1.c
@@ -0,0 +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 not 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 <string.h>
+#include <sys/timeb.h>
+
+
+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;
+}
diff --git a/pthreads/tests/test.h b/pthreads/tests/test.h
new file mode 100644
index 000000000..3132c6914
--- /dev/null
+++ b/pthreads/tests/test.h
@@ -0,0 +1,140 @@
+/*
+ * 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 <windows.h>
+#include <stdio.h>
+
+#define PTW32_THREAD_NULL_ID {NULL,0}
+
+#if defined(__MINGW32__)
+#include <stdint.h>
+#elif defined(__BORLANDC__)
+#define int64_t ULONGLONG
+#else
+#define int64_t _int64
+#endif
+
+
+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
diff --git a/pthreads/tests/tryentercs.c b/pthreads/tests/tryentercs.c
new file mode 100644
index 000000000..13a6e096d
--- /dev/null
+++ b/pthreads/tests/tryentercs.c
@@ -0,0 +1,103 @@
+/*
+ * tryentercs.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * See if we have the TryEnterCriticalSection function.
+ * Does not use any part of pthreads.
+ */
+
+#include <windows.h>
+#include <process.h>
+#include <stdio.h>
+
+/*
+ * Function pointer to TryEnterCriticalSection if it exists
+ * - otherwise NULL
+ */
+BOOL (WINAPI *_try_enter_critical_section)(LPCRITICAL_SECTION) =
+NULL;
+
+/*
+ * Handle to kernel32.dll
+ */
+static HINSTANCE _h_kernel32;
+
+
+int
+main()
+{
+ CRITICAL_SECTION cs;
+
+ SetLastError(0);
+
+ printf("Last Error [main enter] %ld\n", (long) GetLastError());
+
+ /*
+ * Load KERNEL32 and try to get address of TryEnterCriticalSection
+ */
+ _h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL"));
+ _try_enter_critical_section =
+ (BOOL (PT_STDCALL *)(LPCRITICAL_SECTION))
+ GetProcAddress(_h_kernel32,
+ (LPCSTR) "TryEnterCriticalSection");
+
+ if (_try_enter_critical_section != NULL)
+ {
+ InitializeCriticalSection(&cs);
+
+ SetLastError(0);
+
+ if ((*_try_enter_critical_section)(&cs) != 0)
+ {
+ LeaveCriticalSection(&cs);
+ }
+ else
+ {
+ printf("Last Error [try enter] %ld\n", (long) GetLastError());
+
+ _try_enter_critical_section = NULL;
+ }
+ DeleteCriticalSection(&cs);
+ }
+
+ (void) FreeLibrary(_h_kernel32);
+
+ printf("This system %s TryEnterCriticalSection.\n",
+ (_try_enter_critical_section == NULL) ? "DOES NOT SUPPORT" : "SUPPORTS");
+ printf("POSIX Mutexes will be based on Win32 %s.\n",
+ (_try_enter_critical_section == NULL) ? "Mutexes" : "Critical Sections");
+
+ return(0);
+}
+
diff --git a/pthreads/tests/tryentercs2.c b/pthreads/tests/tryentercs2.c
new file mode 100644
index 000000000..a1c4d97f3
--- /dev/null
+++ b/pthreads/tests/tryentercs2.c
@@ -0,0 +1,92 @@
+/*
+ * tryentercs.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
+ *
+ * --------------------------------------------------------------------------
+ *
+ * See if we have the TryEnterCriticalSection function.
+ * Does not use any part of pthreads.
+ */
+
+#include <windows.h>
+#include <process.h>
+#include <stdio.h>
+
+/*
+ * Function pointer to TryEnterCriticalSection if it exists
+ * - otherwise NULL
+ */
+BOOL (WINAPI *_try_enter_critical_section)(LPCRITICAL_SECTION) = NULL;
+
+/*
+ * Handle to kernel32.dll
+ */
+static HINSTANCE _h_kernel32;
+
+
+int
+main()
+{
+ LPCRITICAL_SECTION lpcs = NULL;
+
+ SetLastError(0);
+
+ printf("Last Error [main enter] %ld\n", (long) GetLastError());
+
+ /*
+ * Load KERNEL32 and try to get address of TryEnterCriticalSection
+ */
+ _h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL"));
+ _try_enter_critical_section =
+ (BOOL (PT_STDCALL *)(LPCRITICAL_SECTION))
+ GetProcAddress(_h_kernel32,
+ (LPCSTR) "TryEnterCriticalSection");
+
+ if (_try_enter_critical_section != NULL)
+ {
+ SetLastError(0);
+
+ (*_try_enter_critical_section)(lpcs);
+
+ printf("Last Error [try enter] %ld\n", (long) GetLastError());
+ }
+
+ (void) FreeLibrary(_h_kernel32);
+
+ printf("This system %s TryEnterCriticalSection.\n",
+ (_try_enter_critical_section == NULL) ? "DOES NOT SUPPORT" : "SUPPORTS");
+ printf("POSIX Mutexes will be based on Win32 %s.\n",
+ (_try_enter_critical_section == NULL) ? "Mutexes" : "Critical Sections");
+
+ return(0);
+}
+
diff --git a/pthreads/tests/tsd1.c b/pthreads/tests/tsd1.c
new file mode 100644
index 000000000..c28e4c53e
--- /dev/null
+++ b/pthreads/tests/tsd1.c
@@ -0,0 +1,211 @@
+/*
+ * tsd1.c
+ *
+ * Test Thread Specific Data (TSD) key creation and destruction.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Description:
+ * -
+ *
+ * Test Method (validation or falsification):
+ * - validation
+ *
+ * Requirements Tested:
+ * - keys are created for each existing thread including the main thread
+ * - keys are created for newly created threads
+ * - keys are thread specific
+ * - destroy routine is called on each thread exit including the main thread
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - none
+ *
+ * Output:
+ * - text to stdout
+ *
+ * Assumptions:
+ * - already validated: pthread_create()
+ * pthread_once()
+ * - main thread also has a POSIX thread identity
+ *
+ * Pass Criteria:
+ * - stdout matches file reference/tsd1.out
+ *
+ * Fail Criteria:
+ * - fails to match file reference/tsd1.out
+ * - output identifies failed component
+ */
+
+#include <sched.h>
+#include "test.h"
+
+enum {
+ NUM_THREADS = 100
+};
+
+static pthread_key_t key = NULL;
+static int accesscount[NUM_THREADS];
+static int thread_set[NUM_THREADS];
+static int thread_destroyed[NUM_THREADS];
+static pthread_barrier_t startBarrier;
+
+static void
+destroy_key(void * arg)
+{
+ int * j = (int *) arg;
+
+ (*j)++;
+
+ assert(*j == 2);
+
+ thread_destroyed[j - accesscount] = 1;
+}
+
+static void
+setkey(void * arg)
+{
+ int * j = (int *) arg;
+
+ thread_set[j - accesscount] = 1;
+
+ assert(*j == 0);
+
+ assert(pthread_getspecific(key) == NULL);
+
+ assert(pthread_setspecific(key, arg) == 0);
+ assert(pthread_setspecific(key, arg) == 0);
+ assert(pthread_setspecific(key, arg) == 0);
+
+ assert(pthread_getspecific(key) == arg);
+
+ (*j)++;
+
+ assert(*j == 1);
+}
+
+static void *
+mythread(void * arg)
+{
+ (void) pthread_barrier_wait(&startBarrier);
+
+ setkey(arg);
+
+ return 0;
+
+ /* Exiting the thread will call the key destructor. */
+}
+
+int
+main()
+{
+ int i;
+ int fail = 0;
+ pthread_t thread[NUM_THREADS];
+
+ assert(pthread_barrier_init(&startBarrier, NULL, NUM_THREADS/2) == 0);
+
+ for (i = 1; i < NUM_THREADS/2; i++)
+ {
+ accesscount[i] = thread_set[i] = thread_destroyed[i] = 0;
+ assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0);
+ }
+
+ /*
+ * Here we test that existing threads will get a key created
+ * for them.
+ */
+ assert(pthread_key_create(&key, destroy_key) == 0);
+
+ (void) pthread_barrier_wait(&startBarrier);
+
+ /*
+ * Test main thread key.
+ */
+ accesscount[0] = 0;
+ setkey((void *) &accesscount[0]);
+
+ /*
+ * Here we test that new threads will get a key created
+ * for them.
+ */
+ for (i = NUM_THREADS/2; i < NUM_THREADS; i++)
+ {
+ accesscount[i] = thread_set[i] = thread_destroyed[i] = 0;
+ assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0);
+ }
+
+ /*
+ * Wait for all threads to complete.
+ */
+ for (i = 1; i < NUM_THREADS; i++)
+ {
+ int result = 0;
+
+ assert(pthread_join(thread[i], (void **) &result) == 0);
+ }
+
+ assert(pthread_key_delete(key) == 0);
+
+ assert(pthread_barrier_destroy(&startBarrier) == 0);
+
+ for (i = 1; i < NUM_THREADS; i++)
+ {
+ /*
+ * The counter is incremented once when the key is set to
+ * a value, and again when the key is destroyed. If the key
+ * doesn't get set for some reason then it will still be
+ * NULL and the destroy function will not be called, and
+ * hence accesscount will not equal 2.
+ */
+ if (accesscount[i] != 2)
+ {
+ fail++;
+ fprintf(stderr, "Thread %d key, set = %d, destroyed = %d\n",
+ i, thread_set[i], thread_destroyed[i]);
+ }
+ }
+
+ fflush(stderr);
+
+ return (fail);
+}
diff --git a/pthreads/tests/tsd2.c b/pthreads/tests/tsd2.c
new file mode 100644
index 000000000..d1f50cde3
--- /dev/null
+++ b/pthreads/tests/tsd2.c
@@ -0,0 +1,215 @@
+/*
+ * tsd2.c
+ *
+ * Test Thread Specific Data (TSD) key creation and destruction.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Description:
+ * -
+ *
+ * Test Method (validation or falsification):
+ * - validation
+ *
+ * Requirements Tested:
+ * - keys are created for each existing thread including the main thread
+ * - keys are created for newly created threads
+ * - keys are thread specific
+ * - destroy routine is called on each thread exit including the main thread
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - none
+ *
+ * Output:
+ * - text to stdout
+ *
+ * Assumptions:
+ * - already validated: pthread_create()
+ * pthread_once()
+ * - main thread also has a POSIX thread identity
+ *
+ * Pass Criteria:
+ * - stdout matches file reference/tsd1.out
+ *
+ * Fail Criteria:
+ * - fails to match file reference/tsd1.out
+ * - output identifies failed component
+ */
+
+#include <sched.h>
+#include "test.h"
+
+enum {
+ NUM_THREADS = 100
+};
+
+static pthread_key_t key = NULL;
+static int accesscount[NUM_THREADS];
+static int thread_set[NUM_THREADS];
+static int thread_destroyed[NUM_THREADS];
+static pthread_barrier_t startBarrier;
+
+static void
+destroy_key(void * arg)
+{
+ int * j = (int *) arg;
+
+ (*j)++;
+
+ /* Set TSD key from the destructor to test destructor iteration */
+ if (*j == 2)
+ assert(pthread_setspecific(key, arg) == 0);
+ else
+ assert(*j == 3);
+
+ thread_destroyed[j - accesscount] = 1;
+}
+
+static void
+setkey(void * arg)
+{
+ int * j = (int *) arg;
+
+ thread_set[j - accesscount] = 1;
+
+ assert(*j == 0);
+
+ assert(pthread_getspecific(key) == NULL);
+
+ assert(pthread_setspecific(key, arg) == 0);
+ assert(pthread_setspecific(key, arg) == 0);
+ assert(pthread_setspecific(key, arg) == 0);
+
+ assert(pthread_getspecific(key) == arg);
+
+ (*j)++;
+
+ assert(*j == 1);
+}
+
+static void *
+mythread(void * arg)
+{
+ (void) pthread_barrier_wait(&startBarrier);
+
+ setkey(arg);
+
+ return 0;
+
+ /* Exiting the thread will call the key destructor. */
+}
+
+int
+main()
+{
+ int i;
+ int fail = 0;
+ pthread_t thread[NUM_THREADS];
+
+ assert(pthread_barrier_init(&startBarrier, NULL, NUM_THREADS/2) == 0);
+
+ for (i = 1; i < NUM_THREADS/2; i++)
+ {
+ accesscount[i] = thread_set[i] = thread_destroyed[i] = 0;
+ assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0);
+ }
+
+ /*
+ * Here we test that existing threads will get a key created
+ * for them.
+ */
+ assert(pthread_key_create(&key, destroy_key) == 0);
+
+ (void) pthread_barrier_wait(&startBarrier);
+
+ /*
+ * Test main thread key.
+ */
+ accesscount[0] = 0;
+ setkey((void *) &accesscount[0]);
+
+ /*
+ * Here we test that new threads will get a key created
+ * for them.
+ */
+ for (i = NUM_THREADS/2; i < NUM_THREADS; i++)
+ {
+ accesscount[i] = thread_set[i] = thread_destroyed[i] = 0;
+ assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0);
+ }
+
+ /*
+ * Wait for all threads to complete.
+ */
+ for (i = 1; i < NUM_THREADS; i++)
+ {
+ int result = 0;
+
+ assert(pthread_join(thread[i], (void **) &result) == 0);
+ }
+
+ assert(pthread_key_delete(key) == 0);
+
+ assert(pthread_barrier_destroy(&startBarrier) == 0);
+
+ for (i = 1; i < NUM_THREADS; i++)
+ {
+ /*
+ * The counter is incremented once when the key is set to
+ * a value, and again when the key is destroyed. If the key
+ * doesn't get set for some reason then it will still be
+ * NULL and the destroy function will not be called, and
+ * hence accesscount will not equal 2.
+ */
+ if (accesscount[i] != 3)
+ {
+ fail++;
+ fprintf(stderr, "Thread %d key, set = %d, destroyed = %d\n",
+ i, thread_set[i], thread_destroyed[i]);
+ }
+ }
+
+ fflush(stderr);
+
+ return (fail);
+}
diff --git a/pthreads/tests/valid1.c b/pthreads/tests/valid1.c
new file mode 100644
index 000000000..4d5cab592
--- /dev/null
+++ b/pthreads/tests/valid1.c
@@ -0,0 +1,103 @@
+/*
+ * File: valid1.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 that thread validation works.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+enum {
+ NUMTHREADS = 1
+};
+
+static int washere = 0;
+
+void * func(void * arg)
+{
+ washere = 1;
+ return (void *) 0;
+}
+
+int
+main()
+{
+ pthread_t t;
+ void * result = NULL;
+
+ washere = 0;
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+ assert(pthread_join(t, &result) == 0);
+ assert(result == 0);
+ assert(washere == 1);
+ sched_yield();
+ assert(pthread_kill(t, 0) == ESRCH);
+
+ return 0;
+}
diff --git a/pthreads/tests/valid2.c b/pthreads/tests/valid2.c
new file mode 100644
index 000000000..b9671798b
--- /dev/null
+++ b/pthreads/tests/valid2.c
@@ -0,0 +1,84 @@
+/*
+ * File: valid2.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:
+ * - Confirm that thread validation fails for garbage thread ID.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * -
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - No output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - Process returns zero exit status.
+ *
+ * Fail Criteria:
+ * - Process returns non-zero exit status.
+ */
+
+#include "test.h"
+
+int
+main()
+{
+ pthread_t NullThread = PTW32_THREAD_NULL_ID;
+
+ assert(pthread_kill(NullThread, 0) == ESRCH);
+
+ return 0;
+}
diff --git a/pthreads/tsd.c b/pthreads/tsd.c
new file mode 100644
index 000000000..ed44fe6cb
--- /dev/null
+++ b/pthreads/tsd.c
@@ -0,0 +1,44 @@
+/*
+ * tsd.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"
+
+
+#include "pthread_key_create.c"
+#include "pthread_key_delete.c"
+#include "pthread_setspecific.c"
+#include "pthread_getspecific.c"
diff --git a/pthreads/version.rc b/pthreads/version.rc
new file mode 100644
index 000000000..a6c22a2ac
--- /dev/null
+++ b/pthreads/version.rc
@@ -0,0 +1,384 @@
+/* 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
+ */
+
+#include <winver.h>
+#include "pthread.h"
+
+/*
+ * Note: the correct __CLEANUP_* macro must be defined corresponding to
+ * the definition used for the object file builds. This is done in the
+ * relevent makefiles for the command line builds, but users should ensure
+ * that their resource compiler knows what it is too.
+ * If using the default (no __CLEANUP_* defined), pthread.h will define it
+ * as __CLEANUP_C.
+ */
+
+#ifdef PTW32_RC_MSC
+# if defined(__CLEANUP_C)
+# define PTW32_VERSIONINFO_NAME "pthreadVC\0"
+# define PTW32_VERSIONINFO_COMMENT "MS C build -- longjmp thread exiting\0"
+# elif defined(__CLEANUP_CXX)
+# define PTW32_VERSIONINFO_NAME "pthreadVCE\0"
+# define PTW32_VERSIONINFO_COMMENT "MS C++ build -- C++ exception thread exiting\0"
+# elif defined(__CLEANUP_SEH)
+# define PTW32_VERSIONINFO_NAME "pthreadVSE\0"
+# define PTW32_VERSIONINFO_COMMENT "MS C build -- structured exception thread exiting\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"
+# elif defined(__CLEANUP_CXX)
+# define PTW32_VERSIONINFO_NAME "pthreadGCE\0"
+# define PTW32_VERSIONINFO_COMMENT "GNU C++ build -- C++ exception thread exiting\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"
+# elif defined(__CLEANUP_CXX)
+# define PTW32_VERSIONINFO_NAME "pthreadBCE\0"
+# define PTW32_VERSIONINFO_COMMENT "BORLAND C++ build -- C++ exception thread exiting\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"
+# elif defined(__CLEANUP_CXX)
+# define PTW32_VERSIONINFO_NAME "pthreadWCE\0"
+# define PTW32_VERSIONINFO_COMMENT "WATCOM C++ build -- C++ exception thread exiting\0"
+# else
+# error Resource compiler doesn't know which cleanup style you're using - see version.rc
+# endif
+#else
+# error Resource compiler doesn't know which compiler you're using - see version.rc
+#endif
+
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION PTW32_VERSION
+ PRODUCTVERSION PTW32_VERSION
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "POSIX Threads for Windows32 Library\0"
+ VALUE "ProductVersion", PTW32_VERSION_STRING
+ VALUE "FileVersion", PTW32_VERSION_STRING
+ 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
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+/*
+VERSIONINFO Resource
+
+The VERSIONINFO resource-definition statement creates a version-information
+resource. The resource contains such information about the file as its
+version number, its intended operating system, and its original filename.
+The resource is intended to be used with the Version Information functions.
+
+versionID VERSIONINFO fixed-info { block-statement...}
+
+versionID
+ Version-information resource identifier. This value must be 1.
+
+fixed-info
+ Version information, such as the file version and the intended operating
+ system. This parameter consists of the following statements.
+
+
+ Statement Description
+ --------------------------------------------------------------------------
+ FILEVERSION
+ version Binary version number for the file. The version
+ consists of two 32-bit integers, defined by four
+ 16-bit integers. For example, "FILEVERSION 3,10,0,61"
+ is translated into two doublewords: 0x0003000a and
+ 0x0000003d, in that order. Therefore, if version is
+ defined by the DWORD values dw1 and dw2, they need
+ to appear in the FILEVERSION statement as follows:
+ HIWORD(dw1), LOWORD(dw1), HIWORD(dw2), LOWORD(dw2).
+ PRODUCTVERSION
+ version Binary version number for the product with which the
+ file is distributed. The version parameter is two
+ 32-bit integers, defined by four 16-bit integers.
+ For more information about version, see the
+ FILEVERSION description.
+ FILEFLAGSMASK
+ fileflagsmask Bits in the FILEFLAGS statement are valid. If a bit
+ is set, the corresponding bit in FILEFLAGS is valid.
+ FILEFLAGSfileflags Attributes of the file. The fileflags parameter must
+ be the combination of all the file flags that are
+ valid at compile time. For 16-bit Windows, this
+ value is 0x3f.
+ FILEOSfileos Operating system for which this file was designed.
+ The fileos parameter can be one of the operating
+ system values given in the Remarks section.
+ FILETYPEfiletype General type of file. The filetype parameter can be
+ one of the file type values listed in the Remarks
+ section.
+ FILESUBTYPE
+ subtype Function of the file. The subtype parameter is zero
+ unless the type parameter in the FILETYPE statement
+ is VFT_DRV, VFT_FONT, or VFT_VXD. For a list of file
+ subtype values, see the Remarks section.
+
+block-statement
+ Specifies one or more version-information blocks. A block can contain
+ string information or variable information. For more information, see
+ StringFileInfo Block or VarFileInfo Block.
+
+Remarks
+
+To use the constants specified with the VERSIONINFO statement, you must
+include the Winver.h or Windows.h header file in the resource-definition file.
+
+The following list describes the parameters used in the VERSIONINFO statement:
+
+fileflags
+ A combination of the following values.
+
+ Value Description
+
+ VS_FF_DEBUG File contains debugging information or is compiled
+ with debugging features enabled.
+ VS_FF_PATCHED File has been modified and is not identical to the
+ original shipping file of the same version number.
+ VS_FF_PRERELEASE File is a development version, not a commercially
+ released product.
+ VS_FF_PRIVATEBUILD File was not built using standard release procedures.
+ If this value is given, the StringFileInfo block must
+ contain a PrivateBuild string.
+ VS_FF_SPECIALBUILD File was built by the original company using standard
+ release procedures but is a variation of the standard
+ file of the same version number. If this value is
+ given, the StringFileInfo block must contain a
+ SpecialBuild string.
+
+fileos
+ One of the following values.
+
+ Value Description
+
+ VOS_UNKNOWN The operating system for which the file was designed
+ is unknown.
+ VOS_DOS File was designed for MS-DOS.
+ VOS_NT File was designed for Windows Server 2003 family,
+ Windows XP, Windows 2000, or Windows NT.
+ VOS__WINDOWS16 File was designed for 16-bit Windows.
+ VOS__WINDOWS32 File was designed for 32-bit Windows.
+ VOS_DOS_WINDOWS16 File was designed for 16-bit Windows running with
+ MS-DOS.
+ VOS_DOS_WINDOWS32 File was designed for 32-bit Windows running with
+ MS-DOS.
+ VOS_NT_WINDOWS32 File was designed for Windows Server 2003 family,
+ Windows XP, Windows 2000, or Windows NT.
+
+ The values 0x00002L, 0x00003L, 0x20000L and 0x30000L are reserved.
+
+filetype
+ One of the following values.
+
+ Value Description
+
+ VFT_UNKNOWN File type is unknown.
+ VFT_APP File contains an application.
+ VFT_DLL File contains a dynamic-link library (DLL).
+ VFT_DRV File contains a device driver. If filetype is
+ VFT_DRV, subtype contains a more specific
+ description of the driver.
+ VFT_FONT File contains a font. If filetype is VFT_FONT,
+ subtype contains a more specific description of the
+ font.
+ VFT_VXD File contains a virtual device.
+ VFT_STATIC_LIB File contains a static-link library.
+
+ All other values are reserved for use by Microsoft.
+
+subtype
+ Additional information about the file type.
+
+ If filetype specifies VFT_DRV, this parameter can be one of the
+ following values.
+
+ Value Description
+
+ VFT2_UNKNOWN Driver type is unknown.
+ VFT2_DRV_COMM File contains a communications driver.
+ VFT2_DRV_PRINTER File contains a printer driver.
+ VFT2_DRV_KEYBOARD File contains a keyboard driver.
+ VFT2_DRV_LANGUAGE File contains a language driver.
+ VFT2_DRV_DISPLAY File contains a display driver.
+ VFT2_DRV_MOUSE File contains a mouse driver.
+ VFT2_DRV_NETWORK File contains a network driver.
+ VFT2_DRV_SYSTEM File contains a system driver.
+ VFT2_DRV_INSTALLABLE File contains an installable driver.
+ VFT2_DRV_SOUND File contains a sound driver.
+ VFT2_DRV_VERSIONED_PRINTER File contains a versioned printer driver.
+
+ If filetype specifies VFT_FONT, this parameter can be one of the
+ following values.
+
+ Value Description
+
+ VFT2_UNKNOWN Font type is unknown.
+ VFT2_FONT_RASTER File contains a raster font.
+ VFT2_FONT_VECTOR File contains a vector font.
+ VFT2_FONT_TRUETYPE File contains a TrueType font.
+
+ If filetype specifies VFT_VXD, this parameter must be the virtual-device
+ identifier included in the virtual-device control block.
+
+ All subtype values not listed here are reserved for use by Microsoft.
+
+langID
+ One of the following language codes.
+
+ Code Language Code Language
+
+ 0x0401 Arabic 0x0415 Polish
+ 0x0402 Bulgarian 0x0416 Portuguese (Brazil)
+ 0x0403 Catalan 0x0417 Rhaeto-Romanic
+ 0x0404 Traditional Chinese 0x0418 Romanian
+ 0x0405 Czech 0x0419 Russian
+ 0x0406 Danish 0x041A Croato-Serbian (Latin)
+ 0x0407 German 0x041B Slovak
+ 0x0408 Greek 0x041C Albanian
+ 0x0409 U.S. English 0x041D Swedish
+ 0x040A Castilian Spanish 0x041E Thai
+ 0x040B Finnish 0x041F Turkish
+ 0x040C French 0x0420 Urdu
+ 0x040D Hebrew 0x0421 Bahasa
+ 0x040E Hungarian 0x0804 Simplified Chinese
+ 0x040F Icelandic 0x0807 Swiss German
+ 0x0410 Italian 0x0809 U.K. English
+ 0x0411 Japanese 0x080A Mexican Spanish
+ 0x0412 Korean 0x080C Belgian French
+ 0x0413 Dutch 0x0C0C Canadian French
+ 0x0414 Norwegian ā€“ Bokmal 0x100C Swiss French
+ 0x0810 Swiss Italian 0x0816 Portuguese (Portugal)
+ 0x0813 Belgian Dutch 0x081A Serbo-Croatian (Cyrillic)
+ 0x0814 Norwegian ā€“ Nynorsk
+
+charsetID
+ One of the following character-set identifiers.
+
+ Identifier Character Set
+
+ 0 7-bit ASCII
+ 932 Japan (Shift %Gā€“%@ JIS X-0208)
+ 949 Korea (Shift %Gā€“%@ KSC 5601)
+ 950 Taiwan (Big5)
+ 1200 Unicode
+ 1250 Latin-2 (Eastern European)
+ 1251 Cyrillic
+ 1252 Multilingual
+ 1253 Greek
+ 1254 Turkish
+ 1255 Hebrew
+ 1256 Arabic
+
+string-name
+ One of the following predefined names.
+
+ Name Description
+
+ Comments Additional information that should be displayed for
+ diagnostic purposes.
+ CompanyName Company that produced the file%Gā€”%@for example,
+ "Microsoft Corporation" or "Standard Microsystems
+ Corporation, Inc." This string is required.
+ FileDescription File description to be presented to users. This
+ string may be displayed in a list box when the user
+ is choosing files to install%Gā€”%@for example,
+ "Keyboard Driver for AT-Style Keyboards". This
+ string is required.
+ FileVersion Version number of the file%Gā€”%@for example,
+ "3.10" or "5.00.RC2". This string is required.
+ InternalName Internal name of the file, if one exists ā€” for
+ example, a module name if the file is a dynamic-link
+ library. If the file has no internal name, this
+ string should be the original filename, without
+ extension. This string is required.
+ LegalCopyright Copyright notices that apply to the file. This
+ should include the full text of all notices, legal
+ symbols, copyright dates, and so on ā€” for example,
+ "Copyright (C) Microsoft Corporation 1990ā€“1999".
+ This string is optional.
+ LegalTrademarks Trademarks and registered trademarks that apply to
+ the file. This should include the full text of all
+ notices, legal symbols, trademark numbers, and so on.
+ This string is optional.
+ OriginalFilename Original name of the file, not including a path.
+ This information enables an application to determine
+ whether a file has been renamed by a user. The
+ format of the name depends on the file system for
+ which the file was created. This string is required.
+ PrivateBuild Information about a private version of the file ā€” for
+ example, "Built by TESTER1 on \TESTBED". This string
+ should be present only if VS_FF_PRIVATEBUILD is
+ specified in the fileflags parameter of the root
+ block.
+ ProductName Name of the product with which the file is
+ distributed. This string is required.
+ ProductVersion Version of the product with which the file is
+ distributed ā€” for example, "3.10" or "5.00.RC2".
+ This string is required.
+ SpecialBuild Text that indicates how this version of the file
+ differs from the standard version ā€” for example,
+ "Private build for TESTER1 solving mouse problems
+ on M250 and M250E computers". This string should be
+ present only if VS_FF_SPECIALBUILD is specified in
+ the fileflags parameter of the root block.
+ */
diff --git a/pthreads/w32_CancelableWait.c b/pthreads/w32_CancelableWait.c
new file mode 100644
index 000000000..97e15aa31
--- /dev/null
+++ b/pthreads/w32_CancelableWait.c
@@ -0,0 +1,160 @@
+/*
+ * w32_CancelableWait.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 INLINE int
+ptw32_cancelable_wait (HANDLE waitHandle, DWORD timeout)
+ /*
+ * -------------------------------------------------------------------
+ * This provides an extra hook into the pthread_cancel
+ * mechanism that will allow you to wait on a Windows handle and make it a
+ * cancellation point. This function blocks until the given WIN32 handle is
+ * signaled or pthread_cancel has been called. It is implemented using
+ * WaitForMultipleObjects on 'waitHandle' and a manually reset WIN32
+ * event used to implement pthread_cancel.
+ *
+ * Given this hook it would be possible to implement more of the cancellation
+ * points.
+ * -------------------------------------------------------------------
+ */
+{
+ int result;
+ pthread_t self;
+ ptw32_thread_t * sp;
+ HANDLE handles[2];
+ DWORD nHandles = 1;
+ DWORD status;
+
+ handles[0] = waitHandle;
+
+ self = pthread_self();
+ sp = (ptw32_thread_t *) self.p;
+
+ if (sp != NULL)
+ {
+ /*
+ * Get cancelEvent handle
+ */
+ if (sp->cancelState == PTHREAD_CANCEL_ENABLE)
+ {
+
+ if ((handles[1] = sp->cancelEvent) != NULL)
+ {
+ nHandles++;
+ }
+ }
+ }
+ else
+ {
+ handles[1] = NULL;
+ }
+
+ status = WaitForMultipleObjects (nHandles, handles, PTW32_FALSE, timeout);
+
+ switch (status - WAIT_OBJECT_0)
+ {
+ case 0:
+ /*
+ * Got the handle.
+ * In the event that both handles are signalled, the smallest index
+ * value (us) is returned. As it has been arranged, this ensures that
+ * we don't drop a signal that we should act on (i.e. semaphore,
+ * mutex, or condition variable etc).
+ */
+ result = 0;
+ break;
+
+ case 1:
+ /*
+ * Got cancel request.
+ * In the event that both handles are signaled, the cancel will
+ * be ignored (see case 0 comment).
+ */
+ ResetEvent (handles[1]);
+
+ if (sp != NULL)
+ {
+ /*
+ * Should handle POSIX and implicit POSIX threads..
+ * Make sure we haven't been async-canceled in the meantime.
+ */
+ (void) pthread_mutex_lock (&sp->cancelLock);
+ if (sp->state < PThreadStateCanceling)
+ {
+ sp->state = PThreadStateCanceling;
+ sp->cancelState = PTHREAD_CANCEL_DISABLE;
+ (void) pthread_mutex_unlock (&sp->cancelLock);
+ ptw32_throw (PTW32_EPS_CANCEL);
+
+ /* Never reached */
+ }
+ (void) pthread_mutex_unlock (&sp->cancelLock);
+ }
+
+ /* Should never get to here. */
+ result = EINVAL;
+ break;
+
+ default:
+ if (status == WAIT_TIMEOUT)
+ {
+ result = ETIMEDOUT;
+ }
+ else
+ {
+ result = EINVAL;
+ }
+ break;
+ }
+
+ return (result);
+
+} /* CancelableWait */
+
+int
+pthreadCancelableWait (HANDLE waitHandle)
+{
+ return (ptw32_cancelable_wait (waitHandle, INFINITE));
+}
+
+int
+pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout)
+{
+ return (ptw32_cancelable_wait (waitHandle, timeout));
+}