1 /* thread.h: Locking and threading module definitions
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
5 Written by Marco Fuykschot <marco@ddi.nl>
6 Major update 2001 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 #ifndef _CYGNUS_THREADS_
15 #define _CYGNUS_THREADS_
17 #define LOCK_FD_LIST 1
18 #define LOCK_MEMORY_LIST 2
19 #define LOCK_MMAP_LIST 3
20 #define LOCK_DLL_LIST 4
32 void SetResourceLock (int, int, const char *) __attribute__ ((regparm (3)));
33 void ReleaseResourceLock (int, int, const char *)
34 __attribute__ ((regparm (3)));
41 lock_counter (0), win32_obj_id (0)
48 CloseHandle (win32_obj_id);
54 win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
57 debug_printf ("CreateSemaphore failed. %E");
65 if (InterlockedIncrement ((long *)&lock_counter) != 1)
66 WaitForSingleObject (win32_obj_id, INFINITE);
71 if (InterlockedDecrement ((long *)&lock_counter))
72 ::ReleaseSemaphore (win32_obj_id, 1, NULL);
76 unsigned long lock_counter;
86 LPCRITICAL_SECTION Lock (int);
90 CRITICAL_SECTION lock;
94 #define PTHREAD_MAGIC 0xdf0df045
95 #define PTHREAD_MUTEX_MAGIC PTHREAD_MAGIC+1
96 #define PTHREAD_KEY_MAGIC PTHREAD_MAGIC+2
97 #define PTHREAD_ATTR_MAGIC PTHREAD_MAGIC+3
98 #define PTHREAD_MUTEXATTR_MAGIC PTHREAD_MAGIC+4
99 #define PTHREAD_COND_MAGIC PTHREAD_MAGIC+5
100 #define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6
101 #define SEM_MAGIC PTHREAD_MAGIC+7
102 #define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8
103 #define PTHREAD_RWLOCK_MAGIC PTHREAD_MAGIC+9
104 #define PTHREAD_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
106 #define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
108 /* verifyable_object should not be defined here - it's a general purpose class */
110 class verifyable_object
115 verifyable_object (long);
116 virtual ~verifyable_object ();
124 } verifyable_object_state;
126 verifyable_object_state verifyable_object_isvalid (void const *, long);
127 verifyable_object_state verifyable_object_isvalid (void const *, long, void *);
129 template <class list_node> inline void
130 List_insert (list_node *&head, list_node *node)
136 while (InterlockedCompareExchangePointer (&head, node, node->next) != node->next);
139 template <class list_node> inline void
140 List_remove (fast_mutex &mx, list_node *&head, list_node *node)
147 if (InterlockedCompareExchangePointer (&head, node->next, node) != node)
149 list_node *cur = head;
151 while (cur->next && node != cur->next)
153 if (node == cur->next)
154 cur->next = cur->next->next;
161 template <class list_node> class List
173 void fixup_after_fork ()
178 void insert (list_node *node)
180 List_insert (head, node);
183 void remove (list_node *node)
185 List_remove (mx, head, node);
188 void for_each (void (list_node::*callback) ())
191 list_node *cur = head;
204 api_fatal ("Could not create mutex for list synchronisation.");
211 class pthread_key: public verifyable_object
214 static bool is_good_object (pthread_key_t const *);
217 int set (const void *);
220 pthread_key (void (*)(void *));
222 static void fixup_before_fork ()
224 keys.for_each (&pthread_key::_fixup_before_fork);
227 static void fixup_after_fork ()
229 keys.fixup_after_fork ();
230 keys.for_each (&pthread_key::_fixup_after_fork);
233 static void run_all_destructors ()
235 keys.for_each (&pthread_key::run_destructor);
238 /* List support calls */
239 class pthread_key *next;
241 static List<pthread_key> keys;
242 void _fixup_before_fork ();
243 void _fixup_after_fork ();
244 void (*destructor) (void *);
245 void run_destructor ();
249 class pthread_attr: public verifyable_object
252 static bool is_good_object(pthread_attr_t const *);
256 struct sched_param schedparam;
263 class pthread_mutexattr: public verifyable_object
266 static bool is_good_object(pthread_mutexattr_t const *);
269 pthread_mutexattr ();
270 ~pthread_mutexattr ();
273 class pthread_mutex: public verifyable_object
276 static bool is_good_object (pthread_mutex_t const *);
277 static bool is_good_initializer (pthread_mutex_t const *);
278 static bool is_good_initializer_or_object (pthread_mutex_t const *);
279 static bool is_good_initializer_or_bad_object (pthread_mutex_t const *mutex);
280 static bool can_be_unlocked (pthread_mutex_t const *mutex);
281 static void init_mutex ();
282 static int init (pthread_mutex_t *, const pthread_mutexattr_t *);
284 unsigned long lock_counter;
286 unsigned int recursion_counter;
292 pthread_t get_pthread_self () const
294 return PTHREAD_MUTEX_NORMAL == type ? MUTEX_OWNER_ANONYMOUS :
300 return _lock (get_pthread_self ());
304 return _trylock (get_pthread_self ());
308 return _unlock (get_pthread_self ());
312 return _destroy (get_pthread_self ());
315 void set_owner (pthread_t self)
317 recursion_counter = 1;
321 int lock_recursive ()
323 if (UINT_MAX == recursion_counter)
329 pthread_mutex (pthread_mutexattr * = NULL);
330 pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
333 class pthread_mutex * next;
334 static void fixup_after_fork ()
336 mutexes.fixup_after_fork ();
337 mutexes.for_each (&pthread_mutex::_fixup_after_fork);
341 int _lock (pthread_t self);
342 int _trylock (pthread_t self);
343 int _unlock (pthread_t self);
344 int _destroy (pthread_t self);
346 void _fixup_after_fork ();
348 static List<pthread_mutex> mutexes;
349 static fast_mutex mutex_initialization_lock;
352 #define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
355 class pthread: public verifyable_object
359 class pthread_attr attr;
360 void *(*function) (void *);
365 int cancelstate, canceltype;
370 virtual void create (void *(*)(void *), pthread_attr *, void *);
375 static void init_mainthread ();
376 static bool is_good_object(pthread_t const *);
377 static void atforkprepare();
378 static void atforkparent();
379 static void atforkchild();
382 static int cancel (pthread_t);
383 static int join (pthread_t * thread, void **return_val);
384 static int detach (pthread_t * thread);
385 static int create (pthread_t * thread, const pthread_attr_t * attr,
386 void *(*start_routine) (void *), void *arg);
387 static int once (pthread_once_t *, void (*)(void));
388 static int atfork(void (*)(void), void (*)(void), void (*)(void));
389 static int suspend (pthread_t * thread);
390 static int resume (pthread_t * thread);
392 virtual void exit (void *value_ptr) __attribute__ ((noreturn));
394 virtual int cancel ();
396 virtual void testcancel ();
397 static void static_cancel_self ();
399 static DWORD cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel = true);
401 virtual int setcancelstate (int state, int *oldstate);
402 virtual int setcanceltype (int type, int *oldtype);
404 virtual void push_cleanup_handler (__pthread_cleanup_handler *handler);
405 virtual void pop_cleanup_handler (int const execute);
407 static pthread* self ();
408 static DWORD WINAPI thread_init_wrapper (void *);
410 virtual unsigned long getsequence_np();
412 static int equal (pthread_t t1, pthread_t t2)
417 /* List support calls */
419 static void fixup_after_fork ()
421 threads.fixup_after_fork ();
422 threads.for_each (&pthread::_fixup_after_fork);
425 static void suspend_all_except_self ()
427 threads.for_each (&pthread::suspend_except_self);
430 static void resume_all ()
432 threads.for_each (&pthread::resume);
436 static List<pthread> threads;
438 __pthread_cleanup_handler *cleanup_stack;
441 void suspend_except_self ();
444 void _fixup_after_fork ();
446 void pop_all_cleanup_handlers (void);
447 void precreate (pthread_attr *);
449 void set_tls_self_pointer ();
450 bool create_cancel_event ();
451 static pthread *get_tls_self_pointer ();
453 DWORD get_thread_id ();
456 class pthread_null : public pthread
459 static pthread *get_null_pthread();
462 /* From pthread These should never get called
463 * as the ojbect is not verifyable
465 void create (void *(*)(void *), pthread_attr *, void *);
466 void exit (void *value_ptr) __attribute__ ((noreturn));
469 int setcancelstate (int state, int *oldstate);
470 int setcanceltype (int type, int *oldtype);
471 void push_cleanup_handler (__pthread_cleanup_handler *handler);
472 void pop_cleanup_handler (int const execute);
473 unsigned long getsequence_np();
477 static pthread_null _instance;
480 class pthread_condattr: public verifyable_object
483 static bool is_good_object(pthread_condattr_t const *);
487 ~pthread_condattr ();
490 class pthread_cond: public verifyable_object
493 static bool is_good_object (pthread_cond_t const *);
494 static bool is_good_initializer (pthread_cond_t const *);
495 static bool is_good_initializer_or_object (pthread_cond_t const *);
496 static bool is_good_initializer_or_bad_object (pthread_cond_t const *);
497 static void init_mutex ();
498 static int init (pthread_cond_t *, const pthread_condattr_t *);
502 unsigned long waiting;
503 unsigned long pending;
506 pthread_mutex mtx_in;
507 pthread_mutex mtx_out;
509 pthread_mutex_t mtx_cond;
511 void unblock (const bool all);
512 int wait (pthread_mutex_t mutex, DWORD dwMilliseconds = INFINITE);
514 pthread_cond (pthread_condattr *);
517 class pthread_cond * next;
518 static void fixup_after_fork ()
520 conds.fixup_after_fork ();
521 conds.for_each (&pthread_cond::_fixup_after_fork);
525 void _fixup_after_fork ();
527 static List<pthread_cond> conds;
528 static fast_mutex cond_initialization_lock;
531 class pthread_rwlockattr: public verifyable_object
534 static bool is_good_object(pthread_rwlockattr_t const *);
537 pthread_rwlockattr ();
538 ~pthread_rwlockattr ();
541 class pthread_rwlock: public verifyable_object
544 static bool is_good_object (pthread_rwlock_t const *);
545 static bool is_good_initializer (pthread_rwlock_t const *);
546 static bool is_good_initializer_or_object (pthread_rwlock_t const *);
547 static bool is_good_initializer_or_bad_object (pthread_rwlock_t const *);
548 static void init_mutex ();
549 static int init (pthread_rwlock_t *, const pthread_rwlockattr_t *);
553 unsigned long waiting_readers;
554 unsigned long waiting_writers;
558 struct RWLOCK_READER *next;
561 fast_mutex readers_mx;
572 pthread_cond cond_readers;
573 pthread_cond cond_writers;
575 pthread_rwlock (pthread_rwlockattr *);
578 class pthread_rwlock * next;
579 static void fixup_after_fork ()
581 rwlocks.fixup_after_fork ();
582 rwlocks.for_each (&pthread_rwlock::_fixup_after_fork);
586 static List<pthread_rwlock> rwlocks;
588 void add_reader (struct RWLOCK_READER *rd);
589 void remove_reader (struct RWLOCK_READER *rd);
590 struct RWLOCK_READER *lookup_reader (pthread_t thread);
597 cond_writers.unblock (false);
599 else if (waiting_readers)
600 cond_readers.unblock (true);
604 static void rdlock_cleanup (void *arg);
605 static void wrlock_cleanup (void *arg);
607 void _fixup_after_fork ();
609 static fast_mutex rwlock_initialization_lock;
615 pthread_mutex_t mutex;
619 /* shouldn't be here */
620 class semaphore: public verifyable_object
623 static bool is_good_object(sem_t const *);
625 static int init (sem_t * sem, int pshared, unsigned int value);
626 static int destroy (sem_t * sem);
627 static sem_t *open (const char *name, int oflag, mode_t mode,
629 static int wait (sem_t * sem);
630 static int post (sem_t * sem);
631 static int getvalue (sem_t * sem, int *sval);
632 static int trywait (sem_t * sem);
633 static int timedwait (sem_t * sem, const struct timespec *abstime);
640 semaphore (int, unsigned int);
641 semaphore (const char *name, int oflag, mode_t mode, unsigned int value);
644 class semaphore * next;
645 static void fixup_after_fork ()
647 semaphores.fixup_after_fork ();
648 semaphores.for_each (&semaphore::_fixup_after_fork);
654 int _getvalue (int *sval);
656 int _timedwait (const struct timespec *abstime);
658 void _fixup_after_fork ();
660 static List<semaphore> semaphores;
667 class callback * next;
674 long int threadcount;
676 callback *pthread_prepare;
677 callback *pthread_child;
678 callback *pthread_parent;
681 void fixup_before_fork (void);
682 void fixup_after_fork (void);
684 #if 0 // avoid initialization since zero is implied and
686 concurrency (0), threadcount (0),
687 pthread_prepare (NULL), pthread_child (NULL), pthread_parent (NULL)
693 #define MT_INTERFACE user_data->threadinterface
694 #endif // _CYGNUS_THREADS_