1 /* thread.h: Locking and threading module definitions
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 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_MMAP_LIST 1
29 void SetResourceLock (int, int, const char *) __attribute__ ((regparm (3)));
30 void ReleaseResourceLock (int, int, const char *)
31 __attribute__ ((regparm (3)));
38 lock_counter (0), win32_obj_id (0)
45 CloseHandle (win32_obj_id);
51 win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
54 debug_printf ("CreateSemaphore failed. %E");
62 if (InterlockedIncrement ((long *)&lock_counter) != 1)
63 WaitForSingleObject (win32_obj_id, INFINITE);
68 if (InterlockedDecrement ((long *)&lock_counter))
69 ::ReleaseSemaphore (win32_obj_id, 1, NULL);
73 unsigned long lock_counter;
83 LPCRITICAL_SECTION Lock (int);
87 CRITICAL_SECTION lock;
91 #define PTHREAD_MAGIC 0xdf0df045
92 #define PTHREAD_MUTEX_MAGIC PTHREAD_MAGIC+1
93 #define PTHREAD_KEY_MAGIC PTHREAD_MAGIC+2
94 #define PTHREAD_ATTR_MAGIC PTHREAD_MAGIC+3
95 #define PTHREAD_MUTEXATTR_MAGIC PTHREAD_MAGIC+4
96 #define PTHREAD_COND_MAGIC PTHREAD_MAGIC+5
97 #define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6
98 #define SEM_MAGIC PTHREAD_MAGIC+7
99 #define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8
100 #define PTHREAD_RWLOCK_MAGIC PTHREAD_MAGIC+9
101 #define PTHREAD_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
103 #define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
105 /* verifyable_object should not be defined here - it's a general purpose class */
107 class verifyable_object
112 verifyable_object (long);
113 virtual ~verifyable_object ();
121 } verifyable_object_state;
123 verifyable_object_state verifyable_object_isvalid (void const *, long);
124 verifyable_object_state verifyable_object_isvalid (void const *, long, void *);
126 template <class list_node> inline void
127 List_insert (list_node *&head, list_node *node)
133 while (InterlockedCompareExchangePointer (&head, node, node->next) != node->next);
136 template <class list_node> inline void
137 List_remove (fast_mutex &mx, list_node *&head, list_node *node)
144 if (InterlockedCompareExchangePointer (&head, node->next, node) != node)
146 list_node *cur = head;
148 while (cur->next && node != cur->next)
150 if (node == cur->next)
151 cur->next = cur->next->next;
158 template <class list_node> class List
170 void fixup_after_fork ()
175 void insert (list_node *node)
177 List_insert (head, node);
180 void remove (list_node *node)
182 List_remove (mx, head, node);
185 void for_each (void (list_node::*callback) ())
188 list_node *cur = head;
201 api_fatal ("Could not create mutex for list synchronisation.");
208 class pthread_key: public verifyable_object
211 static bool is_good_object (pthread_key_t const *);
214 int set (const void *);
217 pthread_key (void (*)(void *));
219 static void fixup_before_fork ()
221 keys.for_each (&pthread_key::_fixup_before_fork);
224 static void fixup_after_fork ()
226 keys.fixup_after_fork ();
227 keys.for_each (&pthread_key::_fixup_after_fork);
230 static void run_all_destructors ()
232 keys.for_each (&pthread_key::run_destructor);
235 /* List support calls */
236 class pthread_key *next;
238 static List<pthread_key> keys;
239 void _fixup_before_fork ();
240 void _fixup_after_fork ();
241 void (*destructor) (void *);
242 void run_destructor ();
246 class pthread_attr: public verifyable_object
249 static bool is_good_object(pthread_attr_t const *);
253 struct sched_param schedparam;
260 class pthread_mutexattr: public verifyable_object
263 static bool is_good_object(pthread_mutexattr_t const *);
266 pthread_mutexattr ();
267 ~pthread_mutexattr ();
270 class pthread_mutex: public verifyable_object
273 static bool is_good_object (pthread_mutex_t const *);
274 static bool is_good_initializer (pthread_mutex_t const *);
275 static bool is_good_initializer_or_object (pthread_mutex_t const *);
276 static bool is_good_initializer_or_bad_object (pthread_mutex_t const *mutex);
277 static bool can_be_unlocked (pthread_mutex_t const *mutex);
278 static void init_mutex ();
279 static int init (pthread_mutex_t *, const pthread_mutexattr_t *);
281 unsigned long lock_counter;
283 unsigned int recursion_counter;
289 pthread_t get_pthread_self () const
291 return PTHREAD_MUTEX_NORMAL == type ? MUTEX_OWNER_ANONYMOUS :
297 return _lock (get_pthread_self ());
301 return _trylock (get_pthread_self ());
305 return _unlock (get_pthread_self ());
309 return _destroy (get_pthread_self ());
312 void set_owner (pthread_t self)
314 recursion_counter = 1;
318 int lock_recursive ()
320 if (UINT_MAX == recursion_counter)
326 pthread_mutex (pthread_mutexattr * = NULL);
327 pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
330 class pthread_mutex * next;
331 static void fixup_after_fork ()
333 mutexes.fixup_after_fork ();
334 mutexes.for_each (&pthread_mutex::_fixup_after_fork);
338 int _lock (pthread_t self);
339 int _trylock (pthread_t self);
340 int _unlock (pthread_t self);
341 int _destroy (pthread_t self);
343 void _fixup_after_fork ();
345 static List<pthread_mutex> mutexes;
346 static fast_mutex mutex_initialization_lock;
349 #define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
352 class pthread: public verifyable_object
356 class pthread_attr attr;
357 void *(*function) (void *);
362 int cancelstate, canceltype;
367 virtual void create (void *(*)(void *), pthread_attr *, void *);
372 static void init_mainthread ();
373 static bool is_good_object(pthread_t const *);
374 static void atforkprepare();
375 static void atforkparent();
376 static void atforkchild();
379 static int cancel (pthread_t);
380 static int join (pthread_t * thread, void **return_val);
381 static int detach (pthread_t * thread);
382 static int create (pthread_t * thread, const pthread_attr_t * attr,
383 void *(*start_routine) (void *), void *arg);
384 static int once (pthread_once_t *, void (*)(void));
385 static int atfork(void (*)(void), void (*)(void), void (*)(void));
386 static int suspend (pthread_t * thread);
387 static int resume (pthread_t * thread);
389 virtual void exit (void *value_ptr) __attribute__ ((noreturn));
391 virtual int cancel ();
393 virtual void testcancel ();
394 static void static_cancel_self ();
396 static DWORD cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel = true);
398 virtual int setcancelstate (int state, int *oldstate);
399 virtual int setcanceltype (int type, int *oldtype);
401 virtual void push_cleanup_handler (__pthread_cleanup_handler *handler);
402 virtual void pop_cleanup_handler (int const execute);
404 static pthread* self ();
405 static DWORD WINAPI thread_init_wrapper (void *);
407 virtual unsigned long getsequence_np();
409 static int equal (pthread_t t1, pthread_t t2)
414 /* List support calls */
416 static void fixup_after_fork ()
418 threads.fixup_after_fork ();
419 threads.for_each (&pthread::_fixup_after_fork);
422 static void suspend_all_except_self ()
424 threads.for_each (&pthread::suspend_except_self);
427 static void resume_all ()
429 threads.for_each (&pthread::resume);
433 static List<pthread> threads;
435 __pthread_cleanup_handler *cleanup_stack;
438 void suspend_except_self ();
441 void _fixup_after_fork ();
443 void pop_all_cleanup_handlers (void);
444 void precreate (pthread_attr *);
446 void set_tls_self_pointer ();
447 bool create_cancel_event ();
448 static pthread *get_tls_self_pointer ();
450 DWORD get_thread_id ();
453 class pthread_null : public pthread
456 static pthread *get_null_pthread();
459 /* From pthread These should never get called
460 * as the ojbect is not verifyable
462 void create (void *(*)(void *), pthread_attr *, void *);
463 void exit (void *value_ptr) __attribute__ ((noreturn));
466 int setcancelstate (int state, int *oldstate);
467 int setcanceltype (int type, int *oldtype);
468 void push_cleanup_handler (__pthread_cleanup_handler *handler);
469 void pop_cleanup_handler (int const execute);
470 unsigned long getsequence_np();
474 static pthread_null _instance;
477 class pthread_condattr: public verifyable_object
480 static bool is_good_object(pthread_condattr_t const *);
484 ~pthread_condattr ();
487 class pthread_cond: public verifyable_object
490 static bool is_good_object (pthread_cond_t const *);
491 static bool is_good_initializer (pthread_cond_t const *);
492 static bool is_good_initializer_or_object (pthread_cond_t const *);
493 static bool is_good_initializer_or_bad_object (pthread_cond_t const *);
494 static void init_mutex ();
495 static int init (pthread_cond_t *, const pthread_condattr_t *);
499 unsigned long waiting;
500 unsigned long pending;
503 pthread_mutex mtx_in;
504 pthread_mutex mtx_out;
506 pthread_mutex_t mtx_cond;
508 void unblock (const bool all);
509 int wait (pthread_mutex_t mutex, DWORD dwMilliseconds = INFINITE);
511 pthread_cond (pthread_condattr *);
514 class pthread_cond * next;
515 static void fixup_after_fork ()
517 conds.fixup_after_fork ();
518 conds.for_each (&pthread_cond::_fixup_after_fork);
522 void _fixup_after_fork ();
524 static List<pthread_cond> conds;
525 static fast_mutex cond_initialization_lock;
528 class pthread_rwlockattr: public verifyable_object
531 static bool is_good_object(pthread_rwlockattr_t const *);
534 pthread_rwlockattr ();
535 ~pthread_rwlockattr ();
538 class pthread_rwlock: public verifyable_object
541 static bool is_good_object (pthread_rwlock_t const *);
542 static bool is_good_initializer (pthread_rwlock_t const *);
543 static bool is_good_initializer_or_object (pthread_rwlock_t const *);
544 static bool is_good_initializer_or_bad_object (pthread_rwlock_t const *);
545 static void init_mutex ();
546 static int init (pthread_rwlock_t *, const pthread_rwlockattr_t *);
550 unsigned long waiting_readers;
551 unsigned long waiting_writers;
555 struct RWLOCK_READER *next;
558 fast_mutex readers_mx;
569 pthread_cond cond_readers;
570 pthread_cond cond_writers;
572 pthread_rwlock (pthread_rwlockattr *);
575 class pthread_rwlock * next;
576 static void fixup_after_fork ()
578 rwlocks.fixup_after_fork ();
579 rwlocks.for_each (&pthread_rwlock::_fixup_after_fork);
583 static List<pthread_rwlock> rwlocks;
585 void add_reader (struct RWLOCK_READER *rd);
586 void remove_reader (struct RWLOCK_READER *rd);
587 struct RWLOCK_READER *lookup_reader (pthread_t thread);
594 cond_writers.unblock (false);
596 else if (waiting_readers)
597 cond_readers.unblock (true);
601 static void rdlock_cleanup (void *arg);
602 static void wrlock_cleanup (void *arg);
604 void _fixup_after_fork ();
606 static fast_mutex rwlock_initialization_lock;
612 pthread_mutex_t mutex;
616 /* shouldn't be here */
617 class semaphore: public verifyable_object
620 static bool is_good_object(sem_t const *);
622 static int init (sem_t * sem, int pshared, unsigned int value);
623 static int destroy (sem_t * sem);
624 static sem_t *open (const char *name, int oflag, mode_t mode,
626 static int wait (sem_t * sem);
627 static int post (sem_t * sem);
628 static int getvalue (sem_t * sem, int *sval);
629 static int trywait (sem_t * sem);
630 static int timedwait (sem_t * sem, const struct timespec *abstime);
637 semaphore (int, unsigned int);
638 semaphore (const char *name, int oflag, mode_t mode, unsigned int value);
641 class semaphore * next;
642 static void fixup_after_fork ()
644 semaphores.fixup_after_fork ();
645 semaphores.for_each (&semaphore::_fixup_after_fork);
651 int _getvalue (int *sval);
653 int _timedwait (const struct timespec *abstime);
655 void _fixup_after_fork ();
657 static List<semaphore> semaphores;
664 class callback * next;
671 long int threadcount;
673 callback *pthread_prepare;
674 callback *pthread_child;
675 callback *pthread_parent;
678 void fixup_before_fork (void);
679 void fixup_after_fork (void);
681 #if 0 // avoid initialization since zero is implied and
683 concurrency (0), threadcount (0),
684 pthread_prepare (NULL), pthread_child (NULL), pthread_parent (NULL)
690 #define MT_INTERFACE user_data->threadinterface
691 #endif // _CYGNUS_THREADS_