pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:1:   #include "global.h" - RCSID("$Id: threads.c,v 1.93 1999/05/02 08:11:50 hubbe Exp $"); + RCSID("$Id: threads.c,v 1.94 1999/05/08 00:41:01 hubbe Exp $");      int num_threads = 1;   int threads_disabled = 0;      #ifdef _REENTRANT   #include "threads.h"   #include "array.h"   #include "mapping.h"   #include "object.h"   #include "pike_macros.h"
pike.git/src/threads.c:329:    INT32 x;    for(x=0; x<THREAD_TABLE_SIZE; x++)    thread_table_chains[x] = NULL;   }      unsigned INT32 thread_table_hash(THREAD_T *tid)   {    return th_hash(*tid) % THREAD_TABLE_SIZE;   }    + #ifdef PIKE_DEBUG + static void dumpmem(char *desc, void *x, int size) + { +  int e; +  unsigned char *tmp=(unsigned char *)x; +  fprintf(stderr,"%s: ",desc); +  for(e=0;e<size;e++) +  fprintf(stderr,"%02x",tmp[e]); +  fprintf(stderr,"\n"); + } + #endif +  +    void thread_table_insert(struct object *o)   {    struct thread_state *s = OBJ2THREAD(o);    unsigned INT32 h = thread_table_hash(&s->id);   #ifdef PIKE_DEBUG    if(h>=THREAD_TABLE_SIZE)    fatal("thread_table_hash failed miserably!\n"); -  +  if(thread_state_for_id(s->id)) +  fatal("Registring thread twice!\n"); + /* dumpmem("thread_table_insert",&s->id, sizeof(THREAD_T)); */   #endif    mt_lock( & thread_table_lock );    if((s->hashlink = thread_table_chains[h]) != NULL)    s->hashlink->backlink = &s->hashlink;    thread_table_chains[h] = s;    s->backlink = &thread_table_chains[h];    mt_unlock( & thread_table_lock );   }      void thread_table_delete(struct object *o)   {    struct thread_state *s = OBJ2THREAD(o); -  + /* dumpmem("thread_table_delete",&s->id, sizeof(THREAD_T)); */    mt_lock( & thread_table_lock );    if(s->hashlink != NULL)    s->hashlink->backlink = s->backlink;    *(s->backlink) = s->hashlink;    mt_unlock( & thread_table_lock );   }      struct thread_state *thread_state_for_id(THREAD_T tid)   {    unsigned INT32 h = thread_table_hash(&tid);    struct thread_state *s = NULL; -  + #if 0 +  if(num_threads>1) +  dumpmem("thread_state_for_id: ",&tid,sizeof(tid)); + #endif   #ifdef PIKE_DEBUG    if(h>=THREAD_TABLE_SIZE)    fatal("thread_table_hash failed miserably!\n");   #endif    mt_lock( & thread_table_lock );    if(thread_table_chains[h] == NULL)    {    /* NULL result */    }    else if(th_equal((s=thread_table_chains[h])->id, tid))
pike.git/src/threads.c:393:    s->hashlink->backlink = s->backlink;    *(s->backlink) = s->hashlink;    /* And relink at the head of the chain */    if((s->hashlink = thread_table_chains[h]) != NULL)    s->hashlink->backlink = &s->hashlink;    thread_table_chains[h] = s;    s->backlink = &thread_table_chains[h];    }    }    mt_unlock( & thread_table_lock ); + #if 0 +  if(num_threads>1 && s) +  dumpmem("thread_state_for_id return value: ",&s->id,sizeof(tid)); + #endif    return s;    /* NOTEZ BIEN: Return value only guaranteed to remain valid as long    as you have the interpreter lock, unless tid == th_self() */   }      struct object *thread_for_id(THREAD_T tid)   {    struct thread_state *s = thread_state_for_id(tid); -  return (s == NULL? NULL : -  (struct object *)(((char *)s)-((((struct object *)NULL)->storage)- -  ((char*)NULL)))); +  return (s == NULL? NULL : THREADSTATE2OBJ(s));    /* See NB in thread_state_for_id. Lifespan of result can be prolonged    by incrementing refcount though. */   }      void f_all_threads(INT32 args)   {    /* Return an unordered array containing all threads that was running    at the time this function was invoked */       INT32 x;    struct svalue *oldsp;    struct thread_state *s;       pop_n_elems(args);    oldsp = sp;    mt_lock( & thread_table_lock );    for(x=0; x<THREAD_TABLE_SIZE; x++)    for(s=thread_table_chains[x]; s; s=s->hashlink) { -  struct object *o = -  (struct object *)(((char *)s)-((((struct object *)NULL)->storage)- -  ((char*)NULL))); +  struct object *o = THREADSTATE2OBJ(s);    ref_push_object(o);    }    mt_unlock( & thread_table_lock );    f_aggregate(sp-oldsp);   }         static void check_threads(struct callback *cb, void *arg, void * arg2)   {    static int div_;    if(div_++ & 255) return;    -  + #ifdef DEBUG +  if(thread_for_id(th_self()) != thread_id) +  fatal("thread_for_id() (or thread_id) failed!\n") + #endif +     THREADS_ALLOW();    /* Allow other threads to run */    THREADS_DISALLOW(); -  +  + #ifdef DEBUG +  if(thread_for_id(th_self()) != thread_id) +  fatal("thread_for_id() (or thread_id) failed!\n") + #endif +  +    }    - void *new_thread_func(void * data) + TH_RETURN_TYPE new_thread_func(void * data)   {    struct thread_starter arg = *(struct thread_starter *)data;    JMP_BUF back;    INT32 tmp;       THREADS_FPRINTF(0, (stderr,"THREADS_DISALLOW() Thread %08x created...\n",    (unsigned int)arg.id));       if((tmp=mt_lock( & interpreter_lock)))    fatal("Failed to lock interpreter, errno %d\n",tmp);    init_interpreter();    thread_id=arg.id;    SWAP_OUT_THREAD(OBJ2THREAD(thread_id)); /* Init struct */    OBJ2THREAD(thread_id)->swapped=0;    stack_top=((char *)&data)+ (thread_stack_size-16384) * STACK_DIRECTION;    recoveries = NULL;    -  + #if defined(PIKE_DEBUG) +  if(d_flag) +  { +  if( thread_id && !th_equal( OBJ2THREAD(thread_id)->id, th_self()) ) +  fatal("Current thread is wrong. %x %x\n",OBJ2THREAD(thread_id)->id,th_self()); +  +  if(thread_for_id(th_self()) != thread_id) +  fatal("thread_for_id() (or thread_id) failed in new_thread_func! %p != %p\n",thread_for_id(th_self()),thread_id); +  } + #endif +    #ifdef THREAD_TRACE    {    t_flag = default_t_flag;    }   #endif /* THREAD_TRACE */       THREADS_FPRINTF(0, (stderr,"THREAD %08x INITED\n",(unsigned int)thread_id));    if(SETJMP(back))    {    if(throw_severity < THROW_EXIT)
pike.git/src/threads.c:652:    }    case 1:    break;    }       /* Needs to be cloned here, since create()    * might use threads.    */    o=clone_object(mutex_key,0);    +  DO_IF_DEBUG( if(thread_for_id(th_self()) != thread_id) +  fatal("thread_for_id() (or thread_id) failed! %p != %p\n",thread_for_id(th_self()),thread_id) ; ) +     if(m->key)    {    SWAP_OUT_CURRENT_THREAD();    do    {    THREADS_FPRINTF(1, (stderr,"WAITING TO LOCK m:%08x\n",(unsigned int)m));    co_wait(& m->condition, & interpreter_lock);    }while(m->key);    SWAP_IN_CURRENT_THREAD();    }    m->key=o;    OB2KEY(o)->mut=m;    -  +  DO_IF_DEBUG( if(thread_for_id(th_self()) != thread_id) +  fatal("thread_for_id() (or thread_id) failed! %p != %p\n",thread_for_id(th_self()),thread_id) ; ) +     THREADS_FPRINTF(1, (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));    pop_n_elems(args);    push_object(o);   }      void f_mutex_trylock(INT32 args)
pike.git/src/threads.c:1000: Inside #if defined(POSIX_THREADS)
   thread_table_init();   #ifdef POSIX_THREADS    pthread_attr_init(&pattr);   #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE    pthread_attr_setstacksize(&pattr, thread_stack_size);   #endif    pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);       pthread_attr_init(&small_pattr);   #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE -  pthread_attr_setstacksize(&small_pattr, 32768); +  pthread_attr_setstacksize(&small_pattr, 4096*sizeof(char *));   #endif    pthread_attr_setdetachstate(&small_pattr, PTHREAD_CREATE_DETACHED);      #endif   }      void th_init(void)   {    struct program *tmp;    INT32 mutex_key_offset;
