Branch: Tag:

1996-10-03

1996-10-03 23:44:19 by Fredrik Hübinette (Hubbe) <hubbe@hubbe.net>

threads added

Rev: src/Makefile.src:1.9
Rev: src/backend.c:1.3
Rev: src/builtin_functions.c:1.6
Rev: src/configure.in:1.6
Rev: src/constants.c:1.3
Rev: src/error.c:1.4
Rev: src/error.h:1.3
Rev: src/interpret.c:1.5
Rev: src/interpret.h:1.3
Rev: src/machine.h.in:1.5
Rev: src/main.c:1.5
Rev: src/modules/files/configure.in:1.6
Rev: src/modules/files/efuns.c:1.3
Rev: src/modules/files/file.c:1.7
Rev: src/modules/files/file_machine.h.in:1.3
Rev: src/modules/files/socket.c:1.3
Rev: src/modules/gdbmmod/gdbmmod.c:1.2
Rev: src/modules/readlinemod/readlinemod.c:1.3
Rev: src/modules/spider/configure.in:1.4
Rev: src/modules/spider/spider.c:1.10
Rev: src/program.c:1.2
Rev: src/threads.c:1.1
Rev: src/threads.h:1.1

1: + #include "global.h" + #include "threads.h" + #include "array.h" + #include "object.h"    -  + int num_threads = 1; + int threads_disabled = 0; +  + #ifdef _REENTRANT +  + MUTEX_T interpreter_lock, compiler_lock; + struct program *mutex_key = 0; + pthread_attr_t pattr; +  + void *new_thread_func(void * data) + { +  JMP_BUF back; +  struct array *foo; +  INT32 args; +  foo=(struct array *)data; +  args=foo->size; +  mt_lock( & interpreter_lock); +  init_interpreter(); +  +  +  if(SETJMP(back)) +  { +  exit_on_error="Error in handle_error in master object!\nPrevious error:"; +  assign_svalue_no_free(sp++, & throw_value); +  APPLY_MASTER("handle_error", 1); +  pop_stack(); +  automatic_fatal=0; +  } else { +  push_array_items(foo); +  f_call_function(args); +  } +  +  UNSETJMP(back); +  +  cleanup_interpret(); +  mt_unlock(& interpreter_lock); +  num_threads--; +  th_exit(0); + } +  + void f_thread_create(INT32 args) + { +  pthread_t dummy; +  int tmp; +  struct array *a=aggregate_array(args); +  num_threads++; +  tmp=th_create(&dummy,new_thread_func,a); +  if(tmp) num_threads--; +  push_int(tmp); + } +  + void th_init() + { +  mt_lock( & interpreter_lock); +  pthread_attr_init(&pattr); +  pthread_attr_setstacksize(&pattr, 2 * 1024 * 1204); +  pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED); +  +  add_efun("thread_create",f_thread_create,"function(mixed ...:int)",OPT_SIDE_EFFECT); + } +  +  + #define THIS_MUTEX ((MUTEX_T *)(fp->current_storage)) +  + void f_mutex_lock(INT32 args) + { +  MUTEX_T *m; +  struct object *o; +  pop_n_elems(args); +  m=THIS_MUTEX; +  THREADS_ALLOW(); +  mt_lock(m); +  THREADS_DISALLOW(); +  o=clone(mutex_key,0); +  ((struct object **)(o->storage))[0]=fp->current_object; +  fp->current_object->refs++; +  push_object(o); + } +  + void f_mutex_trylock(INT32 args) + { +  MUTEX_T *m; +  int i; +  pop_n_elems(args); +  +  m=THIS_MUTEX; +  THREADS_ALLOW(); +  i=mt_lock(m); +  THREADS_DISALLOW(); +  +  if(i) +  { +  struct object *o; +  o=clone(mutex_key,0); +  ((struct object **)o->storage)[0]=fp->current_object; +  fp->current_object->refs++; +  push_object(o); +  } else { +  push_int(0); +  } + } +  + void init_mutex_obj(struct object *o) { mt_init(THIS_MUTEX); } + void exit_mutex_obj(struct object *o) { mt_destroy(THIS_MUTEX); } +  + #define THIS_KEY (*(struct object **)fp->current_storage) + void init_mutex_key_obj(struct object *o) { THIS_KEY=0; } +  + void exit_mutex_key_obj(struct object *o) + { +  if(THIS_KEY) +  { +  mt_unlock((MUTEX_T *)THIS_KEY->storage); +  init_mutex_key_obj(o); +  } + } +  + #define THIS_COND ((COND_T *)(fp->current_storage)) + void f_cond_wait(INT32 args) + { +  COND_T *c; +  +  if(args > 1) pop_n_elems(args - 1); +  +  if(sp[-1].type != T_OBJECT) +  error("Bad argument 1 to condition->wait()\n"); +  +  if(sp[-1].u.object->prog) +  { +  if(sp[-1].u.object->prog != mutex_key) +  error("Bad argument 1 to condition->wait()\n"); +  +  destruct(sp[-1].u.object); +  pop_stack(); +  } +  +  c=THIS_COND; +  THREADS_ALLOW(); +  co_wait(c,0); +  THREADS_DISALLOW(); + } +  + 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); } +  + void th_init_programs() + { +  start_new_program(); +  add_storage(sizeof(MUTEX_T)); +  add_function("lock",f_mutex_lock,"function(:object)",0); +  add_function("trylock",f_mutex_trylock,"function(:object)",0); +  set_init_callback(init_mutex_obj); +  set_exit_callback(exit_mutex_obj); +  end_c_program("/precompiled/mutex"); +  +  start_new_program(); +  add_storage(sizeof(struct object *)); +  set_exit_callback(exit_mutex_key_obj); +  mutex_key=end_c_program("/precompiled/mutex_key"); +  +  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); +  end_c_program("/precompiled/condition"); + } +  + #endif   Newline at end of file added.