07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | #include "global.h"
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | RCSID("$Id: threads.c,v 1.75 1998/07/10 15:52:06 grubba Exp $");
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | |
int num_threads = 1;
int threads_disabled = 0;
#ifdef _REENTRANT
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | #include "threads.h"
#include "array.h"
#include "object.h"
|
bb55f8 | 1997-03-16 | Fredrik Hübinette (Hubbe) | | #include "pike_macros.h"
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | #include "callback.h"
|
9c6f7d | 1997-04-15 | Fredrik Hübinette (Hubbe) | | #include "builtin_functions.h"
#include "constants.h"
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | #include "program.h"
|
c5b96b | 1997-11-11 | Henrik Grubbström (Grubba) | | #include "gc.h"
|
3c0c28 | 1998-01-26 | Fredrik Hübinette (Hubbe) | | #include "main.h"
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
ef1e93 | 1998-03-26 | Henrik Grubbström (Grubba) | | int live_threads = 0;
COND_T live_threads_change;
COND_T threads_disabled_change;
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | #ifdef __NT__
#ifdef DEBUG
static int IsValidHandle(HANDLE h)
{
__try {
HANDLE ret;
if(DuplicateHandle(GetCurrentProcess(),
h,
GetCurrentProcess(),
&ret,
NULL,
0,
DUPLICATE_SAME_ACCESS))
{
CloseHandle(ret);
}
}
__except (1) {
return 0;
}
return 1;
}
void CheckValidHandle(HANDLE h)
{
if(!IsValidHandle((HANDLE)h))
fatal("Invalid handle!\n");
}
#endif
#endif
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | #ifdef SIMULATE_COND_WITH_EVENT
int co_wait(COND_T *c, MUTEX_T *m)
{
struct cond_t_queue me;
event_init(&me.event);
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | me.next=0;
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | mt_lock(& c->lock);
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | if(c->tail)
{
c->tail->next=&me;
c->tail=&me;
}else{
c->head=c->tail=&me;
}
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | |
mt_unlock(& c->lock);
mt_unlock(m);
event_wait(&me.event);
mt_lock(m);
event_destroy(& me.event);
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(me.next)
fatal("Wait on event return prematurely!!\n");
#endif
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | return 0;
}
int co_signal(COND_T *c)
{
struct cond_t_queue *t;
mt_lock(& c->lock);
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | if((t=c->head))
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | {
c->head=t->next;
t->next=0;
if(!c->head) c->tail=0;
}
mt_unlock(& c->lock);
if(t)
event_signal(& t->event);
return 0;
}
int co_broadcast(COND_T *c)
{
struct cond_t_queue *t,*n;
mt_lock(& c->lock);
n=c->head;
c->head=c->tail=0;
mt_unlock(& c->lock);
while((t=n))
{
n=t->next;
|
dc7cc9 | 1998-01-14 | Fredrik Hübinette (Hubbe) | | t->next=0;
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | event_signal(& t->event);
}
return 0;
}
int co_destroy(COND_T *c)
{
struct cond_t_queue *t;
mt_lock(& c->lock);
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | t=c->head;
mt_unlock(& c->lock);
if(t) return -1;
mt_destroy(& c->lock);
|
e42eaf | 1998-01-02 | Fredrik Hübinette (Hubbe) | | return 0;
}
#endif
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | #define THIS_THREAD ((struct thread_state *)fp->current_storage)
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | struct object *thread_id;
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | static struct callback *threads_evaluator_callback=0;
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | int thread_id_result_variable;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | MUTEX_T interpreter_lock, thread_table_lock, interleave_lock;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | struct program *mutex_key = 0;
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | struct program *thread_id_prog = 0;
|
97ffe4 | 1997-01-26 | Per Hedbor | | #ifdef POSIX_THREADS
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | pthread_attr_t pattr;
|
864d3c | 1998-01-29 | Fredrik Hübinette (Hubbe) | | pthread_attr_t small_pattr;
|
97ffe4 | 1997-01-26 | Per Hedbor | | #endif
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | struct thread_starter
{
struct object *id;
struct array *args;
};
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | static volatile IMUTEX_T *interleave_list = NULL;
void init_threads_disable(struct object *o)
{
if (!threads_disabled) {
THREADS_FPRINTF(0, (stderr, "init_threads_disable(): Locking IM's...\n"));
if (thread_id) {
IMUTEX_T *im;
THREADS_ALLOW();
mt_lock(&interleave_lock);
im = (IMUTEX_T *)interleave_list;
while(im) {
mt_lock(&(im->lock));
im = im->next;
}
THREADS_DISALLOW();
} else {
IMUTEX_T *im;
mt_lock(&interleave_lock);
im = (IMUTEX_T *)interleave_list;
while(im) {
mt_lock(&(im->lock));
im = im->next;
}
}
THREADS_FPRINTF(0,
(stderr, "init_threads_disable(): Disabling threads.\n"));
threads_disabled = 1;
} else {
threads_disabled++;
}
THREADS_FPRINTF(0, (stderr, "init_threads_disable(): threads_disabled:%d\n",
threads_disabled));
while (live_threads) {
THREADS_FPRINTF(0,
(stderr,
"_disable_threads(): Waiting for %d threads to finish\n",
live_threads));
co_wait(&live_threads_change, &interpreter_lock);
}
}
|
de413f | 1998-03-26 | Per Hedbor | | void exit_threads_disable(struct object *o)
{
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr, "exit_threads_disable(): threads_disabled:%d\n",
threads_disabled));
|
40e949 | 1998-07-05 | Henrik Grubbström (Grubba) | | if(threads_disabled) {
if(!--threads_disabled) {
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | IMUTEX_T *im = (IMUTEX_T *)interleave_list;
while(im) {
THREADS_FPRINTF(0,
(stderr,
"exit_threads_disable(): Unlocking IM 0x%08p\n", im));
mt_unlock(&(im->lock));
im = im->next;
}
mt_unlock(&interleave_lock);
THREADS_FPRINTF(0, (stderr, "_exit_threads_disable(): Wake up!\n"));
|
2202fe | 1998-04-23 | Fredrik Hübinette (Hubbe) | | co_broadcast(&threads_disabled_change);
|
40e949 | 1998-07-05 | Henrik Grubbström (Grubba) | | }
#ifdef DEBUG
} else {
fatal("exit_threads_disable() called too many times!\n");
#endif /* DEBUG */
}
|
de413f | 1998-03-26 | Per Hedbor | | }
|
063fe3 | 1998-03-10 | Per Hedbor | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | void init_interleave_mutex(IMUTEX_T *im)
|
063fe3 | 1998-03-10 | Per Hedbor | | {
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | mt_init(&(im->lock));
|
6e1db5 | 1998-07-09 | Henrik Grubbström (Grubba) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr,
"init_interleave_mutex(): init_threads_disable()\n"));
|
6e1db5 | 1998-07-09 | Henrik Grubbström (Grubba) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | init_threads_disable(NULL);
|
6e1db5 | 1998-07-09 | Henrik Grubbström (Grubba) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr,
"init_interleave_mutex(): Locking IM 0x%08p\n", im));
|
6e1db5 | 1998-07-09 | Henrik Grubbström (Grubba) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | |
mt_lock(&(im->lock));
im->next = (IMUTEX_T *)interleave_list;
if (interleave_list) {
interleave_list->prev = im;
|
6e1db5 | 1998-07-09 | Henrik Grubbström (Grubba) | | }
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | interleave_list = im;
im->prev = NULL;
|
6e1db5 | 1998-07-09 | Henrik Grubbström (Grubba) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr,
"init_interleave_mutex(): exit_threads_disable()\n"));
exit_threads_disable(NULL);
}
void exit_interleave_mutex(IMUTEX_T *im)
{
init_threads_disable(NULL);
if (im->prev) {
im->prev->next = im->next;
} else {
interleave_list = im->next;
}
if (im->next) {
im->next->prev = im->prev;
|
ef1e93 | 1998-03-26 | Henrik Grubbström (Grubba) | | }
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | |
mt_unlock(&(im->lock));
exit_threads_disable(NULL);
|
063fe3 | 1998-03-10 | Per Hedbor | | }
|
eac209 | 1998-02-27 | Marcus Comstedt | |
#define THREAD_TABLE_SIZE 127 /* Totally arbitrary prime */
static struct thread_state *thread_table_chains[THREAD_TABLE_SIZE];
|
22ca07 | 1998-04-08 | Fredrik Hübinette (Hubbe) | | void thread_table_init(void)
|
eac209 | 1998-02-27 | Marcus Comstedt | | {
INT32 x;
for(x=0; x<THREAD_TABLE_SIZE; x++)
thread_table_chains[x] = NULL;
}
unsigned INT32 thread_table_hash(THREAD_T *tid)
{
|
d21327 | 1998-02-28 | Fredrik Hübinette (Hubbe) | | return th_hash(*tid) % THREAD_TABLE_SIZE;
|
eac209 | 1998-02-27 | Marcus Comstedt | | }
void thread_table_insert(struct object *o)
{
struct thread_state *s = (struct thread_state *)o->storage;
unsigned INT32 h = thread_table_hash(&s->id);
mt_lock( & thread_table_lock );
if((s->hashlink = thread_table_chains[h]) != NULL)
s->hashlink->backlink = &s->hashlink;
thread_table_chains[h] = s;
s->backlink = &thread_table_chains[h];
mt_unlock( & thread_table_lock );
}
void thread_table_delete(struct object *o)
{
struct thread_state *s = (struct thread_state *)o->storage;
mt_lock( & thread_table_lock );
if(s->hashlink != NULL)
s->hashlink->backlink = s->backlink;
*(s->backlink) = s->hashlink;
mt_unlock( & thread_table_lock );
}
struct thread_state *thread_state_for_id(THREAD_T tid)
{
unsigned INT32 h = thread_table_hash(&tid);
struct thread_state *s = NULL;
mt_lock( & thread_table_lock );
|
d21327 | 1998-02-28 | Fredrik Hübinette (Hubbe) | | if(thread_table_chains[h] == NULL)
{
|
eac209 | 1998-02-27 | Marcus Comstedt | |
|
d21327 | 1998-02-28 | Fredrik Hübinette (Hubbe) | | }
else if(th_equal((s=thread_table_chains[h])->id, tid))
{
|
eac209 | 1998-02-27 | Marcus Comstedt | |
|
d21327 | 1998-02-28 | Fredrik Hübinette (Hubbe) | | }
else
{
|
eac209 | 1998-02-27 | Marcus Comstedt | | while((s = s->hashlink) != NULL)
|
d21327 | 1998-02-28 | Fredrik Hübinette (Hubbe) | | if(th_equal(s->id, tid))
|
eac209 | 1998-02-27 | Marcus Comstedt | | break;
if(s != NULL) {
if(s->hashlink != NULL)
s->hashlink->backlink = s->backlink;
*(s->backlink) = s->hashlink;
if((s->hashlink = thread_table_chains[h]) != NULL)
s->hashlink->backlink = &s->hashlink;
thread_table_chains[h] = s;
s->backlink = &thread_table_chains[h];
}
}
mt_unlock( & thread_table_lock );
return s;
}
struct object *thread_for_id(THREAD_T tid)
{
struct thread_state *s = thread_state_for_id(tid);
return (s == NULL? NULL :
(struct object *)(((char *)s)-((((struct object *)NULL)->storage)-
((char*)NULL))));
}
void f_all_threads(INT32 args)
{
INT32 x;
struct svalue *oldsp;
struct thread_state *s;
pop_n_elems(args);
oldsp = sp;
mt_lock( & thread_table_lock );
for(x=0; x<THREAD_TABLE_SIZE; x++)
for(s=thread_table_chains[x]; s; s=s->hashlink) {
struct object *o =
(struct object *)(((char *)s)-((((struct object *)NULL)->storage)-
((char*)NULL)));
|
d6ac73 | 1998-04-20 | Henrik Grubbström (Grubba) | | ref_push_object(o);
|
eac209 | 1998-02-27 | Marcus Comstedt | | }
mt_unlock( & thread_table_lock );
f_aggregate(sp-oldsp);
}
|
9ef9a3 | 1996-11-16 | Fredrik Hübinette (Hubbe) | | static void check_threads(struct callback *cb, void *arg, void * arg2)
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | {
|
0a861b | 1997-09-17 | Fredrik Hübinette (Hubbe) | | static int div_;
if(div_++ & 255) return;
|
de413f | 1998-03-26 | Per Hedbor | | THREADS_ALLOW();
THREADS_DISALLOW();
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | }
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | void *new_thread_func(void * data)
{
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | struct thread_starter arg = *(struct thread_starter *)data;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | JMP_BUF back;
|
725ba9 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | INT32 tmp;
|
b1b51f | 1996-10-11 | Fredrik Hübinette (Hubbe) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr,"THREADS_DISALLOW() Thread %08x created...\n",
(unsigned int)arg.id));
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | |
|
9c6f7d | 1997-04-15 | Fredrik Hübinette (Hubbe) | | if((tmp=mt_lock( & interpreter_lock)))
|
725ba9 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | fatal("Failed to lock interpreter, errno %d\n",tmp);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | init_interpreter();
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | thread_id=arg.id;
|
a7fef4 | 1997-09-03 | Per Hedbor | | SWAP_OUT_THREAD((struct thread_state *)thread_id->storage);
((struct thread_state *)thread_id->storage)->swapped=0;
|
78112c | 1998-04-13 | Henrik Grubbström (Grubba) | | #ifdef THREAD_TRACE
{
t_flag = default_t_flag;
}
#endif /* THREAD_TRACE */
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr,"THREAD %08x INITED\n",(unsigned int)thread_id));
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | if(SETJMP(back))
{
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | if(throw_severity < THROW_EXIT)
{
ONERROR tmp;
SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!");
assign_svalue_no_free(sp++, & throw_value);
APPLY_MASTER("handle_error", 1);
pop_stack();
UNSET_ONERROR(tmp);
}
if(throw_severity == THROW_EXIT)
{
do_exit(throw_value.u.integer);
}
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | } else {
|
725ba9 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | INT32 args=arg.args->size;
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | back.severity=THROW_EXIT;
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | push_array_items(arg.args);
arg.args=0;
|
97ffe4 | 1997-01-26 | Per Hedbor | | f_call_function(args);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | |
object_low_set_index(thread_id,
thread_id_result_variable,
sp-1);
pop_stack();
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | }
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | ((struct thread_state *)(thread_id->storage))->status=THREAD_EXITED;
co_signal(& ((struct thread_state *)(thread_id->storage))->status_change);
|
4bdad0 | 1997-09-01 | Per Hedbor | | free((char *)data);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | UNSETJMP(back);
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr,"THREADS_ALLOW() Thread %08x done\n",
(unsigned int)thread_id));
|
b1b51f | 1996-10-11 | Fredrik Hübinette (Hubbe) | |
|
eac209 | 1998-02-27 | Marcus Comstedt | | thread_table_delete(thread_id);
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | free_object(thread_id);
thread_id=0;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | cleanup_interpret();
num_threads--;
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | if(!num_threads && threads_evaluator_callback)
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | {
remove_callback(threads_evaluator_callback);
threads_evaluator_callback=0;
}
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | mt_unlock(& interpreter_lock);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | th_exit(0);
|
9c8b2d | 1997-04-20 | Henrik Grubbström (Grubba) | |
return(NULL);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | }
|
97ffe4 | 1997-01-26 | Per Hedbor | | #ifdef UNIX_THREADS
int num_lwps = 1;
#endif
|
b1b51f | 1996-10-11 | Fredrik Hübinette (Hubbe) | |
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | void f_thread_create(INT32 args)
{
|
97ffe4 | 1997-01-26 | Per Hedbor | | THREAD_T dummy;
|
b1b51f | 1996-10-11 | Fredrik Hübinette (Hubbe) | | struct thread_starter *arg;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | int tmp;
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | arg=ALLOC_STRUCT(thread_starter);
arg->args=aggregate_array(args);
|
e70975 | 1997-03-12 | Fredrik Hübinette (Hubbe) | | arg->id=clone_object(thread_id_prog,0);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | ((struct thread_state *)arg->id->storage)->status=THREAD_RUNNING;
|
b2a0fb | 1997-02-06 | Henrik Grubbström (Grubba) | |
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | tmp=th_create(&((struct thread_state *)arg->id->storage)->id,
new_thread_func,
arg);
|
b2a0fb | 1997-02-06 | Henrik Grubbström (Grubba) | |
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | if(!tmp)
{
num_threads++;
|
eac209 | 1998-02-27 | Marcus Comstedt | | thread_table_insert(arg->id);
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | |
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | if(!threads_evaluator_callback)
|
a29e02 | 1996-10-15 | Fredrik Hübinette (Hubbe) | | {
threads_evaluator_callback=add_to_callback(&evaluator_callbacks,
check_threads, 0,0);
}
|
d6ac73 | 1998-04-20 | Henrik Grubbström (Grubba) | | ref_push_object(arg->id);
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr, "THREAD_CREATE -> t:%08x\n",
(unsigned int)arg->id));
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | } else {
free_object(arg->id);
free_array(arg->args);
free((char *)arg);
|
70d5f8 | 1998-03-25 | Henrik Grubbström (Grubba) | | error("Failed to create thread (errno = %d).\n",tmp);
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | }
}
|
1e4a64 | 1997-09-03 | Martin Stjernholm | | #ifdef UNIX_THREADS
|
97ffe4 | 1997-01-26 | Per Hedbor | | void f_thread_set_concurrency(INT32 args)
{
int c=1;
if(args) c=sp[-args].u.integer;
else error("No argument to thread_set_concurrency(int concurrency);\n");
pop_n_elems(args);
|
09dceb | 1997-09-01 | Per Hedbor | | num_lwps=c;
|
97ffe4 | 1997-01-26 | Per Hedbor | | th_setconcurrency(c);
}
|
1e4a64 | 1997-09-03 | Martin Stjernholm | | #endif
|
97ffe4 | 1997-01-26 | Per Hedbor | |
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | void f_this_thread(INT32 args)
{
pop_n_elems(args);
|
d6ac73 | 1998-04-20 | Henrik Grubbström (Grubba) | | ref_push_object(thread_id);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | }
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | #define THIS_MUTEX ((struct mutex_storage *)(fp->current_storage))
struct mutex_storage
{
COND_T condition;
struct object *key;
};
struct key_storage
{
struct mutex_storage *mut;
|
09dceb | 1997-09-01 | Per Hedbor | | struct object *owner;
|
4bdad0 | 1997-09-01 | Per Hedbor | | int initialized;
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | };
#define OB2KEY(X) ((struct key_storage *)((X)->storage))
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
void f_mutex_lock(INT32 args)
{
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | struct mutex_storage *m;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | struct object *o;
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | |
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | m=THIS_MUTEX;
|
46d7bf | 1997-09-03 | Henrik Grubbström (Grubba) | |
|
65df5c | 1997-09-01 | Per Hedbor | | o=clone_object(mutex_key,0);
|
852ce9 | 1997-09-08 | Fredrik Hübinette (Hubbe) | | if(!args || IS_ZERO(sp-args))
|
4bdad0 | 1997-09-01 | Per Hedbor | | {
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | if(m->key && OB2KEY(m->key)->owner == thread_id)
{
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0,
(stderr, "Recursive LOCK k:%08x, m:%08x(%08x), t:%08x\n",
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | (unsigned int)OB2KEY(m->key),
(unsigned int)m,
(unsigned int)OB2KEY(m->key)->mut,
(unsigned int) thread_id));
free_object(o);
error("Recursive mutex locks!\n");
}
|
4bdad0 | 1997-09-01 | Per Hedbor | | }
|
0a861b | 1997-09-17 | Fredrik Hübinette (Hubbe) | | if(m->key)
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | {
|
b504ed | 1997-09-21 | Fredrik Hübinette (Hubbe) | | SWAP_OUT_CURRENT_THREAD();
do
|
0a861b | 1997-09-17 | Fredrik Hübinette (Hubbe) | | {
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(1, (stderr,"WAITING TO LOCK m:%08x\n",(unsigned int)m));
|
b504ed | 1997-09-21 | Fredrik Hübinette (Hubbe) | | co_wait(& m->condition, & interpreter_lock);
}while(m->key);
SWAP_IN_CURRENT_THREAD();
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | }
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | m->key=o;
|
46d7bf | 1997-09-03 | Henrik Grubbström (Grubba) | | OB2KEY(o)->mut=m;
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | |
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(1, (stderr, "LOCK k:%08x, m:%08x(%08x), t:%08x\n",
(unsigned int)OB2KEY(o),
(unsigned int)m,
(unsigned int)OB2KEY(m->key)->mut,
(unsigned int)thread_id));
|
65d3c3 | 1997-09-08 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | push_object(o);
}
void f_mutex_trylock(INT32 args)
{
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | struct mutex_storage *m;
struct object *o;
int i=0;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
e70975 | 1997-03-12 | Fredrik Hübinette (Hubbe) | | o=clone_object(mutex_key,0);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | m=THIS_MUTEX;
|
4bdad0 | 1997-09-01 | Per Hedbor | |
|
46d7bf | 1997-09-03 | Henrik Grubbström (Grubba) | |
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | if(!args || IS_ZERO(sp-args))
|
65df5c | 1997-09-01 | Per Hedbor | | {
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | if(m->key && OB2KEY(m->key)->owner == thread_id)
{
free_object(o);
error("Recursive mutex locks!\n");
}
|
65df5c | 1997-09-01 | Per Hedbor | | }
|
50fd18 | 1997-09-17 | Fredrik Hübinette (Hubbe) | |
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | if(!m->key)
{
|
e4293f | 1997-04-17 | Fredrik Hübinette (Hubbe) | | OB2KEY(o)->mut=m;
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | m->key=o;
i=1;
}
|
4bdad0 | 1997-09-01 | Per Hedbor | |
|
65d3c3 | 1997-09-08 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | if(i)
{
push_object(o);
} else {
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | destruct(o);
free_object(o);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | push_int(0);
}
}
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | void init_mutex_obj(struct object *o)
{
co_init(& THIS_MUTEX->condition);
THIS_MUTEX->key=0;
}
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | void exit_mutex_obj(struct object *o)
{
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(1, (stderr, "DESTROYING MUTEX m:%08x\n",
(unsigned int)THIS_MUTEX));
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | if(THIS_MUTEX->key) destruct(THIS_MUTEX->key);
|
88fe36 | 1997-09-04 | Per Hedbor | | THIS_MUTEX->key=0;
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | co_destroy(& THIS_MUTEX->condition);
}
#define THIS_KEY ((struct key_storage *)(fp->current_storage))
void init_mutex_key_obj(struct object *o)
{
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(1, (stderr, "KEY k:%08x, o:%08x\n",
(unsigned int)THIS_KEY, (unsigned int)thread_id));
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | THIS_KEY->mut=0;
|
d6ac73 | 1998-04-20 | Henrik Grubbström (Grubba) | | add_ref(THIS_KEY->owner=thread_id);
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | THIS_KEY->initialized=1;
}
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
void exit_mutex_key_obj(struct object *o)
{
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(1, (stderr, "UNLOCK k:%08x m:(%08x) t:%08x o:%08x\n",
(unsigned int)THIS_KEY,
(unsigned int)THIS_KEY->mut,
(unsigned int)thread_id,
(unsigned int)THIS_KEY->owner));
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | if(THIS_KEY->mut)
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | {
|
03b1fe | 1997-09-06 | Per Hedbor | | struct mutex_storage *mut = THIS_KEY->mut;
|
c11387 | 1997-09-15 | Henrik Grubbström (Grubba) | |
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
|
03b1fe | 1997-09-06 | Per Hedbor | | if(mut->key != o)
fatal("Mutex unlock from wrong key %p != %p!\n",THIS_KEY->mut->key,o);
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | #endif
|
03b1fe | 1997-09-06 | Per Hedbor | | mut->key=0;
|
46d7bf | 1997-09-03 | Henrik Grubbström (Grubba) | | if (THIS_KEY->owner) {
free_object(THIS_KEY->owner);
THIS_KEY->owner=0;
}
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | THIS_KEY->mut=0;
THIS_KEY->initialized=0;
|
c11387 | 1997-09-15 | Henrik Grubbström (Grubba) | | co_signal(& mut->condition);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | }
}
#define THIS_COND ((COND_T *)(fp->current_storage))
void f_cond_wait(INT32 args)
{
COND_T *c;
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | struct object *key;
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
if(args > 1) pop_n_elems(args - 1);
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | c=THIS_COND;
if(args > 0)
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | {
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | struct mutex_storage *mut;
if(sp[-1].type != T_OBJECT)
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | error("Bad argument 1 to condition->wait()\n");
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | |
key=sp[-1].u.object;
if(key->prog != mutex_key)
error("Bad argument 1 to condition->wait()\n");
mut=OB2KEY(key)->mut;
|
88fe36 | 1997-09-04 | Per Hedbor | | if(!mut) error("Bad argument 1 to condition->wait()\n");
|
368d4a | 1997-09-03 | Per Hedbor | |
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | |
mut->key=0;
OB2KEY(key)->mut=0;
co_signal(& mut->condition);
|
88fe36 | 1997-09-04 | Per Hedbor | |
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | |
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | SWAP_OUT_CURRENT_THREAD();
co_wait(c, &interpreter_lock);
|
88fe36 | 1997-09-04 | Per Hedbor | |
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | if(OB2KEY(key)->initialized)
{
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | while(mut->key) co_wait(& mut->condition, &interpreter_lock);
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | mut->key=key;
OB2KEY(key)->mut=mut;
}
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | SWAP_IN_CURRENT_THREAD();
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | pop_stack();
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | } else {
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | SWAP_OUT_CURRENT_THREAD();
co_wait(c, &interpreter_lock);
SWAP_IN_CURRENT_THREAD();
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | }
}
void f_cond_signal(INT32 args) { pop_n_elems(args); co_signal(THIS_COND); }
void f_cond_broadcast(INT32 args) { pop_n_elems(args); co_broadcast(THIS_COND); }
void init_cond_obj(struct object *o) { co_init(THIS_COND); }
void exit_cond_obj(struct object *o) { co_destroy(THIS_COND); }
|
a7fef4 | 1997-09-03 | Per Hedbor | | void f_thread_backtrace(INT32 args)
{
struct thread_state *foo = (struct thread_state *)fp->current_object->storage;
struct thread_state *bar = (struct thread_state *)thread_id->storage;
struct svalue *osp = sp;
pop_n_elems(args);
if(foo->sp)
{
SWAP_OUT_THREAD(bar);
SWAP_IN_THREAD(foo);
sp=osp;
f_backtrace(0);
osp=sp;
sp=foo->sp;
SWAP_OUT_THREAD(foo);
SWAP_IN_THREAD(bar);
sp=osp;
} else {
push_int(0);
f_allocate(1);
}
}
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | void f_thread_id_status(INT32 args)
{
pop_n_elems(args);
push_int(THIS_THREAD->status);
}
static void f_thread_id_result(INT32 args)
{
struct thread_state *th=THIS_THREAD;
SWAP_OUT_CURRENT_THREAD();
while(th->status != THREAD_EXITED)
co_wait(&th->status_change, &interpreter_lock);
SWAP_IN_CURRENT_THREAD();
low_object_index_no_free(sp,
fp->current_object,
thread_id_result_variable);
sp++;
}
|
a7fef4 | 1997-09-03 | Per Hedbor | | void init_thread_obj(struct object *o)
{
MEMSET(o->storage, 0, sizeof(struct thread_state));
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | THIS_THREAD->status=THREAD_NOT_STARTED;
co_init(& THIS_THREAD->status_change);
}
void exit_thread_obj(struct object *o)
{
co_destroy(& THIS_THREAD->status_change);
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | th_destroy(& THIS_THREAD->id);
|
a7fef4 | 1997-09-03 | Per Hedbor | | }
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
static void thread_was_marked(struct object *o)
{
struct thread_state *tmp=(struct thread_state *)(o->storage);
if(tmp->swapped)
{
|
469411 | 1997-11-07 | Fredrik Hübinette (Hubbe) | | debug_gc_xmark_svalues(tmp->evaluator_stack,tmp->sp-tmp->evaluator_stack-1,"idle thread stack");
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | }
}
#endif
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | void low_th_init(void)
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | {
|
e4419e | 1997-02-06 | Fredrik Hübinette (Hubbe) | | #ifdef SGI_SPROC_THREADS
#error /* Need to specify a filename */
us_cookie = usinit("");
#endif /* SGI_SPROC_THREADS */
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | THREADS_FPRINTF(0, (stderr, "THREADS_DISALLOW() Initializing threads.\n"));
|
fed8de | 1997-10-05 | Henrik Grubbström (Grubba) | |
#ifdef POSIX_THREADS
#ifdef HAVE_PTHREAD_INIT
pthread_init();
#endif /* HAVE_PTHREAD_INIT */
#endif /* POSIX_THREADS */
|
12ae2f | 1997-09-05 | Henrik Grubbström (Grubba) | | mt_init( & interpreter_lock);
|
e4419e | 1997-02-06 | Fredrik Hübinette (Hubbe) | | mt_lock( & interpreter_lock);
|
eac209 | 1998-02-27 | Marcus Comstedt | | mt_init( & thread_table_lock);
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | mt_init( & interleave_lock);
|
ef1e93 | 1998-03-26 | Henrik Grubbström (Grubba) | | co_init( & live_threads_change);
co_init( & threads_disabled_change);
|
eac209 | 1998-02-27 | Marcus Comstedt | | thread_table_init();
|
e4419e | 1997-02-06 | Fredrik Hübinette (Hubbe) | | #ifdef POSIX_THREADS
pthread_attr_init(&pattr);
#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
|
c3cdf2 | 1998-02-19 | Per Hedbor | | pthread_attr_setstacksize(&pattr, 1024 * 1204);
|
e4419e | 1997-02-06 | Fredrik Hübinette (Hubbe) | | #endif
pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
|
864d3c | 1998-01-29 | Fredrik Hübinette (Hubbe) | |
pthread_attr_init(&small_pattr);
#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
pthread_attr_setstacksize(&small_pattr, 32768);
#endif
pthread_attr_setdetachstate(&small_pattr, PTHREAD_CREATE_DETACHED);
|
e4419e | 1997-02-06 | Fredrik Hübinette (Hubbe) | | #endif
|
a91ca0 | 1998-07-10 | Henrik Grubbström (Grubba) | | }
void th_init(void)
{
struct program *tmp;
INT32 mutex_key_offset;
|
e4419e | 1997-02-06 | Fredrik Hübinette (Hubbe) | | add_efun("thread_create",f_thread_create,"function(mixed ...:object)",
OPT_SIDE_EFFECT);
#ifdef UNIX_THREADS
add_efun("thread_set_concurrency",f_thread_set_concurrency,
"function(int:void)", OPT_SIDE_EFFECT);
#endif
add_efun("this_thread",f_this_thread,"function(:object)",
OPT_EXTERNAL_DEPEND);
|
eac209 | 1998-02-27 | Marcus Comstedt | | add_efun("all_threads",f_all_threads,"function(:array(object))",
OPT_EXTERNAL_DEPEND);
|
e4419e | 1997-02-06 | Fredrik Hübinette (Hubbe) | |
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | start_new_program();
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | add_storage(sizeof(struct mutex_storage));
|
fe76ce | 1997-09-08 | Fredrik Hübinette (Hubbe) | | add_function("lock",f_mutex_lock,"function(int|void:object)",0);
add_function("trylock",f_mutex_trylock,"function(int|void:object)",0);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | set_init_callback(init_mutex_obj);
set_exit_callback(exit_mutex_obj);
|
b98eb3 | 1997-02-11 | Henrik Grubbström (Grubba) | | end_class("mutex", 0);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
start_new_program();
|
46d7bf | 1997-09-03 | Henrik Grubbström (Grubba) | | mutex_key_offset = add_storage(sizeof(struct key_storage));
map_variable("_owner", "object", 0,
mutex_key_offset + OFFSETOF(key_storage, owner), T_OBJECT);
|
598892 | 1996-10-05 | Fredrik Hübinette (Hubbe) | | set_init_callback(init_mutex_key_obj);
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | set_exit_callback(exit_mutex_key_obj);
|
e4419e | 1997-02-06 | Fredrik Hübinette (Hubbe) | | mutex_key=end_program();
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | mutex_key->flags|=PROGRAM_DESTRUCT_IMMEDIATE;
|
e45f66 | 1998-03-20 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
|
f839fa | 1997-02-28 | Fredrik Hübinette (Hubbe) | | if(!mutex_key)
fatal("Failed to initialize mutex_key program!\n");
|
e45f66 | 1998-03-20 | Fredrik Hübinette (Hubbe) | | #endif
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | |
start_new_program();
add_storage(sizeof(COND_T));
add_function("wait",f_cond_wait,"function(void|object:void)",0);
add_function("signal",f_cond_signal,"function(:void)",0);
add_function("broadcast",f_cond_broadcast,"function(:void)",0);
set_init_callback(init_cond_obj);
set_exit_callback(exit_cond_obj);
|
b98eb3 | 1997-02-11 | Henrik Grubbström (Grubba) | | end_class("condition", 0);
|
de413f | 1998-03-26 | Per Hedbor | |
{
struct program *tmp;
start_new_program();
set_init_callback(init_threads_disable);
set_exit_callback(exit_threads_disable);
tmp = end_program();
tmp->flags|=PROGRAM_DESTRUCT_IMMEDIATE;
add_global_program("_disable_threads", tmp);
|
56a696 | 1998-04-05 | Fredrik Hübinette (Hubbe) | | free_program(tmp);
|
de413f | 1998-03-26 | Per Hedbor | | }
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | |
start_new_program();
|
a7fef4 | 1997-09-03 | Per Hedbor | | add_storage(sizeof(struct thread_state));
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | thread_id_result_variable=simple_add_variable("result","mixed",0);
|
a7fef4 | 1997-09-03 | Per Hedbor | | add_function("backtrace",f_thread_backtrace,"function(:array)",0);
|
574088 | 1998-01-01 | Fredrik Hübinette (Hubbe) | | add_function("wait",f_thread_id_result,"function(:mixed)",0);
add_function("status",f_thread_id_status,"function(:int)",0);
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
set_gc_mark_callback(thread_was_marked);
#endif
|
a7fef4 | 1997-09-03 | Per Hedbor | | set_init_callback(init_thread_obj);
|
a2db6b | 1998-01-02 | Fredrik Hübinette (Hubbe) | | set_exit_callback(exit_thread_obj);
|
e4419e | 1997-02-06 | Fredrik Hübinette (Hubbe) | | thread_id_prog=end_program();
|
f839fa | 1997-02-28 | Fredrik Hübinette (Hubbe) | | if(!mutex_key)
fatal("Failed to initialize thread program!\n");
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | |
|
e70975 | 1997-03-12 | Fredrik Hübinette (Hubbe) | | thread_id=clone_object(thread_id_prog,0);
|
03b1fe | 1997-09-06 | Per Hedbor | | SWAP_OUT_THREAD((struct thread_state *)thread_id->storage);
((struct thread_state *)thread_id->storage)->swapped=0;
|
eac209 | 1998-02-27 | Marcus Comstedt | | ((struct thread_state *)thread_id->storage)->id=th_self();
thread_table_insert(thread_id);
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | }
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void th_cleanup(void)
|
6d1a5e | 1996-10-07 | Fredrik Hübinette (Hubbe) | | {
if(mutex_key)
{
free_program(mutex_key);
mutex_key=0;
}
if(thread_id_prog)
{
free_program(thread_id_prog);
thread_id_prog=0;
}
if(thread_id)
{
destruct(thread_id);
free_object(thread_id);
thread_id=0;
}
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | }
|
063fe3 | 1998-03-10 | Per Hedbor | |
static struct farmer {
struct farmer *neighbour;
void *field;
void (*harvest)(void *);
THREAD_T me;
COND_T harvest_moon;
} *farmers;
static MUTEX_T rosie;
static void *farm(void *_a)
{
struct farmer *me = (struct farmer *)_a;
do
{
me->harvest( me->field );
me->harvest = 0;
mt_lock( &rosie );
me->neighbour = farmers;
farmers = me;
while(!me->harvest) co_wait( &me->harvest_moon, &rosie );
mt_unlock( &rosie );
} while(1);
|
3d09c7 | 1998-05-01 | Henrik Grubbström (Grubba) | |
return NULL;
|
063fe3 | 1998-03-10 | Per Hedbor | | }
|
22ca07 | 1998-04-08 | Fredrik Hübinette (Hubbe) | | int th_num_idle_farmers(void)
|
063fe3 | 1998-03-10 | Per Hedbor | | {
int q = 0;
struct farmer *f = farmers;
while(f) { f = f->neighbour; q++; }
return q;
}
static int _num_farmers;
int th_num_farmers()
{
return _num_farmers;
}
static struct farmer *new_farmer(void (*fun)(void *), void *args)
{
struct farmer *me = malloc(sizeof(struct farmer));
_num_farmers++;
me->neighbour = 0;
me->field = args;
me->harvest = fun;
co_init( &me->harvest_moon );
#ifdef UNIX_THREADS
thr_create(NULL,8192,farm,(void *)me,THR_DAEMON|THR_DETACHED|THR_BOUND,0);
#else
th_create_small(&me->me, farm, me);
#endif
|
a2a880 | 1998-03-18 | Per Hedbor | | return me;
|
063fe3 | 1998-03-10 | Per Hedbor | | }
void th_farm(void (*fun)(void *), void *here)
{
if(!fun) fatal("The farmers don't known how to handle empty fields\n");
mt_lock( &rosie );
if(farmers)
{
struct farmer *f = farmers;
farmers = f->neighbour;
mt_unlock( &rosie );
f->field = here;
f->harvest = fun;
co_signal( &f->harvest_moon );
return;
}
mt_unlock( &rosie );
new_farmer( fun, here );
}
|
07513e | 1996-10-04 | Fredrik Hübinette (Hubbe) | | #endif
|