diff --git a/src/threads.c b/src/threads.c index 71ebc4a70ec5f26dd00ad12613c2468cd61f7ac4..9252895d2d2b2d3b7d303f9442ed421d8724a3fa 100644 --- a/src/threads.c +++ b/src/threads.c @@ -1,5 +1,5 @@ #include "global.h" -RCSID("$Id: threads.c,v 1.93 1999/05/02 08:11:50 hubbe Exp $"); +RCSID("$Id: threads.c,v 1.94 1999/05/08 00:41:01 hubbe Exp $"); int num_threads = 1; int threads_disabled = 0; @@ -336,6 +336,19 @@ unsigned INT32 thread_table_hash(THREAD_T *tid) return th_hash(*tid) % THREAD_TABLE_SIZE; } +#ifdef PIKE_DEBUG +static void dumpmem(char *desc, void *x, int size) +{ + int e; + unsigned char *tmp=(unsigned char *)x; + fprintf(stderr,"%s: ",desc); + for(e=0;e<size;e++) + fprintf(stderr,"%02x",tmp[e]); + fprintf(stderr,"\n"); +} +#endif + + void thread_table_insert(struct object *o) { struct thread_state *s = OBJ2THREAD(o); @@ -343,6 +356,9 @@ void thread_table_insert(struct object *o) #ifdef PIKE_DEBUG if(h>=THREAD_TABLE_SIZE) fatal("thread_table_hash failed miserably!\n"); + if(thread_state_for_id(s->id)) + fatal("Registring thread twice!\n"); +/* dumpmem("thread_table_insert",&s->id, sizeof(THREAD_T)); */ #endif mt_lock( & thread_table_lock ); if((s->hashlink = thread_table_chains[h]) != NULL) @@ -355,6 +371,7 @@ void thread_table_insert(struct object *o) void thread_table_delete(struct object *o) { struct thread_state *s = OBJ2THREAD(o); +/* dumpmem("thread_table_delete",&s->id, sizeof(THREAD_T)); */ mt_lock( & thread_table_lock ); if(s->hashlink != NULL) s->hashlink->backlink = s->backlink; @@ -366,6 +383,10 @@ struct thread_state *thread_state_for_id(THREAD_T tid) { unsigned INT32 h = thread_table_hash(&tid); struct thread_state *s = NULL; +#if 0 + if(num_threads>1) + dumpmem("thread_state_for_id: ",&tid,sizeof(tid)); +#endif #ifdef PIKE_DEBUG if(h>=THREAD_TABLE_SIZE) fatal("thread_table_hash failed miserably!\n"); @@ -400,6 +421,10 @@ struct thread_state *thread_state_for_id(THREAD_T tid) } } mt_unlock( & thread_table_lock ); +#if 0 + if(num_threads>1 && s) + dumpmem("thread_state_for_id return value: ",&s->id,sizeof(tid)); +#endif return s; /* NOTEZ BIEN: Return value only guaranteed to remain valid as long as you have the interpreter lock, unless tid == th_self() */ @@ -408,9 +433,7 @@ struct thread_state *thread_state_for_id(THREAD_T tid) 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)))); + return (s == NULL? NULL : THREADSTATE2OBJ(s)); /* See NB in thread_state_for_id. Lifespan of result can be prolonged by incrementing refcount though. */ } @@ -429,9 +452,7 @@ void f_all_threads(INT32 args) 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))); + struct object *o = THREADSTATE2OBJ(s); ref_push_object(o); } mt_unlock( & thread_table_lock ); @@ -444,12 +465,24 @@ static void check_threads(struct callback *cb, void *arg, void * arg2) static int div_; if(div_++ & 255) return; +#ifdef DEBUG + if(thread_for_id(th_self()) != thread_id) + fatal("thread_for_id() (or thread_id) failed!\n") +#endif + THREADS_ALLOW(); /* Allow other threads to run */ THREADS_DISALLOW(); + +#ifdef DEBUG + if(thread_for_id(th_self()) != thread_id) + fatal("thread_for_id() (or thread_id) failed!\n") +#endif + + } -void *new_thread_func(void * data) +TH_RETURN_TYPE new_thread_func(void * data) { struct thread_starter arg = *(struct thread_starter *)data; JMP_BUF back; @@ -467,6 +500,17 @@ void *new_thread_func(void * data) stack_top=((char *)&data)+ (thread_stack_size-16384) * STACK_DIRECTION; recoveries = NULL; +#if defined(PIKE_DEBUG) + if(d_flag) + { + if( thread_id && !th_equal( OBJ2THREAD(thread_id)->id, th_self()) ) + fatal("Current thread is wrong. %x %x\n",OBJ2THREAD(thread_id)->id,th_self()); + + if(thread_for_id(th_self()) != thread_id) + fatal("thread_for_id() (or thread_id) failed in new_thread_func! %p != %p\n",thread_for_id(th_self()),thread_id); + } +#endif + #ifdef THREAD_TRACE { t_flag = default_t_flag; @@ -659,6 +703,9 @@ void f_mutex_lock(INT32 args) */ o=clone_object(mutex_key,0); + DO_IF_DEBUG( if(thread_for_id(th_self()) != thread_id) + fatal("thread_for_id() (or thread_id) failed! %p != %p\n",thread_for_id(th_self()),thread_id) ; ) + if(m->key) { SWAP_OUT_CURRENT_THREAD(); @@ -672,6 +719,9 @@ void f_mutex_lock(INT32 args) m->key=o; OB2KEY(o)->mut=m; + DO_IF_DEBUG( if(thread_for_id(th_self()) != thread_id) + fatal("thread_for_id() (or thread_id) failed! %p != %p\n",thread_for_id(th_self()),thread_id) ; ) + THREADS_FPRINTF(1, (stderr, "LOCK k:%08x, m:%08x(%08x), t:%08x\n", (unsigned int)OB2KEY(o), (unsigned int)m, @@ -1007,7 +1057,7 @@ void low_th_init(void) pthread_attr_init(&small_pattr); #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE - pthread_attr_setstacksize(&small_pattr, 32768); + pthread_attr_setstacksize(&small_pattr, 4096*sizeof(char *)); #endif pthread_attr_setdetachstate(&small_pattr, PTHREAD_CREATE_DETACHED); @@ -1170,7 +1220,7 @@ static struct farmer { static MUTEX_T rosie; -static void *farm(void *_a) +static TH_RETURN_TYPE farm(void *_a) { struct farmer *me = (struct farmer *)_a; do @@ -1215,14 +1265,7 @@ static struct farmer *new_farmer(void (*fun)(void *), void *args) me->field = args; me->harvest = fun; co_init( &me->harvest_moon ); -#ifdef UNIX_THREADS - /* FIXME: Why not increase the stacksize of th_create_small(), - * and use it instead? - */ - thr_create(NULL, 65536, farm, me, THR_DAEMON|THR_DETACHED, &me->me); -#else th_create_small(&me->me, farm, me); -#endif return me; } diff --git a/src/threads.h b/src/threads.h index 674248e429ac685ec5f188a6770bb9c794a45488..34d4db6d46012bf24648985cfb62a4761f4f4162 100644 --- a/src/threads.h +++ b/src/threads.h @@ -1,5 +1,5 @@ /* - * $Id: threads.h,v 1.65 1999/04/15 19:12:51 hubbe Exp $ + * $Id: threads.h,v 1.66 1999/05/08 00:41:03 hubbe Exp $ */ #ifndef THREADS_H #define THREADS_H @@ -126,7 +126,7 @@ extern pthread_attr_t small_pattr; #define th_setconcurrency(X) thr_setconcurrency(X) #define th_create(ID,fun,arg) thr_create(NULL,thread_stack_size,fun,arg,THR_DAEMON|THR_DETACHED,ID) -#define th_create_small(ID,fun,arg) thr_create(NULL,32768,fun,arg,THR_DAEMON|THR_DETACHED,ID) +#define th_create_small(ID,fun,arg) thr_create(NULL,8192*sizeof(char *),fun,arg,THR_DAEMON|THR_DETACHED,ID) #define th_exit(foo) thr_exit(foo) #define th_self() thr_self() #define th_kill(ID,sig) thr_kill((ID),(sig)) @@ -179,17 +179,18 @@ extern pthread_attr_t small_pattr; #include <process.h> #include <windows.h> -#define THREAD_T HANDLE +#define THREAD_T unsigned #define th_setconcurrency(X) -#define th_create(ID,fun,arg) (!(*(ID)=_beginthread(fun, 2*1024*1024, arg))) -#define th_create_small(ID,fun,arg) (!(*(ID)=_beginthread(fun, 32768, arg))) +#define th_create(ID,fun,arg) (!_beginthreadex(NULL, 2*1024*1024,fun, arg,0,ID)) +#define th_create_small(ID,fun,arg) (!_beginthreadex(NULL, 8192*sizeof(char *), fun,arg,0,ID)) +#define TH_RETURN_TYPE unsigned __stdcall #define th_exit(foo) _endthread(foo) #define th_join(ID,res) /******************* FIXME! ****************/ -#define th_self() GetCurrentThread() +#define th_self() GetCurrentThreadId() #define th_destroy(X) #define th_yield() Sleep(0) #define th_equal(X,Y) ((X)==(Y)) -#define th_hash(X) ((unsigned INT32)(X)) +#define th_hash(X) (X) #define MUTEX_T HANDLE #define mt_init(X) CheckValidHandle((*(X)=CreateMutex(NULL, 0, NULL))) @@ -316,6 +317,10 @@ struct thread_state { #endif /* THREAD_TRACE */ }; +#ifndef TH_RETURN_TYPE +#define TH_RETURN_TYPE void * +#endif + #ifndef th_destroy #define th_destroy(X) #endif @@ -433,8 +438,12 @@ struct thread_state { #define OBJ2THREAD(X) \ ((struct thread_state *)((X)->storage+thread_storage_offset)) +#define THREADSTATE2OBJ(X) BASEOF((X),object,storage[thread_storage_offset]) + #define THREADS_ALLOW() do { \ struct thread_state *_tmp=OBJ2THREAD(thread_id); \ + DO_IF_DEBUG( if(thread_for_id(th_self()) != thread_id) \ + fatal("thread_for_id() (or thread_id) failed! %p != %p\n",thread_for_id(th_self()),thread_id) ; ) \ if(num_threads > 1 && !threads_disabled) { \ SWAP_OUT_THREAD(_tmp); \ THREADS_FPRINTF(1, (stderr, "THREADS_ALLOW() %s:%d t:%08x(#%d)\n", \ @@ -458,6 +467,8 @@ struct thread_state { } \ SWAP_IN_THREAD(_tmp);\ } \ + DO_IF_DEBUG( if(thread_for_id(th_self()) != thread_id) \ + fatal("thread_for_id() (or thread_id) failed! %p != %p\n",thread_for_id(th_self()),thread_id) ; ) \ } while(0) #define THREADS_ALLOW_UID() do { \ @@ -507,7 +518,7 @@ struct thread_state { /* Prototypes begin here */ struct thread_starter; -void *new_thread_func(void * data); +TH_RETURN_TYPE new_thread_func(void * data); void f_thread_create(INT32 args); void f_thread_set_concurrency(INT32 args); void f_this_thread(INT32 args);