summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog40
-rw-r--r--cancel.c25
-rw-r--r--create.c22
-rw-r--r--exit.c2
-rw-r--r--global.c12
-rw-r--r--implement.h22
-rw-r--r--misc.c15
-rw-r--r--private.c6
-rw-r--r--sched.c8
-rw-r--r--signal.c9
-rw-r--r--sync.c37
11 files changed, 128 insertions, 70 deletions
diff --git a/ChangeLog b/ChangeLog
index 1054549..c6d39e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,45 @@
Tue Jul 28 14:04:29 1998 Ross Johnson <rpj@swan.canberra.edu.au>
+ * implement.h: Add _PTHREAD_VALID macro.
+
+ * sync.c (pthread_join): Modify to use the new thread
+ type and _pthread_delete_thread(). Rename "target" to "thread".
+ Remove extra local variable "target".
+ (pthread_detach): Ditto.
+
+ * signal.c (pthread_sigmask): Move init of "us" out of inner block.
+ Fix instance of "this" should have been "us". Rename "us" to "thread".
+
+ * sched.c (pthread_setschedparam): Modify to use the new thread
+ type.
+ (pthread_getschedparam): Ditto.
+
+ * private.c (_pthread_find_thread): Fix return type and arg.
+
+ * implement.h: Remove _PTHREAD_YES and _PTHREAD_NO.
+ (_pthread_new_thread): Add prototype.
+ (_pthread_find_thread): Ditto.
+ (_pthread_delete_thread): Ditto.
+ (_pthread_new_thread_entry): Remove prototype.
+ (_pthread_find_thread_entry): Ditto.
+ (_pthread_delete_thread_entry): Ditto.
+ ( _PTHREAD_NEW, _PTHREAD_INUSE, _PTHREAD_EXITED, _PTHREAD_REUSE):
+ Add.
+
+
+ * create.c (pthread_create): Minor rename "us" to "new" (I need
+ these cues but it doesn't stop me coming out with some major bugs
+ at times).
+ Load start_routine and arg into the thread so the wrapper can
+ call it.
+
+ * exit.c (pthread_exit): Fix pthread_this should be pthread_self.
+
+ * cancel.c (pthread_setcancelstate): Change
+ _pthread_threads_thread_t * to pthread_t and init with
+ pthread_this().
+ (pthread_setcanceltype): Ditto.
+
* exit.c (_pthread_exit): Add new pthread_t arg.
Rename _pthread_delete_thread_entry to _pthread_delete_thread.
Rename "us" to "thread".
diff --git a/cancel.c b/cancel.c
index 8974e5c..e79ee08 100644
--- a/cancel.c
+++ b/cancel.c
@@ -12,7 +12,7 @@ int
pthread_setcancelstate(int state,
int *oldstate)
{
- _pthread_threads_thread_t * us = _PTHREAD_THIS;
+ pthread_t us = pthread_self();
/* Validate the new cancellation state. */
if (state != PTHREAD_CANCEL_ENABLE
@@ -33,7 +33,7 @@ pthread_setcancelstate(int state,
int
pthread_setcanceltype(int type, int *oldtype)
{
- _pthread_threads_thread_t * us = _PTHREAD_THIS;
+ pthread_t us = pthread_self();
/* Validate the new cancellation type. */
if (type != PTHREAD_CANCEL_DEFERRED
@@ -54,32 +54,29 @@ pthread_setcanceltype(int type, int *oldtype)
int
pthread_cancel(pthread_t thread)
{
- _pthread_threads_thread_t * us = _PTHREAD_THIS;
-
- if (us == NULL)
+ if (_PTHREAD_VALID(thread)
+ && thread->ptstatus != _PTHREAD_REUSE)
{
- return ESRCH;
+ thread->cancel_pending = TRUE;
+ return 0;
}
- us->cancel_pending = TRUE;
-
- return 0;
+ return ESRCH;
}
void
pthread_testcancel(void)
{
- _pthread_threads_thread_t * us;
+ pthread_t thread;
- us = _PTHREAD_THIS;
+ thread = pthread_self();
- if (us == NULL
- || us->cancelstate == PTHREAD_CANCEL_DISABLE)
+ if (thread->cancelstate == PTHREAD_CANCEL_DISABLE)
{
return;
}
- if (us->cancel_pending == TRUE)
+ if (thread->cancel_pending == TRUE)
{
pthread_exit(PTHREAD_CANCELED);
diff --git a/create.c b/create.c
index 71744c9..d4218d1 100644
--- a/create.c
+++ b/create.c
@@ -17,7 +17,7 @@ unsigned
_pthread_start_call(void * us_arg)
{
/* We're now in a running thread. Any local variables here are on
- this threads private stack so we're safe to leave data in them
+ this thread's private stack so we're safe to leave data in them
until we leave. */
pthread_t us;
_pthread_call_t * call;
@@ -56,21 +56,21 @@ pthread_create(pthread_t *thread,
void * security = NULL;
DWORD threadID;
pthread_attr_t * attr_copy;
- pthread_t us;
+ pthread_t new;
/* Success unless otherwise set. */
int ret;
/* CRITICAL SECTION */
pthread_mutex_lock(&_pthread_table_mutex);
- ret = _pthread_new_thread(&us);
+ ret = _pthread_new_thread(&new);
pthread_mutex_lock(&_pthread_table_mutex);
/* END CRITICAL SECTION */
if (ret == 0)
{
- attr_copy = &(us->attr);
+ attr_copy = &(new->attr);
/* Map given attributes otherwise just use default values. */
if (attr != NULL)
@@ -88,13 +88,17 @@ pthread_create(pthread_t *thread,
#endif /* HAVE_SIGSET_T */
}
+ /* We call a generic wrapper which then calls the start routine. */
+ new->call.routine = start_routine;
+ new->call.arg = arg;
+
/* Start running, not suspended. */
flags = 0;
handle = (HANDLE) _beginthreadex(security,
attr_copy->stacksize,
_pthread_start_call,
- (void *) us,
+ (void *) new,
flags,
&threadID);
@@ -111,9 +115,9 @@ pthread_create(pthread_t *thread,
if (ret == 0)
{
/* Let the caller know the thread handle. */
- us->win32handle = handle;
- us->ptstatus = _PTHREAD_INUSE;
- *thread = (pthread_t) us;
+ new->win32handle = handle;
+ new->ptstatus = _PTHREAD_INUSE;
+ *thread = new;
}
else
{
@@ -121,7 +125,7 @@ pthread_create(pthread_t *thread,
pthread_mutex_lock(&_pthread_table_mutex);
/* Remove the failed thread entry. */
- _pthread_delete_thread(us);
+ _pthread_delete_thread(new);
pthread_mutex_lock(&_pthread_table_mutex);
/* END CRITICAL SECTION */
diff --git a/exit.c b/exit.c
index e74c843..93d8a0b 100644
--- a/exit.c
+++ b/exit.c
@@ -69,5 +69,5 @@ _pthread_exit(pthread_t thread, void * value, int return_code)
void
pthread_exit(void * value)
{
- _pthread_exit(pthread_this(), value, 0);
+ _pthread_exit(pthread_self(), value, 0);
}
diff --git a/global.c b/global.c
index 8b317b9..9db37af 100644
--- a/global.c
+++ b/global.c
@@ -38,8 +38,16 @@ pthread_mutex_t _pthread_table_mutex = PTHREAD_MUTEX_INITIALIZER;
DWORD _pthread_threads_count = 0;
-/* Per thread management storage. */
-_pthread_threads_thread_t _pthread_threads_table[PTHREAD_THREADS_MAX];
+/* Per thread management storage. See comments in private.c */
+_pthread_t _pthread_virgins[PTHREAD_THREADS_MAX];
+
+int _pthread_virgin_next = 0;
+
+pthread_t _pthread_reuse[PTHREAD_THREADS_MAX];
+
+int _pthread_reuse_top = -1;
+
+pthread_t _pthread_win32handle_map[PTHREAD_THREADS_MAX];
/* Per thread mutex locks. */
pthread_mutex_t _pthread_threads_mutex_table[PTHREAD_THREADS_MAX];
diff --git a/implement.h b/implement.h
index c19e6b9..5ee9ba3 100644
--- a/implement.h
+++ b/implement.h
@@ -9,8 +9,17 @@
#define _PTHREAD_HASH_INDEX(x) (((ULONG) x) % PTHREAD_THREADS_MAX)
-#define _PTHREAD_YES 1
-#define _PTHREAD_NO 0
+enum {
+ _PTHREAD_NEW,
+ _PTHREAD_INUSE,
+ _PTHREAD_EXITED,
+ _PTHREAD_REUSE
+};
+
+#define _PTHREAD_VALID(T) \
+ (T) != NULL \
+ && ((T)->ptstatus == _PTHREAD_NEW
+ || (T)->ptstatus == _PTHREAD_INUSE)
/* Handler execution flags. */
#define _PTHREAD_HANDLER_NOEXECUTE 0
@@ -103,18 +112,17 @@ void _pthread_handler_pop_all(int stack,
/* Primitives to manage threads table entries. */
-int _pthread_new_thread_entry(pthread_t thread,
- _pthread_threads_thread_t * entry);
+int _pthread_new_thread(pthread_t * thread);
-_pthread_threads_thread_t * _pthread_find_thread_entry(pthread_t thread);
+pthread_t _pthread_find_thread(HANDLE win32handle);
-void _pthread_delete_thread_entry(_pthread_threads_thread_t * this);
+int _pthread_delete_thread(pthread_t thread);
/* Thread cleanup. */
void _pthread_vacuum(void);
-void _pthread_exit(void * value, int return_code);
+void _pthread_exit(pthread_t thread, void * value, int return_code);
#ifdef __cplusplus
}
diff --git a/misc.c b/misc.c
index 60dbb4a..9834630 100644
--- a/misc.c
+++ b/misc.c
@@ -49,15 +49,22 @@ pthread_self(void)
that all of the Win32 functions we are going to use only need
HANDLEs. The morons. */
+ /* FIXME: Need a new lookup method with the new thread allocation
+ scheme.
+
+ We can use the Win32 handle though as a basis (perhaps
+ to look up a table) because pthread_self() will never be called
+ after the Win32 thread has terminated (unless we can raise
+ ourselves from the dead!), and therefore the Win32 handle cannot
+ have been reused yet. */
+
+#if 0
return GetCurrentThread();
+#endif
}
int
pthread_equal(pthread_t t1, pthread_t t2)
{
- /* For the time being, assume that HANDLEs can be directly compared.
- If not, then use the appropriate Win32 function for
- comparison. */
-
return (t1 != t2);
}
diff --git a/private.c b/private.c
index db26563..8206b7e 100644
--- a/private.c
+++ b/private.c
@@ -135,10 +135,10 @@ _pthread_new_thread(pthread_t * thread)
return 0;
}
-_pthread_threads_thread *
-_pthread_find_thread(pthread_t thread)
+pthread_t
+_pthread_find_thread((HANDLE) win32handle)
{
- /* Should no longer be needed */
+ /* FIXME: No-op at present */
}
int
diff --git a/sched.c b/sched.c
index 21780c6..e29e684 100644
--- a/sched.c
+++ b/sched.c
@@ -36,7 +36,7 @@ int pthread_setschedparam(pthread_t thread, int policy,
const struct sched_param *param)
{
/* Validate the thread id. */
- if (_pthread_find_thread_entry(thread) < 0)
+ if (_PTHREAD_VALID(thread) < 0)
{
return EINVAL;
}
@@ -61,7 +61,7 @@ int pthread_setschedparam(pthread_t thread, int policy,
}
/* This is practically guaranteed to return TRUE. */
- (void) SetThreadPriority(thread, param->sched_policy);
+ (void) SetThreadPriority(thread->win32handle, param->sched_policy);
return 0;
}
@@ -71,7 +71,7 @@ int pthread_getschedparam(pthread_t thread, int *policy,
int prio;
/* Validate the thread id. */
- if (_pthread_find_thread_entry(thread) < 0)
+ if (_PTHREAD_VALID(thread) != 0)
{
return EINVAL;
}
@@ -86,7 +86,7 @@ int pthread_getschedparam(pthread_t thread, int *policy,
*policy = SCHED_OTHER;
/* Fill out the sched_param structure. */
- prio = GetThreadPriority(thread);
+ prio = GetThreadPriority(thread->win32handle);
if (prio == THREAD_PRIORITY_ERROR_RETURN)
{
return EINVAL;
diff --git a/signal.c b/signal.c
index 888319d..77fa0dd 100644
--- a/signal.c
+++ b/signal.c
@@ -10,6 +10,8 @@
int
pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
{
+ pthread_t thread = pthread_self();
+
/* Validate the `how' argument.*/
if (set != NULL)
{
@@ -30,19 +32,18 @@ pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
/* Copy the old mask before modifying it. */
if (oset != NULL)
{
- memcpy(oset, this->attr->sigmask, sizeof(sigset_t));
+ memcpy(oset, thread->attr.sigmask, sizeof(sigset_t));
}
if (set != NULL)
{
- _pthread_threads_thread_t * us = _PTHREAD_THIS;
int i;
/* FIXME: this code assumes that sigmask is an even multiple of
the size of a long integer. */
unsigned long *src = set;
- unsigned long *dest = us->attr.sigmask;
+ unsigned long *dest = thread->attr.sigmask;
switch (how)
{
@@ -61,7 +62,7 @@ pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
}
case SIG_SET:
/* Replace the whole sigmask. */
- memcpy(us->attr.sigmask, set, sizeof(sigset_t));
+ memcpy(thread->attr.sigmask, set, sizeof(sigset_t));
break;
}
}
diff --git a/sync.c b/sync.c
index 7483598..69a10f6 100644
--- a/sync.c
+++ b/sync.c
@@ -57,7 +57,6 @@ pthread_join(pthread_t thread, void ** valueptr)
{
LPDWORD exitcode;
int detachstate;
- _pthread_threads_thread_t * target;
/* First check if we are trying to join to ourselves. */
if (thread == pthread_self())
@@ -65,15 +64,12 @@ pthread_join(pthread_t thread, void ** valueptr)
return EDEADLK;
}
- /* Find the thread. */
- target = _pthread_find_thread_entry(thread);
-
- if (target != NULL)
+ if (thread != NULL)
{
pthread_mutex_t * target_thread_mutex;
int ret;
- target_thread_mutex = _PTHREAD_THREAD_MUTEX(target);
+ target_thread_mutex = _PTHREAD_THREAD_MUTEX(thread);
/* CRITICAL SECTION */
pthread_mutex_lock(&_pthread_table_mutex);
@@ -81,13 +77,13 @@ pthread_join(pthread_t thread, void ** valueptr)
/* If the thread is in DETACHED state, then join will return
immediately. */
- if (pthread_attr_getdetachedstate(&(target->attr), &detachstate) != 0
+ if (pthread_attr_getdetachedstate(&(thread->attr), &detachstate) != 0
|| detachstate == PTHREAD_CREATE_DETACHED)
{
return EINVAL;
}
- target->join_count++;
+ thread->join_count++;
pthread_mutex_lock(&_pthread_table_mutex);
/* END CRITICAL SECTION */
@@ -96,7 +92,7 @@ pthread_join(pthread_t thread, void ** valueptr)
pthread_testcancel();
/* Wait on the kernel thread object. */
- switch (WaitForSingleObject(thread, INFINITE))
+ switch (WaitForSingleObject(thread->win32handle, INFINITE))
{
case WAIT_FAILED:
/* The thread does not exist. */
@@ -121,27 +117,27 @@ pthread_join(pthread_t thread, void ** valueptr)
/* Collect the value pointer passed to pthread_exit(). If
another thread detaches our target thread while we're
waiting, then we report a deadlock as it likely that storage
- pointed to by target->joinvalueptr has been freed or
+ pointed to by thread->joinvalueptr has been freed or
otherwise no longer valid. */
- if (pthread_attr_getdetachedstate(&(target->attr), &detachstate) != 0
+ if (pthread_attr_getdetachedstate(&(thread->attr), &detachstate) != 0
|| detachstate == PTHREAD_CREATE_DETACHED)
{
ret = EDEADLK;
}
else
{
- *value_ptr = target->joinvalueptr;
+ *value_ptr = thread->joinvalueptr;
ret = 0;
}
- target->join_count--;
+ thread->join_count--;
/* If we're the last join to return then we are responsible for
removing the target thread's table entry. */
- if (target->join_count == 0)
+ if (thread->join_count == 0)
{
- _pthread_delete_thread_entry(target);
+ ret = _pthread_delete_thread(thread);
}
pthread_mutex_lock(&_pthread_table_mutex);
@@ -157,7 +153,6 @@ pthread_join(pthread_t thread, void ** valueptr)
int
pthread_detach(pthread_t thread)
{
- _pthread_threads_thread_t * target;
int detachstate;
int ret;
pthread_mutex_t * target_thread_mutex;
@@ -165,19 +160,17 @@ pthread_detach(pthread_t thread)
/* CRITICAL SECTION */
pthread_mutex_lock(&_pthread_table_mutex);
- target = _pthread_find_thread_entry(thread);
-
- if (target == NULL)
+ if (thread == NULL)
{
ret = ESRCH;
}
else
{
- target_thread_mutex = _PTHREAD_THREAD_MUTEX(target);
+ target_thread_mutex = _PTHREAD_THREAD_MUTEX(thread);
/* Check that we can detach this thread. */
- if (pthread_attr_getdetachedstate(&(target->attr), &detachstate) != 0
+ if (pthread_attr_getdetachedstate(&(thread->attr), &detachstate) != 0
|| detachstate == PTHREAD_CREATE_DETACHED)
{
ret = EINVAL;
@@ -188,7 +181,7 @@ pthread_detach(pthread_t thread)
/* 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(&(target->attr),
+ pthread_attr_setdetachedstate(&(thread->attr),
PTHREAD_CREATE_DETACHED);
ret = 0;