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
;
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 void init_mutex ();
274 static int init (pthread_mutex_t
*, const pthread_mutexattr_t
*attr
,
275 const pthread_mutex_t
);
276 static bool is_good_object (pthread_mutex_t
const *);
277 static bool is_initializer (pthread_mutex_t
const *);
278 static bool is_initializer_or_object (pthread_mutex_t
const *);
279 static bool is_initializer_or_bad_object (pthread_mutex_t
const *);
285 void set_type (int in_type
) {type
= in_type
;}
287 int lock_recursive ()
289 if (recursion_counter
== UINT_MAX
)
295 bool can_be_unlocked ();
297 pthread_mutex (pthread_mutexattr
* = NULL
);
298 pthread_mutex (pthread_mutex_t
*, pthread_mutexattr
*);
301 class pthread_mutex
*next
;
302 static void fixup_after_fork ()
304 mutexes
.fixup_after_fork ();
305 mutexes
.for_each (&pthread_mutex::_fixup_after_fork
);
309 unsigned long lock_counter
;
313 DWORD tid
; /* the thread id of the owner */
316 void set_shared (int in_shared
) { pshared
= in_shared
; }
317 void set_owner (pthread_t self
)
319 recursion_counter
= 1;
322 tid
= GetCurrentThreadId ();
326 static const pthread_t _new_mutex
;
327 static const pthread_t _unlocked_mutex
;
328 static const pthread_t _destroyed_mutex
;
331 unsigned int recursion_counter
;
337 void _fixup_after_fork ();
339 static List
<pthread_mutex
> mutexes
;
340 static fast_mutex mutex_initialization_lock
;
341 friend class pthread_cond
;
344 class pthread_spinlock
: public pthread_mutex
347 static bool is_good_object (pthread_spinlock_t
const *);
348 static int init (pthread_spinlock_t
*, int);
353 pthread_spinlock (int);
356 #define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
357 #define WAIT_SIGNALED (WAIT_OBJECT_0 + 2)
360 class pthread
: public verifyable_object
364 class pthread_attr attr
;
365 void *(*function
) (void *);
371 int cancelstate
, canceltype
;
376 virtual bool create (void *(*)(void *), pthread_attr
*, void *);
381 static void init_mainthread ();
382 static bool is_good_object(pthread_t
const *);
383 static void atforkprepare();
384 static void atforkparent();
385 static void atforkchild();
388 static int cancel (pthread_t
);
389 static int join (pthread_t
* thread
, void **return_val
);
390 static int detach (pthread_t
* thread
);
391 static int create (pthread_t
* thread
, const pthread_attr_t
* attr
,
392 void *(*start_routine
) (void *), void *arg
);
393 static int once (pthread_once_t
*, void (*)(void));
394 static int atfork(void (*)(void), void (*)(void), void (*)(void));
395 static int suspend (pthread_t
* thread
);
396 static int resume (pthread_t
* thread
);
398 virtual void exit (void *value_ptr
) __attribute__ ((noreturn
));
400 virtual int cancel ();
402 virtual void testcancel ();
403 static HANDLE
get_cancel_event ();
404 static void static_cancel_self ();
406 virtual int setcancelstate (int state
, int *oldstate
);
407 virtual int setcanceltype (int type
, int *oldtype
);
409 virtual void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
410 virtual void pop_cleanup_handler (int const execute
);
412 static pthread
* self ();
413 static DWORD WINAPI
thread_init_wrapper (void *);
415 virtual unsigned long getsequence_np();
417 static int equal (pthread_t t1
, pthread_t t2
)
422 /* List support calls */
424 static void fixup_after_fork ()
426 threads
.fixup_after_fork ();
427 threads
.for_each (&pthread::_fixup_after_fork
);
430 static void suspend_all_except_self ()
432 threads
.for_each (&pthread::suspend_except_self
);
435 static void resume_all ()
437 threads
.for_each (&pthread::resume
);
441 static List
<pthread
> threads
;
443 __pthread_cleanup_handler
*cleanup_stack
;
447 void suspend_except_self ();
450 void _fixup_after_fork ();
452 void pop_all_cleanup_handlers ();
453 void precreate (pthread_attr
*);
455 bool create_cancel_event ();
456 static void set_tls_self_pointer (pthread
*);
458 DWORD
get_thread_id ();
461 class pthread_null
: public pthread
464 static pthread
*get_null_pthread();
467 /* From pthread These should never get called
468 * as the ojbect is not verifyable
470 bool create (void *(*)(void *), pthread_attr
*, void *);
471 void exit (void *value_ptr
) __attribute__ ((noreturn
));
474 int setcancelstate (int state
, int *oldstate
);
475 int setcanceltype (int type
, int *oldtype
);
476 void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
477 void pop_cleanup_handler (int const execute
);
478 unsigned long getsequence_np();
482 static pthread_null _instance
;
485 class pthread_condattr
: public verifyable_object
488 static bool is_good_object(pthread_condattr_t
const *);
492 ~pthread_condattr ();
495 class pthread_cond
: public verifyable_object
498 static bool is_good_object (pthread_cond_t
const *);
499 static bool is_initializer (pthread_cond_t
const *);
500 static bool is_initializer_or_object (pthread_cond_t
const *);
501 static bool is_initializer_or_bad_object (pthread_cond_t
const *);
502 static void init_mutex ();
503 static int init (pthread_cond_t
*, const pthread_condattr_t
*);
507 unsigned long waiting
;
508 unsigned long pending
;
511 pthread_mutex mtx_in
;
512 pthread_mutex mtx_out
;
514 pthread_mutex_t mtx_cond
;
516 void unblock (const bool all
);
517 int wait (pthread_mutex_t mutex
, DWORD dwMilliseconds
= INFINITE
);
519 pthread_cond (pthread_condattr
*);
522 class pthread_cond
* next
;
523 static void fixup_after_fork ()
525 conds
.fixup_after_fork ();
526 conds
.for_each (&pthread_cond::_fixup_after_fork
);
530 void _fixup_after_fork ();
532 static List
<pthread_cond
> conds
;
533 static fast_mutex cond_initialization_lock
;
536 class pthread_rwlockattr
: public verifyable_object
539 static bool is_good_object(pthread_rwlockattr_t
const *);
542 pthread_rwlockattr ();
543 ~pthread_rwlockattr ();
546 class pthread_rwlock
: public verifyable_object
549 static bool is_good_object (pthread_rwlock_t
const *);
550 static bool is_initializer (pthread_rwlock_t
const *);
551 static bool is_initializer_or_object (pthread_rwlock_t
const *);
552 static bool is_initializer_or_bad_object (pthread_rwlock_t
const *);
553 static void init_mutex ();
554 static int init (pthread_rwlock_t
*, const pthread_rwlockattr_t
*);
558 unsigned long waiting_readers
;
559 unsigned long waiting_writers
;
563 struct RWLOCK_READER
*next
;
567 fast_mutex readers_mx
;
578 pthread_cond cond_readers
;
579 pthread_cond cond_writers
;
581 pthread_rwlock (pthread_rwlockattr
*);
584 class pthread_rwlock
* next
;
585 static void fixup_after_fork ()
587 rwlocks
.fixup_after_fork ();
588 rwlocks
.for_each (&pthread_rwlock::_fixup_after_fork
);
592 static List
<pthread_rwlock
> rwlocks
;
594 void add_reader (struct RWLOCK_READER
*rd
);
595 void remove_reader (struct RWLOCK_READER
*rd
);
596 struct RWLOCK_READER
*lookup_reader (pthread_t thread
);
603 cond_writers
.unblock (false);
605 else if (waiting_readers
)
606 cond_readers
.unblock (true);
610 static void rdlock_cleanup (void *arg
);
611 static void wrlock_cleanup (void *arg
);
613 void _fixup_after_fork ();
615 static fast_mutex rwlock_initialization_lock
;
621 pthread_mutex_t mutex
;
625 /* shouldn't be here */
626 class semaphore
: public verifyable_object
629 static bool is_good_object(sem_t
const *);
631 static int init (sem_t
*sem
, int pshared
, unsigned int value
);
632 static int destroy (sem_t
*sem
);
633 static sem_t
*open (unsigned long long hash
, LUID luid
, int fd
, int oflag
,
634 mode_t mode
, unsigned int value
, bool &wasopen
);
635 static int close (sem_t
*sem
);
636 static int wait (sem_t
*sem
);
637 static int post (sem_t
*sem
);
638 static int getvalue (sem_t
*sem
, int *sval
);
639 static int trywait (sem_t
*sem
);
640 static int timedwait (sem_t
*sem
, const struct timespec
*abstime
);
642 static int getinternal (sem_t
*sem
, int *sfd
, unsigned long long *shash
,
643 LUID
*sluid
, unsigned int *sval
);
649 unsigned long long hash
;
653 semaphore (int, unsigned int);
654 semaphore (unsigned long long, LUID
, int, sem_t
*, int, mode_t
, unsigned int);
657 class semaphore
* next
;
658 static void fixup_after_fork ()
660 semaphores
.fixup_after_fork ();
661 semaphores
.for_each (&semaphore::_fixup_after_fork
);
663 static void terminate ()
666 semaphores
.for_each (&semaphore::_terminate
);
672 int _getvalue (int *sval
);
674 int _timedwait (const struct timespec
*abstime
);
676 void _fixup_after_fork ();
679 static List
<semaphore
> semaphores
;
686 class callback
* next
;
693 long int threadcount
;
695 callback
*pthread_prepare
;
696 callback
*pthread_child
;
697 callback
*pthread_parent
;
700 void fixup_before_fork ();
701 void fixup_after_fork ();
703 #if 0 // avoid initialization since zero is implied and
705 concurrency (0), threadcount (0),
706 pthread_prepare (NULL
), pthread_child (NULL
), pthread_parent (NULL
)
712 #define MT_INTERFACE user_data->threadinterface