OSDN Git Service

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