1 /* thread.cc: Locking and threading module functions
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
9 /* Implementation overview and caveats:
11 Win32 puts some contraints on what can and cannot be implemented. Where
12 possible we work around those contrainsts. Where we cannot work around
13 the constraints we either pretend to be conformant, or return an error
16 Some caveats: PROCESS_SHARED objects, while they pretend to be process
17 shared, may not actually work. Some test cases are needed to determine
18 win32's behaviour. My suspicion is that the win32 handle needs to be
19 opened with different flags for proper operation.
21 R.Collins, April 2001. */
24 #include "create_posix_thread.h"
34 #include "exception.h"
36 /* For Linux compatibility, the length of a thread name is 16 characters. */
39 extern "C" void __fp_lock_all ();
40 extern "C" void __fp_unlock_all ();
41 extern "C" bool valid_sched_parameters(const struct sched_param
*);
42 extern "C" int sched_get_thread_priority(HANDLE thread
);
43 extern "C" int sched_set_thread_priority(HANDLE thread
, int priority
);
45 extern int threadsafe
;
47 const pthread_t
pthread_mutex::_new_mutex
= (pthread_t
) 1;
48 const pthread_t
pthread_mutex::_unlocked_mutex
= (pthread_t
) 2;
49 const pthread_t
pthread_mutex::_destroyed_mutex
= (pthread_t
) 3;
54 delete_and_clear (T
* * const ptr
)
61 pthread_mutex::no_owner()
66 debug_printf ("NULL owner value");
69 else if (owner
== _destroyed_mutex
)
71 paranoid_printf ("attempt to use destroyed mutex");
74 else if (owner
== _new_mutex
|| owner
== _unlocked_mutex
)
82 extern "C" struct _reent
*
85 return &_my_tls
.local_clib
;
89 __cygwin_lock_init (_LOCK_T
*lock
)
91 *lock
= _LOCK_T_INITIALIZER
;
95 __cygwin_lock_init_recursive (_LOCK_T
*lock
)
97 *lock
= _LOCK_T_RECURSIVE_INITIALIZER
;
101 __cygwin_lock_fini (_LOCK_T
*lock
)
103 pthread_mutex_destroy ((pthread_mutex_t
*) lock
);
107 __cygwin_lock_lock (_LOCK_T
*lock
)
109 paranoid_printf ("threadcount %d. locking", MT_INTERFACE
->threadcount
);
110 pthread_mutex_lock ((pthread_mutex_t
*) lock
);
114 __cygwin_lock_trylock (_LOCK_T
*lock
)
116 return pthread_mutex_trylock ((pthread_mutex_t
*) lock
);
121 __cygwin_lock_unlock (_LOCK_T
*lock
)
123 pthread_mutex_unlock ((pthread_mutex_t
*) lock
);
124 paranoid_printf ("threadcount %d. unlocked", MT_INTERFACE
->threadcount
);
127 static inline verifyable_object_state
128 verifyable_object_isvalid (void const *objectptr
, thread_magic_t magic
,
129 void *static_ptr1
= NULL
,
130 void *static_ptr2
= NULL
,
131 void *static_ptr3
= NULL
)
133 verifyable_object_state state
= INVALID_OBJECT
;
137 if (!objectptr
|| !(*(const char **) objectptr
))
140 verifyable_object
**object
= (verifyable_object
**) objectptr
;
142 if ((static_ptr1
&& *object
== static_ptr1
) ||
143 (static_ptr2
&& *object
== static_ptr2
) ||
144 (static_ptr3
&& *object
== static_ptr3
))
145 state
= VALID_STATIC_OBJECT
;
146 else if ((*object
)->magic
== magic
)
147 state
= VALID_OBJECT
;
149 __except (NO_ERROR
) {}
156 pthread_attr::is_good_object (pthread_attr_t
const *attr
)
158 if (verifyable_object_isvalid (attr
, PTHREAD_ATTR_MAGIC
) != VALID_OBJECT
)
164 pthread_condattr::is_good_object (pthread_condattr_t
const *attr
)
166 if (verifyable_object_isvalid (attr
, PTHREAD_CONDATTR_MAGIC
) != VALID_OBJECT
)
172 pthread_rwlockattr::is_good_object (pthread_rwlockattr_t
const *attr
)
174 if (verifyable_object_isvalid (attr
, PTHREAD_RWLOCKATTR_MAGIC
) != VALID_OBJECT
)
180 pthread_key::is_good_object (pthread_key_t
const *key
)
182 if (verifyable_object_isvalid (key
, PTHREAD_KEY_MAGIC
) != VALID_OBJECT
)
188 pthread_spinlock::is_good_object (pthread_spinlock_t
const *mutex
)
190 if (verifyable_object_isvalid (mutex
, PTHREAD_SPINLOCK_MAGIC
) != VALID_OBJECT
)
196 pthread_mutex::is_good_object (pthread_mutex_t
const *mutex
)
198 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
) != VALID_OBJECT
)
204 pthread_mutex::is_initializer (pthread_mutex_t
const *mutex
)
206 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
207 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
208 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
209 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) != VALID_STATIC_OBJECT
)
215 pthread_mutex::is_initializer_or_object (pthread_mutex_t
const *mutex
)
217 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
218 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
219 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
220 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) == INVALID_OBJECT
)
225 /* FIXME: Accommodate PTHREAD_MUTEX_ERRORCHECK */
227 pthread_mutex::can_be_unlocked ()
229 pthread_t self
= pthread::self ();
230 /* Check if the mutex is owned by the current thread and can be unlocked.
231 * Also check for the ANONYMOUS owner to cover NORMAL mutexes as well. */
232 bool res
= type
== PTHREAD_MUTEX_NORMAL
|| no_owner ()
233 || (recursion_counter
== 1 && pthread::equal (owner
, self
));
234 pthread_printf ("recursion_counter %u res %d", recursion_counter
, res
);
239 pthread_mutexattr::is_good_object (pthread_mutexattr_t
const * attr
)
241 if (verifyable_object_isvalid (attr
, PTHREAD_MUTEXATTR_MAGIC
) != VALID_OBJECT
)
246 inline bool __attribute__ ((used
))
247 pthread::is_good_object (pthread_t
const *thread
)
249 if (verifyable_object_isvalid (thread
, PTHREAD_MAGIC
) != VALID_OBJECT
)
254 /* Thread synchronisation */
256 pthread_cond::is_good_object (pthread_cond_t
const *cond
)
258 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
) != VALID_OBJECT
)
264 pthread_cond::is_initializer (pthread_cond_t
const *cond
)
266 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) != VALID_STATIC_OBJECT
)
272 pthread_cond::is_initializer_or_object (pthread_cond_t
const *cond
)
274 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) == INVALID_OBJECT
)
280 pthread_barrierattr::is_good_object (pthread_barrierattr_t
const *cond
)
282 if (verifyable_object_isvalid (cond
, PTHREAD_BARRIERATTR_MAGIC
)
289 pthread_barrier::is_good_object (pthread_barrier_t
const *cond
)
291 if (verifyable_object_isvalid (cond
, PTHREAD_BARRIER_MAGIC
) != VALID_OBJECT
)
298 pthread_rwlock::is_good_object (pthread_rwlock_t
const *rwlock
)
300 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
) != VALID_OBJECT
)
306 pthread_rwlock::is_initializer (pthread_rwlock_t
const *rwlock
)
308 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) != VALID_STATIC_OBJECT
)
314 pthread_rwlock::is_initializer_or_object (pthread_rwlock_t
const *rwlock
)
316 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) == INVALID_OBJECT
)
322 semaphore::is_good_object (sem_t
const * sem
)
324 if (verifyable_object_isvalid (sem
, SEM_MAGIC
) != VALID_OBJECT
)
332 pthread_mutex::init_mutex ();
333 pthread_cond::init_mutex ();
334 pthread_rwlock::init_mutex ();
338 MTinterface::fixup_before_fork ()
340 pthread_key::fixup_before_fork ();
341 semaphore::fixup_before_fork ();
344 /* This function is called from a single threaded process */
346 MTinterface::fixup_after_fork ()
348 pthread_key::fixup_after_fork ();
351 pthread::init_mainthread ();
353 pthread::fixup_after_fork ();
354 pthread_mutex::fixup_after_fork ();
355 pthread_cond::fixup_after_fork ();
356 pthread_rwlock::fixup_after_fork ();
357 semaphore::fixup_after_fork ();
364 pthread::init_mainthread ()
366 pthread
*thread
= _my_tls
.tid
;
367 if (!thread
|| thread
== pthread_null::get_null_pthread ())
369 thread
= new pthread ();
371 api_fatal ("failed to create mainthread object");
374 thread
->set_tls_self_pointer ();
375 thread
->thread_id
= GetCurrentThreadId ();
376 if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
377 GetCurrentProcess (), &thread
->win32_obj_id
,
378 0, FALSE
, DUPLICATE_SAME_ACCESS
))
379 api_fatal ("failed to create mainthread handle");
380 if (!thread
->create_cancel_event ())
381 api_fatal ("couldn't create cancel event for main thread");
382 VerifyHandle (thread
->win32_obj_id
);
383 /* Make sure the pthread mutex is recursive. See comment in
384 pthread::precreate (called only for subsequent pthreads)
385 for a description. */
386 thread
->mutex
.set_type (PTHREAD_MUTEX_RECURSIVE
);
387 thread
->postcreate ();
393 pthread
*thread
= _my_tls
.tid
;
396 thread
= pthread_null::get_null_pthread ();
397 thread
->set_tls_self_pointer ();
403 pthread::set_tls_self_pointer ()
409 List
<pthread
> pthread::threads
;
412 pthread::pthread ():verifyable_object (PTHREAD_MAGIC
), win32_obj_id (0),
413 valid (false), suspended (false), canceled (false),
414 cancelstate (0), canceltype (0), cancel_event (0),
415 joiner (NULL
), next (NULL
), cleanup_stack (NULL
)
417 if (this != pthread_null::get_null_pthread ())
418 threads
.insert (this);
419 sigprocmask (SIG_SETMASK
, NULL
, &parent_sigmask
);
425 CloseHandle (win32_obj_id
);
427 CloseHandle (cancel_event
);
429 if (this != pthread_null::get_null_pthread ())
430 threads
.remove (this);
434 pthread::create_cancel_event ()
436 cancel_event
= ::CreateEvent (&sec_none_nih
, true, false, NULL
);
439 system_printf ("couldn't create cancel event, %E");
440 /* we need the event for correct behaviour */
447 pthread::precreate (pthread_attr
*newattr
)
449 pthread_mutex
*verifyable_mutex_obj
= &mutex
;
451 /* already running ? */
457 attr
.joinable
= newattr
->joinable
;
458 attr
.contentionscope
= newattr
->contentionscope
;
459 attr
.inheritsched
= newattr
->inheritsched
;
460 attr
.schedparam
= newattr
->schedparam
;
461 attr
.stackaddr
= newattr
->stackaddr
;
462 attr
.stacksize
= newattr
->stacksize
;
463 attr
.guardsize
= newattr
->guardsize
;
466 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
468 thread_printf ("New thread object access mutex is not valid. this %p",
473 /* This mutex MUST be recursive. Consider the following scenario:
474 - The thread installs a cleanup handler.
475 - The cleanup handler calls a function which itself installs a
477 - pthread_cancel is called for this thread.
478 - The thread's cleanup handler is called under mutex lock condition.
479 - The cleanup handler calls the subsequent function with cleanup handler.
480 - The function runs to completion, so it calls pthread_cleanup_pop.
481 - pthread_cleanup_pop calls pthread::pop_cleanup_handler which will again
482 try to lock the mutex.
484 mutex
.set_type (PTHREAD_MUTEX_RECURSIVE
);
485 if (!create_cancel_event ())
490 pthread::create (void *(*func
) (void *), pthread_attr
*newattr
,
503 /* stackaddr holds the uppermost stack address. See the comments in
504 pthread_attr_setstack and pthread_attr_setstackaddr for a description. */
505 ULONG stacksize
= attr
.stacksize
?: get_rlimit_stack ();
506 PVOID stackaddr
= attr
.stackaddr
? ((caddr_t
) attr
.stackaddr
- stacksize
)
508 win32_obj_id
= create_posix_thread (thread_init_wrapper
, this, stackaddr
,
509 stacksize
, attr
.guardsize
, 0, &thread_id
);
513 thread_printf ("CreateThread failed: this %p, %E", this);
528 pthread::postcreate ()
532 InterlockedIncrement (&MT_INTERFACE
->threadcount
);
534 /* Per POSIX the new thread inherits the sched priority from its caller
535 thread if PTHREAD_INHERIT_SCHED is set.
536 FIXME: set the priority appropriately for system contention scope */
537 if (attr
.inheritsched
== PTHREAD_INHERIT_SCHED
)
538 attr
.schedparam
.sched_priority
539 = sched_get_thread_priority (GetCurrentThread ());
540 if (attr
.schedparam
.sched_priority
)
541 sched_set_thread_priority (win32_obj_id
, attr
.schedparam
.sched_priority
);
545 pthread::exit (void *value_ptr
)
547 class pthread
*thread
= this;
548 _cygtls
*tls
= cygtls
; /* Save cygtls before deleting this. */
550 // run cleanup handlers
551 pop_all_cleanup_handlers ();
553 pthread_key::run_all_destructors ();
556 // cleanup if thread is in detached state and not joined
557 if (equal (joiner
, thread
))
562 return_ptr
= value_ptr
;
566 if (_my_tls
.local_clib
.__cleanup
== _cygtls::cleanup_early
)
567 _my_tls
.local_clib
.__cleanup
= NULL
;
568 _reclaim_reent (_REENT
);
570 if (InterlockedDecrement (&MT_INTERFACE
->threadcount
) == 0)
574 if (tls
== _main_tls
)
576 cygheap
->find_tls (tls
); /* Lock _main_tls mutex. */
577 _cygtls
*dummy
= (_cygtls
*) malloc (sizeof (_cygtls
));
580 _main_tls
->initialized
= 0;
582 /* This also unlocks and closes the _main_tls mutex. */
583 tls
->remove (INFINITE
);
591 class pthread
*thread
= this;
592 class pthread
*self
= pthread::self ();
602 if (canceltype
== PTHREAD_CANCEL_DEFERRED
||
603 cancelstate
== PTHREAD_CANCEL_DISABLE
)
608 SetEvent (cancel_event
);
611 else if (equal (thread
, self
))
615 return 0; // Never reached
618 // cancel asynchronous
619 SuspendThread (win32_obj_id
);
620 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
623 context
.ContextFlags
= CONTEXT_CONTROL
;
624 GetThreadContext (win32_obj_id
, &context
);
625 /* The OS is not foolproof in terms of asynchronous thread cancellation
626 and tends to hang infinitely if we change the instruction pointer.
627 So just don't cancel asynchronously if the thread is currently
628 executing Windows code. Rely on deferred cancellation in this case. */
629 threadlist_t
*tl_entry
= cygheap
->find_tls (cygtls
);
630 if (!cygtls
->inside_kernel (&context
))
632 context
.Rip
= (ULONG_PTR
) pthread::static_cancel_self
;
633 SetThreadContext (win32_obj_id
, &context
);
635 cygheap
->unlock_tls (tl_entry
);
638 /* See above. For instance, a thread which waits for a semaphore in sem_wait
639 will call cygwait which in turn calls WFMO. While this WFMO call
640 is cancelable by setting the thread's cancel_event object, the OS
641 apparently refuses to set the thread's context and continues to wait for
642 the WFMO conditions. This is *not* reflected in the return value of
643 SetThreadContext or ResumeThread, btw.
644 So, what we do here is to set the cancel_event as well to allow at least
645 a deferred cancel. */
647 SetEvent (cancel_event
);
648 ResumeThread (win32_obj_id
);
653 /* TODO: Insert pthread_testcancel into the required functions.
655 Here are the lists of required and optional functions per POSIX.1-2001
656 and POSIX.1-2008. A star (*) indicates that the Cygwin function already
657 is a cancellation point (aka "calls pthread_testcancel"), an o (o)
658 indicates that the function is not implemented in Cygwin.
660 Required cancellation points:
688 * pthread_cond_timedwait ()
689 * pthread_cond_wait ()
691 * pthread_testcancel ()
722 Optional cancellation points:
727 catclose () Implemented externally: libcatgets
728 catgets () Implemented externally: libcatgets
729 catopen () Implemented externally: libcatgets
737 dbm_close () Implemented externally: libgdbm
738 dbm_delete () Implemented externally: libgdbm
739 dbm_fetch () Implemented externally: libgdbm
740 dbm_nextkey () Implemented externally: libgdbm
741 dbm_open () Implemented externally: libgdbm
742 dbm_store () Implemented externally: libgdbm
759 * fcntl () (any value)
814 getopt () (if opterr is nonzero)
834 iconv_close () Implemented externally: libiconv
835 iconv_open () Implemented externally: libiconv
867 o posix_trace_clear ()
868 o posix_trace_close ()
869 o posix_trace_create ()
870 o posix_trace_create_withlog ()
871 o posix_trace_eventtypelist_getnext_id ()
872 o posix_trace_eventtypelist_rewind ()
873 o posix_trace_flush ()
874 o posix_trace_get_attr ()
875 o posix_trace_get_filter ()
876 o posix_trace_get_status ()
877 o posix_trace_getnext_event ()
878 o posix_trace_open ()
879 o posix_trace_rewind ()
880 o posix_trace_set_filter ()
881 o posix_trace_shutdown ()
882 o posix_trace_timedgetnext_event ()
883 o posix_typed_mem_open ()
887 pthread_rwlock_rdlock ()
888 o pthread_rwlock_timedrdlock ()
889 o pthread_rwlock_timedwrlock ()
890 pthread_rwlock_wrlock ()
950 An implementation may also mark other functions not specified in the
951 standard as cancellation points. In particular, an implementation is
952 likely to mark any nonstandard function that may block as a
953 cancellation point. */
956 pthread::testcancel ()
958 if (cancelstate
== PTHREAD_CANCEL_DISABLE
)
961 /* We check for the canceled flag first. This allows to use the
962 pthread_testcancel function a lot without adding the overhead of
963 an OS call. Only if the thread is marked as canceled, we wait for
964 cancel_event being really set, on the off-chance that pthread_cancel
965 gets interrupted or terminated before calling SetEvent. */
966 if (canceled
&& IsEventSignalled (cancel_event
))
970 /* Return cancel event handle if it exists *and* cancel is not disabled.
971 This function is supposed to be used from other functions which are
972 cancelable and need the cancel event in a WFMO call. */
974 pthread::get_cancel_event ()
976 pthread_t thread
= pthread::self ();
978 return (thread
&& thread
->cancel_event
979 && thread
->cancelstate
!= PTHREAD_CANCEL_DISABLE
)
980 ? thread
->cancel_event
: NULL
;
984 pthread::static_cancel_self ()
986 pthread::self ()->cancel_self ();
990 pthread::setcancelstate (int state
, int *oldstate
)
992 if (state
!= PTHREAD_CANCEL_ENABLE
&& state
!= PTHREAD_CANCEL_DISABLE
)
996 *oldstate
= cancelstate
;
1003 pthread::setcanceltype (int type
, int *oldtype
)
1005 if (type
!= PTHREAD_CANCEL_DEFERRED
&& type
!= PTHREAD_CANCEL_ASYNCHRONOUS
)
1009 *oldtype
= canceltype
;
1016 pthread::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
1018 if (this != self ())
1020 api_fatal ("Attempt to push a cleanup handler across threads");
1021 handler
->next
= cleanup_stack
;
1022 cleanup_stack
= handler
;
1026 pthread::pop_cleanup_handler (int const execute
)
1028 if (this != self ())
1029 // TODO: send a signal or something to the thread ?
1030 api_fatal ("Attempt to execute a cleanup handler across threads");
1034 if (cleanup_stack
!= NULL
)
1036 __pthread_cleanup_handler
*handler
= cleanup_stack
;
1039 (*handler
->function
) (handler
->arg
);
1040 cleanup_stack
= handler
->next
;
1047 pthread::pop_all_cleanup_handlers ()
1049 /* We will no honor cancels since the thread is exiting. */
1050 cancelstate
= PTHREAD_CANCEL_DISABLE
;
1052 while (cleanup_stack
!= NULL
)
1053 pop_cleanup_handler (1);
1057 pthread::cancel_self ()
1059 /* Can someone explain why the pthread:: is needed here? g++ complains
1061 pthread::exit (PTHREAD_CANCELED
);
1065 pthread::get_thread_id ()
1071 pthread::_fixup_after_fork ()
1073 /* set thread to not running if it is not the forking thread */
1074 if (this != pthread::self ())
1078 win32_obj_id
= NULL
;
1080 cancel_event
= NULL
;
1085 pthread::suspend_except_self ()
1087 if (valid
&& this != pthread::self ())
1088 SuspendThread (win32_obj_id
);
1095 ResumeThread (win32_obj_id
);
1098 /* instance members */
1100 pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC
),
1101 joinable (PTHREAD_CREATE_JOINABLE
), contentionscope (PTHREAD_SCOPE_PROCESS
),
1102 inheritsched (PTHREAD_INHERIT_SCHED
), stackaddr (NULL
), stacksize (0),
1103 guardsize (wincap
.def_guard_page_size ()), name (NULL
)
1105 schedparam
.sched_priority
= 0;
1108 pthread_attr::~pthread_attr ()
1112 pthread_condattr::pthread_condattr ():verifyable_object
1113 (PTHREAD_CONDATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
),
1114 clock_id (CLOCK_REALTIME
)
1118 pthread_condattr::~pthread_condattr ()
1122 List
<pthread_cond
> pthread_cond::conds
;
1124 /* This is used for cond creation protection within a single process only */
1125 fast_mutex NO_COPY
pthread_cond::cond_initialization_lock
;
1127 /* We can only be called once.
1128 TODO: (no rush) use a non copied memory section to
1129 hold an initialization flag. */
1131 pthread_cond::init_mutex ()
1133 if (!cond_initialization_lock
.init ())
1134 api_fatal ("Could not create win32 Mutex for pthread cond static initializer support.");
1137 pthread_cond::pthread_cond (pthread_condattr
*attr
) :
1138 verifyable_object (PTHREAD_COND_MAGIC
),
1139 shared (0), clock_id (CLOCK_REALTIME
), waiting (0), pending (0),
1140 sem_wait (NULL
), mtx_cond(NULL
), next (NULL
)
1142 pthread_mutex
*verifyable_mutex_obj
;
1146 clock_id
= attr
->clock_id
;
1148 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
1155 verifyable_mutex_obj
= &mtx_in
;
1156 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1158 thread_printf ("Internal cond mutex is not valid. this %p", this);
1163 * Change the mutex type to NORMAL.
1164 * This mutex MUST be of type normal
1166 mtx_in
.set_type (PTHREAD_MUTEX_NORMAL
);
1168 verifyable_mutex_obj
= &mtx_out
;
1169 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1171 thread_printf ("Internal cond mutex is not valid. this %p", this);
1175 /* Change the mutex type to NORMAL to speed up mutex operations */
1176 mtx_out
.set_type (PTHREAD_MUTEX_NORMAL
);
1178 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, INT32_MAX
, NULL
);
1181 pthread_printf ("CreateSemaphore failed. %E");
1186 conds
.insert (this);
1189 pthread_cond::~pthread_cond ()
1192 CloseHandle (sem_wait
);
1194 conds
.remove (this);
1198 pthread_cond::unblock (const bool all
)
1203 * Block outgoing threads (and avoid simultanous unblocks)
1207 releaseable
= waiting
- pending
;
1215 * Block incoming threads until all waiting threads are released.
1220 * Calculate releaseable again because threads can enter until
1221 * the semaphore has been taken, but they can not leave, therefore pending
1222 * is unchanged and releaseable can only get higher
1224 releaseable
= waiting
- pending
;
1227 released
= all
? releaseable
: 1;
1228 pending
+= released
;
1232 ::ReleaseSemaphore (sem_wait
, released
, NULL
);
1236 * And let the threads release.
1242 pthread_cond::wait (pthread_mutex_t mutex
, PLARGE_INTEGER timeout
)
1247 if (InterlockedIncrement (&waiting
) == 1)
1249 else if (mtx_cond
!= mutex
)
1251 InterlockedDecrement (&waiting
);
1258 * Release the mutex and wait on semaphore
1263 rv
= cygwait (sem_wait
, timeout
, cw_cancel
| cw_sig_restart
);
1267 if (rv
!= WAIT_OBJECT_0
&& WaitForSingleObject (sem_wait
, 0) == WAIT_OBJECT_0
)
1268 /* Thread got cancelled ot timed out while a signalling is in progress.
1269 Set wait result back to signaled */
1272 InterlockedDecrement (&waiting
);
1274 if (rv
== WAIT_OBJECT_0
&& --pending
== 0)
1276 * All signaled threads are released,
1277 * new threads can enter Wait
1286 if (rv
== WAIT_CANCELED
)
1287 pthread::static_cancel_self ();
1288 else if (rv
== WAIT_TIMEOUT
)
1295 pthread_cond::_fixup_after_fork ()
1297 waiting
= pending
= 0;
1300 /* Unlock eventually locked mutexes */
1304 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, INT32_MAX
, NULL
);
1306 api_fatal ("pthread_cond::_fixup_after_fork () failed to recreate win32 semaphore");
1309 pthread_barrierattr::pthread_barrierattr ()
1310 : verifyable_object (PTHREAD_BARRIERATTR_MAGIC
)
1311 , shared (PTHREAD_PROCESS_PRIVATE
)
1315 pthread_barrierattr::~pthread_barrierattr ()
1319 pthread_barrier::pthread_barrier ()
1320 : verifyable_object (PTHREAD_BARRIER_MAGIC
)
1324 pthread_barrier::~pthread_barrier ()
1328 pthread_rwlockattr::pthread_rwlockattr ():verifyable_object
1329 (PTHREAD_RWLOCKATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
)
1333 pthread_rwlockattr::~pthread_rwlockattr ()
1337 List
<pthread_rwlock
> pthread_rwlock::rwlocks
;
1339 /* This is used for rwlock creation protection within a single process only */
1340 fast_mutex NO_COPY
pthread_rwlock::rwlock_initialization_lock
;
1342 /* We can only be called once.
1343 TODO: (no rush) use a non copied memory section to
1344 hold an initialization flag. */
1346 pthread_rwlock::init_mutex ()
1348 if (!rwlock_initialization_lock
.init ())
1349 api_fatal ("Could not create win32 Mutex for pthread rwlock static initializer support.");
1352 pthread_rwlock::pthread_rwlock (pthread_rwlockattr
*attr
) :
1353 verifyable_object (PTHREAD_RWLOCK_MAGIC
),
1354 shared (0), waiting_readers (0), waiting_writers (0), writer (NULL
),
1355 readers (NULL
), readers_mx (), mtx (NULL
), cond_readers (NULL
), cond_writers (NULL
),
1358 pthread_mutex
*verifyable_mutex_obj
= &mtx
;
1359 pthread_cond
*verifyable_cond_obj
;
1361 if (!readers_mx
.init ())
1363 thread_printf ("Internal rwlock synchronisation mutex is not valid. this %p", this);
1369 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
1375 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1377 thread_printf ("Internal rwlock mutex is not valid. this %p", this);
1381 /* Change the mutex type to NORMAL to speed up mutex operations */
1382 mtx
.set_type (PTHREAD_MUTEX_NORMAL
);
1384 verifyable_cond_obj
= &cond_readers
;
1385 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
1387 thread_printf ("Internal rwlock readers cond is not valid. this %p", this);
1392 verifyable_cond_obj
= &cond_writers
;
1393 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
1395 thread_printf ("Internal rwlock writers cond is not valid. this %p", this);
1401 rwlocks
.insert (this);
1404 pthread_rwlock::~pthread_rwlock ()
1406 rwlocks
.remove (this);
1410 pthread_rwlock::rdlock (PLARGE_INTEGER timeout
)
1413 struct RWLOCK_READER
*reader
;
1417 reader
= lookup_reader ();
1420 if (reader
->n
< UINT32_MAX
)
1427 while (writer
|| waiting_writers
)
1431 pthread_cleanup_push (pthread_rwlock::rdlock_cleanup
, this);
1434 ret
= cond_readers
.wait (&mtx
, timeout
);
1437 pthread_cleanup_pop (0);
1439 if (ret
== ETIMEDOUT
)
1446 if ((reader
= add_reader ()))
1461 pthread_rwlock::tryrdlock ()
1467 if (writer
|| waiting_writers
)
1471 RWLOCK_READER
*reader
= lookup_reader ();
1473 reader
= add_reader ();
1474 if (reader
&& reader
->n
< UINT32_MAX
)
1486 pthread_rwlock::wrlock (PLARGE_INTEGER timeout
)
1489 pthread_t self
= pthread::self ();
1493 if (writer
== self
|| lookup_reader ())
1499 while (writer
|| readers
)
1503 pthread_cleanup_push (pthread_rwlock::wrlock_cleanup
, this);
1506 ret
= cond_writers
.wait (&mtx
, timeout
);
1509 pthread_cleanup_pop (0);
1511 if (ret
== ETIMEDOUT
)
1527 pthread_rwlock::trywrlock ()
1530 pthread_t self
= pthread::self ();
1534 if (writer
|| readers
)
1545 pthread_rwlock::unlock ()
1553 if (writer
!= pthread::self ())
1563 struct RWLOCK_READER
*reader
= lookup_reader ();
1570 if (--reader
->n
> 0)
1573 remove_reader (reader
);
1585 pthread_rwlock::RWLOCK_READER
*
1586 pthread_rwlock::add_reader ()
1588 RWLOCK_READER
*rd
= new RWLOCK_READER
;
1590 List_insert_nolock (readers
, rd
);
1595 pthread_rwlock::remove_reader (struct RWLOCK_READER
*rd
)
1597 List_remove (readers_mx
, readers
, rd
);
1600 struct pthread_rwlock::RWLOCK_READER
*
1601 pthread_rwlock::lookup_reader ()
1604 pthread_t thread
= pthread::self ();
1606 struct RWLOCK_READER
*cur
= readers
;
1608 while (cur
&& cur
->thread
!= thread
)
1611 readers_mx
.unlock ();
1617 pthread_rwlock::rdlock_cleanup (void *arg
)
1619 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1621 --(rwlock
->waiting_readers
);
1623 rwlock
->mtx
.unlock ();
1627 pthread_rwlock::wrlock_cleanup (void *arg
)
1629 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1631 --(rwlock
->waiting_writers
);
1633 rwlock
->mtx
.unlock ();
1637 pthread_rwlock::_fixup_after_fork ()
1639 pthread_t self
= pthread::self ();
1640 struct RWLOCK_READER
**temp
= &readers
;
1642 waiting_readers
= 0;
1643 waiting_writers
= 0;
1645 if (!readers_mx
.init ())
1646 api_fatal ("pthread_rwlock::_fixup_after_fork () failed to recreate mutex");
1648 /* Unlock eventually locked mutex */
1651 * Remove all readers except self
1655 if ((*temp
)->thread
== self
)
1656 temp
= &((*temp
)->next
);
1659 struct RWLOCK_READER
*cur
= *temp
;
1660 *temp
= (*temp
)->next
;
1667 /* static members */
1668 /* This stores pthread_key information across fork() boundaries */
1669 List
<pthread_key
> pthread_key::keys
;
1671 /* non-static members */
1673 pthread_key::pthread_key (void (*aDestructor
) (void *)):verifyable_object (PTHREAD_KEY_MAGIC
), destructor (aDestructor
)
1675 tls_index
= TlsAlloc ();
1676 if (tls_index
== TLS_OUT_OF_INDEXES
)
1682 pthread_key::~pthread_key ()
1684 /* We may need to make the list code lock the list during operations
1689 TlsFree (tls_index
);
1694 pthread_key::_fixup_before_fork ()
1700 pthread_key::_fixup_after_fork ()
1702 tls_index
= TlsAlloc ();
1703 if (tls_index
== TLS_OUT_OF_INDEXES
)
1704 api_fatal ("pthread_key::recreate_key_from_buffer () failed to reallocate Tls storage");
1708 bool pthread_key::iterate_dtors_once_more
;
1711 pthread_key::run_destructor ()
1715 void *oldValue
= get ();
1719 destructor (oldValue
);
1721 iterate_dtors_once_more
= true;
1726 /* pshared mutexs */
1728 /* static members */
1730 List
<pthread_mutex
> pthread_mutex::mutexes
;
1732 /* This is used for mutex creation protection within a single process only */
1733 fast_mutex NO_COPY
pthread_mutex::mutex_initialization_lock
;
1736 pthread_mutex::init_mutex ()
1738 if (!mutex_initialization_lock
.init ())
1739 api_fatal ("Could not create win32 Mutex for pthread mutex static initializer support.");
1742 pthread_mutex::pthread_mutex (pthread_mutexattr
*attr
) :
1743 verifyable_object (0), /* set magic to zero initially */
1745 win32_obj_id (NULL
), owner (_new_mutex
),
1749 recursion_counter (0), condwaits (0),
1750 type (PTHREAD_MUTEX_NORMAL
),
1751 pshared (PTHREAD_PROCESS_PRIVATE
)
1753 win32_obj_id
= ::CreateEvent (&sec_none_nih
, false, false, NULL
);
1756 /*attr checked in the C call */
1758 /* handled in the caller */;
1759 else if (attr
->pshared
!= PTHREAD_PROCESS_SHARED
)
1760 type
= attr
->mutextype
;
1762 return; /* Not implemented */
1764 magic
= PTHREAD_MUTEX_MAGIC
;
1765 mutexes
.insert (this);
1768 pthread_mutex::~pthread_mutex ()
1772 CloseHandle (win32_obj_id
);
1773 win32_obj_id
= NULL
;
1776 mutexes
.remove (this);
1777 owner
= _destroyed_mutex
;
1782 pthread_mutex::lock (PLARGE_INTEGER timeout
)
1784 pthread_t self
= ::pthread_self ();
1787 if (InterlockedIncrement (&lock_counter
) == 1)
1789 else if (type
== PTHREAD_MUTEX_NORMAL
/* potentially causes deadlock */
1790 || !pthread::equal (owner
, self
))
1792 if (cygwait (win32_obj_id
, timeout
, cw_sig
| cw_sig_restart
)
1797 InterlockedDecrement (&lock_counter
);
1803 InterlockedDecrement (&lock_counter
);
1804 if (type
== PTHREAD_MUTEX_RECURSIVE
)
1805 result
= lock_recursive ();
1810 pthread_printf ("mutex %p, self %p, owner %p, lock_counter %d, recursion_counter %u",
1811 this, self
, owner
, lock_counter
, recursion_counter
);
1816 pthread_mutex::unlock ()
1819 pthread_t self
= ::pthread_self ();
1820 if (type
== PTHREAD_MUTEX_NORMAL
)
1821 /* no error checking */;
1822 else if (no_owner ())
1823 res
= type
== PTHREAD_MUTEX_ERRORCHECK
? EPERM
: 0;
1824 else if (!pthread::equal (owner
, self
))
1826 if (!res
&& recursion_counter
> 0 && --recursion_counter
== 0)
1827 /* Don't try to unlock anything if recursion_counter == 0.
1828 This means the mutex was never locked or that we've forked. */
1830 owner
= (pthread_t
) _unlocked_mutex
;
1832 tid
= 0; // thread-id
1834 if (InterlockedDecrement (&lock_counter
))
1835 ::SetEvent (win32_obj_id
); // Another thread is waiting
1839 pthread_printf ("mutex %p, owner %p, self %p, lock_counter %d, recursion_counter %u, type %d, res %d",
1840 this, owner
, self
, lock_counter
, recursion_counter
, type
, res
);
1845 pthread_mutex::trylock ()
1847 pthread_t self
= ::pthread_self ();
1850 if (InterlockedCompareExchange (&lock_counter
, 1, 0) == 0)
1852 else if (type
== PTHREAD_MUTEX_RECURSIVE
&& pthread::equal (owner
, self
))
1853 result
= lock_recursive ();
1861 pthread_mutex::destroy ()
1863 if (condwaits
|| trylock ())
1864 // Do not destroy a condwaited or locked mutex
1866 else if (recursion_counter
> 1)
1868 // Do not destroy a recursive locked mutex
1869 recursion_counter
--;
1878 pthread_mutex::_fixup_after_fork ()
1880 pthread_printf ("mutex %p", this);
1881 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
1882 api_fatal ("pthread_mutex::_fixup_after_fork () doesn't understand PROCESS_SHARED mutex's");
1884 /* All waiting threads are gone after a fork */
1885 recursion_counter
= 0;
1889 tid
= 0xffffffff; /* Don't know the tid after a fork */
1891 win32_obj_id
= ::CreateEvent (&sec_none_nih
, false, false, NULL
);
1893 api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 event for mutex");
1896 pthread_mutexattr::pthread_mutexattr ():verifyable_object (PTHREAD_MUTEXATTR_MAGIC
),
1897 pshared (PTHREAD_PROCESS_PRIVATE
), mutextype (PTHREAD_MUTEX_NORMAL
)
1901 pthread_mutexattr::~pthread_mutexattr ()
1905 /* pshared spinlocks
1907 The infrastructure is provided by the underlying pthread_mutex class.
1908 The rest is a simplification implementing spin locking. */
1910 pthread_spinlock::pthread_spinlock (int pshared
) :
1911 pthread_mutex (NULL
)
1913 magic
= PTHREAD_SPINLOCK_MAGIC
;
1914 set_type (PTHREAD_MUTEX_NORMAL
);
1915 set_shared (pshared
);
1919 pthread_spinlock::lock ()
1921 pthread_t self
= ::pthread_self ();
1926 We want to spin using 'pause' instruction on multi-core system but we
1927 want to avoid this on single-core systems.
1929 The limit of 1000 spins is semi-arbitrary. Microsoft suggests (in their
1930 InitializeCriticalSectionAndSpinCount documentation on MSDN) they are
1931 using spin count limit 4000 for their heap manager critical
1932 sections. Other source suggest spin count as small as 200 for fast path
1935 unsigned const FAST_SPINS_LIMIT
= wincap
.cpu_count () != 1 ? 1000 : 0;
1939 if (InterlockedExchange (&lock_counter
, 1) == 0)
1944 else if (unlikely(pthread::equal (owner
, self
)))
1946 else if (spins
< FAST_SPINS_LIMIT
)
1949 __asm__
volatile ("pause":::);
1953 /* Minimal timeout to minimize CPU usage while still spinning. */
1954 LARGE_INTEGER timeout
;
1955 timeout
.QuadPart
= -10000LL;
1956 /* FIXME: no cancel? */
1957 cygwait (win32_obj_id
, &timeout
, cw_sig
);
1960 while (result
== -1);
1961 pthread_printf ("spinlock %p, self %p, owner %p", this, self
, owner
);
1966 pthread_spinlock::unlock ()
1968 pthread_t self
= ::pthread_self ();
1971 if (!pthread::equal (owner
, self
))
1975 owner
= (pthread_t
) _unlocked_mutex
;
1977 tid
= 0; // thread-id
1979 InterlockedExchange (&lock_counter
, 0);
1980 ::SetEvent (win32_obj_id
);
1983 pthread_printf ("spinlock %p, owner %p, self %p, res %d",
1984 this, owner
, self
, result
);
1989 pthread::thread_init_wrapper (void *arg
)
1992 pthread
*thread
= (pthread
*) arg
;
1993 /* This *must* be set prior to calling set_tls_self_pointer or there is
1994 a race with the signal processing code which may miss the signal mask
1996 _my_tls
.sigmask
= thread
->parent_sigmask
;
1997 thread
->set_tls_self_pointer ();
1999 // Give thread default name
2000 SetThreadName (GetCurrentThreadId (), program_invocation_short_name
);
2002 thread
->mutex
.lock ();
2004 // if thread is detached force cleanup on exit
2005 if (thread
->attr
.joinable
== PTHREAD_CREATE_DETACHED
&& thread
->joiner
== NULL
)
2006 thread
->joiner
= thread
;
2007 thread
->mutex
.unlock ();
2009 debug_printf ("tid %p", &_my_tls
);
2010 thread_printf ("started thread %p %p %p %p %p %p", arg
, &_my_tls
.local_clib
,
2011 _impure_ptr
, thread
, thread
->function
, thread
->arg
);
2013 // call the user's thread
2014 void *ret
= thread
->function (thread
->arg
);
2018 return 0; // just for show. Never returns.
2022 pthread::getsequence_np ()
2024 return get_thread_id ();
2028 pthread::create (pthread_t
*thread
, const pthread_attr_t
*attr
,
2029 void *(*start_routine
) (void *), void *arg
)
2031 if (attr
&& !pthread_attr::is_good_object (attr
))
2034 *thread
= new pthread ();
2035 if (!(*thread
)->create (start_routine
, attr
? *attr
: NULL
, arg
))
2046 pthread::once (pthread_once_t
*once_control
, void (*init_routine
) (void))
2049 if (once_control
->state
)
2052 pthread_mutex_lock (&once_control
->mutex
);
2053 /* Here we must set a cancellation handler to unlock the mutex if needed */
2054 /* but a cancellation handler is not the right thing. We need this in the thread
2055 *cleanup routine. Assumption: a thread can only be in one pthread_once routine
2056 *at a time. Stote a mutex_t *in the pthread_structure. if that's non null unlock
2057 *on pthread_exit ();
2059 if (!once_control
->state
)
2062 once_control
->state
= 1;
2063 pthread_mutex_unlock (&once_control
->mutex
);
2064 while (pthread_mutex_destroy (&once_control
->mutex
) == EBUSY
);
2067 /* Here we must remove our cancellation handler */
2068 pthread_mutex_unlock (&once_control
->mutex
);
2073 pthread::cancel (pthread_t thread
)
2075 if (!is_good_object (&thread
))
2078 return thread
->cancel ();
2082 pthread::atforkprepare ()
2084 callback
*cb
= MT_INTERFACE
->pthread_prepare
;
2093 MT_INTERFACE
->fixup_before_fork ();
2097 pthread::atforkparent ()
2101 callback
*cb
= MT_INTERFACE
->pthread_parent
;
2110 pthread::atforkchild ()
2112 MT_INTERFACE
->fixup_after_fork ();
2116 callback
*cb
= MT_INTERFACE
->pthread_child
;
2124 /* Register a set of functions to run before and after fork.
2125 prepare calls are called in LI-FC order.
2126 parent and child calls are called in FI-FC order. */
2128 pthread::atfork (void (*prepare
)(void), void (*parent
)(void), void (*child
)(void))
2130 callback
*prepcb
= NULL
, *parentcb
= NULL
, *childcb
= NULL
;
2133 prepcb
= new callback
;
2139 parentcb
= new callback
;
2149 childcb
= new callback
;
2162 prepcb
->cb
= prepare
;
2163 List_insert_nolock (MT_INTERFACE
->pthread_prepare
, prepcb
);
2167 parentcb
->cb
= parent
;
2168 callback
**t
= &MT_INTERFACE
->pthread_parent
;
2171 /* t = pointer to last next in the list */
2172 List_insert_nolock (*t
, parentcb
);
2176 childcb
->cb
= child
;
2177 callback
**t
= &MT_INTERFACE
->pthread_child
;
2180 /* t = pointer to last next in the list */
2181 List_insert_nolock (*t
, childcb
);
2187 pthread::join (pthread_t
*thread
, void **return_val
, PLARGE_INTEGER timeout
)
2189 pthread_t joiner
= self ();
2191 joiner
->testcancel ();
2193 // Initialize return val with NULL
2197 if (!is_good_object (&joiner
))
2200 if (!is_good_object (thread
))
2203 if (equal (*thread
,joiner
))
2206 (*thread
)->mutex
.lock ();
2208 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2210 (*thread
)->mutex
.unlock ();
2215 (*thread
)->joiner
= joiner
;
2216 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2217 (*thread
)->mutex
.unlock ();
2219 switch (cygwait ((*thread
)->win32_obj_id
, timeout
,
2220 cw_sig
| cw_sig_restart
| cw_cancel
))
2224 *return_val
= (*thread
)->return_ptr
;
2228 // set joined thread back to joinable since we got canceled
2229 (*thread
)->joiner
= NULL
;
2230 (*thread
)->attr
.joinable
= PTHREAD_CREATE_JOINABLE
;
2231 joiner
->cancel_self ();
2235 // set joined thread back to joinable since we got canceled
2236 (*thread
)->joiner
= NULL
;
2237 (*thread
)->attr
.joinable
= PTHREAD_CREATE_JOINABLE
;
2238 return (timeout
&& timeout
->QuadPart
== 0LL) ? EBUSY
: ETIMEDOUT
;
2240 // should never happen
2249 pthread::detach (pthread_t
*thread
)
2251 if (!is_good_object (thread
))
2254 (*thread
)->mutex
.lock ();
2255 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2257 (*thread
)->mutex
.unlock ();
2261 // check if thread is still alive
2262 if ((*thread
)->valid
&& WaitForSingleObject ((*thread
)->win32_obj_id
, 0) == WAIT_TIMEOUT
)
2264 // force cleanup on exit
2265 (*thread
)->joiner
= *thread
;
2266 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2267 (*thread
)->mutex
.unlock ();
2271 // thread has already terminated.
2272 (*thread
)->mutex
.unlock ();
2280 pthread::suspend (pthread_t
*thread
)
2282 if (!is_good_object (thread
))
2285 if ((*thread
)->suspended
== false)
2287 (*thread
)->suspended
= true;
2288 SuspendThread ((*thread
)->win32_obj_id
);
2296 pthread::resume (pthread_t
*thread
)
2298 if (!is_good_object (thread
))
2301 if ((*thread
)->suspended
== true)
2302 ResumeThread ((*thread
)->win32_obj_id
);
2303 (*thread
)->suspended
= false;
2309 pthread_convert_abstime (clockid_t clock_id
, const struct timespec
*abstime
,
2310 PLARGE_INTEGER timeout
)
2314 /* According to SUSv3, the abstime value must be checked for validity. */
2315 if (!valid_timespec (*abstime
))
2318 /* Check for immediate timeout before converting */
2319 clock_gettime (clock_id
, &tp
);
2320 if (tp
.tv_sec
> abstime
->tv_sec
2321 || (tp
.tv_sec
== abstime
->tv_sec
2322 && tp
.tv_nsec
> abstime
->tv_nsec
))
2325 timeout
->QuadPart
= abstime
->tv_sec
* NS100PERSEC
2326 + (abstime
->tv_nsec
+ (NSPERSEC
/NS100PERSEC
) - 1)
2327 / (NSPERSEC
/NS100PERSEC
);
2330 case CLOCK_REALTIME_COARSE
:
2331 case CLOCK_REALTIME
:
2332 timeout
->QuadPart
+= FACTOR
;
2335 /* other clocks must be handled as relative timeout */
2336 timeout
->QuadPart
-= tp
.tv_sec
* NS100PERSEC
+ tp
.tv_nsec
2337 / (NSPERSEC
/NS100PERSEC
);
2338 timeout
->QuadPart
*= -1LL;
2345 pthread_cond::init (pthread_cond_t
*cond
, const pthread_condattr_t
*attr
)
2347 pthread_cond_t new_cond
;
2349 if (attr
&& !pthread_condattr::is_good_object (attr
))
2352 cond_initialization_lock
.lock ();
2354 new_cond
= new pthread_cond (attr
? (*attr
) : NULL
);
2355 if (!is_good_object (&new_cond
))
2358 cond_initialization_lock
.unlock ();
2374 cond_initialization_lock
.unlock ();
2379 pthread_rwlock::init (pthread_rwlock_t
*rwlock
, const pthread_rwlockattr_t
*attr
)
2381 pthread_rwlock_t new_rwlock
;
2383 if (attr
&& !pthread_rwlockattr::is_good_object (attr
))
2386 rwlock_initialization_lock
.lock ();
2388 new_rwlock
= new pthread_rwlock (attr
? (*attr
) : NULL
);
2389 if (!is_good_object (&new_rwlock
))
2392 rwlock_initialization_lock
.unlock ();
2400 *rwlock
= new_rwlock
;
2408 rwlock_initialization_lock
.unlock ();
2415 pthread_mutex::init (pthread_mutex_t
*mutex
,
2416 const pthread_mutexattr_t
*attr
,
2417 const pthread_mutex_t initializer
)
2419 if (attr
&& !pthread_mutexattr::is_good_object (attr
))
2422 mutex_initialization_lock
.lock ();
2423 if (initializer
== NULL
|| pthread_mutex::is_initializer (mutex
))
2425 pthread_mutex_t new_mutex
= new pthread_mutex (attr
? (*attr
) : NULL
);
2426 if (!is_good_object (&new_mutex
))
2429 mutex_initialization_lock
.unlock ();
2433 if (!attr
&& initializer
)
2435 if (initializer
== PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
)
2436 new_mutex
->type
= PTHREAD_MUTEX_RECURSIVE
;
2437 else if (initializer
== PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
)
2438 new_mutex
->type
= PTHREAD_MUTEX_NORMAL
;
2439 else if (initializer
== PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
)
2440 new_mutex
->type
= PTHREAD_MUTEX_ERRORCHECK
;
2450 mutex_initialization_lock
.unlock ();
2455 mutex_initialization_lock
.unlock ();
2456 pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex
, attr
, initializer
);
2464 pthread_spinlock::init (pthread_spinlock_t
*spinlock
, int pshared
)
2466 pthread_spinlock_t new_spinlock
= new pthread_spinlock (pshared
);
2467 if (!is_good_object (&new_spinlock
))
2469 delete new_spinlock
;
2475 *spinlock
= new_spinlock
;
2479 delete new_spinlock
;
2483 pthread_printf ("*spinlock %p, pshared %d", *spinlock
, pshared
);
2489 List
<semaphore
> semaphore::semaphores
;
2491 semaphore::semaphore (int pshared
, unsigned int value
)
2492 : verifyable_object (SEM_MAGIC
),
2500 SECURITY_ATTRIBUTES sa
= (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2501 ? sec_all
: sec_none_nih
;
2502 this->win32_obj_id
= ::CreateSemaphore (&sa
, value
, INT32_MAX
, NULL
);
2503 if (!this->win32_obj_id
)
2506 semaphores
.insert (this);
2509 semaphore::semaphore (unsigned long long shash
, LUID sluid
, int sfd
,
2510 sem_t
*ssem
, int oflag
, mode_t mode
, unsigned int value
)
2511 : verifyable_object (SEM_MAGIC
),
2512 shared (PTHREAD_PROCESS_SHARED
),
2513 currentvalue (-1), /* Unused for named semaphores. */
2520 char name
[MAX_PATH
];
2522 __small_sprintf (name
, "semaphore/%016X%08x%08x",
2523 hash
, luid
.HighPart
, luid
.LowPart
);
2524 this->win32_obj_id
= ::CreateSemaphore (&sec_all
, value
, INT32_MAX
, name
);
2525 if (!this->win32_obj_id
)
2527 if (GetLastError () == ERROR_ALREADY_EXISTS
&& (oflag
& O_EXCL
))
2530 CloseHandle (this->win32_obj_id
);
2534 semaphores
.insert (this);
2537 semaphore::~semaphore ()
2540 CloseHandle (win32_obj_id
);
2542 semaphores
.remove (this);
2549 ReleaseSemaphore (win32_obj_id
, 1, &dummy
);
2553 semaphore::_getvalue (int *sval
)
2556 SEMAPHORE_BASIC_INFORMATION sbi
;
2558 status
= NtQuerySemaphore (win32_obj_id
, SemaphoreBasicInformation
, &sbi
,
2561 if (NT_SUCCESS (status
))
2563 *sval
= sbi
.CurrentCount
;
2569 __seterrno_from_nt_status (status
);
2576 semaphore::_trywait ()
2578 /* FIXME: signals should be able to interrupt semaphores...
2579 We probably need WaitForMultipleObjects here. */
2580 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
2589 semaphore::_wait (PLARGE_INTEGER timeout
)
2593 switch (cygwait (win32_obj_id
, timeout
,
2594 cw_cancel
| cw_cancel_self
| cw_sig_eintr
))
2602 set_errno (ETIMEDOUT
);
2605 pthread_printf ("cygwait failed. %E");
2610 __except (NO_ERROR
) {}
2616 semaphore::_fixup_before_fork ()
2619 SEMAPHORE_BASIC_INFORMATION sbi
;
2621 status
= NtQuerySemaphore (win32_obj_id
, SemaphoreBasicInformation
, &sbi
,
2623 if (NT_SUCCESS (status
))
2624 currentvalue
= sbi
.CurrentCount
;
2626 currentvalue
= startvalue
;
2630 semaphore::_fixup_after_fork ()
2632 if (shared
== PTHREAD_PROCESS_PRIVATE
)
2634 pthread_printf ("sem %p", this);
2635 win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, currentvalue
,
2638 api_fatal ("failed to create new win32 semaphore, "
2639 "currentvalue %ld, %E", currentvalue
);
2644 semaphore::_terminate ()
2646 int _sem_close (sem_t
*, bool);
2649 _sem_close (sem
, false);
2652 /* static members */
2655 semaphore::init (sem_t
*sem
, int pshared
, unsigned int value
)
2658 We can't tell the difference between reinitialising an
2659 existing semaphore and initialising a semaphore who's
2660 contents happen to be a valid pointer
2662 if (is_good_object (sem
))
2663 paranoid_printf ("potential attempt to reinitialise a semaphore");
2665 if (value
> SEM_VALUE_MAX
)
2671 *sem
= new semaphore (pshared
, value
);
2673 if (!is_good_object (sem
))
2684 semaphore::destroy (sem_t
*sem
)
2686 if (!is_good_object (sem
))
2692 /* It's invalid to destroy a semaphore not opened with sem_init. */
2693 if ((*sem
)->fd
!= -1)
2699 /* FIXME - new feature - test for busy against threads... */
2707 semaphore::close (sem_t
*sem
)
2709 if (!is_good_object (sem
))
2715 /* It's invalid to close a semaphore not opened with sem_open. */
2716 if ((*sem
)->fd
== -1)
2728 semaphore::open (unsigned long long hash
, LUID luid
, int fd
, int oflag
,
2729 mode_t mode
, unsigned int value
, bool &wasopen
)
2731 if (value
> SEM_VALUE_MAX
)
2737 /* sem_open is supposed to return the same pointer, if the same named
2738 semaphore is opened multiple times in the same process, as long as
2739 the semaphore hasn't been closed or unlinked in the meantime. */
2740 semaphores
.mx
.lock ();
2741 for (semaphore
*sema
= semaphores
.head
; sema
; sema
= sema
->next
)
2742 if (sema
->fd
>= 0 && sema
->hash
== hash
2743 && sema
->luid
.HighPart
== luid
.HighPart
2744 && sema
->luid
.LowPart
== luid
.LowPart
)
2747 semaphores
.mx
.unlock ();
2750 semaphores
.mx
.unlock ();
2753 sem_t
*sem
= new sem_t
;
2760 *sem
= new semaphore (hash
, luid
, fd
, sem
, oflag
, mode
, value
);
2762 if (!is_good_object (sem
))
2772 semaphore::wait (sem_t
*sem
)
2774 pthread_testcancel ();
2776 if (!is_good_object (sem
))
2782 return (*sem
)->_wait ();
2786 semaphore::trywait (sem_t
*sem
)
2788 if (!is_good_object (sem
))
2794 return (*sem
)->_trywait ();
2798 semaphore::clockwait (sem_t
*sem
, clockid_t clock_id
,
2799 const struct timespec
*abstime
)
2801 LARGE_INTEGER timeout
;
2803 if (!is_good_object (sem
))
2809 /* According to SUSv3, abstime need not be checked for validity,
2810 if the semaphore can be locked immediately. */
2811 if (!(*sem
)->_trywait ())
2816 int err
= pthread_convert_abstime (clock_id
, abstime
, &timeout
);
2820 return (*sem
)->_wait (&timeout
);
2822 __except (NO_ERROR
) {}
2828 semaphore::post (sem_t
*sem
)
2830 if (!is_good_object (sem
))
2841 semaphore::getvalue (sem_t
*sem
, int *sval
)
2845 if (is_good_object (sem
))
2846 return (*sem
)->_getvalue (sval
);
2848 __except (NO_ERROR
) {}
2855 semaphore::getinternal (sem_t
*sem
, int *sfd
, unsigned long long *shash
,
2856 LUID
*sluid
, unsigned int *sval
)
2860 if (!is_good_object (sem
))
2862 if ((*sfd
= (*sem
)->fd
) < 0)
2864 *shash
= (*sem
)->hash
;
2865 *sluid
= (*sem
)->luid
;
2866 /* POSIX defines the value in calls to sem_init/sem_open as unsigned,
2867 but the sem_getvalue gets a pointer to int to return the value.
2869 return (*sem
)->_getvalue ((int *)sval
);
2871 __except (NO_ERROR
) {}
2879 pthread_null::get_null_pthread ()
2881 /* because of weird entry points */
2882 _instance
.magic
= 0;
2886 pthread_null::pthread_null ()
2888 attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2889 /* Mark ourselves as invalid */
2893 pthread_null::~pthread_null ()
2898 pthread_null::create (void *(*)(void *), pthread_attr
*, void *)
2904 pthread_null::exit (void *value_ptr
)
2906 _my_tls
.remove (INFINITE
);
2911 pthread_null::cancel ()
2917 pthread_null::testcancel ()
2922 pthread_null::setcancelstate (int state
, int *oldstate
)
2928 pthread_null::setcanceltype (int type
, int *oldtype
)
2934 pthread_null::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
2939 pthread_null::pop_cleanup_handler (int const execute
)
2944 pthread_null::getsequence_np ()
2949 pthread_null
pthread_null::_instance
;
2952 pthread_barrier::init (const pthread_barrierattr_t
* attr
, unsigned count
)
2954 pthread_mutex_t
* mutex
= NULL
;
2956 if (unlikely ((attr
!= NULL
2957 && (! pthread_barrierattr::is_good_object (attr
)
2958 || (*attr
)->shared
== PTHREAD_PROCESS_SHARED
))
2962 int retval
= pthread_mutex_init (&mtx
, NULL
);
2963 if (unlikely (retval
!= 0))
2966 retval
= pthread_cond_init (&cond
, NULL
);
2967 if (unlikely (retval
!= 0))
2969 int ret
= pthread_mutex_destroy (mutex
);
2971 api_fatal ("pthread_mutex_destroy (%p) = %d", mutex
, ret
);
2985 pthread_barrier::destroy ()
2987 if (unlikely (wt
!= 0))
2990 int retval
= pthread_cond_destroy (&cond
);
2991 if (unlikely (retval
!= 0))
2996 retval
= pthread_mutex_destroy (&mtx
);
2997 if (unlikely (retval
!= 0))
3010 pthread_barrier::wait ()
3012 int retval
= pthread_mutex_lock (&mtx
);
3013 if (unlikely (retval
!= 0))
3016 if (unlikely (wt
>= cnt
))
3018 api_fatal ("wt >= cnt (%u >= %u)", wt
, cnt
);
3022 if (unlikely (++wt
== cnt
))
3025 /* This is the last thread to reach the barrier. Signal the waiting
3026 threads to wake up and continue. */
3027 retval
= pthread_cond_broadcast (&cond
);
3028 if (unlikely (retval
!= 0))
3032 retval
= pthread_mutex_unlock (&mtx
);
3033 if (unlikely (retval
!= 0))
3036 return PTHREAD_BARRIER_SERIAL_THREAD
;
3040 uint64_t cycle
= cyc
;
3043 retval
= pthread_cond_wait (&cond
, &mtx
);
3044 if (unlikely (retval
!= 0))
3047 while (unlikely (cycle
== cyc
));
3049 retval
= pthread_mutex_unlock (&mtx
);
3050 if (unlikely (retval
!= 0))
3051 api_fatal ("pthread_mutex_unlock (%p) = %d", &mtx
, retval
);
3059 int ret
= pthread_mutex_unlock (&mtx
);
3060 if (unlikely (ret
!= 0))
3061 api_fatal ("pthread_mutex_unlock (%p) = %d", &mtx
, ret
);
3067 /* Returns running thread's name; works for both cygthreads and pthreads */
3071 char *result
= (char *) cygthread::name ();
3073 if (result
== _my_tls
.locals
.unknown_thread_name
)
3076 pthread_getname_np (pthread_self (), result
, (size_t) THRNAMELEN
);
3085 /* Thread creation */
3088 pthread_create (pthread_t
*thread
, const pthread_attr_t
*attr
,
3089 void *(*start_routine
) (void *), void *arg
)
3091 return pthread::create (thread
, attr
, start_routine
, arg
);
3095 pthread_once (pthread_once_t
* once_control
, void (*init_routine
) (void))
3097 return pthread::once (once_control
, init_routine
);
3101 pthread_atfork (void (*prepare
)(void), void (*parent
)(void), void (*child
)(void))
3103 return pthread::atfork (prepare
, parent
, child
);
3108 pthread_t
pthread_self ()
3110 return pthread::self ();
3114 pthread_equal (pthread_t t1
, pthread_t t2
)
3116 return pthread::equal (t1
, t2
);
3120 pthread_getsequence_np (pthread_t
* thread
)
3122 if (!pthread::is_good_object (thread
))
3124 return (*thread
)->getsequence_np ();
3130 pthread_getname_np (pthread_t thread
, char *buf
, size_t buflen
)
3134 if (!pthread::is_good_object (&thread
))
3137 if (!thread
->attr
.name
)
3138 name
= program_invocation_short_name
;
3140 name
= thread
->attr
.name
;
3142 /* Return ERANGE if the provided buffer is less than THRNAMELEN. Truncate
3143 and zero-terminate the name to fit in buf. This means we always return
3144 something if the buffer is THRNAMELEN or larger, but there is no way to
3145 tell if we have the whole name. */
3146 if (buflen
< THRNAMELEN
)
3152 strlcpy (buf
, name
, buflen
);
3164 pthread_setname_np (pthread_t thread
, const char *name
)
3168 if (!pthread::is_good_object (&thread
))
3171 if (strlen (name
) > THRNAMELEN
)
3178 oldname
= thread
->attr
.name
;
3179 thread
->attr
.name
= cp
;
3181 SetThreadName (GetThreadId (thread
->win32_obj_id
), thread
->attr
.name
);
3192 pthread_exit (void *value_ptr
)
3194 pthread::self ()->exit (value_ptr
);
3195 __builtin_unreachable (); /* FIXME: don't know why this is necessary */
3199 pthread_detach (pthread_t thread
)
3201 return pthread::detach (&thread
);
3205 pthread_join (pthread_t thread
, void **return_val
)
3207 return pthread::join (&thread
, (void **) return_val
, NULL
);
3211 pthread_tryjoin_np (pthread_t thread
, void **return_val
)
3213 LARGE_INTEGER timeout
= { QuadPart
:0LL };
3215 return pthread::join (&thread
, (void **) return_val
, &timeout
);
3219 pthread_timedjoin_np (pthread_t thread
, void **return_val
,
3220 const struct timespec
*abstime
)
3222 LARGE_INTEGER timeout
;
3224 int err
= pthread_convert_abstime (CLOCK_REALTIME
, abstime
, &timeout
);
3227 return pthread::join (&thread
, (void **) return_val
, &timeout
);
3230 /* Thread suspend/resume */
3232 /* This isn't a posix call... should we keep it? */
3234 pthread_suspend (pthread_t thread
)
3236 return pthread::suspend (&thread
);
3241 pthread_continue (pthread_t thread
)
3243 return pthread::resume (&thread
);
3249 pthread_kill (pthread_t thread
, int sig
)
3251 // lock myself, for the use of thread2signal
3252 // two different kills might clash: FIXME
3254 if (!pthread::is_good_object (&thread
))
3257 /* check that sig is in right range */
3258 if (sig
< 0 || sig
>= _NSIG
)
3263 si
.si_code
= SI_USER
;
3264 si
.si_pid
= myself
->pid
;
3265 si
.si_uid
= myself
->uid
;
3271 rval
= (int) sig_send (NULL
, si
, thread
->cygtls
);
3273 rval
= get_errno ();
3276 switch (WaitForSingleObject (thread
->win32_obj_id
, 0))
3291 pthread_sigmask (int operation
, const sigset_t
*set
, sigset_t
*old_set
)
3293 int res
= handle_sigprocmask (operation
, set
, old_set
, _my_tls
.sigmask
);
3294 syscall_printf ("%d = pthread_sigmask(%d, %p, %p)",
3295 res
, operation
, set
, old_set
);
3300 pthread_sigqueue (pthread_t
*thread
, int sig
, const union sigval value
)
3304 if (!pthread::is_good_object (thread
))
3306 if (!(*thread
)->valid
)
3310 si
.si_code
= SI_QUEUE
;
3311 si
.si_value
= value
;
3312 si
.si_pid
= myself
->pid
;
3313 si
.si_uid
= myself
->uid
;
3314 return (int) sig_send (NULL
, si
, (*thread
)->cygtls
);
3320 pthread_cancel (pthread_t thread
)
3322 return pthread::cancel (thread
);
3326 pthread_setcancelstate (int state
, int *oldstate
)
3328 return pthread::self ()->setcancelstate (state
, oldstate
);
3332 pthread_setcanceltype (int type
, int *oldtype
)
3334 return pthread::self ()->setcanceltype (type
, oldtype
);
3338 pthread_testcancel ()
3340 pthread::self ()->testcancel ();
3344 _pthread_cleanup_push (__pthread_cleanup_handler
*handler
)
3346 pthread::self ()->push_cleanup_handler (handler
);
3350 _pthread_cleanup_pop (int execute
)
3352 pthread::self ()->pop_cleanup_handler (execute
);
3355 /* provided for source level compatability.
3356 See http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
3359 pthread_getconcurrency ()
3361 return MT_INTERFACE
->concurrency
;
3364 /* provided for source level compatability. See
3365 http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
3368 pthread_setconcurrency (int new_level
)
3372 MT_INTERFACE
->concurrency
= new_level
;
3376 /* Thread scheduling */
3378 /* keep this in sync with sched.cc */
3380 pthread_getschedparam (pthread_t thread
, int *policy
,
3381 struct sched_param
*param
)
3383 if (!pthread::is_good_object (&thread
))
3385 *policy
= SCHED_FIFO
;
3386 param
->sched_priority
= sched_get_thread_priority (thread
->win32_obj_id
);
3390 /* keep this in sync with sched.cc */
3392 pthread_setschedparam (pthread_t thread
, int policy
,
3393 const struct sched_param
*param
)
3395 if (!pthread::is_good_object (&thread
))
3397 if (policy
!= SCHED_FIFO
)
3402 sched_set_thread_priority (thread
->win32_obj_id
, param
->sched_priority
);
3404 thread
->attr
.schedparam
.sched_priority
= param
->sched_priority
;
3409 pthread_setschedprio (pthread_t thread
, int priority
)
3411 if (!pthread::is_good_object (&thread
))
3414 sched_set_thread_priority (thread
->win32_obj_id
, priority
);
3416 thread
->attr
.schedparam
.sched_priority
= priority
;
3420 /* Thread affinity */
3423 pthread_getaffinity_np (pthread_t thread
, size_t sizeof_set
, cpu_set_t
*set
)
3425 if (!pthread::is_good_object (&thread
))
3428 return sched_get_thread_affinity (thread
->win32_obj_id
, sizeof_set
, set
);
3432 pthread_setaffinity_np (pthread_t thread
, size_t sizeof_set
, const cpu_set_t
*set
)
3434 if (!pthread::is_good_object (&thread
))
3437 return sched_set_thread_affinity (thread
->win32_obj_id
, sizeof_set
, set
);
3443 pthread_attr_init (pthread_attr_t
*attr
)
3445 *attr
= new pthread_attr
;
3446 if (!pthread_attr::is_good_object (attr
))
3456 pthread_attr_getinheritsched (const pthread_attr_t
*attr
,
3459 if (!pthread_attr::is_good_object (attr
))
3461 *inheritsched
= (*attr
)->inheritsched
;
3466 pthread_attr_getschedparam (const pthread_attr_t
*attr
,
3467 struct sched_param
*param
)
3469 if (!pthread_attr::is_good_object (attr
))
3471 *param
= (*attr
)->schedparam
;
3475 /* From a pure code point of view, this should call a helper in sched.cc,
3476 to allow for someone adding scheduler policy changes to win32 in the future.
3477 However that's extremely unlikely, so short and sweet will do us */
3479 pthread_attr_getschedpolicy (const pthread_attr_t
*attr
, int *policy
)
3481 if (!pthread_attr::is_good_object (attr
))
3483 *policy
= SCHED_FIFO
;
3489 pthread_attr_getscope (const pthread_attr_t
*attr
, int *contentionscope
)
3491 if (!pthread_attr::is_good_object (attr
))
3493 *contentionscope
= (*attr
)->contentionscope
;
3498 pthread_attr_setdetachstate (pthread_attr_t
*attr
, int detachstate
)
3500 if (!pthread_attr::is_good_object (attr
))
3502 if (detachstate
< 0 || detachstate
> 1)
3504 (*attr
)->joinable
= detachstate
;
3509 pthread_attr_getdetachstate (const pthread_attr_t
*attr
, int *detachstate
)
3511 if (!pthread_attr::is_good_object (attr
))
3513 *detachstate
= (*attr
)->joinable
;
3518 pthread_attr_setinheritsched (pthread_attr_t
*attr
, int inheritsched
)
3520 if (!pthread_attr::is_good_object (attr
))
3522 if (inheritsched
!= PTHREAD_INHERIT_SCHED
3523 && inheritsched
!= PTHREAD_EXPLICIT_SCHED
)
3525 (*attr
)->inheritsched
= inheritsched
;
3530 pthread_attr_setschedparam (pthread_attr_t
*attr
,
3531 const struct sched_param
*param
)
3533 if (!pthread_attr::is_good_object (attr
))
3535 if (!valid_sched_parameters (param
))
3537 (*attr
)->schedparam
= *param
;
3541 /* See __pthread_attr_getschedpolicy for some notes */
3543 pthread_attr_setschedpolicy (pthread_attr_t
*attr
, int policy
)
3545 if (!pthread_attr::is_good_object (attr
))
3547 if (policy
!= SCHED_FIFO
)
3553 pthread_attr_setscope (pthread_attr_t
*attr
, int contentionscope
)
3555 if (!pthread_attr::is_good_object (attr
))
3557 if (contentionscope
!= PTHREAD_SCOPE_SYSTEM
3558 && contentionscope
!= PTHREAD_SCOPE_PROCESS
)
3560 /* In future, we may be able to support system scope by escalating the thread
3561 priority to exceed the priority class. For now we only support PROCESS scope. */
3562 if (contentionscope
!= PTHREAD_SCOPE_PROCESS
)
3564 (*attr
)->contentionscope
= contentionscope
;
3569 pthread_attr_setstack (pthread_attr_t
*attr
, void *addr
, size_t size
)
3571 if (!pthread_attr::is_good_object (attr
))
3575 if (size
< PTHREAD_STACK_MIN
)
3577 /* The incoming address addr points to the lowest addressable byte of a
3578 buffer of size bytes. Due to the way pthread_attr_setstackaddr is defined
3579 on Linux, the lowest address ot the stack can't be reliably computed when
3580 using pthread_attr_setstackaddr/pthread_attr_setstacksize. Therefore we
3581 store the uppermost address of the stack in stackaddr. See also the
3582 comment in pthread_attr_setstackaddr. */
3583 (*attr
)->stackaddr
= (caddr_t
) addr
+ size
;
3584 (*attr
)->stacksize
= size
;
3589 pthread_attr_getstack (const pthread_attr_t
*attr
, void **addr
, size_t *size
)
3591 if (!pthread_attr::is_good_object (attr
))
3593 /* stackaddr holds the uppermost stack address. See the comment in
3594 pthread_attr_setstack. */
3595 *addr
= (caddr_t
) (*attr
)->stackaddr
- (*attr
)->stacksize
;
3596 *size
= (*attr
)->stacksize
;
3601 pthread_attr_setstackaddr (pthread_attr_t
*attr
, void *addr
)
3603 if (!pthread_attr::is_good_object (attr
))
3607 /* This function is deprecated in SUSv4, but SUSv3 didn't define
3608 if the incoming stack address is the lowest address of the memory
3609 area defined as stack, or if it's the start address of the stack
3610 at which it begins its growth. On Linux it's the latter which
3611 means the uppermost stack address on x86 based systems. See comment
3612 in pthread_attr_setstack as well. */
3613 (*attr
)->stackaddr
= addr
;
3618 pthread_attr_getstackaddr (const pthread_attr_t
*attr
, void **addr
)
3620 if (!pthread_attr::is_good_object (attr
))
3622 /* See comment in pthread_attr_setstackaddr. */
3623 *addr
= (*attr
)->stackaddr
;
3628 pthread_attr_setstacksize (pthread_attr_t
*attr
, size_t size
)
3630 if (!pthread_attr::is_good_object (attr
))
3632 if (size
< PTHREAD_STACK_MIN
)
3634 (*attr
)->stacksize
= size
;
3639 pthread_attr_getstacksize (const pthread_attr_t
*attr
, size_t *size
)
3641 if (!pthread_attr::is_good_object (attr
))
3643 /* If the stacksize has not been set by the application, return the
3644 default stacksize. Note that this is different from what
3645 pthread_attr_getstack returns. */
3646 *size
= (*attr
)->stacksize
?: get_rlimit_stack ();
3651 pthread_attr_setguardsize (pthread_attr_t
*attr
, size_t size
)
3653 if (!pthread_attr::is_good_object (attr
))
3655 /* We don't support a guardsize of more than 1 Meg. */
3656 if (size
> 1024 * 1024)
3658 (*attr
)->guardsize
= size
;
3663 pthread_attr_getguardsize (const pthread_attr_t
*attr
, size_t *size
)
3665 if (!pthread_attr::is_good_object (attr
))
3667 *size
= (*attr
)->guardsize
;
3672 pthread_attr_destroy (pthread_attr_t
*attr
)
3674 if (!pthread_attr::is_good_object (attr
))
3682 pthread_getattr_np (pthread_t thread
, pthread_attr_t
*attr
)
3684 THREAD_BASIC_INFORMATION tbi
;
3687 if (!pthread::is_good_object (&thread
))
3690 /* attr may not be pre-initialized */
3691 if (!pthread_attr::is_good_object (attr
))
3693 int rv
= pthread_attr_init (attr
);
3698 (*attr
)->joinable
= thread
->attr
.joinable
;
3699 (*attr
)->contentionscope
= thread
->attr
.contentionscope
;
3700 (*attr
)->inheritsched
= thread
->attr
.inheritsched
;
3701 (*attr
)->schedparam
= thread
->attr
.schedparam
;
3702 (*attr
)->guardsize
= thread
->attr
.guardsize
;
3704 status
= NtQueryInformationThread (thread
->win32_obj_id
,
3705 ThreadBasicInformation
,
3706 &tbi
, sizeof (tbi
), NULL
);
3707 if (NT_SUCCESS (status
))
3709 PTEB teb
= (PTEB
) tbi
.TebBaseAddress
;
3710 /* stackaddr holds the uppermost stack address. See the comments
3711 in pthread_attr_setstack and pthread_attr_setstackaddr for a
3713 (*attr
)->stackaddr
= teb
->Tib
.StackBase
;
3714 (*attr
)->stacksize
= (uintptr_t) teb
->Tib
.StackBase
3715 - (uintptr_t) (teb
->DeallocationStack
?: teb
->Tib
.StackLimit
);
3719 debug_printf ("NtQueryInformationThread(ThreadBasicInformation), "
3720 "status %y", status
);
3721 (*attr
)->stackaddr
= thread
->attr
.stackaddr
;
3722 (*attr
)->stacksize
= thread
->attr
.stacksize
;
3728 /* Thread Specific Data */
3731 pthread_key_create (pthread_key_t
*key
, void (*destructor
) (void *))
3733 *key
= new pthread_key (destructor
);
3735 if (!pthread_key::is_good_object (key
))
3745 pthread_key_delete (pthread_key_t key
)
3747 if (!pthread_key::is_good_object (&key
))
3755 pthread_getspecific (pthread_key_t key
)
3757 if (!pthread_key::is_good_object (&key
))
3760 return (key
)->get ();
3764 pthread_setspecific (pthread_key_t key
, const void *value
)
3766 if (!pthread_key::is_good_object (&key
))
3775 pthread_mutex_init (pthread_mutex_t
* mutex
, const pthread_mutexattr_t
* attr
)
3777 return pthread_mutex::init (mutex
, attr
, NULL
);
3781 pthread_mutex_getprioceiling (const pthread_mutex_t
*mutex
,
3784 /* We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support
3787 We can support mutex priorities in the future though:
3788 Store a priority with each mutex.
3789 When the mutex is optained, set the thread priority as appropriate
3790 When the mutex is released, reset the thread priority. */
3795 pthread_mutex_lock (pthread_mutex_t
*mutex
)
3797 if (pthread_mutex::is_initializer (mutex
))
3798 pthread_mutex::init (mutex
, NULL
, *mutex
);
3799 if (!pthread_mutex::is_good_object (mutex
))
3801 return (*mutex
)->lock ();
3805 pthread_mutex_clocklock (pthread_mutex_t
*mutex
, clockid_t clock_id
,
3806 const struct timespec
*abstime
)
3808 LARGE_INTEGER timeout
;
3810 if (pthread_mutex::is_initializer (mutex
))
3811 pthread_mutex::init (mutex
, NULL
, *mutex
);
3812 if (!pthread_mutex::is_good_object (mutex
))
3815 /* According to SUSv3, abstime need not be checked for validity,
3816 if the mutex can be locked immediately. */
3817 if (!(*mutex
)->trylock ())
3822 int err
= pthread_convert_abstime (clock_id
, abstime
, &timeout
);
3826 return (*mutex
)->lock (&timeout
);
3828 __except (NO_ERROR
) {}
3834 pthread_mutex_timedlock (pthread_mutex_t
*mutex
, const struct timespec
*abstime
)
3836 return pthread_mutex_clocklock (mutex
, CLOCK_REALTIME
, abstime
);
3840 pthread_mutex_trylock (pthread_mutex_t
*mutex
)
3842 if (pthread_mutex::is_initializer (mutex
))
3843 pthread_mutex::init (mutex
, NULL
, *mutex
);
3844 if (!pthread_mutex::is_good_object (mutex
))
3846 return (*mutex
)->trylock ();
3850 pthread_mutex_unlock (pthread_mutex_t
*mutex
)
3852 if (pthread_mutex::is_initializer (mutex
))
3853 pthread_mutex::init (mutex
, NULL
, *mutex
);
3854 if (!pthread_mutex::is_good_object (mutex
))
3856 return (*mutex
)->unlock ();
3860 pthread_mutex_destroy (pthread_mutex_t
*mutex
)
3864 if (pthread_mutex::is_initializer (mutex
))
3866 if (!pthread_mutex::is_good_object (mutex
))
3869 rv
= (*mutex
)->destroy ();
3878 pthread_mutex_setprioceiling (pthread_mutex_t
*mutex
, int prioceiling
,
3884 /* Mutex attributes */
3886 /* Win32 doesn't support mutex priorities - see __pthread_mutex_getprioceiling
3889 pthread_mutexattr_getprotocol (const pthread_mutexattr_t
*attr
,
3892 if (!pthread_mutexattr::is_good_object (attr
))
3898 pthread_mutexattr_getpshared (const pthread_mutexattr_t
*attr
,
3901 if (!pthread_mutexattr::is_good_object (attr
))
3903 *pshared
= (*attr
)->pshared
;
3908 pthread_mutexattr_gettype (const pthread_mutexattr_t
*attr
, int *type
)
3910 if (!pthread_mutexattr::is_good_object (attr
))
3912 *type
= (*attr
)->mutextype
;
3916 /* FIXME: write and test process shared mutex's. */
3918 pthread_mutexattr_init (pthread_mutexattr_t
*attr
)
3920 *attr
= new pthread_mutexattr ();
3921 if (!pthread_mutexattr::is_good_object (attr
))
3931 pthread_mutexattr_destroy (pthread_mutexattr_t
*attr
)
3933 if (!pthread_mutexattr::is_good_object (attr
))
3941 /* Win32 doesn't support mutex priorities */
3943 pthread_mutexattr_setprotocol (pthread_mutexattr_t
*attr
, int protocol
)
3945 if (!pthread_mutexattr::is_good_object (attr
))
3950 /* Win32 doesn't support mutex priorities */
3952 pthread_mutexattr_setprioceiling (pthread_mutexattr_t
*attr
,
3955 if (!pthread_mutexattr::is_good_object (attr
))
3961 pthread_mutexattr_getprioceiling (const pthread_mutexattr_t
*attr
,
3964 if (!pthread_mutexattr::is_good_object (attr
))
3970 pthread_mutexattr_setpshared (pthread_mutexattr_t
*attr
, int pshared
)
3972 if (!pthread_mutexattr::is_good_object (attr
))
3974 /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
3977 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
3979 (*attr
)->pshared
= pshared
;
3983 /* see pthread_mutex_gettype */
3985 pthread_mutexattr_settype (pthread_mutexattr_t
*attr
, int type
)
3987 if (!pthread_mutexattr::is_good_object (attr
))
3992 case PTHREAD_MUTEX_ERRORCHECK
:
3993 case PTHREAD_MUTEX_RECURSIVE
:
3994 case PTHREAD_MUTEX_NORMAL
:
3995 (*attr
)->mutextype
= type
;
4007 pthread_spin_init (pthread_spinlock_t
*spinlock
, int pshared
)
4009 return pthread_spinlock::init (spinlock
, pshared
);
4013 pthread_spin_lock (pthread_spinlock_t
*spinlock
)
4015 if (!pthread_spinlock::is_good_object (spinlock
))
4017 return (*spinlock
)->lock ();
4021 pthread_spin_trylock (pthread_spinlock_t
*spinlock
)
4023 if (!pthread_spinlock::is_good_object (spinlock
))
4025 return (*spinlock
)->trylock ();
4029 pthread_spin_unlock (pthread_spinlock_t
*spinlock
)
4031 if (!pthread_spinlock::is_good_object (spinlock
))
4033 return (*spinlock
)->unlock ();
4037 pthread_spin_destroy (pthread_spinlock_t
*spinlock
)
4039 if (!pthread_spinlock::is_good_object (spinlock
))
4041 return (*spinlock
)->destroy ();
4044 /* Synchronisation */
4047 pthread_cond_init (pthread_cond_t
* cond
, const pthread_condattr_t
* attr
)
4049 return pthread_cond::init (cond
, attr
);
4053 pthread_cond_destroy (pthread_cond_t
*cond
)
4055 if (pthread_cond::is_initializer (cond
))
4057 if (!pthread_cond::is_good_object (cond
))
4060 /* reads are atomic */
4061 if ((*cond
)->waiting
)
4071 pthread_cond_broadcast (pthread_cond_t
*cond
)
4073 if (pthread_cond::is_initializer (cond
))
4075 if (!pthread_cond::is_good_object (cond
))
4078 (*cond
)->unblock (true);
4084 pthread_cond_signal (pthread_cond_t
*cond
)
4086 if (pthread_cond::is_initializer (cond
))
4088 if (!pthread_cond::is_good_object (cond
))
4091 (*cond
)->unblock (false);
4097 __pthread_cond_wait_init (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
)
4099 if (!pthread_mutex::is_good_object (mutex
))
4101 if (!(*mutex
)->can_be_unlocked ())
4104 if (pthread_cond::is_initializer (cond
))
4105 pthread_cond::init (cond
, NULL
);
4106 if (!pthread_cond::is_good_object (cond
))
4113 __pthread_cond_clockwait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
4114 clockid_t clock_id
, const struct timespec
*abstime
)
4117 LARGE_INTEGER timeout
;
4121 err
= pthread_convert_abstime (clock_id
, abstime
, &timeout
);
4125 err
= (*cond
)->wait (*mutex
, &timeout
);
4127 while (err
== ETIMEDOUT
);
4132 pthread_cond_clockwait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
4133 clockid_t clock_id
, const struct timespec
*abstime
)
4137 pthread_testcancel ();
4141 err
= __pthread_cond_wait_init (cond
, mutex
);
4144 err
= __pthread_cond_clockwait (cond
, mutex
, clock_id
, abstime
);
4155 pthread_cond_timedwait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
4156 const struct timespec
*abstime
)
4160 pthread_testcancel ();
4164 err
= __pthread_cond_wait_init (cond
, mutex
);
4167 err
= __pthread_cond_clockwait (cond
, mutex
, (*cond
)->clock_id
, abstime
);
4178 pthread_cond_wait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
)
4180 pthread_testcancel ();
4182 int err
= __pthread_cond_wait_init (cond
, mutex
);
4185 return (*cond
)->wait (*mutex
, NULL
);
4188 /* Thread cond attributes */
4191 pthread_condattr_init (pthread_condattr_t
*condattr
)
4193 *condattr
= new pthread_condattr
;
4194 if (!pthread_condattr::is_good_object (condattr
))
4204 pthread_condattr_getpshared (const pthread_condattr_t
*attr
, int *pshared
)
4206 if (!pthread_condattr::is_good_object (attr
))
4208 *pshared
= (*attr
)->shared
;
4213 pthread_condattr_setpshared (pthread_condattr_t
*attr
, int pshared
)
4215 if (!pthread_condattr::is_good_object (attr
))
4217 if ((pshared
< 0) || (pshared
> 1))
4219 /* shared cond vars not currently supported */
4220 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
4222 (*attr
)->shared
= pshared
;
4227 pthread_condattr_getclock (const pthread_condattr_t
*attr
, clockid_t
*clock_id
)
4229 if (!pthread_condattr::is_good_object (attr
))
4231 *clock_id
= (*attr
)->clock_id
;
4236 pthread_condattr_setclock (pthread_condattr_t
*attr
, clockid_t clock_id
)
4238 if (!pthread_condattr::is_good_object (attr
))
4240 if (CLOCKID_IS_PROCESS (clock_id
) || CLOCKID_IS_THREAD (clock_id
)
4241 || clock_id
>= MAX_CLOCKS
)
4243 (*attr
)->clock_id
= clock_id
;
4248 pthread_condattr_destroy (pthread_condattr_t
*condattr
)
4250 if (!pthread_condattr::is_good_object (condattr
))
4260 pthread_rwlock_init (pthread_rwlock_t
*rwlock
, const pthread_rwlockattr_t
*attr
)
4262 return pthread_rwlock::init (rwlock
, attr
);
4266 pthread_rwlock_destroy (pthread_rwlock_t
*rwlock
)
4268 if (pthread_rwlock::is_initializer (rwlock
))
4270 if (!pthread_rwlock::is_good_object (rwlock
))
4273 if ((*rwlock
)->writer
|| (*rwlock
)->readers
||
4274 (*rwlock
)->waiting_readers
|| (*rwlock
)->waiting_writers
)
4284 pthread_rwlock_rdlock (pthread_rwlock_t
*rwlock
)
4286 pthread_testcancel ();
4288 if (pthread_rwlock::is_initializer (rwlock
))
4289 pthread_rwlock::init (rwlock
, NULL
);
4290 if (!pthread_rwlock::is_good_object (rwlock
))
4293 return (*rwlock
)->rdlock ();
4297 pthread_rwlock_clockrdlock (pthread_rwlock_t
*rwlock
, clockid_t clock_id
,
4298 const struct timespec
*abstime
)
4300 LARGE_INTEGER timeout
;
4302 pthread_testcancel ();
4304 if (pthread_rwlock::is_initializer (rwlock
))
4305 pthread_rwlock::init (rwlock
, NULL
);
4306 if (!pthread_rwlock::is_good_object (rwlock
))
4309 /* According to SUSv3, abstime need not be checked for validity,
4310 if the rwlock can be locked immediately. */
4311 if (!(*rwlock
)->tryrdlock ())
4316 int err
= pthread_convert_abstime (clock_id
, abstime
, &timeout
);
4320 return (*rwlock
)->rdlock (&timeout
);
4322 __except (NO_ERROR
) {}
4328 pthread_rwlock_timedrdlock (pthread_rwlock_t
*rwlock
,
4329 const struct timespec
*abstime
)
4331 return pthread_rwlock_clockrdlock (rwlock
, CLOCK_REALTIME
, abstime
);
4335 pthread_rwlock_tryrdlock (pthread_rwlock_t
*rwlock
)
4337 if (pthread_rwlock::is_initializer (rwlock
))
4338 pthread_rwlock::init (rwlock
, NULL
);
4339 if (!pthread_rwlock::is_good_object (rwlock
))
4342 return (*rwlock
)->tryrdlock ();
4346 pthread_rwlock_wrlock (pthread_rwlock_t
*rwlock
)
4348 pthread_testcancel ();
4350 if (pthread_rwlock::is_initializer (rwlock
))
4351 pthread_rwlock::init (rwlock
, NULL
);
4352 if (!pthread_rwlock::is_good_object (rwlock
))
4355 return (*rwlock
)->wrlock ();
4359 pthread_rwlock_clockwrlock (pthread_rwlock_t
*rwlock
, clockid_t clock_id
,
4360 const struct timespec
*abstime
)
4362 LARGE_INTEGER timeout
;
4364 pthread_testcancel ();
4366 if (pthread_rwlock::is_initializer (rwlock
))
4367 pthread_rwlock::init (rwlock
, NULL
);
4368 if (!pthread_rwlock::is_good_object (rwlock
))
4371 /* According to SUSv3, abstime need not be checked for validity,
4372 if the rwlock can be locked immediately. */
4373 if (!(*rwlock
)->trywrlock ())
4378 int err
= pthread_convert_abstime (clock_id
, abstime
, &timeout
);
4382 return (*rwlock
)->wrlock (&timeout
);
4384 __except (NO_ERROR
) {}
4390 pthread_rwlock_timedwrlock (pthread_rwlock_t
*rwlock
,
4391 const struct timespec
*abstime
)
4393 return pthread_rwlock_clockwrlock (rwlock
, CLOCK_REALTIME
, abstime
);
4397 pthread_rwlock_trywrlock (pthread_rwlock_t
*rwlock
)
4399 if (pthread_rwlock::is_initializer (rwlock
))
4400 pthread_rwlock::init (rwlock
, NULL
);
4401 if (!pthread_rwlock::is_good_object (rwlock
))
4404 return (*rwlock
)->trywrlock ();
4408 pthread_rwlock_unlock (pthread_rwlock_t
*rwlock
)
4410 if (pthread_rwlock::is_initializer (rwlock
))
4412 if (!pthread_rwlock::is_good_object (rwlock
))
4415 return (*rwlock
)->unlock ();
4418 /* RW Lock attributes */
4421 pthread_rwlockattr_init (pthread_rwlockattr_t
*rwlockattr
)
4423 *rwlockattr
= new pthread_rwlockattr
;
4424 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
4426 delete (*rwlockattr
);
4434 pthread_rwlockattr_getpshared (const pthread_rwlockattr_t
*attr
, int *pshared
)
4436 if (!pthread_rwlockattr::is_good_object (attr
))
4438 *pshared
= (*attr
)->shared
;
4443 pthread_rwlockattr_setpshared (pthread_rwlockattr_t
*attr
, int pshared
)
4445 if (!pthread_rwlockattr::is_good_object (attr
))
4447 if ((pshared
< 0) || (pshared
> 1))
4449 /* shared rwlock vars not currently supported */
4450 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
4452 (*attr
)->shared
= pshared
;
4457 pthread_rwlockattr_destroy (pthread_rwlockattr_t
*rwlockattr
)
4459 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
4461 delete (*rwlockattr
);
4469 pthread_barrier_init (pthread_barrier_t
* bar
,
4470 const pthread_barrierattr_t
* attr
, unsigned count
)
4472 if (unlikely (bar
== NULL
))
4475 *bar
= new pthread_barrier
;
4476 return (*bar
)->init (attr
, count
);
4480 pthread_barrier_destroy (pthread_barrier_t
* bar
)
4482 if (unlikely (! pthread_barrier::is_good_object (bar
)))
4486 ret
= (*bar
)->destroy ();
4488 delete_and_clear (bar
);
4494 pthread_barrier_wait (pthread_barrier_t
* bar
)
4496 if (unlikely (! pthread_barrier::is_good_object (bar
)))
4499 return (*bar
)->wait ();
4502 /* Barrier attributes */
4505 pthread_barrierattr_init (pthread_barrierattr_t
* battr
)
4507 if (unlikely (battr
== NULL
))
4510 *battr
= new pthread_barrierattr
;
4511 (*battr
)->shared
= PTHREAD_PROCESS_PRIVATE
;
4517 pthread_barrierattr_setpshared (pthread_barrierattr_t
* battr
, int shared
)
4519 if (unlikely (! pthread_barrierattr::is_good_object (battr
)))
4522 if (unlikely (shared
!= PTHREAD_PROCESS_SHARED
4523 && shared
!= PTHREAD_PROCESS_PRIVATE
))
4526 (*battr
)->shared
= shared
;
4531 pthread_barrierattr_getpshared (const pthread_barrierattr_t
* battr
,
4534 if (unlikely (! pthread_barrierattr::is_good_object (battr
)
4538 *shared
= (*battr
)->shared
;
4543 pthread_barrierattr_destroy (pthread_barrierattr_t
* battr
)
4545 if (unlikely (! pthread_barrierattr::is_good_object (battr
)))
4548 delete_and_clear (battr
);
4552 /* Thread clock ID */
4555 pthread_getcpuclockid (pthread_t thread
, clockid_t
*clk_id
)
4557 if (!pthread::is_good_object (&thread
))
4559 *clk_id
= (clockid_t
) THREADID_TO_CLOCKID (thread
->getsequence_np ());