1 /* thread.cc: Locking and threading module functions
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
5 Originally written by Marco Fuykschot <marco@ddi.nl>
6 Substantialy enhanced by Robert Collins <rbtcollins@hotmail.com>
8 This file is part of Cygwin.
10 This software is a copyrighted work licensed under the terms of the
11 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
14 /* Implementation overview and caveats:
16 Win32 puts some contraints on what can and cannot be implemented. Where
17 possible we work around those contrainsts. Where we cannot work around
18 the constraints we either pretend to be conformant, or return an error
21 Some caveats: PROCESS_SHARED objects while they pretend to be process
22 shared, may not actually work. Some test cases are needed to determine
23 win32's behaviour. My suspicion is that the win32 handle needs to be
24 opened with different flags for proper operation.
26 R.Collins, April 2001. */
39 #include "perprocess.h"
42 #include <semaphore.h>
44 #include <sys/timeb.h>
45 #include <exceptions.h>
46 #include <sys/fcntl.h>
49 extern "C" void __fp_lock_all ();
50 extern "C" void __fp_unlock_all ();
51 static inline verifyable_object_state
52 verifyable_object_isvalid (void const * objectptr
, long magic
,
53 void *static_ptr1
= NULL
,
54 void *static_ptr2
= NULL
,
55 void *static_ptr3
= NULL
);
57 extern int threadsafe
;
60 extern "C" struct _reent
*
63 return &_my_tls
.local_clib
;
67 __cygwin_lock_init (_LOCK_T
*lock
)
69 *lock
= _LOCK_T_INITIALIZER
;
73 __cygwin_lock_init_recursive (_LOCK_T
*lock
)
75 *lock
= _LOCK_T_RECURSIVE_INITIALIZER
;
79 __cygwin_lock_fini (_LOCK_T
*lock
)
81 pthread_mutex_destroy ((pthread_mutex_t
*) lock
);
85 __cygwin_lock_lock (_LOCK_T
*lock
)
87 if (MT_INTERFACE
->threadcount
<= 1)
88 paranoid_printf ("threadcount %d. not locking", MT_INTERFACE
->threadcount
);
91 paranoid_printf ("threadcount %d. locking", MT_INTERFACE
->threadcount
);
92 pthread_mutex_lock ((pthread_mutex_t
*) lock
);
97 __cygwin_lock_trylock (_LOCK_T
*lock
)
99 return pthread_mutex_trylock ((pthread_mutex_t
*) lock
);
104 __cygwin_lock_unlock (_LOCK_T
*lock
)
106 if (MT_INTERFACE
->threadcount
<= 1)
107 paranoid_printf ("threadcount %d. not unlocking", MT_INTERFACE
->threadcount
);
110 pthread_mutex_unlock ((pthread_mutex_t
*) lock
);
111 paranoid_printf ("threadcount %d. unlocked", MT_INTERFACE
->threadcount
);
115 static inline verifyable_object_state
116 verifyable_object_isvalid (void const * objectptr
, long magic
, void *static_ptr1
,
117 void *static_ptr2
, void *static_ptr3
)
119 verifyable_object
**object
= (verifyable_object
**) objectptr
;
122 if (efault
.faulted ())
123 return INVALID_OBJECT
;
125 if ((static_ptr1
&& *object
== static_ptr1
) ||
126 (static_ptr2
&& *object
== static_ptr2
) ||
127 (static_ptr3
&& *object
== static_ptr3
))
128 return VALID_STATIC_OBJECT
;
129 if ((*object
)->magic
!= magic
)
130 return INVALID_OBJECT
;
136 pthread_attr::is_good_object (pthread_attr_t
const *attr
)
138 if (verifyable_object_isvalid (attr
, PTHREAD_ATTR_MAGIC
) != VALID_OBJECT
)
144 pthread_condattr::is_good_object (pthread_condattr_t
const *attr
)
146 if (verifyable_object_isvalid (attr
, PTHREAD_CONDATTR_MAGIC
) != VALID_OBJECT
)
152 pthread_rwlockattr::is_good_object (pthread_rwlockattr_t
const *attr
)
154 if (verifyable_object_isvalid (attr
, PTHREAD_RWLOCKATTR_MAGIC
) != VALID_OBJECT
)
160 pthread_key::is_good_object (pthread_key_t
const *key
)
162 if (verifyable_object_isvalid (key
, PTHREAD_KEY_MAGIC
) != VALID_OBJECT
)
168 pthread_mutex::is_good_object (pthread_mutex_t
const *mutex
)
170 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
) != VALID_OBJECT
)
176 pthread_mutex::is_good_initializer (pthread_mutex_t
const *mutex
)
178 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
179 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
180 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
181 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) != VALID_STATIC_OBJECT
)
187 pthread_mutex::is_good_initializer_or_object (pthread_mutex_t
const *mutex
)
189 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
190 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
191 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
192 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) == INVALID_OBJECT
)
198 pthread_mutex::is_good_initializer_or_bad_object (pthread_mutex_t
const *mutex
)
200 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
201 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
202 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
203 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) == VALID_OBJECT
)
209 pthread_mutex::can_be_unlocked (pthread_mutex_t
const *mutex
)
211 pthread_t self
= pthread::self ();
213 if (!is_good_object (mutex
))
215 /* Check if the mutex is owned by the current thread and can be unlocked.
216 * Also check for the ANONYMOUS owner to cover NORMAL mutexes as well. */
217 return ((*mutex
)->recursion_counter
== 1
218 && ((*mutex
)->owner
== MUTEX_OWNER_ANONYMOUS
219 || pthread::equal ((*mutex
)->owner
, self
)));
223 pthread_mutexattr::is_good_object (pthread_mutexattr_t
const * attr
)
225 if (verifyable_object_isvalid (attr
, PTHREAD_MUTEXATTR_MAGIC
) != VALID_OBJECT
)
230 inline bool __attribute__ ((used
))
231 pthread::is_good_object (pthread_t
const *thread
)
233 if (verifyable_object_isvalid (thread
, PTHREAD_MAGIC
) != VALID_OBJECT
)
238 /* Thread synchronisation */
240 pthread_cond::is_good_object (pthread_cond_t
const *cond
)
242 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
) != VALID_OBJECT
)
248 pthread_cond::is_good_initializer (pthread_cond_t
const *cond
)
250 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) != VALID_STATIC_OBJECT
)
256 pthread_cond::is_good_initializer_or_object (pthread_cond_t
const *cond
)
258 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) == INVALID_OBJECT
)
264 pthread_cond::is_good_initializer_or_bad_object (pthread_cond_t
const *cond
)
266 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) == VALID_OBJECT
)
273 pthread_rwlock::is_good_object (pthread_rwlock_t
const *rwlock
)
275 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
) != VALID_OBJECT
)
281 pthread_rwlock::is_good_initializer (pthread_rwlock_t
const *rwlock
)
283 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) != VALID_STATIC_OBJECT
)
289 pthread_rwlock::is_good_initializer_or_object (pthread_rwlock_t
const *rwlock
)
291 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) == INVALID_OBJECT
)
297 pthread_rwlock::is_good_initializer_or_bad_object (pthread_rwlock_t
const *rwlock
)
299 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) == VALID_OBJECT
)
305 semaphore::is_good_object (sem_t
const * sem
)
307 if (verifyable_object_isvalid (sem
, SEM_MAGIC
) != VALID_OBJECT
)
313 ResourceLocks::Lock (int _resid
)
319 SetResourceLock (int _res_id
, int _mode
, const char *_function
)
321 EnterCriticalSection (user_data
->resourcelocks
->Lock (_res_id
));
325 ReleaseResourceLock (int _res_id
, int _mode
, const char *_function
)
327 LeaveCriticalSection (user_data
->resourcelocks
->Lock (_res_id
));
331 ResourceLocks::Init ()
333 InitializeCriticalSection (&lock
);
335 thread_printf ("lock %p inited by %p , %d", &lock
, user_data
, myself
->pid
);
339 ResourceLocks::Delete ()
343 thread_printf ("Close Resource Locks %p ", &lock
);
344 DeleteCriticalSection (&lock
);
352 pthread_mutex::init_mutex ();
353 pthread_cond::init_mutex ();
354 pthread_rwlock::init_mutex ();
358 MTinterface::fixup_before_fork ()
360 pthread_key::fixup_before_fork ();
363 /* This function is called from a single threaded process */
365 MTinterface::fixup_after_fork ()
367 pthread_key::fixup_after_fork ();
370 pthread::init_mainthread ();
372 pthread::fixup_after_fork ();
373 pthread_mutex::fixup_after_fork ();
374 pthread_cond::fixup_after_fork ();
375 pthread_rwlock::fixup_after_fork ();
376 semaphore::fixup_after_fork ();
383 pthread::init_mainthread ()
385 pthread
*thread
= get_tls_self_pointer ();
388 thread
= new pthread ();
390 api_fatal ("failed to create mainthread object");
393 set_tls_self_pointer (thread
);
394 thread
->thread_id
= GetCurrentThreadId ();
395 if (!DuplicateHandle (hMainProc
, GetCurrentThread (), hMainProc
,
396 &thread
->win32_obj_id
, 0, FALSE
, DUPLICATE_SAME_ACCESS
))
397 api_fatal ("failed to create mainthread handle");
398 if (!thread
->create_cancel_event ())
399 api_fatal ("couldn't create cancel event for main thread");
400 VerifyHandle (thread
->win32_obj_id
);
401 thread
->postcreate ();
407 pthread
*thread
= get_tls_self_pointer ();
410 thread
= pthread_null::get_null_pthread ();
411 set_tls_self_pointer (thread
);
417 pthread::get_tls_self_pointer ()
423 pthread::set_tls_self_pointer (pthread
*thread
)
425 thread
->cygtls
= &_my_tls
;
426 _my_tls
.tid
= thread
;
429 List
<pthread
> pthread::threads
;
432 pthread::pthread ():verifyable_object (PTHREAD_MAGIC
), win32_obj_id (0),
433 valid (false), suspended (false),
434 cancelstate (0), canceltype (0), cancel_event (0),
435 joiner (NULL
), next (NULL
), cleanup_stack (NULL
)
437 if (this != pthread_null::get_null_pthread ())
438 threads
.insert (this);
444 CloseHandle (win32_obj_id
);
446 CloseHandle (cancel_event
);
448 if (this != pthread_null::get_null_pthread ())
449 threads
.remove (this);
453 pthread::create_cancel_event ()
455 cancel_event
= ::CreateEvent (&sec_none_nih
, TRUE
, FALSE
, NULL
);
458 system_printf ("couldn't create cancel event, %E");
459 /* we need the event for correct behaviour */
466 pthread::precreate (pthread_attr
*newattr
)
468 pthread_mutex
*verifyable_mutex_obj
= &mutex
;
470 /* already running ? */
476 attr
.joinable
= newattr
->joinable
;
477 attr
.contentionscope
= newattr
->contentionscope
;
478 attr
.inheritsched
= newattr
->inheritsched
;
479 attr
.stacksize
= newattr
->stacksize
;
482 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
484 thread_printf ("New thread object access mutex is not valid. this %p",
489 /* Change the mutex type to NORMAL to speed up mutex operations */
490 mutex
.type
= PTHREAD_MUTEX_NORMAL
;
491 if (!create_cancel_event ())
496 pthread::create (void *(*func
) (void *), pthread_attr
*newattr
,
509 win32_obj_id
= ::CreateThread (&sec_none_nih
, attr
.stacksize
,
510 thread_init_wrapper
, this, 0, &thread_id
);
514 thread_printf ("CreateThread failed: this %p, %E", this);
521 low_priority_sleep (0);
529 pthread::postcreate ()
533 InterlockedIncrement (&MT_INTERFACE
->threadcount
);
534 /* FIXME: set the priority appropriately for system contention scope */
535 if (attr
.inheritsched
== PTHREAD_EXPLICIT_SCHED
)
537 /* FIXME: set the scheduling settings for the new thread */
538 /* sched_thread_setparam (win32_obj_id, attr.schedparam); */
543 pthread::exit (void *value_ptr
)
545 class pthread
*thread
= this;
547 // run cleanup handlers
548 pop_all_cleanup_handlers ();
550 pthread_key::run_all_destructors ();
553 // cleanup if thread is in detached state and not joined
554 if (equal (joiner
, thread
))
559 return_ptr
= value_ptr
;
563 if (_my_tls
.local_clib
.__sdidinit
< 0)
564 _my_tls
.local_clib
.__sdidinit
= 0;
565 (_reclaim_reent
) (_REENT
);
568 if (InterlockedDecrement (&MT_INTERFACE
->threadcount
) == 0)
572 _my_tls
.remove (INFINITE
);
580 class pthread
*thread
= this;
581 class pthread
*self
= pthread::self ();
591 if (canceltype
== PTHREAD_CANCEL_DEFERRED
||
592 cancelstate
== PTHREAD_CANCEL_DISABLE
)
596 SetEvent (cancel_event
);
599 else if (equal (thread
, self
))
603 return 0; // Never reached
606 // cancel asynchronous
607 SuspendThread (win32_obj_id
);
608 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
611 context
.ContextFlags
= CONTEXT_CONTROL
;
612 GetThreadContext (win32_obj_id
, &context
);
613 context
.Eip
= (DWORD
) pthread::static_cancel_self
;
614 SetThreadContext (win32_obj_id
, &context
);
617 ResumeThread (win32_obj_id
);
621 TODO: insert pthread_testcancel into the required functions
622 the required function list is: *indicates done, X indicates not present in cygwin.
641 *pthread_cond_timedwait ()
642 *pthread_cond_wait ()
644 *pthread_testcancel ()
668 the optional list is:
788 Note, that for fcntl (), for any value of the cmd argument.
790 And we must not introduce cancellation points anywhere else that's part of the posix or
796 pthread::testcancel ()
798 if (cancelstate
== PTHREAD_CANCEL_DISABLE
)
801 if (WaitForSingleObject (cancel_event
, 0) == WAIT_OBJECT_0
)
806 pthread::static_cancel_self ()
808 pthread::self ()->cancel_self ();
812 cancelable_wait (HANDLE object
, DWORD timeout
, const cw_cancel_action cancel_action
,
813 const enum cw_sig_wait sig_wait
)
817 HANDLE wait_objects
[3];
818 pthread_t thread
= pthread::self ();
820 /* Do not change the wait order.
821 The object must have higher priority than the cancel event,
822 because WaitForMultipleObjects will return the smallest index
823 if both objects are signaled. */
824 wait_objects
[num
++] = object
;
826 if (cancel_action
== cw_no_cancel
|| !pthread::is_good_object (&thread
) ||
827 thread
->cancelstate
== PTHREAD_CANCEL_DISABLE
)
828 cancel_n
= (DWORD
) -1;
831 cancel_n
= WAIT_OBJECT_0
+ num
++;
832 wait_objects
[cancel_n
] = thread
->cancel_event
;
836 if (sig_wait
== cw_sig_nosig
|| &_my_tls
!= _main_tls
)
840 sig_n
= WAIT_OBJECT_0
+ num
++;
841 wait_objects
[sig_n
] = signal_arrived
;
846 res
= WaitForMultipleObjects (num
, wait_objects
, FALSE
, timeout
);
849 if (cancel_action
== cw_cancel_self
)
850 pthread::static_cancel_self ();
853 else if (res
!= sig_n
)
855 else if (sig_wait
== cw_sig_eintr
)
859 _my_tls
.call_signal_handler ();
868 pthread::setcancelstate (int state
, int *oldstate
)
874 if (state
!= PTHREAD_CANCEL_ENABLE
&& state
!= PTHREAD_CANCEL_DISABLE
)
879 *oldstate
= cancelstate
;
889 pthread::setcanceltype (int type
, int *oldtype
)
895 if (type
!= PTHREAD_CANCEL_DEFERRED
&& type
!= PTHREAD_CANCEL_ASYNCHRONOUS
)
900 *oldtype
= canceltype
;
910 pthread::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
914 api_fatal ("Attempt to push a cleanup handler across threads");
915 handler
->next
= cleanup_stack
;
916 cleanup_stack
= handler
;
920 pthread::pop_cleanup_handler (int const execute
)
923 // TODO: send a signal or something to the thread ?
924 api_fatal ("Attempt to execute a cleanup handler across threads");
928 if (cleanup_stack
!= NULL
)
930 __pthread_cleanup_handler
*handler
= cleanup_stack
;
933 (*handler
->function
) (handler
->arg
);
934 cleanup_stack
= handler
->next
;
941 pthread::pop_all_cleanup_handlers ()
943 while (cleanup_stack
!= NULL
)
944 pop_cleanup_handler (1);
948 pthread::cancel_self ()
950 exit (PTHREAD_CANCELED
);
954 pthread::get_thread_id ()
960 pthread::_fixup_after_fork ()
962 /* set thread to not running if it is not the forking thread */
963 if (this != pthread::self ())
973 pthread::suspend_except_self ()
975 if (valid
&& this != pthread::self ())
976 SuspendThread (win32_obj_id
);
983 ResumeThread (win32_obj_id
);
986 /* instance members */
988 pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC
),
989 joinable (PTHREAD_CREATE_JOINABLE
), contentionscope (PTHREAD_SCOPE_PROCESS
),
990 inheritsched (PTHREAD_INHERIT_SCHED
), stacksize (0)
992 schedparam
.sched_priority
= 0;
995 pthread_attr::~pthread_attr ()
999 pthread_condattr::pthread_condattr ():verifyable_object
1000 (PTHREAD_CONDATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
)
1004 pthread_condattr::~pthread_condattr ()
1008 List
<pthread_cond
> pthread_cond::conds
;
1010 /* This is used for cond creation protection within a single process only */
1011 fast_mutex NO_COPY
pthread_cond::cond_initialization_lock
;
1013 /* We can only be called once.
1014 TODO: (no rush) use a non copied memory section to
1015 hold an initialization flag. */
1017 pthread_cond::init_mutex ()
1019 if (!cond_initialization_lock
.init ())
1020 api_fatal ("Could not create win32 Mutex for pthread cond static initializer support.");
1023 pthread_cond::pthread_cond (pthread_condattr
*attr
) :
1024 verifyable_object (PTHREAD_COND_MAGIC
),
1025 shared (0), waiting (0), pending (0), sem_wait (NULL
),
1026 mtx_cond(NULL
), next (NULL
)
1028 pthread_mutex
*verifyable_mutex_obj
;
1031 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
1037 verifyable_mutex_obj
= &mtx_in
;
1038 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1040 thread_printf ("Internal cond mutex is not valid. this %p", this);
1045 * Change the mutex type to NORMAL.
1046 * This mutex MUST be of type normal
1048 mtx_in
.type
= PTHREAD_MUTEX_NORMAL
;
1050 verifyable_mutex_obj
= &mtx_out
;
1051 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1053 thread_printf ("Internal cond mutex is not valid. this %p", this);
1057 /* Change the mutex type to NORMAL to speed up mutex operations */
1058 mtx_out
.type
= PTHREAD_MUTEX_NORMAL
;
1060 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1063 debug_printf ("CreateSemaphore failed. %E");
1068 conds
.insert (this);
1071 pthread_cond::~pthread_cond ()
1074 CloseHandle (sem_wait
);
1076 conds
.remove (this);
1080 pthread_cond::unblock (const bool all
)
1082 unsigned long releaseable
;
1085 * Block outgoing threads (and avoid simultanous unblocks)
1089 releaseable
= waiting
- pending
;
1092 unsigned long released
;
1097 * Block incoming threads until all waiting threads are released.
1102 * Calculate releaseable again because threads can enter until
1103 * the semaphore has been taken, but they can not leave, therefore pending
1104 * is unchanged and releaseable can only get higher
1106 releaseable
= waiting
- pending
;
1109 released
= all
? releaseable
: 1;
1110 pending
+= released
;
1114 ::ReleaseSemaphore (sem_wait
, released
, NULL
);
1118 * And let the threads release.
1124 pthread_cond::wait (pthread_mutex_t mutex
, DWORD dwMilliseconds
)
1129 if (InterlockedIncrement ((long *)&waiting
) == 1)
1131 else if (mtx_cond
!= mutex
)
1133 InterlockedDecrement ((long *)&waiting
);
1140 * Release the mutex and wait on semaphore
1145 rv
= cancelable_wait (sem_wait
, dwMilliseconds
, cw_no_cancel_self
, cw_sig_eintr
);
1149 if (rv
!= WAIT_OBJECT_0
)
1152 * It might happen that a signal is sent while the thread got canceled
1153 * or timed out. Try to take one.
1154 * If the thread gets one than a signal|broadcast is in progress.
1156 if (WaitForSingleObject (sem_wait
, 0) == WAIT_OBJECT_0
)
1158 * thread got cancelled ot timed out while a signalling is in progress.
1159 * Set wait result back to signaled
1164 InterlockedDecrement ((long *)&waiting
);
1166 if (rv
== WAIT_OBJECT_0
&& --pending
== 0)
1168 * All signaled threads are released,
1169 * new threads can enter Wait
1178 if (rv
== WAIT_CANCELED
)
1179 pthread::static_cancel_self ();
1180 else if (rv
== WAIT_SIGNALED
)
1181 /* SUSv3 states: If a signal is delivered to a thread waiting for a
1182 condition variable, upon return from the signal handler the thread
1183 resumes waiting for the condition variable as if it was not
1184 interrupted, or it shall return zero due to spurious wakeup.
1185 We opt for the latter choice here. */
1187 else if (rv
== WAIT_TIMEOUT
)
1194 pthread_cond::_fixup_after_fork ()
1196 waiting
= pending
= 0;
1199 /* Unlock eventually locked mutexes */
1203 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1205 api_fatal ("pthread_cond::_fixup_after_fork () failed to recreate win32 semaphore");
1208 pthread_rwlockattr::pthread_rwlockattr ():verifyable_object
1209 (PTHREAD_RWLOCKATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
)
1213 pthread_rwlockattr::~pthread_rwlockattr ()
1217 List
<pthread_rwlock
> pthread_rwlock::rwlocks
;
1219 /* This is used for rwlock creation protection within a single process only */
1220 fast_mutex NO_COPY
pthread_rwlock::rwlock_initialization_lock
;
1222 /* We can only be called once.
1223 TODO: (no rush) use a non copied memory section to
1224 hold an initialization flag. */
1226 pthread_rwlock::init_mutex ()
1228 if (!rwlock_initialization_lock
.init ())
1229 api_fatal ("Could not create win32 Mutex for pthread rwlock static initializer support.");
1232 pthread_rwlock::pthread_rwlock (pthread_rwlockattr
*attr
) :
1233 verifyable_object (PTHREAD_RWLOCK_MAGIC
),
1234 shared (0), waiting_readers (0), waiting_writers (0), writer (NULL
),
1235 readers (NULL
), readers_mx (), mtx (NULL
), cond_readers (NULL
), cond_writers (NULL
),
1238 pthread_mutex
*verifyable_mutex_obj
= &mtx
;
1239 pthread_cond
*verifyable_cond_obj
;
1241 if (!readers_mx
.init ())
1243 thread_printf ("Internal rwlock synchronisation mutex is not valid. this %p", this);
1249 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
1255 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1257 thread_printf ("Internal rwlock mutex is not valid. this %p", this);
1261 /* Change the mutex type to NORMAL to speed up mutex operations */
1262 mtx
.type
= PTHREAD_MUTEX_NORMAL
;
1264 verifyable_cond_obj
= &cond_readers
;
1265 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
1267 thread_printf ("Internal rwlock readers cond is not valid. this %p", this);
1272 verifyable_cond_obj
= &cond_writers
;
1273 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
1275 thread_printf ("Internal rwlock writers cond is not valid. this %p", this);
1281 rwlocks
.insert (this);
1284 pthread_rwlock::~pthread_rwlock ()
1286 rwlocks
.remove (this);
1290 pthread_rwlock::rdlock ()
1293 struct RWLOCK_READER
*reader
;
1294 pthread_t self
= pthread::self ();
1298 if (lookup_reader (self
))
1304 reader
= new struct RWLOCK_READER
;
1311 while (writer
|| waiting_writers
)
1313 pthread_cleanup_push (pthread_rwlock::rdlock_cleanup
, this);
1316 cond_readers
.wait (&mtx
);
1319 pthread_cleanup_pop (0);
1322 reader
->thread
= self
;
1323 add_reader (reader
);
1332 pthread_rwlock::tryrdlock ()
1335 pthread_t self
= pthread::self ();
1339 if (writer
|| waiting_writers
|| lookup_reader (self
))
1343 struct RWLOCK_READER
*reader
= new struct RWLOCK_READER
;
1346 reader
->thread
= self
;
1347 add_reader (reader
);
1359 pthread_rwlock::wrlock ()
1362 pthread_t self
= pthread::self ();
1366 if (writer
== self
|| lookup_reader (self
))
1372 while (writer
|| readers
)
1374 pthread_cleanup_push (pthread_rwlock::wrlock_cleanup
, this);
1377 cond_writers
.wait (&mtx
);
1380 pthread_cleanup_pop (0);
1392 pthread_rwlock::trywrlock ()
1395 pthread_t self
= pthread::self ();
1399 if (writer
|| readers
)
1410 pthread_rwlock::unlock ()
1413 pthread_t self
= pthread::self ();
1429 struct RWLOCK_READER
*reader
= lookup_reader (self
);
1437 remove_reader (reader
);
1450 pthread_rwlock::add_reader (struct RWLOCK_READER
*rd
)
1452 List_insert (readers
, rd
);
1456 pthread_rwlock::remove_reader (struct RWLOCK_READER
*rd
)
1458 List_remove (readers_mx
, readers
, rd
);
1461 struct pthread_rwlock::RWLOCK_READER
*
1462 pthread_rwlock::lookup_reader (pthread_t thread
)
1466 struct RWLOCK_READER
*cur
= readers
;
1468 while (cur
&& cur
->thread
!= thread
)
1471 readers_mx
.unlock ();
1477 pthread_rwlock::rdlock_cleanup (void *arg
)
1479 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1481 --(rwlock
->waiting_readers
);
1483 rwlock
->mtx
.unlock ();
1487 pthread_rwlock::wrlock_cleanup (void *arg
)
1489 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1491 --(rwlock
->waiting_writers
);
1493 rwlock
->mtx
.unlock ();
1497 pthread_rwlock::_fixup_after_fork ()
1499 pthread_t self
= pthread::self ();
1500 struct RWLOCK_READER
**temp
= &readers
;
1502 waiting_readers
= 0;
1503 waiting_writers
= 0;
1505 if (!readers_mx
.init ())
1506 api_fatal ("pthread_rwlock::_fixup_after_fork () failed to recreate mutex");
1508 /* Unlock eventually locked mutex */
1511 * Remove all readers except self
1515 if ((*temp
)->thread
== self
)
1516 temp
= &((*temp
)->next
);
1519 struct RWLOCK_READER
*cur
= *temp
;
1520 *temp
= (*temp
)->next
;
1527 /* static members */
1528 /* This stores pthread_key information across fork() boundaries */
1529 List
<pthread_key
> pthread_key::keys
;
1531 /* non-static members */
1533 pthread_key::pthread_key (void (*aDestructor
) (void *)):verifyable_object (PTHREAD_KEY_MAGIC
), destructor (aDestructor
)
1535 tls_index
= TlsAlloc ();
1536 if (tls_index
== TLS_OUT_OF_INDEXES
)
1542 pthread_key::~pthread_key ()
1544 /* We may need to make the list code lock the list during operations
1549 TlsFree (tls_index
);
1554 pthread_key::_fixup_before_fork ()
1560 pthread_key::_fixup_after_fork ()
1562 tls_index
= TlsAlloc ();
1563 if (tls_index
== TLS_OUT_OF_INDEXES
)
1564 api_fatal ("pthread_key::recreate_key_from_buffer () failed to reallocate Tls storage");
1569 pthread_key::run_destructor ()
1573 void *oldValue
= get ();
1577 destructor (oldValue
);
1584 REMOVED FROM CURRENT. These can be reinstated with the daemon, when all the
1585 gymnastics can be a lot easier.
1587 the mutex_t (size 4) is not used as a verifyable object because we cannot
1588 guarantee the same address space for all processes.
1589 we use the following:
1590 high bit set (never a valid address).
1591 second byte is reserved for the priority.
1592 third byte is reserved
1593 fourth byte is the mutex id. (max 255 cygwin mutexs system wide).
1594 creating mutex's does get slower and slower, but as creation is a one time
1595 job, it should never become an issue
1597 And if you're looking at this and thinking, why not an array in cygwin for all mutexs,
1598 - you incur a penalty on _every_ mutex call and you have toserialise them all.
1601 option 2? put everything in userspace and update the ABI?
1602 - bad karma as well - the HANDLE, while identical across process's,
1603 Isn't duplicated, it's reopened. */
1605 /* static members */
1607 List
<pthread_mutex
> pthread_mutex::mutexes
;
1609 /* This is used for mutex creation protection within a single process only */
1610 fast_mutex NO_COPY
pthread_mutex::mutex_initialization_lock
;
1612 /* We can only be called once.
1613 TODO: (no rush) use a non copied memory section to
1614 hold an initialization flag. */
1616 pthread_mutex::init_mutex ()
1618 if (!mutex_initialization_lock
.init ())
1619 api_fatal ("Could not create win32 Mutex for pthread mutex static initializer support.");
1622 pthread_mutex::pthread_mutex (pthread_mutexattr
*attr
) :
1623 verifyable_object (PTHREAD_MUTEX_MAGIC
),
1625 win32_obj_id (NULL
), recursion_counter (0),
1626 condwaits (0), owner (NULL
), type (PTHREAD_MUTEX_ERRORCHECK
),
1627 pshared (PTHREAD_PROCESS_PRIVATE
)
1629 win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1635 /*attr checked in the C call */
1638 if (attr
->pshared
== PTHREAD_PROCESS_SHARED
)
1645 type
= attr
->mutextype
;
1648 mutexes
.insert (this);
1651 pthread_mutex::~pthread_mutex ()
1654 CloseHandle (win32_obj_id
);
1656 mutexes
.remove (this);
1660 pthread_mutex::_lock (pthread_t self
)
1664 if (InterlockedIncrement ((long *)&lock_counter
) == 1)
1666 else if (type
== PTHREAD_MUTEX_NORMAL
|| !pthread::equal (owner
, self
))
1668 cancelable_wait (win32_obj_id
, INFINITE
, cw_no_cancel
, cw_sig_resume
);
1673 InterlockedDecrement ((long *) &lock_counter
);
1674 if (type
== PTHREAD_MUTEX_RECURSIVE
)
1675 result
= lock_recursive ();
1684 pthread_mutex::_trylock (pthread_t self
)
1688 if (InterlockedCompareExchange ((long *) &lock_counter
, 1, 0) == 0)
1690 else if (type
== PTHREAD_MUTEX_RECURSIVE
&& pthread::equal (owner
, self
))
1691 result
= lock_recursive ();
1699 pthread_mutex::_unlock (pthread_t self
)
1701 if (!pthread::equal (owner
, self
))
1704 if (--recursion_counter
== 0)
1707 if (InterlockedDecrement ((long *)&lock_counter
))
1708 // Another thread is waiting
1709 ::ReleaseSemaphore (win32_obj_id
, 1, NULL
);
1716 pthread_mutex::_destroy (pthread_t self
)
1718 if (condwaits
|| _trylock (self
))
1719 // Do not destroy a condwaited or locked mutex
1721 else if (recursion_counter
!= 1)
1723 // Do not destroy a recursive locked mutex
1724 --recursion_counter
;
1733 pthread_mutex::_fixup_after_fork ()
1735 debug_printf ("mutex %x in _fixup_after_fork", this);
1736 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
1737 api_fatal ("pthread_mutex::_fixup_after_fork () doesn'tunderstand PROCESS_SHARED mutex's");
1740 /* mutex has no owner, reset to initial */
1742 else if (lock_counter
!= 0)
1743 /* All waiting threads are gone after a fork */
1746 win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1748 api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 semaphore for mutex");
1753 pthread_mutexattr::pthread_mutexattr ():verifyable_object (PTHREAD_MUTEXATTR_MAGIC
),
1754 pshared (PTHREAD_PROCESS_PRIVATE
), mutextype (PTHREAD_MUTEX_ERRORCHECK
)
1758 pthread_mutexattr::~pthread_mutexattr ()
1762 List
<semaphore
> semaphore::semaphores
;
1764 semaphore::semaphore (int pshared
, unsigned int value
)
1765 : verifyable_object (SEM_MAGIC
),
1767 currentvalue (value
),
1770 SECURITY_ATTRIBUTES sa
= (pshared
!= PTHREAD_PROCESS_PRIVATE
)
1771 ? sec_all
: sec_none_nih
;
1772 this->win32_obj_id
= ::CreateSemaphore (&sa
, value
, LONG_MAX
, NULL
);
1773 if (!this->win32_obj_id
)
1776 semaphores
.insert (this);
1779 semaphore::semaphore (const char *sem_name
, int oflag
, mode_t mode
,
1781 : verifyable_object (SEM_MAGIC
),
1782 shared (PTHREAD_PROCESS_SHARED
),
1783 currentvalue (value
), /* Unused for named semaphores. */
1786 if (oflag
& O_CREAT
)
1788 SECURITY_ATTRIBUTES sa
= sec_all
;
1789 security_descriptor sd
;
1791 set_security_attribute (mode
, &sa
, sd
);
1792 this->win32_obj_id
= ::CreateSemaphore (&sa
, value
, LONG_MAX
, sem_name
);
1793 if (!this->win32_obj_id
)
1795 if (GetLastError () == ERROR_ALREADY_EXISTS
&& (oflag
& O_EXCL
))
1798 CloseHandle (this->win32_obj_id
);
1804 this->win32_obj_id
= ::OpenSemaphore (SEMAPHORE_ALL_ACCESS
, FALSE
,
1806 if (!this->win32_obj_id
)
1814 name
= new char [strlen (sem_name
+ 1)];
1818 CloseHandle (this->win32_obj_id
);
1822 strcpy (name
, sem_name
);
1825 semaphores
.insert (this);
1828 semaphore::~semaphore ()
1831 CloseHandle (win32_obj_id
);
1835 semaphores
.remove (this);
1841 if (ReleaseSemaphore (win32_obj_id
, 1, ¤tvalue
))
1846 semaphore::_getvalue (int *sval
)
1850 switch (WaitForSingleObject (win32_obj_id
, 0))
1853 ReleaseSemaphore (win32_obj_id
, 1, &val
);
1867 semaphore::_trywait ()
1869 /* FIXME: signals should be able to interrupt semaphores...
1870 We probably need WaitForMultipleObjects here. */
1871 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
1881 semaphore::_timedwait (const struct timespec
*abstime
)
1887 if (efault
.faulted ())
1889 /* According to SUSv3, abstime need not be checked for validity,
1890 if the semaphore can be locked immediately. */
1897 gettimeofday (&tv
, NULL
);
1898 waitlength
= abstime
->tv_sec
* 1000 + abstime
->tv_nsec
/ (1000 * 1000);
1899 waitlength
-= tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
1902 switch (cancelable_wait (win32_obj_id
, waitlength
, cw_cancel_self
, cw_sig_eintr
))
1911 set_errno (ETIMEDOUT
);
1914 debug_printf ("cancelable_wait failed. %E");
1924 switch (cancelable_wait (win32_obj_id
, INFINITE
, cw_cancel_self
, cw_sig_eintr
))
1933 debug_printf ("cancelable_wait failed. %E");
1940 semaphore::_fixup_after_fork ()
1942 if (shared
== PTHREAD_PROCESS_PRIVATE
)
1944 debug_printf ("sem %x in _fixup_after_fork", this);
1945 /* FIXME: duplicate code here and in the constructor. */
1946 this->win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, currentvalue
,
1949 api_fatal ("failed to create new win32 semaphore, error %d");
1953 verifyable_object::verifyable_object (long verifyer
):
1958 verifyable_object::~verifyable_object ()
1964 pthread::thread_init_wrapper (void *arg
)
1966 pthread
*thread
= (pthread
*) arg
;
1967 set_tls_self_pointer (thread
);
1969 thread
->mutex
.lock ();
1971 // if thread is detached force cleanup on exit
1972 if (thread
->attr
.joinable
== PTHREAD_CREATE_DETACHED
&& thread
->joiner
== NULL
)
1973 thread
->joiner
= thread
;
1974 thread
->mutex
.unlock ();
1976 thread_printf ("started thread %p %p %p %p %p %p", arg
, &_my_tls
.local_clib
,
1977 _impure_ptr
, thread
, thread
->function
, thread
->arg
);
1979 // call the user's thread
1980 void *ret
= thread
->function (thread
->arg
);
1984 return 0; // just for show. Never returns.
1988 pthread::getsequence_np ()
1990 return get_thread_id ();
1994 pthread::create (pthread_t
*thread
, const pthread_attr_t
*attr
,
1995 void *(*start_routine
) (void *), void *arg
)
1997 if (attr
&& !pthread_attr::is_good_object (attr
))
2000 *thread
= new pthread ();
2001 if (!(*thread
)->create (start_routine
, attr
? *attr
: NULL
, arg
))
2012 pthread::once (pthread_once_t
*once_control
, void (*init_routine
) (void))
2015 if (once_control
->state
)
2018 pthread_mutex_lock (&once_control
->mutex
);
2019 /* Here we must set a cancellation handler to unlock the mutex if needed */
2020 /* but a cancellation handler is not the right thing. We need this in the thread
2021 *cleanup routine. Assumption: a thread can only be in one pthread_once routine
2022 *at a time. Stote a mutex_t *in the pthread_structure. if that's non null unlock
2023 *on pthread_exit ();
2025 if (!once_control
->state
)
2028 once_control
->state
= 1;
2030 /* Here we must remove our cancellation handler */
2031 pthread_mutex_unlock (&once_control
->mutex
);
2036 pthread::cancel (pthread_t thread
)
2038 if (!is_good_object (&thread
))
2041 return thread
->cancel ();
2045 pthread::atforkprepare ()
2047 callback
*cb
= MT_INTERFACE
->pthread_prepare
;
2056 MT_INTERFACE
->fixup_before_fork ();
2060 pthread::atforkparent ()
2064 callback
*cb
= MT_INTERFACE
->pthread_parent
;
2073 pthread::atforkchild ()
2075 MT_INTERFACE
->fixup_after_fork ();
2079 callback
*cb
= MT_INTERFACE
->pthread_child
;
2087 /* Register a set of functions to run before and after fork.
2088 prepare calls are called in LI-FC order.
2089 parent and child calls are called in FI-FC order. */
2091 pthread::atfork (void (*prepare
)(void), void (*parent
)(void), void (*child
)(void))
2093 callback
*prepcb
= NULL
, *parentcb
= NULL
, *childcb
= NULL
;
2096 prepcb
= new callback
;
2102 parentcb
= new callback
;
2112 childcb
= new callback
;
2125 prepcb
->cb
= prepare
;
2126 List_insert (MT_INTERFACE
->pthread_prepare
, prepcb
);
2130 parentcb
->cb
= parent
;
2131 callback
**t
= &MT_INTERFACE
->pthread_parent
;
2134 /* t = pointer to last next in the list */
2135 List_insert (*t
, parentcb
);
2139 childcb
->cb
= child
;
2140 callback
**t
= &MT_INTERFACE
->pthread_child
;
2143 /* t = pointer to last next in the list */
2144 List_insert (*t
, childcb
);
2150 pthread_attr_init (pthread_attr_t
*attr
)
2152 if (pthread_attr::is_good_object (attr
))
2155 *attr
= new pthread_attr
;
2156 if (!pthread_attr::is_good_object (attr
))
2166 pthread_attr_getinheritsched (const pthread_attr_t
*attr
,
2169 if (!pthread_attr::is_good_object (attr
))
2171 *inheritsched
= (*attr
)->inheritsched
;
2176 pthread_attr_getschedparam (const pthread_attr_t
*attr
,
2177 struct sched_param
*param
)
2179 if (!pthread_attr::is_good_object (attr
))
2181 *param
= (*attr
)->schedparam
;
2185 /* From a pure code point of view, this should call a helper in sched.cc,
2186 to allow for someone adding scheduler policy changes to win32 in the future.
2187 However that's extremely unlikely, so short and sweet will do us */
2189 pthread_attr_getschedpolicy (const pthread_attr_t
*attr
, int *policy
)
2191 if (!pthread_attr::is_good_object (attr
))
2193 *policy
= SCHED_FIFO
;
2199 pthread_attr_getscope (const pthread_attr_t
*attr
, int *contentionscope
)
2201 if (!pthread_attr::is_good_object (attr
))
2203 *contentionscope
= (*attr
)->contentionscope
;
2208 pthread_attr_setdetachstate (pthread_attr_t
*attr
, int detachstate
)
2210 if (!pthread_attr::is_good_object (attr
))
2212 if (detachstate
< 0 || detachstate
> 1)
2214 (*attr
)->joinable
= detachstate
;
2219 pthread_attr_getdetachstate (const pthread_attr_t
*attr
, int *detachstate
)
2221 if (!pthread_attr::is_good_object (attr
))
2223 *detachstate
= (*attr
)->joinable
;
2228 pthread_attr_setinheritsched (pthread_attr_t
*attr
, int inheritsched
)
2230 if (!pthread_attr::is_good_object (attr
))
2232 if (inheritsched
!= PTHREAD_INHERIT_SCHED
2233 && inheritsched
!= PTHREAD_EXPLICIT_SCHED
)
2235 (*attr
)->inheritsched
= inheritsched
;
2240 pthread_attr_setschedparam (pthread_attr_t
*attr
,
2241 const struct sched_param
*param
)
2243 if (!pthread_attr::is_good_object (attr
))
2245 if (!valid_sched_parameters (param
))
2247 (*attr
)->schedparam
= *param
;
2251 /* See __pthread_attr_getschedpolicy for some notes */
2253 pthread_attr_setschedpolicy (pthread_attr_t
*attr
, int policy
)
2255 if (!pthread_attr::is_good_object (attr
))
2257 if (policy
!= SCHED_FIFO
)
2263 pthread_attr_setscope (pthread_attr_t
*attr
, int contentionscope
)
2265 if (!pthread_attr::is_good_object (attr
))
2267 if (contentionscope
!= PTHREAD_SCOPE_SYSTEM
2268 && contentionscope
!= PTHREAD_SCOPE_PROCESS
)
2270 /* In future, we may be able to support system scope by escalating the thread
2271 priority to exceed the priority class. For now we only support PROCESS scope. */
2272 if (contentionscope
!= PTHREAD_SCOPE_PROCESS
)
2274 (*attr
)->contentionscope
= contentionscope
;
2279 pthread_attr_setstacksize (pthread_attr_t
*attr
, size_t size
)
2281 if (!pthread_attr::is_good_object (attr
))
2283 (*attr
)->stacksize
= size
;
2288 pthread_attr_getstacksize (const pthread_attr_t
*attr
, size_t *size
)
2290 if (!pthread_attr::is_good_object (attr
))
2292 *size
= (*attr
)->stacksize
;
2297 pthread_attr_destroy (pthread_attr_t
*attr
)
2299 if (!pthread_attr::is_good_object (attr
))
2307 pthread::join (pthread_t
*thread
, void **return_val
)
2309 pthread_t joiner
= self ();
2311 joiner
->testcancel ();
2313 // Initialize return val with NULL
2317 if (!is_good_object (&joiner
))
2320 if (!is_good_object (thread
))
2323 if (equal (*thread
,joiner
))
2326 (*thread
)->mutex
.lock ();
2328 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2330 (*thread
)->mutex
.unlock ();
2335 (*thread
)->joiner
= joiner
;
2336 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2337 (*thread
)->mutex
.unlock ();
2339 switch (cancelable_wait ((*thread
)->win32_obj_id
, INFINITE
, cw_no_cancel_self
, cw_sig_resume
))
2343 *return_val
= (*thread
)->return_ptr
;
2347 // set joined thread back to joinable since we got canceled
2348 (*thread
)->joiner
= NULL
;
2349 (*thread
)->attr
.joinable
= PTHREAD_CREATE_JOINABLE
;
2350 joiner
->cancel_self ();
2354 // should never happen
2363 pthread::detach (pthread_t
*thread
)
2365 if (!is_good_object (thread
))
2368 (*thread
)->mutex
.lock ();
2369 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2371 (*thread
)->mutex
.unlock ();
2375 // check if thread is still alive
2376 if ((*thread
)->valid
&& WaitForSingleObject ((*thread
)->win32_obj_id
, 0) == WAIT_TIMEOUT
)
2378 // force cleanup on exit
2379 (*thread
)->joiner
= *thread
;
2380 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2381 (*thread
)->mutex
.unlock ();
2385 // thread has already terminated.
2386 (*thread
)->mutex
.unlock ();
2394 pthread::suspend (pthread_t
*thread
)
2396 if (!is_good_object (thread
))
2399 if ((*thread
)->suspended
== false)
2401 (*thread
)->suspended
= true;
2402 SuspendThread ((*thread
)->win32_obj_id
);
2410 pthread::resume (pthread_t
*thread
)
2412 if (!is_good_object (thread
))
2415 if ((*thread
)->suspended
== true)
2416 ResumeThread ((*thread
)->win32_obj_id
);
2417 (*thread
)->suspended
= false;
2422 /* provided for source level compatability.
2423 See http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2426 pthread_getconcurrency ()
2428 return MT_INTERFACE
->concurrency
;
2431 /* keep this in sync with sched.cc */
2433 pthread_getschedparam (pthread_t thread
, int *policy
,
2434 struct sched_param
*param
)
2436 if (!pthread::is_good_object (&thread
))
2438 *policy
= SCHED_FIFO
;
2439 /* we don't return the current effective priority, we return the current
2440 requested priority */
2441 *param
= thread
->attr
.schedparam
;
2445 /* Thread Specific Data */
2447 pthread_key_create (pthread_key_t
*key
, void (*destructor
) (void *))
2449 /* The opengroup docs don't define if we should check this or not,
2450 but creation is relatively rare. */
2451 if (pthread_key::is_good_object (key
))
2454 *key
= new pthread_key (destructor
);
2456 if (!pthread_key::is_good_object (key
))
2466 pthread_key_delete (pthread_key_t key
)
2468 if (!pthread_key::is_good_object (&key
))
2475 /* provided for source level compatability. See
2476 http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2479 pthread_setconcurrency (int new_level
)
2483 MT_INTERFACE
->concurrency
= new_level
;
2487 /* keep syncronised with sched.cc */
2489 pthread_setschedparam (pthread_t thread
, int policy
,
2490 const struct sched_param
*param
)
2492 if (!pthread::is_good_object (&thread
))
2494 if (policy
!= SCHED_FIFO
)
2499 sched_set_thread_priority (thread
->win32_obj_id
, param
->sched_priority
);
2501 thread
->attr
.schedparam
.sched_priority
= param
->sched_priority
;
2507 pthread_setspecific (pthread_key_t key
, const void *value
)
2509 if (!pthread_key::is_good_object (&key
))
2516 pthread_getspecific (pthread_key_t key
)
2518 if (!pthread_key::is_good_object (&key
))
2521 return (key
)->get ();
2526 pthread_cond_destroy (pthread_cond_t
*cond
)
2528 if (pthread_cond::is_good_initializer (cond
))
2530 if (!pthread_cond::is_good_object (cond
))
2533 /* reads are atomic */
2534 if ((*cond
)->waiting
)
2544 pthread_cond::init (pthread_cond_t
*cond
, const pthread_condattr_t
*attr
)
2547 pthread_cond_t new_cond
;
2549 if (attr
&& !pthread_condattr::is_good_object (attr
))
2552 cond_initialization_lock
.lock ();
2554 /* Disabled since recognition of a valid object doesn't work reliably
2555 if the object is uninitialized. */
2556 if (!is_good_initializer_or_bad_object (cond
))
2558 cond_initialization_lock
.unlock ();
2562 new_cond
= new pthread_cond (attr
? (*attr
) : NULL
);
2563 if (!is_good_object (&new_cond
))
2566 cond_initialization_lock
.unlock ();
2571 cond_initialization_lock
.unlock ();
2577 pthread_cond_broadcast (pthread_cond_t
*cond
)
2579 if (pthread_cond::is_good_initializer (cond
))
2581 if (!pthread_cond::is_good_object (cond
))
2584 (*cond
)->unblock (true);
2590 pthread_cond_signal (pthread_cond_t
*cond
)
2592 if (pthread_cond::is_good_initializer (cond
))
2594 if (!pthread_cond::is_good_object (cond
))
2597 (*cond
)->unblock (false);
2603 __pthread_cond_dowait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
2606 if (!pthread_mutex::is_good_object (mutex
))
2608 if (!pthread_mutex::can_be_unlocked (mutex
))
2611 if (pthread_cond::is_good_initializer (cond
))
2612 pthread_cond::init (cond
, NULL
);
2613 if (!pthread_cond::is_good_object (cond
))
2616 return (*cond
)->wait (*mutex
, waitlength
);
2620 pthread_cond_timedwait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
2621 const struct timespec
*abstime
)
2627 if (efault
.faulted ())
2630 pthread_testcancel ();
2632 /* According to SUSv3, the abstime value must be checked for validity. */
2633 if (abstime
->tv_sec
< 0
2634 || abstime
->tv_nsec
< 0
2635 || abstime
->tv_nsec
> 999999999)
2638 gettimeofday (&tv
, NULL
);
2639 /* Check for immediate timeout before converting to microseconds, since
2640 the resulting value can easily overflow long. This also allows to
2641 evaluate microseconds directly in DWORD. */
2642 if (tv
.tv_sec
> abstime
->tv_sec
2643 || (tv
.tv_sec
== abstime
->tv_sec
2644 && tv
.tv_usec
> abstime
->tv_nsec
/ 1000))
2647 waitlength
= (abstime
->tv_sec
- tv
.tv_sec
) * 1000;
2648 waitlength
+= (abstime
->tv_nsec
/ 1000 - tv
.tv_usec
) / 1000;
2649 return __pthread_cond_dowait (cond
, mutex
, waitlength
);
2653 pthread_cond_wait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
)
2655 pthread_testcancel ();
2657 return __pthread_cond_dowait (cond
, mutex
, INFINITE
);
2661 pthread_condattr_init (pthread_condattr_t
*condattr
)
2663 if (pthread_condattr::is_good_object (condattr
))
2666 *condattr
= new pthread_condattr
;
2667 if (!pthread_condattr::is_good_object (condattr
))
2677 pthread_condattr_getpshared (const pthread_condattr_t
*attr
, int *pshared
)
2679 if (!pthread_condattr::is_good_object (attr
))
2681 *pshared
= (*attr
)->shared
;
2686 pthread_condattr_setpshared (pthread_condattr_t
*attr
, int pshared
)
2688 if (!pthread_condattr::is_good_object (attr
))
2690 if ((pshared
< 0) || (pshared
> 1))
2692 /* shared cond vars not currently supported */
2693 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2695 (*attr
)->shared
= pshared
;
2700 pthread_condattr_destroy (pthread_condattr_t
*condattr
)
2702 if (!pthread_condattr::is_good_object (condattr
))
2710 pthread_rwlock_destroy (pthread_rwlock_t
*rwlock
)
2712 if (pthread_rwlock::is_good_initializer (rwlock
))
2714 if (!pthread_rwlock::is_good_object (rwlock
))
2717 if ((*rwlock
)->writer
|| (*rwlock
)->readers
||
2718 (*rwlock
)->waiting_readers
|| (*rwlock
)->waiting_writers
)
2728 pthread_rwlock::init (pthread_rwlock_t
*rwlock
, const pthread_rwlockattr_t
*attr
)
2730 pthread_rwlock_t new_rwlock
;
2732 if (attr
&& !pthread_rwlockattr::is_good_object (attr
))
2735 rwlock_initialization_lock
.lock ();
2737 /* Disabled since recognition of a valid object doesn't work reliably
2738 if the object is uninitialized. */
2739 if (!is_good_initializer_or_bad_object (rwlock
))
2741 rwlock_initialization_lock
.unlock ();
2745 new_rwlock
= new pthread_rwlock (attr
? (*attr
) : NULL
);
2746 if (!is_good_object (&new_rwlock
))
2749 rwlock_initialization_lock
.unlock ();
2753 *rwlock
= new_rwlock
;
2754 rwlock_initialization_lock
.unlock ();
2760 pthread_rwlock_rdlock (pthread_rwlock_t
*rwlock
)
2762 pthread_testcancel ();
2764 if (pthread_rwlock::is_good_initializer (rwlock
))
2765 pthread_rwlock::init (rwlock
, NULL
);
2766 if (!pthread_rwlock::is_good_object (rwlock
))
2769 return (*rwlock
)->rdlock ();
2773 pthread_rwlock_tryrdlock (pthread_rwlock_t
*rwlock
)
2775 if (pthread_rwlock::is_good_initializer (rwlock
))
2776 pthread_rwlock::init (rwlock
, NULL
);
2777 if (!pthread_rwlock::is_good_object (rwlock
))
2780 return (*rwlock
)->tryrdlock ();
2784 pthread_rwlock_wrlock (pthread_rwlock_t
*rwlock
)
2786 pthread_testcancel ();
2788 if (pthread_rwlock::is_good_initializer (rwlock
))
2789 pthread_rwlock::init (rwlock
, NULL
);
2790 if (!pthread_rwlock::is_good_object (rwlock
))
2793 return (*rwlock
)->wrlock ();
2797 pthread_rwlock_trywrlock (pthread_rwlock_t
*rwlock
)
2799 if (pthread_rwlock::is_good_initializer (rwlock
))
2800 pthread_rwlock::init (rwlock
, NULL
);
2801 if (!pthread_rwlock::is_good_object (rwlock
))
2804 return (*rwlock
)->trywrlock ();
2808 pthread_rwlock_unlock (pthread_rwlock_t
*rwlock
)
2810 if (pthread_rwlock::is_good_initializer (rwlock
))
2812 if (!pthread_rwlock::is_good_object (rwlock
))
2815 return (*rwlock
)->unlock ();
2819 pthread_rwlockattr_init (pthread_rwlockattr_t
*rwlockattr
)
2821 if (pthread_rwlockattr::is_good_object (rwlockattr
))
2824 *rwlockattr
= new pthread_rwlockattr
;
2825 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
2827 delete (*rwlockattr
);
2835 pthread_rwlockattr_getpshared (const pthread_rwlockattr_t
*attr
, int *pshared
)
2837 if (!pthread_rwlockattr::is_good_object (attr
))
2839 *pshared
= (*attr
)->shared
;
2844 pthread_rwlockattr_setpshared (pthread_rwlockattr_t
*attr
, int pshared
)
2846 if (!pthread_rwlockattr::is_good_object (attr
))
2848 if ((pshared
< 0) || (pshared
> 1))
2850 /* shared rwlock vars not currently supported */
2851 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2853 (*attr
)->shared
= pshared
;
2858 pthread_rwlockattr_destroy (pthread_rwlockattr_t
*rwlockattr
)
2860 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
2862 delete (*rwlockattr
);
2869 pthread_kill (pthread_t thread
, int sig
)
2871 // lock myself, for the use of thread2signal
2872 // two different kills might clash: FIXME
2874 if (!pthread::is_good_object (&thread
))
2879 si
.si_code
= SI_USER
;
2880 si
.si_pid
= myself
->pid
;
2881 si
.si_uid
= myself
->uid
;
2882 thread
->cygtls
->set_threadkill ();
2883 int rval
= sig
? sig_send (NULL
, si
, thread
->cygtls
) : 0;
2890 pthread_sigmask (int operation
, const sigset_t
*set
, sigset_t
*old_set
)
2892 return handle_sigprocmask (operation
, set
, old_set
, _my_tls
.sigmask
);
2898 pthread_equal (pthread_t t1
, pthread_t t2
)
2900 return pthread::equal (t1
, t2
);
2906 pthread_mutex::init (pthread_mutex_t
*mutex
,
2907 const pthread_mutexattr_t
*attr
,
2908 const pthread_mutex_t initializer
)
2910 pthread_mutex_t new_mutex
;
2912 if (attr
&& !pthread_mutexattr::is_good_object (attr
))
2915 mutex_initialization_lock
.lock ();
2917 /* Disabled since recognition of a valid object doesn't work reliably
2918 if the object is uninitialized. */
2919 if (!is_good_initializer_or_bad_object (mutex
))
2921 mutex_initialization_lock
.unlock ();
2925 new_mutex
= new pthread_mutex (attr
? (*attr
) : NULL
);
2926 if (!is_good_object (&new_mutex
))
2929 mutex_initialization_lock
.unlock ();
2933 if (!attr
&& initializer
)
2935 if (initializer
== PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
)
2936 new_mutex
->type
= PTHREAD_MUTEX_RECURSIVE
;
2937 else if (initializer
== PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
)
2938 new_mutex
->type
= PTHREAD_MUTEX_NORMAL
;
2939 else if (initializer
== PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
)
2940 new_mutex
->type
= PTHREAD_MUTEX_ERRORCHECK
;
2944 mutex_initialization_lock
.unlock ();
2950 pthread_mutex_getprioceiling (const pthread_mutex_t
*mutex
,
2953 /* We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support
2956 We can support mutex priorities in the future though:
2957 Store a priority with each mutex.
2958 When the mutex is optained, set the thread priority as appropriate
2959 When the mutex is released, reset the thread priority. */
2964 pthread_mutex_lock (pthread_mutex_t
*mutex
)
2966 if (pthread_mutex::is_good_initializer (mutex
))
2967 pthread_mutex::init (mutex
, NULL
, *mutex
);
2968 if (!pthread_mutex::is_good_object (mutex
))
2970 return (*mutex
)->lock ();
2974 pthread_mutex_trylock (pthread_mutex_t
*mutex
)
2976 if (pthread_mutex::is_good_initializer (mutex
))
2977 pthread_mutex::init (mutex
, NULL
, *mutex
);
2978 if (!pthread_mutex::is_good_object (mutex
))
2980 return (*mutex
)->trylock ();
2984 pthread_mutex_unlock (pthread_mutex_t
*mutex
)
2986 if (pthread_mutex::is_good_initializer (mutex
))
2988 if (!pthread_mutex::is_good_object (mutex
))
2990 return (*mutex
)->unlock ();
2994 pthread_mutex_destroy (pthread_mutex_t
*mutex
)
2998 if (pthread_mutex::is_good_initializer (mutex
))
3000 if (!pthread_mutex::is_good_object (mutex
))
3003 rv
= (*mutex
)->destroy ();
3012 pthread_mutex_setprioceiling (pthread_mutex_t
*mutex
, int prioceiling
,
3018 /* Win32 doesn't support mutex priorities - see __pthread_mutex_getprioceiling
3021 pthread_mutexattr_getprotocol (const pthread_mutexattr_t
*attr
,
3024 if (!pthread_mutexattr::is_good_object (attr
))
3030 pthread_mutexattr_getpshared (const pthread_mutexattr_t
*attr
,
3033 if (!pthread_mutexattr::is_good_object (attr
))
3035 *pshared
= (*attr
)->pshared
;
3040 pthread_mutexattr_gettype (const pthread_mutexattr_t
*attr
, int *type
)
3042 if (!pthread_mutexattr::is_good_object (attr
))
3044 *type
= (*attr
)->mutextype
;
3048 /* FIXME: write and test process shared mutex's. */
3050 pthread_mutexattr_init (pthread_mutexattr_t
*attr
)
3052 if (pthread_mutexattr::is_good_object (attr
))
3055 *attr
= new pthread_mutexattr ();
3056 if (!pthread_mutexattr::is_good_object (attr
))
3066 pthread_mutexattr_destroy (pthread_mutexattr_t
*attr
)
3068 if (!pthread_mutexattr::is_good_object (attr
))
3076 /* Win32 doesn't support mutex priorities */
3078 pthread_mutexattr_setprotocol (pthread_mutexattr_t
*attr
, int protocol
)
3080 if (!pthread_mutexattr::is_good_object (attr
))
3085 /* Win32 doesn't support mutex priorities */
3087 pthread_mutexattr_setprioceiling (pthread_mutexattr_t
*attr
,
3090 if (!pthread_mutexattr::is_good_object (attr
))
3096 pthread_mutexattr_getprioceiling (const pthread_mutexattr_t
*attr
,
3099 if (!pthread_mutexattr::is_good_object (attr
))
3105 pthread_mutexattr_setpshared (pthread_mutexattr_t
*attr
, int pshared
)
3107 if (!pthread_mutexattr::is_good_object (attr
))
3109 /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
3112 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
3114 (*attr
)->pshared
= pshared
;
3118 /* see pthread_mutex_gettype */
3120 pthread_mutexattr_settype (pthread_mutexattr_t
*attr
, int type
)
3122 if (!pthread_mutexattr::is_good_object (attr
))
3127 case PTHREAD_MUTEX_ERRORCHECK
:
3128 case PTHREAD_MUTEX_RECURSIVE
:
3129 case PTHREAD_MUTEX_NORMAL
:
3130 (*attr
)->mutextype
= type
;
3141 /* static members */
3144 semaphore::init (sem_t
*sem
, int pshared
, unsigned int value
)
3146 /* opengroup calls this undefined */
3147 if (is_good_object (sem
))
3150 if (value
> SEM_VALUE_MAX
)
3153 *sem
= new semaphore (pshared
, value
);
3155 if (!is_good_object (sem
))
3165 semaphore::destroy (sem_t
*sem
)
3167 if (!is_good_object (sem
))
3170 /* FIXME - new feature - test for busy against threads... */
3178 semaphore::open (const char *name
, int oflag
, mode_t mode
, unsigned int value
)
3180 if (value
> SEM_VALUE_MAX
)
3186 sem_t
*sem
= new sem_t
;
3193 *sem
= new semaphore (name
, oflag
, mode
, value
);
3195 if (!is_good_object (sem
))
3205 semaphore::wait (sem_t
*sem
)
3207 pthread_testcancel ();
3209 if (!is_good_object (sem
))
3215 return (*sem
)->_wait ();
3219 semaphore::trywait (sem_t
*sem
)
3221 if (!is_good_object (sem
))
3227 return (*sem
)->_trywait ();
3231 semaphore::timedwait (sem_t
*sem
, const struct timespec
*abstime
)
3233 if (!is_good_object (sem
))
3239 return (*sem
)->_timedwait (abstime
);
3243 semaphore::post (sem_t
*sem
)
3245 if (!is_good_object (sem
))
3256 semaphore::getvalue (sem_t
*sem
, int *sval
)
3259 if (efault
.faulted () || !is_good_object (sem
))
3265 return (*sem
)->_getvalue (sval
);
3270 pthread_null::get_null_pthread ()
3272 /* because of weird entry points */
3273 _instance
.magic
= 0;
3277 pthread_null::pthread_null ()
3279 attr
.joinable
= PTHREAD_CREATE_DETACHED
;
3280 /* Mark ourselves as invalid */
3284 pthread_null::~pthread_null ()
3289 pthread_null::create (void *(*)(void *), pthread_attr
*, void *)
3295 pthread_null::exit (void *value_ptr
)
3297 _my_tls
.remove (INFINITE
);
3302 pthread_null::cancel ()
3308 pthread_null::testcancel ()
3313 pthread_null::setcancelstate (int state
, int *oldstate
)
3319 pthread_null::setcanceltype (int type
, int *oldtype
)
3325 pthread_null::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
3330 pthread_null::pop_cleanup_handler (int const execute
)
3335 pthread_null::getsequence_np ()
3340 pthread_null
pthread_null::_instance
;