diff options
Diffstat (limited to 'implement.h')
-rw-r--r-- | implement.h | 273 |
1 files changed, 272 insertions, 1 deletions
diff --git a/implement.h b/implement.h index db6b5a2..523f475 100644 --- a/implement.h +++ b/implement.h @@ -1,12 +1,281 @@ /* * implement.h * - * Implementation specific (non API) stuff. + * Definitions that don't need to be public. + * + * Keeps all the internals out of pthread.h */ #ifndef _IMPLEMENT_H #define _IMPLEMENT_H +/* + * Code contributed by John E. Bossom <JEB>. + */ + +typedef enum { + /* + * This enumeration represents the state of the thread; + * The thread is still "alive" if the numeric value of the + * state is greater or equal "PThreadStateRunning". + */ + PThreadStateInitial = 0, /* Thread not running */ + PThreadStateRunning, /* Thread alive & kicking */ + PThreadStateSuspended, /* Thread alive but suspended */ + PThreadStateCanceling, /* Thread alive but and is */ + /* in the process of terminating */ + /* due to a cancellation request */ + PThreadStateException, /* Thread alive but exiting */ + /* due to an exception */ + PThreadStateLast +} +PThreadState; + + +typedef enum { + /* + * This enumeration represents the reason why a thread has + * terminated/is terminating. + */ + PThreadDemisePeaceful = 0, /* Death due natural causes */ + PThreadDemiseCancelled, /* Death due to user cancel */ + PThreadDemiseException, /* Death due to unhandled */ + /* exception */ + PThreadDemiseNotDead /* I'm not dead! */ +} +PThreadDemise; + + +struct pthread_t_ { + DWORD thread; + HANDLE threadH; + PThreadState state; + PThreadDemise demise; + void *exitStatus; + void *parms; + int detachState; + int cancelState; + int cancelType; + HANDLE cancelEvent; + int implicit:1; + void *keys; +}; + + +struct pthread_attr_t_ { + void *stackaddr; + size_t stacksize; + int detachstate; +}; + + +struct pthread_key_t_ { + DWORD key; + void (*destructor) (void *); + pthread_mutex_t threadsLock; + void *threads; +}; + + +struct pthread_mutexattr_t_ { + int pshared; +}; + + +struct pthread_mutex_t_ { + int valid; + CRITICAL_SECTION cs; + }; + + +struct pthread_cond_t_ { + long waiters; /* # waiting threads */ + pthread_mutex_t waitersLock; /* Mutex that guards access to + waiter count */ + sem_t sema; /* Queue up threads waiting for the + condition to become signaled */ + HANDLE waitersDone; /* An auto reset event used by the + broadcast/signal thread to wait + for the waiting thread(s) to wake + up and get a chance at the + semaphore */ + int wasBroadcast; /* keeps track if we are signaling + or broadcasting */ +}; + + +struct pthread_condattr_t_ { + int pshared; +}; + + +struct pthread_once_t_ { + unsigned short flag; + pthread_mutex_t lock; +}; + + +typedef struct ThreadParms ThreadParms; +typedef struct ThreadKeyAssoc ThreadKeyAssoc; + + +struct ThreadParms { + pthread_t tid; + void *(*start) (void *); + void *arg; +}; + + +struct ThreadKeyAssoc { + /* + * Purpose: + * This structure creates an association between a + * thread and a key. + * It is used to implement the implicit invocation + * of a user defined destroy routine for thread + * specific data registered by a user upon exiting a + * thread. + * + * Attributes: + * lock + * protects access to the rest of the structure + * + * thread + * reference to the thread that owns the association. + * As long as this is not NULL, the association remains + * referenced by the pthread_t. + * + * key + * reference to the key that owns the association. + * As long as this is not NULL, the association remains + * referenced by the pthread_key_t. + * + * nextKey + * The pthread_t->keys attribute is the head of a + * chain of associations that runs through the nextKey + * link. This chain provides the 1 to many relationship + * between a pthread_t and all pthread_key_t on which + * it called pthread_setspecific. + * + * nextThread + * The pthread_key_t->threads attribute is the head of + * a chain of assoctiations that runs through the + * nextThreads link. This chain provides the 1 to many + * relationship between a pthread_key_t and all the + * PThreads that have called pthread_setspecific for + * this pthread_key_t. + * + * + * Notes: + * 1) As long as one of the attributes, thread or key, is + * not NULL, the association is being referenced; once + * both are NULL, the association must be released. + * + * 2) Under WIN32, an association is only created by + * pthread_setspecific if the user provided a + * destroyRoutine when they created the key. + * + * + */ + pthread_mutex_t lock; + pthread_t thread; + pthread_key_t key; + ThreadKeyAssoc *nextKey; + ThreadKeyAssoc *nextThread; +}; + + +/* + * -------------------------------------------------------------- + * MAKE_SOFTWARE_EXCEPTION + * This macro constructs a software exception code following + * the same format as the standard Win32 error codes as defined + * in WINERROR.H + * Values are 32 bit values layed out as follows: + * + * 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 + * +---+-+-+-----------------------+-------------------------------+ + * |Sev|C|R| Facility | Code | + * +---+-+-+-----------------------+-------------------------------+ + * + * Severity Values: + */ +#define SE_SUCCESS 0x00 +#define SE_INFORMATION 0x01 +#define SE_WARNING 0x10 +#define SE_ERROR 0x11 + +#define MAKE_SOFTWARE_EXCEPTION( _severity, _facility, _exception ) \ +( (DWORD) ( ( (_severity) << 30 ) | /* Severity code */ \ + ( 1 << 29 ) | /* MS=0, User=1 */ \ + ( 0 << 28 ) | /* Reserved */ \ + ( (_facility) << 16 ) | /* Facility Code */ \ + ( (_exception) << 0 ) /* Exception Code */ \ + ) ) + +/* + * We choose one specific Facility/Error code combination to + * identify our software exceptions vs. WIN32 exceptions. + * We store our actual component and error code within + * the optional information array. + */ +#define EXCEPTION_PTHREAD_SERVICES \ + MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \ + PTHREAD_SERVICES_FACILITY, \ + PTHREAD_SERVICES_ERROR ) + + +#define PTHREAD_SERVICES_FACILITY 0xBAD +#define PTHREAD_SERVICES_ERROR 0xDEED + + +/* Function pointer to TryEnterCriticalSection if it exists; otherwise NULL */ +extern BOOL (WINAPI *_pthread_try_enter_critical_section)(LPCRITICAL_SECTION); + +/* Declared in global.c */ +extern int _pthread_processInitialized; +extern pthread_key_t _pthread_selfThreadKey; +extern pthread_key_t _pthread_cleanupKey; + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * ===================== + * ===================== + * Forward Declarations + * ===================== + * ===================== + */ +int _pthread_processInitialize (void); + +void _pthread_processTerminate (void); + +void _pthread_threadDestroy (pthread_t tid); + +void _pthread_cleanupStack (void); + +void *_pthread_threadStart (ThreadParms * threadParms); + +void _pthread_callUserDestroyRoutines (pthread_t thread); + +int _pthread_tkAssocCreate (ThreadKeyAssoc ** assocP, + pthread_t thread, + pthread_key_t key); + +void _pthread_tkAssocDestroy (ThreadKeyAssoc * assoc); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/* </JEB> */ + + +#if 0 /* Pre Bossom */ + /* Use internally to initialise const ints and thread admin array sizes. */ #define _PTHREAD_MAX_THREADS 128 #define _PTHREAD_MAX_KEYS 128 @@ -194,4 +463,6 @@ extern pthread_key_t _pthread_key_reuse[]; /* Index to the first available reusable pthread_key_t. */ extern int _pthread_key_reuse_top; +#endif /* Pre Bossom */ + #endif /* _IMPLEMENT_H */ |