pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:517:   PMOD_EXPORT INLINE void pike_unlock_interpreter (DLOC_DECL)   {    THREADS_FPRINTF (1, (stderr, "Releasing iplock" DLOC_PF(" @ ",) "\n"    COMMA_DLOC_ARGS_OPT));    UNSET_LOCKING_THREAD;    mt_unlock (&interpreter_lock);   }      PMOD_EXPORT INLINE void pike_wait_interpreter (COND_T *cond COMMA_DLOC_DECL)   { +  int owner = threads_disabled;    pike_low_wait_interpreter (cond COMMA_DLOC_ARGS_OPT); -  if (threads_disabled) threads_disabled_wait (DLOC_ARGS_OPT); +  if (!owner && threads_disabled) threads_disabled_wait (DLOC_ARGS_OPT);   }      PMOD_EXPORT INLINE int pike_timedwait_interpreter (COND_T *cond,    long sec, long nsec    COMMA_DLOC_DECL)   { -  +  int owner = threads_disabled;    int res = pike_low_timedwait_interpreter (cond, sec, nsec    COMMA_DLOC_ARGS_OPT); -  if (threads_disabled) threads_disabled_wait (DLOC_ARGS_OPT); +  if (!owner && threads_disabled) threads_disabled_wait (DLOC_ARGS_OPT);    return res;   }      PMOD_EXPORT void pike_init_thread_state (struct thread_state *ts)   {    /* NB: Assumes that there's a temporary Pike_interpreter_struct    * in Pike_interpreter_pointer, which we copy, and replace    * with ourselves.    */    Pike_interpreter.thread_state = ts;
pike.git/src/threads.c:903:    *!    *! @note    *! You should make sure that the returned object is freed even if    *! some kind of error is thrown. That means in practice that it    *! should only have references (direct or indirect) from function    *! local variables. Also, it shouldn't be referenced from cyclic    *! memory structures, since those are only destructed by the periodic    *! gc. (This advice applies to mutex locks in general, for that    *! matter.)    */ - void init_threads_disable(struct object *o) + void init_threads_disable(struct object *UNUSED(o))   {    low_init_threads_disable();       if(live_threads) {    SWAP_OUT_CURRENT_THREAD();    while (live_threads) {    THREADS_FPRINTF(1,    (stderr,    "_disable_threads(): Waiting for %d threads to finish\n",    live_threads));    low_co_wait_interpreter (&live_threads_change);    }    THREADS_FPRINTF(0, (stderr, "_disable_threads(): threads now disabled\n"));    SWAP_IN_CURRENT_THREAD();    }   }    - void exit_threads_disable(struct object *o) + void exit_threads_disable(struct object *UNUSED(o))   {    THREADS_FPRINTF(0, (stderr, "exit_threads_disable(): threads_disabled:%d\n",    threads_disabled));    if(threads_disabled) {    if(!--threads_disabled) {    IMUTEX_T *im = (IMUTEX_T *)interleave_list;       /* Order shouldn't matter for unlock, so no need to do it backwards. */    while(im) {    THREADS_FPRINTF(0, (stderr,
pike.git/src/threads.c:1197:    cleanup_interpret(); /* Must be done before EXIT_THREAD_STATE */    Pike_interpreter.thread_state->status=THREAD_EXITED;    co_signal(&Pike_interpreter.thread_state->status_change);    thread_table_delete(Pike_interpreter.thread_state);    EXIT_THREAD_STATE(Pike_interpreter.thread_state);    Pike_interpreter.thread_state=NULL;    free_object(thread_obj);    thread_obj = NULL;    num_threads--;    mt_unlock_interpreter(); + #ifdef PIKE_DEBUG +  Pike_interpreter_pointer = NULL; + #endif    }   }      PMOD_EXPORT void enable_external_threads(void)   {    num_threads++;   }      PMOD_EXPORT void disable_external_threads(void)   {
pike.git/src/threads.c:1284: Inside #if defined(PIKE_DEBUG)
   }    fprintf(stderr,"-----------------------\n");   }   #endif      PMOD_EXPORT int count_pike_threads(void)   {    return num_pike_threads;   }    - static void check_threads(struct callback *cb, void *arg, void * arg2) + static void check_threads(struct callback *UNUSED(cb), void *UNUSED(arg), void *UNUSED(arg2))   {   #ifdef PROFILE_CHECK_THREADS    static unsigned long calls = 0, yields = 0;    static unsigned long clock_checks = 0, no_clock_advs = 0;   #if 0    static unsigned long slice_int_n = 0; /* Slice interval length. */    static double slice_int_mean = 0.0, slice_int_m2 = 0.0;    static unsigned long tsc_int_n = 0; /* Actual tsc interval length. */    static double tsc_int_mean = 0.0, tsc_int_m2 = 0.0;    static unsigned long tsc_tgt_n = 0; /* Target tsc interval length. */
pike.git/src/threads.c:2251:    struct mutex_storage *m = THIS_MUTEX;       pop_n_elems(args);       if (m->key)    ref_push_object(m->key);    else    push_int(0);   }    - void init_mutex_obj(struct object *o) + void init_mutex_obj(struct object *UNUSED(o))   {    co_init(& THIS_MUTEX->condition);    THIS_MUTEX->key=0;    THIS_MUTEX->num_waiting = 0;   }    - void exit_mutex_obj(struct object *o) + void exit_mutex_obj(struct object *UNUSED(o))   {    struct mutex_storage *m = THIS_MUTEX;    struct object *key = m->key;       THREADS_FPRINTF(1, (stderr, "DESTROYING MUTEX m:%p\n", THIS_MUTEX));      #ifndef PICKY_MUTEX    if (key) {    /* The last key will destroy m->condition in its exit hook. */    THREADS_FPRINTF(1, (stderr, "Destructed mutex is in use - delaying cleanup\n"));
pike.git/src/threads.c:2296:    * lock we need to double it to a broadcast. The last thread    * that stops waiting will destroy m->condition. */    co_broadcast (&m->condition);    }    }    else    co_destroy(& m->condition);   #endif   }    - void exit_mutex_obj_compat_7_4(struct object *o) + void exit_mutex_obj_compat_7_4(struct object *UNUSED(o))   {    struct mutex_storage *m = THIS_MUTEX;    struct object *key = m->key;       THREADS_FPRINTF(1, (stderr, "DESTROYING MUTEX m:%p\n", THIS_MUTEX));       if(key) {    m->key=0;    destruct(key); /* Will destroy m->condition if m->num_waiting is zero. */    }
pike.git/src/threads.c:2334:    *!    *! As long as they are held, the corresponding mutex will be locked.    *!    *! The corresponding mutex will be unlocked when the object    *! is destructed (eg by not having any references left).    *!    *! @seealso    *! @[Mutex], @[Condition]    */   #define THIS_KEY ((struct key_storage *)(CURRENT_STORAGE)) - void init_mutex_key_obj(struct object *o) + void init_mutex_key_obj(struct object *UNUSED(o))   {    THREADS_FPRINTF(1, (stderr, "KEY k:%p, t:%p\n",    THIS_KEY, Pike_interpreter.thread_state));    THIS_KEY->mut=0;    THIS_KEY->mutex_obj = NULL;    THIS_KEY->owner = Pike_interpreter.thread_state;    add_ref(THIS_KEY->owner_obj = Pike_interpreter.thread_state->thread_obj);    THIS_KEY->initialized=1;   }    - void exit_mutex_key_obj(struct object *o) + void exit_mutex_key_obj(struct object *DEBUGUSED(o))   {    THREADS_FPRINTF(1, (stderr, "UNLOCK k:%p m:(%p) t:%p o:%p\n",    THIS_KEY, THIS_KEY->mut,    Pike_interpreter.thread_state, THIS_KEY->owner));    if(THIS_KEY->mut)    {    struct mutex_storage *mut = THIS_KEY->mut;    struct object *mutex_obj;      #ifdef PIKE_DEBUG
pike.git/src/threads.c:2567:    *!    *! @seealso    *! @[signal()]    */   void f_cond_broadcast(INT32 args)   {    pop_n_elems(args);    co_broadcast(&(THIS_COND->cond));   }    - void init_cond_obj(struct object *o) + void init_cond_obj(struct object *UNUSED(o))   {    co_init(&(THIS_COND->cond));    THIS_COND->wait_count = 0;   }    - void exit_cond_obj(struct object *o) + void exit_cond_obj(struct object *UNUSED(o))   {    /* Wake up any threads that might be waiting on this cond.    *    * Note that we are already destructed (o->prog == NULL),    * so wait_count can't increase.    *    * FIXME: This code wouldn't be needed if exit callbacks were called    * only when the ref count reaches zero.    * /grubba 2006-01-29    */
pike.git/src/threads.c:2691:   {    pop_n_elems(args);    push_int64(PTR_TO_INT(THREAD_T_TO_PTR(THIS_THREAD->id)));   }      /*! @decl mixed wait()    *!    *! Waits for the thread to complete, and then returns    *! the value returned from the thread function.    */ - static void f_thread_id_result(INT32 args) + static void f_thread_id_result(INT32 UNUSED(args))   {    struct thread_state *th=THIS_THREAD;       if (threads_disabled) {    Pike_error("Cannot wait for threads when threads are disabled!\n");    }       th->waiting++;       THREADS_FPRINTF(0, (stderr, "Thread->wait(): Waiting for thread_state %p "
pike.git/src/threads.c:2728:       if (!th->thread_obj)    /* Do this only if exit_thread_obj already has run. */    cleanup_thread_state (th);   }      static int num_pending_interrupts = 0;   static struct callback *thread_interrupt_callback = NULL;      static void check_thread_interrupt(struct callback *foo, -  void *bar, void *gazonk) +  void *UNUSED(bar), void *UNUSED(gazonk))   {    if (Pike_interpreter.thread_state->flags & THREAD_FLAG_SIGNAL_MASK) {    if (Pike_interpreter.thread_state->flags & THREAD_FLAG_TERM) {    throw_severity = THROW_THREAD_EXIT;    } else {    throw_severity = THROW_ERROR;    }    Pike_interpreter.thread_state->flags &= ~THREAD_FLAG_SIGNAL_MASK;    if (!--num_pending_interrupts) {    remove_callback(foo);
pike.git/src/threads.c:2806:    *! @note    *! Interrupts are asynchronous, and are currently not queued.    */   static void f_thread_id_kill(INT32 args)   {    pop_n_elems(args);    low_thread_kill (THIS_THREAD);    push_int(0);   }    - void init_thread_obj(struct object *o) + void init_thread_obj(struct object *UNUSED(o))   {    MEMSET(&THIS_THREAD->state, 0, sizeof(struct Pike_interpreter_struct));    THIS_THREAD->thread_obj = Pike_fp->current_object;    THIS_THREAD->swapped = 0;    THIS_THREAD->status=THREAD_NOT_STARTED;    THIS_THREAD->flags = 0;    THIS_THREAD->waiting = 0;    SET_SVAL(THIS_THREAD->result, T_INT, NUMBER_UNDEFINED, integer, 0);    co_init(& THIS_THREAD->status_change);    THIS_THREAD->thread_local=NULL;
pike.git/src/threads.c:2845:    if (!--num_pending_interrupts) {    remove_callback(thread_interrupt_callback);    thread_interrupt_callback = NULL;    }    }       co_destroy(& THIS_THREAD->status_change);    th_destroy(& THIS_THREAD->id);   }    - void exit_thread_obj(struct object *o) + void exit_thread_obj(struct object *UNUSED(o))   {    THIS_THREAD->thread_obj = NULL;       cleanup_thread_state (THIS_THREAD);       if(THIS_THREAD->thread_local != NULL) {    free_mapping(THIS_THREAD->thread_local);    THIS_THREAD->thread_local = NULL;    }   }      /*! @endclass    */    - static void thread_was_recursed(struct object *o) + static void thread_was_recursed(struct object *UNUSED(o))   {    struct thread_state *tmp=THIS_THREAD;    if(tmp->thread_local != NULL)    gc_recurse_mapping(tmp->thread_local);   }    - static void thread_was_checked(struct object *o) + static void thread_was_checked(struct object *UNUSED(o))   {    struct thread_state *tmp=THIS_THREAD;    if(tmp->thread_local != NULL)    debug_gc_check (tmp->thread_local,    " as mapping for thread local values in thread");      #ifdef PIKE_DEBUG    if(tmp->swapped)    gc_mark_stack_external (tmp->state.frame_pointer, tmp->state.stack_pointer,    tmp->state.evaluator_stack);