diff options
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | cleanup.c | 55 | ||||
-rw-r--r-- | global.c | 22 | ||||
-rw-r--r-- | implement.h | 41 | ||||
-rw-r--r-- | pthread.h | 70 |
5 files changed, 127 insertions, 76 deletions
@@ -1,3 +1,18 @@ +Thu Jul 23 23:25:30 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * global.c: New. Global data objects declared here. These moved from + pthread.h. + + * pthread.h: Move implementation hidden definitions into + implement.h. + + * implement.h: Move implementation hidden definitions from + pthread.h. Add constants to index into the different handler stacks. + + * cleanup.c (_pthread_handler_push): Simplify args. Restructure. + (_pthread_handler_pop): Simplify args. Restructure. + (_pthread_handler_pop_all): Simplify args. Restructure. + Wed Jul 22 00:16:22 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au> * attr.c, implement.h, pthread.h, ChangeLog: Resolve CVS merge @@ -10,7 +10,7 @@ #include "implement.h" void -_pthread_handler_push(_pthread_handler_node_t ** stacktop, +_pthread_handler_push(int stack, int poporder, void (*routine)(void *), void *arg) @@ -19,6 +19,9 @@ _pthread_handler_push(_pthread_handler_node_t ** stacktop, popped off in the order given by poporder. */ _pthread_handler_node_t * new; _pthread_handler_node_t * next; + _pthread_handler_node_t ** stacktop; + + stacktop = _PTHREAD_STACK(stack); new = (_pthread_handler_node_t *) malloc(sizeof(_pthread_handler_node_t)); @@ -34,7 +37,7 @@ _pthread_handler_push(_pthread_handler_node_t ** stacktop, { /* Add the new node to the start of the list. */ new->next = *stacktop; - stacktop = next; + *stacktop = next; } else { @@ -48,29 +51,35 @@ _pthread_handler_push(_pthread_handler_node_t ** stacktop, else { next = *stacktop; + while (next != NULL) { next = next->next; } + next = new; } } } void -_pthread_handler_pop(_pthread_handler_node_t ** stacktop, - int execute) +_pthread_handler_pop(int stack, int execute) { - _pthread_handler_node_t * handler = *stacktop; + _pthread_handler_node_t ** stacktop; + _pthread_handler_node_t * next; + void (* func)(void *); + void * arg; - if (handler != NULL) - { - void (* func)(void *) = handler->routine; - void * arg = handler->arg; + stacktop = _PTHREAD_STACK(stack); - *stacktop = handler->next; + if (*stacktop != NULL) + { + func = (*stacktop)->routine; + arg = (*stacktop)->arg; + next = (*stacktop)->next; - free(handler); + free(*stacktop); + *stacktop = next; if (execute != 0 && func != NULL) { @@ -80,12 +89,28 @@ _pthread_handler_pop(_pthread_handler_node_t ** stacktop, } void -_pthread_handler_pop_all(_pthread_handler_node_t ** stacktop, - int execute) +_pthread_handler_pop_all(int stack, int execute) { - /* Pop and run all handlers on the given stack. */ + /* Pop and possibly run all handlers on the given stack. */ + _pthread_handler_node_t ** stacktop; + _pthread_handler_node_t * next; + void (* func)(void *); + void * arg; + + stacktop = _PTHREAD_STACK(stack); + while (*stacktop != NULL) { - _pthread_handler_pop(stacktop, execute); + func = (*stacktop)->routine; + arg = (*stacktop)->arg; + next = (*stacktop)->next; + + free(*stacktop); + *stacktop = next; + + if (execute != 0 && func != NULL) + { + (void) func(arg); + } } } diff --git a/global.c b/global.c new file mode 100644 index 0000000..bcc034d --- /dev/null +++ b/global.c @@ -0,0 +1,22 @@ +/* + * global.c + * + * Description: + * This translation unit instantiates data associated with the implementation + * as a whole. + */ + +#include <windows.h> +#include <process.h> +#include "pthread.h" +#include "implement.h" + +pthread_mutex_t _pthread_count_mutex = PTHREAD_MUTEX_INITIALIZER; + +DWORD _pthread_threads_count = 0; + +_pthread_threads_thread_t _pthread_threads_table[PTHREAD_THREADS_MAX]; + +unsigned short _pthread_once_flag; + +pthread_mutex_t _pthread_once_lock = PTHREAD_MUTEX_INITIALIZER; diff --git a/implement.h b/implement.h index 2256965..e507831 100644 --- a/implement.h +++ b/implement.h @@ -27,6 +27,47 @@ enum { _PTHREAD_HANDLER_POP_LIFO, _PTHREAD_HANDLER_POP_FIFO }; */ #define RND_SIZEOF(T) (((sizeof(T) / sizeof(DWORD)) + 1) * sizeof(DWORD)) +/* 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; +}; + +/* Stores a thread call routine and argument. */ +typedef struct { + unsigned (*routine)(void *); + void * arg; +} _pthread_call_t; + +#define _PTHREAD_THIS (_pthread_find_thread_entry(pthread_this())) + +#define _PTHREAD_STACK(stack) \ + ((_pthread_handler_node_t *) &(_PTHREAD_THIS)->cleanupstack + stack); + +/* An element in the thread table. */ +typedef struct _pthread_threads_thread _pthread_threads_thread_t; + +struct _pthread_threads_thread { + pthread_t thread; + pthread_attr_t attr; + _pthread_call_t call; + enum { + _PTHREAD_CLEANUP_STACK, + _PTHREAD_DESTRUCTOR_STACK, + _PTHREAD_FORKPREPARE_STACK, + _PTHREAD_FORKPARENT_STACK, + _PTHREAD_FORKCHILD_STACK + }; + _pthread_handler_node_t * cleanupstack; + _pthread_handler_node_t * destructorstack; + _pthread_handler_node_t * forkpreparestack; + _pthread_handler_node_t * forkparentstack; + _pthread_handler_node_t * forkchildstack; +}; + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -231,80 +231,31 @@ void _pthread_handler_pop_all(_pthread_handler_node_t ** stacktop, doesn't say if the implemention must enforce them. The macros below partially enforce scope but can lead to compile or runtime errors. */ -enum { _PTHREAD_HANDLER_POP_LIFO, _PTHREAD_HANDLER_POP_FIFO }; - -#define _PTHREAD_THIS (_pthread_find_thread_entry(pthread_this())) +enum { + _PTHREAD_HANDLER_POP_LIFO, + _PTHREAD_HANDLER_POP_FIFO +}; #ifdef pthread_cleanup_push #undef pthread_cleanup_push #endif + #define pthread_cleanup_push(routine, arg) \ { \ - _pthread_handler_push(&(_PTHREAD_THIS->cleanupstack), \ + _pthread_handler_push(_PTHREAD_CLEANUP_STACK, \ _PTHREAD_HANDLER_POP_LIFO, routine, arg); #ifdef pthread_cleanup_pop #undef pthread_cleanup_pop #endif + #define pthread_cleanup_pop(execute) \ - _pthread_handler_pop(&(_PTHREAD_THIS->cleanupstack), execute);\ + _pthread_handler_pop(_PTHREAD_CLEANUP_STACK, execute);\ } -/************************************************************************** - Below here goes all internal definitions required by this implementation - of pthreads that must be global to any application that uses it. - **************************************************************************/ - -/* General description of a cleanup handler or destructor */ - -typedef struct _pthread_handler_node _pthread_handler_node_t; - -struct _pthread_handler_node { - _pthread_handler_node_t next; - void (* routine)(void *); - void * arg; -}; - -/* Stores a thread call routine and argument. */ -typedef struct { - unsigned (*routine)(void *); - void * arg; -} _pthread_call_t; - -/* An element in the thread table. */ - -typedef struct _pthread_threads_thread _pthread_threads_thread_t; - -struct _pthread_threads_thread { - pthread_t thread; - pthread_attr_t attr; - _pthread_call_t call; - _pthread_handler_node_t * cleanupstack; - _pthread_handler_node_t * destructorstack; - _pthread_handler_node_t * forkpreparestack; - _pthread_handler_node_t * forkparentstack; - _pthread_handler_node_t * forkchildstack; -}; - -/* _PTHREAD_BUILD_DLL must only be defined if we are building the DLL. */ - -#ifndef _PTHREADS_BUILD_DLL - /* Global data needed by the application but which must not be static - in the DLL. - */ -pthread_mutex_t _pthread_count_mutex = PTHREAD_MUTEX_INITIALIZER; - -DWORD _pthread_threads_count = 0; - -_pthread_threads_thread_t * _pthread_threads_table[PTHREAD_THREADS_MAX]; - -unsigned short _pthread_once_flag; - -pthread_mutex_t _pthread_once_lock = PTHREAD_MUTEX_INITIALIZER; - -#else + in the DLL. */ extern pthread_mutex_t _pthread_count_mutex; @@ -316,8 +267,5 @@ extern unsigned short _pthread_once_flag; extern pthread_mutex_t _pthread_once_lock; -#endif - -/* End of application static data */ #endif /* _PTHREADS_H */ |