1 /* thread.h: Locking and threading module definitions
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007,
4 2008, 2009, 2010 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
39 DWORD
cancelable_wait (HANDLE
, DWORD
, const cw_cancel_action
= cw_cancel_self
,
40 const enum cw_sig_wait
= cw_sig_nosig
)
41 __attribute__ ((regparm (3)));
47 lock_counter (0), win32_obj_id (0)
54 CloseHandle (win32_obj_id
);
60 win32_obj_id
= ::CreateEvent (&sec_none_nih
, false, false, NULL
);
63 debug_printf ("CreateEvent failed. %E");
71 if (InterlockedIncrement ((long *) &lock_counter
) != 1)
72 cancelable_wait (win32_obj_id
, INFINITE
, cw_no_cancel
, cw_sig_resume
);
77 if (InterlockedDecrement ((long *) &lock_counter
))
78 ::SetEvent (win32_obj_id
);
82 unsigned long lock_counter
;
89 #define PTHREAD_MAGIC 0xdf0df045
90 #define PTHREAD_MUTEX_MAGIC PTHREAD_MAGIC+1
91 #define PTHREAD_KEY_MAGIC PTHREAD_MAGIC+2
92 #define PTHREAD_ATTR_MAGIC PTHREAD_MAGIC+3
93 #define PTHREAD_MUTEXATTR_MAGIC PTHREAD_MAGIC+4
94 #define PTHREAD_COND_MAGIC PTHREAD_MAGIC+5
95 #define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6
96 #define SEM_MAGIC PTHREAD_MAGIC+7
97 #define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8
98 #define PTHREAD_RWLOCK_MAGIC PTHREAD_MAGIC+9
99 #define PTHREAD_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
101 #define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
103 typedef unsigned long thread_magic_t
;
105 /* verifyable_object should not be defined here - it's a general purpose class */
107 class verifyable_object
110 thread_magic_t magic
;
112 verifyable_object (thread_magic_t verifyer
): magic (verifyer
) {}
113 virtual ~verifyable_object () { magic
= 0; }
121 } verifyable_object_state
;
123 template <class list_node
> inline void
124 List_insert (list_node
*&head
, list_node
*node
)
130 while (InterlockedCompareExchangePointer (&head
, node
, node
->next
) != node
->next
);
133 template <class list_node
> inline void
134 List_remove (fast_mutex
&mx
, list_node
*&head
, list_node
const *node
)
141 if (InterlockedCompareExchangePointer (&head
, node
->next
, node
) != node
)
143 list_node
*cur
= head
;
145 while (cur
->next
&& node
!= cur
->next
)
147 if (node
== cur
->next
)
148 cur
->next
= cur
->next
->next
;
155 template <class list_node
> class List
167 void fixup_after_fork ()
172 void insert (list_node
*node
)
174 List_insert (head
, node
);
177 void remove (list_node
*node
)
179 List_remove (mx
, head
, node
);
182 void for_each (void (list_node::*callback
) ())
185 list_node
*cur
= head
;
201 api_fatal ("Could not create mutex for list synchronisation.");
205 class pthread_key
: public verifyable_object
209 static bool is_good_object (pthread_key_t
const *);
211 int set (const void *value
) {TlsSetValue (tls_index
, (void *) value
); return 0;}
212 void *get () const {return TlsGetValue (tls_index
);}
214 pthread_key (void (*)(void *));
216 static void fixup_before_fork ()
218 keys
.for_each (&pthread_key::_fixup_before_fork
);
221 static void fixup_after_fork ()
223 keys
.fixup_after_fork ();
224 keys
.for_each (&pthread_key::_fixup_after_fork
);
227 static void run_all_destructors ()
229 keys
.for_each (&pthread_key::run_destructor
);
232 /* List support calls */
233 class pthread_key
*next
;
235 static List
<pthread_key
> keys
;
236 void _fixup_before_fork ();
237 void _fixup_after_fork ();
238 void (*destructor
) (void *);
239 void run_destructor ();
243 class pthread_attr
: public verifyable_object
246 static bool is_good_object(pthread_attr_t
const *);
250 struct sched_param schedparam
;
257 class pthread_mutexattr
: public verifyable_object
260 static bool is_good_object(pthread_mutexattr_t
const *);
263 pthread_mutexattr ();
264 ~pthread_mutexattr ();
267 class pthread_mutex
: public verifyable_object
270 static void init_mutex ();
271 static int init (pthread_mutex_t
*, const pthread_mutexattr_t
*attr
,
272 const pthread_mutex_t
);
273 static bool is_good_object (pthread_mutex_t
const *);
274 static bool is_initializer (pthread_mutex_t
const *);
275 static bool is_initializer_or_object (pthread_mutex_t
const *);
276 static bool is_initializer_or_bad_object (pthread_mutex_t
const *);
282 void set_type (int in_type
) {type
= in_type
;}
284 int lock_recursive ()
286 if (recursion_counter
== UINT_MAX
)
292 bool can_be_unlocked ();
294 pthread_mutex (pthread_mutexattr
* = NULL
);
295 pthread_mutex (pthread_mutex_t
*, pthread_mutexattr
*);
298 class pthread_mutex
*next
;
299 static void fixup_after_fork ()
301 mutexes
.fixup_after_fork ();
302 mutexes
.for_each (&pthread_mutex::_fixup_after_fork
);
306 unsigned long lock_counter
;
308 unsigned int recursion_counter
;
312 DWORD tid
; /* the thread id of the owner */
317 void set_owner (pthread_t self
)
319 recursion_counter
= 1;
322 tid
= GetCurrentThreadId ();
325 static const pthread_t _new_mutex
;
326 static const pthread_t _unlocked_mutex
;
327 static const pthread_t _destroyed_mutex
;
330 void _fixup_after_fork ();
332 static List
<pthread_mutex
> mutexes
;
333 static fast_mutex mutex_initialization_lock
;
334 friend class pthread_cond
;
337 #define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
338 #define WAIT_SIGNALED (WAIT_OBJECT_0 + 2)
341 class pthread
: public verifyable_object
345 class pthread_attr attr
;
346 void *(*function
) (void *);
351 int cancelstate
, canceltype
;
356 virtual bool create (void *(*)(void *), pthread_attr
*, void *);
361 static void init_mainthread ();
362 static bool is_good_object(pthread_t
const *);
363 static void atforkprepare();
364 static void atforkparent();
365 static void atforkchild();
368 static int cancel (pthread_t
);
369 static int join (pthread_t
* thread
, void **return_val
);
370 static int detach (pthread_t
* thread
);
371 static int create (pthread_t
* thread
, const pthread_attr_t
* attr
,
372 void *(*start_routine
) (void *), void *arg
);
373 static int once (pthread_once_t
*, void (*)(void));
374 static int atfork(void (*)(void), void (*)(void), void (*)(void));
375 static int suspend (pthread_t
* thread
);
376 static int resume (pthread_t
* thread
);
378 virtual void exit (void *value_ptr
) __attribute__ ((noreturn
));
380 virtual int cancel ();
382 virtual void testcancel ();
383 static void static_cancel_self ();
385 virtual int setcancelstate (int state
, int *oldstate
);
386 virtual int setcanceltype (int type
, int *oldtype
);
388 virtual void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
389 virtual void pop_cleanup_handler (int const execute
);
391 static pthread
* self ();
392 static DWORD WINAPI
thread_init_wrapper (void *);
394 virtual unsigned long getsequence_np();
396 static int equal (pthread_t t1
, pthread_t t2
)
401 /* List support calls */
403 static void fixup_after_fork ()
405 threads
.fixup_after_fork ();
406 threads
.for_each (&pthread::_fixup_after_fork
);
409 static void suspend_all_except_self ()
411 threads
.for_each (&pthread::suspend_except_self
);
414 static void resume_all ()
416 threads
.for_each (&pthread::resume
);
420 static List
<pthread
> threads
;
422 __pthread_cleanup_handler
*cleanup_stack
;
426 void suspend_except_self ();
429 void _fixup_after_fork ();
431 void pop_all_cleanup_handlers ();
432 void precreate (pthread_attr
*);
434 bool create_cancel_event ();
435 static void set_tls_self_pointer (pthread
*);
437 DWORD
get_thread_id ();
440 class pthread_null
: public pthread
443 static pthread
*get_null_pthread();
446 /* From pthread These should never get called
447 * as the ojbect is not verifyable
449 bool create (void *(*)(void *), pthread_attr
*, void *);
450 void exit (void *value_ptr
) __attribute__ ((noreturn
));
453 int setcancelstate (int state
, int *oldstate
);
454 int setcanceltype (int type
, int *oldtype
);
455 void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
456 void pop_cleanup_handler (int const execute
);
457 unsigned long getsequence_np();
461 static pthread_null _instance
;
464 class pthread_condattr
: public verifyable_object
467 static bool is_good_object(pthread_condattr_t
const *);
471 ~pthread_condattr ();
474 class pthread_cond
: public verifyable_object
477 static bool is_good_object (pthread_cond_t
const *);
478 static bool is_initializer (pthread_cond_t
const *);
479 static bool is_initializer_or_object (pthread_cond_t
const *);
480 static bool is_initializer_or_bad_object (pthread_cond_t
const *);
481 static void init_mutex ();
482 static int init (pthread_cond_t
*, const pthread_condattr_t
*);
486 unsigned long waiting
;
487 unsigned long pending
;
490 pthread_mutex mtx_in
;
491 pthread_mutex mtx_out
;
493 pthread_mutex_t mtx_cond
;
495 void unblock (const bool all
);
496 int wait (pthread_mutex_t mutex
, DWORD dwMilliseconds
= INFINITE
);
498 pthread_cond (pthread_condattr
*);
501 class pthread_cond
* next
;
502 static void fixup_after_fork ()
504 conds
.fixup_after_fork ();
505 conds
.for_each (&pthread_cond::_fixup_after_fork
);
509 void _fixup_after_fork ();
511 static List
<pthread_cond
> conds
;
512 static fast_mutex cond_initialization_lock
;
515 class pthread_rwlockattr
: public verifyable_object
518 static bool is_good_object(pthread_rwlockattr_t
const *);
521 pthread_rwlockattr ();
522 ~pthread_rwlockattr ();
525 class pthread_rwlock
: public verifyable_object
528 static bool is_good_object (pthread_rwlock_t
const *);
529 static bool is_initializer (pthread_rwlock_t
const *);
530 static bool is_initializer_or_object (pthread_rwlock_t
const *);
531 static bool is_initializer_or_bad_object (pthread_rwlock_t
const *);
532 static void init_mutex ();
533 static int init (pthread_rwlock_t
*, const pthread_rwlockattr_t
*);
537 unsigned long waiting_readers
;
538 unsigned long waiting_writers
;
542 struct RWLOCK_READER
*next
;
546 fast_mutex readers_mx
;
557 pthread_cond cond_readers
;
558 pthread_cond cond_writers
;
560 pthread_rwlock (pthread_rwlockattr
*);
563 class pthread_rwlock
* next
;
564 static void fixup_after_fork ()
566 rwlocks
.fixup_after_fork ();
567 rwlocks
.for_each (&pthread_rwlock::_fixup_after_fork
);
571 static List
<pthread_rwlock
> rwlocks
;
573 void add_reader (struct RWLOCK_READER
*rd
);
574 void remove_reader (struct RWLOCK_READER
*rd
);
575 struct RWLOCK_READER
*lookup_reader (pthread_t thread
);
582 cond_writers
.unblock (false);
584 else if (waiting_readers
)
585 cond_readers
.unblock (true);
589 static void rdlock_cleanup (void *arg
);
590 static void wrlock_cleanup (void *arg
);
592 void _fixup_after_fork ();
594 static fast_mutex rwlock_initialization_lock
;
600 pthread_mutex_t mutex
;
604 /* shouldn't be here */
605 class semaphore
: public verifyable_object
608 static bool is_good_object(sem_t
const *);
610 static int init (sem_t
*sem
, int pshared
, unsigned int value
);
611 static int destroy (sem_t
*sem
);
612 static sem_t
*open (unsigned long long hash
, LUID luid
, int fd
, int oflag
,
613 mode_t mode
, unsigned int value
, bool &wasopen
);
614 static int close (sem_t
*sem
);
615 static int wait (sem_t
*sem
);
616 static int post (sem_t
*sem
);
617 static int getvalue (sem_t
*sem
, int *sval
);
618 static int trywait (sem_t
*sem
);
619 static int timedwait (sem_t
*sem
, const struct timespec
*abstime
);
621 static int getinternal (sem_t
*sem
, int *sfd
, unsigned long long *shash
,
622 LUID
*sluid
, unsigned int *sval
);
628 unsigned long long hash
;
632 semaphore (int, unsigned int);
633 semaphore (unsigned long long, LUID
, int, sem_t
*, int, mode_t
, unsigned int);
636 class semaphore
* next
;
637 static void fixup_after_fork ()
639 semaphores
.fixup_after_fork ();
640 semaphores
.for_each (&semaphore::_fixup_after_fork
);
642 static void terminate ()
644 semaphores
.for_each (&semaphore::_terminate
);
650 int _getvalue (int *sval
);
652 int _timedwait (const struct timespec
*abstime
);
654 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 ();
679 void fixup_after_fork ();
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