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