4
* Definitions that don't need to be public.
6
* Keeps all the internals out of pthread.h
8
* Pthreads-win32 - POSIX Threads Library for Win32
11
* This library is free software; you can redistribute it and/or
12
* modify it under the terms of the GNU Library General Public
13
* License as published by the Free Software Foundation; either
14
* version 2 of the License, or (at your option) any later version.
16
* This library is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
* Library General Public License for more details.
21
* You should have received a copy of the GNU Library General Public
22
* License along with this library; if not, write to the Free
23
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
38
/* use local include files during development */
39
#include "semaphore.h"
42
#if defined(HAVE_C_INLINE) || defined(__cplusplus)
50
* This enumeration represents the state of the thread;
51
* The thread is still "alive" if the numeric value of the
52
* state is greater or equal "PThreadStateRunning".
54
PThreadStateInitial = 0, /* Thread not running */
55
PThreadStateRunning, /* Thread alive & kicking */
56
PThreadStateSuspended, /* Thread alive but suspended */
57
PThreadStateCanceling, /* Thread alive but and is */
58
/* in the process of terminating */
59
/* due to a cancellation request */
60
PThreadStateException, /* Thread alive but exiting */
61
/* due to an exception */
69
* This enumeration represents the reason why a thread has
70
* terminated/is terminating.
72
PThreadDemisePeaceful = 0, /* Death due natural causes */
73
PThreadDemiseCancelled, /* Death due to user cancel */
74
PThreadDemiseException, /* Death due to unhandled */
76
PThreadDemiseNotDead /* I'm not dead! */
92
pthread_mutex_t cancelLock; /* Used for async-cancel safety */
98
#endif /* __CLEANUP_C */
101
#endif /* HAVE_SIGSET_T */
108
* Special value to mark attribute objects as valid.
110
#define PTW32_ATTR_VALID ((unsigned long) 0xC4C0FFEE)
112
struct pthread_attr_t_ {
117
struct sched_param param;
121
#endif /* HAVE_SIGSET_T */
126
* ====================
127
* ====================
128
* Semaphores, Mutexes and Condition Variables
129
* ====================
130
* ====================
136
CRITICAL_SECTION sem_lock_cs;
140
#endif /* NEED_SEM */
143
#define PTW32_OBJECT_AUTO_INIT ((void *) -1)
144
#define PTW32_OBJECT_INVALID NULL
146
struct pthread_mutex_t_ {
150
pthread_t ownerThread;
152
CRITICAL_SECTION try_lock_cs;
155
struct pthread_mutexattr_t_ {
161
* Possible values, other than PTW32_OBJECT_INVALID,
162
* for the "interlock" element in a spinlock.
164
* In this implementation, when a spinlock is initialised,
165
* the number of cpus available to the process is checked.
166
* If there is only one cpu then "interlock" is set equal to
167
* PTW32_SPIN_USE_MUTEX and u.mutex is a initialised mutex.
168
* If the number of cpus is greater than 1 then "interlock"
169
* is set equal to PTW32_SPIN_UNLOCKED and the number is
170
* stored in u.cpus. This arrangement allows the spinlock
171
* routines to attempt an InterlockedCompareExchange on "interlock"
172
* immediately and, if that fails, to try the inferior mutex.
174
* "u.cpus" isn't used for anything yet, but could be used at
175
* some point to optimise spinlock behaviour.
177
#define PTW32_SPIN_UNLOCKED (1)
178
#define PTW32_SPIN_LOCKED (2)
179
#define PTW32_SPIN_USE_MUTEX (3)
181
struct pthread_spinlock_t_ {
182
long interlock; /* Locking element for multi-cpus. */
184
int cpus; /* No. of cpus if multi cpus, or */
185
pthread_mutex_t mutex; /* mutex if single cpu. */
189
struct pthread_barrier_t_ {
190
unsigned int nCurrentBarrierHeight;
191
unsigned int nInitialBarrierHeight;
194
sem_t semBarrierBreeched[2];
197
struct pthread_barrierattr_t_ {
201
struct pthread_key_t_ {
203
void (*destructor) (void *);
204
pthread_mutex_t threadsLock;
209
typedef struct ThreadParms ThreadParms;
210
typedef struct ThreadKeyAssoc ThreadKeyAssoc;
214
void *(*start) (void *);
219
struct pthread_cond_t_ {
220
long nWaitersBlocked; /* Number of threads blocked */
221
long nWaitersGone; /* Number of threads timed out */
222
long nWaitersUnblocked; /* Number of threads unblocked */
223
long nWaitersToUnblock; /* Number of threads to unblock */
224
sem_t semBlockQueue; /* Queue up threads waiting for the */
225
/* condition to become signalled */
226
sem_t semBlockLock; /* Semaphore that guards access to */
227
/* | waiters blocked count/block queue */
228
/* +-> Mandatory Sync.LEVEL-1 */
229
pthread_mutex_t mtxUnblockLock; /* Mutex that guards access to */
230
/* | waiters (to)unblock(ed) counts */
231
/* +-> Optional* Sync.LEVEL-2 */
235
struct pthread_condattr_t_ {
239
#define PTW32_RWLOCK_MAGIC 0xfacade2
241
struct pthread_rwlock_t_ {
242
pthread_mutex_t mtxExclusiveAccess;
243
pthread_mutex_t mtxSharedAccessCompleted;
244
pthread_cond_t cndSharedAccessCompleted;
245
int nSharedAccessCount;
246
int nExclusiveAccessCount;
247
int nCompletedSharedAccessCount;
251
struct pthread_rwlockattr_t_ {
256
struct ThreadKeyAssoc {
259
* This structure creates an association between a
261
* It is used to implement the implicit invocation
262
* of a user defined destroy routine for thread
263
* specific data registered by a user upon exiting a
268
* protects access to the rest of the structure
271
* reference to the thread that owns the association.
272
* As long as this is not NULL, the association remains
273
* referenced by the pthread_t.
276
* reference to the key that owns the association.
277
* As long as this is not NULL, the association remains
278
* referenced by the pthread_key_t.
281
* The pthread_t->keys attribute is the head of a
282
* chain of associations that runs through the nextKey
283
* link. This chain provides the 1 to many relationship
284
* between a pthread_t and all pthread_key_t on which
285
* it called pthread_setspecific.
288
* The pthread_key_t->threads attribute is the head of
289
* a chain of assoctiations that runs through the
290
* nextThreads link. This chain provides the 1 to many
291
* relationship between a pthread_key_t and all the
292
* PThreads that have called pthread_setspecific for
293
* this pthread_key_t.
297
* 1) As long as one of the attributes, thread or key, is
298
* not NULL, the association is being referenced; once
299
* both are NULL, the association must be released.
301
* 2) Under WIN32, an association is only created by
302
* pthread_setspecific if the user provided a
303
* destroyRoutine when they created the key.
307
pthread_mutex_t lock;
310
ThreadKeyAssoc *nextKey;
311
ThreadKeyAssoc *nextThread;
317
* --------------------------------------------------------------
318
* MAKE_SOFTWARE_EXCEPTION
319
* This macro constructs a software exception code following
320
* the same format as the standard Win32 error codes as defined
322
* Values are 32 bit values layed out as follows:
324
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
325
* +---+-+-+-----------------------+-------------------------------+
326
* |Sev|C|R| Facility | Code |
327
* +---+-+-+-----------------------+-------------------------------+
331
#define SE_SUCCESS 0x00
332
#define SE_INFORMATION 0x01
333
#define SE_WARNING 0x02
334
#define SE_ERROR 0x03
336
#define MAKE_SOFTWARE_EXCEPTION( _severity, _facility, _exception ) \
337
( (DWORD) ( ( (_severity) << 30 ) | /* Severity code */ \
338
( 1 << 29 ) | /* MS=0, User=1 */ \
339
( 0 << 28 ) | /* Reserved */ \
340
( (_facility) << 16 ) | /* Facility Code */ \
341
( (_exception) << 0 ) /* Exception Code */ \
345
* We choose one specific Facility/Error code combination to
346
* identify our software exceptions vs. WIN32 exceptions.
347
* We store our actual component and error code within
348
* the optional information array.
350
#define EXCEPTION_PTW32_SERVICES \
351
MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \
352
PTW32_SERVICES_FACILITY, \
353
PTW32_SERVICES_ERROR )
355
#define PTW32_SERVICES_FACILITY 0xBAD
356
#define PTW32_SERVICES_ERROR 0xDEED
358
#endif /* __CLEANUP_SEH */
361
* Services available through EXCEPTION_PTW32_SERVICES
362
* and also used [as parameters to ptw32_throw()] as
363
* generic exception selectors.
366
#define PTW32_EPS_EXIT (1)
367
#define PTW32_EPS_CANCEL (2)
369
/* Mutex constants */
371
PTW32_MUTEX_LOCK_IDX_INIT = -1,
372
PTW32_MUTEX_OWNER_ANONYMOUS = 1
376
/* Declared in global.c */
377
extern int ptw32_processInitialized;
378
extern pthread_key_t ptw32_selfThreadKey;
379
extern pthread_key_t ptw32_cleanupKey;
381
extern int ptw32_mutex_default_kind;
383
extern int ptw32_concurrency;
385
extern CRITICAL_SECTION ptw32_mutex_test_init_lock;
386
extern CRITICAL_SECTION ptw32_cond_test_init_lock;
387
extern CRITICAL_SECTION ptw32_rwlock_test_init_lock;
388
extern CRITICAL_SECTION ptw32_spinlock_test_init_lock;
391
extern int pthread_count;
394
/* Declared in misc.c */
396
#define calloc(n, s) ptw32_calloc(n, s)
397
void *ptw32_calloc(size_t n, size_t s);
400
/* Declared in private.c */
401
void ptw32_throw(DWORD exception);
405
#endif /* __cplusplus */
408
* =====================
409
* =====================
410
* Forward Declarations
411
* =====================
412
* =====================
414
int ptw32_processInitialize (void);
416
void ptw32_processTerminate (void);
418
void ptw32_threadDestroy (pthread_t tid);
420
void ptw32_pop_cleanup_all (int execute);
422
pthread_t ptw32_new (void);
424
#if ! defined (__MINGW32__) || defined (__MSVCRT__)
429
ptw32_threadStart (void * vthreadParms);
431
void ptw32_callUserDestroyRoutines (pthread_t thread);
433
int ptw32_tkAssocCreate (ThreadKeyAssoc ** assocP,
437
void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc);
439
int ptw32_sem_timedwait (sem_t * sem,
440
const struct timespec * abstime);
443
void ptw32_decrease_semaphore(sem_t * sem);
444
BOOL ptw32_increase_semaphore(sem_t * sem,
446
#endif /* NEED_SEM */
450
#endif /* __cplusplus */
458
_CRTIMP unsigned long __cdecl _beginthread (void (__cdecl *) (void *),
460
_CRTIMP void __cdecl _endthread(void);
461
_CRTIMP unsigned long __cdecl _beginthreadex(void *, unsigned,
462
unsigned (__stdcall *) (void *), void *, unsigned, unsigned *);
463
_CRTIMP void __cdecl _endthreadex(unsigned);
469
# include <process.h>
473
* Check for old and new versions of cygwin. See the FAQ file:
475
* Question 1 - How do I get pthreads-win32 to link under Cygwin or Mingw32?
477
* Patch by Anders Norlander <anorland@hem2.passagen.se>
479
#if defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(NEED_CREATETHREAD)
482
* Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE
483
* in order to avoid warnings because of return type
486
#define _beginthreadex(security, \
492
CreateThread(security, \
494
(LPTHREAD_START_ROUTINE) start_proc, \
499
#define _endthreadex ExitThread
501
#endif /* __CYGWIN32__ || __CYGWIN__ || NEED_CREATETHREAD*/
504
#endif /* _IMPLEMENT_H */