diff options
author | rpj <rpj> | 1999-01-03 18:47:50 +0000 |
---|---|---|
committer | rpj <rpj> | 1999-01-03 18:47:50 +0000 |
commit | 36f0ed4155fdab7b12c5c5ddf4252170fac0a77e (patch) | |
tree | 2d8ed62df0b72d42a74b383d389ee7c28a0324da /implement.h | |
parent | 4650bcf1f1efd88a0c8f502c28945bfabd7ef6db (diff) |
Merge John Bossom's code into the main trunk. See ChangeLog for details.snapshot-1999-01-04-1305
This will be tagged as snapshot-1999-01-04-1305
Diffstat (limited to 'implement.h')
-rw-r--r-- | implement.h | 292 |
1 files changed, 135 insertions, 157 deletions
diff --git a/implement.h b/implement.h index db6b5a2..6bcedf6 100644 --- a/implement.h +++ b/implement.h @@ -1,197 +1,175 @@ /* * 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 -/* Use internally to initialise const ints and thread admin array sizes. */ -#define _PTHREAD_MAX_THREADS 128 -#define _PTHREAD_MAX_KEYS 128 - -#define _PTHREAD_HASH_INDEX(x) (((ULONG) x) % PTHREAD_THREADS_MAX) - -enum { - _PTHREAD_NEW, - _PTHREAD_INUSE, - _PTHREAD_EXITED, - _PTHREAD_REUSE -}; - -enum { - _PTHREAD_TSD_KEY_DELETED, - _PTHREAD_TSD_KEY_INUSE, - _PTHREAD_TSD_KEY_REUSE -}; - -#define _PTHREAD_VALID(T) \ - ((T) != NULL \ - && ((T)->ptstatus == _PTHREAD_NEW \ - || (T)->ptstatus == _PTHREAD_INUSE)) +/* + * Code contributed by John E. Bossom <JEB>. + */ -/* Handler execution flags. */ -#define _PTHREAD_HANDLER_NOEXECUTE 0 -#define _PTHREAD_HANDLER_EXECUTE 1 -/* Special value to mark attribute objects as valid. */ -#define _PTHREAD_ATTR_VALID 0xC0FFEE +typedef struct ThreadParms ThreadParms; +typedef struct ThreadKeyAssoc ThreadKeyAssoc; -/* General description of a handler function on a stack. */ -typedef struct _pthread_handler_node _pthread_handler_node_t; -struct _pthread_handler_node { - _pthread_handler_node_t * next; - void (* routine)(void *); - void * arg; +struct ThreadParms { + pthread_t tid; + void *(*start) (void *); + void *arg; }; -/* TSD key element. */ -typedef struct _pthread_tsd_key _pthread_tsd_key_t; -struct _pthread_tsd_key { - int in_use; - int status; - void (* destructor)(void *); +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; }; -/* Stores a thread call routine and argument. */ -typedef struct { - unsigned (*routine)(void *); - void * arg; -} _pthread_call_t; - -/* Macro to compute the address of a given handler stack. */ -#define _PTHREAD_STACK(stack) \ - ((_pthread_handler_node_t **) &(pthread_self()->cleanupstack) + stack); - -/* Macro to compute the table index of a thread entry from it's entry - address. */ -#define _PTHREAD_THREADS_TABLE_INDEX(this) \ - ((_pthread_threads_table_t *) this - \ - (_pthread_threads_table_t *) _pthread_threads_threads_table) - -/* Macro to compute the address of a per-thread mutex lock. */ -#define _PTHREAD_THREAD_MUTEX(this) \ - (&_pthread_threads_mutex_table[_PTHREAD_THREADS_TABLE_INDEX(this)]) - -/* An element in the thread table. */ -typedef struct _pthread _pthread_t; - -/* Keep the old typedef until we've updated all source files. */ -typedef struct _pthread _pthread_threads_thread_t; - -/* Related constants */ -struct _pthread { - HANDLE win32handle; - int ptstatus; /* _PTHREAD_EXITED - _PTHREAD_REUSABLE */ - pthread_attr_t attr; - _pthread_call_t call; - int cancel_pending; - int cancelstate; /* PTHREAD_CANCEL_DISABLE - PTHREAD_CANCEL_ENABLE */ - - int canceltype; /* PTHREAD_CANCEL_ASYNCHRONOUS - PTHREAD_CANCEL_DEFERRED */ - void ** joinvalueptr; - int join_count; - - /* These must be kept in this order and together. */ - _pthread_handler_node_t * cleanupstack; - _pthread_handler_node_t * forkpreparestack; - _pthread_handler_node_t * forkparentstack; - _pthread_handler_node_t * forkchildstack; -}; -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Generic handler push and pop routines. */ - -int _pthread_handler_push(int stack, - int poporder, - void (*routine)(void *), - void *arg); - -void _pthread_handler_pop(int stack, - int execute); - -void _pthread_handler_pop_all(int stack, - int execute); +/* + * -------------------------------------------------------------- + * 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 */ \ + ) ) -void _pthread_destructor_run_all(); +/* + * 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 ) -/* Primitives to manage threads table entries. */ -int _pthread_new_thread(pthread_t * thread); +#define PTHREAD_SERVICES_FACILITY 0xBAD +#define PTHREAD_SERVICES_ERROR 0xDEED -int _pthread_delete_thread(pthread_t thread); -/* Thread cleanup. */ +/* Function pointer to TryEnterCriticalSection if it exists; otherwise NULL */ +extern BOOL (WINAPI *_pthread_try_enter_critical_section)(LPCRITICAL_SECTION); -void _pthread_vacuum(void); +/* Declared in global.c */ +extern int _pthread_processInitialized; +extern pthread_key_t _pthread_selfThreadKey; +extern pthread_key_t _pthread_cleanupKey; -void _pthread_exit(pthread_t thread, void * value, int return_code); #ifdef __cplusplus -} +extern "C" { #endif /* __cplusplus */ +/* + * ===================== + * ===================== + * Forward Declarations + * ===================== + * ===================== + */ +int _pthread_processInitialize (void); -/* Global declared dll.c */ - -extern DWORD _pthread_threadID_TlsIndex; - -extern DWORD _pthread_TSD_keys_TlsIndex; - - -/* Global data declared in global.c */ - -extern pthread_mutex_t _pthread_table_mutex; - -extern DWORD _pthread_threads_count; - -/* An array of struct _pthread */ -extern _pthread_t _pthread_virgins[]; - -/* Index to the next available previously unused struct _pthread */ -extern int _pthread_virgin_next; - -/* An array of pointers to struct _pthread */ -extern pthread_t _pthread_reuse[]; +void _pthread_processTerminate (void); -/* Index to the first available reusable pthread_t. */ -extern int _pthread_reuse_top; +void _pthread_threadDestroy (pthread_t tid); -/* An array of pointers to struct _pthread indexed by hashing - the Win32 handle. */ -extern pthread_t _pthread_win32handle_map[]; +void _pthread_cleanupStack (void); -/* Per thread mutex locks. */ -extern pthread_mutex_t _pthread_threads_mutex_table[]; +void *_pthread_threadStart (ThreadParms * threadParms); -/* Global TSD key array. */ -extern _pthread_tsd_key_t _pthread_tsd_key_table[]; +void _pthread_callUserDestroyRoutines (pthread_t thread); -/* Mutex lock for TSD operations */ -extern pthread_mutex_t _pthread_tsd_mutex; +int _pthread_tkAssocCreate (ThreadKeyAssoc ** assocP, + pthread_t thread, + pthread_key_t key); -/* Function pointer to TryEnterCriticalSection if it exists; otherwise NULL */ -extern BOOL (WINAPI *_pthread_try_enter_critical_section)(LPCRITICAL_SECTION); +void _pthread_tkAssocDestroy (ThreadKeyAssoc * assoc); -/* An array of pthread_key_t */ -extern pthread_key_t _pthread_key_virgins[]; - -/* Index to the next available previously unused pthread_key_t */ -extern int _pthread_key_virgin_next; - -/* An array of pthread_key_t */ -extern pthread_key_t _pthread_key_reuse[]; +#ifdef __cplusplus +} +#endif /* __cplusplus */ -/* Index to the first available reusable pthread_key_t. */ -extern int _pthread_key_reuse_top; +/* </JEB> */ #endif /* _IMPLEMENT_H */ |