pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:1:   #include "global.h" - RCSID("$Id: threads.c,v 1.13 1996/12/06 08:30:17 per Exp $"); + RCSID("$Id: threads.c,v 1.14 1997/01/26 22:49:14 per Exp $");      int num_threads = 1;   int threads_disabled = 0;      #ifdef _REENTRANT   #include "threads.h"   #include "array.h"   #include "object.h"   #include "macros.h"   #include "callback.h"      struct object *thread_id;   static struct callback *threads_evaluator_callback=0;      MUTEX_T interpreter_lock = PTHREAD_MUTEX_INITIALIZER;   struct program *mutex_key = 0;   struct program *thread_id_prog = 0; -  + #ifdef POSIX_THREADS   pthread_attr_t pattr; -  + #endif      struct thread_starter   {    struct object *id;    struct array *args;   };      static void check_threads(struct callback *cb, void *arg, void * arg2)   {    THREADS_ALLOW();       /* Allow other threads to run */       THREADS_DISALLOW();   }      void *new_thread_func(void * data)   { -  + /* static int dbt;*/    struct thread_starter arg = *(struct thread_starter *)data;    JMP_BUF back;    INT32 tmp;    -  free((char *)data); -  + /* fprintf(stderr, "Thread create[%d]...",dbt++);*/    if(tmp=mt_lock( & interpreter_lock))    fatal("Failed to lock interpreter, errno %d\n",tmp); -  + /* fprintf(stderr,"Created[%d]...",dbt);*/ +  free((char *)data); /* Moved by per, to avoid some bugs.... */    init_interpreter();       thread_id=arg.id;       if(SETJMP(back))    {    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);    } else {    INT32 args=arg.args->size; -  +     push_array_items(arg.args); -  f_call_function(args); +     arg.args=0; -  +  f_call_function(args); +  pop_stack(); /* Discard the return value. /Per */    }       UNSETJMP(back);       destruct(thread_id);       free_object(thread_id);    thread_id=0;       cleanup_interpret();    num_threads--;    if(!num_threads)    {    remove_callback(threads_evaluator_callback);    threads_evaluator_callback=0;    } -  + /* fprintf(stderr,"Done[%d]\n",dbt--);*/    mt_unlock(& interpreter_lock);    th_exit(0);   }    -  + #ifdef UNIX_THREADS + int num_lwps = 1; + #endif      void f_thread_create(INT32 args)   { -  pthread_t dummy; +  THREAD_T dummy;    struct thread_starter *arg;    int tmp;    arg=ALLOC_STRUCT(thread_starter);    arg->args=aggregate_array(args);    arg->id=clone(thread_id_prog,0);    tmp=th_create(&dummy,new_thread_func,arg);    if(!tmp)    {    num_threads++;       if(num_threads == 1 && !threads_evaluator_callback)    {    threads_evaluator_callback=add_to_callback(&evaluator_callbacks,    check_threads, 0,0);    } -  + #ifdef UNIX_THREADS +  if((num_lwps==1) || num_threads/3 > num_lwps) +  th_setconcurrency(++num_lwps); + #endif    push_object(arg->id);    arg->id->refs++;    } else {    free_object(arg->id);    free_array(arg->args);    free((char *)arg);    push_int(0);    }   }    -  + 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); +  num_threads=c; +  th_setconcurrency(c); + } +    void f_this_thread(INT32 args)   {    pop_n_elems(args);    push_object(thread_id);    thread_id->refs++;   }      void th_init()   {    mt_lock( & interpreter_lock); -  + #ifdef POSIX_THREADS    pthread_attr_init(&pattr);   #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE    pthread_attr_setstacksize(&pattr, 2 * 1024 * 1204);   #endif    pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED); -  + #endif       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);   }         #define THIS_MUTEX ((struct mutex_storage *)(fp->current_storage))         /* Note:    * No reference is kept to the key object, it is destructed if the