cvsuser 03/12/18 09:15:01
Modified: include/parrot thread.h
src thread.c
Log:
parrot-threads-6
* better thread state handling
* cleanup
Revision Changes Path
1.12 +5 -6 parrot/include/parrot/thread.h
Index: thread.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/thread.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -w -r1.11 -r1.12
--- thread.h 18 Dec 2003 16:14:58 -0000 1.11
+++ thread.h 18 Dec 2003 17:14:58 -0000 1.12
@@ -1,7 +1,7 @@
/* thread.h
* Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
* CVS Info
- * $Id: thread.h,v 1.11 2003/12/18 16:14:58 leo Exp $
+ * $Id: thread.h,v 1.12 2003/12/18 17:14:58 leo Exp $
* Overview:
* This is the api header for the thread primitives
* Data Structure and Algorithms:
@@ -55,11 +55,10 @@
#endif
typedef enum {
- THREAD_STATE_NEW, /* initial after malloc */
THREAD_STATE_JOINABLE, /* default */
- THREAD_STATE_DETACHED, /* i.e. non-joinable */
- THREAD_STATE_JOINED, /* JOIN was issued */
- THREAD_STATE_FINISHED /* the thread function has ended */
+ THREAD_STATE_DETACHED = 0x01, /* i.e. non-joinable */
+ THREAD_STATE_JOINED = 0x02, /* JOIN was issued */
+ THREAD_STATE_FINISHED = 0x04 /* the thread function has ended */
} thread_state_enum;
/*
1.4 +55 -14 parrot/src/thread.c
Index: thread.c
===================================================================
RCS file: /cvs/public/parrot/src/thread.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -r1.3 -r1.4
--- thread.c 18 Dec 2003 16:15:10 -0000 1.3
+++ thread.c 18 Dec 2003 17:15:01 -0000 1.4
@@ -1,7 +1,7 @@
/* thread.c
* Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
* CVS Info
- * $Id: thread.c,v 1.3 2003/12/18 16:15:10 leo Exp $
+ * $Id: thread.c,v 1.4 2003/12/18 17:15:01 leo Exp $
* Overview:
* Thread handling stuff
* Data Structure and Algorithms:
@@ -26,13 +26,28 @@
thread_func(void *arg)
{
PMC *self = (PMC*) arg;
+ UINTVAL tid;
+
Parrot_Interp interpreter = PMC_data(self);
runops(interpreter, (opcode_t *)self->cache.struct_val -
(opcode_t *)interpreter->code->byte_code);
+ /*
+ * thread is finito
+ */
+ LOCK(interpreter_array_mutex);
+ interpreter->thread_data->state |= THREAD_STATE_FINISHED;
+ if (interpreter != interpreter_array[tid]) {
+ UNLOCK(interpreter_array_mutex);
+ internal_exception(1, "thread finished: interpreter mismatch");
+ }
+ if ((interpreter->thread_data->state & THREAD_STATE_DETACHED) ||
+ (interpreter->thread_data->state & THREAD_STATE_JOINED)) {
+ interpreter_array[tid] = NULL;
+ }
+ UNLOCK(interpreter_array_mutex);
/*
* TODO pass return value
- * TODO set state and clear interp array
*/
return NULL;
}
@@ -99,7 +114,7 @@
}
/*
- * pt_yield
+ * pt_thread_yield
* religuish the processor
*/
@@ -110,22 +125,27 @@
}
/*
- * helper, check if tid is valid - call holds mutex
+ * helper, check if tid is valid - caller holds mutex
* return interpreter for tid
*/
static Parrot_Interp
-pt_check_tid(UINTVAL tid)
+pt_check_tid(UINTVAL tid, const char *from)
{
if (tid >= n_interpreters) {
UNLOCK(interpreter_array_mutex);
- internal_exception(1, "join: illegal thread tid %d", tid);
+ internal_exception(1, "%s: illegal thread tid %d", from, tid);
+ }
+ if (tid == 0) {
+ UNLOCK(interpreter_array_mutex);
+ internal_exception(1, "%s: llegal thread tid %d (main)", from, tid);
}
if (!interpreter_array[tid]) {
UNLOCK(interpreter_array_mutex);
- internal_exception(1, "join: illegal thread tid %d - empty", tid);
+ internal_exception(1, "%s: illegal thread tid %d - empty", from, tid);
}
return interpreter_array[tid];
}
+
/*
* join (wait for) a joinable thread
*/
@@ -136,13 +156,14 @@
int state;
LOCK(interpreter_array_mutex);
- interpreter = pt_check_tid(tid);
- if (interpreter->thread_data->state == THREAD_STATE_JOINABLE) {
+ interpreter = pt_check_tid(tid, "join");
+ if (interpreter->thread_data->state == THREAD_STATE_JOINABLE ||
+ interpreter->thread_data->state == THREAD_STATE_FINISHED) {
void *retval;
+ interpreter->thread_data->state |= THREAD_STATE_JOINED;
UNLOCK(interpreter_array_mutex);
JOIN(interpreter->thread_data->thread, retval);
LOCK(interpreter_array_mutex);
- interpreter->thread_data->state = THREAD_STATE_JOINED;
UNLOCK(interpreter_array_mutex);
return retval;
}
@@ -161,6 +182,22 @@
void
pt_thread_detach(UINTVAL tid)
{
+ Parrot_Interp interpreter;
+
+ LOCK(interpreter_array_mutex);
+ interpreter = pt_check_tid(tid, "detach");
+ /*
+ * if interpreter is joinable, we detach em
+ */
+ if (interpreter->thread_data->state == THREAD_STATE_JOINABLE ||
+ interpreter->thread_data->state == THREAD_STATE_FINISHED) {
+ DETACH(interpreter->thread_data->thread);
+ interpreter->thread_data->state |= THREAD_STATE_DETACHED;
+ if (interpreter->thread_data->state & THREAD_STATE_FINISHED) {
+ interpreter_array[tid] = NULL;
+ }
+ }
+ UNLOCK(interpreter_array_mutex);
}
/*
@@ -172,13 +209,17 @@
Parrot_Interp interpreter;
LOCK(interpreter_array_mutex);
- interpreter = pt_check_tid(tid);
+ interpreter = pt_check_tid(tid, "kill");
/*
* if interpreter is joinable, we detach em
*/
if (interpreter->thread_data->state == THREAD_STATE_JOINABLE) {
DETACH(interpreter->thread_data->thread);
- interpreter->thread_data->state = THREAD_STATE_DETACHED;
+ interpreter->thread_data->state |= THREAD_STATE_DETACHED;
+ }
+ if (interpreter->thread_data->state & THREAD_STATE_FINISHED) {
+ UNLOCK(interpreter_array_mutex);
+ return;
}
UNLOCK(interpreter_array_mutex);
/*
@@ -193,7 +234,7 @@
/*
* all threaded interpreters are stored in an array
- * assumens that called with LOCK hold
+ * assumes that caller holds LOCK
*/
void
pt_add_to_interpreters(Parrot_Interp interpreter, Parrot_Interp new_interp)