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 void static_cancel_self ();
404 virtual int setcancelstate (int state
, int *oldstate
);
405 virtual int setcanceltype (int type
, int *oldtype
);
407 virtual void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
408 virtual void pop_cleanup_handler (int const execute
);
410 static pthread
* self ();
411 static DWORD WINAPI
thread_init_wrapper (void *);
413 virtual unsigned long getsequence_np();
415 static int equal (pthread_t t1
, pthread_t t2
)
420 /* List support calls */
422 static void fixup_after_fork ()
424 threads
.fixup_after_fork ();
425 threads
.for_each (&pthread::_fixup_after_fork
);
428 static void suspend_all_except_self ()
430 threads
.for_each (&pthread::suspend_except_self
);
433 static void resume_all ()
435 threads
.for_each (&pthread::resume
);
439 static List
<pthread
> threads
;
441 __pthread_cleanup_handler
*cleanup_stack
;
445 void suspend_except_self ();
448 void _fixup_after_fork ();
450 void pop_all_cleanup_handlers ();
451 void precreate (pthread_attr
*);
453 bool create_cancel_event ();
454 static void set_tls_self_pointer (pthread
*);
456 DWORD
get_thread_id ();
459 class pthread_null
: public pthread
462 static pthread
*get_null_pthread();
465 /* From pthread These should never get called
466 * as the ojbect is not verifyable
468 bool create (void *(*)(void *), pthread_attr
*, void *);
469 void exit (void *value_ptr
) __attribute__ ((noreturn
));
472 int setcancelstate (int state
, int *oldstate
);
473 int setcanceltype (int type
, int *oldtype
);
474 void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
475 void pop_cleanup_handler (int const execute
);
476 unsigned long getsequence_np();
480 static pthread_null _instance
;
483 class pthread_condattr
: public verifyable_object
486 static bool is_good_object(pthread_condattr_t
const *);
490 ~pthread_condattr ();
493 class pthread_cond
: public verifyable_object
496 static bool is_good_object (pthread_cond_t
const *);
497 static bool is_initializer (pthread_cond_t
const *);
498 static bool is_initializer_or_object (pthread_cond_t
const *);
499 static bool is_initializer_or_bad_object (pthread_cond_t
const *);
500 static void init_mutex ();
501 static int init (pthread_cond_t
*, const pthread_condattr_t
*);
505 unsigned long waiting
;
506 unsigned long pending
;
509 pthread_mutex mtx_in
;
510 pthread_mutex mtx_out
;
512 pthread_mutex_t mtx_cond
;
514 void unblock (const bool all
);
515 int wait (pthread_mutex_t mutex
, DWORD dwMilliseconds
= INFINITE
);
517 pthread_cond (pthread_condattr
*);
520 class pthread_cond
* next
;
521 static void fixup_after_fork ()
523 conds
.fixup_after_fork ();
524 conds
.for_each (&pthread_cond::_fixup_after_fork
);
528 void _fixup_after_fork ();
530 static List
<pthread_cond
> conds
;
531 static fast_mutex cond_initialization_lock
;
534 class pthread_rwlockattr
: public verifyable_object
537 static bool is_good_object(pthread_rwlockattr_t
const *);
540 pthread_rwlockattr ();
541 ~pthread_rwlockattr ();
544 class pthread_rwlock
: public verifyable_object
547 static bool is_good_object (pthread_rwlock_t
const *);
548 static bool is_initializer (pthread_rwlock_t
const *);
549 static bool is_initializer_or_object (pthread_rwlock_t
const *);
550 static bool is_initializer_or_bad_object (pthread_rwlock_t
const *);
551 static void init_mutex ();
552 static int init (pthread_rwlock_t
*, const pthread_rwlockattr_t
*);
556 unsigned long waiting_readers
;
557 unsigned long waiting_writers
;
561 struct RWLOCK_READER
*next
;
565 fast_mutex readers_mx
;
576 pthread_cond cond_readers
;
577 pthread_cond cond_writers
;
579 pthread_rwlock (pthread_rwlockattr
*);
582 class pthread_rwlock
* next
;
583 static void fixup_after_fork ()
585 rwlocks
.fixup_after_fork ();
586 rwlocks
.for_each (&pthread_rwlock::_fixup_after_fork
);
590 static List
<pthread_rwlock
> rwlocks
;
592 void add_reader (struct RWLOCK_READER
*rd
);
593 void remove_reader (struct RWLOCK_READER
*rd
);
594 struct RWLOCK_READER
*lookup_reader (pthread_t thread
);
601 cond_writers
.unblock (false);
603 else if (waiting_readers
)
604 cond_readers
.unblock (true);
608 static void rdlock_cleanup (void *arg
);
609 static void wrlock_cleanup (void *arg
);
611 void _fixup_after_fork ();
613 static fast_mutex rwlock_initialization_lock
;
619 pthread_mutex_t mutex
;
623 /* shouldn't be here */
624 class semaphore
: public verifyable_object
627 static bool is_good_object(sem_t
const *);
629 static int init (sem_t
*sem
, int pshared
, unsigned int value
);
630 static int destroy (sem_t
*sem
);
631 static sem_t
*open (unsigned long long hash
, LUID luid
, int fd
, int oflag
,
632 mode_t mode
, unsigned int value
, bool &wasopen
);
633 static int close (sem_t
*sem
);
634 static int wait (sem_t
*sem
);
635 static int post (sem_t
*sem
);
636 static int getvalue (sem_t
*sem
, int *sval
);
637 static int trywait (sem_t
*sem
);
638 static int timedwait (sem_t
*sem
, const struct timespec
*abstime
);
640 static int getinternal (sem_t
*sem
, int *sfd
, unsigned long long *shash
,
641 LUID
*sluid
, unsigned int *sval
);
647 unsigned long long hash
;
651 semaphore (int, unsigned int);
652 semaphore (unsigned long long, LUID
, int, sem_t
*, int, mode_t
, unsigned int);
655 class semaphore
* next
;
656 static void fixup_after_fork ()
658 semaphores
.fixup_after_fork ();
659 semaphores
.for_each (&semaphore::_fixup_after_fork
);
661 static void terminate ()
664 semaphores
.for_each (&semaphore::_terminate
);
670 int _getvalue (int *sval
);
672 int _timedwait (const struct timespec
*abstime
);
674 void _fixup_after_fork ();
677 static List
<semaphore
> semaphores
;
684 class callback
* next
;
691 long int threadcount
;
693 callback
*pthread_prepare
;
694 callback
*pthread_child
;
695 callback
*pthread_parent
;
698 void fixup_before_fork ();
699 void fixup_after_fork ();
701 #if 0 // avoid initialization since zero is implied and
703 concurrency (0), threadcount (0),
704 pthread_prepare (NULL
), pthread_child (NULL
), pthread_parent (NULL
)
710 #define MT_INTERFACE user_data->threadinterface