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
43 void SetResourceLock (int, int, const char *) __attribute__ ((regparm (3)));
44 void ReleaseResourceLock (int, int, const char *)
45 __attribute__ ((regparm (3)));
48 DWORD
cancelable_wait (HANDLE
, DWORD
, const cw_cancel_action
= cw_cancel_self
, const enum cw_sig_wait
= cw_sig_nosig
)
49 __attribute__ ((regparm (3)));
55 lock_counter (0), win32_obj_id (0)
62 CloseHandle (win32_obj_id
);
68 win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
71 debug_printf ("CreateSemaphore failed. %E");
79 if (InterlockedIncrement ((long *) &lock_counter
) != 1)
80 cancelable_wait (win32_obj_id
, INFINITE
, cw_no_cancel
, cw_sig_resume
);
85 if (InterlockedDecrement ((long *) &lock_counter
))
86 ::ReleaseSemaphore (win32_obj_id
, 1, NULL
);
90 unsigned long lock_counter
;
100 LPCRITICAL_SECTION
Lock (int);
104 CRITICAL_SECTION lock
;
108 #define PTHREAD_MAGIC 0xdf0df045
109 #define PTHREAD_MUTEX_MAGIC PTHREAD_MAGIC+1
110 #define PTHREAD_KEY_MAGIC PTHREAD_MAGIC+2
111 #define PTHREAD_ATTR_MAGIC PTHREAD_MAGIC+3
112 #define PTHREAD_MUTEXATTR_MAGIC PTHREAD_MAGIC+4
113 #define PTHREAD_COND_MAGIC PTHREAD_MAGIC+5
114 #define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6
115 #define SEM_MAGIC PTHREAD_MAGIC+7
116 #define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8
117 #define PTHREAD_RWLOCK_MAGIC PTHREAD_MAGIC+9
118 #define PTHREAD_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
120 #define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
122 /* verifyable_object should not be defined here - it's a general purpose class */
124 class verifyable_object
129 verifyable_object (long);
130 virtual ~verifyable_object ();
138 } verifyable_object_state
;
140 verifyable_object_state
verifyable_object_isvalid (void const * objectptr
, long magic
,
141 void *static_ptr1
= NULL
,
142 void *static_ptr2
= NULL
,
143 void *static_ptr3
= NULL
);
145 template <class list_node
> inline void
146 List_insert (list_node
*&head
, list_node
*node
)
152 while (InterlockedCompareExchangePointer (&head
, node
, node
->next
) != node
->next
);
155 template <class list_node
> inline void
156 List_remove (fast_mutex
&mx
, list_node
*&head
, list_node
const *node
)
163 if (InterlockedCompareExchangePointer (&head
, node
->next
, node
) != node
)
165 list_node
*cur
= head
;
167 while (cur
->next
&& node
!= cur
->next
)
169 if (node
== cur
->next
)
170 cur
->next
= cur
->next
->next
;
177 template <class list_node
> class List
189 void fixup_after_fork ()
194 void insert (list_node
*node
)
196 List_insert (head
, node
);
199 void remove (list_node
*node
)
201 List_remove (mx
, head
, node
);
204 void for_each (void (list_node::*callback
) ())
207 list_node
*cur
= head
;
220 api_fatal ("Could not create mutex for list synchronisation.");
227 class pthread_key
: public verifyable_object
231 static bool is_good_object (pthread_key_t
const *);
233 int set (const void *value
) {TlsSetValue (tls_index
, (void *) value
); return 0;}
234 void *get () const {return TlsGetValue (tls_index
);}
236 pthread_key (void (*)(void *));
238 static void fixup_before_fork ()
240 keys
.for_each (&pthread_key::_fixup_before_fork
);
243 static void fixup_after_fork ()
245 keys
.fixup_after_fork ();
246 keys
.for_each (&pthread_key::_fixup_after_fork
);
249 static void run_all_destructors ()
251 keys
.for_each (&pthread_key::run_destructor
);
254 /* List support calls */
255 class pthread_key
*next
;
257 static List
<pthread_key
> keys
;
258 void _fixup_before_fork ();
259 void _fixup_after_fork ();
260 void (*destructor
) (void *);
261 void run_destructor ();
265 class pthread_attr
: public verifyable_object
268 static bool is_good_object(pthread_attr_t
const *);
272 struct sched_param schedparam
;
279 class pthread_mutexattr
: public verifyable_object
282 static bool is_good_object(pthread_mutexattr_t
const *);
285 pthread_mutexattr ();
286 ~pthread_mutexattr ();
289 class pthread_mutex
: public verifyable_object
292 static bool is_good_object (pthread_mutex_t
const *);
293 static bool is_good_initializer (pthread_mutex_t
const *);
294 static bool is_good_initializer_or_object (pthread_mutex_t
const *);
295 static bool is_good_initializer_or_bad_object (pthread_mutex_t
const *mutex
);
296 static bool can_be_unlocked (pthread_mutex_t
const *mutex
);
297 static void init_mutex ();
298 static int init (pthread_mutex_t
*mutex
, const pthread_mutexattr_t
*attr
,
299 const pthread_mutex_t initializer
= NULL
);
301 unsigned long lock_counter
;
303 unsigned int recursion_counter
;
309 pthread_t
get_pthread_self () const
311 return PTHREAD_MUTEX_NORMAL
== type
? MUTEX_OWNER_ANONYMOUS
:
317 return _lock (get_pthread_self ());
321 return _trylock (get_pthread_self ());
325 return _unlock (get_pthread_self ());
329 return _destroy (get_pthread_self ());
332 void set_owner (pthread_t self
)
334 recursion_counter
= 1;
338 int lock_recursive ()
340 if (UINT_MAX
== recursion_counter
)
346 pthread_mutex (pthread_mutexattr
* = NULL
);
347 pthread_mutex (pthread_mutex_t
*, pthread_mutexattr
*);
350 class pthread_mutex
* next
;
351 static void fixup_after_fork ()
353 mutexes
.fixup_after_fork ();
354 mutexes
.for_each (&pthread_mutex::_fixup_after_fork
);
358 int _lock (pthread_t self
);
359 int _trylock (pthread_t self
);
360 int _unlock (pthread_t self
);
361 int _destroy (pthread_t self
);
363 void _fixup_after_fork ();
365 static List
<pthread_mutex
> mutexes
;
366 static fast_mutex mutex_initialization_lock
;
369 #define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
370 #define WAIT_SIGNALED (WAIT_OBJECT_0 + 2)
373 class pthread
: public verifyable_object
377 class pthread_attr attr
;
378 void *(*function
) (void *);
383 int cancelstate
, canceltype
;
388 virtual void create (void *(*)(void *), pthread_attr
*, void *);
393 static void init_mainthread ();
394 static bool is_good_object(pthread_t
const *);
395 static void atforkprepare();
396 static void atforkparent();
397 static void atforkchild();
400 static int cancel (pthread_t
);
401 static int join (pthread_t
* thread
, void **return_val
);
402 static int detach (pthread_t
* thread
);
403 static int create (pthread_t
* thread
, const pthread_attr_t
* attr
,
404 void *(*start_routine
) (void *), void *arg
);
405 static int once (pthread_once_t
*, void (*)(void));
406 static int atfork(void (*)(void), void (*)(void), void (*)(void));
407 static int suspend (pthread_t
* thread
);
408 static int resume (pthread_t
* thread
);
410 virtual void exit (void *value_ptr
) __attribute__ ((noreturn
));
412 virtual int cancel ();
414 virtual void testcancel ();
415 static void static_cancel_self ();
417 virtual int setcancelstate (int state
, int *oldstate
);
418 virtual int setcanceltype (int type
, int *oldtype
);
420 virtual void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
421 virtual void pop_cleanup_handler (int const execute
);
423 static pthread
* self ();
424 static DWORD WINAPI
thread_init_wrapper (void *);
426 virtual unsigned long getsequence_np();
428 static int equal (pthread_t t1
, pthread_t t2
)
433 /* List support calls */
435 static void fixup_after_fork ()
437 threads
.fixup_after_fork ();
438 threads
.for_each (&pthread::_fixup_after_fork
);
441 static void suspend_all_except_self ()
443 threads
.for_each (&pthread::suspend_except_self
);
446 static void resume_all ()
448 threads
.for_each (&pthread::resume
);
452 static List
<pthread
> threads
;
454 __pthread_cleanup_handler
*cleanup_stack
;
457 void suspend_except_self ();
460 void _fixup_after_fork ();
462 void pop_all_cleanup_handlers (void);
463 void precreate (pthread_attr
*);
465 bool create_cancel_event ();
466 static pthread
*get_tls_self_pointer ();
467 static void set_tls_self_pointer (pthread
*);
469 DWORD
get_thread_id ();
472 class pthread_null
: public pthread
475 static pthread
*get_null_pthread();
478 /* From pthread These should never get called
479 * as the ojbect is not verifyable
481 void create (void *(*)(void *), pthread_attr
*, void *);
482 void exit (void *value_ptr
) __attribute__ ((noreturn
));
485 int setcancelstate (int state
, int *oldstate
);
486 int setcanceltype (int type
, int *oldtype
);
487 void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
488 void pop_cleanup_handler (int const execute
);
489 unsigned long getsequence_np();
493 static pthread_null _instance
;
496 class pthread_condattr
: public verifyable_object
499 static bool is_good_object(pthread_condattr_t
const *);
503 ~pthread_condattr ();
506 class pthread_cond
: public verifyable_object
509 static bool is_good_object (pthread_cond_t
const *);
510 static bool is_good_initializer (pthread_cond_t
const *);
511 static bool is_good_initializer_or_object (pthread_cond_t
const *);
512 static bool is_good_initializer_or_bad_object (pthread_cond_t
const *);
513 static void init_mutex ();
514 static int init (pthread_cond_t
*, const pthread_condattr_t
*);
518 unsigned long waiting
;
519 unsigned long pending
;
522 pthread_mutex mtx_in
;
523 pthread_mutex mtx_out
;
525 pthread_mutex_t mtx_cond
;
527 void unblock (const bool all
);
528 int wait (pthread_mutex_t mutex
, DWORD dwMilliseconds
= INFINITE
);
530 pthread_cond (pthread_condattr
*);
533 class pthread_cond
* next
;
534 static void fixup_after_fork ()
536 conds
.fixup_after_fork ();
537 conds
.for_each (&pthread_cond::_fixup_after_fork
);
541 void _fixup_after_fork ();
543 static List
<pthread_cond
> conds
;
544 static fast_mutex cond_initialization_lock
;
547 class pthread_rwlockattr
: public verifyable_object
550 static bool is_good_object(pthread_rwlockattr_t
const *);
553 pthread_rwlockattr ();
554 ~pthread_rwlockattr ();
557 class pthread_rwlock
: public verifyable_object
560 static bool is_good_object (pthread_rwlock_t
const *);
561 static bool is_good_initializer (pthread_rwlock_t
const *);
562 static bool is_good_initializer_or_object (pthread_rwlock_t
const *);
563 static bool is_good_initializer_or_bad_object (pthread_rwlock_t
const *);
564 static void init_mutex ();
565 static int init (pthread_rwlock_t
*, const pthread_rwlockattr_t
*);
569 unsigned long waiting_readers
;
570 unsigned long waiting_writers
;
574 struct RWLOCK_READER
*next
;
577 fast_mutex readers_mx
;
588 pthread_cond cond_readers
;
589 pthread_cond cond_writers
;
591 pthread_rwlock (pthread_rwlockattr
*);
594 class pthread_rwlock
* next
;
595 static void fixup_after_fork ()
597 rwlocks
.fixup_after_fork ();
598 rwlocks
.for_each (&pthread_rwlock::_fixup_after_fork
);
602 static List
<pthread_rwlock
> rwlocks
;
604 void add_reader (struct RWLOCK_READER
*rd
);
605 void remove_reader (struct RWLOCK_READER
*rd
);
606 struct RWLOCK_READER
*lookup_reader (pthread_t thread
);
613 cond_writers
.unblock (false);
615 else if (waiting_readers
)
616 cond_readers
.unblock (true);
620 static void rdlock_cleanup (void *arg
);
621 static void wrlock_cleanup (void *arg
);
623 void _fixup_after_fork ();
625 static fast_mutex rwlock_initialization_lock
;
631 pthread_mutex_t mutex
;
635 /* shouldn't be here */
636 class semaphore
: public verifyable_object
639 static bool is_good_object(sem_t
const *);
641 static int init (sem_t
* sem
, int pshared
, unsigned int value
);
642 static int destroy (sem_t
* sem
);
643 static sem_t
*open (const char *name
, int oflag
, mode_t mode
,
645 static int wait (sem_t
* sem
);
646 static int post (sem_t
* sem
);
647 static int getvalue (sem_t
* sem
, int *sval
);
648 static int trywait (sem_t
* sem
);
649 static int timedwait (sem_t
* sem
, const struct timespec
*abstime
);
656 semaphore (int, unsigned int);
657 semaphore (const char *name
, int oflag
, mode_t mode
, unsigned int value
);
660 class semaphore
* next
;
661 static void fixup_after_fork ()
663 semaphores
.fixup_after_fork ();
664 semaphores
.for_each (&semaphore::_fixup_after_fork
);
670 int _getvalue (int *sval
);
672 int _timedwait (const struct timespec
*abstime
);
674 void _fixup_after_fork ();
676 static List
<semaphore
> semaphores
;
683 class callback
* next
;
690 long int threadcount
;
692 callback
*pthread_prepare
;
693 callback
*pthread_child
;
694 callback
*pthread_parent
;
697 void fixup_before_fork (void);
698 void fixup_after_fork (void);
700 #if 0 // avoid initialization since zero is implied and
702 concurrency (0), threadcount (0),
703 pthread_prepare (NULL
), pthread_child (NULL
), pthread_parent (NULL
)
709 #define MT_INTERFACE user_data->threadinterface
710 #endif // _CYGNUS_THREADS_