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