2 /* thread.h: Locking and threading module definitions
4 This file is part of Cygwin.
6 This software is a copyrighted work licensed under the terms of the
7 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
12 #define LOCK_MMAP_LIST 1
18 extern size_t get_rlimit_stack (void);
21 char *mythreadname (void);
34 lock_counter (0), win32_obj_id (0)
41 CloseHandle (win32_obj_id
);
47 win32_obj_id
= ::CreateEvent (&sec_none_nih
, false, false, NULL
);
50 debug_printf ("CreateEvent failed. %E");
58 if (InterlockedIncrement (&lock_counter
) != 1)
59 cygwait (win32_obj_id
, cw_infinite
, cw_sig
| cw_sig_restart
);
64 if (InterlockedDecrement (&lock_counter
))
65 ::SetEvent (win32_obj_id
);
76 #define PTHREAD_MAGIC 0xdf0df045
77 #define PTHREAD_MUTEX_MAGIC PTHREAD_MAGIC+1
78 #define PTHREAD_KEY_MAGIC PTHREAD_MAGIC+2
79 #define PTHREAD_ATTR_MAGIC PTHREAD_MAGIC+3
80 #define PTHREAD_MUTEXATTR_MAGIC PTHREAD_MAGIC+4
81 #define PTHREAD_COND_MAGIC PTHREAD_MAGIC+5
82 #define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6
83 #define SEM_MAGIC PTHREAD_MAGIC+7
84 #define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8
85 #define PTHREAD_RWLOCK_MAGIC PTHREAD_MAGIC+9
86 #define PTHREAD_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
87 #define PTHREAD_SPINLOCK_MAGIC PTHREAD_MAGIC+11
88 #define PTHREAD_BARRIER_MAGIC PTHREAD_MAGIC+12
89 #define PTHREAD_BARRIERATTR_MAGIC PTHREAD_MAGIC+13
91 #define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
93 typedef uint32_t thread_magic_t
;
95 /* verifyable_object should not be defined here - it's a general purpose class */
97 class verifyable_object
100 thread_magic_t magic
;
102 verifyable_object (thread_magic_t verifyer
): magic (verifyer
) {}
103 virtual ~verifyable_object () { magic
= 0; }
111 } verifyable_object_state
;
113 template <class list_node
> inline void
114 List_insert (fast_mutex
&mx
, list_node
*&head
, list_node
*node
)
121 while (InterlockedCompareExchangePointer ((PVOID
volatile *) &head
,
122 node
, node
->next
) != node
->next
);
126 template <class list_node
> inline void
127 List_insert_nolock (list_node
*&head
, list_node
*node
)
133 while (InterlockedCompareExchangePointer ((PVOID
volatile *) &head
,
134 node
, node
->next
) != node
->next
);
137 template <class list_node
> inline void
138 List_remove (fast_mutex
&mx
, list_node
*&head
, list_node
*node
)
145 if (InterlockedCompareExchangePointer ((PVOID
volatile *) &head
,
146 node
->next
, node
) != node
)
148 list_node
*cur
= head
;
150 while (cur
->next
&& node
!= cur
->next
)
152 if (node
== cur
->next
)
153 cur
->next
= cur
->next
->next
;
160 template <class list_node
> class List
172 void fixup_after_fork ()
177 void insert (list_node
*node
)
179 List_insert (mx
, head
, node
);
182 void remove (list_node
*node
)
184 List_remove (mx
, head
, node
);
187 void for_each (void (list_node::*callback
) ())
190 list_node
*cur
= head
;
206 api_fatal ("Could not create mutex for list synchronisation.");
210 class pthread_key
: public verifyable_object
213 static bool iterate_dtors_once_more
;
215 static bool is_good_object (pthread_key_t
const *);
217 int set (const void *value
) {TlsSetValue (tls_index
, (void *) value
); return 0;}
218 void *get () const {return TlsGetValue (tls_index
);}
220 pthread_key (void (*)(void *));
222 static void fixup_before_fork ()
224 keys
.for_each (&pthread_key::_fixup_before_fork
);
227 static void fixup_after_fork ()
229 keys
.fixup_after_fork ();
230 keys
.for_each (&pthread_key::_fixup_after_fork
);
233 static void run_all_destructors ()
235 /* POSIX requires at least four iterations of running destructors:
237 If, after all the destructors have been called for all non-NULL
238 values with associated destructors, there are still some non-NULL
239 values with associated destructors, then the process is repeated.
240 If, after at least {PTHREAD_DESTRUCTOR_ITERATIONS} iterations of
241 destructor calls for outstanding non-NULL values, there are still
242 some non-NULL values with associated destructors, implementations
243 may stop calling destructors, or they may continue calling
244 destructors until no non-NULL values with associated destructors
245 exist, even though this might result in an infinite loop. */
246 for (int i
= 0; i
< PTHREAD_DESTRUCTOR_ITERATIONS
; ++i
)
248 iterate_dtors_once_more
= false;
249 keys
.for_each (&pthread_key::run_destructor
);
250 if (!iterate_dtors_once_more
)
255 /* List support calls */
256 class pthread_key
*next
;
258 static List
<pthread_key
> keys
;
259 void _fixup_before_fork ();
260 void _fixup_after_fork ();
261 void (*destructor
) (void *);
262 void run_destructor ();
266 class pthread_attr
: public verifyable_object
269 static bool is_good_object(pthread_attr_t
const *);
273 struct sched_param schedparam
;
283 class pthread_mutexattr
: public verifyable_object
286 static bool is_good_object(pthread_mutexattr_t
const *);
289 pthread_mutexattr ();
290 ~pthread_mutexattr ();
293 class pthread_mutex
: public verifyable_object
296 static void init_mutex ();
297 static int init (pthread_mutex_t
*, const pthread_mutexattr_t
*attr
,
298 const pthread_mutex_t
);
299 static bool is_good_object (pthread_mutex_t
const *);
300 static bool is_initializer (pthread_mutex_t
const *);
301 static bool is_initializer_or_object (pthread_mutex_t
const *);
302 static bool is_initializer_or_bad_object (pthread_mutex_t
const *);
304 int lock (PLARGE_INTEGER timeout
= NULL
);
308 void set_type (int in_type
) {type
= in_type
;}
310 int lock_recursive ()
312 if (recursion_counter
== UINT_MAX
)
318 bool can_be_unlocked ();
320 pthread_mutex (pthread_mutexattr
* = NULL
);
321 pthread_mutex (pthread_mutex_t
*, pthread_mutexattr
*);
324 class pthread_mutex
*next
;
325 static void fixup_after_fork ()
327 mutexes
.fixup_after_fork ();
328 mutexes
.for_each (&pthread_mutex::_fixup_after_fork
);
336 DWORD tid
; /* the thread id of the owner */
339 void set_shared (int in_shared
) { pshared
= in_shared
; }
340 void set_owner (pthread_t self
)
342 recursion_counter
= 1;
345 tid
= GetCurrentThreadId ();
349 static const pthread_t _new_mutex
;
350 static const pthread_t _unlocked_mutex
;
351 static const pthread_t _destroyed_mutex
;
354 unsigned int recursion_counter
;
360 void _fixup_after_fork ();
362 static List
<pthread_mutex
> mutexes
;
363 static fast_mutex mutex_initialization_lock
;
364 friend class pthread_cond
;
367 class pthread_spinlock
: public pthread_mutex
370 static bool is_good_object (pthread_spinlock_t
const *);
371 static int init (pthread_spinlock_t
*, int);
376 pthread_spinlock (int);
380 class pthread
: public verifyable_object
384 class pthread_attr attr
;
385 void *(*function
) (void *);
391 int cancelstate
, canceltype
;
396 virtual bool create (void *(*)(void *), pthread_attr
*, void *);
401 static void init_mainthread ();
402 static bool is_good_object(pthread_t
const *);
403 static void atforkprepare();
404 static void atforkparent();
405 static void atforkchild();
408 static int cancel (pthread_t
);
409 static int join (pthread_t
* thread
, void **return_val
, PLARGE_INTEGER
);
410 static int detach (pthread_t
* thread
);
411 static int create (pthread_t
* thread
, const pthread_attr_t
* attr
,
412 void *(*start_routine
) (void *), void *arg
);
413 static int once (pthread_once_t
*, void (*)(void));
414 static int atfork(void (*)(void), void (*)(void), void (*)(void));
415 static int suspend (pthread_t
* thread
);
416 static int resume (pthread_t
* thread
);
418 virtual void exit (void *value_ptr
) __attribute__ ((noreturn
));
420 virtual int cancel ();
422 virtual void testcancel ();
423 static HANDLE
get_cancel_event ();
424 static void static_cancel_self () __attribute__ ((noreturn
));
426 virtual int setcancelstate (int state
, int *oldstate
);
427 virtual int setcanceltype (int type
, int *oldtype
);
429 virtual void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
430 virtual void pop_cleanup_handler (int const execute
);
432 static pthread
* self ();
433 static DWORD
thread_init_wrapper (void *);
435 virtual unsigned long getsequence_np();
437 static int equal (pthread_t t1
, pthread_t t2
)
442 /* List support calls */
444 static void fixup_after_fork ()
446 threads
.fixup_after_fork ();
447 threads
.for_each (&pthread::_fixup_after_fork
);
450 static void suspend_all_except_self ()
452 threads
.for_each (&pthread::suspend_except_self
);
455 static void resume_all ()
457 threads
.for_each (&pthread::resume
);
461 static List
<pthread
> threads
;
463 __pthread_cleanup_handler
*cleanup_stack
;
465 sigset_t parent_sigmask
;
467 void suspend_except_self ();
470 void _fixup_after_fork ();
472 void pop_all_cleanup_handlers ();
473 void precreate (pthread_attr
*);
475 bool create_cancel_event ();
476 void set_tls_self_pointer ();
477 void cancel_self () __attribute__ ((noreturn
));
478 DWORD
get_thread_id ();
481 class pthread_null
: public pthread
484 static pthread
*get_null_pthread();
487 /* From pthread These should never get called
488 * as the ojbect is not verifyable
490 bool create (void *(*)(void *), pthread_attr
*, void *);
491 void exit (void *value_ptr
) __attribute__ ((noreturn
));
494 int setcancelstate (int state
, int *oldstate
);
495 int setcanceltype (int type
, int *oldtype
);
496 void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
497 void pop_cleanup_handler (int const execute
);
498 unsigned long getsequence_np();
502 static pthread_null _instance
;
505 class pthread_condattr
: public verifyable_object
508 static bool is_good_object(pthread_condattr_t
const *);
513 ~pthread_condattr ();
516 class pthread_cond
: public verifyable_object
519 static bool is_good_object (pthread_cond_t
const *);
520 static bool is_initializer (pthread_cond_t
const *);
521 static bool is_initializer_or_object (pthread_cond_t
const *);
522 static bool is_initializer_or_bad_object (pthread_cond_t
const *);
523 static void init_mutex ();
524 static int init (pthread_cond_t
*, const pthread_condattr_t
*);
533 pthread_mutex mtx_in
;
534 pthread_mutex mtx_out
;
536 pthread_mutex_t mtx_cond
;
538 void unblock (const bool all
);
539 int wait (pthread_mutex_t mutex
, PLARGE_INTEGER timeout
= NULL
);
541 pthread_cond (pthread_condattr
*);
544 class pthread_cond
* next
;
545 static void fixup_after_fork ()
547 conds
.fixup_after_fork ();
548 conds
.for_each (&pthread_cond::_fixup_after_fork
);
552 void _fixup_after_fork ();
554 static List
<pthread_cond
> conds
;
555 static fast_mutex cond_initialization_lock
;
559 class pthread_barrierattr
: public verifyable_object
562 static bool is_good_object(pthread_barrierattr_t
const *);
565 pthread_barrierattr ();
566 ~pthread_barrierattr ();
570 class pthread_barrier
: public verifyable_object
573 static bool is_good_object(pthread_barrier_t
const *);
575 pthread_mutex_t mtx
; /* Mutex protecting everything below. */
576 pthread_cond_t cond
; /* Conditional variable to wait on. */
577 unsigned cnt
; /* Barrier count. Threads to wait for. */
578 uint64_t cyc
; /* Cycle count. */
579 unsigned wt
; /* Already waiting threads count. */
581 int init (const pthread_barrierattr_t
*, unsigned);
590 class pthread_rwlockattr
: public verifyable_object
593 static bool is_good_object(pthread_rwlockattr_t
const *);
596 pthread_rwlockattr ();
597 ~pthread_rwlockattr ();
600 class pthread_rwlock
: public verifyable_object
603 static bool is_good_object (pthread_rwlock_t
const *);
604 static bool is_initializer (pthread_rwlock_t
const *);
605 static bool is_initializer_or_object (pthread_rwlock_t
const *);
606 static bool is_initializer_or_bad_object (pthread_rwlock_t
const *);
607 static void init_mutex ();
608 static int init (pthread_rwlock_t
*, const pthread_rwlockattr_t
*);
612 uint32_t waiting_readers
;
613 uint32_t waiting_writers
;
617 struct RWLOCK_READER
*next
;
620 RWLOCK_READER (): next (NULL
), thread (pthread::self ()), n (0) {}
622 fast_mutex readers_mx
;
624 int rdlock (PLARGE_INTEGER timeout
= NULL
);
627 int wrlock (PLARGE_INTEGER timeout
= NULL
);
633 pthread_cond cond_readers
;
634 pthread_cond cond_writers
;
636 pthread_rwlock (pthread_rwlockattr
*);
639 class pthread_rwlock
* next
;
640 static void fixup_after_fork ()
642 rwlocks
.fixup_after_fork ();
643 rwlocks
.for_each (&pthread_rwlock::_fixup_after_fork
);
647 static List
<pthread_rwlock
> rwlocks
;
649 RWLOCK_READER
*add_reader ();
650 void remove_reader (struct RWLOCK_READER
*rd
);
651 struct RWLOCK_READER
*lookup_reader ();
658 cond_writers
.unblock (false);
660 else if (waiting_readers
)
661 cond_readers
.unblock (true);
665 static void rdlock_cleanup (void *arg
);
666 static void wrlock_cleanup (void *arg
);
668 void _fixup_after_fork ();
670 static fast_mutex rwlock_initialization_lock
;
676 pthread_mutex_t mutex
;
680 /* shouldn't be here */
681 class semaphore
: public verifyable_object
684 static bool is_good_object(sem_t
const *);
686 static int init (sem_t
*sem
, int pshared
, unsigned int value
);
687 static int destroy (sem_t
*sem
);
688 static sem_t
*open (unsigned long long hash
, LUID luid
, int fd
, int oflag
,
689 mode_t mode
, unsigned int value
, bool &wasopen
);
690 static int close (sem_t
*sem
);
691 static int wait (sem_t
*sem
);
692 static int post (sem_t
*sem
);
693 static int getvalue (sem_t
*sem
, int *sval
);
694 static int trywait (sem_t
*sem
);
695 static int clockwait (sem_t
*sem
, clockid_t clock_id
,
696 const struct timespec
*abstime
);
698 static int getinternal (sem_t
*sem
, int *sfd
, unsigned long long *shash
,
699 LUID
*sluid
, unsigned int *sval
);
706 unsigned long long hash
;
710 semaphore (int, unsigned int);
711 semaphore (unsigned long long, LUID
, int, sem_t
*, int, mode_t
, unsigned int);
714 class semaphore
* next
;
715 static void fixup_before_fork ()
717 semaphores
.for_each (&semaphore::_fixup_before_fork
);
719 static void fixup_after_fork ()
721 semaphores
.fixup_after_fork ();
722 semaphores
.for_each (&semaphore::_fixup_after_fork
);
724 static void terminate ()
727 semaphores
.for_each (&semaphore::_terminate
);
732 int _getvalue (int *sval
);
734 int _wait (PLARGE_INTEGER timeout
= NULL
);
736 void _fixup_before_fork ();
737 void _fixup_after_fork ();
740 static List
<semaphore
> semaphores
;
747 class callback
* next
;
756 callback
*pthread_prepare
;
757 callback
*pthread_child
;
758 callback
*pthread_parent
;
761 void fixup_before_fork ();
762 void fixup_after_fork ();
764 #if 0 // avoid initialization since zero is implied and
766 concurrency (0), threadcount (0),
767 pthread_prepare (NULL
), pthread_child (NULL
), pthread_parent (NULL
)
773 #define MT_INTERFACE user_data->threadinterface