1 /* thread.cc: Locking and threading module functions
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
12 /* Implementation overview and caveats:
14 Win32 puts some contraints on what can and cannot be implemented. Where
15 possible we work around those contrainsts. Where we cannot work around
16 the constraints we either pretend to be conformant, or return an error
19 Some caveats: PROCESS_SHARED objects, while they pretend to be process
20 shared, may not actually work. Some test cases are needed to determine
21 win32's behaviour. My suspicion is that the win32 handle needs to be
22 opened with different flags for proper operation.
24 R.Collins, April 2001. */
27 #include "miscfuncs.h"
32 #include "perprocess.h"
38 #include "miscfuncs.h"
40 extern "C" void __fp_lock_all ();
41 extern "C" void __fp_unlock_all ();
42 extern "C" int valid_sched_parameters(const struct sched_param *);
43 extern "C" int sched_set_thread_priority(HANDLE thread, int priority);
44 static inline verifyable_object_state
45 verifyable_object_isvalid (void const * objectptr, thread_magic_t magic,
46 void *static_ptr1 = NULL,
47 void *static_ptr2 = NULL,
48 void *static_ptr3 = NULL);
50 extern int threadsafe;
52 const pthread_t pthread_mutex::_new_mutex = (pthread_t) 1;
53 const pthread_t pthread_mutex::_unlocked_mutex = (pthread_t) 2;
54 const pthread_t pthread_mutex::_destroyed_mutex = (pthread_t) 3;
57 pthread_mutex::no_owner()
62 debug_printf ("NULL owner value");
65 else if (owner == _destroyed_mutex)
67 paranoid_printf ("attempt to use destroyed mutex");
70 else if (owner == _new_mutex || owner == _unlocked_mutex)
78 extern "C" struct _reent *
81 return &_my_tls.local_clib;
85 __cygwin_lock_init (_LOCK_T *lock)
87 *lock = _LOCK_T_INITIALIZER;
91 __cygwin_lock_init_recursive (_LOCK_T *lock)
93 *lock = _LOCK_T_RECURSIVE_INITIALIZER;
97 __cygwin_lock_fini (_LOCK_T *lock)
99 pthread_mutex_destroy ((pthread_mutex_t*) lock);
103 __cygwin_lock_lock (_LOCK_T *lock)
105 paranoid_printf ("threadcount %d. locking", MT_INTERFACE->threadcount);
106 pthread_mutex_lock ((pthread_mutex_t*) lock);
110 __cygwin_lock_trylock (_LOCK_T *lock)
112 return pthread_mutex_trylock ((pthread_mutex_t*) lock);
117 __cygwin_lock_unlock (_LOCK_T *lock)
119 pthread_mutex_unlock ((pthread_mutex_t*) lock);
120 paranoid_printf ("threadcount %d. unlocked", MT_INTERFACE->threadcount);
123 static inline verifyable_object_state
124 verifyable_object_isvalid (void const *objectptr, thread_magic_t magic, void *static_ptr1,
125 void *static_ptr2, void *static_ptr3)
128 if (efault.faulted (objectptr))
129 return INVALID_OBJECT;
131 verifyable_object **object = (verifyable_object **) objectptr;
133 if ((static_ptr1 && *object == static_ptr1) ||
134 (static_ptr2 && *object == static_ptr2) ||
135 (static_ptr3 && *object == static_ptr3))
136 return VALID_STATIC_OBJECT;
137 if ((*object)->magic != magic)
138 return INVALID_OBJECT;
144 pthread_attr::is_good_object (pthread_attr_t const *attr)
146 if (verifyable_object_isvalid (attr, PTHREAD_ATTR_MAGIC) != VALID_OBJECT)
152 pthread_condattr::is_good_object (pthread_condattr_t const *attr)
154 if (verifyable_object_isvalid (attr, PTHREAD_CONDATTR_MAGIC) != VALID_OBJECT)
160 pthread_rwlockattr::is_good_object (pthread_rwlockattr_t const *attr)
162 if (verifyable_object_isvalid (attr, PTHREAD_RWLOCKATTR_MAGIC) != VALID_OBJECT)
168 pthread_key::is_good_object (pthread_key_t const *key)
170 if (verifyable_object_isvalid (key, PTHREAD_KEY_MAGIC) != VALID_OBJECT)
176 pthread_spinlock::is_good_object (pthread_spinlock_t const *mutex)
178 if (verifyable_object_isvalid (mutex, PTHREAD_SPINLOCK_MAGIC) != VALID_OBJECT)
184 pthread_mutex::is_good_object (pthread_mutex_t const *mutex)
186 if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)
192 pthread_mutex::is_initializer (pthread_mutex_t const *mutex)
194 if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC,
195 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
196 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP,
197 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP) != VALID_STATIC_OBJECT)
203 pthread_mutex::is_initializer_or_object (pthread_mutex_t const *mutex)
205 if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC,
206 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
207 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP,
208 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP) == INVALID_OBJECT)
213 /* FIXME: Accommodate PTHREAD_MUTEX_ERRORCHECK */
215 pthread_mutex::can_be_unlocked ()
217 pthread_t self = pthread::self ();
218 /* Check if the mutex is owned by the current thread and can be unlocked.
219 * Also check for the ANONYMOUS owner to cover NORMAL mutexes as well. */
220 bool res = type == PTHREAD_MUTEX_NORMAL || no_owner ()
221 || (recursion_counter == 1 && pthread::equal (owner, self));
222 pthread_printf ("recursion_counter %d res %d", recursion_counter, res);
227 pthread_mutexattr::is_good_object (pthread_mutexattr_t const * attr)
229 if (verifyable_object_isvalid (attr, PTHREAD_MUTEXATTR_MAGIC) != VALID_OBJECT)
234 inline bool __attribute__ ((used))
235 pthread::is_good_object (pthread_t const *thread)
237 if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
242 /* Thread synchronisation */
244 pthread_cond::is_good_object (pthread_cond_t const *cond)
246 if (verifyable_object_isvalid (cond, PTHREAD_COND_MAGIC) != VALID_OBJECT)
252 pthread_cond::is_initializer (pthread_cond_t const *cond)
254 if (verifyable_object_isvalid (cond, PTHREAD_COND_MAGIC, PTHREAD_COND_INITIALIZER) != VALID_STATIC_OBJECT)
260 pthread_cond::is_initializer_or_object (pthread_cond_t const *cond)
262 if (verifyable_object_isvalid (cond, PTHREAD_COND_MAGIC, PTHREAD_COND_INITIALIZER) == INVALID_OBJECT)
269 pthread_rwlock::is_good_object (pthread_rwlock_t const *rwlock)
271 if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC) != VALID_OBJECT)
277 pthread_rwlock::is_initializer (pthread_rwlock_t const *rwlock)
279 if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC, PTHREAD_RWLOCK_INITIALIZER) != VALID_STATIC_OBJECT)
285 pthread_rwlock::is_initializer_or_object (pthread_rwlock_t const *rwlock)
287 if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC, PTHREAD_RWLOCK_INITIALIZER) == INVALID_OBJECT)
293 semaphore::is_good_object (sem_t const * sem)
295 if (verifyable_object_isvalid (sem, SEM_MAGIC) != VALID_OBJECT)
303 pthread_mutex::init_mutex ();
304 pthread_cond::init_mutex ();
305 pthread_rwlock::init_mutex ();
309 MTinterface::fixup_before_fork ()
311 pthread_key::fixup_before_fork ();
314 /* This function is called from a single threaded process */
316 MTinterface::fixup_after_fork ()
318 pthread_key::fixup_after_fork ();
321 pthread::init_mainthread ();
323 pthread::fixup_after_fork ();
324 pthread_mutex::fixup_after_fork ();
325 pthread_cond::fixup_after_fork ();
326 pthread_rwlock::fixup_after_fork ();
327 semaphore::fixup_after_fork ();
334 pthread::init_mainthread ()
336 pthread *thread = _my_tls.tid;
339 thread = new pthread ();
341 api_fatal ("failed to create mainthread object");
344 set_tls_self_pointer (thread);
345 thread->thread_id = GetCurrentThreadId ();
346 if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
347 GetCurrentProcess (), &thread->win32_obj_id,
348 0, FALSE, DUPLICATE_SAME_ACCESS))
349 api_fatal ("failed to create mainthread handle");
350 if (!thread->create_cancel_event ())
351 api_fatal ("couldn't create cancel event for main thread");
352 VerifyHandle (thread->win32_obj_id);
353 thread->postcreate ();
359 pthread *thread = _my_tls.tid;
362 thread = pthread_null::get_null_pthread ();
363 set_tls_self_pointer (thread);
369 pthread::set_tls_self_pointer (pthread *thread)
371 thread->cygtls = &_my_tls;
372 _my_tls.tid = thread;
375 List<pthread> pthread::threads;
378 pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0),
379 valid (false), suspended (false), canceled (false),
380 cancelstate (0), canceltype (0), cancel_event (0),
381 joiner (NULL), next (NULL), cleanup_stack (NULL)
383 if (this != pthread_null::get_null_pthread ())
384 threads.insert (this);
385 sigprocmask (SIG_SETMASK, NULL, &parent_sigmask);
391 CloseHandle (win32_obj_id);
393 CloseHandle (cancel_event);
395 if (this != pthread_null::get_null_pthread ())
396 threads.remove (this);
400 pthread::create_cancel_event ()
402 cancel_event = ::CreateEvent (&sec_none_nih, true, false, NULL);
405 system_printf ("couldn't create cancel event, %E");
406 /* we need the event for correct behaviour */
413 pthread::precreate (pthread_attr *newattr)
415 pthread_mutex *verifyable_mutex_obj = &mutex;
417 /* already running ? */
423 attr.joinable = newattr->joinable;
424 attr.contentionscope = newattr->contentionscope;
425 attr.inheritsched = newattr->inheritsched;
426 attr.stackaddr = newattr->stackaddr;
427 attr.stacksize = newattr->stacksize;
428 attr.guardsize = newattr->guardsize;
431 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
433 thread_printf ("New thread object access mutex is not valid. this %p",
438 /* Change the mutex type to NORMAL to speed up mutex operations */
439 mutex.set_type (PTHREAD_MUTEX_NORMAL);
440 if (!create_cancel_event ())
445 pthread::create (void *(*func) (void *), pthread_attr *newattr,
458 win32_obj_id = CygwinCreateThread (thread_init_wrapper, this,
459 attr.stackaddr, attr.stacksize,
460 attr.guardsize, 0, &thread_id);
464 thread_printf ("CreateThread failed: this %p, %E", this);
479 pthread::postcreate ()
483 InterlockedIncrement (&MT_INTERFACE->threadcount);
484 /* FIXME: set the priority appropriately for system contention scope */
485 if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED)
487 /* FIXME: set the scheduling settings for the new thread */
488 /* sched_thread_setparam (win32_obj_id, attr.schedparam); */
493 pthread::exit (void *value_ptr)
495 class pthread *thread = this;
497 // run cleanup handlers
498 pop_all_cleanup_handlers ();
500 pthread_key::run_all_destructors ();
503 // cleanup if thread is in detached state and not joined
504 if (equal (joiner, thread))
509 return_ptr = value_ptr;
513 if (_my_tls.local_clib.__sdidinit < 0)
514 _my_tls.local_clib.__sdidinit = 0;
515 (_reclaim_reent) (_REENT);
517 if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0)
521 if (cygtls == _main_tls)
523 _cygtls *dummy = (_cygtls *) malloc (sizeof (_cygtls));
526 _main_tls->initialized = false;
535 class pthread *thread = this;
536 class pthread *self = pthread::self ();
546 if (canceltype == PTHREAD_CANCEL_DEFERRED ||
547 cancelstate == PTHREAD_CANCEL_DISABLE)
552 SetEvent (cancel_event);
555 else if (equal (thread, self))
559 return 0; // Never reached
562 // cancel asynchronous
563 SuspendThread (win32_obj_id);
564 if (WaitForSingleObject (win32_obj_id, 0) == WAIT_TIMEOUT)
567 context.ContextFlags = CONTEXT_CONTROL;
568 GetThreadContext (win32_obj_id, &context);
569 context.Eip = (DWORD) pthread::static_cancel_self;
570 SetThreadContext (win32_obj_id, &context);
573 ResumeThread (win32_obj_id);
578 /* TODO: Insert pthread_testcancel into the required functions.
580 Here are the lists of required and optional functions per POSIX.1-2001
581 and POSIX.1-2008. A star (*) indicates that the Cygwin function already
582 is a cancellation point (aka "calls pthread_testcancel"), an o (o)
583 indicates that the function is not implemented in Cygwin.
585 Required cancellation points:
613 * pthread_cond_timedwait ()
614 * pthread_cond_wait ()
616 * pthread_testcancel ()
647 Optional cancellation points:
652 catclose () Implemented externally: libcatgets
653 catgets () Implemented externally: libcatgets
654 catopen () Implemented externally: libcatgets
662 dbm_close () Implemented externally: libgdbm
663 dbm_delete () Implemented externally: libgdbm
664 dbm_fetch () Implemented externally: libgdbm
665 dbm_nextkey () Implemented externally: libgdbm
666 dbm_open () Implemented externally: libgdbm
667 dbm_store () Implemented externally: libgdbm
684 * fcntl () (any value)
739 getopt () (if opterr is nonzero)
759 iconv_close () Implemented externally: libiconv
760 iconv_open () Implemented externally: libiconv
792 o posix_trace_clear ()
793 o posix_trace_close ()
794 o posix_trace_create ()
795 o posix_trace_create_withlog ()
796 o posix_trace_eventtypelist_getnext_id ()
797 o posix_trace_eventtypelist_rewind ()
798 o posix_trace_flush ()
799 o posix_trace_get_attr ()
800 o posix_trace_get_filter ()
801 o posix_trace_get_status ()
802 o posix_trace_getnext_event ()
803 o posix_trace_open ()
804 o posix_trace_rewind ()
805 o posix_trace_set_filter ()
806 o posix_trace_shutdown ()
807 o posix_trace_timedgetnext_event ()
808 o posix_typed_mem_open ()
812 pthread_rwlock_rdlock ()
813 pthread_rwlock_timedrdlock ()
814 pthread_rwlock_timedwrlock ()
815 pthread_rwlock_wrlock ()
875 An implementation may also mark other functions not specified in the
876 standard as cancellation points. In particular, an implementation is
877 likely to mark any nonstandard function that may block as a
878 cancellation point. */
881 pthread::testcancel ()
883 if (cancelstate == PTHREAD_CANCEL_DISABLE)
886 /* We check for the canceled flag first. This allows to use the
887 pthread_testcancel function a lot without adding the overhead of
888 an OS call. Only if the thread is marked as canceled, we wait for
889 cancel_event being really set, on the off-chance that pthread_cancel
890 gets interrupted before calling SetEvent. */
893 WaitForSingleObject (cancel_event, INFINITE);
898 /* Return cancel event handle if it exists *and* cancel is not disabled.
899 This function is supposed to be used from other functions which are
900 cancelable and need the cancel event in a WFMO call. */
902 pthread::get_cancel_event ()
904 pthread_t thread = pthread::self ();
906 return (thread && thread->cancel_event
907 && thread->cancelstate != PTHREAD_CANCEL_DISABLE)
908 ? thread->cancel_event : NULL;
912 pthread::static_cancel_self ()
914 pthread::self ()->cancel_self ();
918 cancelable_wait (HANDLE object, PLARGE_INTEGER timeout,
919 const cw_cancel_action cancel_action,
920 const enum cw_sig_wait sig_wait)
924 HANDLE wait_objects[4];
925 pthread_t thread = pthread::self ();
927 /* Do not change the wait order.
928 The object must have higher priority than the cancel event,
929 because WaitForMultipleObjects will return the smallest index
930 if both objects are signaled. */
931 wait_objects[num++] = object;
933 if (cancel_action == cw_no_cancel || !pthread::is_good_object (&thread) ||
934 thread->cancelstate == PTHREAD_CANCEL_DISABLE)
935 cancel_n = WAIT_TIMEOUT + 1;
938 cancel_n = WAIT_OBJECT_0 + num++;
939 wait_objects[cancel_n] = thread->cancel_event;
943 if (sig_wait == cw_sig_nosig)
944 sig_n = WAIT_TIMEOUT + 1;
947 sig_n = WAIT_OBJECT_0 + num++;
948 wait_objects[sig_n] = signal_arrived;
953 timeout_n = WAIT_TIMEOUT + 1;
956 timeout_n = WAIT_OBJECT_0 + num++;
957 if (!_my_tls.locals.cw_timer)
958 NtCreateTimer (&_my_tls.locals.cw_timer, TIMER_ALL_ACCESS, NULL,
960 NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
961 wait_objects[timeout_n] = _my_tls.locals.cw_timer;
966 res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
969 if (cancel_action == cw_cancel_self)
970 pthread::static_cancel_self ();
973 else if (res == timeout_n)
975 else if (res != sig_n)
977 else if (sig_wait == cw_sig_eintr)
981 _my_tls.call_signal_handler ();
989 const size_t sizeof_tbi = sizeof (TIMER_BASIC_INFORMATION);
990 PTIMER_BASIC_INFORMATION tbi = (PTIMER_BASIC_INFORMATION) malloc (sizeof_tbi);
992 NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, tbi,
994 /* if timer expired, TimeRemaining is negative and represents the
995 system uptime when signalled */
996 if (timeout->QuadPart < 0LL)
997 timeout->QuadPart = tbi->SignalState ? 0LL : tbi->TimeRemaining.QuadPart;
998 NtCancelTimer (_my_tls.locals.cw_timer, NULL);
1005 pthread::setcancelstate (int state, int *oldstate)
1011 if (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE)
1016 *oldstate = cancelstate;
1017 cancelstate = state;
1026 pthread::setcanceltype (int type, int *oldtype)
1032 if (type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS)
1037 *oldtype = canceltype;
1047 pthread::push_cleanup_handler (__pthread_cleanup_handler *handler)
1049 if (this != self ())
1051 api_fatal ("Attempt to push a cleanup handler across threads");
1052 handler->next = cleanup_stack;
1053 cleanup_stack = handler;
1057 pthread::pop_cleanup_handler (int const execute)
1059 if (this != self ())
1060 // TODO: send a signal or something to the thread ?
1061 api_fatal ("Attempt to execute a cleanup handler across threads");
1065 if (cleanup_stack != NULL)
1067 __pthread_cleanup_handler *handler = cleanup_stack;
1070 (*handler->function) (handler->arg);
1071 cleanup_stack = handler->next;
1078 pthread::pop_all_cleanup_handlers ()
1080 while (cleanup_stack != NULL)
1081 pop_cleanup_handler (1);
1085 pthread::cancel_self ()
1087 /* Can someone explain why the pthread:: is needed here? g++ complains
1089 pthread::exit (PTHREAD_CANCELED);
1093 pthread::get_thread_id ()
1099 pthread::_fixup_after_fork ()
1101 /* set thread to not running if it is not the forking thread */
1102 if (this != pthread::self ())
1106 win32_obj_id = NULL;
1108 cancel_event = NULL;
1113 pthread::suspend_except_self ()
1115 if (valid && this != pthread::self ())
1116 SuspendThread (win32_obj_id);
1123 ResumeThread (win32_obj_id);
1126 /* instance members */
1128 pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC),
1129 joinable (PTHREAD_CREATE_JOINABLE), contentionscope (PTHREAD_SCOPE_PROCESS),
1130 inheritsched (PTHREAD_INHERIT_SCHED), stackaddr (NULL), stacksize (0),
1131 guardsize ((size_t) -1)
1133 schedparam.sched_priority = 0;
1136 pthread_attr::~pthread_attr ()
1140 pthread_condattr::pthread_condattr ():verifyable_object
1141 (PTHREAD_CONDATTR_MAGIC), shared (PTHREAD_PROCESS_PRIVATE),
1142 clock_id (CLOCK_REALTIME)
1146 pthread_condattr::~pthread_condattr ()
1150 List<pthread_cond> pthread_cond::conds;
1152 /* This is used for cond creation protection within a single process only */
1153 fast_mutex NO_COPY pthread_cond::cond_initialization_lock;
1155 /* We can only be called once.
1156 TODO: (no rush) use a non copied memory section to
1157 hold an initialization flag. */
1159 pthread_cond::init_mutex ()
1161 if (!cond_initialization_lock.init ())
1162 api_fatal ("Could not create win32 Mutex for pthread cond static initializer support.");
1165 pthread_cond::pthread_cond (pthread_condattr *attr) :
1166 verifyable_object (PTHREAD_COND_MAGIC),
1167 shared (0), clock_id (CLOCK_REALTIME), waiting (0), pending (0),
1168 sem_wait (NULL), mtx_cond(NULL), next (NULL)
1170 pthread_mutex *verifyable_mutex_obj;
1174 clock_id = attr->clock_id;
1176 if (attr->shared != PTHREAD_PROCESS_PRIVATE)
1183 verifyable_mutex_obj = &mtx_in;
1184 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
1186 thread_printf ("Internal cond mutex is not valid. this %p", this);
1191 * Change the mutex type to NORMAL.
1192 * This mutex MUST be of type normal
1194 mtx_in.set_type (PTHREAD_MUTEX_NORMAL);
1196 verifyable_mutex_obj = &mtx_out;
1197 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
1199 thread_printf ("Internal cond mutex is not valid. this %p", this);
1203 /* Change the mutex type to NORMAL to speed up mutex operations */
1204 mtx_out.set_type (PTHREAD_MUTEX_NORMAL);
1206 sem_wait = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
1209 pthread_printf ("CreateSemaphore failed. %E");
1214 conds.insert (this);
1217 pthread_cond::~pthread_cond ()
1220 CloseHandle (sem_wait);
1222 conds.remove (this);
1226 pthread_cond::unblock (const bool all)
1228 unsigned long releaseable;
1231 * Block outgoing threads (and avoid simultanous unblocks)
1235 releaseable = waiting - pending;
1238 unsigned long released;
1243 * Block incoming threads until all waiting threads are released.
1248 * Calculate releaseable again because threads can enter until
1249 * the semaphore has been taken, but they can not leave, therefore pending
1250 * is unchanged and releaseable can only get higher
1252 releaseable = waiting - pending;
1255 released = all ? releaseable : 1;
1256 pending += released;
1260 ::ReleaseSemaphore (sem_wait, released, NULL);
1264 * And let the threads release.
1270 pthread_cond::wait (pthread_mutex_t mutex, PLARGE_INTEGER timeout)
1275 if (InterlockedIncrement ((long *)&waiting) == 1)
1277 else if (mtx_cond != mutex)
1279 InterlockedDecrement ((long *)&waiting);
1286 * Release the mutex and wait on semaphore
1291 rv = cancelable_wait (sem_wait, timeout, cw_no_cancel_self, cw_sig_eintr);
1295 if (rv != WAIT_OBJECT_0)
1298 * It might happen that a signal is sent while the thread got canceled
1299 * or timed out. Try to take one.
1300 * If the thread gets one than a signal|broadcast is in progress.
1302 if (WaitForSingleObject (sem_wait, 0) == WAIT_OBJECT_0)
1304 * thread got cancelled ot timed out while a signalling is in progress.
1305 * Set wait result back to signaled
1310 InterlockedDecrement ((long *)&waiting);
1312 if (rv == WAIT_OBJECT_0 && --pending == 0)
1314 * All signaled threads are released,
1315 * new threads can enter Wait
1324 if (rv == WAIT_CANCELED)
1325 pthread::static_cancel_self ();
1326 else if (rv == WAIT_SIGNALED)
1327 /* SUSv3 states: If a signal is delivered to a thread waiting for a
1328 condition variable, upon return from the signal handler the thread
1329 resumes waiting for the condition variable as if it was not
1330 interrupted, or it shall return zero due to spurious wakeup.
1331 We opt for the latter choice here. */
1333 else if (rv == WAIT_TIMEOUT)
1340 pthread_cond::_fixup_after_fork ()
1342 waiting = pending = 0;
1345 /* Unlock eventually locked mutexes */
1349 sem_wait = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
1351 api_fatal ("pthread_cond::_fixup_after_fork () failed to recreate win32 semaphore");
1354 pthread_rwlockattr::pthread_rwlockattr ():verifyable_object
1355 (PTHREAD_RWLOCKATTR_MAGIC), shared (PTHREAD_PROCESS_PRIVATE)
1359 pthread_rwlockattr::~pthread_rwlockattr ()
1363 List<pthread_rwlock> pthread_rwlock::rwlocks;
1365 /* This is used for rwlock creation protection within a single process only */
1366 fast_mutex NO_COPY pthread_rwlock::rwlock_initialization_lock;
1368 /* We can only be called once.
1369 TODO: (no rush) use a non copied memory section to
1370 hold an initialization flag. */
1372 pthread_rwlock::init_mutex ()
1374 if (!rwlock_initialization_lock.init ())
1375 api_fatal ("Could not create win32 Mutex for pthread rwlock static initializer support.");
1378 pthread_rwlock::pthread_rwlock (pthread_rwlockattr *attr) :
1379 verifyable_object (PTHREAD_RWLOCK_MAGIC),
1380 shared (0), waiting_readers (0), waiting_writers (0), writer (NULL),
1381 readers (NULL), readers_mx (), mtx (NULL), cond_readers (NULL), cond_writers (NULL),
1384 pthread_mutex *verifyable_mutex_obj = &mtx;
1385 pthread_cond *verifyable_cond_obj;
1387 if (!readers_mx.init ())
1389 thread_printf ("Internal rwlock synchronisation mutex is not valid. this %p", this);
1395 if (attr->shared != PTHREAD_PROCESS_PRIVATE)
1401 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
1403 thread_printf ("Internal rwlock mutex is not valid. this %p", this);
1407 /* Change the mutex type to NORMAL to speed up mutex operations */
1408 mtx.set_type (PTHREAD_MUTEX_NORMAL);
1410 verifyable_cond_obj = &cond_readers;
1411 if (!pthread_cond::is_good_object (&verifyable_cond_obj))
1413 thread_printf ("Internal rwlock readers cond is not valid. this %p", this);
1418 verifyable_cond_obj = &cond_writers;
1419 if (!pthread_cond::is_good_object (&verifyable_cond_obj))
1421 thread_printf ("Internal rwlock writers cond is not valid. this %p", this);
1427 rwlocks.insert (this);
1430 pthread_rwlock::~pthread_rwlock ()
1432 rwlocks.remove (this);
1436 pthread_rwlock::rdlock ()
1439 struct RWLOCK_READER *reader;
1440 pthread_t self = pthread::self ();
1444 reader = lookup_reader (self);
1447 if (reader->n < ULONG_MAX)
1454 reader = new struct RWLOCK_READER;
1461 while (writer || waiting_writers)
1463 pthread_cleanup_push (pthread_rwlock::rdlock_cleanup, this);
1466 cond_readers.wait (&mtx);
1469 pthread_cleanup_pop (0);
1472 reader->thread = self;
1474 add_reader (reader);
1483 pthread_rwlock::tryrdlock ()
1486 pthread_t self = pthread::self ();
1490 if (writer || waiting_writers || lookup_reader (self))
1494 struct RWLOCK_READER *reader;
1496 reader = lookup_reader (self);
1497 if (reader && reader->n < ULONG_MAX)
1499 else if ((reader = new struct RWLOCK_READER))
1501 reader->thread = self;
1503 add_reader (reader);
1515 pthread_rwlock::wrlock ()
1518 pthread_t self = pthread::self ();
1522 if (writer == self || lookup_reader (self))
1528 while (writer || readers)
1530 pthread_cleanup_push (pthread_rwlock::wrlock_cleanup, this);
1533 cond_writers.wait (&mtx);
1536 pthread_cleanup_pop (0);
1548 pthread_rwlock::trywrlock ()
1551 pthread_t self = pthread::self ();
1555 if (writer || readers)
1566 pthread_rwlock::unlock ()
1569 pthread_t self = pthread::self ();
1585 struct RWLOCK_READER *reader = lookup_reader (self);
1592 if (--reader->n > 0)
1595 remove_reader (reader);
1608 pthread_rwlock::add_reader (struct RWLOCK_READER *rd)
1610 List_insert (readers, rd);
1614 pthread_rwlock::remove_reader (struct RWLOCK_READER *rd)
1616 List_remove (readers_mx, readers, rd);
1619 struct pthread_rwlock::RWLOCK_READER *
1620 pthread_rwlock::lookup_reader (pthread_t thread)
1624 struct RWLOCK_READER *cur = readers;
1626 while (cur && cur->thread != thread)
1629 readers_mx.unlock ();
1635 pthread_rwlock::rdlock_cleanup (void *arg)
1637 pthread_rwlock *rwlock = (pthread_rwlock *) arg;
1639 --(rwlock->waiting_readers);
1641 rwlock->mtx.unlock ();
1645 pthread_rwlock::wrlock_cleanup (void *arg)
1647 pthread_rwlock *rwlock = (pthread_rwlock *) arg;
1649 --(rwlock->waiting_writers);
1651 rwlock->mtx.unlock ();
1655 pthread_rwlock::_fixup_after_fork ()
1657 pthread_t self = pthread::self ();
1658 struct RWLOCK_READER **temp = &readers;
1660 waiting_readers = 0;
1661 waiting_writers = 0;
1663 if (!readers_mx.init ())
1664 api_fatal ("pthread_rwlock::_fixup_after_fork () failed to recreate mutex");
1666 /* Unlock eventually locked mutex */
1669 * Remove all readers except self
1673 if ((*temp)->thread == self)
1674 temp = &((*temp)->next);
1677 struct RWLOCK_READER *cur = *temp;
1678 *temp = (*temp)->next;
1685 /* static members */
1686 /* This stores pthread_key information across fork() boundaries */
1687 List<pthread_key> pthread_key::keys;
1689 /* non-static members */
1691 pthread_key::pthread_key (void (*aDestructor) (void *)):verifyable_object (PTHREAD_KEY_MAGIC), destructor (aDestructor)
1693 tls_index = TlsAlloc ();
1694 if (tls_index == TLS_OUT_OF_INDEXES)
1700 pthread_key::~pthread_key ()
1702 /* We may need to make the list code lock the list during operations
1707 TlsFree (tls_index);
1712 pthread_key::_fixup_before_fork ()
1718 pthread_key::_fixup_after_fork ()
1720 tls_index = TlsAlloc ();
1721 if (tls_index == TLS_OUT_OF_INDEXES)
1722 api_fatal ("pthread_key::recreate_key_from_buffer () failed to reallocate Tls storage");
1727 pthread_key::run_destructor ()
1731 void *oldValue = get ();
1735 destructor (oldValue);
1740 /* pshared mutexs */
1742 /* static members */
1744 List<pthread_mutex> pthread_mutex::mutexes;
1746 /* This is used for mutex creation protection within a single process only */
1747 fast_mutex NO_COPY pthread_mutex::mutex_initialization_lock;
1750 pthread_mutex::init_mutex ()
1752 if (!mutex_initialization_lock.init ())
1753 api_fatal ("Could not create win32 Mutex for pthread mutex static initializer support.");
1756 pthread_mutex::pthread_mutex (pthread_mutexattr *attr) :
1757 verifyable_object (0), /* set magic to zero initially */
1759 win32_obj_id (NULL), owner (_new_mutex),
1763 recursion_counter (0), condwaits (0),
1764 type (PTHREAD_MUTEX_ERRORCHECK),
1765 pshared (PTHREAD_PROCESS_PRIVATE)
1767 win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL);
1770 /*attr checked in the C call */
1772 /* handled in the caller */;
1773 else if (attr->pshared != PTHREAD_PROCESS_SHARED)
1774 type = attr->mutextype;
1776 return; /* Not implemented */
1778 magic = PTHREAD_MUTEX_MAGIC;
1779 mutexes.insert (this);
1782 pthread_mutex::~pthread_mutex ()
1786 CloseHandle (win32_obj_id);
1787 win32_obj_id = NULL;
1790 mutexes.remove (this);
1791 owner = _destroyed_mutex;
1796 pthread_mutex::lock ()
1798 pthread_t self = ::pthread_self ();
1801 if (InterlockedIncrement ((long *) &lock_counter) == 1)
1803 else if (type == PTHREAD_MUTEX_NORMAL /* potentially causes deadlock */
1804 || !pthread::equal (owner, self))
1806 cancelable_wait (win32_obj_id, NULL, cw_no_cancel, cw_sig_resume);
1811 InterlockedDecrement ((long *) &lock_counter);
1812 if (type == PTHREAD_MUTEX_RECURSIVE)
1813 result = lock_recursive ();
1818 pthread_printf ("mutex %p, self %p, owner %p, lock_counter %d, recursion_counter %d",
1819 this, self, owner, lock_counter, recursion_counter);
1824 pthread_mutex::unlock ()
1827 pthread_t self = ::pthread_self ();
1828 if (type == PTHREAD_MUTEX_NORMAL)
1829 /* no error checking */;
1830 else if (no_owner ())
1831 res = type == PTHREAD_MUTEX_ERRORCHECK ? EINVAL : 0;
1832 else if (!pthread::equal (owner, self))
1834 if (!res && recursion_counter > 0 && --recursion_counter == 0)
1835 /* Don't try to unlock anything if recursion_counter == 0.
1836 This means the mutex was never locked or that we've forked. */
1838 owner = (pthread_t) _unlocked_mutex;
1842 if (InterlockedDecrement ((long *) &lock_counter))
1843 ::SetEvent (win32_obj_id); // Another thread is waiting
1847 pthread_printf ("mutex %p, owner %p, self %p, lock_counter %d, recursion_counter %d, type %d, res %d",
1848 this, owner, self, lock_counter, recursion_counter, type, res);
1853 pthread_mutex::trylock ()
1855 pthread_t self = ::pthread_self ();
1858 if (InterlockedCompareExchange ((long *) &lock_counter, 1, 0) == 0)
1860 else if (type == PTHREAD_MUTEX_RECURSIVE && pthread::equal (owner, self))
1861 result = lock_recursive ();
1869 pthread_mutex::destroy ()
1871 if (condwaits || trylock ())
1872 // Do not destroy a condwaited or locked mutex
1874 else if (recursion_counter > 1)
1876 // Do not destroy a recursive locked mutex
1877 recursion_counter--;
1886 pthread_mutex::_fixup_after_fork ()
1888 pthread_printf ("mutex %p", this);
1889 if (pshared != PTHREAD_PROCESS_PRIVATE)
1890 api_fatal ("pthread_mutex::_fixup_after_fork () doesn't understand PROCESS_SHARED mutex's");
1892 /* All waiting threads are gone after a fork */
1893 recursion_counter = 0;
1897 tid = 0xffffffff; /* Don't know the tid after a fork */
1899 win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL);
1901 api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 event for mutex");
1904 pthread_mutexattr::pthread_mutexattr ():verifyable_object (PTHREAD_MUTEXATTR_MAGIC),
1905 pshared (PTHREAD_PROCESS_PRIVATE), mutextype (PTHREAD_MUTEX_ERRORCHECK)
1909 pthread_mutexattr::~pthread_mutexattr ()
1913 /* pshared spinlocks
1915 The infrastructure is provided by the underlying pthread_mutex class.
1916 The rest is a simplification implementing spin locking. */
1918 pthread_spinlock::pthread_spinlock (int pshared) :
1919 pthread_mutex (NULL)
1921 magic = PTHREAD_SPINLOCK_MAGIC;
1922 set_type (PTHREAD_MUTEX_NORMAL);
1923 set_shared (pshared);
1927 pthread_spinlock::lock ()
1929 pthread_t self = ::pthread_self ();
1934 if (InterlockedExchange ((long *) &lock_counter, 1) == 0)
1939 else if (pthread::equal (owner, self))
1943 /* Minimal timeout to minimize CPU usage while still spinning. */
1944 LARGE_INTEGER timeout;
1945 timeout.QuadPart = -10000LL;
1946 cancelable_wait (win32_obj_id, &timeout, cw_no_cancel, cw_sig_resume);
1949 while (result == -1);
1950 pthread_printf ("spinlock %p, self %p, owner %p", this, self, owner);
1955 pthread_spinlock::unlock ()
1957 pthread_t self = ::pthread_self ();
1960 if (!pthread::equal (owner, self))
1964 owner = (pthread_t) _unlocked_mutex;
1968 InterlockedExchange ((long *) &lock_counter, 0);
1969 ::SetEvent (win32_obj_id);
1972 pthread_printf ("spinlock %p, owner %p, self %p, res %d",
1973 this, owner, self, result);
1978 pthread::thread_init_wrapper (void *arg)
1980 pthread *thread = (pthread *) arg;
1981 set_tls_self_pointer (thread);
1983 thread->mutex.lock ();
1985 // if thread is detached force cleanup on exit
1986 if (thread->attr.joinable == PTHREAD_CREATE_DETACHED && thread->joiner == NULL)
1987 thread->joiner = thread;
1988 _my_tls.sigmask = thread->parent_sigmask;
1989 thread->mutex.unlock ();
1991 thread_printf ("started thread %p %p %p %p %p %p", arg, &_my_tls.local_clib,
1992 _impure_ptr, thread, thread->function, thread->arg);
1994 // call the user's thread
1995 void *ret = thread->function (thread->arg);
1999 return 0; // just for show. Never returns.
2003 pthread::getsequence_np ()
2005 return get_thread_id ();
2009 pthread::create (pthread_t *thread, const pthread_attr_t *attr,
2010 void *(*start_routine) (void *), void *arg)
2012 if (attr && !pthread_attr::is_good_object (attr))
2015 *thread = new pthread ();
2016 if (!(*thread)->create (start_routine, attr ? *attr : NULL, arg))
2027 pthread::once (pthread_once_t *once_control, void (*init_routine) (void))
2030 if (once_control->state)
2033 pthread_mutex_lock (&once_control->mutex);
2034 /* Here we must set a cancellation handler to unlock the mutex if needed */
2035 /* but a cancellation handler is not the right thing. We need this in the thread
2036 *cleanup routine. Assumption: a thread can only be in one pthread_once routine
2037 *at a time. Stote a mutex_t *in the pthread_structure. if that's non null unlock
2038 *on pthread_exit ();
2040 if (!once_control->state)
2043 once_control->state = 1;
2045 /* Here we must remove our cancellation handler */
2046 pthread_mutex_unlock (&once_control->mutex);
2051 pthread::cancel (pthread_t thread)
2053 if (!is_good_object (&thread))
2056 return thread->cancel ();
2060 pthread::atforkprepare ()
2062 callback *cb = MT_INTERFACE->pthread_prepare;
2071 MT_INTERFACE->fixup_before_fork ();
2075 pthread::atforkparent ()
2079 callback *cb = MT_INTERFACE->pthread_parent;
2088 pthread::atforkchild ()
2090 MT_INTERFACE->fixup_after_fork ();
2094 callback *cb = MT_INTERFACE->pthread_child;
2102 /* Register a set of functions to run before and after fork.
2103 prepare calls are called in LI-FC order.
2104 parent and child calls are called in FI-FC order. */
2106 pthread::atfork (void (*prepare)(void), void (*parent)(void), void (*child)(void))
2108 callback *prepcb = NULL, *parentcb = NULL, *childcb = NULL;
2111 prepcb = new callback;
2117 parentcb = new callback;
2127 childcb = new callback;
2140 prepcb->cb = prepare;
2141 List_insert (MT_INTERFACE->pthread_prepare, prepcb);
2145 parentcb->cb = parent;
2146 callback **t = &MT_INTERFACE->pthread_parent;
2149 /* t = pointer to last next in the list */
2150 List_insert (*t, parentcb);
2154 childcb->cb = child;
2155 callback **t = &MT_INTERFACE->pthread_child;
2158 /* t = pointer to last next in the list */
2159 List_insert (*t, childcb);
2165 pthread_attr_init (pthread_attr_t *attr)
2167 if (pthread_attr::is_good_object (attr))
2170 *attr = new pthread_attr;
2171 if (!pthread_attr::is_good_object (attr))
2181 pthread_attr_getinheritsched (const pthread_attr_t *attr,
2184 if (!pthread_attr::is_good_object (attr))
2186 *inheritsched = (*attr)->inheritsched;
2191 pthread_attr_getschedparam (const pthread_attr_t *attr,
2192 struct sched_param *param)
2194 if (!pthread_attr::is_good_object (attr))
2196 *param = (*attr)->schedparam;
2200 /* From a pure code point of view, this should call a helper in sched.cc,
2201 to allow for someone adding scheduler policy changes to win32 in the future.
2202 However that's extremely unlikely, so short and sweet will do us */
2204 pthread_attr_getschedpolicy (const pthread_attr_t *attr, int *policy)
2206 if (!pthread_attr::is_good_object (attr))
2208 *policy = SCHED_FIFO;
2214 pthread_attr_getscope (const pthread_attr_t *attr, int *contentionscope)
2216 if (!pthread_attr::is_good_object (attr))
2218 *contentionscope = (*attr)->contentionscope;
2223 pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate)
2225 if (!pthread_attr::is_good_object (attr))
2227 if (detachstate < 0 || detachstate > 1)
2229 (*attr)->joinable = detachstate;
2234 pthread_attr_getdetachstate (const pthread_attr_t *attr, int *detachstate)
2236 if (!pthread_attr::is_good_object (attr))
2238 *detachstate = (*attr)->joinable;
2243 pthread_attr_setinheritsched (pthread_attr_t *attr, int inheritsched)
2245 if (!pthread_attr::is_good_object (attr))
2247 if (inheritsched != PTHREAD_INHERIT_SCHED
2248 && inheritsched != PTHREAD_EXPLICIT_SCHED)
2250 (*attr)->inheritsched = inheritsched;
2255 pthread_attr_setschedparam (pthread_attr_t *attr,
2256 const struct sched_param *param)
2258 if (!pthread_attr::is_good_object (attr))
2260 if (!valid_sched_parameters (param))
2262 (*attr)->schedparam = *param;
2266 /* See __pthread_attr_getschedpolicy for some notes */
2268 pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy)
2270 if (!pthread_attr::is_good_object (attr))
2272 if (policy != SCHED_FIFO)
2278 pthread_attr_setscope (pthread_attr_t *attr, int contentionscope)
2280 if (!pthread_attr::is_good_object (attr))
2282 if (contentionscope != PTHREAD_SCOPE_SYSTEM
2283 && contentionscope != PTHREAD_SCOPE_PROCESS)
2285 /* In future, we may be able to support system scope by escalating the thread
2286 priority to exceed the priority class. For now we only support PROCESS scope. */
2287 if (contentionscope != PTHREAD_SCOPE_PROCESS)
2289 (*attr)->contentionscope = contentionscope;
2294 pthread_attr_setstack (pthread_attr_t *attr, void *addr, size_t size)
2296 if (!pthread_attr::is_good_object (attr))
2300 if (size < PTHREAD_STACK_MIN)
2302 (*attr)->stackaddr = addr;
2303 (*attr)->stacksize = size;
2308 pthread_attr_getstack (const pthread_attr_t *attr, void **addr, size_t *size)
2310 if (!pthread_attr::is_good_object (attr))
2312 /* uses lowest address of stack on all platforms */
2313 *addr = (void *)((int)(*attr)->stackaddr - (*attr)->stacksize);
2314 *size = (*attr)->stacksize;
2319 pthread_attr_setstackaddr (pthread_attr_t *attr, void *addr)
2321 if (!pthread_attr::is_good_object (attr))
2325 (*attr)->stackaddr = addr;
2330 pthread_attr_getstackaddr (const pthread_attr_t *attr, void **addr)
2332 if (!pthread_attr::is_good_object (attr))
2334 /* uses stack address, which is the higher address on platforms
2335 where the stack grows downwards, such as x86 */
2336 *addr = (*attr)->stackaddr;
2341 pthread_attr_setstacksize (pthread_attr_t *attr, size_t size)
2343 if (!pthread_attr::is_good_object (attr))
2345 if (size < PTHREAD_STACK_MIN)
2347 (*attr)->stacksize = size;
2352 pthread_attr_getstacksize (const pthread_attr_t *attr, size_t *size)
2354 if (!pthread_attr::is_good_object (attr))
2356 *size = (*attr)->stacksize;
2361 pthread_attr_setguardsize (pthread_attr_t *attr, size_t size)
2363 if (!pthread_attr::is_good_object (attr))
2365 /* We don't support a guardsize of more than 1 Meg. */
2366 if (size > 1024 * 1024)
2368 (*attr)->guardsize = size;
2373 pthread_attr_getguardsize (const pthread_attr_t *attr, size_t *size)
2375 if (!pthread_attr::is_good_object (attr))
2377 *size = (*attr)->guardsize;
2382 pthread_attr_destroy (pthread_attr_t *attr)
2384 if (!pthread_attr::is_good_object (attr))
2392 pthread::join (pthread_t *thread, void **return_val)
2394 pthread_t joiner = self ();
2396 joiner->testcancel ();
2398 // Initialize return val with NULL
2402 if (!is_good_object (&joiner))
2405 if (!is_good_object (thread))
2408 if (equal (*thread,joiner))
2411 (*thread)->mutex.lock ();
2413 if ((*thread)->attr.joinable == PTHREAD_CREATE_DETACHED)
2415 (*thread)->mutex.unlock ();
2420 (*thread)->joiner = joiner;
2421 (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
2422 (*thread)->mutex.unlock ();
2424 switch (cancelable_wait ((*thread)->win32_obj_id, NULL, cw_no_cancel_self, cw_sig_resume))
2428 *return_val = (*thread)->return_ptr;
2432 // set joined thread back to joinable since we got canceled
2433 (*thread)->joiner = NULL;
2434 (*thread)->attr.joinable = PTHREAD_CREATE_JOINABLE;
2435 joiner->cancel_self ();
2439 // should never happen
2448 pthread::detach (pthread_t *thread)
2450 if (!is_good_object (thread))
2453 (*thread)->mutex.lock ();
2454 if ((*thread)->attr.joinable == PTHREAD_CREATE_DETACHED)
2456 (*thread)->mutex.unlock ();
2460 // check if thread is still alive
2461 if ((*thread)->valid && WaitForSingleObject ((*thread)->win32_obj_id, 0) == WAIT_TIMEOUT)
2463 // force cleanup on exit
2464 (*thread)->joiner = *thread;
2465 (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
2466 (*thread)->mutex.unlock ();
2470 // thread has already terminated.
2471 (*thread)->mutex.unlock ();
2479 pthread::suspend (pthread_t *thread)
2481 if (!is_good_object (thread))
2484 if ((*thread)->suspended == false)
2486 (*thread)->suspended = true;
2487 SuspendThread ((*thread)->win32_obj_id);
2495 pthread::resume (pthread_t *thread)
2497 if (!is_good_object (thread))
2500 if ((*thread)->suspended == true)
2501 ResumeThread ((*thread)->win32_obj_id);
2502 (*thread)->suspended = false;
2508 pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
2510 const size_t sizeof_tbi = sizeof (THREAD_BASIC_INFORMATION);
2511 PTHREAD_BASIC_INFORMATION tbi;
2514 if (!pthread::is_good_object (&thread))
2517 /* attr may not be pre-initialized */
2518 if (!pthread_attr::is_good_object (attr))
2520 int rv = pthread_attr_init (attr);
2525 (*attr)->joinable = thread->attr.joinable;
2526 (*attr)->contentionscope = thread->attr.contentionscope;
2527 (*attr)->inheritsched = thread->attr.inheritsched;
2528 (*attr)->schedparam = thread->attr.schedparam;
2529 (*attr)->guardsize = thread->attr.guardsize;
2531 tbi = (PTHREAD_BASIC_INFORMATION) malloc (sizeof_tbi);
2532 ret = NtQueryInformationThread (thread->win32_obj_id, ThreadBasicInformation,
2533 tbi, sizeof_tbi, NULL);
2535 if (NT_SUCCESS (ret))
2537 PNT_TIB tib = tbi->TebBaseAddress;
2538 (*attr)->stackaddr = tib->StackBase;
2539 /* stack grows downwards on x86 systems */
2540 (*attr)->stacksize = (int)tib->StackBase - (int)tib->StackLimit;
2544 debug_printf ("NtQueryInformationThread(ThreadBasicInformation), "
2546 (*attr)->stackaddr = thread->attr.stackaddr;
2547 (*attr)->stacksize = thread->attr.stacksize;
2553 /* provided for source level compatability.
2554 See http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2557 pthread_getconcurrency ()
2559 return MT_INTERFACE->concurrency;
2563 pthread_getcpuclockid (pthread_t thread, clockid_t *clk_id)
2565 if (!pthread::is_good_object (&thread))
2567 *clk_id = (clockid_t) THREADID_TO_CLOCKID (thread->getsequence_np ());
2571 /* keep this in sync with sched.cc */
2573 pthread_getschedparam (pthread_t thread, int *policy,
2574 struct sched_param *param)
2576 if (!pthread::is_good_object (&thread))
2578 *policy = SCHED_FIFO;
2579 /* we don't return the current effective priority, we return the current
2580 requested priority */
2581 *param = thread->attr.schedparam;
2585 /* Thread Specific Data */
2587 pthread_key_create (pthread_key_t *key, void (*destructor) (void *))
2589 *key = new pthread_key (destructor);
2591 if (!pthread_key::is_good_object (key))
2601 pthread_key_delete (pthread_key_t key)
2603 if (!pthread_key::is_good_object (&key))
2610 /* provided for source level compatability. See
2611 http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2614 pthread_setconcurrency (int new_level)
2618 MT_INTERFACE->concurrency = new_level;
2622 /* keep syncronised with sched.cc */
2624 pthread_setschedparam (pthread_t thread, int policy,
2625 const struct sched_param *param)
2627 if (!pthread::is_good_object (&thread))
2629 if (policy != SCHED_FIFO)
2634 sched_set_thread_priority (thread->win32_obj_id, param->sched_priority);
2636 thread->attr.schedparam.sched_priority = param->sched_priority;
2641 pthread_setschedprio (pthread_t thread, int priority)
2643 if (!pthread::is_good_object (&thread))
2646 sched_set_thread_priority (thread->win32_obj_id, priority);
2648 thread->attr.schedparam.sched_priority = priority;
2653 pthread_setspecific (pthread_key_t key, const void *value)
2655 if (!pthread_key::is_good_object (&key))
2662 pthread_getspecific (pthread_key_t key)
2664 if (!pthread_key::is_good_object (&key))
2667 return (key)->get ();
2672 pthread_cond_destroy (pthread_cond_t *cond)
2674 if (pthread_cond::is_initializer (cond))
2676 if (!pthread_cond::is_good_object (cond))
2679 /* reads are atomic */
2680 if ((*cond)->waiting)
2690 pthread_cond::init (pthread_cond_t *cond, const pthread_condattr_t *attr)
2692 pthread_cond_t new_cond;
2694 if (attr && !pthread_condattr::is_good_object (attr))
2697 cond_initialization_lock.lock ();
2699 new_cond = new pthread_cond (attr ? (*attr) : NULL);
2700 if (!is_good_object (&new_cond))
2703 cond_initialization_lock.unlock ();
2708 if (efault.faulted ())
2711 cond_initialization_lock.unlock ();
2716 cond_initialization_lock.unlock ();
2722 pthread_cond_broadcast (pthread_cond_t *cond)
2724 if (pthread_cond::is_initializer (cond))
2726 if (!pthread_cond::is_good_object (cond))
2729 (*cond)->unblock (true);
2735 pthread_cond_signal (pthread_cond_t *cond)
2737 if (pthread_cond::is_initializer (cond))
2739 if (!pthread_cond::is_good_object (cond))
2742 (*cond)->unblock (false);
2748 __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex,
2749 PLARGE_INTEGER waitlength)
2751 if (!pthread_mutex::is_good_object (mutex))
2753 if (!(*mutex)->can_be_unlocked ())
2756 if (pthread_cond::is_initializer (cond))
2757 pthread_cond::init (cond, NULL);
2758 if (!pthread_cond::is_good_object (cond))
2761 return (*cond)->wait (*mutex, waitlength);
2765 pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
2766 const struct timespec *abstime)
2769 LARGE_INTEGER timeout;
2772 if (efault.faulted ())
2775 pthread_testcancel ();
2777 /* According to SUSv3, the abstime value must be checked for validity. */
2778 if (abstime->tv_sec < 0
2779 || abstime->tv_nsec < 0
2780 || abstime->tv_nsec > 999999999)
2783 clock_gettime ((*cond)->clock_id, &tp);
2785 /* Check for immediate timeout before converting */
2786 if (tp.tv_sec > abstime->tv_sec
2787 || (tp.tv_sec == abstime->tv_sec
2788 && tp.tv_nsec > abstime->tv_nsec))
2791 timeout.QuadPart = abstime->tv_sec * NSPERSEC
2792 + (abstime->tv_nsec + 99LL) / 100LL;
2794 switch ((*cond)->clock_id)
2796 case CLOCK_REALTIME:
2797 timeout.QuadPart += FACTOR;
2800 /* other clocks must be handled as relative timeout */
2801 timeout.QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL;
2802 timeout.QuadPart *= -1LL;
2805 return __pthread_cond_dowait (cond, mutex, &timeout);
2809 pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
2811 pthread_testcancel ();
2813 return __pthread_cond_dowait (cond, mutex, NULL);
2817 pthread_condattr_init (pthread_condattr_t *condattr)
2819 if (pthread_condattr::is_good_object (condattr))
2822 *condattr = new pthread_condattr;
2823 if (!pthread_condattr::is_good_object (condattr))
2833 pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared)
2835 if (!pthread_condattr::is_good_object (attr))
2837 *pshared = (*attr)->shared;
2842 pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared)
2844 if (!pthread_condattr::is_good_object (attr))
2846 if ((pshared < 0) || (pshared > 1))
2848 /* shared cond vars not currently supported */
2849 if (pshared != PTHREAD_PROCESS_PRIVATE)
2851 (*attr)->shared = pshared;
2856 pthread_condattr_getclock (const pthread_condattr_t *attr, clockid_t *clock_id)
2858 if (!pthread_condattr::is_good_object (attr))
2860 *clock_id = (*attr)->clock_id;
2865 pthread_condattr_setclock (pthread_condattr_t *attr, clockid_t clock_id)
2867 if (!pthread_condattr::is_good_object (attr))
2871 case CLOCK_REALTIME:
2872 case CLOCK_MONOTONIC:
2877 (*attr)->clock_id = clock_id;
2882 pthread_condattr_destroy (pthread_condattr_t *condattr)
2884 if (!pthread_condattr::is_good_object (condattr))
2892 pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
2894 if (pthread_rwlock::is_initializer (rwlock))
2896 if (!pthread_rwlock::is_good_object (rwlock))
2899 if ((*rwlock)->writer || (*rwlock)->readers ||
2900 (*rwlock)->waiting_readers || (*rwlock)->waiting_writers)
2910 pthread_rwlock::init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
2912 pthread_rwlock_t new_rwlock;
2914 if (attr && !pthread_rwlockattr::is_good_object (attr))
2917 rwlock_initialization_lock.lock ();
2919 new_rwlock = new pthread_rwlock (attr ? (*attr) : NULL);
2920 if (!is_good_object (&new_rwlock))
2923 rwlock_initialization_lock.unlock ();
2928 if (efault.faulted ())
2931 rwlock_initialization_lock.unlock ();
2935 *rwlock = new_rwlock;
2936 rwlock_initialization_lock.unlock ();
2942 pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
2944 pthread_testcancel ();
2946 if (pthread_rwlock::is_initializer (rwlock))
2947 pthread_rwlock::init (rwlock, NULL);
2948 if (!pthread_rwlock::is_good_object (rwlock))
2951 return (*rwlock)->rdlock ();
2955 pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
2957 if (pthread_rwlock::is_initializer (rwlock))
2958 pthread_rwlock::init (rwlock, NULL);
2959 if (!pthread_rwlock::is_good_object (rwlock))
2962 return (*rwlock)->tryrdlock ();
2966 pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
2968 pthread_testcancel ();
2970 if (pthread_rwlock::is_initializer (rwlock))
2971 pthread_rwlock::init (rwlock, NULL);
2972 if (!pthread_rwlock::is_good_object (rwlock))
2975 return (*rwlock)->wrlock ();
2979 pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
2981 if (pthread_rwlock::is_initializer (rwlock))
2982 pthread_rwlock::init (rwlock, NULL);
2983 if (!pthread_rwlock::is_good_object (rwlock))
2986 return (*rwlock)->trywrlock ();
2990 pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
2992 if (pthread_rwlock::is_initializer (rwlock))
2994 if (!pthread_rwlock::is_good_object (rwlock))
2997 return (*rwlock)->unlock ();
3001 pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr)
3003 if (pthread_rwlockattr::is_good_object (rwlockattr))
3006 *rwlockattr = new pthread_rwlockattr;
3007 if (!pthread_rwlockattr::is_good_object (rwlockattr))
3009 delete (*rwlockattr);
3017 pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *pshared)
3019 if (!pthread_rwlockattr::is_good_object (attr))
3021 *pshared = (*attr)->shared;
3026 pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared)
3028 if (!pthread_rwlockattr::is_good_object (attr))
3030 if ((pshared < 0) || (pshared > 1))
3032 /* shared rwlock vars not currently supported */
3033 if (pshared != PTHREAD_PROCESS_PRIVATE)
3035 (*attr)->shared = pshared;
3040 pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr)
3042 if (!pthread_rwlockattr::is_good_object (rwlockattr))
3044 delete (*rwlockattr);
3051 pthread_kill (pthread_t thread, int sig)
3053 // lock myself, for the use of thread2signal
3054 // two different kills might clash: FIXME
3056 if (!pthread::is_good_object (&thread))
3061 si.si_code = SI_USER;
3062 si.si_pid = myself->pid;
3063 si.si_uid = myself->uid;
3069 thread->cygtls->set_threadkill ();
3070 rval = sig_send (NULL, si, thread->cygtls);
3073 switch (WaitForSingleObject (thread->win32_obj_id, 0))
3088 pthread_sigmask (int operation, const sigset_t *set, sigset_t *old_set)
3090 return handle_sigprocmask (operation, set, old_set, _my_tls.sigmask);
3096 pthread_equal (pthread_t t1, pthread_t t2)
3098 return pthread::equal (t1, t2);
3104 pthread_mutex::init (pthread_mutex_t *mutex,
3105 const pthread_mutexattr_t *attr,
3106 const pthread_mutex_t initializer)
3108 if (attr && !pthread_mutexattr::is_good_object (attr))
3111 mutex_initialization_lock.lock ();
3112 if (initializer == NULL || pthread_mutex::is_initializer (mutex))
3114 pthread_mutex_t new_mutex = new pthread_mutex (attr ? (*attr) : NULL);
3115 if (!is_good_object (&new_mutex))
3118 mutex_initialization_lock.unlock ();
3122 if (!attr && initializer)
3124 if (initializer == PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
3125 new_mutex->type = PTHREAD_MUTEX_RECURSIVE;
3126 else if (initializer == PTHREAD_NORMAL_MUTEX_INITIALIZER_NP)
3127 new_mutex->type = PTHREAD_MUTEX_NORMAL;
3128 else if (initializer == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
3129 new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
3133 if (efault.faulted ())
3136 mutex_initialization_lock.unlock ();
3142 mutex_initialization_lock.unlock ();
3143 pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex, attr, initializer);
3149 pthread_mutex_getprioceiling (const pthread_mutex_t *mutex,
3152 /* We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support
3155 We can support mutex priorities in the future though:
3156 Store a priority with each mutex.
3157 When the mutex is optained, set the thread priority as appropriate
3158 When the mutex is released, reset the thread priority. */
3163 pthread_mutex_lock (pthread_mutex_t *mutex)
3165 if (pthread_mutex::is_initializer (mutex))
3166 pthread_mutex::init (mutex, NULL, *mutex);
3167 if (!pthread_mutex::is_good_object (mutex))
3169 return (*mutex)->lock ();
3173 pthread_mutex_trylock (pthread_mutex_t *mutex)
3175 if (pthread_mutex::is_initializer (mutex))
3176 pthread_mutex::init (mutex, NULL, *mutex);
3177 if (!pthread_mutex::is_good_object (mutex))
3179 return (*mutex)->trylock ();
3183 pthread_mutex_unlock (pthread_mutex_t *mutex)
3185 if (pthread_mutex::is_initializer (mutex))
3187 if (!pthread_mutex::is_good_object (mutex))
3189 return (*mutex)->unlock ();
3193 pthread_mutex_destroy (pthread_mutex_t *mutex)
3197 if (pthread_mutex::is_initializer (mutex))
3199 if (!pthread_mutex::is_good_object (mutex))
3202 rv = (*mutex)->destroy ();
3211 pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling,
3220 pthread_spinlock::init (pthread_spinlock_t *spinlock, int pshared)
3222 pthread_spinlock_t new_spinlock = new pthread_spinlock (pshared);
3223 if (!is_good_object (&new_spinlock))
3225 delete new_spinlock;
3230 if (efault.faulted ())
3232 delete new_spinlock;
3236 *spinlock = new_spinlock;
3237 pthread_printf ("*spinlock %p, pshared %d", *spinlock, pshared);
3243 pthread_spin_lock (pthread_spinlock_t *spinlock)
3245 if (!pthread_spinlock::is_good_object (spinlock))
3247 return (*spinlock)->lock ();
3251 pthread_spin_trylock (pthread_spinlock_t *spinlock)
3253 if (!pthread_spinlock::is_good_object (spinlock))
3255 return (*spinlock)->trylock ();
3259 pthread_spin_unlock (pthread_spinlock_t *spinlock)
3261 if (!pthread_spinlock::is_good_object (spinlock))
3263 return (*spinlock)->unlock ();
3267 pthread_spin_destroy (pthread_spinlock_t *spinlock)
3269 if (!pthread_spinlock::is_good_object (spinlock))
3271 return (*spinlock)->destroy ();
3274 /* Win32 doesn't support mutex priorities - see __pthread_mutex_getprioceiling
3277 pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attr,
3280 if (!pthread_mutexattr::is_good_object (attr))
3286 pthread_mutexattr_getpshared (const pthread_mutexattr_t *attr,
3289 if (!pthread_mutexattr::is_good_object (attr))
3291 *pshared = (*attr)->pshared;
3296 pthread_mutexattr_gettype (const pthread_mutexattr_t *attr, int *type)
3298 if (!pthread_mutexattr::is_good_object (attr))
3300 *type = (*attr)->mutextype;
3304 /* FIXME: write and test process shared mutex's. */
3306 pthread_mutexattr_init (pthread_mutexattr_t *attr)
3308 if (pthread_mutexattr::is_good_object (attr))
3311 *attr = new pthread_mutexattr ();
3312 if (!pthread_mutexattr::is_good_object (attr))
3322 pthread_mutexattr_destroy (pthread_mutexattr_t *attr)
3324 if (!pthread_mutexattr::is_good_object (attr))
3332 /* Win32 doesn't support mutex priorities */
3334 pthread_mutexattr_setprotocol (pthread_mutexattr_t *attr, int protocol)
3336 if (!pthread_mutexattr::is_good_object (attr))
3341 /* Win32 doesn't support mutex priorities */
3343 pthread_mutexattr_setprioceiling (pthread_mutexattr_t *attr,
3346 if (!pthread_mutexattr::is_good_object (attr))
3352 pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *attr,
3355 if (!pthread_mutexattr::is_good_object (attr))
3361 pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared)
3363 if (!pthread_mutexattr::is_good_object (attr))
3365 /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
3368 if (pshared != PTHREAD_PROCESS_PRIVATE)
3370 (*attr)->pshared = pshared;
3374 /* see pthread_mutex_gettype */
3376 pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type)
3378 if (!pthread_mutexattr::is_good_object (attr))
3383 case PTHREAD_MUTEX_ERRORCHECK:
3384 case PTHREAD_MUTEX_RECURSIVE:
3385 case PTHREAD_MUTEX_NORMAL:
3386 (*attr)->mutextype = type;
3397 List<semaphore> semaphore::semaphores;
3399 semaphore::semaphore (int pshared, unsigned int value)
3400 : verifyable_object (SEM_MAGIC),
3402 currentvalue (value),
3407 SECURITY_ATTRIBUTES sa = (pshared != PTHREAD_PROCESS_PRIVATE)
3408 ? sec_all : sec_none_nih;
3409 this->win32_obj_id = ::CreateSemaphore (&sa, value, LONG_MAX, NULL);
3410 if (!this->win32_obj_id)
3413 semaphores.insert (this);
3416 semaphore::semaphore (unsigned long long shash, LUID sluid, int sfd,
3417 sem_t *ssem, int oflag, mode_t mode, unsigned int value)
3418 : verifyable_object (SEM_MAGIC),
3419 shared (PTHREAD_PROCESS_SHARED),
3420 currentvalue (value), /* Unused for named semaphores. */
3426 char name[MAX_PATH];
3428 __small_sprintf (name, "semaphore/%016X%08x%08x",
3429 hash, luid.HighPart, luid.LowPart);
3430 this->win32_obj_id = ::CreateSemaphore (&sec_all, value, LONG_MAX, name);
3431 if (!this->win32_obj_id)
3433 if (GetLastError () == ERROR_ALREADY_EXISTS && (oflag & O_EXCL))
3436 CloseHandle (this->win32_obj_id);
3440 semaphores.insert (this);
3443 semaphore::~semaphore ()
3446 CloseHandle (win32_obj_id);
3448 semaphores.remove (this);
3454 if (ReleaseSemaphore (win32_obj_id, 1, ¤tvalue))
3459 semaphore::_getvalue (int *sval)
3463 switch (WaitForSingleObject (win32_obj_id, 0))
3466 ReleaseSemaphore (win32_obj_id, 1, &val);
3480 semaphore::_trywait ()
3482 /* FIXME: signals should be able to interrupt semaphores...
3483 We probably need WaitForMultipleObjects here. */
3484 if (WaitForSingleObject (win32_obj_id, 0) == WAIT_TIMEOUT)
3494 semaphore::_timedwait (const struct timespec *abstime)
3496 LARGE_INTEGER timeout;
3499 if (efault.faulted ())
3501 /* According to SUSv3, abstime need not be checked for validity,
3502 if the semaphore can be locked immediately. */
3509 timeout.QuadPart = abstime->tv_sec * NSPERSEC
3510 + (abstime->tv_nsec + 99) / 100 + FACTOR;
3512 switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel_self, cw_sig_eintr))
3521 set_errno (ETIMEDOUT);
3524 pthread_printf ("cancelable_wait failed. %E");
3534 switch (cancelable_wait (win32_obj_id, NULL, cw_cancel_self, cw_sig_eintr))
3543 pthread_printf ("cancelable_wait failed. %E");
3550 semaphore::_fixup_after_fork ()
3552 if (shared == PTHREAD_PROCESS_PRIVATE)
3554 pthread_printf ("sem %x", this);
3555 /* FIXME: duplicate code here and in the constructor. */
3556 this->win32_obj_id = ::CreateSemaphore (&sec_none_nih, currentvalue,
3559 api_fatal ("failed to create new win32 semaphore, error %d");
3564 semaphore::_terminate ()
3566 int _sem_close (sem_t *, bool);
3569 _sem_close (sem, false);
3572 /* static members */
3575 semaphore::init (sem_t *sem, int pshared, unsigned int value)
3578 We can't tell the difference between reinitialising an
3579 existing semaphore and initialising a semaphore who's
3580 contents happen to be a valid pointer
3582 if (is_good_object (sem))
3584 paranoid_printf ("potential attempt to reinitialise a semaphore");
3587 if (value > SEM_VALUE_MAX)
3593 *sem = new semaphore (pshared, value);
3595 if (!is_good_object (sem))
3606 semaphore::destroy (sem_t *sem)
3608 if (!is_good_object (sem))
3614 /* It's invalid to destroy a semaphore not opened with sem_init. */
3615 if ((*sem)->fd != -1)
3621 /* FIXME - new feature - test for busy against threads... */
3629 semaphore::close (sem_t *sem)
3631 if (!is_good_object (sem))
3637 /* It's invalid to close a semaphore not opened with sem_open. */
3638 if ((*sem)->fd == -1)
3650 semaphore::open (unsigned long long hash, LUID luid, int fd, int oflag,
3651 mode_t mode, unsigned int value, bool &wasopen)
3653 if (value > SEM_VALUE_MAX)
3659 /* sem_open is supposed to return the same pointer, if the same named
3660 semaphore is opened multiple times in the same process, as long as
3661 the semaphore hasn't been closed or unlinked in the meantime. */
3662 semaphores.mx.lock ();
3663 for (semaphore *sema = semaphores.head; sema; sema = sema->next)
3664 if (sema->fd >= 0 && sema->hash == hash
3665 && sema->luid.HighPart == luid.HighPart
3666 && sema->luid.LowPart == sema->luid.LowPart)
3669 semaphores.mx.unlock ();
3672 semaphores.mx.unlock ();
3675 sem_t *sem = new sem_t;
3682 *sem = new semaphore (hash, luid, fd, sem, oflag, mode, value);
3684 if (!is_good_object (sem))
3694 semaphore::wait (sem_t *sem)
3696 pthread_testcancel ();
3698 if (!is_good_object (sem))
3704 return (*sem)->_wait ();
3708 semaphore::trywait (sem_t *sem)
3710 if (!is_good_object (sem))
3716 return (*sem)->_trywait ();
3720 semaphore::timedwait (sem_t *sem, const struct timespec *abstime)
3722 if (!is_good_object (sem))
3728 return (*sem)->_timedwait (abstime);
3732 semaphore::post (sem_t *sem)
3734 if (!is_good_object (sem))
3745 semaphore::getvalue (sem_t *sem, int *sval)
3748 if (efault.faulted () || !is_good_object (sem))
3754 return (*sem)->_getvalue (sval);
3758 semaphore::getinternal (sem_t *sem, int *sfd, unsigned long long *shash,
3759 LUID *sluid, unsigned int *sval)
3762 if (efault.faulted () || !is_good_object (sem))
3767 if ((*sfd = (*sem)->fd) < 0)
3772 *shash = (*sem)->hash;
3773 *sluid = (*sem)->luid;
3774 /* POSIX defines the value in calls to sem_init/sem_open as unsigned, but
3775 the sem_getvalue gets a pointer to int to return the value. Go figure! */
3776 return (*sem)->_getvalue ((int *)sval);
3781 pthread_null::get_null_pthread ()
3783 /* because of weird entry points */
3784 _instance.magic = 0;
3788 pthread_null::pthread_null ()
3790 attr.joinable = PTHREAD_CREATE_DETACHED;
3791 /* Mark ourselves as invalid */
3795 pthread_null::~pthread_null ()
3800 pthread_null::create (void *(*)(void *), pthread_attr *, void *)
3806 pthread_null::exit (void *value_ptr)
3808 _my_tls.remove (INFINITE);
3813 pthread_null::cancel ()
3819 pthread_null::testcancel ()
3824 pthread_null::setcancelstate (int state, int *oldstate)
3830 pthread_null::setcanceltype (int type, int *oldtype)
3836 pthread_null::push_cleanup_handler (__pthread_cleanup_handler *handler)
3841 pthread_null::pop_cleanup_handler (int const execute)
3846 pthread_null::getsequence_np ()
3851 pthread_null pthread_null::_instance;