diff options
-rw-r--r-- | ChangeLog | 66 | ||||
-rw-r--r-- | attr.c | 8 | ||||
-rw-r--r-- | cleanup.c | 2 | ||||
-rw-r--r-- | condvar.c | 12 | ||||
-rw-r--r-- | config.h | 1 | ||||
-rw-r--r-- | create.c | 5 | ||||
-rw-r--r-- | dll.c | 21 | ||||
-rw-r--r-- | exit.c | 6 | ||||
-rw-r--r-- | fork.c | 10 | ||||
-rw-r--r-- | global.c | 25 | ||||
-rw-r--r-- | implement.h | 23 | ||||
-rw-r--r-- | process.h | 16 | ||||
-rw-r--r-- | pthread.h | 27 | ||||
-rw-r--r-- | windows.h | 15 |
14 files changed, 179 insertions, 58 deletions
@@ -1,3 +1,69 @@ +Tue Aug 4 00:09:30 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * implement.h(_pthread_virgins): Add extern. + (_pthread_virgin_next): Ditto. + (_pthread_reuse): Ditto. + (_pthread_reuse_top): Ditto. + (_pthread_win32handle_map): Ditto. + (_pthread_threads_mutex_table): Ditto. + + * global.c (_pthread_virgins): Changed from array to pointer. + Storage allocation for the array moved into dll.c. + (_pthread_reuse): Ditto. + (_pthread_win32handle_map): Ditto. + (_pthread_threads_mutex_table): Ditto. + + * dll.c (PthreadsEntryPoint): Set up thread admin storage when + DLL is loaded. + + * fork.c (pthread_atfork): Fix function pointer arg to all + _pthread_handler_push() calls. Change "arg" arg to NULL in child push. + + * exit.c: Add windows.h and process.h includes. + (_pthread_exit): Add local detachstate declaration. + (_pthread_exit): Fix incorrect name for pthread_attr_getdetachstate(). + + * pthread.h (_POSIX_THREAD_ATTR_STACKSIZE): Move from global.c + (_POSIX_THREAD_ATTR_STACKADDR): Ditto. + + * create.c (pthread_create): Fix #if should be #ifdef. + (_pthread_start_call): Remove usused variables. + + * process.h: Create. + + * windows.h: Move _beginthreadex and _endthreadex into + process.h + +Mon Aug 3 21:19:57 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * condvar.c (pthread_cond_init): Add NULL attr to + pthread_mutex_init() call - default attributes will be used. + (cond_wait): Fix typo. + (cond_wait): Fix typo - cv was ev. + (pthread_cond_broadcast): Fix two identical typos. + + * cleanup.c (_pthread_destructor_pop_all): Remove _ prefix from + PTHREAD_DESTRUCTOR_ITERATIONS. + + * pthread.h: Move _POSIX_* values into posix.h + + * pthread.h: Fix typo in pthread_mutex_init() prototype. + + * attr.c (pthread_attr_init): Fix error in priority member init. + + * windows.h (THREAD_PRIORITY_NORMAL): Add. + + * pthread.h (sched_param): Add missing ';' to struct definition. + + * attr.c (pthread_attr_init): Remove obsolete pthread_attr_t + member initialisation - cancelstate, canceltype, cancel_pending. + (is_attr): Make arg "attr" a const. + + * implement.h (_PTHREAD_HANDLER_POP_LIFO): Remove definition. + (_PTHREAD_HANDLER_POP_FIFO): Ditto. + (_PTHREAD_VALID): Add missing newline escape (\). + (_pthread_handler_node): Make element "next" a pointer. + 1998-08-02 Ben Elliston <bje@cygnus.com> * windows.h: Remove duplicate TlsSetValue() prototype. Add @@ -7,9 +7,10 @@ #include "pthread.h" #include "implement.h" +#include <string.h> static int -is_attr(pthread_attr_t *attr) +is_attr(const pthread_attr_t *attr) { /* Return 0 if the attr object is valid, non-zero otherwise. */ @@ -98,14 +99,11 @@ pthread_attr_init(pthread_attr_t *attr) attr->stacksize = PTHREAD_STACK_MIN; #endif - attr->cancelstate = PTHREAD_CANCEL_ENABLE; - attr->canceltype = PTHREAD_CANCEL_DEFERRED; - attr->cancel_pending = FALSE; attr->detachedstate = PTHREAD_CREATE_JOINABLE; memset(&(attr->sigmask), 0, sizeof(sigset_t)); /* Priority uses Win32 priority values. */ - int priority = THREAD_PRIORITY_NORMAL; + attr->priority = THREAD_PRIORITY_NORMAL; attr->valid = _PTHREAD_ATTR_VALID; @@ -184,7 +184,7 @@ _pthread_destructor_pop_all() /* Stop destructor execution at a finite time. POSIX allows us to ignore this if we like, even at the risk of an infinite loop. */ - for (count = 0; count < _PTHREAD_DESTRUCTOR_ITERATIONS; count++) + for (count = 0; count < PTHREAD_DESTRUCTOR_ITERATIONS; count++) { /* Loop through all destructors for this thread. */ while (current != NULL) @@ -46,8 +46,8 @@ pthread_cond_init(pthread_cond_t *cv, const pthread_condattr_t *attr) /* Initialize the count to 0. */ cv->waiters_count = 0; - /* Initialize the "mutex". */ - pthread_mutex_init(cv->waiters_count_lock); + /* Initialize the "mutex". FIXME: Check attributes arg. */ + pthread_mutex_init(cv->waiters_count_lock, NULL); /* Create an auto-reset event. */ cv->events[SIGNAL] = CreateEvent (NULL, /* no security */ @@ -84,7 +84,7 @@ cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex, DWORD abstime) /* Avoid race conditions. */ EnterCriticalSection (&cv->waiters_count_lock); - cv->waiters_count_++; + cv->waiters_count++; LeaveCriticalSection (&cv->waiters_count_lock); /* It's okay to release the mutex here since Win32 manual-reset @@ -97,7 +97,7 @@ cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex, DWORD abstime) pthread_cond_signal() being called or pthread_cond_broadcast() being called. */ - result = WaitForMultipleObjects (2, ev->events, FALSE, abstime); + result = WaitForMultipleObjects (2, cv->events, FALSE, abstime); EnterCriticalSection (&cv->waiters_count_lock); cv->waiters_count--; @@ -156,9 +156,9 @@ pthread_cond_broadcast (pthread_cond_t *cv) } /* Avoid race conditions. */ - EnterCriticalSection (&cv->waiters_count_lock_); + EnterCriticalSection (&cv->waiters_count_lock); have_waiters = (cv->waiters_count > 0); - LeaveCriticalSection (&cv->waiters_count_lock_); + LeaveCriticalSection (&cv->waiters_count_lock); if (have_waiters) { SetEvent(cv->events[BROADCAST]); @@ -1 +1,2 @@ #define HAVE_SIGNAL_H +#define HAVE_SIGSET_T @@ -20,11 +20,9 @@ _pthread_start_call(void * us_arg) this thread's private stack so we're safe to leave data in them until we leave. */ pthread_t us; - _pthread_call_t * call; unsigned (*func)(void *); void * arg; unsigned ret; - int from; us = (pthread_t) us_arg; @@ -45,6 +43,7 @@ _pthread_start_call(void * us_arg) _pthread_exit(us, NULL, ret); /* Never Reached */ + return 0; } int @@ -85,7 +84,7 @@ pthread_create(pthread_t *thread, attr_copy->detachedstate = attr->detachedstate; attr_copy->priority = attr->priority; -#if HAVE_SIGSET_T +#ifdef HAVE_SIGSET_T memcpy(&(attr_copy->sigmask), &(attr->sigmask), sizeof(sigset_t)); #endif /* HAVE_SIGSET_T */ } @@ -15,6 +15,9 @@ */ #include <windows.h> +#include <malloc.h> +#include "pthread.h" +#include "implement.h" /* Global index for TLS data. */ DWORD _pthread_threadID_TlsIndex; @@ -32,6 +35,20 @@ BOOL WINAPI PthreadsEntryPoint(HINSTANCE dllHandle, break; case DLL_PROCESS_ATTACH: + /* Allocate storage for thread admin arrays. */ + _pthread_virgins = + (_pthread_t *) malloc(sizeof(_pthread_t) * PTHREAD_THREADS_MAX); + + _pthread_reuse = + (pthread_t *) malloc(sizeof(pthread_t) * PTHREAD_THREADS_MAX); + + _pthread_win32handle_map = + (pthread_t *) malloc(sizeof(pthread_t) * PTHREAD_THREADS_MAX); + + _pthread_threads_mutex_table = + (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t) * PTHREAD_THREADS_MAX); + + /* Per thread thread ID storage. */ _pthread_threadID_TlsIndex = TlsAlloc(); if (_pthread_threadID_TlsIndex == 0xFFFFFFFF) @@ -41,6 +58,10 @@ BOOL WINAPI PthreadsEntryPoint(HINSTANCE dllHandle, break; case DLL_PROCESS_DETACH: + free(_pthread_threads_mutex_table); + free(_pthread_win32handle_map); + free(_pthread_reuse); + free(_pthread_virgins); (void) TlsFree(_pthread_threadID_TlsIndex); break; @@ -6,6 +6,8 @@ * a thread. */ +#include <windows.h> +#include <process.h> #include "pthread.h" #include "implement.h" @@ -33,6 +35,8 @@ _pthread_vacuum(void) void _pthread_exit(pthread_t thread, void * value, int return_code) { + int detachstate; + /* CRITICAL SECTION */ pthread_mutex_lock(&_pthread_table_mutex); @@ -53,7 +57,7 @@ _pthread_exit(pthread_t thread, void * value, int return_code) be deleted by the last waiting pthread_join() after this thread has terminated. */ - if (pthread_attr_getdetachedstate(thread, &detachstate) == 0 + if (pthread_attr_getdetachstate(thread, &detachstate) == 0 && detachstate == PTHREAD_CREATE_DETACHED && thread->join_count == 0) { @@ -27,7 +27,8 @@ pthread_atfork(void (*prepare)(void), /* Push prepare. */ if (_pthread_handler_push(_PTHREAD_FORKPREPARE_STACK, _PTHREAD_HANDLER_POP_FIFO, - (void (*prepare)(void *)), NULL) == ENOMEM) + prepare, + NULL) == ENOMEM) { ret = ENOMEM; } @@ -39,7 +40,8 @@ pthread_atfork(void (*prepare)(void), /* Push parent. */ if (_pthread_handler_push(_PTHREAD_FORKPARENT_STACK, _PTHREAD_HANDLER_POP_LIFO, - (void (*parent)(void *)), NULL) == ENOMEM) + parent, + NULL) == ENOMEM) { ret = ENOMEM; } @@ -51,7 +53,8 @@ pthread_atfork(void (*prepare)(void), /* Push child. */ if (_pthread_handler_push(_PTHREAD_FORKCHILD_STACK, _PTHREAD_HANDLER_POP_LIFO, - (void (*child)(void *)), arg) == ENOMEM) + child, + NULL) == ENOMEM) { ret = ENOMEM; } @@ -129,6 +132,7 @@ fork() } /* Not reached. */ + return 0; } #endif /* HAVE_PID_T && HAVE_FORK */ @@ -11,18 +11,15 @@ #include "pthread.h" #include "implement.h" -#define PTHREAD_THREADS_MAX 128 -#define PTHREAD_STACK_MIN 65535 - -/* Convert these to defined when implemented. */ -#define _POSIX_THREAD_ATTR_STACKSIZE -#ifdef _POSIX_THREAD_ATTR_STACKADDR -#undef _POSIX_THREAD_ATTR_STACKADDR -#endif - /* Making these constants will mean that applications remain binary compatible between versions of the DLL. */ +/* POSIX run-time invariant values. (Currently POSIX minimum values) */ +const int _POSIX_THREAD_THREADS_MAX = 128; +const int _POSIX_THREAD_DESTRUCTOR_ITERATIONS = 4; +const int _POSIX_THREAD_KEYS_MAX = 128; + + const int _pthread_create_joinable = 0; const int _pthread_create_detached = 1; @@ -33,21 +30,23 @@ const int _pthread_cancel_disable = 1; const int _pthread_cancel_asynchronous = 0; const int _pthread_cancel_deferred = 1; +/* FIXME: This is temporary. */ +#define PTHREAD_MUTEX_INITIALIZER {0} pthread_mutex_t _pthread_table_mutex = PTHREAD_MUTEX_INITIALIZER; DWORD _pthread_threads_count = 0; /* Per thread management storage. See comments in private.c */ -_pthread_t _pthread_virgins[PTHREAD_THREADS_MAX]; +_pthread_t * _pthread_virgins; int _pthread_virgin_next = 0; -pthread_t _pthread_reuse[PTHREAD_THREADS_MAX]; +pthread_t * _pthread_reuse; int _pthread_reuse_top = -1; -pthread_t _pthread_win32handle_map[PTHREAD_THREADS_MAX]; +pthread_t * _pthread_win32handle_map; /* Per thread mutex locks. */ -pthread_mutex_t _pthread_threads_mutex_table[PTHREAD_THREADS_MAX]; +pthread_mutex_t * _pthread_threads_mutex_table; diff --git a/implement.h b/implement.h index 56fa7b3..f132674 100644 --- a/implement.h +++ b/implement.h @@ -18,16 +18,13 @@ enum { #define _PTHREAD_VALID(T) \ ((T) != NULL \ - && ((T)->ptstatus == _PTHREAD_NEW + && ((T)->ptstatus == _PTHREAD_NEW \ || (T)->ptstatus == _PTHREAD_INUSE)) /* Handler execution flags. */ #define _PTHREAD_HANDLER_NOEXECUTE 0 #define _PTHREAD_HANDLER_EXECUTE 1 -/* Handler popping schemes. */ -enum { _PTHREAD_HANDLER_POP_LIFO, _PTHREAD_HANDLER_POP_FIFO }; - /* Special value to mark attribute objects as valid. */ #define _PTHREAD_ATTR_VALID 0xC0FFEE @@ -35,7 +32,7 @@ enum { _PTHREAD_HANDLER_POP_LIFO, _PTHREAD_HANDLER_POP_FIFO }; typedef struct _pthread_handler_node _pthread_handler_node_t; struct _pthread_handler_node { - _pthread_handler_node_t next; + _pthread_handler_node_t * next; void (* routine)(void *); void * arg; }; @@ -140,9 +137,21 @@ extern pthread_mutex_t _pthread_table_mutex; extern DWORD _pthread_threads_count; -extern _pthread_threads_thread_t _pthread_threads_table[]; +extern _pthread_t * _pthread_virgins; + +extern int _pthread_virgin_next; + +extern pthread_t * _pthread_reuse; + +extern int _pthread_reuse_top; -extern pthread_mutex_t _pthread_threads_mutex_table[]; +extern pthread_t * _pthread_win32handle_map; + +/* Per thread mutex locks. */ +extern pthread_mutex_t * _pthread_threads_mutex_table; #endif /* _IMPLEMENT_H */ + + + diff --git a/process.h b/process.h new file mode 100644 index 0000000..7f0b5ea --- /dev/null +++ b/process.h @@ -0,0 +1,16 @@ +/* + * process.h + * + * Temporary stand-in for Win32 process.h + * + */ + +HANDLE _beginthreadex(LPSECURITY_ATTRIBUTES security, + DWORD stack, + unsigned (* start_routine)(void *), + LPVOID param, + DWORD flags, + LPDWORD threadID); + +VOID _endthreadex(DWORD); + @@ -22,6 +22,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef _PTHREADS_H #define _PTHREADS_H +/* Convert these to defined when implemented. */ +#define _POSIX_THREAD_ATTR_STACKSIZE +#ifdef _POSIX_THREAD_ATTR_STACKADDR +#undef _POSIX_THREAD_ATTR_STACKADDR +#endif + #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ @@ -46,15 +52,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define SIG_SETMASK 2 #endif /* SIG_SETMASK */ -#define PTHREAD_THREADS_MAX 128 #define PTHREAD_STACK_MIN 65535 -/* Convert these to defined when implemented. */ -#define _POSIX_THREAD_ATTR_STACKSIZE -#ifdef _POSIX_THREAD_ATTR_STACKADDR -#undef _POSIX_THREAD_ATTR_STACKADDR -#endif - /* Thread scheduling policies */ #define SCHED_OTHER 0 @@ -98,7 +97,7 @@ typedef struct { called. */ struct sched_param { int sched_priority; -} +}; enum { SIGNAL, BROADCAST, NUM_EVENTS }; @@ -233,7 +232,7 @@ int pthread_cond_destroy(pthread_cond_t *cv); /* Primitives for mutexes. */ int pthread_mutex_init(pthread_mutex_t *mutex, - pthread_mutex_attr_t *attr); + pthread_mutexattr_t *attr); int pthread_mutex_destroy(pthread_mutex_t *mutex); @@ -270,16 +269,24 @@ int pthread_cancel(pthread_t thread); } #endif /* __cplusplus */ +/* Constants declared in global.c */ +extern const int _POSIX_THREAD_THREADS_MAX; +extern const int _POSIX_THREAD_DESTRUCTOR_ITERATIONS; +extern const int _POSIX_THREAD_KEYS_MAX; + extern const int _pthread_create_joinable; extern const int _pthread_create_detached; -/* Cancelability attributes */ extern const int _pthread_cancel_enable; extern const int _pthread_cancel_disable; extern const int _pthread_cancel_asynchronous; extern const int _pthread_cancel_deferred; +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS +#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX +#define PTHREAD_THREADS_MAX _POSIX_THREAD_THREADS_MAX + #define PTHREAD_CREATE_JOINABLE _pthread_create_joinable #define PTHREAD_CREATE_DETACHED _pthread_create_detached @@ -35,6 +35,12 @@ #define WAIT_FAILED 1 +/* Priority levels */ + +enum { + THREAD_PRIORITY_NORMAL +}; + /* Error numbers */ enum { @@ -111,15 +117,6 @@ BOOL SetThreadPriority(HANDLE threadHandle, int priority); int GetThreadPriority(HANDLE threadHandle); -HANDLE _beginthreadex(LPSECURITY_ATTRIBUTES security, - DWORD stack, - unsigned (* start_routine)(void *), - LPVOID param, - DWORD flags, - LPDWORD threadID); - -VOID _endthreadex(DWORD); - DWORD GetVersion(VOID); #endif /* WINDOWS_H */ |