pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:1:   #include "global.h" - RCSID("$Id: threads.c,v 1.23 1997/04/20 03:53:35 grubba Exp $"); + RCSID("$Id: threads.c,v 1.23.2.1 1997/05/10 12:56:57 hubbe Exp $");      int num_threads = 1;   int threads_disabled = 0;      #ifdef _REENTRANT   #include "threads.h"   #include "array.h"   #include "object.h"   #include "pike_macros.h"   #include "callback.h"
pike.git/src/threads.c:23: Inside #if defined(POSIX_THREADS)
  #ifdef POSIX_THREADS   pthread_attr_t pattr;   #endif      struct thread_starter   {    struct object *id;    struct array *args;   };    + struct thread_id { +  int status; +  COND_T status_change; + }; +  + static int thread_id_result_variable; +  + static MUTEX_T thread_id_kluge = PTHREAD_MUTEX_INITIALIZER; +  + #define THREAD_UNKNOWN 0 + #define THREAD_RUNNING 1 + #define THREAD_EXITED 2 +    static void check_threads(struct callback *cb, void *arg, void * arg2)   {    THREADS_ALLOW();       /* Allow other threads to run */       THREADS_DISALLOW();   }    -  + #define THIS_THREAD ((struct thread_id *)fp->current_storage) + #define THREAD_INFO ((struct thread_id *)thread_id->storage) +  + static void init_thread_id(struct object *o) + { +  THIS_THREAD->status=THREAD_UNKNOWN; +  co_init(& THIS_THREAD->status_change); + } +  + static void exit_thread_id(struct object *o) + { +  co_destroy(& THIS_THREAD->status_change); + } +  + static 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_id *th=THIS_THREAD; +  THREADS_ALLOW(); +  mt_lock(&thread_id_kluge); +  while(th->status != THREAD_EXITED) +  co_wait(&th->status_change, &thread_id_kluge); +  mt_unlock(&thread_id_kluge); +  THREADS_DISALLOW(); +  +  low_object_index_no_free(sp, +  fp->current_object, +  thread_id_result_variable); +  sp++; + } +    void *new_thread_func(void * data)   {   /* static int dbt;*/    struct thread_starter arg = *(struct thread_starter *)data;    JMP_BUF back;    INT32 tmp;      /* 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; -  +  THREAD_INFO->status=THREAD_RUNNING;       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);    arg.args=0;    f_call_function(args); -  pop_stack(); /* Discard the return value. /Per */ +  +  fprintf(stderr,"Done "); +  /* copy return value to the thread_id here */ +  object_low_set_index(thread_id, +  thread_id_result_variable, +  sp-1); +  pop_stack();    }       UNSETJMP(back);    -  destruct(thread_id); +  THREAD_INFO->status=THREAD_EXITED; +  co_signal(& THREAD_INFO->status_change);       free_object(thread_id);    thread_id=0;       cleanup_interpret();    num_threads--;    if(!num_threads)    {    remove_callback(threads_evaluator_callback);    threads_evaluator_callback=0;
pike.git/src/threads.c:97:   #endif      void f_thread_create(INT32 args)   {    THREAD_T dummy;    struct thread_starter *arg;    int tmp;    arg=ALLOC_STRUCT(thread_starter);    arg->args=aggregate_array(args);    arg->id=clone_object(thread_id_prog,0); +  arg->id->refs++;       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_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;
pike.git/src/threads.c:358:    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_class("condition", 0);       start_new_program(); +  add_storage(sizeof(struct thread_id)); +  thread_id_result_variable=simple_add_variable("result","mixed",0); +  add_function("wait",f_thread_id_result,"function(:int)",0); +  add_function("status",f_thread_id_status,"function(:int)",0); +  set_init_callback(init_thread_id); +  set_exit_callback(exit_thread_id);    thread_id_prog=end_program();    if(!mutex_key)    fatal("Failed to initialize thread program!\n");       thread_id=clone_object(thread_id_prog,0);   }      void th_cleanup()   {    if(mutex_key)
pike.git/src/threads.c:381:    }       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;    }   }      #endif