1 /* thread.h: Locking and threading module definitions
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007,
4 2008, 2009, 2010, 2011 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
15 #define LOCK_MMAP_LIST 1
40 DWORD
cancelable_wait (HANDLE
, DWORD
, const cw_cancel_action
= cw_cancel_self
,
41 const enum cw_sig_wait
= cw_sig_nosig
)
42 __attribute__ ((regparm (3)));
48 lock_counter (0), win32_obj_id (0)
55 CloseHandle (win32_obj_id
);
61 win32_obj_id
= ::CreateEvent (&sec_none_nih
, false, false, NULL
);
64 debug_printf ("CreateEvent failed. %E");
72 if (InterlockedIncrement ((long *) &lock_counter
) != 1)
73 cancelable_wait (win32_obj_id
, INFINITE
, cw_no_cancel
, cw_sig_resume
);
78 if (InterlockedDecrement ((long *) &lock_counter
))
79 ::SetEvent (win32_obj_id
);
83 unsigned long lock_counter
;
90 #define PTHREAD_MAGIC 0xdf0df045
91 #define PTHREAD_MUTEX_MAGIC PTHREAD_MAGIC+1
92 #define PTHREAD_KEY_MAGIC PTHREAD_MAGIC+2
93 #define PTHREAD_ATTR_MAGIC PTHREAD_MAGIC+3
94 #define PTHREAD_MUTEXATTR_MAGIC PTHREAD_MAGIC+4
95 #define PTHREAD_COND_MAGIC PTHREAD_MAGIC+5
96 #define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6
97 #define SEM_MAGIC PTHREAD_MAGIC+7
98 #define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8
99 #define PTHREAD_RWLOCK_MAGIC PTHREAD_MAGIC+9
100 #define PTHREAD_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
101 #define PTHREAD_SPINLOCK_MAGIC PTHREAD_MAGIC+11
103 #define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
105 typedef unsigned long thread_magic_t
;
107 /* verifyable_object should not be defined here - it's a general purpose class */
109 class verifyable_object
112 thread_magic_t magic
;
114 verifyable_object (thread_magic_t verifyer
): magic (verifyer
) {}
115 virtual ~verifyable_object () { magic
= 0; }
123 } verifyable_object_state
;
125 template <class list_node
> inline void
126 List_insert (list_node
*&head
, list_node
*node
)
132 while (InterlockedCompareExchangePointer (&head
, node
, node
->next
) != node
->next
);
135 template <class list_node
> inline void
136 List_remove (fast_mutex
&mx
, list_node
*&head
, list_node
const *node
)
143 if (InterlockedCompareExchangePointer (&head
, node
->next
, node
) != node
)
145 list_node
*cur
= head
;
147 while (cur
->next
&& node
!= cur
->next
)
149 if (node
== cur
->next
)
150 cur
->next
= cur
->next
->next
;
157 template <class list_node
> class List
169 void fixup_after_fork ()
174 void insert (list_node
*node
)
176 List_insert (head
, node
);
179 void remove (list_node
*node
)
181 List_remove (mx
, head
, node
);
184 void for_each (void (list_node::*callback
) ())
187 list_node
*cur
= head
;
203 api_fatal ("Could not create mutex for list synchronisation.");
207 class pthread_key
: public verifyable_object
211 static bool is_good_object (pthread_key_t
const *);
213 int set (const void *value
) {TlsSetValue (tls_index
, (void *) value
); return 0;}
214 void *get () const {return TlsGetValue (tls_index
);}
216 pthread_key (void (*)(void *));
218 static void fixup_before_fork ()
220 keys
.for_each (&pthread_key::_fixup_before_fork
);
223 static void fixup_after_fork ()
225 keys
.fixup_after_fork ();
226 keys
.for_each (&pthread_key::_fixup_after_fork
);
229 static void run_all_destructors ()
231 keys
.for_each (&pthread_key::run_destructor
);
234 /* List support calls */
235 class pthread_key
*next
;
237 static List
<pthread_key
> keys
;
238 void _fixup_before_fork ();
239 void _fixup_after_fork ();
240 void (*destructor
) (void *);
241 void run_destructor ();
245 class pthread_attr
: public verifyable_object
248 static bool is_good_object(pthread_attr_t
const *);
252 struct sched_param schedparam
;
259 class pthread_mutexattr
: public verifyable_object
262 static bool is_good_object(pthread_mutexattr_t
const *);
265 pthread_mutexattr ();
266 ~pthread_mutexattr ();
269 class pthread_mutex
: public verifyable_object
272 static void init_mutex ();
273 static int init (pthread_mutex_t
*, const pthread_mutexattr_t
*attr
,
274 const pthread_mutex_t
);
275 static bool is_good_object (pthread_mutex_t
const *);
276 static bool is_initializer (pthread_mutex_t
const *);
277 static bool is_initializer_or_object (pthread_mutex_t
const *);
278 static bool is_initializer_or_bad_object (pthread_mutex_t
const *);
284 void set_type (int in_type
) {type
= in_type
;}
286 int lock_recursive ()
288 if (recursion_counter
== UINT_MAX
)
294 bool can_be_unlocked ();
296 pthread_mutex (pthread_mutexattr
* = NULL
);
297 pthread_mutex (pthread_mutex_t
*, pthread_mutexattr
*);
300 class pthread_mutex
*next
;
301 static void fixup_after_fork ()
303 mutexes
.fixup_after_fork ();
304 mutexes
.for_each (&pthread_mutex::_fixup_after_fork
);
308 unsigned long lock_counter
;
312 DWORD tid
; /* the thread id of the owner */
315 void set_shared (int in_shared
) { pshared
= in_shared
; }
316 void set_owner (pthread_t self
)
318 recursion_counter
= 1;
321 tid
= GetCurrentThreadId ();
325 static const pthread_t _new_mutex
;
326 static const pthread_t _unlocked_mutex
;
327 static const pthread_t _destroyed_mutex
;
330 unsigned int recursion_counter
;
336 void _fixup_after_fork ();
338 static List
<pthread_mutex
> mutexes
;
339 static fast_mutex mutex_initialization_lock
;
340 friend class pthread_cond
;
343 class pthread_spinlock
: public pthread_mutex
346 static bool is_good_object (pthread_spinlock_t
const *);
347 static int init (pthread_spinlock_t
*, int);
352 pthread_spinlock (int);
355 #define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
356 #define WAIT_SIGNALED (WAIT_OBJECT_0 + 2)
359 class pthread
: public verifyable_object
363 class pthread_attr attr
;
364 void *(*function
) (void *);
370 int cancelstate
, canceltype
;
375 virtual bool create (void *(*)(void *), pthread_attr
*, void *);
380 static void init_mainthread ();
381 static bool is_good_object(pthread_t
const *);
382 static void atforkprepare();
383 static void atforkparent();
384 static void atforkchild();
387 static int cancel (pthread_t
);
388 static int join (pthread_t
* thread
, void **return_val
);
389 static int detach (pthread_t
* thread
);
390 static int create (pthread_t
* thread
, const pthread_attr_t
* attr
,
391 void *(*start_routine
) (void *), void *arg
);
392 static int once (pthread_once_t
*, void (*)(void));
393 static int atfork(void (*)(void), void (*)(void), void (*)(void));
394 static int suspend (pthread_t
* thread
);
395 static int resume (pthread_t
* thread
);
397 virtual void exit (void *value_ptr
) __attribute__ ((noreturn
));
399 virtual int cancel ();
401 virtual void testcancel ();
402 static HANDLE
get_cancel_event ();
403 static void static_cancel_self ();
405 virtual int setcancelstate (int state
, int *oldstate
);
406 virtual int setcanceltype (int type
, int *oldtype
);
408 virtual void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
409 virtual void pop_cleanup_handler (int const execute
);
411 static pthread
* self ();
412 static DWORD WINAPI
thread_init_wrapper (void *);
414 virtual unsigned long getsequence_np();
416 static int equal (pthread_t t1
, pthread_t t2
)
421 /* List support calls */
423 static void fixup_after_fork ()
425 threads
.fixup_after_fork ();
426 threads
.for_each (&pthread::_fixup_after_fork
);
429 static void suspend_all_except_self ()
431 threads
.for_each (&pthread::suspend_except_self
);
434 static void resume_all ()
436 threads
.for_each (&pthread::resume
);
440 static List
<pthread
> threads
;
442 __pthread_cleanup_handler
*cleanup_stack
;
446 void suspend_except_self ();
449 void _fixup_after_fork ();
451 void pop_all_cleanup_handlers ();
452 void precreate (pthread_attr
*);
454 bool create_cancel_event ();
455 static void set_tls_self_pointer (pthread
*);
457 DWORD
get_thread_id ();
460 class pthread_null
: public pthread
463 static pthread
*get_null_pthread();
466 /* From pthread These should never get called
467 * as the ojbect is not verifyable
469 bool create (void *(*)(void *), pthread_attr
*, void *);
470 void exit (void *value_ptr
) __attribute__ ((noreturn
));
473 int setcancelstate (int state
, int *oldstate
);
474 int setcanceltype (int type
, int *oldtype
);
475 void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
476 void pop_cleanup_handler (int const execute
);
477 unsigned long getsequence_np();
481 static pthread_null _instance
;
484 class pthread_condattr
: public verifyable_object
487 static bool is_good_object(pthread_condattr_t
const *);
491 ~pthread_condattr ();
494 class pthread_cond
: public verifyable_object
497 static bool is_good_object (pthread_cond_t
const *);
498 static bool is_initializer (pthread_cond_t
const *);
499 static bool is_initializer_or_object (pthread_cond_t
const *);
500 static bool is_initializer_or_bad_object (pthread_cond_t
const *);
501 static void init_mutex ();
502 static int init (pthread_cond_t
*, const pthread_condattr_t
*);
506 unsigned long waiting
;
507 unsigned long pending
;
510 pthread_mutex mtx_in
;
511 pthread_mutex mtx_out
;
513 pthread_mutex_t mtx_cond
;
515 void unblock (const bool all
);
516 int wait (pthread_mutex_t mutex
, DWORD dwMilliseconds
= INFINITE
);
518 pthread_cond (pthread_condattr
*);
521 class pthread_cond
* next
;
522 static void fixup_after_fork ()
524 conds
.fixup_after_fork ();
525 conds
.for_each (&pthread_cond::_fixup_after_fork
);
529 void _fixup_after_fork ();
531 static List
<pthread_cond
> conds
;
532 static fast_mutex cond_initialization_lock
;
535 class pthread_rwlockattr
: public verifyable_object
538 static bool is_good_object(pthread_rwlockattr_t
const *);
541 pthread_rwlockattr ();
542 ~pthread_rwlockattr ();
545 class pthread_rwlock
: public verifyable_object
548 static bool is_good_object (pthread_rwlock_t
const *);
549 static bool is_initializer (pthread_rwlock_t
const *);
550 static bool is_initializer_or_object (pthread_rwlock_t
const *);
551 static bool is_initializer_or_bad_object (pthread_rwlock_t
const *);
552 static void init_mutex ();
553 static int init (pthread_rwlock_t
*, const pthread_rwlockattr_t
*);
557 unsigned long waiting_readers
;
558 unsigned long waiting_writers
;
562 struct RWLOCK_READER
*next
;
566 fast_mutex readers_mx
;
577 pthread_cond cond_readers
;
578 pthread_cond cond_writers
;
580 pthread_rwlock (pthread_rwlockattr
*);
583 class pthread_rwlock
* next
;
584 static void fixup_after_fork ()
586 rwlocks
.fixup_after_fork ();
587 rwlocks
.for_each (&pthread_rwlock::_fixup_after_fork
);
591 static List
<pthread_rwlock
> rwlocks
;
593 void add_reader (struct RWLOCK_READER
*rd
);
594 void remove_reader (struct RWLOCK_READER
*rd
);
595 struct RWLOCK_READER
*lookup_reader (pthread_t thread
);
602 cond_writers
.unblock (false);
604 else if (waiting_readers
)
605 cond_readers
.unblock (true);
609 static void rdlock_cleanup (void *arg
);
610 static void wrlock_cleanup (void *arg
);
612 void _fixup_after_fork ();
614 static fast_mutex rwlock_initialization_lock
;
620 pthread_mutex_t mutex
;
624 /* shouldn't be here */
625 class semaphore
: public verifyable_object
628 static bool is_good_object(sem_t
const *);
630 static int init (sem_t
*sem
, int pshared
, unsigned int value
);
631 static int destroy (sem_t
*sem
);
632 static sem_t
*open (unsigned long long hash
, LUID luid
, int fd
, int oflag
,
633 mode_t mode
, unsigned int value
, bool &wasopen
);
634 static int close (sem_t
*sem
);
635 static int wait (sem_t
*sem
);
636 static int post (sem_t
*sem
);
637 static int getvalue (sem_t
*sem
, int *sval
);
638 static int trywait (sem_t
*sem
);
639 static int timedwait (sem_t
*sem
, const struct timespec
*abstime
);
641 static int getinternal (sem_t
*sem
, int *sfd
, unsigned long long *shash
,
642 LUID
*sluid
, unsigned int *sval
);
648 unsigned long long hash
;
652 semaphore (int, unsigned int);
653 semaphore (unsigned long long, LUID
, int, sem_t
*, int, mode_t
, unsigned int);
656 class semaphore
* next
;
657 static void fixup_after_fork ()
659 semaphores
.fixup_after_fork ();
660 semaphores
.for_each (&semaphore::_fixup_after_fork
);
662 static void terminate ()
665 semaphores
.for_each (&semaphore::_terminate
);
671 int _getvalue (int *sval
);
673 int _timedwait (const struct timespec
*abstime
);
675 void _fixup_after_fork ();
678 static List
<semaphore
> semaphores
;
685 class callback
* next
;
692 long int threadcount
;
694 callback
*pthread_prepare
;
695 callback
*pthread_child
;
696 callback
*pthread_parent
;
699 void fixup_before_fork ();
700 void fixup_after_fork ();
702 #if 0 // avoid initialization since zero is implied and
704 concurrency (0), threadcount (0),
705 pthread_prepare (NULL
), pthread_child (NULL
), pthread_parent (NULL
)
711 #define MT_INTERFACE user_data->threadinterface