pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:1:   #include "global.h" - RCSID("$Id: threads.c,v 1.27 1997/09/01 14:14:30 per Exp $"); + RCSID("$Id: threads.c,v 1.28 1997/09/02 22:18:07 grubba 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:35:   {    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;    - /* 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);*/ +  THREADS_FPRINTF((stderr,"THREADS_DISALLOW() Thread created...\n"));    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);
pike.git/src/threads.c:79:    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--);*/ +  THREADS_FPRINTF((stderr,"THREADS_ALLOW() Thread done\n"));    mt_unlock(& interpreter_lock);    th_exit(0);    /* NOT_REACHED, but removes a warning */    return(NULL);   }      #ifdef UNIX_THREADS   int num_lwps = 1;   #endif   
pike.git/src/threads.c:174:      #define OB2KEY(X) ((struct key_storage *)((X)->storage))      void f_mutex_lock(INT32 args)   {    struct mutex_storage *m;    struct object *o;       pop_n_elems(args);    m=THIS_MUTEX; +  /* Needs to be cloned here, since create() +  * might use threads. +  */    o=clone_object(mutex_key,0);    mt_lock(& mutex_kluge);    if(m->key && OB2KEY(m->key)->owner == thread_id)    { -  m->key->refs++; -  push_object(m->key); +  THREADS_FPRINTF((stderr, "Recursive LOCK k:%08x, m:%08x(%08x), t:%08x\n", +  (unsigned int)OB2KEY(m->key), +  (unsigned int)m, +  (unsigned int)OB2KEY(m->key)->mut, +  (unsigned int) thread_id));    mt_unlock(&mutex_kluge); -  return; -  -  mt_unlock(&mutex_kluge); +  free_object(o);    error("Recursive mutex locks!\n");    }       THREADS_ALLOW();    while(m->key) co_wait(& m->condition, & mutex_kluge); -  OB2KEY(o)->mut=m; -  OB2KEY(o)->owner=thread_id; +     m->key=o; -  +  OB2KEY(o)->mut=m;       mt_unlock(&mutex_kluge);    THREADS_DISALLOW(); -  +  THREADS_FPRINTF((stderr, "LOCK k:%08x, m:%08x(%08x), t:%08x\n", +  (unsigned int)OB2KEY(o), +  (unsigned int)m, +  (unsigned int)OB2KEY(m->key)->mut, +  (unsigned int)thread_id));    push_object(o);   }      void f_mutex_trylock(INT32 args)   {    struct mutex_storage *m;    struct object *o;    int i=0;    pop_n_elems(args);       o=clone_object(mutex_key,0);    m=THIS_MUTEX;       mt_lock(& mutex_kluge);    -  +  /* No reason to release the interpreter lock here +  * since we aren't calling any functions that take time. +  */ +     if(m->key && OB2KEY(m->key)->owner == thread_id)    {    mt_unlock(&mutex_kluge); -  +  free_object(o);    error("Recursive mutex locks!\n");    } -  THREADS_ALLOW(); +     if(!m->key)    {    OB2KEY(o)->mut=m; -  OB2KEY(o)->owner=thread_id; +     m->key=o;    i=1;    }    mt_unlock(&mutex_kluge); -  THREADS_DISALLOW(); +        if(i)    {    push_object(o);    } else {    destruct(o);    free_object(o);    push_int(0);    }   }
pike.git/src/threads.c:251:      void exit_mutex_obj(struct object *o)   {    if(THIS_MUTEX->key) destruct(THIS_MUTEX->key);    co_destroy(& THIS_MUTEX->condition);   }      #define THIS_KEY ((struct key_storage *)(fp->current_storage))   void init_mutex_key_obj(struct object *o)   { +  THREADS_FPRINTF((stderr, "KEY k:%08x, o:%08x\n", +  (unsigned int)THIS_KEY, (unsigned int)thread_id));    THIS_KEY->mut=0; -  THIS_KEY->owner=0; +  THIS_KEY->owner=thread_id; +  thread_id->refs++;    THIS_KEY->initialized=1;   }      void exit_mutex_key_obj(struct object *o)   { -  +  THREADS_FPRINTF((stderr, "UNLOCK k:%08x m:(%08x) t:%08x o:%08x\n", +  (unsigned int)THIS_KEY, +  (unsigned int)THIS_KEY->mut, +  (unsigned int)thread_id, +  (unsigned int)THIS_KEY->owner));    mt_lock(& mutex_kluge);    if(THIS_KEY->mut)    {   #ifdef DEBUG    if(THIS_KEY->mut->key != o)    fatal("Mutex unlock from wrong key %p != %p!\n",THIS_KEY->mut->key,o);   #endif    THIS_KEY->mut->key=0; -  +  if (THIS_KEY->owner) { +  free_object(THIS_KEY->owner);    THIS_KEY->owner=0; -  +  }    co_signal(& THIS_KEY->mut->condition);    THIS_KEY->mut=0;    THIS_KEY->initialized=0;    }    mt_unlock(& mutex_kluge);   }      #define THIS_COND ((COND_T *)(fp->current_storage))   void f_cond_wait(INT32 args)   {
pike.git/src/threads.c:335:   }      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(void)   {    struct program *tmp; +  INT32 mutex_key_offset;      #ifdef SGI_SPROC_THREADS   #error /* Need to specify a filename */    us_cookie = usinit("");   #endif /* SGI_SPROC_THREADS */       mt_lock( & interpreter_lock);   #ifdef POSIX_THREADS    pthread_attr_init(&pattr);   #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
pike.git/src/threads.c:368:       start_new_program();    add_storage(sizeof(struct mutex_storage));    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_class("mutex", 0);       start_new_program(); -  add_storage(sizeof(struct key_storage)); +  mutex_key_offset = add_storage(sizeof(struct key_storage)); +  /* This is needed to allow the gc to find the possible circular reference. +  * It also allows a process to take over ownership of a key. +  */ +  map_variable("_owner", "object", 0, +  mutex_key_offset + OFFSETOF(key_storage, owner), T_OBJECT);    set_init_callback(init_mutex_key_obj);    set_exit_callback(exit_mutex_key_obj);    mutex_key=end_program();    if(!mutex_key)    fatal("Failed to initialize mutex_key program!\n");       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);