pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:1:   #include "global.h" - RCSID("$Id: threads.c,v 1.24 1997/08/30 18:36:01 grubba Exp $"); + RCSID("$Id: threads.c,v 1.25 1997/08/31 22:24:00 per 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 <errno.h>      struct object *thread_id;   static struct callback *threads_evaluator_callback=0;    - MUTEX_T interpreter_lock = PTHREAD_MUTEX_INITIALIZER; + 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   {    struct object *id;    struct array *args;
pike.git/src/threads.c:35:   {    THREADS_ALLOW();       /* Allow other threads to run */       THREADS_DISALLOW();   }      void *new_thread_func(void * data)   { - /* static int dbt;*/ + #ifdef MASSIVE_DEBUG +  static int dbt; + #endif    struct thread_starter arg = *(struct thread_starter *)data;    JMP_BUF back;    INT32 tmp;    - /* fprintf(stderr, "Thread create[%d]...",dbt++);*/ + #ifdef MASSIVE_DEBUG +  fprintf(stderr, "Thread create[%d:%p]...",dbt++,data); + #endif    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.... */ + #ifdef MASSIVE_DEBUG +  fprintf(stderr,"Created[%d:%p]...",dbt,data); + #endif    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); -  +  free((char *)data); /* Moved by per, to avoid some bugs.... */ + #ifdef MASSIVE_DEBUG +  fprintf(stderr,"Error [%d:%p]\n",dbt,data); + #endif    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); -  + #ifdef MASSIVE_DEBUG +  fprintf(stderr,"Called [%d:%p]\n",dbt,data); + #endif    pop_stack(); /* Discard the return value. /Per */ -  +  free((char *)data); /* Moved by per, to avoid some bugs.... */    }       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--);*/ + #ifdef MASSIVE_DEBUG +  fprintf(stderr,"Done[%d:%p]\n",dbt--,data); + #endif    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:130:    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; +  num_lwps=c;    th_setconcurrency(c);   }      void f_this_thread(INT32 args)   {    pop_n_elems(args);    push_object(thread_id);    thread_id->refs++;   }   
pike.git/src/threads.c:152:         /* Note:    * No reference is kept to the key object, it is destructed if the    * mutex is destructed. The key pointer is set to zero by the    * key object when the key is destructed.    */      struct mutex_storage   { + #ifdef SOLARIS +  sema_t sema; + #else    COND_T condition; -  + #endif    struct object *key;   };      struct key_storage   {    struct mutex_storage *mut;    int initialized; -  +  struct object *owner;   };    - static MUTEX_T mutex_kluge = PTHREAD_MUTEX_INITIALIZER; + static MUTEX_T mutex_kluge;      #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; -  +  if(m->key && OB2KEY(m->key)->owner == thread_id) +  error("Recursive mutex locks!\n");    o=clone_object(mutex_key,0); -  mt_lock(& mutex_kluge); + #ifdef SOLARIS    THREADS_ALLOW(); -  while(m->key) co_wait(& m->condition, & mutex_kluge); +  // Might be interrupted by signals. +  while((sema_wait( &m->sema )) && (errno==EAGAIN)); +  THREADS_DISALLOW();    OB2KEY(o)->mut=m;    m->key=o; -  + #else +  THREADS_ALLOW(); +  mt_lock(& mutex_kluge); +  while(m->key) co_wait(& m->condition, & mutex_kluge);    mt_unlock(&mutex_kluge);    THREADS_DISALLOW(); -  +  OB2KEY(o)->mut=m; +  m->key=o; + #endif    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); -  THREADS_ALLOW(); +  if(m->key && OB2KEY(m->key)->owner == thread_id) +  error("Recursive mutex locks!\n");    if(!m->key)    {    OB2KEY(o)->mut=m;    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);    }   }      void init_mutex_obj(struct object *o)   { -  + #ifdef SOLARIS +  sema_init(& THIS_MUTEX->sema, 1, USYNC_THREAD, NULL ); + #else    co_init(& THIS_MUTEX->condition); -  + #endif    THIS_MUTEX->key=0;   }      void exit_mutex_obj(struct object *o)   {    if(THIS_MUTEX->key) destruct(THIS_MUTEX->key); -  + #ifdef SOLARIS +  sema_destroy( & THIS_MUTEX->sema ); + #else    co_destroy(& THIS_MUTEX->condition); -  + #endif   }      #define THIS_KEY ((struct key_storage *)(fp->current_storage))   void init_mutex_key_obj(struct object *o)   {    THIS_KEY->mut=0;    THIS_KEY->initialized=1; -  +  THIS_KEY->owner=thread_id;   }      void exit_mutex_key_obj(struct object *o)   { -  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 -  +  + #ifdef SOLARIS +  sema_post( &THIS_KEY->mut->sema );    THIS_KEY->mut->key=0; -  + #else +  mt_lock(& mutex_kluge); + #endif +  THIS_KEY->mut->key=0; + #ifndef SOLARIS    co_signal(& THIS_KEY->mut->condition); -  + #endif    THIS_KEY->mut=0; -  +  THIS_KEY->owner=0;    THIS_KEY->initialized=0;    } -  + #ifndef SOLARIS    mt_unlock(& mutex_kluge); -  + #endif   }      #define THIS_COND ((COND_T *)(fp->current_storage))   void f_cond_wait(INT32 args)   {    COND_T *c;    struct object *key;       if(args > 1) pop_n_elems(args - 1);   
pike.git/src/threads.c:272:    struct mutex_storage *mut;       if(sp[-1].type != T_OBJECT)    error("Bad argument 1 to condition->wait()\n");       key=sp[-1].u.object;       if(key->prog != mutex_key)    error("Bad argument 1 to condition->wait()\n");    -  mt_lock(&mutex_kluge); +     mut=OB2KEY(key)->mut;    THREADS_ALLOW(); -  + #ifdef SOLARIS +  mut->key=0; +  sema_post( &mut->sema ); +  /* Wait and allow mutex operations */ +  co_wait(c,0); +  while((sema_wait( &mut->sema )) && (errno==EAGAIN)); +  mut->key=key; + #else +  mt_lock(&mutex_kluge);    /* Unlock mutex */    mut->key=0;    OB2KEY(key)->mut=0;    co_signal(& mut->condition); -  +     /* Wait and allow mutex operations */    co_wait(c,&mutex_kluge); -  +     if(OB2KEY(key)->initialized)    {    /* Lock mutex */    while(mut->key) co_wait(& mut->condition, & mutex_kluge);    mut->key=key;    OB2KEY(key)->mut=mut;    }    mt_unlock(&mutex_kluge); -  + #endif    THREADS_DISALLOW();    pop_stack();    } else {    THREADS_ALLOW();    co_wait(c, 0);    THREADS_DISALLOW();    }   }      void f_cond_signal(INT32 args) { pop_n_elems(args); co_signal(THIS_COND); }