source: win32/libpthreads-w32-2.8.0/include/implement.h@ 212

Last change on this file since 212 was 191, checked in by tim, 15 years ago

updated scons build scripts to handle MinGW
added binaries for MinGW build dependencies

File size: 20.4 KB
RevLine 
[191]1/*
2 * implement.h
3 *
4 * Definitions that don't need to be public.
5 *
6 * Keeps all the internals out of pthread.h
7 *
8 * --------------------------------------------------------------------------
9 *
10 * Pthreads-win32 - POSIX Threads Library for Win32
11 * Copyright(C) 1998 John E. Bossom
12 * Copyright(C) 1999,2005 Pthreads-win32 contributors
13 *
14 * Contact Email: rpj@callisto.canberra.edu.au
15 *
16 * The current list of contributors is contained
17 * in the file CONTRIBUTORS included with the source
18 * code distribution. The list can also be seen at the
19 * following World Wide Web location:
20 * http://sources.redhat.com/pthreads-win32/contributors.html
21 *
22 * This library is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU Lesser General Public
24 * License as published by the Free Software Foundation; either
25 * version 2 of the License, or (at your option) any later version.
26 *
27 * This library is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 * Lesser General Public License for more details.
31 *
32 * You should have received a copy of the GNU Lesser General Public
33 * License along with this library in the file COPYING.LIB;
34 * if not, write to the Free Software Foundation, Inc.,
35 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
36 */
37
38#ifndef _IMPLEMENT_H
39#define _IMPLEMENT_H
40
41#ifdef _WIN32_WINNT
42#undef _WIN32_WINNT
43#endif
44#define _WIN32_WINNT 0x400
45
46#include <windows.h>
47
48/*
49 * In case windows.h doesn't define it (e.g. WinCE perhaps)
50 */
51#ifdef WINCE
52typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam);
53#endif
54
55/*
56 * note: ETIMEDOUT is correctly defined in winsock.h
57 */
58#include <winsock.h>
59
60/*
61 * In case ETIMEDOUT hasn't been defined above somehow.
62 */
63#ifndef ETIMEDOUT
64# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
65#endif
66
67#if !defined(malloc)
68#include <malloc.h>
69#endif
70
71#if !defined(INT_MAX)
72#include <limits.h>
73#endif
74
75/* use local include files during development */
76#include "semaphore.h"
77#include "sched.h"
78
79#if defined(HAVE_C_INLINE) || defined(__cplusplus)
80#define INLINE inline
81#else
82#define INLINE
83#endif
84
85#if defined (__MINGW32__) || (_MSC_VER >= 1300)
86#define PTW32_INTERLOCKED_LONG long
87#define PTW32_INTERLOCKED_LPLONG long*
88#else
89#define PTW32_INTERLOCKED_LONG PVOID
90#define PTW32_INTERLOCKED_LPLONG PVOID*
91#endif
92
93#if defined(__MINGW32__)
94#include <stdint.h>
95#elif defined(__BORLANDC__)
96#define int64_t ULONGLONG
97#else
98#define int64_t _int64
99#endif
100
101typedef enum
102{
103 /*
104 * This enumeration represents the state of the thread;
105 * The thread is still "alive" if the numeric value of the
106 * state is greater or equal "PThreadStateRunning".
107 */
108 PThreadStateInitial = 0, /* Thread not running */
109 PThreadStateRunning, /* Thread alive & kicking */
110 PThreadStateSuspended, /* Thread alive but suspended */
111 PThreadStateCancelPending, /* Thread alive but is */
112 /* has cancelation pending. */
113 PThreadStateCanceling, /* Thread alive but is */
114 /* in the process of terminating */
115 /* due to a cancellation request */
116 PThreadStateException, /* Thread alive but exiting */
117 /* due to an exception */
118 PThreadStateLast
119}
120PThreadState;
121
122
123typedef struct ptw32_thread_t_ ptw32_thread_t;
124
125struct ptw32_thread_t_
126{
127#ifdef _UWIN
128 DWORD dummy[5];
129#endif
130 DWORD thread;
131 HANDLE threadH; /* Win32 thread handle - POSIX thread is invalid if threadH == 0 */
132 pthread_t ptHandle; /* This thread's permanent pthread_t handle */
133 ptw32_thread_t * prevReuse; /* Links threads on reuse stack */
134 volatile PThreadState state;
135 void *exitStatus;
136 void *parms;
137 int ptErrno;
138 int detachState;
139 pthread_mutex_t threadLock; /* Used for serialised access to public thread state */
140 int sched_priority; /* As set, not as currently is */
141 pthread_mutex_t cancelLock; /* Used for async-cancel safety */
142 int cancelState;
143 int cancelType;
144 HANDLE cancelEvent;
145#ifdef __CLEANUP_C
146 jmp_buf start_mark;
147#endif /* __CLEANUP_C */
148#if HAVE_SIGSET_T
149 sigset_t sigmask;
150#endif /* HAVE_SIGSET_T */
151 int implicit:1;
152 void *keys;
153 void *nextAssoc;
154};
155
156
157/*
158 * Special value to mark attribute objects as valid.
159 */
160#define PTW32_ATTR_VALID ((unsigned long) 0xC4C0FFEE)
161
162struct pthread_attr_t_
163{
164 unsigned long valid;
165 void *stackaddr;
166 size_t stacksize;
167 int detachstate;
168 struct sched_param param;
169 int inheritsched;
170 int contentionscope;
171#if HAVE_SIGSET_T
172 sigset_t sigmask;
173#endif /* HAVE_SIGSET_T */
174};
175
176
177/*
178 * ====================
179 * ====================
180 * Semaphores, Mutexes and Condition Variables
181 * ====================
182 * ====================
183 */
184
185struct sem_t_
186{
187 int value;
188 pthread_mutex_t lock;
189 HANDLE sem;
190#ifdef NEED_SEM
191 int leftToUnblock;
192#endif
193};
194
195#define PTW32_OBJECT_AUTO_INIT ((void *) -1)
196#define PTW32_OBJECT_INVALID NULL
197
198struct pthread_mutex_t_
199{
200 LONG lock_idx; /* Provides exclusive access to mutex state
201 via the Interlocked* mechanism.
202 0: unlocked/free.
203 1: locked - no other waiters.
204 -1: locked - with possible other waiters.
205 */
206 int recursive_count; /* Number of unlocks a thread needs to perform
207 before the lock is released (recursive
208 mutexes only). */
209 int kind; /* Mutex type. */
210 pthread_t ownerThread;
211 HANDLE event; /* Mutex release notification to waiting
212 threads. */
213};
214
215struct pthread_mutexattr_t_
216{
217 int pshared;
218 int kind;
219};
220
221/*
222 * Possible values, other than PTW32_OBJECT_INVALID,
223 * for the "interlock" element in a spinlock.
224 *
225 * In this implementation, when a spinlock is initialised,
226 * the number of cpus available to the process is checked.
227 * If there is only one cpu then "interlock" is set equal to
228 * PTW32_SPIN_USE_MUTEX and u.mutex is a initialised mutex.
229 * If the number of cpus is greater than 1 then "interlock"
230 * is set equal to PTW32_SPIN_UNLOCKED and the number is
231 * stored in u.cpus. This arrangement allows the spinlock
232 * routines to attempt an InterlockedCompareExchange on "interlock"
233 * immediately and, if that fails, to try the inferior mutex.
234 *
235 * "u.cpus" isn't used for anything yet, but could be used at
236 * some point to optimise spinlock behaviour.
237 */
238#define PTW32_SPIN_UNLOCKED (1)
239#define PTW32_SPIN_LOCKED (2)
240#define PTW32_SPIN_USE_MUTEX (3)
241
242struct pthread_spinlock_t_
243{
244 long interlock; /* Locking element for multi-cpus. */
245 union
246 {
247 int cpus; /* No. of cpus if multi cpus, or */
248 pthread_mutex_t mutex; /* mutex if single cpu. */
249 } u;
250};
251
252struct pthread_barrier_t_
253{
254 unsigned int nCurrentBarrierHeight;
255 unsigned int nInitialBarrierHeight;
256 int iStep;
257 int pshared;
258 sem_t semBarrierBreeched[2];
259};
260
261struct pthread_barrierattr_t_
262{
263 int pshared;
264};
265
266struct pthread_key_t_
267{
268 DWORD key;
269 void (*destructor) (void *);
270 pthread_mutex_t keyLock;
271 void *threads;
272};
273
274
275typedef struct ThreadParms ThreadParms;
276typedef struct ThreadKeyAssoc ThreadKeyAssoc;
277
278struct ThreadParms
279{
280 pthread_t tid;
281 void *(*start) (void *);
282 void *arg;
283};
284
285
286struct pthread_cond_t_
287{
288 long nWaitersBlocked; /* Number of threads blocked */
289 long nWaitersGone; /* Number of threads timed out */
290 long nWaitersToUnblock; /* Number of threads to unblock */
291 sem_t semBlockQueue; /* Queue up threads waiting for the */
292 /* condition to become signalled */
293 sem_t semBlockLock; /* Semaphore that guards access to */
294 /* | waiters blocked count/block queue */
295 /* +-> Mandatory Sync.LEVEL-1 */
296 pthread_mutex_t mtxUnblockLock; /* Mutex that guards access to */
297 /* | waiters (to)unblock(ed) counts */
298 /* +-> Optional* Sync.LEVEL-2 */
299 pthread_cond_t next; /* Doubly linked list */
300 pthread_cond_t prev;
301};
302
303
304struct pthread_condattr_t_
305{
306 int pshared;
307};
308
309#define PTW32_RWLOCK_MAGIC 0xfacade2
310
311struct pthread_rwlock_t_
312{
313 pthread_mutex_t mtxExclusiveAccess;
314 pthread_mutex_t mtxSharedAccessCompleted;
315 pthread_cond_t cndSharedAccessCompleted;
316 int nSharedAccessCount;
317 int nExclusiveAccessCount;
318 int nCompletedSharedAccessCount;
319 int nMagic;
320};
321
322struct pthread_rwlockattr_t_
323{
324 int pshared;
325};
326
327/*
328 * MCS lock queue node - see ptw32_MCS_lock.c
329 */
330struct ptw32_mcs_node_t_
331{
332 struct ptw32_mcs_node_t_ **lock; /* ptr to tail of queue */
333 struct ptw32_mcs_node_t_ *next; /* ptr to successor in queue */
334 LONG readyFlag; /* set after lock is released by
335 predecessor */
336 LONG nextFlag; /* set after 'next' ptr is set by
337 successor */
338};
339
340typedef struct ptw32_mcs_node_t_ ptw32_mcs_local_node_t;
341typedef struct ptw32_mcs_node_t_ *ptw32_mcs_lock_t;
342
343
344struct ThreadKeyAssoc
345{
346 /*
347 * Purpose:
348 * This structure creates an association between a thread and a key.
349 * It is used to implement the implicit invocation of a user defined
350 * destroy routine for thread specific data registered by a user upon
351 * exiting a thread.
352 *
353 * Graphically, the arrangement is as follows, where:
354 *
355 * K - Key with destructor
356 * (head of chain is key->threads)
357 * T - Thread that has called pthread_setspecific(Kn)
358 * (head of chain is thread->keys)
359 * A - Association. Each association is a node at the
360 * intersection of two doubly-linked lists.
361 *
362 * T1 T2 T3
363 * | | |
364 * | | |
365 * K1 -----+-----A-----A----->
366 * | | |
367 * | | |
368 * K2 -----A-----A-----+----->
369 * | | |
370 * | | |
371 * K3 -----A-----+-----A----->
372 * | | |
373 * | | |
374 * V V V
375 *
376 * Access to the association is guarded by two locks: the key's
377 * general lock (guarding the row) and the thread's general
378 * lock (guarding the column). This avoids the need for a
379 * dedicated lock for each association, which not only consumes
380 * more handles but requires that: before the lock handle can
381 * be released - both the key must be deleted and the thread
382 * must have called the destructor. The two-lock arrangement
383 * allows the resources to be freed as soon as either thread or
384 * key is concluded.
385 *
386 * To avoid deadlock: whenever both locks are required, the key
387 * and thread locks are always acquired in the order: key lock
388 * then thread lock. An exception to this exists when a thread
389 * calls the destructors, however this is done carefully to
390 * avoid deadlock.
391 *
392 * An association is created when a thread first calls
393 * pthread_setspecific() on a key that has a specified
394 * destructor.
395 *
396 * An association is destroyed either immediately after the
397 * thread calls the key destructor function on thread exit, or
398 * when the key is deleted.
399 *
400 * Attributes:
401 * thread
402 * reference to the thread that owns the
403 * association. This is actually the pointer to the
404 * thread struct itself. Since the association is
405 * destroyed before the thread exits, this can never
406 * point to a different logical thread to the one that
407 * created the assoc, i.e. after thread struct reuse.
408 *
409 * key
410 * reference to the key that owns the association.
411 *
412 * nextKey
413 * The pthread_t->keys attribute is the head of a
414 * chain of associations that runs through the nextKey
415 * link. This chain provides the 1 to many relationship
416 * between a pthread_t and all pthread_key_t on which
417 * it called pthread_setspecific.
418 *
419 * prevKey
420 * Similarly.
421 *
422 * nextThread
423 * The pthread_key_t->threads attribute is the head of
424 * a chain of assoctiations that runs through the
425 * nextThreads link. This chain provides the 1 to many
426 * relationship between a pthread_key_t and all the
427 * PThreads that have called pthread_setspecific for
428 * this pthread_key_t.
429 *
430 * prevThread
431 * Similarly.
432 *
433 * Notes:
434 * 1) As soon as either the key or the thread is no longer
435 * referencing the association, it can be destroyed. The
436 * association will be removed from both chains.
437 *
438 * 2) Under WIN32, an association is only created by
439 * pthread_setspecific if the user provided a
440 * destroyRoutine when they created the key.
441 *
442 *
443 */
444 ptw32_thread_t * thread;
445 pthread_key_t key;
446 ThreadKeyAssoc *nextKey;
447 ThreadKeyAssoc *nextThread;
448 ThreadKeyAssoc *prevKey;
449 ThreadKeyAssoc *prevThread;
450};
451
452
453#ifdef __CLEANUP_SEH
454/*
455 * --------------------------------------------------------------
456 * MAKE_SOFTWARE_EXCEPTION
457 * This macro constructs a software exception code following
458 * the same format as the standard Win32 error codes as defined
459 * in WINERROR.H
460 * Values are 32 bit values layed out as follows:
461 *
462 * 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
463 * +---+-+-+-----------------------+-------------------------------+
464 * |Sev|C|R| Facility | Code |
465 * +---+-+-+-----------------------+-------------------------------+
466 *
467 * Severity Values:
468 */
469#define SE_SUCCESS 0x00
470#define SE_INFORMATION 0x01
471#define SE_WARNING 0x02
472#define SE_ERROR 0x03
473
474#define MAKE_SOFTWARE_EXCEPTION( _severity, _facility, _exception ) \
475( (DWORD) ( ( (_severity) << 30 ) | /* Severity code */ \
476 ( 1 << 29 ) | /* MS=0, User=1 */ \
477 ( 0 << 28 ) | /* Reserved */ \
478 ( (_facility) << 16 ) | /* Facility Code */ \
479 ( (_exception) << 0 ) /* Exception Code */ \
480 ) )
481
482/*
483 * We choose one specific Facility/Error code combination to
484 * identify our software exceptions vs. WIN32 exceptions.
485 * We store our actual component and error code within
486 * the optional information array.
487 */
488#define EXCEPTION_PTW32_SERVICES \
489 MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \
490 PTW32_SERVICES_FACILITY, \
491 PTW32_SERVICES_ERROR )
492
493#define PTW32_SERVICES_FACILITY 0xBAD
494#define PTW32_SERVICES_ERROR 0xDEED
495
496#endif /* __CLEANUP_SEH */
497
498/*
499 * Services available through EXCEPTION_PTW32_SERVICES
500 * and also used [as parameters to ptw32_throw()] as
501 * generic exception selectors.
502 */
503
504#define PTW32_EPS_EXIT (1)
505#define PTW32_EPS_CANCEL (2)
506
507
508/* Useful macros */
509#define PTW32_MAX(a,b) ((a)<(b)?(b):(a))
510#define PTW32_MIN(a,b) ((a)>(b)?(b):(a))
511
512
513/* Declared in global.c */
514extern PTW32_INTERLOCKED_LONG (WINAPI *
515 ptw32_interlocked_compare_exchange)
516 (PTW32_INTERLOCKED_LPLONG, PTW32_INTERLOCKED_LONG, PTW32_INTERLOCKED_LONG);
517
518/* Declared in pthread_cancel.c */
519extern DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD);
520
521/* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */
522#define PTW32_THREAD_REUSE_EMPTY ((ptw32_thread_t *) 1)
523
524extern int ptw32_processInitialized;
525extern ptw32_thread_t * ptw32_threadReuseTop;
526extern ptw32_thread_t * ptw32_threadReuseBottom;
527extern pthread_key_t ptw32_selfThreadKey;
528extern pthread_key_t ptw32_cleanupKey;
529extern pthread_cond_t ptw32_cond_list_head;
530extern pthread_cond_t ptw32_cond_list_tail;
531
532extern int ptw32_mutex_default_kind;
533
534extern int ptw32_concurrency;
535
536extern int ptw32_features;
537
538extern BOOL ptw32_smp_system; /* True: SMP system, False: Uni-processor system */
539
540extern CRITICAL_SECTION ptw32_thread_reuse_lock;
541extern CRITICAL_SECTION ptw32_mutex_test_init_lock;
542extern CRITICAL_SECTION ptw32_cond_list_lock;
543extern CRITICAL_SECTION ptw32_cond_test_init_lock;
544extern CRITICAL_SECTION ptw32_rwlock_test_init_lock;
545extern CRITICAL_SECTION ptw32_spinlock_test_init_lock;
546
547#ifdef _UWIN
548extern int pthread_count;
549#endif
550
551#ifdef __cplusplus
552extern "C"
553{
554#endif /* __cplusplus */
555
556/*
557 * =====================
558 * =====================
559 * Forward Declarations
560 * =====================
561 * =====================
562 */
563
564 int ptw32_is_attr (const pthread_attr_t * attr);
565
566 int ptw32_cond_check_need_init (pthread_cond_t * cond);
567 int ptw32_mutex_check_need_init (pthread_mutex_t * mutex);
568 int ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock);
569
570 PTW32_INTERLOCKED_LONG WINAPI
571 ptw32_InterlockedCompareExchange (PTW32_INTERLOCKED_LPLONG location,
572 PTW32_INTERLOCKED_LONG value,
573 PTW32_INTERLOCKED_LONG comparand);
574
575 LONG WINAPI
576 ptw32_InterlockedExchange (LPLONG location,
577 LONG value);
578
579 DWORD
580 ptw32_RegisterCancelation (PAPCFUNC callback,
581 HANDLE threadH, DWORD callback_arg);
582
583 int ptw32_processInitialize (void);
584
585 void ptw32_processTerminate (void);
586
587 void ptw32_threadDestroy (pthread_t tid);
588
589 void ptw32_pop_cleanup_all (int execute);
590
591 pthread_t ptw32_new (void);
592
593 pthread_t ptw32_threadReusePop (void);
594
595 void ptw32_threadReusePush (pthread_t thread);
596
597 int ptw32_getprocessors (int *count);
598
599 int ptw32_setthreadpriority (pthread_t thread, int policy, int priority);
600
601 void ptw32_rwlock_cancelwrwait (void *arg);
602
603#if ! defined (__MINGW32__) || defined (__MSVCRT__)
604 unsigned __stdcall
605#else
606 void
607#endif
608 ptw32_threadStart (void *vthreadParms);
609
610 void ptw32_callUserDestroyRoutines (pthread_t thread);
611
612 int ptw32_tkAssocCreate (ptw32_thread_t * thread, pthread_key_t key);
613
614 void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc);
615
616 int ptw32_semwait (sem_t * sem);
617
618 DWORD ptw32_relmillisecs (const struct timespec * abstime);
619
620 void ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node);
621
622 void ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node);
623
624#ifdef NEED_FTIME
625 void ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft);
626 void ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts);
627#endif
628
629/* Declared in misc.c */
630#ifdef NEED_CALLOC
631#define calloc(n, s) ptw32_calloc(n, s)
632 void *ptw32_calloc (size_t n, size_t s);
633#endif
634
635/* Declared in private.c */
636 void ptw32_throw (DWORD exception);
637
638#ifdef __cplusplus
639}
640#endif /* __cplusplus */
641
642
643#ifdef _UWIN_
644# ifdef _MT
645# ifdef __cplusplus
646extern "C"
647{
648# endif
649 _CRTIMP unsigned long __cdecl _beginthread (void (__cdecl *) (void *),
650 unsigned, void *);
651 _CRTIMP void __cdecl _endthread (void);
652 _CRTIMP unsigned long __cdecl _beginthreadex (void *, unsigned,
653 unsigned (__stdcall *) (void *),
654 void *, unsigned, unsigned *);
655 _CRTIMP void __cdecl _endthreadex (unsigned);
656# ifdef __cplusplus
657}
658# endif
659# endif
660#else
661# include <process.h>
662#endif
663
664
665/*
666 * Defaults. Could be overridden when building the inlined version of the dll.
667 * See ptw32_InterlockedCompareExchange.c
668 */
669#ifndef PTW32_INTERLOCKED_COMPARE_EXCHANGE
670#define PTW32_INTERLOCKED_COMPARE_EXCHANGE ptw32_interlocked_compare_exchange
671#endif
672
673#ifndef PTW32_INTERLOCKED_EXCHANGE
674#define PTW32_INTERLOCKED_EXCHANGE InterlockedExchange
675#endif
676
677
678/*
679 * Check for old and new versions of cygwin. See the FAQ file:
680 *
681 * Question 1 - How do I get pthreads-win32 to link under Cygwin or Mingw32?
682 *
683 * Patch by Anders Norlander <anorland@hem2.passagen.se>
684 */
685#if defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(NEED_CREATETHREAD)
686
687/*
688 * Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE
689 * in order to avoid warnings because of return type
690 */
691
692#define _beginthreadex(security, \
693 stack_size, \
694 start_proc, \
695 arg, \
696 flags, \
697 pid) \
698 CreateThread(security, \
699 stack_size, \
700 (LPTHREAD_START_ROUTINE) start_proc, \
701 arg, \
702 flags, \
703 pid)
704
705#define _endthreadex ExitThread
706
707#endif /* __CYGWIN32__ || __CYGWIN__ || NEED_CREATETHREAD */
708
709
710#endif /* _IMPLEMENT_H */
Note: See TracBrowser for help on using the repository browser.