pike.git/src/threads.c:1163:   static struct farmer {    struct farmer *neighbour;    void *field;    void (*harvest)(void *);    THREAD_T me;    COND_T harvest_moon;   } *farmers;      static MUTEX_T rosie;    - static void *farm(void *_a) + static TH_RETURN_TYPE farm(void *_a)   {    struct farmer *me = (struct farmer *)_a;    do    {   /* if(farmers == me) fatal("Ouch!\n"); */   /* fprintf(stderr, "farm_begin %p\n",me ); */    me->harvest( me->field );   /* fprintf(stderr, "farm_end %p\n", me); */       me->harvest = 0;
pike.git/src/threads.c:1208:   }      static struct farmer *new_farmer(void (*fun)(void *), void *args)   {    struct farmer *me = malloc(sizeof(struct farmer));    _num_farmers++;    me->neighbour = 0;    me->field = args;    me->harvest = fun;    co_init( &me->harvest_moon ); - #ifdef UNIX_THREADS -  /* FIXME: Why not increase the stacksize of th_create_small(), -  * and use it instead? -  */ -  thr_create(NULL, 65536, farm, me, THR_DAEMON|THR_DETACHED, &me->me); - #else +     th_create_small(&me->me, farm, me); - #endif +     return me;   }      void th_farm(void (*fun)(void *), void *here)   {    if(!fun) fatal("The farmers don't known how to handle empty fields\n");    mt_lock( &rosie );    if(farmers)    {    struct farmer *f = farmers;