1 /* thread.h: Locking and threading module definitions
3 Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
5 Written by Marco Fuykschot <marco@ddi.nl>
6 Major update 2001 Robert Collins <rbtcollins@hotmail.com>
8 This file is part of Cygwin.
10 This software is a copyrighted work licensed under the terms of the
11 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
14 #ifndef _CYGNUS_THREADS_
15 #define _CYGNUS_THREADS_
17 #define LOCK_FD_LIST 1
18 #define LOCK_MEMORY_LIST 2
19 #define LOCK_MMAP_LIST 3
20 #define LOCK_DLL_LIST 4
27 #if defined (_CYG_THREAD_FAILSAFE) && defined (_MT_SAFE)
28 void AssertResourceOwner (int, int);
30 #define AssertResourceOwner(i,ii)
36 #define SetResourceLock(i,n,c)
37 #define ReleaseResourceLock(i,n,c)
45 #define _NOMNTENT_FUNCS
54 Needed for the group functions
56 struct __group16 _grp
;
69 char _pass
[_PASSWORD_LEN
];
75 DWORD available_drives
;
78 char mnt_fsname
[MAX_PATH
];
79 char mnt_dir
[MAX_PATH
];
82 char _strerror_buf
[20];
87 int _process_facility
;
91 char timezone_buf
[20];
92 struct tm _localtime_buf
;
95 char _username
[UNLEN
+ 1];
99 struct protoent
*_protoent_buf
;
100 struct servent
*_servent_buf
;
101 struct hostent
*_hostent_buf
;
107 struct _reent
*_clib
;
108 struct _winsup_t
*_winsup
;
111 _reent
*_reent_clib ();
112 _winsup_t
*_reent_winsup ();
113 void SetResourceLock (int, int, const char *) __attribute__ ((regparm (3)));
114 void ReleaseResourceLock (int, int, const char *)
115 __attribute__ ((regparm (3)));
117 #ifdef _CYG_THREAD_FAILSAFE
118 void AssertResourceOwner (int, int);
120 #define AssertResourceOwner(i,ii)
133 LPCRITICAL_SECTION
Lock (int);
136 #ifdef _CYG_THREAD_FAILSAFE
141 CRITICAL_SECTION lock
;
145 #define PTHREAD_MAGIC 0xdf0df045
146 #define PTHREAD_MUTEX_MAGIC PTHREAD_MAGIC+1
147 #define PTHREAD_KEY_MAGIC PTHREAD_MAGIC+2
148 #define PTHREAD_ATTR_MAGIC PTHREAD_MAGIC+3
149 #define PTHREAD_MUTEXATTR_MAGIC PTHREAD_MAGIC+4
150 #define PTHREAD_COND_MAGIC PTHREAD_MAGIC+5
151 #define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6
152 #define SEM_MAGIC PTHREAD_MAGIC+7
153 #define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8;
155 /* verifyable_object should not be defined here - it's a general purpose class */
157 class verifyable_object
162 verifyable_object (long);
163 ~verifyable_object ();
171 } verifyable_object_state
;
173 verifyable_object_state
verifyable_object_isvalid (void const *, long);
174 verifyable_object_state
verifyable_object_isvalid (void const *, long, void *);
177 template <class ListNode
> class List
{
180 void Insert (ListNode
*aNode
);
181 ListNode
*Remove ( ListNode
*aNode
);
183 void forEach (void (*)(ListNode
*aNode
));
188 class pthread_key
:public verifyable_object
191 static bool isGoodObject (pthread_key_t
const *);
192 static void runAllDestructors ();
196 int set (const void *);
199 pthread_key (void (*)(void *));
201 static void fixup_before_fork();
202 static void fixup_after_fork();
204 /* List support calls */
205 class pthread_key
*next
;
207 // lists of objects. USE THREADSAFE INSERTS AND DELETES.
208 static List
<pthread_key
> keys
;
209 static void saveAKey (pthread_key
*);
210 static void restoreAKey (pthread_key
*);
211 static void destroyAKey (pthread_key
*);
212 void saveKeyToBuffer ();
213 void recreateKeyFromBuffer ();
214 void (*destructor
) (void *);
215 void run_destructor () const;
220 template <class ListNode
>
221 List
<ListNode
>::List
<ListNode
> () : head(NULL
)
224 template <class ListNode
> void
225 List
<ListNode
>::Insert (ListNode
*aNode
)
229 aNode
->next
= (ListNode
*) InterlockedExchangePointer (&head
, aNode
);
231 template <class ListNode
> ListNode
*
232 List
<ListNode
>::Remove ( ListNode
*aNode
)
240 ListNode
*resultPrev
= head
;
241 while (resultPrev
&& resultPrev
->next
&& !(aNode
== resultPrev
->next
))
242 resultPrev
= resultPrev
->next
;
244 return (ListNode
*)InterlockedExchangePointer (&resultPrev
->next
, resultPrev
->next
->next
);
247 template <class ListNode
> ListNode
*
248 List
<ListNode
>::Pop ()
250 return (ListNode
*) InterlockedExchangePointer (&head
, head
->next
);
252 /* poor mans generic programming. */
253 template <class ListNode
> void
254 List
<ListNode
>::forEach (void (*callback
)(ListNode
*))
256 ListNode
*aNode
= head
;
264 class pthread_attr
:public verifyable_object
267 static bool isGoodObject(pthread_attr_t
const *);
271 struct sched_param schedparam
;
278 class pthread_mutexattr
:public verifyable_object
281 static bool isGoodObject(pthread_mutexattr_t
const *);
284 pthread_mutexattr ();
285 ~pthread_mutexattr ();
288 class pthread_mutex
:public verifyable_object
291 static bool isGoodObject(pthread_mutex_t
const *);
292 static bool isGoodInitializer(pthread_mutex_t
const *);
293 static bool isGoodInitializerOrObject(pthread_mutex_t
const *);
294 CRITICAL_SECTION criticalsection
;
298 class pthread_mutex
* next
;
303 void fixup_after_fork ();
305 pthread_mutex (pthread_mutexattr
* = NULL
);
306 pthread_mutex (pthread_mutex_t
*, pthread_mutexattr
*);
310 class pthread
:public verifyable_object
314 class pthread_attr attr
;
315 void *(*function
) (void *);
319 int cancelstate
, canceltype
;
324 /* signal handling */
325 struct sigaction
*sigs
;
328 virtual void create (void *(*)(void *), pthread_attr
*, void *);
333 static void initMainThread(pthread
*, HANDLE
);
334 static bool isGoodObject(pthread_t
const *);
335 static void atforkprepare();
336 static void atforkparent();
337 static void atforkchild();
340 static int cancel (pthread_t
);
341 static int join (pthread_t
* thread
, void **return_val
);
342 static int detach (pthread_t
* thread
);
343 static int create (pthread_t
* thread
, const pthread_attr_t
* attr
,
344 void *(*start_routine
) (void *), void *arg
);
345 static int once (pthread_once_t
*, void (*)(void));
346 static int atfork(void (*)(void), void (*)(void), void (*)(void));
347 static int suspend (pthread_t
* thread
);
348 static int resume (pthread_t
* thread
);
350 virtual void exit (void *value_ptr
);
352 virtual int cancel ();
354 virtual void testcancel ();
355 static void static_cancel_self ();
357 virtual int setcancelstate (int state
, int *oldstate
);
358 virtual int setcanceltype (int type
, int *oldtype
);
360 virtual void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
361 virtual void pop_cleanup_handler (int const execute
);
363 static pthread
* self ();
364 static void *thread_init_wrapper (void *);
366 virtual unsigned long getsequence_np();
370 __pthread_cleanup_handler
*cleanup_stack
;
373 void pop_all_cleanup_handlers (void);
374 void precreate (pthread_attr
*);
376 void setThreadIdtoCurrent();
377 static void setTlsSelfPointer(pthread
*);
379 DWORD
getThreadId ();
382 class pthreadNull
: public pthread
385 static pthread
*getNullpthread();
388 /* From pthread These should never get called
389 * as the ojbect is not verifyable
391 void create (void *(*)(void *), pthread_attr
*, void *);
392 void exit (void *value_ptr
);
395 int setcancelstate (int state
, int *oldstate
);
396 int setcanceltype (int type
, int *oldtype
);
397 void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
398 void pop_cleanup_handler (int const execute
);
399 unsigned long getsequence_np();
403 static pthreadNull _instance
;
406 class pthread_condattr
:public verifyable_object
409 static bool isGoodObject(pthread_condattr_t
const *);
413 ~pthread_condattr ();
416 class pthread_cond
:public verifyable_object
419 static bool isGoodObject(pthread_cond_t
const *);
420 static bool isGoodInitializer(pthread_cond_t
const *);
421 static bool isGoodInitializerOrObject(pthread_cond_t
const *);
425 pthread_mutex
*mutex
;
426 /* to allow atomic behaviour for cond_broadcast */
427 pthread_mutex_t cond_access
;
429 class pthread_cond
* next
;
430 int TimedWait (DWORD dwMilliseconds
);
433 void fixup_after_fork ();
435 pthread_cond (pthread_condattr
*);
442 pthread_mutex_t mutex
;
446 /* shouldn't be here */
447 class semaphore
:public verifyable_object
450 static bool isGoodObject(sem_t
const *);
452 static int init (sem_t
* sem
, int pshared
, unsigned int value
);
453 static int destroy (sem_t
* sem
);
454 static int wait (sem_t
* sem
);
455 static int trywait (sem_t
* sem
);
456 static int post (sem_t
* sem
);
459 class semaphore
* next
;
465 void fixup_after_fork ();
467 semaphore (int, unsigned int);
475 class callback
* next
;
483 DWORD thread_self_dwTlsIndex
;
484 /* we may get 0 for the Tls index.. grrr */
487 long int threadcount
;
489 // Used for main thread data, and sigproc thread
490 struct __reent_t reents
;
491 struct _winsup_t winsup_reent
;
494 callback
*pthread_prepare
;
495 callback
*pthread_child
;
496 callback
*pthread_parent
;
498 // lists of pthread objects. USE THREADSAFE INSERTS AND DELETES.
499 class pthread_mutex
* mutexs
;
500 class pthread_cond
* conds
;
501 class semaphore
* semaphores
;
504 void fixup_before_fork (void);
505 void fixup_after_fork (void);
507 MTinterface ():reent_index (0), indexallocated (0), threadcount (1)
509 pthread_prepare
= NULL
;
510 pthread_child
= NULL
;
511 pthread_parent
= NULL
;
517 int __pthread_attr_init (pthread_attr_t
* attr
);
518 int __pthread_attr_destroy (pthread_attr_t
* attr
);
519 int __pthread_attr_setdetachstate (pthread_attr_t
*, int);
520 int __pthread_attr_getdetachstate (const pthread_attr_t
*, int *);
521 int __pthread_attr_setstacksize (pthread_attr_t
* attr
, size_t size
);
522 int __pthread_attr_getstacksize (const pthread_attr_t
* attr
, size_t * size
);
524 int __pthread_attr_getinheritsched (const pthread_attr_t
*, int *);
525 int __pthread_attr_getschedparam (const pthread_attr_t
*,
526 struct sched_param
*);
527 int __pthread_attr_getschedpolicy (const pthread_attr_t
*, int *);
528 int __pthread_attr_getscope (const pthread_attr_t
*, int *);
529 int __pthread_attr_getstackaddr (const pthread_attr_t
*, void **);
530 int __pthread_attr_setinheritsched (pthread_attr_t
*, int);
531 int __pthread_attr_setschedparam (pthread_attr_t
*,
532 const struct sched_param
*);
533 int __pthread_attr_setschedpolicy (pthread_attr_t
*, int);
534 int __pthread_attr_setscope (pthread_attr_t
*, int);
535 int __pthread_attr_setstackaddr (pthread_attr_t
*, void *);
537 /* Thread SpecificData */
538 int __pthread_key_create (pthread_key_t
* key
, void (*destructor
) (void *));
539 int __pthread_key_delete (pthread_key_t key
);
540 int __pthread_setspecific (pthread_key_t key
, const void *value
);
541 void *__pthread_getspecific (pthread_key_t key
);
543 /* Thead synchroniation */
544 int __pthread_cond_destroy (pthread_cond_t
* cond
);
545 int __pthread_cond_init (pthread_cond_t
* cond
,
546 const pthread_condattr_t
* attr
);
547 int __pthread_cond_signal (pthread_cond_t
* cond
);
548 int __pthread_cond_broadcast (pthread_cond_t
* cond
);
549 int __pthread_condattr_init (pthread_condattr_t
* condattr
);
550 int __pthread_condattr_destroy (pthread_condattr_t
* condattr
);
551 int __pthread_condattr_getpshared (const pthread_condattr_t
* attr
,
553 int __pthread_condattr_setpshared (pthread_condattr_t
* attr
, int pshared
);
556 int __pthread_kill (pthread_t thread
, int sig
);
557 int __pthread_sigmask (int operation
, const sigset_t
* set
,
561 int __pthread_equal (pthread_t
* t1
, pthread_t
* t2
);
564 int __pthread_mutex_init (pthread_mutex_t
*, const pthread_mutexattr_t
*);
565 int __pthread_mutex_lock (pthread_mutex_t
*);
566 int __pthread_mutex_trylock (pthread_mutex_t
*);
567 int __pthread_mutex_unlock (pthread_mutex_t
*);
568 int __pthread_mutex_destroy (pthread_mutex_t
*);
569 int __pthread_mutex_setprioceiling (pthread_mutex_t
* mutex
,
570 int prioceiling
, int *old_ceiling
);
571 int __pthread_mutex_getprioceiling (const pthread_mutex_t
* mutex
,
575 int __pthread_mutexattr_destroy (pthread_mutexattr_t
*);
576 int __pthread_mutexattr_getprioceiling (const pthread_mutexattr_t
*, int *);
577 int __pthread_mutexattr_getprotocol (const pthread_mutexattr_t
*, int *);
578 int __pthread_mutexattr_getpshared (const pthread_mutexattr_t
*, int *);
579 int __pthread_mutexattr_gettype (const pthread_mutexattr_t
*, int *);
580 int __pthread_mutexattr_init (pthread_mutexattr_t
*);
581 int __pthread_mutexattr_setprioceiling (pthread_mutexattr_t
*, int);
582 int __pthread_mutexattr_setprotocol (pthread_mutexattr_t
*, int);
583 int __pthread_mutexattr_setpshared (pthread_mutexattr_t
*, int);
584 int __pthread_mutexattr_settype (pthread_mutexattr_t
*, int);
588 int __pthread_getconcurrency (void);
589 int __pthread_setconcurrency (int new_level
);
590 int __pthread_getschedparam (pthread_t thread
, int *policy
,
591 struct sched_param
*param
);
592 int __pthread_setschedparam (pthread_t thread
, int policy
,
593 const struct sched_param
*param
);
598 #endif // _CYGNUS_THREADS_