pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:1:   #include "global.h" - RCSID("$Id: threads.c,v 1.47 1997/11/11 04:02:45 grubba Exp $"); + RCSID("$Id: threads.c,v 1.48 1998/01/02 01:05:54 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"   #include "builtin_functions.h"   #include "constants.h"   #include "program.h"   #include "gc.h"    -  + #define THIS_THREAD ((struct thread_state *)fp->current_storage) +    struct object *thread_id;   static struct callback *threads_evaluator_callback=0; -  + int thread_id_result_variable;      MUTEX_T interpreter_lock;   struct program *mutex_key = 0;   struct program *thread_id_prog = 0;   #ifdef POSIX_THREADS   pthread_attr_t pattr;   #endif      struct thread_starter   {
pike.git/src/threads.c:66:    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 */ +  +  /* copy return value to the thread_id here */ +  object_low_set_index(thread_id, +  thread_id_result_variable, +  sp-1); +  pop_stack();    }    -  +  ((struct thread_state *)(thread_id->storage))->status=THREAD_EXITED; +  co_signal(& ((struct thread_state *)(thread_id->storage))->status_change); +     free((char *)data); /* Moved by per, to avoid some bugs.... */    UNSETJMP(back);       destruct(thread_id);    THREADS_FPRINTF((stderr,"THREADS_ALLOW() Thread %08x done\n",    (unsigned int)thread_id));       free_object(thread_id);    thread_id=0;    cleanup_interpret();
pike.git/src/threads.c:103:   #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); +  ((struct thread_state *)arg->id->storage)->status=THREAD_RUNNING;       tmp=th_create(&dummy,new_thread_func,arg);       if(!tmp)    {    num_threads++;       if(!threads_evaluator_callback)    {    threads_evaluator_callback=add_to_callback(&evaluator_callbacks,
pike.git/src/threads.c:388:    sp=foo->sp;    SWAP_OUT_THREAD(foo);    SWAP_IN_THREAD(bar);    sp=osp;    } else {    push_int(0);    f_allocate(1);    }   }    + 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_state *th=THIS_THREAD; +  +  SWAP_OUT_CURRENT_THREAD(); +  +  while(th->status != THREAD_EXITED) +  co_wait(&th->status_change, &interpreter_lock); +  +  SWAP_IN_CURRENT_THREAD(); +  +  low_object_index_no_free(sp, +  fp->current_object, +  thread_id_result_variable); +  sp++; + } +    void init_thread_obj(struct object *o)   {    MEMSET(o->storage, 0, sizeof(struct thread_state)); -  +  THIS_THREAD->status=THREAD_NOT_STARTED; +  co_init(& THIS_THREAD->status_change);   }    -  +  + void exit_thread_obj(struct object *o) + { +  co_destroy(& THIS_THREAD->status_change); + } +    #ifdef DEBUG   static void thread_was_marked(struct object *o)   {    struct thread_state *tmp=(struct thread_state *)(o->storage);    if(tmp->swapped)    {    debug_gc_xmark_svalues(tmp->evaluator_stack,tmp->sp-tmp->evaluator_stack-1,"idle thread stack");    }   }   #endif
pike.git/src/threads.c:474:    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_state)); +  thread_id_result_variable=simple_add_variable("result","mixed",0);    add_function("backtrace",f_thread_backtrace,"function(:array)",0); -  +  add_function("wait",f_thread_id_result,"function(:mixed)",0); +  add_function("status",f_thread_id_status,"function(:int)",0);   #ifdef DEBUG    set_gc_mark_callback(thread_was_marked);   #endif    set_init_callback(init_thread_obj); -  +  set_init_callback(exit_thread_obj);    thread_id_prog=end_program();    if(!mutex_key)    fatal("Failed to initialize thread program!\n");       thread_id=clone_object(thread_id_prog,0);    SWAP_OUT_THREAD((struct thread_state *)thread_id->storage); /* Init struct */    ((struct thread_state *)thread_id->storage)->swapped=0;   }      void th_cleanup(void)