From ee95385721e0dbd4ba637e78b30101f1c9d24e75 Mon Sep 17 00:00:00 2001 From: rpj Date: Sat, 25 Jul 1998 14:26:49 +0000 Subject: Sun Jul 26 00:09:59 1998 Ross Johnson * private.c (_pthread_delete_thread_entry): Mutex locks removed. Mutexes must be applied at the caller level. (_pthread_new_thread_entry): Ditto. (_pthread_new_thread_entry): Init cancelstate, canceltype, and cancel_pending to default values. (_pthread_new_thread_entry): Rename "this" to "new". (_pthread_find_thread_entry): Rename "this" to "entry". (_pthread_delete_thread_entry): Rename "thread_entry" to "entry". * create.c (_pthread_start_call): Mutexes changed to _pthread_count_mutex. All access to the threads table entries is under the one mutex. Otherwise chaos reigns. Sat Jul 25 23:16:51 1998 Ross Johnson * implement.h (_pthread_threads_thread): Move cancelstate and canceltype members out of pthread_attr_t into here. --- ChangeLog | 22 +++++++++++++++++++ cancel.c | 35 +++++++++++++++--------------- create.c | 15 ++++++------- implement.h | 7 +++++- private.c | 71 ++++++++++++++++++++++++++----------------------------------- pthread.h | 6 ------ sync.c | 56 ++++++++++++++++++++++++++++++++++-------------- 7 files changed, 122 insertions(+), 90 deletions(-) diff --git a/ChangeLog b/ChangeLog index 18ed5cd..ea0fdcc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +Sun Jul 26 00:09:59 1998 Ross Johnson + + * private.c (_pthread_delete_thread_entry): Mutex locks removed. + Mutexes must be applied at the caller level. + (_pthread_new_thread_entry): Ditto. + (_pthread_new_thread_entry): Init cancelstate, canceltype, and + cancel_pending to default values. + (_pthread_new_thread_entry): Rename "this" to "new". + (_pthread_find_thread_entry): Rename "this" to "entry". + (_pthread_delete_thread_entry): Rename "thread_entry" to "entry". + + * create.c (_pthread_start_call): Mutexes changed to + _pthread_count_mutex. All access to the threads table entries is + under the one mutex. Otherwise chaos reigns. + +Sat Jul 25 23:16:51 1998 Ross Johnson + + * implement.h (_pthread_threads_thread): Move cancelstate and + canceltype members out of pthread_attr_t into here. + + * fork.c (fork): Add comment. + 1998-07-25 Ben Elliston * fork.c (fork): Autoconfiscate. diff --git a/cancel.c b/cancel.c index e9e33f1..1b48b28 100644 --- a/cancel.c +++ b/cancel.c @@ -6,6 +6,7 @@ */ #include "pthread.h" +#include "implement.h" int pthread_setcancelstate(int state, @@ -14,53 +15,53 @@ pthread_setcancelstate(int state, _pthread_threads_thread_t * this = *_PTHREAD_THIS; /* Validate the new cancellation state. */ - if (state != PTHREAD_CANCEL_ENABLE || state != PTHREAD_CANCEL_DISABLE) + if (state != PTHREAD_CANCEL_ENABLE + || state != PTHREAD_CANCEL_DISABLE) { return EINVAL; } if (oldstate != NULL) { - *oldstate = this->cancelability; + *oldstate = this->cancelstate; } - this->cancelability = state; + this->cancelstate = state; return 0; } int pthread_setcanceltype(int type, int *oldtype) { - _pthread_threads_thread_t * this = *_PTHREAD_THIS; + _pthread_threads_thread_t * us = _PTHREAD_THIS; /* Validate the new cancellation type. */ - if (type != PTHREAD_CANCEL_DEFERRED || type != PTHREAD_CANCEL_ASYNCHRONOUS) + if (type != PTHREAD_CANCEL_DEFERRED + || type != PTHREAD_CANCEL_ASYNCHRONOUS) { return EINVAL; } if (oldtype != NULL) { - *oldtype = this->canceltype; + *oldtype = us->canceltype; } - this->canceltype = type; + us->canceltype = type; return 0; } int pthread_cancel(pthread_t thread) { - _pthread_threads_thread_t * this; - - this = _PTHREAD_THIS; + _pthread_threads_thread_t * us = _PTHREAD_THIS; - if (this == NULL) + if (us == NULL) { return ESRCH; } - this->cancelthread = _PTHREAD_YES; + us->cancel_pending = TRUE; return 0; } @@ -68,17 +69,17 @@ pthread_cancel(pthread_t thread) void pthread_testcancel(void) { - _pthread_threads_thread_t * this; + _pthread_threads_thread_t * us; - this = _PTHREAD_THIS; + us = _PTHREAD_THIS; - if (this == NULL || - this->attr.cancelstate == PTHREAD_CANCEL_DISABLE) + if (us == NULL + || us->cancelstate == PTHREAD_CANCEL_DISABLE) { return; } - if (this->cancelthread == _PTHREAD_YES) + if (us->cancel_pending == TRUE) { pthread_exit(PTHREAD_CANCELED); diff --git a/create.c b/create.c index 2a94baf..8cc5a57 100644 --- a/create.c +++ b/create.c @@ -20,7 +20,6 @@ _pthread_start_call(void * us_arg) this threads private stack so we're safe to leave data in them until we leave. */ _pthread_threads_thread__t * us; - pthread_mutex_t * us_thread_mutex; _pthread_call_t * call; unsigned (*func)(void *); void * arg; @@ -39,8 +38,6 @@ _pthread_start_call(void * us_arg) func = us->call.routine; arg = us->call.arg; - us_thread_mutex = _PTHREAD_THREAD_MUTEX(us); - /* FIXME: Should we be using sigsetjmp() here instead. */ from = setjmp(us->call.env); @@ -55,7 +52,7 @@ _pthread_start_call(void * us_arg) was called and there are no waiting joins. */ /* CRITICAL SECTION */ - pthread_mutex_lock(us_thread_mutex); + pthread_mutex_lock(&_pthread_count_mutex); if (us->detach == TRUE && us->join_count == 0) @@ -63,7 +60,7 @@ _pthread_start_call(void * us_arg) _pthread_delete_thread_entry(us); } - pthread_mutex_lock(us_thread_mutex); + pthread_mutex_lock(&_pthread_count_mutex); /* END CRITICAL SECTION */ } else @@ -76,7 +73,7 @@ _pthread_start_call(void * us_arg) was called and there are no waiting joins. */ /* CRITICAL SECTION */ - pthread_mutex_lock(us_thread_mutex); + pthread_mutex_lock(&_pthread_count_mutex); if (us->detach == TRUE && us->join_count == 0) @@ -84,7 +81,7 @@ _pthread_start_call(void * us_arg) _pthread_delete_thread_entry(us); } - pthread_mutex_lock(us_thread_mutex); + pthread_mutex_lock(&_pthread_count_mutex); /* END CRITICAL SECTION */ ret = 0; @@ -130,10 +127,10 @@ pthread_create(pthread_t *thread, #if HAVE_SIGSET_T memcpy(&(attr_copy->sigmask), &(attr->sigmask), sizeof(sigset_t)); #endif /* HAVE_SIGSET_T */ - - this->detach = (attr->detachedstate == PTHREAD_CREATE_DETACHED); } + this->detach = (attr->detachedstate == PTHREAD_CREATE_DETACHED); + /* Start running, not suspended. */ flags = 0; diff --git a/implement.h b/implement.h index 807bf0e..3216573 100644 --- a/implement.h +++ b/implement.h @@ -62,7 +62,12 @@ struct _pthread_threads_thread { pthread_t thread; pthread_attr_t attr; _pthread_call_t call; - int cancelthread; + int cancel_pending; + int cancelstate; /* PTHREAD_CANCEL_DISABLE + PTHREAD_CANCEL_ENABLE */ + + int canceltype; /* PTHREAD_CANCEL_ASYNCHRONOUS + PTHREAD_CANCEL_DEFERRED */ void ** joinvalueptr; int join_count; _pthread_handler_node_t * cleanupstack; diff --git a/private.c b/private.c index d77f0b2..cee84e9 100644 --- a/private.c +++ b/private.c @@ -6,8 +6,6 @@ * the implementation and may be used throughout it. */ -#include -#include #include "pthread.h" #include "implement.h" @@ -27,51 +25,48 @@ int _pthread_new_thread_entry(pthread_t thread, _pthread_threads_thread_t * entry) { - _pthread_threads_thread_t * this; - - /* CRITICAL SECTION */ - pthread_mutex_lock(&_pthread_count_mutex); + _pthread_threads_thread_t * new; if (_pthread_threads_count >= PTHREAD_THREADS_MAX) { return EAGAIN; } - this = &_pthread_threads_table[_PTHREAD_HASH_INDEX(thread)]; + new = &_pthread_threads_table[_PTHREAD_HASH_INDEX(thread)]; - while (this->thread != NULL) + while (new->thread != NULL) { - this++; + new++; - if (this == &_pthread_threads_table[PTHREAD_THREADS_MAX]) + if (new == &_pthread_threads_table[PTHREAD_THREADS_MAX]) { /* Wrap to the top of the table. */ - this == _pthread_threads_table; + new == _pthread_threads_table; } } - if (this->thread != NULL) + if (new->thread != NULL) { /* INTERNAL ERROR: There should be at least one slot left. */ return ESRCH; } else { - this->thread = thread; - pthread_attr_init(&(this->attr)); - this->joinvalueptr = NULL; - this->cleanupstack = NULL; - this->destructorstack = NULL; - this->forkpreparestack = NULL; - this->forkparentstack = NULL; - this->forkchildstack = NULL; + new->thread = thread; + pthread_attr_init(&(new->attr)); + new->joinvalueptr = NULL; + new->cancelstate = PTHREAD_CANCEL_ENABLE; + new->canceltype = PTHREAD_CANCEL_DEFERRED; + new->cancel_pending = FALSE; + new->cleanupstack = NULL; + new->destructorstack = NULL; + new->forkpreparestack = NULL; + new->forkparentstack = NULL; + new->forkchildstack = NULL; } _pthread_threads_count++; - entry = this; - - pthread_mutex_unlock(&_pthread_count_mutex); - /* END CRITICAL SECTION */ + entry = new; return 0; } @@ -79,45 +74,42 @@ _pthread_new_thread_entry(pthread_t thread, _pthread_threads_thread_t * entry) _pthread_threads_thread * _pthread_find_thread_entry(pthread_t thread) { - _pthread_threads_thread_t * this; + _pthread_threads_thread_t * entry; _pthread_threads_thread_t * start; - start = this = &_pthread_threads_table[_PTHREAD_HASH_INDEX(thread)]; + start = entry = &_pthread_threads_table[_PTHREAD_HASH_INDEX(thread)]; - while (this->thread != thread) + while (entry->thread != thread) { - this++; + entry++; - if (this == &_pthread_threads_table[PTHREAD_THREADS_MAX]) + if (entry == &_pthread_threads_table[PTHREAD_THREADS_MAX]) { /* Wrap to top of table. */ - this = _pthread_threads_table; + entry = _pthread_threads_table; } } - if (this->thread == NULL || this == start) + if (entry->thread == NULL || entry == start) { /* Failed to find the thread. */ return NULL; } - return this; + return entry; } void -_pthread_delete_thread_entry(_pthread_threads_thread_t * thread_entry) +_pthread_delete_thread_entry(_pthread_threads_thread_t * entry) { /* We don't check that the thread has been properly cleaned up, so it had better be done already. */ - /* CRITICAL SECTION */ - pthread_mutex_lock(&_pthread_count_mutex); - /* Remove the thread entry if necessary. */ - if (thread_entry->thread != NULL) + if (entry->thread != NULL) { - thread_entry->thread = NULL; + entry->thread = NULL; if (_pthread_threads_count > 0) { @@ -132,7 +124,4 @@ _pthread_delete_thread_entry(_pthread_threads_thread_t * thread_entry) { /* FIXME: INTERNAL ERROR: This should not happen. */ } - - pthread_mutex_unlock(&_pthread_count_mutex); - /* END CRITICAL SECTION */ } diff --git a/pthread.h b/pthread.h index 0c0036b..cce502a 100644 --- a/pthread.h +++ b/pthread.h @@ -88,15 +88,9 @@ typedef struct { size_t stacksize; /* PTHREAD_STACK_MIN */ #endif - int cancelstate; /* PTHREAD_CANCEL_DISABLE - PTHREAD_CANCEL_ENABLE */ - int detachedstate; /* PTHREAD_CREATE_DETACHED PTHREAD_CREATE_JOINABLE */ - int canceltype; /* PTHREAD_CANCEL_ASYNCHRONOUS - PTHREAD_CANCEL_DEFERRED */ - #ifdef HAVE_SIGSET_T sigset_t sigmask; #endif /* HAVE_SIGSET_T */ diff --git a/sync.c b/sync.c index 84d9bd9..e9b5bc2 100644 --- a/sync.c +++ b/sync.c @@ -76,21 +76,25 @@ pthread_join(pthread_t thread, void ** valueptr) target_thread_mutex = _PTHREAD_THREAD_MUTEX(target); /* CRITICAL SECTION */ - pthread_mutex_lock(target_thread_mutex); + pthread_mutex_lock(&_pthread_count_mutex); /* If the thread is in DETACHED state, then join will return immediately. */ - if (target->detach == TRUE) + if (pthread_attr_getdetachedstate(&(target->attr), &detachstate) != 0 + || detachstate == PTHREAD_CREATE_DETACHED) { return EINVAL; } target->join_count++; - pthread_mutex_lock(target_thread_mutex); + pthread_mutex_lock(&_pthread_count_mutex); /* END CRITICAL SECTION */ + /* CANCELATION POINT */ + pthread_testcancel(); + /* Wait on the kernel thread object. */ switch (WaitForSingleObject(thread, INFINITE)) { @@ -152,26 +156,46 @@ pthread_join(pthread_t thread, void ** valueptr) int pthread_detach(pthread_t thread) { - _pthread_threads_thread_t * this; + _pthread_threads_thread_t * target; int detachstate; + int ret; + pthread_mutex_t * target_thread_mutex; - this = _pthread_find_thread_entry(thread); + /* CRITICAL SECTION */ + pthread_mutex_lock(&_pthread_count_mutex); - if (this == NULL) + target = _pthread_find_thread_entry(thread); + + if (target == NULL) { - return ESRCH; + ret = ESRCH; } - - /* Check that we can detach this thread. */ - if (pthread_attr_getdetachedstate(&(this->attr), &detachstate) != 0 - || detachstate == PTHREAD_CREATE_DETACHED) + else { - return EINVAL; + + target_thread_mutex = _PTHREAD_THREAD_MUTEX(target); + + /* Check that we can detach this thread. */ + if (pthread_attr_getdetachedstate(&(target->attr), &detachstate) != 0 + || detachstate == PTHREAD_CREATE_DETACHED) + { + ret = EINVAL; + } + else + { + + /* This is all we do here - the rest is done either when the + thread exits or when pthread_join() exits. Once this is + set it will never be unset. */ + pthread_attr_setdetachedstate(&(this->attr), + PTHREAD_CREATE_DETACHED); + + ret = 0; + } } - /* This is all we do here - the rest is done either when the thread - exits or when pthread_join() exits. */ - this->detach = TRUE; + pthread_mutex_unlock(&_pthread_count_mutex); + /* END CRITICAL SECTION */ - return 0; + return ret; } -- cgit v1.2.3