From a416ab17ecf9f2cb0f1e3f7bd645a8d1ce690ca2 Mon Sep 17 00:00:00 2001 From: rpj Date: Mon, 18 Feb 2002 03:16:52 +0000 Subject: Major reorganisation of source code; new routine and tests added. --- ChangeLog | 213 +++++-- GNUmakefile | 353 ++++++++---- Makefile | 644 ++++++++++++--------- Nmakefile.tests | 396 ++++++------- attr.c | 21 +- attr_destroy.c | 80 --- attr_getdetachstate.c | 89 --- attr_getscope.c | 55 -- attr_getstackaddr.c | 99 ---- attr_getstacksize.c | 102 ---- attr_init.c | 118 ---- attr_is_attr.c | 49 -- attr_setdetachstate.c | 93 ---- attr_setscope.c | 62 --- attr_setstackaddr.c | 99 ---- attr_setstacksize.c | 112 ---- barrier.c | 14 +- barrier_attr_destroy.c | 84 --- barrier_attr_getpshared.c | 97 ---- barrier_attr_init.c | 86 --- barrier_attr_setpshared.c | 120 ---- barrier_destroy.c | 70 --- barrier_init.c | 84 --- barrier_wait.c | 114 ---- cancel.c | 8 +- cancel_cancel.c | 180 ------ cancel_setcancelstate.c | 125 ----- cancel_setcanceltype.c | 125 ----- cancel_testcancel.c | 91 --- condvar.c | 20 +- condvar_attr_destroy.c | 86 --- condvar_attr_getpshared.c | 97 ---- condvar_attr_init.c | 87 --- condvar_attr_setpshared.c | 117 ---- condvar_check_need_init.c | 94 ---- condvar_destroy.c | 222 -------- condvar_init.c | 143 ----- condvar_signal.c | 355 ------------ condvar_wait.c | 527 ------------------ global.c | 9 + implement.h | 259 +++++---- misc.c | 2 +- mutex.c | 1080 +----------------------------------- nonportable.c | 14 +- np_delay.c | 155 ------ np_getw32threadhandle.c | 53 -- np_mutexattr_setkind.c | 57 -- np_num_processors.c | 56 -- np_win32_attach.c | 162 ------ private.c | 980 +------------------------------- pthread.c | 7 +- pthread.def | 325 +++++------ pthread.h | 61 +- pthread_attr_destroy.c | 80 +++ pthread_attr_getdetachstate.c | 89 +++ pthread_attr_getinheritsched.c | 52 ++ pthread_attr_getschedparam.c | 52 ++ pthread_attr_getschedpolicy.c | 62 +++ pthread_attr_getscope.c | 55 ++ pthread_attr_getstackaddr.c | 99 ++++ pthread_attr_getstacksize.c | 102 ++++ pthread_attr_init.c | 118 ++++ pthread_attr_setdetachstate.c | 93 ++++ pthread_attr_setinheritsched.c | 58 ++ pthread_attr_setschedparam.c | 63 +++ pthread_attr_setschedpolicy.c | 56 ++ pthread_attr_setscope.c | 62 +++ pthread_attr_setstackaddr.c | 99 ++++ pthread_attr_setstacksize.c | 112 ++++ pthread_barrier_destroy.c | 70 +++ pthread_barrier_init.c | 84 +++ pthread_barrier_wait.c | 114 ++++ pthread_barrierattr_destroy.c | 84 +++ pthread_barrierattr_getpshared.c | 97 ++++ pthread_barrierattr_init.c | 86 +++ pthread_barrierattr_setpshared.c | 120 ++++ pthread_cancel.c | 180 ++++++ pthread_cond_destroy.c | 246 ++++++++ pthread_cond_init.c | 164 ++++++ pthread_cond_signal.c | 355 ++++++++++++ pthread_cond_wait.c | 527 ++++++++++++++++++ pthread_condattr_destroy.c | 86 +++ pthread_condattr_getpshared.c | 97 ++++ pthread_condattr_init.c | 87 +++ pthread_condattr_setpshared.c | 117 ++++ pthread_delay_np.c | 155 ++++++ pthread_detach.c | 88 +++ pthread_getschedparam.c | 74 +++ pthread_getspecific.c | 75 +++ pthread_getw32threadhandle_np.c | 53 ++ pthread_join.c | 152 +++++ pthread_key_create.c | 108 ++++ pthread_key_delete.c | 127 +++++ pthread_mutex_destroy.c | 134 +++++ pthread_mutex_init.c | 107 ++++ pthread_mutex_lock.c | 105 ++++ pthread_mutex_timedlock.c | 356 ++++++++++++ pthread_mutex_trylock.c | 99 ++++ pthread_mutex_unlock.c | 93 ++++ pthread_mutexattr_destroy.c | 83 +++ pthread_mutexattr_getkind_np.c | 44 ++ pthread_mutexattr_getpshared.c | 97 ++++ pthread_mutexattr_gettype.c | 57 ++ pthread_mutexattr_init.c | 86 +++ pthread_mutexattr_setkind_np.c | 45 ++ pthread_mutexattr_setpshared.c | 120 ++++ pthread_mutexattr_settype.c | 144 +++++ pthread_num_processors_np.c | 56 ++ pthread_rwlock_destroy.c | 140 +++++ pthread_rwlock_init.c | 109 ++++ pthread_rwlock_rdlock.c | 101 ++++ pthread_rwlock_tryrdlock.c | 101 ++++ pthread_rwlock_trywrlock.c | 120 ++++ pthread_rwlock_unlock.c | 93 ++++ pthread_rwlock_wrlock.c | 146 +++++ pthread_rwlockattr_destroy.c | 85 +++ pthread_rwlockattr_getpshared.c | 99 ++++ pthread_rwlockattr_init.c | 84 +++ pthread_rwlockattr_setpshared.c | 122 ++++ pthread_setcancelstate.c | 125 +++++ pthread_setcanceltype.c | 125 +++++ pthread_setschedparam.c | 78 +++ pthread_setspecific.c | 151 +++++ pthread_spin_destroy.c | 102 ++++ pthread_spin_init.c | 123 ++++ pthread_spin_lock.c | 77 +++ pthread_spin_trylock.c | 69 +++ pthread_spin_unlock.c | 64 +++ pthread_testcancel.c | 91 +++ pthread_timechange_handler_np.c | 108 ++++ pthread_win32_attach_detach_np.c | 162 ++++++ ptw32_InterlockedCompareExchange.c | 108 ++++ ptw32_callUserDestroyRoutines.c | 155 ++++++ ptw32_cond_check_need_init.c | 94 ++++ ptw32_decrease_semaphore.c | 74 +++ ptw32_getprocessors.c | 84 +++ ptw32_increase_semaphore.c | 73 +++ ptw32_is_attr.c | 49 ++ ptw32_mutex_check_need_init.c | 94 ++++ ptw32_processInitialize.c | 100 ++++ ptw32_processTerminate.c | 100 ++++ ptw32_rwlock_check_need_init.c | 93 ++++ ptw32_spinlock_check_need_init.c | 81 +++ ptw32_threadDestroy.c | 66 +++ ptw32_threadStart.c | 373 +++++++++++++ ptw32_throw.c | 130 +++++ ptw32_timespec.c | 81 +++ ptw32_tkAssocCreate.c | 142 +++++ ptw32_tkAssocDestroy.c | 68 +++ rwlock.c | 826 +-------------------------- sched.c | 361 +----------- sched_get_priority_max.c | 69 +++ sched_get_priority_min.c | 69 +++ sched_getscheduler.c | 66 +++ sched_setscheduler.c | 78 +++ sched_yield.c | 71 +++ sem_close.c | 58 ++ sem_destroy.c | 121 ++++ sem_getvalue.c | 124 +++++ sem_init.c | 163 ++++++ sem_open.c | 58 ++ sem_post.c | 104 ++++ sem_post_multiple.c | 107 ++++ sem_timedwait.c | 198 +++++++ sem_trywait.c | 110 ++++ sem_unlink.c | 58 ++ sem_wait.c | 115 ++++ semaphore.c | 26 +- semaphore_close.c | 58 -- semaphore_decrease.c | 74 --- semaphore_destroy.c | 121 ---- semaphore_getvalue.c | 124 ----- semaphore_increase.c | 73 --- semaphore_init.c | 163 ------ semaphore_open.c | 58 -- semaphore_post.c | 104 ---- semaphore_postmultiple.c | 107 ---- semaphore_timedwait.c | 197 ------- semaphore_trywait.c | 110 ---- semaphore_unlink.c | 58 -- semaphore_wait.c | 115 ---- spin.c | 281 +--------- sync.c | 160 +----- tests/ChangeLog | 5 + tests/GNUmakefile | 7 +- tests/Makefile | 4 +- tests/condvar1_1.c | 117 ++++ tests/condvar1_2.c | 122 ++++ tests/condvar3_1.c | 2 + tests/exit4.c | 13 +- tsd.c | 308 +--------- 191 files changed, 13969 insertions(+), 10609 deletions(-) delete mode 100644 attr_destroy.c delete mode 100644 attr_getdetachstate.c delete mode 100644 attr_getscope.c delete mode 100644 attr_getstackaddr.c delete mode 100644 attr_getstacksize.c delete mode 100644 attr_init.c delete mode 100644 attr_is_attr.c delete mode 100644 attr_setdetachstate.c delete mode 100644 attr_setscope.c delete mode 100644 attr_setstackaddr.c delete mode 100644 attr_setstacksize.c delete mode 100644 barrier_attr_destroy.c delete mode 100644 barrier_attr_getpshared.c delete mode 100644 barrier_attr_init.c delete mode 100644 barrier_attr_setpshared.c delete mode 100644 barrier_destroy.c delete mode 100644 barrier_init.c delete mode 100644 barrier_wait.c delete mode 100644 cancel_cancel.c delete mode 100644 cancel_setcancelstate.c delete mode 100644 cancel_setcanceltype.c delete mode 100644 cancel_testcancel.c delete mode 100644 condvar_attr_destroy.c delete mode 100644 condvar_attr_getpshared.c delete mode 100644 condvar_attr_init.c delete mode 100644 condvar_attr_setpshared.c delete mode 100644 condvar_check_need_init.c delete mode 100644 condvar_destroy.c delete mode 100644 condvar_init.c delete mode 100644 condvar_signal.c delete mode 100644 condvar_wait.c delete mode 100644 np_delay.c delete mode 100644 np_getw32threadhandle.c delete mode 100644 np_mutexattr_setkind.c delete mode 100644 np_num_processors.c delete mode 100644 np_win32_attach.c create mode 100644 pthread_attr_destroy.c create mode 100644 pthread_attr_getdetachstate.c create mode 100644 pthread_attr_getinheritsched.c create mode 100644 pthread_attr_getschedparam.c create mode 100644 pthread_attr_getschedpolicy.c create mode 100644 pthread_attr_getscope.c create mode 100644 pthread_attr_getstackaddr.c create mode 100644 pthread_attr_getstacksize.c create mode 100644 pthread_attr_init.c create mode 100644 pthread_attr_setdetachstate.c create mode 100644 pthread_attr_setinheritsched.c create mode 100644 pthread_attr_setschedparam.c create mode 100644 pthread_attr_setschedpolicy.c create mode 100644 pthread_attr_setscope.c create mode 100644 pthread_attr_setstackaddr.c create mode 100644 pthread_attr_setstacksize.c create mode 100644 pthread_barrier_destroy.c create mode 100644 pthread_barrier_init.c create mode 100644 pthread_barrier_wait.c create mode 100644 pthread_barrierattr_destroy.c create mode 100644 pthread_barrierattr_getpshared.c create mode 100644 pthread_barrierattr_init.c create mode 100644 pthread_barrierattr_setpshared.c create mode 100644 pthread_cancel.c create mode 100644 pthread_cond_destroy.c create mode 100644 pthread_cond_init.c create mode 100644 pthread_cond_signal.c create mode 100644 pthread_cond_wait.c create mode 100644 pthread_condattr_destroy.c create mode 100644 pthread_condattr_getpshared.c create mode 100644 pthread_condattr_init.c create mode 100644 pthread_condattr_setpshared.c create mode 100644 pthread_delay_np.c create mode 100644 pthread_detach.c create mode 100644 pthread_getschedparam.c create mode 100644 pthread_getspecific.c create mode 100644 pthread_getw32threadhandle_np.c create mode 100644 pthread_join.c create mode 100644 pthread_key_create.c create mode 100644 pthread_key_delete.c create mode 100644 pthread_mutex_destroy.c create mode 100644 pthread_mutex_init.c create mode 100644 pthread_mutex_lock.c create mode 100644 pthread_mutex_timedlock.c create mode 100644 pthread_mutex_trylock.c create mode 100644 pthread_mutex_unlock.c create mode 100644 pthread_mutexattr_destroy.c create mode 100644 pthread_mutexattr_getkind_np.c create mode 100644 pthread_mutexattr_getpshared.c create mode 100644 pthread_mutexattr_gettype.c create mode 100644 pthread_mutexattr_init.c create mode 100644 pthread_mutexattr_setkind_np.c create mode 100644 pthread_mutexattr_setpshared.c create mode 100644 pthread_mutexattr_settype.c create mode 100644 pthread_num_processors_np.c create mode 100644 pthread_rwlock_destroy.c create mode 100644 pthread_rwlock_init.c create mode 100644 pthread_rwlock_rdlock.c create mode 100644 pthread_rwlock_tryrdlock.c create mode 100644 pthread_rwlock_trywrlock.c create mode 100644 pthread_rwlock_unlock.c create mode 100644 pthread_rwlock_wrlock.c create mode 100644 pthread_rwlockattr_destroy.c create mode 100644 pthread_rwlockattr_getpshared.c create mode 100644 pthread_rwlockattr_init.c create mode 100644 pthread_rwlockattr_setpshared.c create mode 100644 pthread_setcancelstate.c create mode 100644 pthread_setcanceltype.c create mode 100644 pthread_setschedparam.c create mode 100644 pthread_setspecific.c create mode 100644 pthread_spin_destroy.c create mode 100644 pthread_spin_init.c create mode 100644 pthread_spin_lock.c create mode 100644 pthread_spin_trylock.c create mode 100644 pthread_spin_unlock.c create mode 100644 pthread_testcancel.c create mode 100644 pthread_timechange_handler_np.c create mode 100644 pthread_win32_attach_detach_np.c create mode 100644 ptw32_InterlockedCompareExchange.c create mode 100644 ptw32_callUserDestroyRoutines.c create mode 100644 ptw32_cond_check_need_init.c create mode 100644 ptw32_decrease_semaphore.c create mode 100644 ptw32_getprocessors.c create mode 100644 ptw32_increase_semaphore.c create mode 100644 ptw32_is_attr.c create mode 100644 ptw32_mutex_check_need_init.c create mode 100644 ptw32_processInitialize.c create mode 100644 ptw32_processTerminate.c create mode 100644 ptw32_rwlock_check_need_init.c create mode 100644 ptw32_spinlock_check_need_init.c create mode 100644 ptw32_threadDestroy.c create mode 100644 ptw32_threadStart.c create mode 100644 ptw32_throw.c create mode 100644 ptw32_timespec.c create mode 100644 ptw32_tkAssocCreate.c create mode 100644 ptw32_tkAssocDestroy.c create mode 100644 sched_get_priority_max.c create mode 100644 sched_get_priority_min.c create mode 100644 sched_getscheduler.c create mode 100644 sched_setscheduler.c create mode 100644 sched_yield.c create mode 100644 sem_close.c create mode 100644 sem_destroy.c create mode 100644 sem_getvalue.c create mode 100644 sem_init.c create mode 100644 sem_open.c create mode 100644 sem_post.c create mode 100644 sem_post_multiple.c create mode 100644 sem_timedwait.c create mode 100644 sem_trywait.c create mode 100644 sem_unlink.c create mode 100644 sem_wait.c delete mode 100644 semaphore_close.c delete mode 100644 semaphore_decrease.c delete mode 100644 semaphore_destroy.c delete mode 100644 semaphore_getvalue.c delete mode 100644 semaphore_increase.c delete mode 100644 semaphore_init.c delete mode 100644 semaphore_open.c delete mode 100644 semaphore_post.c delete mode 100644 semaphore_postmultiple.c delete mode 100644 semaphore_timedwait.c delete mode 100644 semaphore_trywait.c delete mode 100644 semaphore_unlink.c delete mode 100644 semaphore_wait.c create mode 100644 tests/condvar1_1.c create mode 100644 tests/condvar1_2.c diff --git a/ChangeLog b/ChangeLog index 3b68aad..f01e060 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,124 @@ +2002-02-17 Ross Johnson @@ -78,17 +201,17 @@ This file is used to congregate the separate modules for potential inline optimisation and backward build compatibility. * cancel.c: Likewise. - * barrier_attr_destroy.c: Separated routine from cancel.c. - * barrier_attr_getpshared.c: Likewise. - * barrier_attr_init.c: Likewise. - * barrier_attr_setpshared.c: Likewise. - * barrier_destroy.c: Likewise. - * barrier_init.c: Likewise. - * barrier_wait.c: Likewise. - * cancel_cancel.c: Likewise. - * cancel_setcancelstate.c: Likewise. - * cancel_setcanceltype.c: Likewise. - * cancel_testcancel.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 @@ -123,19 +246,19 @@ * 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. - * semaphore_close.c: Separated routine from semaphore.c. - * semaphore_decrease.c: Likewise. - * semaphore_destroy.c: Likewise. - * semaphore_getvalue.c: Likewise. - * semaphore_increase.c: Likewise. - * semaphore_init.c: Likewise. - * semaphore_open.c: Likewise. - * semaphore_post.c: Likewise. - * semaphore_postmultiple.c: Likewise. - * semaphore_timedwait.c: Likewise. - * semaphore_trywait.c: Likewise. - * semaphore_unlink.c: Likewise. - * semaphore_wait.c: Likewise. + * 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 @@ -144,17 +267,17 @@ * 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. - * attr_destroy.c: Separated routine from attr.c. - * attr_getdetachstate.c: Likewise. - * attr_getscope.c: Likewise. - * attr_getstackaddr.c: Likewise. - * attr_getstacksize.c: Likewise. - * attr_init.c: Likewise. - * attr_is_attr.c: Likewise. - * attr_setdetachstate.c: Likewise. - * attr_setscope.c: Likewise. - * attr_setstackaddr.c: Likewise. - * attr_setstacksize.c: Likewise. + * 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. diff --git a/GNUmakefile b/GNUmakefile index ddaa96c..ad995ff 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -90,78 +90,133 @@ DLL_OBJS = \ # Separate modules for minimum size statically linked images SMALL_STATIC_OBJS = \ - attr_is_attr.o \ - attr_init.o \ - attr_destroy.o \ - attr_getdetachstate.o \ - attr_setdetachstate.o \ - attr_getstackaddr.o \ - attr_setstackaddr.o \ - attr_getstacksize.o \ - attr_setstacksize.o \ - attr_getscope.o \ - attr_setscope.o \ - barrier_init.o \ - barrier_destroy.o \ - barrier_wait.o \ - barrier_attr_init.o \ - barrier_attr_destroy.o \ - barrier_attr_setpshared.o \ - barrier_attr_getpshared.o \ - cancel_setcancelstate.o \ - cancel_setcanceltype.o \ - cancel_testcancel.o \ - cancel_cancel.o \ + 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 \ - condvar_attr_destroy.o \ - condvar_attr_getpshared.o \ - condvar_attr_init.o \ - condvar_attr_setpshared.o \ - condvar_check_need_init.o \ - condvar_destroy.o \ - condvar_init.o \ - condvar_signal.o \ - condvar_wait.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 \ exit.o \ fork.o \ global.o \ - mutex.o \ - np_mutexattr_setkind.o \ - np_mutexattr_getkind.o \ - np_getw32threadhandle.o \ - np_delay.o \ - np_num_processors.o \ - np_win32_attach.o \ - private.o \ + pthread_mutex_init.o \ + pthread_mutex_destroy.o \ + pthread_mutexattr_init.o \ + pthread_mutexattr_destroy.o \ + pthread_mutexattr_getpshared.o \ + pthread_mutexattr_setpshared.o \ + pthread_mutexattr_settype.o \ + pthread_mutexattr_gettype.o \ + pthread_mutex_lock.o \ + pthread_mutex_timedlock.o \ + pthread_mutex_unlock.o \ + pthread_mutex_trylock.o \ + pthread_mutexattr_setkind_np.o \ + pthread_mutexattr_getkind_np.o \ + pthread_getw32threadhandle_np.o \ + pthread_delay_np.o \ + pthread_num_processors_np.o \ + pthread_win32_attach_detach_np.o \ pthread_equal.o \ pthread_getconcurrency.o \ pthread_once.o \ pthread_self.o \ pthread_setconcurrency.o \ + pthread_rwlock_init.o \ + pthread_rwlock_destroy.o \ + pthread_rwlockattr_init.o \ + pthread_rwlockattr_destroy.o \ + pthread_rwlockattr_getpshared.o \ + pthread_rwlockattr_setpshared.o \ + pthread_rwlock_rdlock.o \ + pthread_rwlock_wrlock.o \ + pthread_rwlock_unlock.o \ + pthread_rwlock_tryrdlock.o \ + pthread_rwlock_trywrlock.o \ + pthread_setschedparam.o \ + pthread_getschedparam.o \ + pthread_timechange_handler_np.o \ + ptw32_is_attr.o \ + ptw32_cond_check_need_init.o \ + ptw32_mutex_check_need_init.o \ + ptw32_processInitialize.o \ + ptw32_processTerminate.o \ + ptw32_threadStart.o \ + ptw32_threadDestroy.o \ + ptw32_tkAssocCreate.o \ + ptw32_tkAssocDestroy.o \ + ptw32_callUserDestroyRoutines.o \ + ptw32_timespec.o \ + ptw32_throw.o \ + ptw32_InterlockedCompareExchange.o \ + ptw32_getprocessors.o \ ptw32_calloc.o \ ptw32_new.o \ - rwlock.o \ - sched.o \ - semaphore_init.o \ - semaphore_destroy.o \ - semaphore_trywait.o \ - semaphore_timedwait.o \ - semaphore_wait.o \ - semaphore_post.o \ - semaphore_postmultiple.o \ - semaphore_getvalue.o \ - semaphore_increase.o \ - semaphore_decrease.o \ - semaphore_open.o \ - semaphore_close.o \ - semaphore_unlink.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 \ + ptw32_increase_semaphore.o \ + ptw32_decrease_semaphore.o \ signal.o \ - spin.o \ - sync.o \ - tsd.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 INCL = \ @@ -172,43 +227,42 @@ INCL = \ need_errno.h ATTR_SRCS = \ - attr_is_attr.c \ - attr_init.c \ - attr_destroy.c \ - attr_getdetachstate.c \ - attr_setdetachstate.c \ - attr_getstackaddr.c \ - attr_setstackaddr.c \ - attr_getstacksize.c \ - attr_setstacksize.c \ - attr_getscope.c \ - attr_setscope.c + 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 = \ - barrier_init.c \ - barrier_destroy.c \ - barrier_wait.c \ - barrier_attr_init.c \ - barrier_attr_destroy.c \ - barrier_attr_setpshared.c \ - barrier_attr_getpshared.c + 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 = \ - cancel_setcancelstate.c \ - cancel_setcanceltype.c \ - cancel_testcancel.c \ - cancel_cancel.c + pthread_setcancelstate.c \ + pthread_setcanceltype.c \ + pthread_testcancel.c \ + pthread_cancel.c CONDVAR_SRCS = \ - condvar_attr_destroy.c \ - condvar_attr_getpshared.c \ - condvar_attr_init.c \ - condvar_attr_setpshared.c \ - condvar_check_need_init.c \ - condvar_destroy.c \ - condvar_init.c \ - condvar_signal.c \ - condvar_wait.c + 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 MISC_SRCS = \ pthread_equal.c \ @@ -220,28 +274,106 @@ MISC_SRCS = \ 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 = \ - np_mutexattr_setkind.c \ - np_mutexattr_getkind.c \ - np_getw32threadhandle.c \ - np_delay.c \ - np_num_processors.c \ - np_win32_attach.c + 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_throw.c \ + ptw32_InterlockedCompareExchange.c \ + ptw32_getprocessors.c + +RWLOCK_SRCS = \ + ptw32_rwlock_check_need_init.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_wrlock.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 = \ - semaphore_init.c \ - semaphore_destroy.c \ - semaphore_trywait.c \ - semaphore_timedwait.c \ - semaphore_wait.c \ - semaphore_post.c \ - semaphore_postmultiple.c \ - semaphore_getvalue.c \ - semaphore_increase.c \ - semaphore_decrease.c \ - semaphore_open.c \ - semaphore_close.c \ - semaphore_unlink.c + 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 \ + ptw32_increase_semaphore.c \ + ptw32_decrease_semaphore.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 + GC_DLL = pthreadGC.dll GCE_DLL = pthreadGCE.dll @@ -305,5 +437,12 @@ barrier.o: barrier.c $(BARRIER_SRCS) $(INCL) cancel.o: cancel.c $(CANCEL_SRCS) $(INCL) condvar.o: condvar.c $(CONDVAR_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) diff --git a/Makefile b/Makefile index 4bb23c7..1a19e97 100644 --- a/Makefile +++ b/Makefile @@ -1,253 +1,391 @@ -# 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. - -DEVROOT=c:\pthreads - -DLLDEST=$(DEVROOT)\DLL -LIBDEST=$(DEVROOT)\DLL - -DLLS = pthreadVCE.dll pthreadVSE.dll pthreadVC.dll - -OPTIM = /O2 - -# C++ Exceptions -VCEFLAGS = /GX /TP /D__CLEANUP_CXX -#Structured Exceptions -VSEFLAGS = /D__CLEANUP_SEH -#C cleanup code -VCFLAGS = /D__CLEANUP_C - -#CFLAGS = $(OPTIM) /W3 /MT /nologo /Yd /Zi /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H /DTEST_ICE -CFLAGS = $(OPTIM) /W3 /MT /nologo /Yd /Zi /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H - -# 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 - -# Separate modules for minimising the size of statically linked images -SMALL_STATIC_OBJS = \ - attr_is_attr.obj \ - attr_init.obj \ - attr_destroy.obj \ - attr_getdetachstate.obj \ - attr_setdetachstate.obj \ - attr_getstackaddr.obj \ - attr_setstackaddr.obj \ - attr_getstacksize.obj \ - attr_setstacksize.obj \ - attr_getscope.obj \ - attr_setscope.obj \ - barrier_init.obj \ - barrier_destroy.obj \ - barrier_wait.obj \ - barrier_attr_init.obj \ - barrier_attr_destroy.obj \ - barrier_attr_setpshared.obj \ - barrier_attr_getpshared.obj \ - cancel_setcancelstate.obj \ - cancel_setcanceltype.obj \ - cancel_testcancel.obj \ - cancel_cancel.obj \ - cleanup.obj \ - condvar_attr_destroy.obj \ - condvar_attr_getpshared.obj \ - condvar_attr_init.obj \ - condvar_attr_setpshared.obj \ - condvar_check_need_init.obj \ - condvar_destroy.obj \ - condvar_init.obj \ - condvar_signal.obj \ - condvar_wait.obj \ - create.obj \ - dll.obj \ - errno.obj \ - exit.obj \ - fork.obj \ - global.obj \ - mutex.obj \ - np_mutexattr_setkind.obj \ - np_mutexattr_getkind.obj \ - np_getw32threadhandle.obj \ - np_delay.obj \ - np_num_processors.obj \ - np_win32_attach.obj \ - private.obj \ - pthread_equal.obj \ - pthread_getconcurrency.obj \ - pthread_once.obj \ - pthread_self.obj \ - pthread_setconcurrency.obj \ - ptw32_calloc.obj \ - ptw32_new.obj \ - rwlock.obj \ - sched.obj \ - semaphore_init.obj \ - semaphore_destroy.obj \ - semaphore_trywait.obj \ - semaphore_timedwait.obj \ - semaphore_wait.obj \ - semaphore_post.obj \ - semaphore_postmultiple.obj \ - semaphore_getvalue.obj \ - semaphore_increase.obj \ - semaphore_decrease.obj \ - semaphore_open.obj \ - semaphore_close.obj \ - semaphore_unlink.obj \ - signal.obj \ - spin.obj \ - sync.obj \ - tsd.obj \ - w32_CancelableWait.obj - -INCL = config.h implement.h semaphore.h pthread.h need_errno.h - -ATTR_SRCS = \ - attr_is_attr.c \ - attr_init.c \ - attr_destroy.c \ - attr_getdetachstate.c \ - attr_setdetachstate.c \ - attr_getstackaddr.c \ - attr_setstackaddr.c \ - attr_getstacksize.c \ - attr_setstacksize.c \ - attr_getscope.c \ - attr_setscope.c - -BARRIER_SRCS = \ - barrier_init.c \ - barrier_destroy.c \ - barrier_wait.c \ - barrier_attr_init.c \ - barrier_attr_destroy.c \ - barrier_attr_setpshared.c \ - barrier_attr_getpshared.c - -CANCEL_SRCS = \ - cancel_setcancelstate.c \ - cancel_setcanceltype.c \ - cancel_testcancel.c \ - cancel_cancel.c - -CONDVAR_SRCS = \ - condvar_attr_destroy.c \ - condvar_attr_getpshared.c \ - condvar_attr_init.c \ - condvar_attr_setpshared.c \ - condvar_check_need_init.c \ - condvar_destroy.c \ - condvar_init.c \ - condvar_signal.c \ - condvar_wait.c - -MISC_SRCS = \ - pthread_equal.c \ - pthread_getconcurrency.c \ - pthread_once.c \ - pthread_self.c \ - pthread_setconcurrency.c \ - ptw32_calloc.c \ - ptw32_new.c \ - w32_CancelableWait.c - -NONPORTABLE_SRCS = \ - np_mutexattr_setkind.c \ - np_mutexattr_getkind.c \ - np_getw32threadhandle.c \ - np_delay.c \ - np_num_processors.c \ - np_win32_attach.c - -SEMAPHORE_SRCS = \ - semaphore_init.c \ - semaphore_destroy.c \ - semaphore_trywait.c \ - semaphore_timedwait.c \ - semaphore_wait.c \ - semaphore_post.c \ - semaphore_postmultiple.c \ - semaphore_getvalue.c \ - semaphore_increase.c \ - semaphore_decrease.c \ - semaphore_open.c \ - semaphore_close.c \ - semaphore_unlink.c - -all: - @ 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) - -auto: - @ nmake clean VCE - @ nmake clean VSE - @ nmake clean VC - -VCE: - @ nmake /nologo EHFLAGS="$(VCEFLAGS)" pthreadVCE.dll - -VSE: - @ nmake /nologo EHFLAGS="$(VSEFLAGS)" pthreadVSE.dll - -VC: - @ nmake /nologo EHFLAGS="$(VCFLAGS)" pthreadVC.dll - -realclean: clean - if exist *.dll del *.dll - if exist *.lib del *.lib - -clean: - if exist *.obj del *.obj - if exist *.ilk del *.ilk - if exist *.pdb del *.pdb - if exist *.exp del *.exp - if exist *.o del *.o - - -install: $(DLLS) - copy pthread*.dll $(DLLDEST) - copy pthread*.lib $(LIBDEST) - -$(DLLS): $(DLL_OBJS) pthread.def - cl /LD /Zi /nologo $(DLL_OBJS) \ - /link /nodefaultlib:libcmt /implib:$*.lib \ - msvcrt.lib wsock32.lib /def:pthread.def /out:$@ - -.c.obj: - cl $(EHFLAGS) $(CFLAGS) -c $< - -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) -misc.obj: misc.c $(MISC_SRCS) $(INCL) -nonportable.obj: nonportable.c $(NONPORTABLE_SRCS) $(INCL) -semaphore.obj: semaphore.c $(SEMAPHORE_SRCS) $(INCL) - +# This makefile is compatible with MS nmake and can be used as a +# replacement for buildlib.bat. I've changed the target from an ordinary dll +# (/LD) to a debugging dll (/LDd). +# +# The variables $DLLDEST and $LIBDEST hold the destination directories for the +# dll and the lib, respectively. Probably all that needs to change is $DEVROOT. + +DEVROOT=c:\pthreads + +DLLDEST=$(DEVROOT)\DLL +LIBDEST=$(DEVROOT)\DLL + +DLLS = pthreadVCE.dll pthreadVSE.dll pthreadVC.dll + +OPTIM = /O2 + +# C++ Exceptions +VCEFLAGS = /GX /TP /D__CLEANUP_CXX +#Structured Exceptions +VSEFLAGS = /D__CLEANUP_SEH +#C cleanup code +VCFLAGS = /D__CLEANUP_C + +#CFLAGS = $(OPTIM) /W3 /MT /nologo /Yd /Zi /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H /DTEST_ICE +CFLAGS = $(OPTIM) /W3 /MT /nologo /Yd /Zi /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H + +# 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 + +# 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 \ + 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_rwlock_check_need_init.obj \ + ptw32_cond_check_need_init.obj \ + ptw32_mutex_check_need_init.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 \ + ptw32_increase_semaphore.obj \ + ptw32_decrease_semaphore.obj \ + signal.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 + +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 + +MISC_SRCS = \ + pthread_equal.c \ + pthread_getconcurrency.c \ + pthread_once.c \ + pthread_self.c \ + pthread_setconcurrency.c \ + ptw32_calloc.c \ + ptw32_new.c \ + w32_CancelableWait.c + +MUTEX_SRCS = \ + ptw32_mutex_check_need_init.c \ + pthread_mutex_init.c \ + pthread_mutex_destroy.c \ + pthread_mutexattr_init.c \ + pthread_mutexattr_destroy.c \ + pthread_mutexattr_getpshared.c \ + pthread_mutexattr_setpshared.c \ + pthread_mutexattr_settype.c \ + pthread_mutexattr_gettype.c \ + pthread_mutex_lock.c \ + pthread_mutex_timedlock.c \ + pthread_mutex_unlock.c \ + pthread_mutex_trylock.c + +NONPORTABLE_SRCS = \ + pthread_mutexattr_setkind_np.c \ + pthread_mutexattr_getkind_np.c \ + pthread_getw32threadhandle_np.c \ + pthread_delay_np.c \ + pthread_num_processors_np.c \ + pthread_win32_attach_detach_np.c \ + pthread_timechange_handler_np.c + +PRIVATE_SRCS = \ + ptw32_is_attr.c \ + ptw32_processInitialize.c \ + ptw32_processTerminate.c \ + ptw32_threadStart.c \ + ptw32_threadDestroy.c \ + ptw32_tkAssocCreate.c \ + ptw32_tkAssocDestroy.c \ + ptw32_callUserDestroyRoutines.c \ + ptw32_timespec.c \ + ptw32_throw.c \ + ptw32_InterlockedCompareExchange.c \ + ptw32_getprocessors.c + +RWLOCK_SRCS = \ + ptw32_rwlock_check_need_init.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_wrlock.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 \ + ptw32_increase_semaphore.c \ + ptw32_decrease_semaphore.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: + @ 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) + +auto: + @ nmake clean VCE + @ nmake clean VSE + @ nmake clean VC + +VCE: + @ nmake /nologo EHFLAGS="$(VCEFLAGS)" pthreadVCE.dll + +VSE: + @ nmake /nologo EHFLAGS="$(VSEFLAGS)" pthreadVSE.dll + +VC: + @ nmake /nologo EHFLAGS="$(VCFLAGS)" pthreadVC.dll + +realclean: clean + if exist *.dll del *.dll + if exist *.lib del *.lib + +clean: + if exist *.obj del *.obj + if exist *.ilk del *.ilk + if exist *.pdb del *.pdb + if exist *.exp del *.exp + if exist *.o del *.o + + +install: $(DLLS) + copy pthread*.dll $(DLLDEST) + copy pthread*.lib $(LIBDEST) + +$(DLLS): $(DLL_OBJS) pthread.def + cl /LD /Zi /nologo $(DLL_OBJS) \ + /link /nodefaultlib:libcmt /implib:$*.lib \ + msvcrt.lib wsock32.lib /def:pthread.def /out:$@ + +.c.obj: + cl $(EHFLAGS) $(CFLAGS) -c $< + +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) +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) diff --git a/Nmakefile.tests b/Nmakefile.tests index b604551..6ca0b5c 100644 --- a/Nmakefile.tests +++ b/Nmakefile.tests @@ -1,196 +1,200 @@ -/* 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 -loadfree:: loadfree.c -mutex1:: mutex1.c -mutex1e:: mutex1e.c -mutex1n:: mutex1n.c -mutex1r:: mutex1r.c -mutex2:: mutex1.2 -exit1:: exit1.c -condvar1:: condvar1.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 -cancel1:: cancel1.c -cancel2:: cancel2.c -mutex3:: mutex3.c -mutex4:: mutex4.c -mutex5:: mutex5.c -mutex6:: mutex6.c -mutex6e:: mutex6e.c -mutex6n:: mutex6n.c -mutex6r:: mutex6r.c -mutex7:: mutex7.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 -join0:: join0.c -join1:: join1.c -join2:: join2.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 -rwlock1:: rwlock1.c -rwlock2:: rwlock2.c -rwlock3:: rwlock3.c -rwlock4:: rwlock4.c -rwlock5:: rwlock5.c -rwlock6:: rwlock6.c -rwlock7:: rwlock7.c -context1:: context1.c -cancel3:: cancel3.c -cancel4:: cancel4.c -cancel5:: cancel5.c -cancel6a:: cancel6a.c -cancel6d:: cancel6d.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 - -loadfree: :test: -mutex5 :test: loadfree -mutex1 :test: loadfree -mutex2 :test: loadfree -exit1 :test: loadfree -condvar1 :test: loadfree -self1 :test: loadfree -condvar2 :test: condvar1 -condvar2_1 :test: condvar2 -create1 :test: mutex2 -cancel1 :test: create1 -cancel2 :test: cancel1 -mutex3 :test: create1 -mutex4 :test: mutex3 -mutex6 :test: mutex4 -mutex6n :test: mutex4 -mutex6e :test: mutex4 -mutex6r :test: mutex4 -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 -join0 :test: create1 -join1 :test: create1 -join2 :test: create1 -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 -context1 :test: cancel2 -cancel3 :test: context1 -cancel4 :test: cancel3 -cancel5 :test: cancel3 -cancel6a :test: cancel3 -cancel6d :test: cancel3 -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 - +/* 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 +loadfree:: loadfree.c +mutex1:: mutex1.c +mutex1e:: mutex1e.c +mutex1n:: mutex1n.c +mutex1r:: mutex1r.c +mutex2:: mutex1.2 +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 +cancel1:: cancel1.c +cancel2:: cancel2.c +mutex3:: mutex3.c +mutex4:: mutex4.c +mutex5:: mutex5.c +mutex6:: mutex6.c +mutex6e:: mutex6e.c +mutex6n:: mutex6n.c +mutex6r:: mutex6r.c +mutex7:: mutex7.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 +join0:: join0.c +join1:: join1.c +join2:: join2.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 +rwlock1:: rwlock1.c +rwlock2:: rwlock2.c +rwlock3:: rwlock3.c +rwlock4:: rwlock4.c +rwlock5:: rwlock5.c +rwlock6:: rwlock6.c +rwlock7:: rwlock7.c +context1:: context1.c +cancel3:: cancel3.c +cancel4:: cancel4.c +cancel5:: cancel5.c +cancel6a:: cancel6a.c +cancel6d:: cancel6d.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 + +loadfree: :test: +mutex5 :test: loadfree +mutex1 :test: loadfree +mutex2 :test: loadfree +exit1 :test: loadfree +condvar1 :test: loadfree +condvar1_1 :test: condvar1 +condvar1_2 :test: join2 +self1 :test: loadfree +condvar2 :test: condvar1 +condvar2_1 :test: condvar2 +create1 :test: mutex2 +cancel1 :test: create1 +cancel2 :test: cancel1 +mutex3 :test: create1 +mutex4 :test: mutex3 +mutex6 :test: mutex4 +mutex6n :test: mutex4 +mutex6e :test: mutex4 +mutex6r :test: mutex4 +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 +join0 :test: create1 +join1 :test: create1 +join2 :test: create1 +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 +context1 :test: cancel2 +cancel3 :test: context1 +cancel4 :test: cancel3 +cancel5 :test: cancel3 +cancel6a :test: cancel3 +cancel6d :test: cancel3 +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 + diff --git a/attr.c b/attr.c index e74f4dc..dfae24d 100644 --- a/attr.c +++ b/attr.c @@ -41,15 +41,14 @@ #include "pthread.h" #include "implement.h" -#include "attr_is_attr.c" -#include "attr_init.c" -#include "attr_destroy.c" -#include "attr_getdetachstate.c" -#include "attr_setdetachstate.c" -#include "attr_getstackaddr.c" -#include "attr_setstackaddr.c" -#include "attr_getstacksize.c" -#include "attr_setstacksize.c" -#include "attr_getscope.c" -#include "attr_setscope.c" +#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/attr_destroy.c b/attr_destroy.c deleted file mode 100644 index e4c29d6..0000000 --- a/attr_destroy.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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 (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/attr_getdetachstate.c b/attr_getdetachstate.c deleted file mode 100644 index 1e29613..0000000 --- a/attr_getdetachstate.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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 (is_attr(attr) != 0 || detachstate == NULL) - { - *detachstate = PTHREAD_CREATE_DETACHED; - return EINVAL; - } - - *detachstate = (*attr)->detachstate; - return 0; -} - diff --git a/attr_getscope.c b/attr_getscope.c deleted file mode 100644 index 52216da..0000000 --- a/attr_getscope.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/attr_getstackaddr.c b/attr_getstackaddr.c deleted file mode 100644 index 79f4c30..0000000 --- a/attr_getstackaddr.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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 (is_attr(attr) != 0) - { - return EINVAL; - } - - *stackaddr = (*attr)->stackaddr; - return 0; - -#else - - return ENOSYS; - -#endif /* _POSIX_THREAD_ATTR_STACKADDR */ -} - diff --git a/attr_getstacksize.c b/attr_getstacksize.c deleted file mode 100644 index b9e9b97..0000000 --- a/attr_getstacksize.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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 (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/attr_init.c b/attr_init.c deleted file mode 100644 index 6ea9234..0000000 --- a/attr_init.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/attr_is_attr.c b/attr_is_attr.c deleted file mode 100644 index 3d6ef4f..0000000 --- a/attr_is_attr.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * attr_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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 -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/attr_setdetachstate.c b/attr_setdetachstate.c deleted file mode 100644 index 8fcfe39..0000000 --- a/attr_setdetachstate.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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 (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/attr_setscope.c b/attr_setscope.c deleted file mode 100644 index 7543201..0000000 --- a/attr_setscope.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/attr_setstackaddr.c b/attr_setstackaddr.c deleted file mode 100644 index f5fc8af..0000000 --- a/attr_setstackaddr.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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 (is_attr(attr) != 0) - { - return EINVAL; - } - - (*attr)->stackaddr = stackaddr; - return 0; - -#else - - return ENOSYS; - -#endif /* _POSIX_THREAD_ATTR_STACKADDR */ -} - diff --git a/attr_setstacksize.c b/attr_setstacksize.c deleted file mode 100644 index 549d6be..0000000 --- a/attr_setstacksize.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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 (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/barrier.c b/barrier.c index 762d742..e948306 100644 --- a/barrier.c +++ b/barrier.c @@ -38,11 +38,11 @@ #include "implement.h" -#include "barrier_init.c" -#include "barrier_destroy.c" -#include "barrier_wait.c" -#include "barrier_attr_init.c" -#include "barrier_attr_destroy.c" -#include "barrier_attr_getpshared.c" -#include "barrier_attr_setpshared.c" +#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/barrier_attr_destroy.c b/barrier_attr_destroy.c deleted file mode 100644 index 7395ca3..0000000 --- a/barrier_attr_destroy.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/barrier_attr_getpshared.c b/barrier_attr_getpshared.c deleted file mode 100644 index 4f7cc64..0000000 --- a/barrier_attr_getpshared.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/barrier_attr_init.c b/barrier_attr_init.c deleted file mode 100644 index ac204fa..0000000 --- a/barrier_attr_init.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/barrier_attr_setpshared.c b/barrier_attr_setpshared.c deleted file mode 100644 index 4ad5c52..0000000 --- a/barrier_attr_setpshared.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/barrier_destroy.c b/barrier_destroy.c deleted file mode 100644 index c8c2142..0000000 --- a/barrier_destroy.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/barrier_init.c b/barrier_init.c deleted file mode 100644 index 865a82a..0000000 --- a/barrier_init.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/barrier_wait.c b/barrier_wait.c deleted file mode 100644 index 07ea32f..0000000 --- a/barrier_wait.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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 - { - BOOL switchCancelState; - int oldCancelState; - pthread_t self = pthread_self(); - - /* - * This routine is not a cancelation point, so temporarily - * prevent sem_wait() from being one. - * PTHREAD_CANCEL_ASYNCHRONOUS threads can still be canceled. - */ - switchCancelState = (self->cancelType == PTHREAD_CANCEL_DEFERRED && - 0 == pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, - &oldCancelState)); - - result = sem_wait(&(b->semBarrierBreeched[step])); - - if (switchCancelState) - { - (void) pthread_setcancelstate(oldCancelState, NULL); - } - } - - /* - * 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/cancel.c b/cancel.c index 92a18d7..1e50446 100644 --- a/cancel.c +++ b/cancel.c @@ -38,8 +38,8 @@ #include "implement.h" -#include "cancel_setcancelstate.c" -#include "cancel_setcanceltype.c" -#include "cancel_testcancel.c" -#include "cancel_cancel.c" +#include "pthread_setcancelstate.c" +#include "pthread_setcanceltype.c" +#include "pthread_testcancel.c" +#include "pthread_cancel.c" diff --git a/cancel_cancel.c b/cancel_cancel.c deleted file mode 100644 index c0ab552..0000000 --- a/cancel_cancel.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * cancel_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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(_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(PTW32_PROGCTR) -#error Module contains CPU-specific code; modify and recompile. -#endif - -static INLINE void -ptw32_cancel_self(void) -{ - ptw32_throw(PTW32_EPS_CANCEL); - - /* Never reached */ -} - -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; - - if (thread == NULL ) - { - return ESRCH; - } - - result = 0; - if ((self = pthread_self()) == 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); - - /* - * Lock for async-cancel safety. - */ - (void) pthread_mutex_lock(&thread->cancelLock); - - if (thread->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS - && thread->cancelState == PTHREAD_CANCEL_ENABLE - && thread->state < PThreadStateCanceling ) - { - if (cancel_self) - { - thread->state = PThreadStateCanceling; - thread->cancelState = PTHREAD_CANCEL_DISABLE; - - (void) pthread_mutex_unlock(&thread->cancelLock); - ptw32_throw(PTW32_EPS_CANCEL); - - /* Never reached */ - } - else - { - HANDLE threadH = thread->threadH; - - SuspendThread(threadH); - - if (WaitForSingleObject(threadH, 0) == WAIT_TIMEOUT ) - { - CONTEXT context; - - thread->state = PThreadStateCanceling; - thread->cancelState = PTHREAD_CANCEL_DISABLE; - context.ContextFlags = CONTEXT_CONTROL; - GetThreadContext(threadH, &context); - PTW32_PROGCTR(context) = (DWORD) ptw32_cancel_self; - SetThreadContext(threadH, &context); - (void) pthread_mutex_unlock(&thread->cancelLock); - ResumeThread(threadH); - } - } - } - else - { - /* - * Set for deferred cancellation. - */ - if ( thread->state >= PThreadStateCanceling - || !SetEvent (thread->cancelEvent)) - { - result = ESRCH; - } - - (void) pthread_mutex_unlock(&thread->cancelLock); - } - - return (result); -} - diff --git a/cancel_setcancelstate.c b/cancel_setcancelstate.c deleted file mode 100644 index 8eaa720..0000000 --- a/cancel_setcancelstate.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * cancel_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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(); - - if (self == NULL - || (state != PTHREAD_CANCEL_ENABLE - && state != PTHREAD_CANCEL_DISABLE)) - { - return EINVAL; - } - - /* - * Lock for async-cancel safety. - */ - (void) pthread_mutex_lock(&self->cancelLock); - - if (oldstate != NULL) - { - *oldstate = self->cancelState; - } - - self->cancelState = state; - - /* - * Check if there is a pending asynchronous cancel - */ - if (state == PTHREAD_CANCEL_ENABLE - && self->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS - && WaitForSingleObject(self->cancelEvent, 0) == WAIT_OBJECT_0) - { - self->state = PThreadStateCanceling; - self->cancelState = PTHREAD_CANCEL_DISABLE; - ResetEvent(self->cancelEvent); - (void) pthread_mutex_unlock(&self->cancelLock); - ptw32_throw(PTW32_EPS_CANCEL); - - /* Never reached */ - } - - (void) pthread_mutex_unlock(&self->cancelLock); - - return (result); - -} /* pthread_setcancelstate */ - diff --git a/cancel_setcanceltype.c b/cancel_setcanceltype.c deleted file mode 100644 index 58b31da..0000000 --- a/cancel_setcanceltype.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * cancel_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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(); - - if (self == NULL - || (type != PTHREAD_CANCEL_DEFERRED - && type != PTHREAD_CANCEL_ASYNCHRONOUS)) - { - return EINVAL; - } - - /* - * Lock for async-cancel safety. - */ - (void) pthread_mutex_lock(&self->cancelLock); - - if (oldtype != NULL) - { - *oldtype = self->cancelType; - } - - self->cancelType = type; - - /* - * Check if there is a pending asynchronous cancel - */ - if (self->cancelState == PTHREAD_CANCEL_ENABLE - && type == PTHREAD_CANCEL_ASYNCHRONOUS - && WaitForSingleObject(self->cancelEvent, 0) == WAIT_OBJECT_0) - { - self->state = PThreadStateCanceling; - self->cancelState = PTHREAD_CANCEL_DISABLE; - ResetEvent(self->cancelEvent); - (void) pthread_mutex_unlock(&self->cancelLock); - ptw32_throw(PTW32_EPS_CANCEL); - - /* Never reached */ - } - - (void) pthread_mutex_unlock(&self->cancelLock); - - return (result); - -} /* pthread_setcanceltype */ - diff --git a/cancel_testcancel.c b/cancel_testcancel.c deleted file mode 100644 index 4086565..0000000 --- a/cancel_testcancel.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * cancel_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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(); - - (void) pthread_mutex_lock(&self->cancelLock); - - if (self != NULL - && self->cancelState != PTHREAD_CANCEL_DISABLE - && WaitForSingleObject (self->cancelEvent, 0) == WAIT_OBJECT_0 - ) - { - /* - * Canceling! - */ - self->state = PThreadStateCanceling; - self->cancelState = PTHREAD_CANCEL_DISABLE; - (void) pthread_mutex_unlock(&self->cancelLock); - ptw32_throw(PTW32_EPS_CANCEL); - } - - (void) pthread_mutex_unlock(&self->cancelLock); -} /* pthread_testcancel */ - diff --git a/condvar.c b/condvar.c index 59878b2..560ed01 100644 --- a/condvar.c +++ b/condvar.c @@ -39,14 +39,12 @@ #include "pthread.h" #include "implement.h" -#include "condvar_check_need_init.c" -#include "condvar_attr_init.c" -#include "condvar_attr_destroy.c" -#include "condvar_attr_getpshared.c" -#include "condvar_attr_setpshared.c" -#include "condvar_init.c" -#include "condvar_destroy.c" -#include "condvar_wait.c" -#include "condvar_timedwait.c" -#include "condvar_signal.c" -#include "condvar_broadcast.c" +#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/condvar_attr_destroy.c b/condvar_attr_destroy.c deleted file mode 100644 index 1be0daf..0000000 --- a/condvar_attr_destroy.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/condvar_attr_getpshared.c b/condvar_attr_getpshared.c deleted file mode 100644 index 6a9890e..0000000 --- a/condvar_attr_getpshared.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * condvar_attr_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/condvar_attr_init.c b/condvar_attr_init.c deleted file mode 100644 index b04c757..0000000 --- a/condvar_attr_init.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * condvar_attr_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/condvar_attr_setpshared.c b/condvar_attr_setpshared.c deleted file mode 100644 index 4e396c2..0000000 --- a/condvar_attr_setpshared.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * condvar_attr_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/condvar_check_need_init.c b/condvar_check_need_init.c deleted file mode 100644 index 1f6bba7..0000000 --- a/condvar_check_need_init.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * condvar_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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_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/condvar_destroy.c b/condvar_destroy.c deleted file mode 100644 index d0af374..0000000 --- a/condvar_destroy.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * condvar_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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) - { - 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 course 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)); - } - - (void) free(cv); - } - } - 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/condvar_init.c b/condvar_init.c deleted file mode 100644 index ecd4297..0000000 --- a/condvar_init.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * condvar_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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: - *cond = cv; - - return result; - -} /* pthread_cond_init */ diff --git a/condvar_signal.c b/condvar_signal.c deleted file mode 100644 index 604ef4d..0000000 --- a/condvar_signal.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * condvar_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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; - * } - * ------------------------------------------------------------- - * - */ - -#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 ) - { - if (sem_wait( &(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 '1'(TRUE) unblockAll arg means unblock ALL waiters. - */ - return (ptw32_cond_unblock(cond, 1)); - -} /* pthread_cond_broadcast */ diff --git a/condvar_wait.c b/condvar_wait.c deleted file mode 100644 index 550b6c0..0000000 --- a/condvar_wait.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * condvar_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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; - * } - * ------------------------------------------------------------- - * - */ - -#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; - int signaled; -} 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 nSignalsWasLeft; - int nWaitersWasGone = 0; /* Initialised to quell warnings. */ - 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) ) - { - if ( !cleanup_args->signaled ) - { - if ( 0 != cv->nWaitersBlocked ) - { - (cv->nWaitersBlocked)--; - } - else - { - (cv->nWaitersGone)++; - } - } - if ( 0 == --(cv->nWaitersToUnblock) ) - { - if ( 0 != cv->nWaitersBlocked ) - { - 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; - } - nSignalsWasLeft = 0; - } - else if ( 0 != (nWaitersWasGone = cv->nWaitersGone) ) - { - cv->nWaitersGone = 0; - } - } - } - else if ( INT_MAX/2 == ++(cv->nWaitersGone) ) - { - if (sem_wait( &(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 ( 0 != nWaitersWasGone ) - { - // sem_adjust( &(cv->semBlockQueue), -nWaitersWasGone ); - while ( nWaitersWasGone-- ) - { - if (sem_wait( &(cv->semBlockQueue)) != 0 ) - { - *resultPtr = errno; - return; - } - } - } - 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; - - 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; - /* - * If we're canceled, or the cancelable wait fails for any reason, - * including a timeout, then tell the cleanup routine that we - * have not been signaled. - */ - cleanup_args.signaled = 0; - -#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; - } - } - - /* - * Not executed if we're canceled. Signaled is false if we timed out. - */ - cleanup_args.signaled = (result == 0); - - /* - * 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/global.c b/global.c index 33a29fe..d541aa4 100644 --- a/global.c +++ b/global.c @@ -42,6 +42,8 @@ int ptw32_processInitialized = FALSE; 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; @@ -77,6 +79,13 @@ CRITICAL_SECTION ptw32_rwlock_test_init_lock; */ 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. diff --git a/implement.h b/implement.h index c6cef70..a564105 100644 --- a/implement.h +++ b/implement.h @@ -7,32 +7,32 @@ * * -------------------------------------------------------------------------- * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2002 Pthreads-win32 contributors + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2002 Pthreads-win32 contributors * - * Contact Email: rpj@ise.canberra.edu.au + * Contact Email: rpj@ise.canberra.edu.au * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 @@ -83,14 +83,14 @@ typedef enum { * 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 */ - PThreadStateCanceling, /* Thread alive but and is */ - /* in the process of terminating */ - /* due to a cancellation request */ - PThreadStateException, /* Thread alive but exiting */ - /* due to an exception */ + PThreadStateInitial = 0, /* Thread not running */ + PThreadStateRunning, /* Thread alive & kicking */ + PThreadStateSuspended, /* Thread alive but suspended */ + PThreadStateCanceling, /* Thread alive but and is */ + /* in the process of terminating */ + /* due to a cancellation request */ + PThreadStateException, /* Thread alive but exiting */ + /* due to an exception */ PThreadStateLast } PThreadState; @@ -101,11 +101,11 @@ typedef enum { * This enumeration represents the reason why a thread has * terminated/is terminating. */ - PThreadDemisePeaceful = 0, /* Death due natural causes */ - PThreadDemiseCancelled, /* Death due to user cancel */ - PThreadDemiseException, /* Death due to unhandled */ - /* exception */ - PThreadDemiseNotDead /* I'm not dead! */ + PThreadDemisePeaceful = 0, /* Death due natural causes */ + PThreadDemiseCancelled, /* Death due to user cancel */ + PThreadDemiseException, /* Death due to unhandled */ + /* exception */ + PThreadDemiseNotDead /* I'm not dead! */ } PThreadDemise; @@ -177,19 +177,19 @@ struct sem_t_ { #define PTW32_OBJECT_INVALID NULL struct pthread_mutex_t_ { - LONG lock_idx; /* Provides exclusive access to mutex state - via the Interlocked* mechanism, as well - as a count of the number of threads - waiting on the mutex. */ - int recursive_count; /* Number of unlocks a thread needs to perform - before the lock is released (recursive - mutexes only). */ - int kind; /* Mutex type. */ + LONG lock_idx; /* Provides exclusive access to mutex state + via the Interlocked* mechanism, as well + as a count of the number of threads + waiting on the mutex. */ + 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; - sem_t wait_sema; /* Mutex release notification to waiting - threads. */ + sem_t wait_sema; /* Mutex release notification to waiting + threads. */ CRITICAL_SECTION wait_cs; /* Serialise lock_idx decrement after mutex - timeout. */ + timeout. */ }; struct pthread_mutexattr_t_ { @@ -219,10 +219,10 @@ struct pthread_mutexattr_t_ { #define PTW32_SPIN_USE_MUTEX (3) struct pthread_spinlock_t_ { - long interlock; /* Locking element for multi-cpus. */ + 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. */ + int cpus; /* No. of cpus if multi cpus, or */ + pthread_mutex_t mutex; /* mutex if single cpu. */ } u; }; @@ -257,17 +257,19 @@ struct ThreadParms { 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 */ + 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; }; @@ -281,65 +283,65 @@ struct pthread_rwlock_t_ { pthread_mutex_t mtxExclusiveAccess; pthread_mutex_t mtxSharedAccessCompleted; pthread_cond_t cndSharedAccessCompleted; - int nSharedAccessCount; - int nExclusiveAccessCount; - int nCompletedSharedAccessCount; - int nMagic; + int nSharedAccessCount; + int nExclusiveAccessCount; + int nCompletedSharedAccessCount; + int nMagic; }; struct pthread_rwlockattr_t_ { - int pshared; + int pshared; }; 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. + * This structure creates an association between a + * thread and a key. + * It is used to implement the implicit invocation + * of a user defined destroy routine for thread + * specific data registered by a user upon exiting a + * thread. * * Attributes: - * lock - * protects access to the rest of the structure + * lock + * protects access to the rest of the structure * - * thread - * reference to the thread that owns the association. - * As long as this is not NULL, the association remains - * referenced by the pthread_t. + * thread + * reference to the thread that owns the association. + * As long as this is not NULL, the association remains + * referenced by the pthread_t. * - * key - * reference to the key that owns the association. - * As long as this is not NULL, the association remains - * referenced by the pthread_key_t. + * key + * reference to the key that owns the association. + * As long as this is not NULL, the association remains + * referenced by the pthread_key_t. * - * nextKey - * The pthread_t->keys attribute is the head of a - * chain of associations that runs through the nextKey - * link. This chain provides the 1 to many relationship - * between a pthread_t and all pthread_key_t on which - * it called pthread_setspecific. + * nextKey + * The pthread_t->keys attribute is the head of a + * chain of associations that runs through the nextKey + * link. This chain provides the 1 to many relationship + * between a pthread_t and all pthread_key_t on which + * it called pthread_setspecific. * - * nextThread - * The pthread_key_t->threads attribute is the head of - * a chain of assoctiations that runs through the - * nextThreads link. This chain provides the 1 to many - * relationship between a pthread_key_t and all the - * PThreads that have called pthread_setspecific for - * this pthread_key_t. + * nextThread + * The pthread_key_t->threads attribute is the head of + * a chain of assoctiations that runs through the + * nextThreads link. This chain provides the 1 to many + * relationship between a pthread_key_t and all the + * PThreads that have called pthread_setspecific for + * this pthread_key_t. * * * Notes: - * 1) As long as one of the attributes, thread or key, is - * not NULL, the association is being referenced; once - * both are NULL, the association must be released. + * 1) As long as one of the attributes, thread or key, is + * not NULL, the association is being referenced; once + * both are NULL, the association must be released. * - * 2) Under WIN32, an association is only created by - * pthread_setspecific if the user provided a - * destroyRoutine when they created the key. + * 2) Under WIN32, an association is only created by + * pthread_setspecific if the user provided a + * destroyRoutine when they created the key. * * */ @@ -355,27 +357,27 @@ struct ThreadKeyAssoc { /* * -------------------------------------------------------------- * 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 + * 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 | + * |Sev|C|R| Facility | Code | * +---+-+-+-----------------------+-------------------------------+ * * Severity Values: */ -#define SE_SUCCESS 0x00 -#define SE_INFORMATION 0x01 -#define SE_WARNING 0x02 -#define SE_ERROR 0x03 +#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 */ \ + ( 1 << 29 ) | /* MS=0, User=1 */ \ + ( 0 << 28 ) | /* Reserved */ \ ( (_facility) << 16 ) | /* Facility Code */ \ ( (_exception) << 0 ) /* Exception Code */ \ ) ) @@ -391,8 +393,8 @@ struct ThreadKeyAssoc { PTW32_SERVICES_FACILITY, \ PTW32_SERVICES_ERROR ) -#define PTW32_SERVICES_FACILITY 0xBAD -#define PTW32_SERVICES_ERROR 0xDEED +#define PTW32_SERVICES_FACILITY 0xBAD +#define PTW32_SERVICES_ERROR 0xDEED #endif /* __CLEANUP_SEH */ @@ -402,8 +404,8 @@ struct ThreadKeyAssoc { * generic exception selectors. */ -#define PTW32_EPS_EXIT (1) -#define PTW32_EPS_CANCEL (2) +#define PTW32_EPS_EXIT (1) +#define PTW32_EPS_CANCEL (2) /* Mutex constants */ enum { @@ -413,24 +415,27 @@ enum { /* Useful macros */ -#define PTW32_MAX(a,b) ((a)<(b)?(b):(a)) -#define PTW32_MIN(a,b) ((a)>(b)?(b):(a)) +#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); + PTW32_INTERLOCKED_LONG, + PTW32_INTERLOCKED_LONG); extern int ptw32_processInitialized; 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 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; @@ -459,10 +464,17 @@ extern "C" { * ===================== * ===================== */ + +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); + PTW32_INTERLOCKED_LONG value, + PTW32_INTERLOCKED_LONG comparand); int ptw32_processInitialize (void); @@ -495,9 +507,14 @@ void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc); #ifdef NEED_SEM void ptw32_decrease_semaphore(sem_t * sem); BOOL ptw32_increase_semaphore(sem_t * sem, - unsigned int n); + unsigned int n); #endif /* NEED_SEM */ +#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 + #ifdef __cplusplus } #endif /* __cplusplus */ @@ -542,7 +559,7 @@ BOOL ptw32_increase_semaphore(sem_t * sem, arg, \ flags, \ pid) \ - CreateThread(security, \ + CreateThread(security, \ stack_size, \ (LPTHREAD_START_ROUTINE) start_proc, \ arg, \ diff --git a/misc.c b/misc.c index 4e3b286..8aa7f96 100644 --- a/misc.c +++ b/misc.c @@ -43,7 +43,7 @@ #include "pthread_equal.c" #include "pthread_setconcurrency.c" #include "pthread_getconcurrency.c" -#include "w32_CancelableWait.c" #include "ptw32_new.c" #include "ptw32_calloc.c" +#include "w32_CancelableWait.c" diff --git a/mutex.c b/mutex.c index fa48760..6bf6acd 100644 --- a/mutex.c +++ b/mutex.c @@ -44,1073 +44,19 @@ #include "implement.h" -static INLINE int -ptw32_mutex_check_need_init(pthread_mutex_t *mutex) -{ - int result = 0; +#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" - /* - * 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. - */ - if (*mutex == PTHREAD_MUTEX_INITIALIZER) - { - result = pthread_mutex_init(mutex, NULL); - } - else if (*mutex == 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); -} - -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 - - /* - * 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 = PTW32_MUTEX_LOCK_IDX_INIT; - mx->recursive_count = 0; - mx->kind = (attr == NULL || *attr == NULL - ? PTHREAD_MUTEX_DEFAULT - : (*attr)->kind); - mx->ownerThread = NULL; - - if ( 0 != sem_init( &mx->wait_sema, 0, 0 )) - { - result = EAGAIN; - free(mx); - mx = NULL; - } - else - { - InitializeCriticalSection( &mx->wait_cs ); - } - } - - *mutex = mx; - - return(result); -} - -int -pthread_mutex_destroy(pthread_mutex_t *mutex) -{ - int result = 0; - pthread_mutex_t mx; - - if (mutex == NULL - || *mutex == NULL) - { - return EINVAL; - } - - /* - * Check to see if we have something to delete. - */ - if (*mutex != PTHREAD_MUTEX_INITIALIZER) - { - mx = *mutex; - - result = pthread_mutex_trylock(&mx); - - /* - * The mutex type may not be RECURSIVE therefore trylock may return EBUSY if - * we already own the mutex. Here we are assuming that it's OK to destroy - * a mutex that we own and have locked recursively. Is this correct? - * - * For FAST mutexes we record the owner as ANONYMOUS for speed. In this - * case we assume that the thread calling pthread_mutex_destroy() is the - * owner, if the mutex is owned at all. - */ - if (result == 0 - || mx->ownerThread == (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS - || pthread_equal( mx->ownerThread, pthread_self() ) ) - { - /* - * 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. - */ - *mutex = NULL; - - result = pthread_mutex_unlock(&mx); - - if (result == 0) - { - (void) sem_destroy( &mx->wait_sema ); - DeleteCriticalSection( &mx->wait_cs ); - free(mx); - } - else - { - /* - * Restore the mutex before we return the error. - */ - *mutex = mx; - } - } - } - else - { - /* - * See notes in ptw32_mutex_check_need_init() above also. - */ - EnterCriticalSection(&ptw32_mutex_test_init_lock); - - /* - * Check again. - */ - if (*mutex == PTHREAD_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); -} - -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 */ - - -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 */ - - -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 */ - - -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 */ - - -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 */ - - -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); -} - - -static INLINE int -ptw32_timed_semwait (sem_t * sem, const struct timespec * abstime) - /* - * ------------------------------------------------------ - * 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 or until abstime. - * 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. - * - * RESULTS - * 2 abstime has passed already - * 1 abstime timed out while waiting - * 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; - -#ifdef NEED_FTIME - - struct timespec currSysTime; - -#else /* NEED_FTIME */ - - struct _timeb currSysTime; - -#endif /* NEED_FTIME */ - - const DWORD NANOSEC_PER_MILLISEC = 1000000; - const DWORD MILLISEC_PER_SEC = 1000; - DWORD milliseconds; - DWORD status; - - if (sem == NULL) - { - result = EINVAL; - } - else - { - if (abstime == NULL) - { - milliseconds = INFINITE; - } - else - { - /* - * Calculate timeout as milliseconds from current system time. - */ - - /* get current system time */ - -#ifdef NEED_FTIME - - { - FILETIME ft; - SYSTEMTIME st; - - GetSystemTime(&st); - SystemTimeToFileTime(&st, &ft); - /* - * GetSystemTimeAsFileTime(&ft); would be faster, - * but it does not exist on WinCE - */ - - filetime_to_timespec(&ft, &currSysTime); - } - - /* - * subtract current system time from abstime - */ - milliseconds = (abstime->tv_sec - currSysTime.tv_sec) * MILLISEC_PER_SEC; - milliseconds += ((abstime->tv_nsec - currSysTime.tv_nsec) + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC; - -#else /* NEED_FTIME */ - _ftime(&currSysTime); - - /* - * subtract current system time from abstime - */ - milliseconds = (abstime->tv_sec - currSysTime.time) * MILLISEC_PER_SEC; - milliseconds += ((abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC) - - currSysTime.millitm; - -#endif /* NEED_FTIME */ - - - if (((int) milliseconds) < 0) - { - return 2; - } - } - -#ifdef NEED_SEM - - status = WaitForSingleObject( (*sem)->event, milliseconds ); - -#else /* NEED_SEM */ - - status = WaitForSingleObject( (*sem)->sem, milliseconds ); - -#endif - - if (status == WAIT_OBJECT_0) - { - -#ifdef NEED_SEM - - ptw32_decrease_semaphore(sem); - -#endif /* NEED_SEM */ - - return 0; - } - else if (status == WAIT_TIMEOUT) - { - return 1; - } - else - { - result = EINVAL; - } - } - - if (result != 0) - { - errno = result; - return -1; - } - - return 0; - -} /* ptw32_timed_semwait */ - - -int -pthread_mutex_lock(pthread_mutex_t *mutex) -{ - int result = 0; - pthread_mutex_t mx; - - - if (mutex == NULL || *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_MUTEX_INITIALIZER) - { - if ((result = ptw32_mutex_check_need_init(mutex)) != 0) - { - return(result); - } - } - - mx = *mutex; - - if( 0 == InterlockedIncrement( &mx->lock_idx ) ) - { - mx->recursive_count = 1; - mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP - ? pthread_self() - : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); - } - else - { - if( mx->kind != PTHREAD_MUTEX_FAST_NP && - pthread_equal( mx->ownerThread, pthread_self() ) ) - { - (void) InterlockedDecrement( &mx->lock_idx ); - - if( mx->kind == PTHREAD_MUTEX_RECURSIVE_NP ) - { - mx->recursive_count++; - } - else - { - result = EDEADLK; - } - } - else - { - if ((result = sem_wait( &mx->wait_sema )) == 0) - { - mx->recursive_count = 1; - mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP - ? pthread_self() - : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); - } - } - } - - return(result); -} - - -int -pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime) -{ - int result = 0; - pthread_mutex_t mx; - -#ifdef NEED_SEM - errno = ENOTSUP; - return -1; -#endif - - if (mutex == NULL || *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_MUTEX_INITIALIZER) - { - if ((result = ptw32_mutex_check_need_init(mutex)) != 0) - { - return(result); - } - } - - mx = *mutex; - - if( 0 == InterlockedIncrement( &mx->lock_idx ) ) - { - mx->recursive_count = 1; - mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP - ? pthread_self() - : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); - } - else - { - if( mx->kind != PTHREAD_MUTEX_FAST_NP && - pthread_equal( mx->ownerThread, pthread_self() ) ) - { - (void) InterlockedDecrement( &mx->lock_idx ); - - if( mx->kind == PTHREAD_MUTEX_RECURSIVE_NP ) - { - mx->recursive_count++; - } - else - { - result = EDEADLK; - } - } - else - { - if (abstime == NULL) - { - result = EINVAL; - } - else - { - switch (ptw32_timed_semwait( &mx->wait_sema, abstime )) - { - case 0: /* We got the mutex. */ - { - mx->recursive_count = 1; - mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP - ? pthread_self() - : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); - break; - } - case 1: /* Timedout, try a second grab. */ - { - EnterCriticalSection(&mx->wait_cs); - - /* - * If we timeout, it is up to us to adjust lock_idx to say - * we're no longer waiting. If the mutex was also unlocked - * while we were timing out, and we simply return ETIMEDOUT, - * then wait_sema would be left in a state that is not consistent - * with the state of lock_idx. - * - * We must check to see if wait_sema has just been posted - * but we can't just call sem_getvalue - we must compete for - * the semaphore using sem_trywait(), otherwise we would need - * additional critical sections elsewhere, which would make the - * logic too inefficient. - * - * If sem_trywait returns EAGAIN then either wait_sema - * was given directly to another waiting thread or - * another thread has called sem_*wait() before us and - * taken the lock. Then we MUST decrement lock_idx and return - * ETIMEDOUT. - * - * Otherwise we MUST return success (because we have effectively - * acquired the lock that would have been ours had we not - * timed out), and NOT decrement lock_idx. - * - * We can almost guarrantee that EAGAIN is the only - * possible error, so no need to test errno. - */ - - if ( -1 == sem_trywait( &mx->wait_sema ) ) - { - (void) InterlockedDecrement( &mx->lock_idx ); - result = ETIMEDOUT; - } - - LeaveCriticalSection(&mx->wait_cs); - break; - } - case 2: /* abstime passed before we started to wait. */ - { - /* - * If we timeout, it is up to us to adjust lock_idx to say - * we're no longer waiting. - * - * The owner thread may still have posted wait_sema thinking - * we were waiting. I believe we must check but then NOT do any - * programmed work if we have acquired the mutex because - * we don't how long ago abstime was. We MUST just release it - * immediately. - */ - EnterCriticalSection(&mx->wait_cs); - - result = ETIMEDOUT; - - if ( -1 == sem_trywait( &mx->wait_sema ) ) - { - (void) InterlockedDecrement( &mx->lock_idx ); - } - else - { - if ( InterlockedDecrement( &mx->lock_idx ) >= 0 ) - { - /* Someone else is waiting on that mutex */ - if ( sem_post( &mx->wait_sema ) != 0 ) - { - result = errno; - } - } - } - - LeaveCriticalSection(&mx->wait_cs); - break; - } - default: - { - result = errno; - break; - } - } - } - } - } - - return(result); -} - - -int -pthread_mutex_unlock(pthread_mutex_t *mutex) -{ - int result = 0; - pthread_mutex_t mx; - - if (mutex == NULL || *mutex == NULL) - { - return EINVAL; - } - - 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_MUTEX_INITIALIZER) - { - if (mx->ownerThread == (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS - || pthread_equal(mx->ownerThread, pthread_self())) - { - if( mx->kind != PTHREAD_MUTEX_RECURSIVE_NP - || 0 == --mx->recursive_count ) - { - mx->ownerThread = NULL; - EnterCriticalSection( &mx->wait_cs ); - - if( InterlockedDecrement( &mx->lock_idx ) >= 0 ) - { - /* Someone is waiting on that mutex */ - if (sem_post( &mx->wait_sema ) != 0) - { - result = errno; - } - } - - LeaveCriticalSection( &mx->wait_cs ); - } - } - else - { - result = EPERM; - } - } - else - { - result = EINVAL; - } - - return(result); -} - -int -pthread_mutex_trylock(pthread_mutex_t *mutex) -{ - int result = 0; - pthread_mutex_t mx; - - if (mutex == NULL || *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_MUTEX_INITIALIZER) - { - result = ptw32_mutex_check_need_init(mutex); - } - - mx = *mutex; - - if (result == 0) - { - if ( (PTW32_INTERLOCKED_LONG) PTW32_MUTEX_LOCK_IDX_INIT == - ptw32_interlocked_compare_exchange((PTW32_INTERLOCKED_LPLONG) &mx->lock_idx, - (PTW32_INTERLOCKED_LONG) 0, - (PTW32_INTERLOCKED_LONG) PTW32_MUTEX_LOCK_IDX_INIT)) - { - mx->recursive_count = 1; - mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP - ? pthread_self() - : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); - } - else - { - if( mx->kind != PTHREAD_MUTEX_FAST_NP && - pthread_equal( mx->ownerThread, pthread_self() ) ) - { - if( mx->kind == PTHREAD_MUTEX_RECURSIVE_NP ) - { - mx->recursive_count++; - } - else - { - result = EDEADLK; - } - } - else - { - result = EBUSY; - } - } - } - - return(result); -} diff --git a/nonportable.c b/nonportable.c index 4c8b449..8e0e507 100644 --- a/nonportable.c +++ b/nonportable.c @@ -37,9 +37,11 @@ #include "pthread.h" #include "implement.h" -#include "np_mutexattr_setkind.c" -#include "np_mutexattr_getkind.c" -#include "np_getw32threadhandle.c" -#include "np_delay.c" -#include "np_num_processors.c" -#include "np_win32_attach.c" +#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/np_delay.c b/np_delay.c deleted file mode 100644 index d2a893e..0000000 --- a/np_delay.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * np_delay.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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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; - - 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 (0 > (wait_time = secs_in_millisecs + millisecs)) - { - return EINVAL; - } - - if (NULL == (self = pthread_self())) - { - return ENOMEM; - } - - if (self->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(self->cancelEvent, wait_time)) ) - { - /* - * Canceling! - */ - (void) pthread_mutex_lock(&self->cancelLock); - if (self->state < PThreadStateCanceling) - { - self->state = PThreadStateCanceling; - self->cancelState = PTHREAD_CANCEL_DISABLE; - (void) pthread_mutex_unlock(&self->cancelLock); - - ptw32_throw(PTW32_EPS_CANCEL); - } - - (void) pthread_mutex_unlock(&self->cancelLock); - return ESRCH; - } - else if (status != WAIT_TIMEOUT) - { - return EINVAL; - } - } - else - { - Sleep( wait_time ); - } - - return (0); -} diff --git a/np_getw32threadhandle.c b/np_getw32threadhandle.c deleted file mode 100644 index 98f610e..0000000 --- a/np_getw32threadhandle.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * np_getw32threadhandle.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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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 (thread != NULL) ? (thread->threadH) : 0; -} diff --git a/np_mutexattr_setkind.c b/np_mutexattr_setkind.c deleted file mode 100644 index df56ca6..0000000 --- a/np_mutexattr_setkind.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * np_mutexattr_setkind.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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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_mutexattr_setkind_np() - */ -int -pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, int kind) -{ - return pthread_mutexattr_settype( attr, kind ); -} - - -/* - * pthread_mutexattr_getkind_np() - */ -int -pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, int *kind) -{ - return pthread_mutexattr_gettype( attr, kind ); -} diff --git a/np_num_processors.c b/np_num_processors.c deleted file mode 100644 index 776e2f7..0000000 --- a/np_num_processors.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * np_num_processors.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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/np_win32_attach.c b/np_win32_attach.c deleted file mode 100644 index f7833ee..0000000 --- a/np_win32_attach.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * np_win32_attach.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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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; - -BOOL -pthread_win32_process_attach_np () -{ - BOOL result = TRUE; - - result = ptw32_processInitialize (); -#ifdef _UWIN - pthread_count++; -#endif - -#ifndef TEST_ICE - - /* - * Load KERNEL32 and try to get address of InterlockedCompareExchange - */ - ptw32_h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL")); - - 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 /* TEST_ICE */ - - ptw32_interlocked_compare_exchange = ptw32_InterlockedCompareExchange; - -#endif /* TEST_ICE */ - - return result; -} - - -BOOL -pthread_win32_process_detach_np () -{ - if (ptw32_processInitialized) - { - pthread_t self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey); - - /* - * Detached threads have their resources automatically - * cleaned up upon exit (others must be 'joined'). - */ - if (self != NULL && - self->detachState == PTHREAD_CREATE_DETACHED) - { - pthread_setspecific (ptw32_selfThreadKey, NULL); - ptw32_threadDestroy (self); - } - - /* - * The DLL is being unmapped into the process's address space - */ - ptw32_processTerminate (); - - 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) - { - pthread_t self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey); - - /* - * Detached threads have their resources automatically - * cleaned up upon exit (others must be 'joined'). - */ - if (self != NULL && - self->detachState == PTHREAD_CREATE_DETACHED) - { - pthread_setspecific (ptw32_selfThreadKey, NULL); - ptw32_threadDestroy (self); - } - } - - return TRUE; -} diff --git a/private.c b/private.c index e0ca43a..19a7aeb 100644 --- a/private.c +++ b/private.c @@ -36,974 +36,18 @@ */ #include "pthread.h" -#include "semaphore.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() explicitely, - * since this initialization routine is automatically called only when - * the dll is loaded. - */ - return TRUE; - } - - ptw32_processInitialized = TRUE; - - /* - * Initialize Keys - */ - if ((pthread_key_create (&ptw32_selfThreadKey, NULL) != 0) || - (pthread_key_create (&ptw32_cleanupKey, NULL) != 0)) - { - - ptw32_processTerminate (); - } - - /* - * Set up the global test and init check locks. - */ - InitializeCriticalSection(&ptw32_mutex_test_init_lock); - InitializeCriticalSection(&ptw32_cond_test_init_lock); - InitializeCriticalSection(&ptw32_rwlock_test_init_lock); - InitializeCriticalSection(&ptw32_spinlock_test_init_lock); - - return (ptw32_processInitialized); - -} /* processInitialize */ - -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) - { - - 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; - } - - /* - * Destroy the global test and init check locks. - */ - DeleteCriticalSection(&ptw32_spinlock_test_init_lock); - DeleteCriticalSection(&ptw32_rwlock_test_init_lock); - DeleteCriticalSection(&ptw32_cond_test_init_lock); - DeleteCriticalSection(&ptw32_mutex_test_init_lock); - - ptw32_processInitialized = FALSE; - } - -} /* processTerminate */ - -#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(&self->cancelLock); - ptw32_callUserDestroyRoutines(self); - - return EXCEPTION_CONTINUE_SEARCH; - break; - } - } -} - -#elif defined(__CLEANUP_CXX) - -#if defined(_MSC_VER) -#include -static terminate_function ptw32_oldTerminate; -#else -#include -static terminate_handler ptw32_oldTerminate; -#endif - -#if 0 -#include -static pthread_mutex_t termLock = PTHREAD_MUTEX_INITIALIZER; -#endif - -void -ptw32_terminate () -{ - pthread_t self = pthread_self(); -#if 0 - FILE * fp; - pthread_mutex_lock(&termLock); - fp = fopen("pthread.log", "a"); - fprintf(fp, "Terminate\n"); - fclose(fp); - pthread_mutex_unlock(&termLock); -#endif - set_terminate(ptw32_oldTerminate); - (void) pthread_mutex_destroy(&self->cancelLock); - ptw32_callUserDestroyRoutines(self); - terminate(); -} - -#endif /* _MSC_VER */ - -#if ! defined (__MINGW32__) || defined (__MSVCRT__) -unsigned __stdcall -#else -void -#endif -ptw32_threadStart (void * vthreadParms) -{ - ThreadParms *threadParms = (ThreadParms *) vthreadParms; - pthread_t self; - 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; - 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. - */ - self->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(&self->cancelLock) == 0) - { - (void) pthread_mutex_unlock(&self->cancelLock); - } -#endif - - pthread_setspecific (ptw32_selfThreadKey, self); - - self->state = PThreadStateRunning; - -#ifdef __CLEANUP_SEH - - __try - { - /* - * Run the caller's routine; - */ - status = self->exitStatus = (*start) (arg); - -#ifdef _UWIN - if (--pthread_count <= 0) - exit(0); -#endif - - } - __except (ExceptionFilter(GetExceptionInformation(), ei)) - { - switch (ei[0]) - { - case PTW32_EPS_CANCEL: - status = PTHREAD_CANCELED; -#ifdef _UWIN - if (--pthread_count <= 0) - exit(0); -#endif - break; - case PTW32_EPS_EXIT: - status = self->exitStatus; - break; - default: - status = PTHREAD_CANCELED; - break; - } - } - -#else /* __CLEANUP_SEH */ - -#ifdef __CLEANUP_C - - setjmp_rc = setjmp( self->start_mark ); - - if( 0 == setjmp_rc ) { - - /* - * Run the caller's routine; - */ - status = self->exitStatus = (*start) (arg); - } - - else { - - switch (setjmp_rc) - { - case PTW32_EPS_CANCEL: - status = PTHREAD_CANCELED; - break; - case PTW32_EPS_EXIT: - status = self->exitStatus; - break; - default: - status = 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 = self->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. - */ - -#if defined(_MSC_VER) - terminate_function term_func = set_terminate(0); -#else - terminate_handler term_func = set_terminate(0); -#endif - - set_terminate(term_func); - - if (term_func != 0) { - term_func(); - } - - throw; - } - } - catch (ptw32_exception_cancel &) - { - /* - * Thread was canceled. - */ - status = self->exitStatus = PTHREAD_CANCELED; - } - catch (ptw32_exception_exit &) - { - /* - * Thread was exited via pthread_exit(). - */ - status = self->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 = self->exitStatus = PTHREAD_CANCELED; - (void) pthread_mutex_lock(&self->cancelLock); - self->state = PThreadStateException; - (void) pthread_mutex_unlock(&self->cancelLock); - (void) pthread_mutex_destroy(&self->cancelLock); - (void) set_terminate(ptw32_oldTerminate); - ptw32_callUserDestroyRoutines(self); - 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 */ - - (void) pthread_mutex_lock(&self->cancelLock); - self->state = PThreadStateLast; - (void) pthread_mutex_unlock(&self->cancelLock); - - - (void) pthread_mutex_destroy(&self->cancelLock); - -#if 1 - if (self->detachState == PTHREAD_CREATE_DETACHED) - { - /* - * We need to cleanup the pthread now in case we have - * been statically linked, in which case the cleanup - * in dllMain won't get done. Joinable threads will - * be cleaned up by pthread_join(). - * - * Note that 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()) if - * this library has been statically linked. For the dll, - * dllMain will do the cleanup automatically. - */ - (void) pthread_win32_thread_detach_np (); - } - else - { - ptw32_callUserDestroyRoutines (self); - } -#else - ptw32_callUserDestroyRoutines (self); -#endif - -#if ! defined (__MINGW32__) || defined (__MSVCRT__) - _endthreadex ((unsigned) status); -#else - _endthread (); -#endif - - /* - * Never reached. - */ - -#if ! defined (__MINGW32__) || defined (__MSVCRT__) - return (unsigned) status; -#endif - -} /* ptw32_threadStart */ - -void -ptw32_threadDestroy (pthread_t thread) -{ - if (thread != NULL) - { - ptw32_callUserDestroyRoutines (thread); - - if (thread->cancelEvent != NULL) - { - CloseHandle (thread->cancelEvent); - } - -#if ! defined (__MINGW32__) || defined (__MSVCRT__) - /* See documentation for endthread vs endthreadex. */ - if( thread->threadH != 0 ) - { - CloseHandle( thread->threadH ); - } -#endif - - free (thread); - } - -} /* ptw32_threadDestroy */ - -int -ptw32_tkAssocCreate (ThreadKeyAssoc ** assocP, - pthread_t thread, - 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 by pthread_exit last. - * - * Parameters: - * assocP - * address into which the association is returned. - * thread - * current running thread. If NULL, then association - * is only added to the key. A NULL thread indicates - * that the user called pthread_setspecific prior - * to starting a thread. That's ok. - * 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 - * ------------------------------------------------------------------- - */ -{ - int result; - ThreadKeyAssoc *assoc; - - /* - * Have to create an association and add it - * to both the key and the thread. - */ - assoc = (ThreadKeyAssoc *) calloc (1, sizeof (*assoc)); - - if (assoc == NULL) - { - result = ENOMEM; - goto FAIL0; - } - - /* - * Initialise only when used for the first time. - */ - assoc->lock = PTHREAD_MUTEX_INITIALIZER; - assoc->thread = thread; - assoc->key = key; - - /* - * Register assoc with key - */ - if ((result = pthread_mutex_lock (&(key->threadsLock))) != 0) - { - goto FAIL2; - } - - assoc->nextThread = (ThreadKeyAssoc *) key->threads; - key->threads = (void *) assoc; - - pthread_mutex_unlock (&(key->threadsLock)); - - if (thread != NULL) - { - /* - * Register assoc with thread - */ - assoc->nextKey = (ThreadKeyAssoc *) thread->keys; - thread->keys = (void *) assoc; - } - - *assocP = assoc; - - return (result); - - /* - * ------------- - * Failure Code - * ------------- - */ -FAIL2: - pthread_mutex_destroy (&(assoc->lock)); - free (assoc); - -FAIL0: - - return (result); - -} /* ptw32_tkAssocCreate */ - - -void -ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc) - /* - * ------------------------------------------------------------------- - * This routine releases all resources for the given ThreadKeyAssoc - * once it is no longer being referenced - * ie) both the key and thread have stopped referencing it. - * - * Parameters: - * assoc - * an instance of ThreadKeyAssoc. - * Returns: - * N/A - * ------------------------------------------------------------------- - */ -{ - - if ((assoc != NULL) && - (assoc->key == NULL && assoc->thread == NULL)) - { - - pthread_mutex_destroy (&(assoc->lock)); - - free (assoc); - } - -} /* ptw32_tkAssocDestroy */ - - -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 **nextP; - ThreadKeyAssoc *assoc; - - if (thread != NULL) - { - /* - * Run through all Thread<-->Key associations - * for the current thread. - * If the pthread_key_t still exits (ie the assoc->key - * is not NULL) then call the user's TSD destroy routine. - * Notes: - * If assoc->key is NULL, then the user previously called - * PThreadKeyDestroy. The association is now only referenced - * by the current thread and must be released; otherwise - * the assoc will be destroyed when the key is destroyed. - */ - nextP = (ThreadKeyAssoc **) & (thread->keys); - assoc = *nextP; - - while (assoc != NULL) - { - - if (pthread_mutex_lock (&(assoc->lock)) == 0) - { - pthread_key_t k; - if ((k = assoc->key) != NULL) - { - /* - * Key still active; pthread_key_delete - * will block on this same mutex before - * it can release actual key; therefore, - * key is valid and we can call the destroy - * routine; - */ - void *value = NULL; - - value = pthread_getspecific (k); - if (value != NULL && k->destructor != NULL) - { - -#ifdef __cplusplus - - try - { - /* - * Run the caller's cleanup routine. - */ - (*(k->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. - */ - (*(k->destructor)) (value); - -#endif /* __cplusplus */ - } - } - - /* - * mark assoc->thread as NULL to indicate the - * thread no longer references this association - */ - assoc->thread = NULL; - - /* - * Remove association from the pthread_t chain - */ - *nextP = assoc->nextKey; - - pthread_mutex_unlock (&(assoc->lock)); - - ptw32_tkAssocDestroy (assoc); - - assoc = *nextP; - } - } - } - -} /* ptw32_callUserDestroyRoutines */ - - - -#ifdef NEED_FTIME - -/* - * time between jan 1, 1601 and jan 1, 1970 in units of 100 nanoseconds - */ -#define TIMESPEC_TO_FILETIME_OFFSET \ - ( ((LONGLONG) 27111902 << 32) + (LONGLONG) 3577643008 ) - -static INLINE void -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 + TIMESPEC_TO_FILETIME_OFFSET; -} - -static INLINE void -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 - TIMESPEC_TO_FILETIME_OFFSET) / 10000000); - ts->tv_nsec = (int)((*(LONGLONG *)ft - TIMESPEC_TO_FILETIME_OFFSET - ((LONGLONG)ts->tv_sec * (LONGLONG)10000000)) * 100); -} - -#endif /* NEED_FTIME */ - - -DWORD -ptw32_get_exception_services_code(void) -{ -#ifdef __CLEANUP_SEH - - return EXCEPTION_PTW32_SERVICES; - -#else - - return (DWORD) NULL; - -#endif -} - - -void -ptw32_throw(DWORD exception) -{ -#ifdef __CLEANUP_C - pthread_t self = pthread_self(); -#endif - - -#ifdef __CLEANUP_SEH - DWORD exceptionInformation[3]; -#endif - - if (exception != PTW32_EPS_CANCEL && - exception != PTW32_EPS_EXIT) - { - /* Should never enter here */ - exit(1); - } - -#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( self->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) ) { - } -} - - -/* - * ptw32_InterlockedCompareExchange -- - * - * Needed because W95 doesn't support InterlockedCompareExchange. - * It is only used when running the dll on W95. Other versions of - * Windows use the Win32 supported version, which may be running on - * different processor types. - * - * This can't be inlined because we need to know it's address so that - * we can call it through a pointer. - */ -PTW32_INTERLOCKED_LONG WINAPI -ptw32_InterlockedCompareExchange(PTW32_INTERLOCKED_LPLONG location, - PTW32_INTERLOCKED_LONG value, - PTW32_INTERLOCKED_LONG comparand) -{ - PTW32_INTERLOCKED_LONG result; - -#if defined(_M_IX86) || defined(_X86_) - -#if defined(_MSC_VER) - - _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 ; if (EAX == [ECX]), - ; [ECX] = EDX - ; else - ; EAX = [ECX] - MOV dword ptr [result], eax - POP edx - POP ecx - } - -#elif defined(__GNUC__) - - __asm__ - ( - "lock\n\t" - "cmpxchgl %3,(%0)" /* if (EAX == [location]), */ - /* [location] = value */ - /* else */ - /* EAX = [location] */ - :"=r" (location), "=a" (result) - :"0" (location), "q" (value), "a" (comparand) - : "memory" ); - -#endif - -#else - - /* - * If execution gets to here then we should be running on a Win95 system - * but either running on something other than an X86 processor, or a - * compiler other than MSVC or GCC. Pthreads-win32 doesn't support that - * platform (yet). - */ - - result = 0; - -#endif - - return result; -} - - -/* - * 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 vProcessCPUs; - DWORD vSystemCPUs; - int result = 0; - - if (GetProcessAffinityMask(GetCurrentProcess(), - &vProcessCPUs, - &vSystemCPUs)) - { - DWORD bit; - int CPUs = 0; - - for (bit = 1; bit != 0; bit <<= 1) - { - if (vProcessCPUs & bit) - { - CPUs++; - } - } - *count = CPUs; - } - else - { - result = EAGAIN; - } - - return(result); -} +#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_timespec.c" +#include "ptw32_throw.c" +#include "ptw32_InterlockedCompareExchange.c" +#include "ptw32_getprocessors.c" diff --git a/pthread.c b/pthread.c index be70f38..8fb39d7 100644 --- a/pthread.c +++ b/pthread.c @@ -2,7 +2,7 @@ * pthread.c * * Description: - * This translation unit agregates operations on threads. + * 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. * @@ -42,4 +42,9 @@ #include "attr.c" #include "barrier.c" #include "cancel.c" +#include "condvar.c" +#include "misc.c" +#include "mutex.c" +#include "private.c" +#include "rwlock.c" #include "semaphore.c" diff --git a/pthread.def b/pthread.def index 1609045..621ee09 100644 --- a/pthread.def +++ b/pthread.def @@ -1,162 +1,163 @@ -; pthread.def -; Last updated: $Date: 2002/02/11 01:53:22 $ - -; Currently unimplemented functions are commented out. - -;LIBRARY pthread - -EXPORTS -;pthread_atfork -pthread_attr_destroy -pthread_attr_getdetachstate -pthread_attr_getinheritsched -pthread_attr_getschedparam -pthread_attr_getschedpolicy -pthread_attr_getscope -pthread_attr_getstackaddr -pthread_attr_getstacksize -pthread_attr_init -pthread_attr_setdetachstate -pthread_attr_setinheritsched -pthread_attr_setschedparam -pthread_attr_setschedpolicy -pthread_attr_setscope -pthread_attr_setstackaddr -pthread_attr_setstacksize -pthread_cancel -; -; These two are implemented as macros in pthread.h -; -;pthread_cleanup_pop -;pthread_cleanup_push -; -pthread_condattr_destroy -pthread_condattr_getpshared -pthread_condattr_init -pthread_condattr_setpshared -pthread_cond_broadcast -pthread_cond_destroy -pthread_cond_init -pthread_cond_signal -pthread_cond_timedwait -pthread_cond_wait -pthread_create -pthread_detach -pthread_equal -pthread_exit -pthread_getconcurrency -pthread_getschedparam -pthread_getspecific -pthread_join -pthread_key_create -pthread_key_delete -;pthread_kill -pthread_mutexattr_destroy -;pthread_mutexattr_getprioceiling -;pthread_mutexattr_getprotocol -pthread_mutexattr_getpshared -pthread_mutexattr_gettype -pthread_mutexattr_init -;pthread_mutexattr_setprioceiling -;pthread_mutexattr_setprotocol -pthread_mutexattr_setpshared -pthread_mutexattr_settype -pthread_mutexattr_destroy -pthread_mutex_init -pthread_mutex_destroy -pthread_mutex_lock -pthread_mutex_trylock -pthread_mutex_timedlock -pthread_mutex_unlock -pthread_once -pthread_self -pthread_setcancelstate -pthread_setcanceltype -pthread_setconcurrency -pthread_setschedparam -pthread_setspecific -;pthread_sigmask -pthread_testcancel -; -; Scheduling -; -sched_get_priority_min -sched_get_priority_max -sched_getscheduler -sched_setscheduler -sched_yield -; -; Semaphores -; -sem_init -sem_destroy -sem_trywait -sem_wait -sem_timedwait -sem_post -sem_open -sem_close -sem_unlink -sem_getvalue -; -; This next one is a macro -;sched_rr_get_interval -; -; -; Read/Write Locks -; -pthread_rwlock_init -pthread_rwlock_destroy -pthread_rwlock_tryrdlock -pthread_rwlock_trywrlock -pthread_rwlock_rdlock -pthread_rwlock_wrlock -pthread_rwlock_unlock -; -; 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 -; -; Non-portable/compatibility with other implementations -; -pthread_delay_np -pthread_mutexattr_getkind_np -pthread_mutexattr_setkind_np -; -; Non-portable local implementation only -; -pthread_getw32threadhandle_np -pthread_num_processors_np -pthreadCancelableWait -pthreadCancelableTimedWait -; -; For use when linking statically -; -pthread_win32_process_attach_np -pthread_win32_process_detach_np -pthread_win32_thread_attach_np -pthread_win32_thread_detach_np -; -; Needed if !defined(_MSC_VER) && !defined(__cplusplus) -; -ptw32_push_cleanup -ptw32_pop_cleanup -; -; Not for use directly. Needed by macros in pthread.h -; to return internal SEH code. -; -ptw32_get_exception_services_code +; pthread.def +; Last updated: $Date: 2002/02/18 03:16:55 $ + +; Currently unimplemented functions are commented out. + +;LIBRARY pthread + +EXPORTS +;pthread_atfork +pthread_attr_destroy +pthread_attr_getdetachstate +pthread_attr_getinheritsched +pthread_attr_getschedparam +pthread_attr_getschedpolicy +pthread_attr_getscope +pthread_attr_getstackaddr +pthread_attr_getstacksize +pthread_attr_init +pthread_attr_setdetachstate +pthread_attr_setinheritsched +pthread_attr_setschedparam +pthread_attr_setschedpolicy +pthread_attr_setscope +pthread_attr_setstackaddr +pthread_attr_setstacksize +pthread_cancel +; +; These two are implemented as macros in pthread.h +; +;pthread_cleanup_pop +;pthread_cleanup_push +; +pthread_condattr_destroy +pthread_condattr_getpshared +pthread_condattr_init +pthread_condattr_setpshared +pthread_cond_broadcast +pthread_cond_destroy +pthread_cond_init +pthread_cond_signal +pthread_cond_timedwait +pthread_cond_wait +pthread_create +pthread_detach +pthread_equal +pthread_exit +pthread_getconcurrency +pthread_getschedparam +pthread_getspecific +pthread_join +pthread_key_create +pthread_key_delete +;pthread_kill +pthread_mutexattr_destroy +;pthread_mutexattr_getprioceiling +;pthread_mutexattr_getprotocol +pthread_mutexattr_getpshared +pthread_mutexattr_gettype +pthread_mutexattr_init +;pthread_mutexattr_setprioceiling +;pthread_mutexattr_setprotocol +pthread_mutexattr_setpshared +pthread_mutexattr_settype +pthread_mutexattr_destroy +pthread_mutex_init +pthread_mutex_destroy +pthread_mutex_lock +pthread_mutex_trylock +pthread_mutex_timedlock +pthread_mutex_unlock +pthread_once +pthread_self +pthread_setcancelstate +pthread_setcanceltype +pthread_setconcurrency +pthread_setschedparam +pthread_setspecific +;pthread_sigmask +pthread_testcancel +; +; Scheduling +; +sched_get_priority_min +sched_get_priority_max +sched_getscheduler +sched_setscheduler +sched_yield +; +; Semaphores +; +sem_init +sem_destroy +sem_trywait +sem_wait +sem_timedwait +sem_post +sem_open +sem_close +sem_unlink +sem_getvalue +; +; This next one is a macro +;sched_rr_get_interval +; +; +; Read/Write Locks +; +pthread_rwlock_init +pthread_rwlock_destroy +pthread_rwlock_tryrdlock +pthread_rwlock_trywrlock +pthread_rwlock_rdlock +pthread_rwlock_wrlock +pthread_rwlock_unlock +; +; 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 +; +; Non-portable/compatibility with other implementations +; +pthread_delay_np +pthread_mutexattr_getkind_np +pthread_mutexattr_setkind_np +pthread_num_processors_np +; +; Non-portable local implementation only +; +pthread_getw32threadhandle_np +pthread_timechange_handler_np +pthreadCancelableWait +pthreadCancelableTimedWait +; +; For use when linking statically +; +pthread_win32_process_attach_np +pthread_win32_process_detach_np +pthread_win32_thread_attach_np +pthread_win32_thread_detach_np +; +; Needed if !defined(_MSC_VER) && !defined(__cplusplus) +; +ptw32_push_cleanup +ptw32_pop_cleanup +; +; Not for use directly. Needed by macros in pthread.h +; to return internal SEH code. +; +ptw32_get_exception_services_code diff --git a/pthread.h b/pthread.h index d19063b..29fef95 100644 --- a/pthread.h +++ b/pthread.h @@ -2,32 +2,32 @@ * * -------------------------------------------------------------------------- * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2002 Pthreads-win32 contributors + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2002 Pthreads-win32 contributors * - * Contact Email: rpj@ise.canberra.edu.au + * Contact Email: rpj@ise.canberra.edu.au * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 ) @@ -549,6 +549,10 @@ struct pthread_once_t_ #define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1) + +/* + * Mutex types. + */ enum { /* Compatibility with LinuxThreads */ @@ -1019,11 +1023,6 @@ int pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, int *kind); * Possibly supported by other POSIX threads implementations */ int pthread_delay_np (struct timespec * interval); - -/* - * Returns the number of CPUs available to the process. - */ -int pthread_getprocessors_np(int * count); int pthread_num_processors_np(void); /* @@ -1035,6 +1034,16 @@ int pthread_win32_process_detach_np(void); int pthread_win32_thread_attach_np(void); int pthread_win32_thread_detach_np(void); +/* + * 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. + */ +void * pthread_timechange_handler_np(void *); + #endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ #if PTW32_LEVEL >= PTW32_LEVEL_MAX diff --git a/pthread_attr_destroy.c b/pthread_attr_destroy.c new file mode 100644 index 0000000..7560fb2 --- /dev/null +++ b/pthread_attr_destroy.c @@ -0,0 +1,80 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_getdetachstate.c b/pthread_attr_getdetachstate.c new file mode 100644 index 0000000..d8467b1 --- /dev/null +++ b/pthread_attr_getdetachstate.c @@ -0,0 +1,89 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_getinheritsched.c b/pthread_attr_getinheritsched.c new file mode 100644 index 0000000..6d01cf3 --- /dev/null +++ b/pthread_attr_getinheritsched.c @@ -0,0 +1,52 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_getschedparam.c b/pthread_attr_getschedparam.c new file mode 100644 index 0000000..19451fc --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_getschedpolicy.c b/pthread_attr_getschedpolicy.c new file mode 100644 index 0000000..f76618c --- /dev/null +++ b/pthread_attr_getschedpolicy.c @@ -0,0 +1,62 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_getscope.c b/pthread_attr_getscope.c new file mode 100644 index 0000000..06bb901 --- /dev/null +++ b/pthread_attr_getscope.c @@ -0,0 +1,55 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_getstackaddr.c b/pthread_attr_getstackaddr.c new file mode 100644 index 0000000..410cc62 --- /dev/null +++ b/pthread_attr_getstackaddr.c @@ -0,0 +1,99 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_getstacksize.c b/pthread_attr_getstacksize.c new file mode 100644 index 0000000..f9a584b --- /dev/null +++ b/pthread_attr_getstacksize.c @@ -0,0 +1,102 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_init.c b/pthread_attr_init.c new file mode 100644 index 0000000..efc3683 --- /dev/null +++ b/pthread_attr_init.c @@ -0,0 +1,118 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_setdetachstate.c b/pthread_attr_setdetachstate.c new file mode 100644 index 0000000..19de87b --- /dev/null +++ b/pthread_attr_setdetachstate.c @@ -0,0 +1,93 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_setinheritsched.c b/pthread_attr_setinheritsched.c new file mode 100644 index 0000000..1653351 --- /dev/null +++ b/pthread_attr_setinheritsched.c @@ -0,0 +1,58 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_setschedparam.c b/pthread_attr_setschedparam.c new file mode 100644 index 0000000..8ad787a --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_setschedpolicy.c b/pthread_attr_setschedpolicy.c new file mode 100644 index 0000000..1614f00 --- /dev/null +++ b/pthread_attr_setschedpolicy.c @@ -0,0 +1,56 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_setscope.c b/pthread_attr_setscope.c new file mode 100644 index 0000000..8d8f2e5 --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_setstackaddr.c b/pthread_attr_setstackaddr.c new file mode 100644 index 0000000..4318e32 --- /dev/null +++ b/pthread_attr_setstackaddr.c @@ -0,0 +1,99 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_attr_setstacksize.c b/pthread_attr_setstacksize.c new file mode 100644 index 0000000..61faa66 --- /dev/null +++ b/pthread_attr_setstacksize.c @@ -0,0 +1,112 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_barrier_destroy.c b/pthread_barrier_destroy.c new file mode 100644 index 0000000..bae8c20 --- /dev/null +++ b/pthread_barrier_destroy.c @@ -0,0 +1,70 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_barrier_init.c b/pthread_barrier_init.c new file mode 100644 index 0000000..44b96fc --- /dev/null +++ b/pthread_barrier_init.c @@ -0,0 +1,84 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_barrier_wait.c b/pthread_barrier_wait.c new file mode 100644 index 0000000..e06e87d --- /dev/null +++ b/pthread_barrier_wait.c @@ -0,0 +1,114 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 + { + BOOL switchCancelState; + int oldCancelState; + pthread_t self = pthread_self(); + + /* + * This routine is not a cancelation point, so temporarily + * prevent sem_wait() from being one. + * PTHREAD_CANCEL_ASYNCHRONOUS threads can still be canceled. + */ + switchCancelState = (self->cancelType == PTHREAD_CANCEL_DEFERRED && + 0 == pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, + &oldCancelState)); + + result = sem_wait(&(b->semBarrierBreeched[step])); + + if (switchCancelState) + { + (void) pthread_setcancelstate(oldCancelState, NULL); + } + } + + /* + * 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/pthread_barrierattr_destroy.c b/pthread_barrierattr_destroy.c new file mode 100644 index 0000000..1d0c717 --- /dev/null +++ b/pthread_barrierattr_destroy.c @@ -0,0 +1,84 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_barrierattr_getpshared.c b/pthread_barrierattr_getpshared.c new file mode 100644 index 0000000..13e7373 --- /dev/null +++ b/pthread_barrierattr_getpshared.c @@ -0,0 +1,97 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_barrierattr_init.c b/pthread_barrierattr_init.c new file mode 100644 index 0000000..0dbe113 --- /dev/null +++ b/pthread_barrierattr_init.c @@ -0,0 +1,86 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_barrierattr_setpshared.c b/pthread_barrierattr_setpshared.c new file mode 100644 index 0000000..e963cb7 --- /dev/null +++ b/pthread_barrierattr_setpshared.c @@ -0,0 +1,120 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_cancel.c b/pthread_cancel.c new file mode 100644 index 0000000..7a94d8d --- /dev/null +++ b/pthread_cancel.c @@ -0,0 +1,180 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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(_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(PTW32_PROGCTR) +#error Module contains CPU-specific code; modify and recompile. +#endif + +static INLINE void +ptw32_cancel_self(void) +{ + ptw32_throw(PTW32_EPS_CANCEL); + + /* Never reached */ +} + +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; + + if (thread == NULL ) + { + return ESRCH; + } + + result = 0; + if ((self = pthread_self()) == 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); + + /* + * Lock for async-cancel safety. + */ + (void) pthread_mutex_lock(&thread->cancelLock); + + if (thread->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS + && thread->cancelState == PTHREAD_CANCEL_ENABLE + && thread->state < PThreadStateCanceling ) + { + if (cancel_self) + { + thread->state = PThreadStateCanceling; + thread->cancelState = PTHREAD_CANCEL_DISABLE; + + (void) pthread_mutex_unlock(&thread->cancelLock); + ptw32_throw(PTW32_EPS_CANCEL); + + /* Never reached */ + } + else + { + HANDLE threadH = thread->threadH; + + SuspendThread(threadH); + + if (WaitForSingleObject(threadH, 0) == WAIT_TIMEOUT ) + { + CONTEXT context; + + thread->state = PThreadStateCanceling; + thread->cancelState = PTHREAD_CANCEL_DISABLE; + context.ContextFlags = CONTEXT_CONTROL; + GetThreadContext(threadH, &context); + PTW32_PROGCTR(context) = (DWORD) ptw32_cancel_self; + SetThreadContext(threadH, &context); + (void) pthread_mutex_unlock(&thread->cancelLock); + ResumeThread(threadH); + } + } + } + else + { + /* + * Set for deferred cancellation. + */ + if ( thread->state >= PThreadStateCanceling + || !SetEvent (thread->cancelEvent)) + { + result = ESRCH; + } + + (void) pthread_mutex_unlock(&thread->cancelLock); + } + + return (result); +} + diff --git a/pthread_cond_destroy.c b/pthread_cond_destroy.c new file mode 100644 index 0000000..f5102ac --- /dev/null +++ b/pthread_cond_destroy.c @@ -0,0 +1,246 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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) + { + 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 */ + + EnterCriticalSection(&ptw32_cond_list_lock); + + 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; + } + + LeaveCriticalSection(&ptw32_cond_list_lock); + + (void) free(cv); + } + } + 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/pthread_cond_init.c b/pthread_cond_init.c new file mode 100644 index 0000000..446fcc1 --- /dev/null +++ b/pthread_cond_init.c @@ -0,0 +1,164 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_cond_signal.c b/pthread_cond_signal.c new file mode 100644 index 0000000..10bea7e --- /dev/null +++ b/pthread_cond_signal.c @@ -0,0 +1,355 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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; + * } + * ------------------------------------------------------------- + * + */ + +#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 ) + { + if (sem_wait( &(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 '1'(TRUE) unblockAll arg means unblock ALL waiters. + */ + return (ptw32_cond_unblock(cond, 1)); + +} /* pthread_cond_broadcast */ diff --git a/pthread_cond_wait.c b/pthread_cond_wait.c new file mode 100644 index 0000000..d1f5155 --- /dev/null +++ b/pthread_cond_wait.c @@ -0,0 +1,527 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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; + * } + * ------------------------------------------------------------- + * + */ + +#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; + int signaled; +} 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 nSignalsWasLeft; + int nWaitersWasGone = 0; /* Initialised to quell warnings. */ + 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) ) + { + if ( !cleanup_args->signaled ) + { + if ( 0 != cv->nWaitersBlocked ) + { + (cv->nWaitersBlocked)--; + } + else + { + (cv->nWaitersGone)++; + } + } + if ( 0 == --(cv->nWaitersToUnblock) ) + { + if ( 0 != cv->nWaitersBlocked ) + { + 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; + } + nSignalsWasLeft = 0; + } + else if ( 0 != (nWaitersWasGone = cv->nWaitersGone) ) + { + cv->nWaitersGone = 0; + } + } + } + else if ( INT_MAX/2 == ++(cv->nWaitersGone) ) + { + if (sem_wait( &(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 ( 0 != nWaitersWasGone ) + { + // sem_adjust( &(cv->semBlockQueue), -nWaitersWasGone ); + while ( nWaitersWasGone-- ) + { + if (sem_wait( &(cv->semBlockQueue)) != 0 ) + { + *resultPtr = errno; + return; + } + } + } + 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; + + 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; + /* + * If we're canceled, or the cancelable wait fails for any reason, + * including a timeout, then tell the cleanup routine that we + * have not been signaled. + */ + cleanup_args.signaled = 0; + +#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; + } + } + + /* + * Not executed if we're canceled. Signaled is false if we timed out. + */ + cleanup_args.signaled = (result == 0); + + /* + * 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/pthread_condattr_destroy.c b/pthread_condattr_destroy.c new file mode 100644 index 0000000..1be0daf --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_condattr_getpshared.c b/pthread_condattr_getpshared.c new file mode 100644 index 0000000..6401a09 --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_condattr_init.c b/pthread_condattr_init.c new file mode 100644 index 0000000..4162cfc --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_condattr_setpshared.c b/pthread_condattr_setpshared.c new file mode 100644 index 0000000..86b745c --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_delay_np.c b/pthread_delay_np.c new file mode 100644 index 0000000..1ee7498 --- /dev/null +++ b/pthread_delay_np.c @@ -0,0 +1,155 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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; + + 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 (0 > (wait_time = secs_in_millisecs + millisecs)) + { + return EINVAL; + } + + if (NULL == (self = pthread_self())) + { + return ENOMEM; + } + + if (self->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(self->cancelEvent, wait_time)) ) + { + /* + * Canceling! + */ + (void) pthread_mutex_lock(&self->cancelLock); + if (self->state < PThreadStateCanceling) + { + self->state = PThreadStateCanceling; + self->cancelState = PTHREAD_CANCEL_DISABLE; + (void) pthread_mutex_unlock(&self->cancelLock); + + ptw32_throw(PTW32_EPS_CANCEL); + } + + (void) pthread_mutex_unlock(&self->cancelLock); + return ESRCH; + } + else if (status != WAIT_TIMEOUT) + { + return EINVAL; + } + } + else + { + Sleep( wait_time ); + } + + return (0); +} diff --git a/pthread_detach.c b/pthread_detach.c new file mode 100644 index 0000000..423997d --- /dev/null +++ b/pthread_detach.c @@ -0,0 +1,88 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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_detach (pthread_t tid) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function detaches the given thread. + * + * PARAMETERS + * thread + * an instance of a pthread_t + * + * + * DESCRIPTION + * This function detaches the given thread. You may + * detach the main thread or to detach a joinable thread + * (You should have used pthread_attr_t to create the + * thread as detached!) + * NOTE: detached threads cannot be joined nor canceled; + * 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; + + if (tid == NULL || + tid->detachState == PTHREAD_CREATE_DETACHED) + { + + result = EINVAL; + + } + else + { + result = 0; + tid->detachState = PTHREAD_CREATE_DETACHED; + } + + return (result); + +} /* pthread_detach */ diff --git a/pthread_getschedparam.c b/pthread_getschedparam.c new file mode 100644 index 0000000..e796a88 --- /dev/null +++ b/pthread_getschedparam.c @@ -0,0 +1,74 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 prio; + + /* Validate the thread id. */ + if (thread == NULL || thread->threadH == 0) + { + return EINVAL; + } + + /* + * 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; + + /* Fill out the sched_param structure. */ + prio = GetThreadPriority(thread->threadH); + if (prio == THREAD_PRIORITY_ERROR_RETURN) + { + return EINVAL; + } + + param->sched_priority = prio; + return 0; +} diff --git a/pthread_getspecific.c b/pthread_getspecific.c new file mode 100644 index 0000000..a8da291 --- /dev/null +++ b/pthread_getspecific.c @@ -0,0 +1,75 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 + * + * ------------------------------------------------------ + */ +{ + int lasterror = GetLastError(); + int lastWSAerror = WSAGetLastError(); + + void *ptr = TlsGetValue (key->key); + + SetLastError( lasterror ); + WSASetLastError( lastWSAerror ); + + return ptr; +} diff --git a/pthread_getw32threadhandle_np.c b/pthread_getw32threadhandle_np.c new file mode 100644 index 0000000..ebd9453 --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 (thread != NULL) ? (thread->threadH) : 0; +} diff --git a/pthread_join.c b/pthread_join.c new file mode 100644 index 0000000..3c076e0 --- /dev/null +++ b/pthread_join.c @@ -0,0 +1,152 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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_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 = 0; + pthread_t self; + + self = pthread_self (); + if (self == NULL) + { + return ENOENT; + } + + if (pthread_equal (self, thread) != 0) + { + result = EDEADLK; + } + else if (thread->detachState == PTHREAD_CREATE_DETACHED) + { + result = EINVAL; + } + 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(thread->threadH); + + if (result == 0) + { + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + + if (value_ptr != NULL + && !GetExitCodeThread (thread->threadH, (LPDWORD) value_ptr)) + { + result = ESRCH; + } + else + { + /* + * The result of making multiple simultaneous calls to + * pthread_join() specifying the same target is undefined. + */ + ptw32_threadDestroy (thread); + } + +#else /* __MINGW32__ && ! __MSVCRT__ */ + + /* + * If using CRTDLL, the thread may have exited, and endthread + * will have closed the handle. + */ + if (value_ptr != NULL) + { + *value_ptr = thread->exitStatus; + } + + /* + * The result of making multiple simultaneous calls to + * pthread_join() specifying the same target is undefined. + */ + ptw32_threadDestroy (thread); + +#endif /* __MINGW32__ && ! __MSVCRT__ */ + + } + else + { + result = ESRCH; + } + } + + return (result); + +} /* pthread_join */ diff --git a/pthread_key_create.c b/pthread_key_create.c new file mode 100644 index 0000000..8ec46d7 --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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->threadsLock = PTHREAD_MUTEX_INITIALIZER; + newkey->destructor = destructor; + } + + *key = newkey; + + return (result); +} diff --git a/pthread_key_delete.c b/pthread_key_delete.c new file mode 100644 index 0000000..0fb3fbb --- /dev/null +++ b/pthread_key_delete.c @@ -0,0 +1,127 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 spcific 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 spcific 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->threadsLock)) == 0) + { + /* + * Run through all Thread<-->Key associations + * for this key. + * If the pthread_t still exits (ie the assoc->thread + * is not NULL) then leave the assoc for the thread to + * destroy. + * Notes: + * If assoc->thread is NULL, then the associated thread + * is no longer referencing this assoc. + * The association is only referenced + * by this key and must be released; otherwise + * the assoc will be destroyed when the thread is destroyed. + */ + ThreadKeyAssoc *assoc; + + assoc = (ThreadKeyAssoc *) key->threads; + + while (assoc != NULL) + { + if (pthread_mutex_lock (&(assoc->lock)) == 0) + { + ThreadKeyAssoc *next; + + assoc->key = NULL; + next = assoc->nextThread; + assoc->nextThread = NULL; + + pthread_mutex_unlock (&(assoc->lock)); + + ptw32_tkAssocDestroy (assoc); + + assoc = next; + } + } + pthread_mutex_unlock (&(key->threadsLock)); + } + + TlsFree (key->key); + if (key->destructor != NULL) + { + pthread_mutex_destroy (&(key->threadsLock)); + } + +#if defined( _DEBUG ) + memset ((char *) key, 0, sizeof (*key)); +#endif + free (key); + } + + return (result); +} diff --git a/pthread_mutex_destroy.c b/pthread_mutex_destroy.c new file mode 100644 index 0000000..c9c1426 --- /dev/null +++ b/pthread_mutex_destroy.c @@ -0,0 +1,134 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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; + + if (mutex == NULL + || *mutex == NULL) + { + return EINVAL; + } + + /* + * Check to see if we have something to delete. + */ + if (*mutex != PTHREAD_MUTEX_INITIALIZER) + { + mx = *mutex; + + result = pthread_mutex_trylock(&mx); + + /* + * The mutex type may not be RECURSIVE therefore trylock may return EBUSY if + * we already own the mutex. Here we are assuming that it's OK to destroy + * a mutex that we own and have locked recursively. Is this correct? + * + * For FAST mutexes we record the owner as ANONYMOUS for speed. In this + * case we assume that the thread calling pthread_mutex_destroy() is the + * owner, if the mutex is owned at all. + */ + if (result == 0 + || mx->ownerThread == (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS + || pthread_equal( mx->ownerThread, pthread_self() ) ) + { + /* + * 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. + */ + *mutex = NULL; + + result = pthread_mutex_unlock(&mx); + + if (result == 0) + { + (void) sem_destroy( &mx->wait_sema ); + DeleteCriticalSection( &mx->wait_cs ); + free(mx); + } + else + { + /* + * Restore the mutex before we return the error. + */ + *mutex = mx; + } + } + } + else + { + /* + * See notes in ptw32_mutex_check_need_init() above also. + */ + EnterCriticalSection(&ptw32_mutex_test_init_lock); + + /* + * Check again. + */ + if (*mutex == PTHREAD_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/pthread_mutex_init.c b/pthread_mutex_init.c new file mode 100644 index 0000000..7076c22 --- /dev/null +++ b/pthread_mutex_init.c @@ -0,0 +1,107 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 + + /* + * 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 = PTW32_MUTEX_LOCK_IDX_INIT; + mx->recursive_count = 0; + mx->kind = (attr == NULL || *attr == NULL + ? PTHREAD_MUTEX_DEFAULT + : (*attr)->kind); + mx->ownerThread = NULL; + + if ( 0 != sem_init( &mx->wait_sema, 0, 0 )) + { + result = EAGAIN; + free(mx); + mx = NULL; + } + else + { + InitializeCriticalSection( &mx->wait_cs ); + } + } + + *mutex = mx; + + return(result); +} diff --git a/pthread_mutex_lock.c b/pthread_mutex_lock.c new file mode 100644 index 0000000..5ba97dc --- /dev/null +++ b/pthread_mutex_lock.c @@ -0,0 +1,105 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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_lock(pthread_mutex_t *mutex) +{ + int result = 0; + pthread_mutex_t mx; + + + if (mutex == NULL || *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_MUTEX_INITIALIZER) + { + if ((result = ptw32_mutex_check_need_init(mutex)) != 0) + { + return(result); + } + } + + mx = *mutex; + + if( 0 == InterlockedIncrement( &mx->lock_idx ) ) + { + mx->recursive_count = 1; + mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP + ? pthread_self() + : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); + } + else + { + if( mx->kind != PTHREAD_MUTEX_FAST_NP && + pthread_equal( mx->ownerThread, pthread_self() ) ) + { + (void) InterlockedDecrement( &mx->lock_idx ); + + if( mx->kind == PTHREAD_MUTEX_RECURSIVE_NP ) + { + mx->recursive_count++; + } + else + { + result = EDEADLK; + } + } + else + { + if ((result = sem_wait( &mx->wait_sema )) == 0) + { + mx->recursive_count = 1; + mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP + ? pthread_self() + : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); + } + } + } + + return(result); +} diff --git a/pthread_mutex_timedlock.c b/pthread_mutex_timedlock.c new file mode 100644 index 0000000..ec1caa9 --- /dev/null +++ b/pthread_mutex_timedlock.c @@ -0,0 +1,356 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef _UWIN +# include +#endif +#ifndef NEED_FTIME +#include +#endif +#include "pthread.h" +#include "implement.h" + + +static INLINE int +ptw32_timed_semwait (sem_t * sem, const struct timespec * abstime) + /* + * ------------------------------------------------------ + * 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 or until abstime. + * 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. + * + * RESULTS + * 2 abstime has passed already + * 1 abstime timed out while waiting + * 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; + +#ifdef NEED_FTIME + + struct timespec currSysTime; + +#else /* NEED_FTIME */ + + struct _timeb currSysTime; + +#endif /* NEED_FTIME */ + + const DWORD NANOSEC_PER_MILLISEC = 1000000; + const DWORD MILLISEC_PER_SEC = 1000; + DWORD milliseconds; + DWORD status; + + if (sem == NULL) + { + result = EINVAL; + } + else + { + if (abstime == NULL) + { + milliseconds = INFINITE; + } + else + { + /* + * Calculate timeout as milliseconds from current system time. + */ + + /* get current system time */ + +#ifdef NEED_FTIME + + { + FILETIME ft; + SYSTEMTIME st; + + GetSystemTime(&st); + SystemTimeToFileTime(&st, &ft); + /* + * GetSystemTimeAsFileTime(&ft); would be faster, + * but it does not exist on WinCE + */ + + ptw32_filetime_to_timespec(&ft, &currSysTime); + } + + /* + * subtract current system time from abstime + */ + milliseconds = (abstime->tv_sec - currSysTime.tv_sec) * MILLISEC_PER_SEC; + milliseconds += ((abstime->tv_nsec - currSysTime.tv_nsec) + + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC; + +#else /* NEED_FTIME */ + _ftime(&currSysTime); + + /* + * subtract current system time from abstime + */ + milliseconds = (abstime->tv_sec - currSysTime.time) * MILLISEC_PER_SEC; + milliseconds += ((abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC) + - currSysTime.millitm; + +#endif /* NEED_FTIME */ + + + if (((int) milliseconds) < 0) + { + return 2; + } + } + +#ifdef NEED_SEM + + status = WaitForSingleObject( (*sem)->event, milliseconds ); + +#else /* NEED_SEM */ + + status = WaitForSingleObject( (*sem)->sem, milliseconds ); + +#endif + + if (status == WAIT_OBJECT_0) + { + +#ifdef NEED_SEM + + ptw32_decrease_semaphore(sem); + +#endif /* NEED_SEM */ + + return 0; + } + else if (status == WAIT_TIMEOUT) + { + return 1; + } + else + { + result = EINVAL; + } + } + + if (result != 0) + { + errno = result; + return -1; + } + + return 0; + +} /* ptw32_timed_semwait */ + + +int +pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime) +{ + int result = 0; + pthread_mutex_t mx; + +#ifdef NEED_SEM + errno = ENOTSUP; + return -1; +#endif + + if (mutex == NULL || *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_MUTEX_INITIALIZER) + { + if ((result = ptw32_mutex_check_need_init(mutex)) != 0) + { + return(result); + } + } + + mx = *mutex; + + if( 0 == InterlockedIncrement( &mx->lock_idx ) ) + { + mx->recursive_count = 1; + mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP + ? pthread_self() + : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); + } + else + { + if( mx->kind != PTHREAD_MUTEX_FAST_NP && + pthread_equal( mx->ownerThread, pthread_self() ) ) + { + (void) InterlockedDecrement( &mx->lock_idx ); + + if( mx->kind == PTHREAD_MUTEX_RECURSIVE_NP ) + { + mx->recursive_count++; + } + else + { + result = EDEADLK; + } + } + else + { + if (abstime == NULL) + { + result = EINVAL; + } + else + { + switch (ptw32_timed_semwait( &mx->wait_sema, abstime )) + { + case 0: /* We got the mutex. */ + { + mx->recursive_count = 1; + mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP + ? pthread_self() + : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); + break; + } + case 1: /* Timedout, try a second grab. */ + { + EnterCriticalSection(&mx->wait_cs); + + /* + * If we timeout, it is up to us to adjust lock_idx to say + * we're no longer waiting. If the mutex was also unlocked + * while we were timing out, and we simply return ETIMEDOUT, + * then wait_sema would be left in a state that is not consistent + * with the state of lock_idx. + * + * We must check to see if wait_sema has just been posted + * but we can't just call sem_getvalue - we must compete for + * the semaphore using sem_trywait(), otherwise we would need + * additional critical sections elsewhere, which would make the + * logic too inefficient. + * + * If sem_trywait returns EAGAIN then either wait_sema + * was given directly to another waiting thread or + * another thread has called sem_*wait() before us and + * taken the lock. Then we MUST decrement lock_idx and return + * ETIMEDOUT. + * + * Otherwise we MUST return success (because we have effectively + * acquired the lock that would have been ours had we not + * timed out), and NOT decrement lock_idx. + * + * We can almost guarrantee that EAGAIN is the only + * possible error, so no need to test errno. + */ + + if ( -1 == sem_trywait( &mx->wait_sema ) ) + { + (void) InterlockedDecrement( &mx->lock_idx ); + result = ETIMEDOUT; + } + + LeaveCriticalSection(&mx->wait_cs); + break; + } + case 2: /* abstime passed before we started to wait. */ + { + /* + * If we timeout, it is up to us to adjust lock_idx to say + * we're no longer waiting. + * + * The owner thread may still have posted wait_sema thinking + * we were waiting. I believe we must check but then NOT do any + * programmed work if we have acquired the mutex because + * we don't how long ago abstime was. We MUST just release it + * immediately. + */ + EnterCriticalSection(&mx->wait_cs); + + result = ETIMEDOUT; + + if ( -1 == sem_trywait( &mx->wait_sema ) ) + { + (void) InterlockedDecrement( &mx->lock_idx ); + } + else + { + if ( InterlockedDecrement( &mx->lock_idx ) >= 0 ) + { + /* Someone else is waiting on that mutex */ + if ( sem_post( &mx->wait_sema ) != 0 ) + { + result = errno; + } + } + } + + LeaveCriticalSection(&mx->wait_cs); + break; + } + default: + { + result = errno; + break; + } + } + } + } + } + + return(result); +} diff --git a/pthread_mutex_trylock.c b/pthread_mutex_trylock.c new file mode 100644 index 0000000..66eb96e --- /dev/null +++ b/pthread_mutex_trylock.c @@ -0,0 +1,99 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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; + + if (mutex == NULL || *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_MUTEX_INITIALIZER) + { + result = ptw32_mutex_check_need_init(mutex); + } + + mx = *mutex; + + if (result == 0) + { + if ( (PTW32_INTERLOCKED_LONG) PTW32_MUTEX_LOCK_IDX_INIT == + ptw32_interlocked_compare_exchange((PTW32_INTERLOCKED_LPLONG) &mx->lock_idx, + (PTW32_INTERLOCKED_LONG) 0, + (PTW32_INTERLOCKED_LONG) PTW32_MUTEX_LOCK_IDX_INIT)) + { + mx->recursive_count = 1; + mx->ownerThread = (mx->kind != PTHREAD_MUTEX_FAST_NP + ? pthread_self() + : (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS); + } + else + { + if( mx->kind != PTHREAD_MUTEX_FAST_NP && + pthread_equal( mx->ownerThread, pthread_self() ) ) + { + if( mx->kind == PTHREAD_MUTEX_RECURSIVE_NP ) + { + mx->recursive_count++; + } + else + { + result = EDEADLK; + } + } + else + { + result = EBUSY; + } + } + } + + return(result); +} diff --git a/pthread_mutex_unlock.c b/pthread_mutex_unlock.c new file mode 100644 index 0000000..0c1ea5f --- /dev/null +++ b/pthread_mutex_unlock.c @@ -0,0 +1,93 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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; + + if (mutex == NULL || *mutex == NULL) + { + return EINVAL; + } + + 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_MUTEX_INITIALIZER) + { + if (mx->ownerThread == (pthread_t) PTW32_MUTEX_OWNER_ANONYMOUS + || pthread_equal(mx->ownerThread, pthread_self())) + { + if( mx->kind != PTHREAD_MUTEX_RECURSIVE_NP + || 0 == --mx->recursive_count ) + { + mx->ownerThread = NULL; + EnterCriticalSection( &mx->wait_cs ); + + if( InterlockedDecrement( &mx->lock_idx ) >= 0 ) + { + /* Someone is waiting on that mutex */ + if (sem_post( &mx->wait_sema ) != 0) + { + result = errno; + } + } + + LeaveCriticalSection( &mx->wait_cs ); + } + } + else + { + result = EPERM; + } + } + else + { + result = EINVAL; + } + + return(result); +} diff --git a/pthread_mutexattr_destroy.c b/pthread_mutexattr_destroy.c new file mode 100644 index 0000000..d2b9865 --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_mutexattr_getkind_np.c b/pthread_mutexattr_getkind_np.c new file mode 100644 index 0000000..cfa27b1 --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_mutexattr_getpshared.c b/pthread_mutexattr_getpshared.c new file mode 100644 index 0000000..8a5c50b --- /dev/null +++ b/pthread_mutexattr_getpshared.c @@ -0,0 +1,97 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_mutexattr_gettype.c b/pthread_mutexattr_gettype.c new file mode 100644 index 0000000..c4232b0 --- /dev/null +++ b/pthread_mutexattr_gettype.c @@ -0,0 +1,57 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_mutexattr_init.c b/pthread_mutexattr_init.c new file mode 100644 index 0000000..fa2da3e --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_mutexattr_setkind_np.c b/pthread_mutexattr_setkind_np.c new file mode 100644 index 0000000..9abaacd --- /dev/null +++ b/pthread_mutexattr_setkind_np.c @@ -0,0 +1,45 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_mutexattr_setpshared.c b/pthread_mutexattr_setpshared.c new file mode 100644 index 0000000..d412573 --- /dev/null +++ b/pthread_mutexattr_setpshared.c @@ -0,0 +1,120 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_mutexattr_settype.c b/pthread_mutexattr_settype.c new file mode 100644 index 0000000..a8b3511 --- /dev/null +++ b/pthread_mutexattr_settype.c @@ -0,0 +1,144 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_num_processors_np.c b/pthread_num_processors_np.c new file mode 100644 index 0000000..8d1deec --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_rwlock_destroy.c b/pthread_rwlock_destroy.c new file mode 100644 index 0000000..96feb0f --- /dev/null +++ b/pthread_rwlock_destroy.c @@ -0,0 +1,140 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#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/pthread_rwlock_init.c b/pthread_rwlock_init.c new file mode 100644 index 0000000..6affbce --- /dev/null +++ b/pthread_rwlock_init.c @@ -0,0 +1,109 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#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/pthread_rwlock_rdlock.c b/pthread_rwlock_rdlock.c new file mode 100644 index 0000000..a23a80d --- /dev/null +++ b/pthread_rwlock_rdlock.c @@ -0,0 +1,101 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#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/pthread_rwlock_tryrdlock.c b/pthread_rwlock_tryrdlock.c new file mode 100644 index 0000000..d3a6cf2 --- /dev/null +++ b/pthread_rwlock_tryrdlock.c @@ -0,0 +1,101 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#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/pthread_rwlock_trywrlock.c b/pthread_rwlock_trywrlock.c new file mode 100644 index 0000000..48bae9f --- /dev/null +++ b/pthread_rwlock_trywrlock.c @@ -0,0 +1,120 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#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/pthread_rwlock_unlock.c b/pthread_rwlock_unlock.c new file mode 100644 index 0000000..1281f01 --- /dev/null +++ b/pthread_rwlock_unlock.c @@ -0,0 +1,93 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#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/pthread_rwlock_wrlock.c b/pthread_rwlock_wrlock.c new file mode 100644 index 0000000..6e85bf1 --- /dev/null +++ b/pthread_rwlock_wrlock.c @@ -0,0 +1,146 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#include "pthread.h" +#include "implement.h" + +static 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)); +} + +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/pthread_rwlockattr_destroy.c b/pthread_rwlockattr_destroy.c new file mode 100644 index 0000000..f1c1d2a --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#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/pthread_rwlockattr_getpshared.c b/pthread_rwlockattr_getpshared.c new file mode 100644 index 0000000..295caf5 --- /dev/null +++ b/pthread_rwlockattr_getpshared.c @@ -0,0 +1,99 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#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/pthread_rwlockattr_init.c b/pthread_rwlockattr_init.c new file mode 100644 index 0000000..f2e2823 --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#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/pthread_rwlockattr_setpshared.c b/pthread_rwlockattr_setpshared.c new file mode 100644 index 0000000..128d2be --- /dev/null +++ b/pthread_rwlockattr_setpshared.c @@ -0,0 +1,122 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include + +#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/pthread_setcancelstate.c b/pthread_setcancelstate.c new file mode 100644 index 0000000..dcf6537 --- /dev/null +++ b/pthread_setcancelstate.c @@ -0,0 +1,125 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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(); + + if (self == NULL + || (state != PTHREAD_CANCEL_ENABLE + && state != PTHREAD_CANCEL_DISABLE)) + { + return EINVAL; + } + + /* + * Lock for async-cancel safety. + */ + (void) pthread_mutex_lock(&self->cancelLock); + + if (oldstate != NULL) + { + *oldstate = self->cancelState; + } + + self->cancelState = state; + + /* + * Check if there is a pending asynchronous cancel + */ + if (state == PTHREAD_CANCEL_ENABLE + && self->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS + && WaitForSingleObject(self->cancelEvent, 0) == WAIT_OBJECT_0) + { + self->state = PThreadStateCanceling; + self->cancelState = PTHREAD_CANCEL_DISABLE; + ResetEvent(self->cancelEvent); + (void) pthread_mutex_unlock(&self->cancelLock); + ptw32_throw(PTW32_EPS_CANCEL); + + /* Never reached */ + } + + (void) pthread_mutex_unlock(&self->cancelLock); + + return (result); + +} /* pthread_setcancelstate */ + diff --git a/pthread_setcanceltype.c b/pthread_setcanceltype.c new file mode 100644 index 0000000..fc0f259 --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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(); + + if (self == NULL + || (type != PTHREAD_CANCEL_DEFERRED + && type != PTHREAD_CANCEL_ASYNCHRONOUS)) + { + return EINVAL; + } + + /* + * Lock for async-cancel safety. + */ + (void) pthread_mutex_lock(&self->cancelLock); + + if (oldtype != NULL) + { + *oldtype = self->cancelType; + } + + self->cancelType = type; + + /* + * Check if there is a pending asynchronous cancel + */ + if (self->cancelState == PTHREAD_CANCEL_ENABLE + && type == PTHREAD_CANCEL_ASYNCHRONOUS + && WaitForSingleObject(self->cancelEvent, 0) == WAIT_OBJECT_0) + { + self->state = PThreadStateCanceling; + self->cancelState = PTHREAD_CANCEL_DISABLE; + ResetEvent(self->cancelEvent); + (void) pthread_mutex_unlock(&self->cancelLock); + ptw32_throw(PTW32_EPS_CANCEL); + + /* Never reached */ + } + + (void) pthread_mutex_unlock(&self->cancelLock); + + return (result); + +} /* pthread_setcanceltype */ + diff --git a/pthread_setschedparam.c b/pthread_setschedparam.c new file mode 100644 index 0000000..2e795b9 --- /dev/null +++ b/pthread_setschedparam.c @@ -0,0 +1,78 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 prio; + + /* Validate the thread id. */ + if (thread == NULL || thread->threadH == 0) + { + return EINVAL; + } + + /* 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; + } + + prio = param->sched_priority; + + /* Validate priority level. */ + if (prio < sched_get_priority_min(policy) || + prio > sched_get_priority_max(policy)) + { + return EINVAL; + } + + /* This is practically guaranteed to return TRUE. */ + (void) SetThreadPriority(thread->threadH, prio); + + return 0; +} diff --git a/pthread_setspecific.c b/pthread_setspecific.c new file mode 100644 index 0000000..37ff975 --- /dev/null +++ b/pthread_setspecific.c @@ -0,0 +1,151 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 == NULL) + { + return ENOENT; + } + } + else + { + /* + * Resolve catch-22 of registering thread with threadSelf + * key + */ + self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey); + if (self == NULL) + { + self = (pthread_t) value; + } + } + + result = 0; + + if (key != NULL) + { + ThreadKeyAssoc *assoc; + + if (self != 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. + */ + assoc = (ThreadKeyAssoc *) self->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 (&assoc, self, key); + } + } + + if (result == 0) + { + if ( ! TlsSetValue (key->key, (LPVOID) value)) + { + result = EAGAIN; + } + } + } + + return (result); +} /* pthread_setspecific */ diff --git a/pthread_spin_destroy.c b/pthread_spin_destroy.c new file mode 100644 index 0000000..1f61930 --- /dev/null +++ b/pthread_spin_destroy.c @@ -0,0 +1,102 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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; + + if (lock == NULL || *lock == NULL) + { + return EINVAL; + } + + if ((s = *lock) != PTHREAD_SPINLOCK_INITIALIZER) + { + if (s->interlock == PTW32_SPIN_USE_MUTEX) + { + return pthread_mutex_destroy(&(s->u.mutex)); + } + + 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)) + { + return 0; + } + + return EINVAL; + } + else + { + int result = 0; + + /* + * 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/pthread_spin_init.c b/pthread_spin_init.c new file mode 100644 index 0000000..0d95b54 --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 + + /* + * 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/pthread_spin_lock.c b/pthread_spin_lock.c new file mode 100644 index 0000000..d3355d1 --- /dev/null +++ b/pthread_spin_lock.c @@ -0,0 +1,77 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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" + + +/* + * NOTE: For speed, these routines don't check if "lock" is valid. + */ +int +pthread_spin_lock(pthread_spinlock_t *lock) +{ + register pthread_spinlock_t s; + + 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/pthread_spin_trylock.c b/pthread_spin_trylock.c new file mode 100644 index 0000000..39b7fd3 --- /dev/null +++ b/pthread_spin_trylock.c @@ -0,0 +1,69 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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" + + +/* + * NOTE: For speed, these routines don't check if "lock" is valid. + */ +int +pthread_spin_trylock(pthread_spinlock_t *lock) +{ + pthread_spinlock_t s = *lock; + + if (s == PTHREAD_SPINLOCK_INITIALIZER) + { + int result; + + if ((result = ptw32_spinlock_check_need_init(lock)) != 0) + { + return(result); + } + } + + 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/pthread_spin_unlock.c b/pthread_spin_unlock.c new file mode 100644 index 0000000..30c11d4 --- /dev/null +++ b/pthread_spin_unlock.c @@ -0,0 +1,64 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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" + + +/* + * NOTE: For speed, these routines don't check if "lock" is valid. + */ +int +pthread_spin_unlock(pthread_spinlock_t *lock) +{ + register pthread_spinlock_t 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/pthread_testcancel.c b/pthread_testcancel.c new file mode 100644 index 0000000..2ba0a2c --- /dev/null +++ b/pthread_testcancel.c @@ -0,0 +1,91 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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(); + + (void) pthread_mutex_lock(&self->cancelLock); + + if (self != NULL + && self->cancelState != PTHREAD_CANCEL_DISABLE + && WaitForSingleObject (self->cancelEvent, 0) == WAIT_OBJECT_0 + ) + { + /* + * Canceling! + */ + self->state = PThreadStateCanceling; + self->cancelState = PTHREAD_CANCEL_DISABLE; + (void) pthread_mutex_unlock(&self->cancelLock); + ptw32_throw(PTW32_EPS_CANCEL); + } + + (void) pthread_mutex_unlock(&self->cancelLock); +} /* pthread_testcancel */ + diff --git a/pthread_timechange_handler_np.c b/pthread_timechange_handler_np.c new file mode 100644 index 0000000..b7d432b --- /dev/null +++ b/pthread_timechange_handler_np.c @@ -0,0 +1,108 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/pthread_win32_attach_detach_np.c b/pthread_win32_attach_detach_np.c new file mode 100644 index 0000000..487bcbb --- /dev/null +++ b/pthread_win32_attach_detach_np.c @@ -0,0 +1,162 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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; + +BOOL +pthread_win32_process_attach_np () +{ + BOOL result = TRUE; + + result = ptw32_processInitialize (); +#ifdef _UWIN + pthread_count++; +#endif + +#ifndef TEST_ICE + + /* + * Load KERNEL32 and try to get address of InterlockedCompareExchange + */ + ptw32_h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL")); + + 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 /* TEST_ICE */ + + ptw32_interlocked_compare_exchange = ptw32_InterlockedCompareExchange; + +#endif /* TEST_ICE */ + + return result; +} + + +BOOL +pthread_win32_process_detach_np () +{ + if (ptw32_processInitialized) + { + pthread_t self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey); + + /* + * Detached threads have their resources automatically + * cleaned up upon exit (others must be 'joined'). + */ + if (self != NULL && + self->detachState == PTHREAD_CREATE_DETACHED) + { + pthread_setspecific (ptw32_selfThreadKey, NULL); + ptw32_threadDestroy (self); + } + + /* + * The DLL is being unmapped into the process's address space + */ + ptw32_processTerminate (); + + 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) + { + pthread_t self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey); + + /* + * Detached threads have their resources automatically + * cleaned up upon exit (others must be 'joined'). + */ + if (self != NULL && + self->detachState == PTHREAD_CREATE_DETACHED) + { + pthread_setspecific (ptw32_selfThreadKey, NULL); + ptw32_threadDestroy (self); + } + } + + return TRUE; +} diff --git a/ptw32_InterlockedCompareExchange.c b/ptw32_InterlockedCompareExchange.c new file mode 100644 index 0000000..0e0ccfd --- /dev/null +++ b/ptw32_InterlockedCompareExchange.c @@ -0,0 +1,108 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 -- + * + * Needed because W95 doesn't support InterlockedCompareExchange. + * It is only used when running the dll on W95. Other versions of + * Windows use the Win32 supported version, which may be running on + * different processor types. + * + * This can't be inlined because we need to know it's address so that + * we can call it through a pointer. + */ +PTW32_INTERLOCKED_LONG WINAPI +ptw32_InterlockedCompareExchange(PTW32_INTERLOCKED_LPLONG location, + PTW32_INTERLOCKED_LONG value, + PTW32_INTERLOCKED_LONG comparand) +{ + PTW32_INTERLOCKED_LONG result; + +#if defined(_M_IX86) || defined(_X86_) + +#if defined(_MSC_VER) + + _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 ; if (EAX == [ECX]), + ; [ECX] = EDX + ; else + ; EAX = [ECX] + MOV dword ptr [result], eax + POP edx + POP ecx + } + +#elif defined(__GNUC__) + + __asm__ + ( + "lock\n\t" + "cmpxchgl %3,(%0)" /* if (EAX == [location]), */ + /* [location] = value */ + /* else */ + /* EAX = [location] */ + :"=r" (location), "=a" (result) + :"0" (location), "q" (value), "a" (comparand) + : "memory" ); + +#endif + +#else + + /* + * If execution gets to here then we should be running on a Win95 system + * but either running on something other than an X86 processor, or a + * compiler other than MSVC or GCC. Pthreads-win32 doesn't support that + * platform (yet). + */ + + result = 0; + +#endif + + return result; +} diff --git a/ptw32_callUserDestroyRoutines.c b/ptw32_callUserDestroyRoutines.c new file mode 100644 index 0000000..cef88cf --- /dev/null +++ b/ptw32_callUserDestroyRoutines.c @@ -0,0 +1,155 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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_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 **nextP; + ThreadKeyAssoc *assoc; + + if (thread != NULL) + { + /* + * Run through all Thread<-->Key associations + * for the current thread. + * If the pthread_key_t still exits (ie the assoc->key + * is not NULL) then call the user's TSD destroy routine. + * Notes: + * If assoc->key is NULL, then the user previously called + * PThreadKeyDestroy. The association is now only referenced + * by the current thread and must be released; otherwise + * the assoc will be destroyed when the key is destroyed. + */ + nextP = (ThreadKeyAssoc **) & (thread->keys); + assoc = *nextP; + + while (assoc != NULL) + { + + if (pthread_mutex_lock (&(assoc->lock)) == 0) + { + pthread_key_t k; + if ((k = assoc->key) != NULL) + { + /* + * Key still active; pthread_key_delete + * will block on this same mutex before + * it can release actual key; therefore, + * key is valid and we can call the destroy + * routine; + */ + void *value = NULL; + + value = pthread_getspecific (k); + if (value != NULL && k->destructor != NULL) + { + +#ifdef __cplusplus + + try + { + /* + * Run the caller's cleanup routine. + */ + (*(k->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. + */ + (*(k->destructor)) (value); + +#endif /* __cplusplus */ + } + } + + /* + * mark assoc->thread as NULL to indicate the + * thread no longer references this association + */ + assoc->thread = NULL; + + /* + * Remove association from the pthread_t chain + */ + *nextP = assoc->nextKey; + + pthread_mutex_unlock (&(assoc->lock)); + + ptw32_tkAssocDestroy (assoc); + + assoc = *nextP; + } + } + } + +} /* ptw32_callUserDestroyRoutines */ diff --git a/ptw32_cond_check_need_init.c b/ptw32_cond_check_need_init.c new file mode 100644 index 0000000..85b6801 --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/ptw32_decrease_semaphore.c b/ptw32_decrease_semaphore.c new file mode 100644 index 0000000..e16dfd6 --- /dev/null +++ b/ptw32_decrease_semaphore.c @@ -0,0 +1,74 @@ +/* + * ------------------------------------------------------------- + * + * Module: ptw32_decrease_semaphore.c + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +#ifdef NEED_SEM + +INLINE void +ptw32_decrease_semaphore(sem_t * sem) +{ + register sem_t s = *sem; + + EnterCriticalSection(&s->sem_lock_cs); + + if (s->value != 0) + { + s->value--; + if (s->value != 0) + { + SetEvent(s->event); + } + } + else + { + /* this case should not happen! */ + } + + LeaveCriticalSection(&s->sem_lock_cs); +} + +#endif /* NEED_SEM */ diff --git a/ptw32_getprocessors.c b/ptw32_getprocessors.c new file mode 100644 index 0000000..79a7b7b --- /dev/null +++ b/ptw32_getprocessors.c @@ -0,0 +1,84 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 vProcessCPUs; + DWORD vSystemCPUs; + int result = 0; + + if (GetProcessAffinityMask(GetCurrentProcess(), + &vProcessCPUs, + &vSystemCPUs)) + { + DWORD bit; + int CPUs = 0; + + for (bit = 1; bit != 0; bit <<= 1) + { + if (vProcessCPUs & bit) + { + CPUs++; + } + } + *count = CPUs; + } + else + { + result = EAGAIN; + } + + return(result); +} diff --git a/ptw32_increase_semaphore.c b/ptw32_increase_semaphore.c new file mode 100644 index 0000000..5f0bbcb --- /dev/null +++ b/ptw32_increase_semaphore.c @@ -0,0 +1,73 @@ +/* + * ------------------------------------------------------------- + * + * Module: ptw32_increase_semaphore.c + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * ------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + +#ifdef NEED_SEM + +INLINE BOOL +ptw32_increase_semaphore(sem_t * sem, unsigned int n) +{ + BOOL result; + register sem_t s = *sem; + + EnterCriticalSection(&s->sem_lock_cs); + + if (s->value + n > s->value) + { + s->value += n; + SetEvent(s->event); + result = TRUE; + } + else + { + result = FALSE; + } + + LeaveCriticalSection(&s->sem_lock_cs); + return result; +} + +#endif /* NEED_SEM */ diff --git a/ptw32_is_attr.c b/ptw32_is_attr.c new file mode 100644 index 0000000..d1ffc3e --- /dev/null +++ b/ptw32_is_attr.c @@ -0,0 +1,49 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/ptw32_mutex_check_need_init.c b/ptw32_mutex_check_need_init.c new file mode 100644 index 0000000..753b214 --- /dev/null +++ b/ptw32_mutex_check_need_init.c @@ -0,0 +1,94 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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_mutex_check_need_init(pthread_mutex_t *mutex) +{ + int result = 0; + + /* + * 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. + */ + if (*mutex == PTHREAD_MUTEX_INITIALIZER) + { + result = pthread_mutex_init(mutex, NULL); + } + else if (*mutex == 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/ptw32_processInitialize.c b/ptw32_processInitialize.c new file mode 100644 index 0000000..7c1818a --- /dev/null +++ b/ptw32_processInitialize.c @@ -0,0 +1,100 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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() explicitely, + * since this initialization routine is automatically called only when + * the dll is loaded. + */ + return TRUE; + } + + ptw32_processInitialized = 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_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/ptw32_processTerminate.c b/ptw32_processTerminate.c new file mode 100644 index 0000000..d816a4b --- /dev/null +++ b/ptw32_processTerminate.c @@ -0,0 +1,100 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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) + { + + 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; + } + + /* + * Destroy the global locks. + */ + 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); + + ptw32_processInitialized = FALSE; + } + +} /* processTerminate */ diff --git a/ptw32_rwlock_check_need_init.c b/ptw32_rwlock_check_need_init.c new file mode 100644 index 0000000..626cf23 --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/ptw32_spinlock_check_need_init.c b/ptw32_spinlock_check_need_init.c new file mode 100644 index 0000000..d8701cd --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/ptw32_threadDestroy.c b/ptw32_threadDestroy.c new file mode 100644 index 0000000..8293b76 --- /dev/null +++ b/ptw32_threadDestroy.c @@ -0,0 +1,66 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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) +{ + if (thread != NULL) + { + ptw32_callUserDestroyRoutines (thread); + + if (thread->cancelEvent != NULL) + { + CloseHandle (thread->cancelEvent); + } + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + /* See documentation for endthread vs endthreadex. */ + if( thread->threadH != 0 ) + { + CloseHandle( thread->threadH ); + } +#endif + + free (thread); + } + +} /* ptw32_threadDestroy */ + diff --git a/ptw32_threadStart.c b/ptw32_threadStart.c new file mode 100644 index 0000000..442e6ec --- /dev/null +++ b/ptw32_threadStart.c @@ -0,0 +1,373 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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(&self->cancelLock); + ptw32_callUserDestroyRoutines(self); + + return EXCEPTION_CONTINUE_SEARCH; + break; + } + } +} + +#elif defined(__CLEANUP_CXX) + +#if defined(_MSC_VER) +#include +static terminate_function ptw32_oldTerminate; +#else +#include +static terminate_handler ptw32_oldTerminate; +#endif + +#if 0 +#include +static pthread_mutex_t termLock = PTHREAD_MUTEX_INITIALIZER; +#endif + +void +ptw32_terminate () +{ + pthread_t self = pthread_self(); +#if 0 + FILE * fp; + pthread_mutex_lock(&termLock); + fp = fopen("pthread.log", "a"); + fprintf(fp, "Terminate\n"); + fclose(fp); + pthread_mutex_unlock(&termLock); +#endif + set_terminate(ptw32_oldTerminate); + (void) pthread_mutex_destroy(&self->cancelLock); + ptw32_callUserDestroyRoutines(self); + terminate(); +} + +#endif /* _MSC_VER */ + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) +unsigned __stdcall +#else +void +#endif +ptw32_threadStart (void * vthreadParms) +{ + ThreadParms *threadParms = (ThreadParms *) vthreadParms; + pthread_t self; + 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; + 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. + */ + self->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(&self->cancelLock) == 0) + { + (void) pthread_mutex_unlock(&self->cancelLock); + } +#endif + + pthread_setspecific (ptw32_selfThreadKey, self); + + self->state = PThreadStateRunning; + +#ifdef __CLEANUP_SEH + + __try + { + /* + * Run the caller's routine; + */ + status = self->exitStatus = (*start) (arg); + +#ifdef _UWIN + if (--pthread_count <= 0) + exit(0); +#endif + + } + __except (ExceptionFilter(GetExceptionInformation(), ei)) + { + switch (ei[0]) + { + case PTW32_EPS_CANCEL: + status = PTHREAD_CANCELED; +#ifdef _UWIN + if (--pthread_count <= 0) + exit(0); +#endif + break; + case PTW32_EPS_EXIT: + status = self->exitStatus; + break; + default: + status = PTHREAD_CANCELED; + break; + } + } + +#else /* __CLEANUP_SEH */ + +#ifdef __CLEANUP_C + + setjmp_rc = setjmp( self->start_mark ); + + if( 0 == setjmp_rc ) { + + /* + * Run the caller's routine; + */ + status = self->exitStatus = (*start) (arg); + } + + else { + + switch (setjmp_rc) + { + case PTW32_EPS_CANCEL: + status = PTHREAD_CANCELED; + break; + case PTW32_EPS_EXIT: + status = self->exitStatus; + break; + default: + status = 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 = self->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. + */ + +#if defined(_MSC_VER) + terminate_function term_func = set_terminate(0); +#else + terminate_handler term_func = set_terminate(0); +#endif + + set_terminate(term_func); + + if (term_func != 0) { + term_func(); + } + + throw; + } + } + catch (ptw32_exception_cancel &) + { + /* + * Thread was canceled. + */ + status = self->exitStatus = PTHREAD_CANCELED; + } + catch (ptw32_exception_exit &) + { + /* + * Thread was exited via pthread_exit(). + */ + status = self->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 = self->exitStatus = PTHREAD_CANCELED; + (void) pthread_mutex_lock(&self->cancelLock); + self->state = PThreadStateException; + (void) pthread_mutex_unlock(&self->cancelLock); + (void) pthread_mutex_destroy(&self->cancelLock); + (void) set_terminate(ptw32_oldTerminate); + ptw32_callUserDestroyRoutines(self); + 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 */ + + (void) pthread_mutex_lock(&self->cancelLock); + self->state = PThreadStateLast; + (void) pthread_mutex_unlock(&self->cancelLock); + + + (void) pthread_mutex_destroy(&self->cancelLock); + +#if 1 + if (self->detachState == PTHREAD_CREATE_DETACHED) + { + /* + * We need to cleanup the pthread now in case we have + * been statically linked, in which case the cleanup + * in dllMain won't get done. Joinable threads will + * be cleaned up by pthread_join(). + * + * Note that 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()) if + * this library has been statically linked. For the dll, + * dllMain will do the cleanup automatically. + */ + (void) pthread_win32_thread_detach_np (); + } + else + { + ptw32_callUserDestroyRoutines (self); + } +#else + ptw32_callUserDestroyRoutines (self); +#endif + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + _endthreadex ((unsigned) status); +#else + _endthread (); +#endif + + /* + * Never reached. + */ + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + return (unsigned) status; +#endif + +} /* ptw32_threadStart */ diff --git a/ptw32_throw.c b/ptw32_throw.c new file mode 100644 index 0000000..6840ce6 --- /dev/null +++ b/ptw32_throw.c @@ -0,0 +1,130 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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_throw(DWORD exception) +{ +#ifdef __CLEANUP_C + pthread_t self = pthread_self(); +#endif + + +#ifdef __CLEANUP_SEH + DWORD exceptionInformation[3]; +#endif + + if (exception != PTW32_EPS_CANCEL && + exception != PTW32_EPS_EXIT) + { + /* Should never enter here */ + exit(1); + } + +#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( self->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/ptw32_timespec.c b/ptw32_timespec.c new file mode 100644 index 0000000..dedcc75 --- /dev/null +++ b/ptw32_timespec.c @@ -0,0 +1,81 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/ptw32_tkAssocCreate.c b/ptw32_tkAssocCreate.c new file mode 100644 index 0000000..f6f6563 --- /dev/null +++ b/ptw32_tkAssocCreate.c @@ -0,0 +1,142 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 (ThreadKeyAssoc ** assocP, + pthread_t thread, + 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 by pthread_exit last. + * + * Parameters: + * assocP + * address into which the association is returned. + * thread + * current running thread. If NULL, then association + * is only added to the key. A NULL thread indicates + * that the user called pthread_setspecific prior + * to starting a thread. That's ok. + * 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 + * ------------------------------------------------------------------- + */ +{ + int result; + ThreadKeyAssoc *assoc; + + /* + * Have to create an association and add it + * to both the key and the thread. + */ + assoc = (ThreadKeyAssoc *) calloc (1, sizeof (*assoc)); + + if (assoc == NULL) + { + result = ENOMEM; + goto FAIL0; + } + + /* + * Initialise only when used for the first time. + */ + assoc->lock = PTHREAD_MUTEX_INITIALIZER; + assoc->thread = thread; + assoc->key = key; + + /* + * Register assoc with key + */ + if ((result = pthread_mutex_lock (&(key->threadsLock))) != 0) + { + goto FAIL2; + } + + assoc->nextThread = (ThreadKeyAssoc *) key->threads; + key->threads = (void *) assoc; + + pthread_mutex_unlock (&(key->threadsLock)); + + if (thread != NULL) + { + /* + * Register assoc with thread + */ + assoc->nextKey = (ThreadKeyAssoc *) thread->keys; + thread->keys = (void *) assoc; + } + + *assocP = assoc; + + return (result); + + /* + * ------------- + * Failure Code + * ------------- + */ +FAIL2: + pthread_mutex_destroy (&(assoc->lock)); + free (assoc); + +FAIL0: + + return (result); + +} /* ptw32_tkAssocCreate */ diff --git a/ptw32_tkAssocDestroy.c b/ptw32_tkAssocDestroy.c new file mode 100644 index 0000000..589e6e3 --- /dev/null +++ b/ptw32_tkAssocDestroy.c @@ -0,0 +1,68 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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) both the key and thread have stopped referencing it. + * + * Parameters: + * assoc + * an instance of ThreadKeyAssoc. + * Returns: + * N/A + * ------------------------------------------------------------------- + */ +{ + + if ((assoc != NULL) && + (assoc->key == NULL && assoc->thread == NULL)) + { + + pthread_mutex_destroy (&(assoc->lock)); + + free (assoc); + } + +} /* ptw32_tkAssocDestroy */ diff --git a/rwlock.c b/rwlock.c index 96a85e4..381a2ad 100644 --- a/rwlock.c +++ b/rwlock.c @@ -34,817 +34,15 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#include -#include - -#include "pthread.h" -#include "implement.h" - -static 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; -} - -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; -} - -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)); -} - - -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 */ - - -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 */ - - -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 */ - - -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 */ - - -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))); -} - -static 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)); -} - -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; -} - -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); -} - -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)); -} - -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; -} +#include "ptw32_rwlock_check_need_init.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_wrlock.c" +#include "pthread_rwlock_unlock.c" +#include "pthread_rwlock_tryrdlock.c" +#include "pthread_rwlock_trywrlock.c" diff --git a/sched.c b/sched.c index 410e1df..ca00bef 100644 --- a/sched.c +++ b/sched.c @@ -38,351 +38,16 @@ #include "implement.h" #include "sched.h" -static int -is_attr(const pthread_attr_t *attr) -{ - return (attr == NULL || - *attr == NULL || - (*attr)->valid != PTW32_ATTR_VALID) ? 1 : 0; -} - - -int -pthread_attr_setschedpolicy(pthread_attr_t *attr, - int policy) -{ - if (is_attr(attr) != 0) - { - return EINVAL; - } - - if (policy != SCHED_OTHER) - { - return ENOTSUP; - } - - return 0; -} - - -int -pthread_attr_getschedpolicy(pthread_attr_t *attr, - int * policy) -{ - if (is_attr(attr) != 0 || policy == NULL) - { - return EINVAL; - } - - /* - * Validate the policy arg. - * Check that a policy constant wasn't passed rather than &policy. - */ - if (policy <= (int *) SCHED_MAX) - { - return EINVAL; - } - - *policy = SCHED_OTHER; - - return 0; -} - - -int -pthread_attr_setschedparam(pthread_attr_t *attr, - const struct sched_param *param) -{ - int priority; - - if (is_attr(attr) != 0 || param == NULL) - { - return EINVAL; - } - - 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; -} - - -int -pthread_attr_getschedparam(const pthread_attr_t *attr, - struct sched_param *param) -{ - if (is_attr(attr) != 0 || param == NULL) - { - return EINVAL; - } - - memcpy(param, &(*attr)->param, sizeof(*param)); - return 0; -} - - -int -pthread_attr_setinheritsched(pthread_attr_t * attr, - int inheritsched) -{ - if (is_attr(attr) != 0) - { - return EINVAL; - } - - if (PTHREAD_INHERIT_SCHED != inheritsched - && PTHREAD_EXPLICIT_SCHED != inheritsched) - { - return EINVAL; - } - - (*attr)->inheritsched = inheritsched; - return 0; -} - - -int -pthread_attr_getinheritsched(pthread_attr_t * attr, - int * inheritsched) -{ - if (is_attr(attr) != 0 || inheritsched == NULL) - { - return EINVAL; - } - - *inheritsched = (*attr)->inheritsched; - return 0; -} - - -int -pthread_setschedparam(pthread_t thread, int policy, - const struct sched_param *param) -{ - int prio; - - /* Validate the thread id. */ - if (thread == NULL || thread->threadH == 0) - { - return EINVAL; - } - - /* 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; - } - - prio = param->sched_priority; - - /* Validate priority level. */ - if (prio < sched_get_priority_min(policy) || - prio > sched_get_priority_max(policy)) - { - return EINVAL; - } - - /* This is practically guaranteed to return TRUE. */ - (void) SetThreadPriority(thread->threadH, prio); - - return 0; -} - - -int -pthread_getschedparam(pthread_t thread, int *policy, - struct sched_param *param) -{ - int prio; - - /* Validate the thread id. */ - if (thread == NULL || thread->threadH == 0) - { - return EINVAL; - } - - /* - * 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; - - /* Fill out the sched_param structure. */ - prio = GetThreadPriority(thread->threadH); - if (prio == THREAD_PRIORITY_ERROR_RETURN) - { - return EINVAL; - } - - param->sched_priority = prio; - return 0; -} - - -/* - * 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 - */ - - -int -sched_get_priority_max(int policy) -{ - if (policy < SCHED_MIN || policy > SCHED_MAX) - { - return EINVAL; - } - -#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 -} - - -int -sched_get_priority_min(int policy) -{ - if (policy < SCHED_MIN || policy > SCHED_MAX) - { - return EINVAL; - } - -#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 -} - - -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, 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; -} - - -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, FALSE, (DWORD) pid); - - if (NULL == h) - { - errno = (GetLastError() == (0xFF & ERROR_ACCESS_DENIED)) ? EPERM : ESRCH; - return -1; - } - } - } - - return SCHED_OTHER; -} - - -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; -} +#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/sched_get_priority_max.c b/sched_get_priority_max.c new file mode 100644 index 0000000..8bffa64 --- /dev/null +++ b/sched_get_priority_max.c @@ -0,0 +1,69 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 + */ + + +int +sched_get_priority_max(int policy) +{ + if (policy < SCHED_MIN || policy > SCHED_MAX) + { + return EINVAL; + } + +#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/sched_get_priority_min.c b/sched_get_priority_min.c new file mode 100644 index 0000000..2536ceb --- /dev/null +++ b/sched_get_priority_min.c @@ -0,0 +1,69 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 + */ + + +int +sched_get_priority_min(int policy) +{ + if (policy < SCHED_MIN || policy > SCHED_MAX) + { + return EINVAL; + } + +#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/sched_getscheduler.c b/sched_getscheduler.c new file mode 100644 index 0000000..9d0cb57 --- /dev/null +++ b/sched_getscheduler.c @@ -0,0 +1,66 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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, FALSE, (DWORD) pid); + + if (NULL == h) + { + errno = (GetLastError() == (0xFF & ERROR_ACCESS_DENIED)) ? EPERM : ESRCH; + return -1; + } + } + } + + return SCHED_OTHER; +} diff --git a/sched_setscheduler.c b/sched_setscheduler.c new file mode 100644 index 0000000..b92cd54 --- /dev/null +++ b/sched_setscheduler.c @@ -0,0 +1,78 @@ +/* + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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, 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/sched_yield.c b/sched_yield.c new file mode 100644 index 0000000..6136444 --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/sem_close.c b/sem_close.c new file mode 100644 index 0000000..0cc8f0f --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/sem_destroy.c b/sem_destroy.c new file mode 100644 index 0000000..80358f8 --- /dev/null +++ b/sem_destroy.c @@ -0,0 +1,121 @@ +/* + * ------------------------------------------------------------- + * + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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; + + if (sem == NULL || *sem == NULL) + { + result = EINVAL; + } + else + { + s = *sem; + *sem = NULL; + +#ifdef NEED_SEM + + if (! CloseHandle(s->event)) + { + *sem = s; + result = EINVAL; + } + else + { + DeleteCriticalSection(&s->sem_lock_cs); + } + +#else /* NEED_SEM */ + + if (! CloseHandle (s->sem)) + { + *sem = s; + result = EINVAL; + } + +#endif /* NEED_SEM */ + + } + + if (result != 0) + { + errno = result; + return -1; + } + + free(s); + + return 0; + +} /* sem_destroy */ diff --git a/sem_getvalue.c b/sem_getvalue.c new file mode 100644 index 0000000..abc76c0 --- /dev/null +++ b/sem_getvalue.c @@ -0,0 +1,124 @@ +/* + * ------------------------------------------------------------- + * + * Module: sem_getvalue.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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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. + */ +{ + int result = 0; + + if ( sem == NULL || *sem == NULL || sval == NULL ) + { + result = EINVAL; + } + else + { + +#ifdef NEED_SEM + + result = ENOSYS; + +#else + long value = *sval; + + /* Note: + * The windows NT documentation says that the increment must be + * greater than zero, but it is set to zero here. If this works, + * the function will return true. If not, we can't do it this way + * so flag it as not implemented. + */ + + if ( ReleaseSemaphore( (*sem)->sem, 0L, &value) ) + { + *sval = value; + } + else + { + result = ENOSYS; + } + +#endif + } + + + if ( result != 0 ) + { + errno = result; + return -1; + } + + return 0; + +} /* sem_getvalue */ diff --git a/sem_init.c b/sem_init.c new file mode 100644 index 0000000..e36678c --- /dev/null +++ b/sem_init.c @@ -0,0 +1,163 @@ +/* + * ------------------------------------------------------------- + * + * Module: sem_init.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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef _UWIN +# include +#endif + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + +#include + +int +sem_init (sem_t * sem, int pshared, unsigned int value) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function initializes an unnamed 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 an unnamed 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, + * ENOSPC a required resource has been exhausted, + * ENOSYS semaphores are not supported, + * EPERM the process lacks appropriate privilege + * + * ------------------------------------------------------ + */ +{ + int result = 0; + sem_t s; + + if (pshared != 0) + { + /* + * Creating a semaphore that can be shared between + * processes + */ + result = EPERM; + + } + else + { + + s = (sem_t) calloc (1, sizeof (*s)); + + if (NULL == s) + { + result = ENOMEM; + } + +#ifdef NEED_SEM + + else + { + s->value = value; + s->event = CreateEvent (NULL, + FALSE, /* manual reset */ + FALSE, /* initial state */ + NULL); + if (0 == s->event) + { + result = ENOSPC; + } + else + { + if (value != 0) + { + SetEvent(s->event); + } + + InitializeCriticalSection(&s->sem_lock_cs); + } + } + +#else /* NEED_SEM */ + + s->sem = CreateSemaphore (NULL, /* Always NULL */ + value, /* Initial value */ + INT_MAX, /* Maximum value */ + NULL); /* Name */ + + if (0 == s->sem) + { + result = ENOSPC; + } + +#endif /* NEED_SEM */ + + } + + if (result != 0) + { + errno = result; + return -1; + } + + *sem = s; + + return 0; + +} /* sem_init */ diff --git a/sem_open.c b/sem_open.c new file mode 100644 index 0000000..79b9535 --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/sem_post.c b/sem_post.c new file mode 100644 index 0000000..afa7533 --- /dev/null +++ b/sem_post.c @@ -0,0 +1,104 @@ +/* + * ------------------------------------------------------------- + * + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_post (sem_t * sem) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function posts a wakeup to a semaphore. + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * DESCRIPTION + * This function posts a wakeup to a semaphore. If there + * are waiting threads (or processes), one is awakened; + * otherwise, the semaphore value is incremented by one. + * + * RESULTS + * 0 successfully posted semaphore, + * -1 failed, error in errno + * ERRNO + * EINVAL 'sem' is not a valid semaphore, + * ENOSYS semaphores are not supported, + * + * ------------------------------------------------------ + */ +{ + int result = 0; + + if (sem == NULL || *sem == NULL) + { + result = EINVAL; + } + +#ifdef NEED_SEM + + else if (! ptw32_increase_semaphore (sem, 1)) + +#else /* NEED_SEM */ + + else if (! ReleaseSemaphore ((*sem)->sem, 1, 0)) + +#endif /* NEED_SEM */ + + { + result = EINVAL; + } + + if (result != 0) + { + errno = result; + return -1; + } + + return 0; + +} /* sem_post */ diff --git a/sem_post_multiple.c b/sem_post_multiple.c new file mode 100644 index 0000000..92139b8 --- /dev/null +++ b/sem_post_multiple.c @@ -0,0 +1,107 @@ +/* + * ------------------------------------------------------------- + * + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +int +sem_post_multiple (sem_t * sem, int count ) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function posts multiple wakeups to a semaphore. + * + * PARAMETERS + * sem + * pointer to an instance of sem_t + * + * count + * counter, must be greater than zero. + * + * DESCRIPTION + * This function posts multiple wakeups to a semaphore. If there + * are waiting threads (or processes), n <= count are awakened; + * the semaphore value is incremented by count - n. + * + * RESULTS + * 0 successfully posted semaphore, + * -1 failed, error in errno + * ERRNO + * EINVAL 'sem' is not a valid semaphore + * or count is less than or equal to zero. + * + * ------------------------------------------------------ + */ +{ + int result = 0; + + if (sem == NULL || *sem == NULL || count <= 0) + { + result = EINVAL; + } + +#ifdef NEED_SEM + + else if (! ptw32_increase_semaphore (sem, count)) + +#else /* NEED_SEM */ + + else if (! ReleaseSemaphore ((*sem)->sem, count, 0)) + +#endif /* NEED_SEM */ + + { + result = EINVAL; + } + + if (result != 0) + { + errno = result; + return -1; + } + + return 0; + +} /* sem_post_multiple */ diff --git a/sem_timedwait.c b/sem_timedwait.c new file mode 100644 index 0000000..11178f2 --- /dev/null +++ b/sem_timedwait.c @@ -0,0 +1,198 @@ +/* + * ------------------------------------------------------------- + * + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef _UWIN +#include +#endif +#ifndef NEED_FTIME +#include +#endif + +#include "pthread.h" +#include "semaphore.h" +#include "implement.h" + + +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; + +#ifdef NEED_FTIME + + struct timespec currSysTime; + +#else /* NEED_FTIME */ + + struct _timeb currSysTime; + +#endif /* NEED_FTIME */ + + const DWORD NANOSEC_PER_MILLISEC = 1000000; + const DWORD MILLISEC_PER_SEC = 1000; + DWORD milliseconds; + + if (sem == NULL) + { + result = EINVAL; + } + else + { + if (abstime == NULL) + { + milliseconds = INFINITE; + } + else + { + /* + * Calculate timeout as milliseconds from current system time. + */ + + /* get current system time */ + +#ifdef NEED_FTIME + + { + FILETIME ft; + SYSTEMTIME st; + + GetSystemTime(&st); + SystemTimeToFileTime(&st, &ft); + /* + * GetSystemTimeAsFileTime(&ft); would be faster, + * but it does not exist on WinCE + */ + + ptw32_filetime_to_timespec(&ft, &currSysTime); + } + + /* + * subtract current system time from abstime + */ + milliseconds = (abstime->tv_sec - currSysTime.tv_sec) * MILLISEC_PER_SEC; + milliseconds += ((abstime->tv_nsec - currSysTime.tv_nsec) + + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC; + +#else /* NEED_FTIME */ + _ftime(&currSysTime); + + /* + * subtract current system time from abstime + */ + milliseconds = (abstime->tv_sec - currSysTime.time) * MILLISEC_PER_SEC; + milliseconds += ((abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC) + - currSysTime.millitm; + +#endif /* NEED_FTIME */ + + + if (((int) milliseconds) < 0) + milliseconds = 0; + } + +#ifdef NEED_SEM + + result = (pthreadCancelableTimedWait ((*sem)->event, milliseconds)); + +#else /* NEED_SEM */ + + result = (pthreadCancelableTimedWait ((*sem)->sem, milliseconds)); + +#endif + + } + + if (result != 0) + { + + errno = result; + return -1; + + } + +#ifdef NEED_SEM + + ptw32_decrease_semaphore(sem); + +#endif /* NEED_SEM */ + + return 0; + +} /* sem_timedwait */ diff --git a/sem_trywait.c b/sem_trywait.c new file mode 100644 index 0000000..aea1d06 --- /dev/null +++ b/sem_trywait.c @@ -0,0 +1,110 @@ +/* + * ------------------------------------------------------------- + * + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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. + * + * ------------------------------------------------------ + */ +{ +#ifdef NEED_SEM + + /* + * not yet implemented! + */ + errno = ENOTSUP; + return -1; + +#else /* NEED_SEM */ + + int result = 0; + + if (sem == NULL || *sem == NULL) + { + result = EINVAL; + } + else if (WaitForSingleObject ((*sem)->sem, 0) == WAIT_TIMEOUT) + { + result = EAGAIN; + } + + if (result != 0) + { + errno = result; + return -1; + } + + return 0; + +#endif /* NEED_SEM */ + +} /* sem_trywait */ diff --git a/sem_unlink.c b/sem_unlink.c new file mode 100644 index 0000000..7dae88e --- /dev/null +++ b/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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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/sem_wait.c b/sem_wait.c new file mode 100644 index 0000000..5095241 --- /dev/null +++ b/sem_wait.c @@ -0,0 +1,115 @@ +/* + * ------------------------------------------------------------- + * + * 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,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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_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; + + if (sem == NULL || *sem == NULL) + { + result = EINVAL; + } + else + { + +#ifdef NEED_SEM + + result = pthreadCancelableWait ((*sem)->event); + +#else /* NEED_SEM */ + + result = pthreadCancelableWait ((*sem)->sem); + +#endif /* NEED_SEM */ + + } + + if (result != 0) + { + errno = result; + return -1; + } + +#ifdef NEED_SEM + + ptw32_decrease_semaphore(sem); + +#endif /* NEED_SEM */ + + return 0; + +} /* sem_wait */ diff --git a/semaphore.c b/semaphore.c index 713a904..bb10926 100644 --- a/semaphore.c +++ b/semaphore.c @@ -59,19 +59,19 @@ #include "implement.h" -#include "semaphore_init.c" -#include "semaphore_destroy.c" -#include "semaphore_trywait.c" -#include "semaphore_wait.c" -#include "semaphore_timedwait.c" -#include "semaphore_post.c" -#include "semaphore_postmultiple.c" -#include "semaphore_getvalue.c" -#include "semaphore_open.c" -#include "semaphore_close.c" -#include "semaphore_unlink.c" +#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" #ifdef NEED_SEM -#include "semaphore_decrease.c" -#include "semaphore_increase.c" +#include "ptw32_decrease_semaphore.c" +#include "ptw32_increase_semaphore.c" #endif diff --git a/semaphore_close.c b/semaphore_close.c deleted file mode 100644 index bb93e96..0000000 --- a/semaphore_close.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/semaphore_decrease.c b/semaphore_decrease.c deleted file mode 100644 index 203d877..0000000 --- a/semaphore_decrease.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore_decrease.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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - - -#ifdef NEED_SEM - -INLINE void -ptw32_decrease_semaphore(sem_t * sem) -{ - register sem_t s = *sem; - - EnterCriticalSection(&s->sem_lock_cs); - - if (s->value != 0) - { - s->value--; - if (s->value != 0) - { - SetEvent(s->event); - } - } - else - { - /* this case should not happen! */ - } - - LeaveCriticalSection(&s->sem_lock_cs); -} - -#endif /* NEED_SEM */ diff --git a/semaphore_destroy.c b/semaphore_destroy.c deleted file mode 100644 index 539f83a..0000000 --- a/semaphore_destroy.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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; - - if (sem == NULL || *sem == NULL) - { - result = EINVAL; - } - else - { - s = *sem; - *sem = NULL; - -#ifdef NEED_SEM - - if (! CloseHandle(s->event)) - { - *sem = s; - result = EINVAL; - } - else - { - DeleteCriticalSection(&s->sem_lock_cs); - } - -#else /* NEED_SEM */ - - if (! CloseHandle (s->sem)) - { - *sem = s; - result = EINVAL; - } - -#endif /* NEED_SEM */ - - } - - if (result != 0) - { - errno = result; - return -1; - } - - free(s); - - return 0; - -} /* sem_destroy */ diff --git a/semaphore_getvalue.c b/semaphore_getvalue.c deleted file mode 100644 index 185bcdb..0000000 --- a/semaphore_getvalue.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore_getvalue.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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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. - */ -{ - int result = 0; - - if ( sem == NULL || *sem == NULL || sval == NULL ) - { - result = EINVAL; - } - else - { - -#ifdef NEED_SEM - - result = ENOSYS; - -#else - long value = *sval; - - /* Note: - * The windows NT documentation says that the increment must be - * greater than zero, but it is set to zero here. If this works, - * the function will return true. If not, we can't do it this way - * so flag it as not implemented. - */ - - if ( ReleaseSemaphore( (*sem)->sem, 0L, &value) ) - { - *sval = value; - } - else - { - result = ENOSYS; - } - -#endif - } - - - if ( result != 0 ) - { - errno = result; - return -1; - } - - return 0; - -} /* sem_getvalue */ diff --git a/semaphore_increase.c b/semaphore_increase.c deleted file mode 100644 index 5a67468..0000000 --- a/semaphore_increase.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore_increase.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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - -#ifdef NEED_SEM - -INLINE BOOL -ptw32_increase_semaphore(sem_t * sem, unsigned int n) -{ - BOOL result; - register sem_t s = *sem; - - EnterCriticalSection(&s->sem_lock_cs); - - if (s->value + n > s->value) - { - s->value += n; - SetEvent(s->event); - result = TRUE; - } - else - { - result = FALSE; - } - - LeaveCriticalSection(&s->sem_lock_cs); - return result; -} - -#endif /* NEED_SEM */ diff --git a/semaphore_init.c b/semaphore_init.c deleted file mode 100644 index bda6849..0000000 --- a/semaphore_init.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore_init.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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef _UWIN -# include -#endif - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - -#include - -int -sem_init (sem_t * sem, int pshared, unsigned int value) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function initializes an unnamed 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 an unnamed 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, - * ENOSPC a required resource has been exhausted, - * ENOSYS semaphores are not supported, - * EPERM the process lacks appropriate privilege - * - * ------------------------------------------------------ - */ -{ - int result = 0; - sem_t s; - - if (pshared != 0) - { - /* - * Creating a semaphore that can be shared between - * processes - */ - result = EPERM; - - } - else - { - - s = (sem_t) calloc (1, sizeof (*s)); - - if (NULL == s) - { - result = ENOMEM; - } - -#ifdef NEED_SEM - - else - { - s->value = value; - s->event = CreateEvent (NULL, - FALSE, /* manual reset */ - FALSE, /* initial state */ - NULL); - if (0 == s->event) - { - result = ENOSPC; - } - else - { - if (value != 0) - { - SetEvent(s->event); - } - - InitializeCriticalSection(&s->sem_lock_cs); - } - } - -#else /* NEED_SEM */ - - s->sem = CreateSemaphore (NULL, /* Always NULL */ - value, /* Initial value */ - INT_MAX, /* Maximum value */ - NULL); /* Name */ - - if (0 == s->sem) - { - result = ENOSPC; - } - -#endif /* NEED_SEM */ - - } - - if (result != 0) - { - errno = result; - return -1; - } - - *sem = s; - - return 0; - -} /* sem_init */ diff --git a/semaphore_open.c b/semaphore_open.c deleted file mode 100644 index 9de124a..0000000 --- a/semaphore_open.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/semaphore_post.c b/semaphore_post.c deleted file mode 100644 index b7ce8da..0000000 --- a/semaphore_post.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - - -int -sem_post (sem_t * sem) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function posts a wakeup to a semaphore. - * - * PARAMETERS - * sem - * pointer to an instance of sem_t - * - * DESCRIPTION - * This function posts a wakeup to a semaphore. If there - * are waiting threads (or processes), one is awakened; - * otherwise, the semaphore value is incremented by one. - * - * RESULTS - * 0 successfully posted semaphore, - * -1 failed, error in errno - * ERRNO - * EINVAL 'sem' is not a valid semaphore, - * ENOSYS semaphores are not supported, - * - * ------------------------------------------------------ - */ -{ - int result = 0; - - if (sem == NULL || *sem == NULL) - { - result = EINVAL; - } - -#ifdef NEED_SEM - - else if (! ptw32_increase_semaphore (sem, 1)) - -#else /* NEED_SEM */ - - else if (! ReleaseSemaphore ((*sem)->sem, 1, 0)) - -#endif /* NEED_SEM */ - - { - result = EINVAL; - } - - if (result != 0) - { - errno = result; - return -1; - } - - return 0; - -} /* sem_post */ diff --git a/semaphore_postmultiple.c b/semaphore_postmultiple.c deleted file mode 100644 index 3218896..0000000 --- a/semaphore_postmultiple.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore_postmultiple.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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - - -int -sem_post_multiple (sem_t * sem, int count ) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function posts multiple wakeups to a semaphore. - * - * PARAMETERS - * sem - * pointer to an instance of sem_t - * - * count - * counter, must be greater than zero. - * - * DESCRIPTION - * This function posts multiple wakeups to a semaphore. If there - * are waiting threads (or processes), n <= count are awakened; - * the semaphore value is incremented by count - n. - * - * RESULTS - * 0 successfully posted semaphore, - * -1 failed, error in errno - * ERRNO - * EINVAL 'sem' is not a valid semaphore - * or count is less than or equal to zero. - * - * ------------------------------------------------------ - */ -{ - int result = 0; - - if (sem == NULL || *sem == NULL || count <= 0) - { - result = EINVAL; - } - -#ifdef NEED_SEM - - else if (! ptw32_increase_semaphore (sem, count)) - -#else /* NEED_SEM */ - - else if (! ReleaseSemaphore ((*sem)->sem, count, 0)) - -#endif /* NEED_SEM */ - - { - result = EINVAL; - } - - if (result != 0) - { - errno = result; - return -1; - } - - return 0; - -} /* sem_post_multiple */ diff --git a/semaphore_timedwait.c b/semaphore_timedwait.c deleted file mode 100644 index 083ee78..0000000 --- a/semaphore_timedwait.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef _UWIN -#include -#endif -#ifndef NEED_FTIME -#include -#endif - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - - -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; - -#ifdef NEED_FTIME - - struct timespec currSysTime; - -#else /* NEED_FTIME */ - - struct _timeb currSysTime; - -#endif /* NEED_FTIME */ - - const DWORD NANOSEC_PER_MILLISEC = 1000000; - const DWORD MILLISEC_PER_SEC = 1000; - DWORD milliseconds; - - if (sem == NULL) - { - result = EINVAL; - } - else - { - if (abstime == NULL) - { - milliseconds = INFINITE; - } - else - { - /* - * Calculate timeout as milliseconds from current system time. - */ - - /* get current system time */ - -#ifdef NEED_FTIME - - { - FILETIME ft; - SYSTEMTIME st; - - GetSystemTime(&st); - SystemTimeToFileTime(&st, &ft); - /* - * GetSystemTimeAsFileTime(&ft); would be faster, - * but it does not exist on WinCE - */ - - filetime_to_timespec(&ft, &currSysTime); - } - - /* - * subtract current system time from abstime - */ - milliseconds = (abstime->tv_sec - currSysTime.tv_sec) * MILLISEC_PER_SEC; - milliseconds += ((abstime->tv_nsec - currSysTime.tv_nsec) + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC; - -#else /* NEED_FTIME */ - _ftime(&currSysTime); - - /* - * subtract current system time from abstime - */ - milliseconds = (abstime->tv_sec - currSysTime.time) * MILLISEC_PER_SEC; - milliseconds += ((abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC) - - currSysTime.millitm; - -#endif /* NEED_FTIME */ - - - if (((int) milliseconds) < 0) - milliseconds = 0; - } - -#ifdef NEED_SEM - - result = (pthreadCancelableTimedWait ((*sem)->event, milliseconds)); - -#else /* NEED_SEM */ - - result = (pthreadCancelableTimedWait ((*sem)->sem, milliseconds)); - -#endif - - } - - if (result != 0) - { - - errno = result; - return -1; - - } - -#ifdef NEED_SEM - - ptw32_decrease_semaphore(sem); - -#endif /* NEED_SEM */ - - return 0; - -} /* sem_timedwait */ diff --git a/semaphore_trywait.c b/semaphore_trywait.c deleted file mode 100644 index 6b20d38..0000000 --- a/semaphore_trywait.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore.c - * - * Purpose: - * Semaphores aren't actually part of the PThreads standard. - * They are defined by the POSIX Standard: - * - * POSIX 1003.1b-1993 (POSIX.1b) - * - * ------------------------------------------------------------- - * - * -------------------------------------------------------------------------- - * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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. - * - * ------------------------------------------------------ - */ -{ -#ifdef NEED_SEM - - /* - * not yet implemented! - */ - errno = ENOTSUP; - return -1; - -#else /* NEED_SEM */ - - int result = 0; - - if (sem == NULL || *sem == NULL) - { - result = EINVAL; - } - else if (WaitForSingleObject ((*sem)->sem, 0) == WAIT_TIMEOUT) - { - result = EAGAIN; - } - - if (result != 0) - { - errno = result; - return -1; - } - - return 0; - -#endif /* NEED_SEM */ - -} /* sem_trywait */ diff --git a/semaphore_unlink.c b/semaphore_unlink.c deleted file mode 100644 index 8f20746..0000000 --- a/semaphore_unlink.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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/semaphore_wait.c b/semaphore_wait.c deleted file mode 100644 index 33bdb9c..0000000 --- a/semaphore_wait.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore_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,2002 Pthreads-win32 contributors - * - * Contact Email: rpj@ise.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library 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_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; - - if (sem == NULL || *sem == NULL) - { - result = EINVAL; - } - else - { - -#ifdef NEED_SEM - - result = pthreadCancelableWait ((*sem)->event); - -#else /* NEED_SEM */ - - result = pthreadCancelableWait ((*sem)->sem); - -#endif /* NEED_SEM */ - - } - - if (result != 0) - { - errno = result; - return -1; - } - -#ifdef NEED_SEM - - ptw32_decrease_semaphore(sem); - -#endif /* NEED_SEM */ - - return 0; - -} /* sem_wait */ diff --git a/spin.c b/spin.c index 5d33214..8947164 100644 --- a/spin.c +++ b/spin.c @@ -38,279 +38,10 @@ #include "implement.h" -static INLINE int -ptw32_spinlock_check_need_init(pthread_spinlock_t *lock) -{ - int result = 0; +#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" - /* - * 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); -} - - -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 - - /* - * 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); -} - -int -pthread_spin_destroy(pthread_spinlock_t *lock) -{ - register pthread_spinlock_t s; - - if (lock == NULL || *lock == NULL) - { - return EINVAL; - } - - if ((s = *lock) != PTHREAD_SPINLOCK_INITIALIZER) - { - if (s->interlock == PTW32_SPIN_USE_MUTEX) - { - return pthread_mutex_destroy(&(s->u.mutex)); - } - - 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)) - { - return 0; - } - - return EINVAL; - } - else - { - int result = 0; - - /* - * 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); - } -} - -/* - * NOTE: For speed, these routines don't check if "lock" is valid. - */ -int -pthread_spin_lock(pthread_spinlock_t *lock) -{ - register pthread_spinlock_t s; - - 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; -} - -int -pthread_spin_unlock(pthread_spinlock_t *lock) -{ - register pthread_spinlock_t 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; -} - -int -pthread_spin_trylock(pthread_spinlock_t *lock) -{ - pthread_spinlock_t s = *lock; - - if (s == PTHREAD_SPINLOCK_INITIALIZER) - { - int result; - - if ((result = ptw32_spinlock_check_need_init(lock)) != 0) - { - return(result); - } - } - - 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/sync.c b/sync.c index 3a093e0..e644910 100644 --- a/sync.c +++ b/sync.c @@ -38,162 +38,6 @@ #include "pthread.h" #include "implement.h" -int -pthread_detach (pthread_t tid) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function detaches the given thread. - * - * PARAMETERS - * thread - * an instance of a pthread_t - * - * - * DESCRIPTION - * This function detaches the given thread. You may - * detach the main thread or to detach a joinable thread - * (You should have used pthread_attr_t to create the - * thread as detached!) - * NOTE: detached threads cannot be joined nor canceled; - * 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; - if (tid == NULL || - tid->detachState == PTHREAD_CREATE_DETACHED) - { - - result = EINVAL; - - } - else - { - result = 0; - tid->detachState = PTHREAD_CREATE_DETACHED; - } - - return (result); - -} /* pthread_detach */ - -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 = 0; - pthread_t self; - - self = pthread_self (); - if (self == NULL) - { - return ENOENT; - } - - if (pthread_equal (self, thread) != 0) - { - result = EDEADLK; - } - else if (thread->detachState == PTHREAD_CREATE_DETACHED) - { - result = EINVAL; - } - 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(thread->threadH); - - if (result == 0) - { - -#if ! defined (__MINGW32__) || defined (__MSVCRT__) - - if (value_ptr != NULL - && !GetExitCodeThread (thread->threadH, (LPDWORD) value_ptr)) - { - result = ESRCH; - } - else - { - /* - * The result of making multiple simultaneous calls to - * pthread_join() specifying the same target is undefined. - */ - ptw32_threadDestroy (thread); - } - -#else /* __MINGW32__ && ! __MSVCRT__ */ - - /* - * If using CRTDLL, the thread may have exited, and endthread - * will have closed the handle. - */ - if (value_ptr != NULL) - { - *value_ptr = thread->exitStatus; - } - - /* - * The result of making multiple simultaneous calls to - * pthread_join() specifying the same target is undefined. - */ - ptw32_threadDestroy (thread); - -#endif /* __MINGW32__ && ! __MSVCRT__ */ - - } - else - { - result = ESRCH; - } - } - - return (result); - -} /* pthread_join */ +#include "pthread_detach.c" +#include "pthread_join.c" diff --git a/tests/ChangeLog b/tests/ChangeLog index 4a4883e..944961d 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2002-02-17 Ross Johnson + + * condvar1_1.c: New test. + * condvar1_2.c: New test. + 2002-02-07 Ross Johnson * delay1.c: New test. diff --git a/tests/GNUmakefile b/tests/GNUmakefile index fc0a7e3..74bd6b3 100644 --- a/tests/GNUmakefile +++ b/tests/GNUmakefile @@ -67,9 +67,10 @@ COPYFILES = $(HDR) $(LIB) $(DLL) TESTS = loadfree \ self1 mutex5 mutex1 mutex1e mutex1n mutex1r \ - condvar1 condvar2 condvar2_1 exit1 create1 equal1 \ + condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 create1 equal1 \ exit2 exit3 \ - join0 join1 join2 mutex2 mutex3 mutex4 mutex6 mutex6n mutex6e mutex6r \ + join0 join1 join2 \ + mutex2 mutex3 mutex4 mutex6 mutex6n mutex6e mutex6r \ mutex7 mutex7n mutex7e mutex7r mutex8 mutex8n mutex8e mutex8r \ count1 once1 tsd1 self2 cancel1 cancel2 \ delay1 delay2 eyal1 \ @@ -148,6 +149,8 @@ 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 diff --git a/tests/Makefile b/tests/Makefile index ad2a055..9532b41 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -73,7 +73,7 @@ EHFLAGS = PASSES= loadfree.pass \ self1.pass mutex5.pass \ mutex1.pass mutex1n.pass mutex1e.pass mutex1r.pass mutex2.pass mutex3.pass \ - condvar1.pass condvar2.pass condvar2_1.pass \ + condvar1.pass condvar1_1.pass condvar1_2.pass condvar2.pass condvar2_1.pass \ exit1.pass create1.pass equal1.pass \ exit2.pass exit3.pass \ join0.pass join1.pass join2.pass \ @@ -213,6 +213,8 @@ 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 diff --git a/tests/condvar1_1.c b/tests/condvar1_1.c new file mode 100644 index 0000000..465c9df --- /dev/null +++ b/tests/condvar1_1.c @@ -0,0 +1,117 @@ +/* + * File: condvar1_1.c + * + * + * -------------------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 destry 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 +#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/tests/condvar1_2.c b/tests/condvar1_2.c new file mode 100644 index 0000000..66237ba --- /dev/null +++ b/tests/condvar1_2.c @@ -0,0 +1,122 @@ +/* + * File: condvar1_2.c + * + * + * -------------------------------------------------------------------------- + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2002 Pthreads-win32 contributors + * + * Contact Email: rpj@ise.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library 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 +#include "test.h" + +enum { + NUM_CV = 100 +}; + +static pthread_cond_t cv[NUM_CV]; + +int +main() +{ + int i, j; + int result = -1; + pthread_t t; + + 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/tests/condvar3_1.c b/tests/condvar3_1.c index e181c58..9c4e25b 100644 --- a/tests/condvar3_1.c +++ b/tests/condvar3_1.c @@ -161,6 +161,8 @@ main() signaled++; } + assert(pthread_cond_destroy(&cv1) == 0); + for (i = 1; i <= NUMTHREADS; i++) { assert(pthread_join(t[i], (void **) &result) == 0); diff --git a/tests/exit4.c b/tests/exit4.c index 3c0c8b1..480fc2e 100644 --- a/tests/exit4.c +++ b/tests/exit4.c @@ -64,21 +64,29 @@ void * func(void * arg) { Guard g("func", counter); + #ifdef USE_PTHREAD_EXIT + pthread_exit(arg); assert(0); //Never reached with pthread_exit + #endif //USE_PTHREAD_EXIT + return ret_value; } #endif /*__CLEANUP_CXX */ -int main(int, char **) +int +main() { #ifndef __CLEANUP_CXX + printf("Test requires C++ cleanup enabled. Skipped.\n"); + #else + { void *ret = 0; Guard g("main", counter); @@ -87,7 +95,10 @@ int main(int, char **) assert(0 == pthread_join(id, &ret)); assert(ret == ret_value); } + assert(counter == init_counter_value); + #endif /*__CLEANUP_CXX */ + return 0; } diff --git a/tsd.c b/tsd.c index 1fa9b5a..52c3517 100644 --- a/tsd.c +++ b/tsd.c @@ -37,310 +37,10 @@ #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; +#include "pthread_key_create.c" +#include "pthread_key_delete.c" +#include "pthread_setspecific.c" +#include "pthread_getspecific.c" - 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->threadsLock = PTHREAD_MUTEX_INITIALIZER; - newkey->destructor = destructor; - } - - *key = newkey; - - return (result); -} - -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 spcific 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 spcific 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->threadsLock)) == 0) - { - /* - * Run through all Thread<-->Key associations - * for this key. - * If the pthread_t still exits (ie the assoc->thread - * is not NULL) then leave the assoc for the thread to - * destroy. - * Notes: - * If assoc->thread is NULL, then the associated thread - * is no longer referencing this assoc. - * The association is only referenced - * by this key and must be released; otherwise - * the assoc will be destroyed when the thread is destroyed. - */ - ThreadKeyAssoc *assoc; - - assoc = (ThreadKeyAssoc *) key->threads; - - while (assoc != NULL) - { - if (pthread_mutex_lock (&(assoc->lock)) == 0) - { - ThreadKeyAssoc *next; - - assoc->key = NULL; - next = assoc->nextThread; - assoc->nextThread = NULL; - - pthread_mutex_unlock (&(assoc->lock)); - - ptw32_tkAssocDestroy (assoc); - - assoc = next; - } - } - pthread_mutex_unlock (&(key->threadsLock)); - } - - TlsFree (key->key); - if (key->destructor != NULL) - { - pthread_mutex_destroy (&(key->threadsLock)); - } - -#if defined( _DEBUG ) - memset ((char *) key, 0, sizeof (*key)); -#endif - free (key); - } - - return (result); -} - - -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 == NULL) - { - return ENOENT; - } - } - else - { - /* - * Resolve catch-22 of registering thread with threadSelf - * key - */ - self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey); - if (self == NULL) - { - self = (pthread_t) value; - } - } - - result = 0; - - if (key != NULL) - { - ThreadKeyAssoc *assoc; - - if (self != 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. - */ - assoc = (ThreadKeyAssoc *) self->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 (&assoc, self, key); - } - } - - if (result == 0) - { - if ( ! TlsSetValue (key->key, (LPVOID) value)) - { - result = EAGAIN; - } - } - } - - return (result); -} /* pthread_setspecific */ - - -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 - * - * ------------------------------------------------------ - */ -{ - int lasterror = GetLastError(); - int lastWSAerror = WSAGetLastError(); - - void *ptr = TlsGetValue (key->key); - - SetLastError( lasterror ); - WSASetLastError( lastWSAerror ); - - return ptr; -} -- cgit v1.2.3