From a7fef4fe0e43c894d02833c87e7706cbb70d23bf Mon Sep 17 00:00:00 2001 From: Per Hedbor <ph@opera.com> Date: Wed, 3 Sep 1997 06:58:17 +0200 Subject: [PATCH] Added thread->backtrace() Rev: src/threads.c:1.30 Rev: src/threads.h:1.15 --- src/threads.c | 40 ++++++++++++++++++++++++++++++---- src/threads.h | 60 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 71 insertions(+), 29 deletions(-) diff --git a/src/threads.c b/src/threads.c index 54658718dd..7c879223ec 100644 --- a/src/threads.c +++ b/src/threads.c @@ -1,5 +1,5 @@ #include "global.h" -RCSID("$Id: threads.c,v 1.29 1997/09/03 03:39:58 per Exp $"); +RCSID("$Id: threads.c,v 1.30 1997/09/03 04:58:17 per Exp $"); int num_threads = 1; int threads_disabled = 0; @@ -18,7 +18,7 @@ int threads_disabled = 0; struct object *thread_id; static struct callback *threads_evaluator_callback=0; -MUTEX_T interpreter_lock = PTHREAD_MUTEX_INITIALIZER; +MUTEX_T interpreter_lock /*= PTHREAD_MUTEX_INITIALIZER*/; struct program *mutex_key = 0; struct program *thread_id_prog = 0; #ifdef POSIX_THREADS @@ -50,8 +50,9 @@ void *new_thread_func(void * data) fatal("Failed to lock interpreter, errno %d\n",tmp); THREADS_FPRINTF((stderr,"THREADS_DISALLOW() Thread created...\n")); init_interpreter(); - thread_id=arg.id; + SWAP_OUT_THREAD((struct thread_state *)thread_id->storage); /* Init struct */ + ((struct thread_state *)thread_id->storage)->swapped=0; if(SETJMP(back)) { @@ -168,7 +169,7 @@ struct key_storage int initialized; }; -static MUTEX_T mutex_kluge = PTHREAD_MUTEX_INITIALIZER; +static MUTEX_T mutex_kluge/* = PTHREAD_MUTEX_INITIALIZER*/; #define OB2KEY(X) ((struct key_storage *)((X)->storage)) @@ -361,6 +362,34 @@ 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); } +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); + } +} + +void init_thread_obj(struct object *o) +{ + MEMSET(o->storage, 0, sizeof(struct thread_state)); +} + void th_init(void) { struct program *tmp; @@ -420,6 +449,9 @@ void th_init(void) end_class("condition", 0); start_new_program(); + add_storage(sizeof(struct thread_state)); + add_function("backtrace",f_thread_backtrace,"function(:array)",0); + set_init_callback(init_thread_obj); thread_id_prog=end_program(); if(!mutex_key) fatal("Failed to initialize thread program!\n"); diff --git a/src/threads.h b/src/threads.h index d97cb2f34a..17368d5ed8 100644 --- a/src/threads.h +++ b/src/threads.h @@ -3,6 +3,7 @@ #include "machine.h" #include "interpret.h" +#include "object.h" #include "error.h" #ifdef HAVE_SYS_TYPES_H /* Needed for pthread_t on OSF/1 */ @@ -176,41 +177,50 @@ struct thread_state { #define THREADS_FPRINTF(X) fprintf X #endif /* VERBOSE_THREADS_DEBUG */ +#define SWAP_OUT_THREAD(_tmp) do { \ + (_tmp)->swapped=1; \ +\ + (_tmp)->evaluator_stack=evaluator_stack;\ + (_tmp)->evaluator_stack_malloced=evaluator_stack_malloced;\ + (_tmp)->fp=fp;\ + (_tmp)->mark_sp=mark_sp;\ + (_tmp)->mark_stack=mark_stack;\ + (_tmp)->mark_stack_malloced=mark_stack_malloced;\ + (_tmp)->recoveries=recoveries;\ + (_tmp)->sp=sp; \ + (_tmp)->thread_id=thread_id;\ + } while(0) + +#define SWAP_IN_THREAD(_tmp) do {\ + (_tmp)->swapped=0; \ +\ + evaluator_stack=(_tmp)->evaluator_stack;\ + evaluator_stack_malloced=(_tmp)->evaluator_stack_malloced;\ + fp=(_tmp)->fp;\ + mark_sp=(_tmp)->mark_sp;\ + mark_stack=(_tmp)->mark_stack;\ + mark_stack_malloced=(_tmp)->mark_stack_malloced;\ + recoveries=(_tmp)->recoveries;\ + sp=(_tmp)->sp;\ + thread_id=(_tmp)->thread_id;\ + } while(0) + #define THREADS_ALLOW() \ do {\ - struct thread_state _tmp; \ - _tmp.swapped=0; \ + struct thread_state *_tmp=(struct thread_state *)thread_id->storage; \ if(num_threads > 1 && !threads_disabled) { \ - _tmp.swapped=1; \ - _tmp.sp=sp; \ - _tmp.evaluator_stack=evaluator_stack; \ - _tmp.mark_sp=mark_sp; \ - _tmp.mark_stack=mark_stack; \ - _tmp.fp=fp; \ - _tmp.recoveries=recoveries; \ - _tmp.evaluator_stack_malloced=evaluator_stack_malloced; \ - _tmp.mark_stack_malloced=mark_stack_malloced; \ - _tmp.thread_id = thread_id; \ + SWAP_OUT_THREAD(_tmp); \ THREADS_FPRINTF((stderr, "THREADS_ALLOW() %s:%d t:%08x\n", \ - __FILE__, __LINE__, (unsigned int)_tmp.thread_id)); \ + __FILE__, __LINE__, (unsigned int)_tmp->thread_id)); \ mt_unlock(& interpreter_lock); \ - /*th_yield();*/\ } #define THREADS_DISALLOW() \ - if(_tmp.swapped) { \ + if(_tmp->swapped) { \ mt_lock(& interpreter_lock); \ THREADS_FPRINTF((stderr, "THREADS_DISALLOW() %s:%d ... t:%08x\n", \ - __FILE__, __LINE__, (unsigned int)_tmp.thread_id)); \ - sp=_tmp.sp; \ - evaluator_stack=_tmp.evaluator_stack; \ - mark_sp=_tmp.mark_sp; \ - mark_stack=_tmp.mark_stack; \ - fp=_tmp.fp; \ - recoveries=_tmp.recoveries; \ - evaluator_stack_malloced=_tmp.evaluator_stack_malloced; \ - mark_stack_malloced=_tmp.mark_stack_malloced; \ - thread_id = _tmp.thread_id; \ + __FILE__, __LINE__, (unsigned int)_tmp->thread_id)); \ + SWAP_IN_THREAD(_tmp);\ } \ } while(0) -- GitLab