]> sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/thread.h
* cygwin.din (pthread_attr_getstack): Export.
[newlib-cygwin.git] / winsup / cygwin / thread.h
1 /* thread.h: Locking and threading module definitions
2
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007,
4 2008, 2009, 2010, 2011 Red Hat, Inc.
5
6 This file is part of Cygwin.
7
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
10 details. */
11
12 #ifndef _THREAD_H
13 #define _THREAD_H
14
15 #define LOCK_MMAP_LIST 1
16
17 #define WRITE_LOCK 1
18 #define READ_LOCK 2
19
20 #include <pthread.h>
21 #include <limits.h>
22 #include "security.h"
23 #include <errno.h>
24 #include "cygerrno.h"
25
26 enum cw_sig_wait
27 {
28 cw_sig_nosig,
29 cw_sig_eintr,
30 cw_sig_resume
31 };
32
33 enum cw_cancel_action
34 {
35 cw_cancel_self,
36 cw_no_cancel_self,
37 cw_no_cancel
38 };
39
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)));
43
44 class fast_mutex
45 {
46 public:
47 fast_mutex () :
48 lock_counter (0), win32_obj_id (0)
49 {
50 }
51
52 ~fast_mutex ()
53 {
54 if(win32_obj_id)
55 CloseHandle (win32_obj_id);
56 }
57
58 bool init ()
59 {
60 lock_counter = 0;
61 win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL);
62 if (!win32_obj_id)
63 {
64 debug_printf ("CreateEvent failed. %E");
65 return false;
66 }
67 return true;
68 }
69
70 void lock ()
71 {
72 if (InterlockedIncrement ((long *) &lock_counter) != 1)
73 cancelable_wait (win32_obj_id, INFINITE, cw_no_cancel, cw_sig_resume);
74 }
75
76 void unlock ()
77 {
78 if (InterlockedDecrement ((long *) &lock_counter))
79 ::SetEvent (win32_obj_id);
80 }
81
82 private:
83 unsigned long lock_counter;
84 HANDLE win32_obj_id;
85 };
86
87 class per_process;
88 class pinfo;
89
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
102
103 #define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
104
105 typedef unsigned long thread_magic_t;
106
107 /* verifyable_object should not be defined here - it's a general purpose class */
108
109 class verifyable_object
110 {
111 public:
112 thread_magic_t magic;
113
114 verifyable_object (thread_magic_t verifyer): magic (verifyer) {}
115 virtual ~verifyable_object () { magic = 0; }
116 };
117
118 typedef enum
119 {
120 VALID_OBJECT,
121 INVALID_OBJECT,
122 VALID_STATIC_OBJECT
123 } verifyable_object_state;
124
125 template <class list_node> inline void
126 List_insert (list_node *&head, list_node *node)
127 {
128 if (!node)
129 return;
130 do
131 node->next = head;
132 while (InterlockedCompareExchangePointer (&head, node, node->next) != node->next);
133 }
134
135 template <class list_node> inline void
136 List_remove (fast_mutex &mx, list_node *&head, list_node const *node)
137 {
138 if (!node)
139 return;
140 mx.lock ();
141 if (head)
142 {
143 if (InterlockedCompareExchangePointer (&head, node->next, node) != node)
144 {
145 list_node *cur = head;
146
147 while (cur->next && node != cur->next)
148 cur = cur->next;
149 if (node == cur->next)
150 cur->next = cur->next->next;
151 }
152 }
153 mx.unlock ();
154 }
155
156
157 template <class list_node> class List
158 {
159 public:
160 List() : head(NULL)
161 {
162 mx_init ();
163 }
164
165 ~List()
166 {
167 }
168
169 void fixup_after_fork ()
170 {
171 mx_init ();
172 }
173
174 void insert (list_node *node)
175 {
176 List_insert (head, node);
177 }
178
179 void remove (list_node *node)
180 {
181 List_remove (mx, head, node);
182 }
183
184 void for_each (void (list_node::*callback) ())
185 {
186 mx.lock ();
187 list_node *cur = head;
188 while (cur)
189 {
190 (cur->*callback) ();
191 cur = cur->next;
192 }
193 mx.unlock ();
194 }
195
196 fast_mutex mx;
197 list_node *head;
198
199 protected:
200 void mx_init ()
201 {
202 if (!mx.init ())
203 api_fatal ("Could not create mutex for list synchronisation.");
204 }
205 };
206
207 class pthread_key: public verifyable_object
208 {
209 DWORD tls_index;
210 public:
211 static bool is_good_object (pthread_key_t const *);
212
213 int set (const void *value) {TlsSetValue (tls_index, (void *) value); return 0;}
214 void *get () const {return TlsGetValue (tls_index);}
215
216 pthread_key (void (*)(void *));
217 ~pthread_key ();
218 static void fixup_before_fork ()
219 {
220 keys.for_each (&pthread_key::_fixup_before_fork);
221 }
222
223 static void fixup_after_fork ()
224 {
225 keys.fixup_after_fork ();
226 keys.for_each (&pthread_key::_fixup_after_fork);
227 }
228
229 static void run_all_destructors ()
230 {
231 keys.for_each (&pthread_key::run_destructor);
232 }
233
234 /* List support calls */
235 class pthread_key *next;
236 private:
237 static List<pthread_key> keys;
238 void _fixup_before_fork ();
239 void _fixup_after_fork ();
240 void (*destructor) (void *);
241 void run_destructor ();
242 void *fork_buf;
243 };
244
245 class pthread_attr: public verifyable_object
246 {
247 public:
248 static bool is_good_object(pthread_attr_t const *);
249 int joinable;
250 int contentionscope;
251 int inheritsched;
252 struct sched_param schedparam;
253 void *stackaddr;
254 size_t stacksize;
255
256 pthread_attr ();
257 ~pthread_attr ();
258 };
259
260 class pthread_mutexattr: public verifyable_object
261 {
262 public:
263 static bool is_good_object(pthread_mutexattr_t const *);
264 int pshared;
265 int mutextype;
266 pthread_mutexattr ();
267 ~pthread_mutexattr ();
268 };
269
270 class pthread_mutex: public verifyable_object
271 {
272 public:
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 *);
280
281 int lock ();
282 int trylock ();
283 int unlock ();
284 int destroy ();
285 void set_type (int in_type) {type = in_type;}
286
287 int lock_recursive ()
288 {
289 if (recursion_counter == UINT_MAX)
290 return EAGAIN;
291 recursion_counter++;
292 return 0;
293 }
294
295 bool can_be_unlocked ();
296
297 pthread_mutex (pthread_mutexattr * = NULL);
298 pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
299 ~pthread_mutex ();
300
301 class pthread_mutex *next;
302 static void fixup_after_fork ()
303 {
304 mutexes.fixup_after_fork ();
305 mutexes.for_each (&pthread_mutex::_fixup_after_fork);
306 }
307
308 protected:
309 unsigned long lock_counter;
310 HANDLE win32_obj_id;
311 pthread_t owner;
312 #ifdef DEBUGGING
313 DWORD tid; /* the thread id of the owner */
314 #endif
315
316 void set_shared (int in_shared) { pshared = in_shared; }
317 void set_owner (pthread_t self)
318 {
319 recursion_counter = 1;
320 owner = self;
321 #ifdef DEBUGGING
322 tid = GetCurrentThreadId ();
323 #endif
324 }
325
326 static const pthread_t _new_mutex;
327 static const pthread_t _unlocked_mutex;
328 static const pthread_t _destroyed_mutex;
329
330 private:
331 unsigned int recursion_counter;
332 LONG condwaits;
333 int type;
334 int pshared;
335
336 bool no_owner ();
337 void _fixup_after_fork ();
338
339 static List<pthread_mutex> mutexes;
340 static fast_mutex mutex_initialization_lock;
341 friend class pthread_cond;
342 };
343
344 class pthread_spinlock: public pthread_mutex
345 {
346 public:
347 static bool is_good_object (pthread_spinlock_t const *);
348 static int init (pthread_spinlock_t *, int);
349
350 int lock ();
351 int unlock ();
352
353 pthread_spinlock (int);
354 };
355
356 #define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
357 #define WAIT_SIGNALED (WAIT_OBJECT_0 + 2)
358
359 class _cygtls;
360 class pthread: public verifyable_object
361 {
362 public:
363 HANDLE win32_obj_id;
364 class pthread_attr attr;
365 void *(*function) (void *);
366 void *arg;
367 void *return_ptr;
368 bool valid;
369 bool suspended;
370 bool canceled;
371 int cancelstate, canceltype;
372 _cygtls *cygtls;
373 HANDLE cancel_event;
374 pthread_t joiner;
375
376 virtual bool create (void *(*)(void *), pthread_attr *, void *);
377
378 pthread ();
379 virtual ~pthread ();
380
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();
386
387 /* API calls */
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);
397
398 virtual void exit (void *value_ptr) __attribute__ ((noreturn));
399
400 virtual int cancel ();
401
402 virtual void testcancel ();
403 static HANDLE get_cancel_event ();
404 static void static_cancel_self ();
405
406 virtual int setcancelstate (int state, int *oldstate);
407 virtual int setcanceltype (int type, int *oldtype);
408
409 virtual void push_cleanup_handler (__pthread_cleanup_handler *handler);
410 virtual void pop_cleanup_handler (int const execute);
411
412 static pthread* self ();
413 static DWORD WINAPI thread_init_wrapper (void *);
414
415 virtual unsigned long getsequence_np();
416
417 static int equal (pthread_t t1, pthread_t t2)
418 {
419 return t1 == t2;
420 }
421
422 /* List support calls */
423 class pthread *next;
424 static void fixup_after_fork ()
425 {
426 threads.fixup_after_fork ();
427 threads.for_each (&pthread::_fixup_after_fork);
428 }
429
430 static void suspend_all_except_self ()
431 {
432 threads.for_each (&pthread::suspend_except_self);
433 }
434
435 static void resume_all ()
436 {
437 threads.for_each (&pthread::resume);
438 }
439
440 private:
441 static List<pthread> threads;
442 DWORD thread_id;
443 __pthread_cleanup_handler *cleanup_stack;
444 pthread_mutex mutex;
445 _cygtls *parent_tls;
446
447 void suspend_except_self ();
448 void resume ();
449
450 void _fixup_after_fork ();
451
452 void pop_all_cleanup_handlers ();
453 void precreate (pthread_attr *);
454 void postcreate ();
455 bool create_cancel_event ();
456 static void set_tls_self_pointer (pthread *);
457 void cancel_self ();
458 DWORD get_thread_id ();
459 };
460
461 class pthread_null : public pthread
462 {
463 public:
464 static pthread *get_null_pthread();
465 ~pthread_null();
466
467 /* From pthread These should never get called
468 * as the ojbect is not verifyable
469 */
470 bool create (void *(*)(void *), pthread_attr *, void *);
471 void exit (void *value_ptr) __attribute__ ((noreturn));
472 int cancel ();
473 void testcancel ();
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();
479
480 private:
481 pthread_null ();
482 static pthread_null _instance;
483 };
484
485 class pthread_condattr: public verifyable_object
486 {
487 public:
488 static bool is_good_object(pthread_condattr_t const *);
489 int shared;
490
491 pthread_condattr ();
492 ~pthread_condattr ();
493 };
494
495 class pthread_cond: public verifyable_object
496 {
497 public:
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 *);
504
505 int shared;
506
507 unsigned long waiting;
508 unsigned long pending;
509 HANDLE sem_wait;
510
511 pthread_mutex mtx_in;
512 pthread_mutex mtx_out;
513
514 pthread_mutex_t mtx_cond;
515
516 void unblock (const bool all);
517 int wait (pthread_mutex_t mutex, DWORD dwMilliseconds = INFINITE);
518
519 pthread_cond (pthread_condattr *);
520 ~pthread_cond ();
521
522 class pthread_cond * next;
523 static void fixup_after_fork ()
524 {
525 conds.fixup_after_fork ();
526 conds.for_each (&pthread_cond::_fixup_after_fork);
527 }
528
529 private:
530 void _fixup_after_fork ();
531
532 static List<pthread_cond> conds;
533 static fast_mutex cond_initialization_lock;
534 };
535
536 class pthread_rwlockattr: public verifyable_object
537 {
538 public:
539 static bool is_good_object(pthread_rwlockattr_t const *);
540 int shared;
541
542 pthread_rwlockattr ();
543 ~pthread_rwlockattr ();
544 };
545
546 class pthread_rwlock: public verifyable_object
547 {
548 public:
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 *);
555
556 int shared;
557
558 unsigned long waiting_readers;
559 unsigned long waiting_writers;
560 pthread_t writer;
561 struct RWLOCK_READER
562 {
563 struct RWLOCK_READER *next;
564 pthread_t thread;
565 unsigned long n;
566 } *readers;
567 fast_mutex readers_mx;
568
569 int rdlock ();
570 int tryrdlock ();
571
572 int wrlock ();
573 int trywrlock ();
574
575 int unlock ();
576
577 pthread_mutex mtx;
578 pthread_cond cond_readers;
579 pthread_cond cond_writers;
580
581 pthread_rwlock (pthread_rwlockattr *);
582 ~pthread_rwlock ();
583
584 class pthread_rwlock * next;
585 static void fixup_after_fork ()
586 {
587 rwlocks.fixup_after_fork ();
588 rwlocks.for_each (&pthread_rwlock::_fixup_after_fork);
589 }
590
591 private:
592 static List<pthread_rwlock> rwlocks;
593
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);
597
598 void release ()
599 {
600 if (waiting_writers)
601 {
602 if (!readers)
603 cond_writers.unblock (false);
604 }
605 else if (waiting_readers)
606 cond_readers.unblock (true);
607 }
608
609
610 static void rdlock_cleanup (void *arg);
611 static void wrlock_cleanup (void *arg);
612
613 void _fixup_after_fork ();
614
615 static fast_mutex rwlock_initialization_lock;
616 };
617
618 class pthread_once
619 {
620 public:
621 pthread_mutex_t mutex;
622 int state;
623 };
624
625 /* shouldn't be here */
626 class semaphore: public verifyable_object
627 {
628 public:
629 static bool is_good_object(sem_t const *);
630 /* API calls */
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);
641
642 static int getinternal (sem_t *sem, int *sfd, unsigned long long *shash,
643 LUID *sluid, unsigned int *sval);
644
645 HANDLE win32_obj_id;
646 int shared;
647 long currentvalue;
648 int fd;
649 unsigned long long hash;
650 LUID luid;
651 sem_t *sem;
652
653 semaphore (int, unsigned int);
654 semaphore (unsigned long long, LUID, int, sem_t *, int, mode_t, unsigned int);
655 ~semaphore ();
656
657 class semaphore * next;
658 static void fixup_after_fork ()
659 {
660 semaphores.fixup_after_fork ();
661 semaphores.for_each (&semaphore::_fixup_after_fork);
662 }
663 static void terminate ()
664 {
665 save_errno save;
666 semaphores.for_each (&semaphore::_terminate);
667 }
668
669 private:
670 int _wait ();
671 void _post ();
672 int _getvalue (int *sval);
673 int _trywait ();
674 int _timedwait (const struct timespec *abstime);
675
676 void _fixup_after_fork ();
677 void _terminate ();
678
679 static List<semaphore> semaphores;
680 };
681
682 class callback
683 {
684 public:
685 void (*cb)(void);
686 class callback * next;
687 };
688
689 struct MTinterface
690 {
691 // General
692 int concurrency;
693 long int threadcount;
694
695 callback *pthread_prepare;
696 callback *pthread_child;
697 callback *pthread_parent;
698
699 void Init ();
700 void fixup_before_fork ();
701 void fixup_after_fork ();
702
703 #if 0 // avoid initialization since zero is implied and
704 MTinterface () :
705 concurrency (0), threadcount (0),
706 pthread_prepare (NULL), pthread_child (NULL), pthread_parent (NULL)
707 {
708 }
709 #endif
710 };
711
712 #define MT_INTERFACE user_data->threadinterface
713 #endif // _THREAD_H
This page took 0.068026 seconds and 5 git commands to generate.