pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:67:      PMOD_EXPORT struct Pike_interpreter_struct * pike_get_interpreter_pointer(void)   {    return Pike_interpreter_pointer;   }   #else /* CONFIGURE_TEST */   #include "pike_threadlib.h"   #endif      #ifndef VERBOSE_THREADS_DEBUG - #define THREADS_FPRINTF(LEVEL,FPRINTF_ARGS) + #define THREADS_FPRINTF(LEVEL,...)   #else - #define THREADS_FPRINTF(LEVEL,FPRINTF_ARGS) do { \ + #define THREADS_FPRINTF(LEVEL,...) do { \    if ((VERBOSE_THREADS_DEBUG + 0) >= (LEVEL)) { \    /* E.g. THREADS_DISALLOW is used in numerous places where the */ \    /* value in errno must not be clobbered. */ \    int saved_errno = errno; \    fprintf (stderr, "[%"PRINTSIZET"x] ", (size_t) th_self()); \ -  fprintf FPRINTF_ARGS; \ +  fprintf (stderr, __VA_ARGS__); \    errno = saved_errno; \    } \    } while(0)   #endif /* VERBOSE_THREADS_DEBUG */      #ifndef PIKE_THREAD_C_STACK_SIZE   #define PIKE_THREAD_C_STACK_SIZE (256 * 1024)   #endif      PMOD_EXPORT size_t thread_stack_size=PIKE_THREAD_C_STACK_SIZE;
pike.git/src/threads.c:457:    /* The double locking here is to ensure that when a thread releases    * the interpreter lock, a different thread gets it first. Thereby    * we ensure a thread switch in check_threads, if there are other    * threads waiting. */    mt_lock (&interpreter_lock_wanted);    mt_lock (&interpreter_lock);    mt_unlock (&interpreter_lock_wanted);       SET_LOCKING_THREAD;    USE_DLOC_ARGS(); -  THREADS_FPRINTF (1, (stderr, "Got iplock" DLOC_PF(" @ ",) "\n" -  COMMA_DLOC_ARGS_OPT)); +  THREADS_FPRINTF (1, "Got iplock" DLOC_PF(" @ ",) "\n", DLOC_ARGS_OPT);   }      PMOD_EXPORT void pike_low_wait_interpreter (COND_T *cond COMMA_DLOC_DECL)   {    USE_DLOC_ARGS(); -  THREADS_FPRINTF (1, (stderr, +  THREADS_FPRINTF (1,    "Waiting on cond %p without iplock" DLOC_PF(" @ ",) "\n", -  cond COMMA_DLOC_ARGS_OPT)); +  cond, DLOC_ARGS_OPT);    UNSET_LOCKING_THREAD;       /* FIXME: Should use interpreter_lock_wanted here as well. The    * problem is that few (if any) thread libs lets us atomically    * unlock a mutex and wait, and then lock a different mutex. */    co_wait (cond, &interpreter_lock);       SET_LOCKING_THREAD; -  THREADS_FPRINTF (1, (stderr, +  THREADS_FPRINTF (1,    "Got signal on cond %p with iplock" DLOC_PF(" @ ",) "\n", -  cond COMMA_DLOC_ARGS_OPT)); +  cond, DLOC_ARGS_OPT);   }      PMOD_EXPORT int pike_low_timedwait_interpreter (COND_T *cond,    long sec, long nsec    COMMA_DLOC_DECL)   {    int res;    USE_DLOC_ARGS(); -  THREADS_FPRINTF (1, (stderr, +  THREADS_FPRINTF (1,    "Waiting on cond %p without iplock" DLOC_PF(" @ ",) "\n", -  cond COMMA_DLOC_ARGS_OPT)); +  cond, DLOC_ARGS_OPT);    UNSET_LOCKING_THREAD;       /* FIXME: Should use interpreter_lock_wanted here as well. The    * problem is that few (if any) thread libs lets us atomically    * unlock a mutex and wait, and then lock a different mutex. */    res = co_wait_timeout (cond, &interpreter_lock, sec, nsec);       SET_LOCKING_THREAD; -  THREADS_FPRINTF (1, (stderr, +  THREADS_FPRINTF (1,    "Got signal on cond %p with iplock" DLOC_PF(" @ ",) "\n", -  cond COMMA_DLOC_ARGS_OPT)); +  cond, DLOC_ARGS_OPT);    return res;   }      static void threads_disabled_wait (DLOC_DECL)   {    assert (threads_disabled);    USE_DLOC_ARGS();    do { -  THREADS_FPRINTF (1, (stderr, -  "Waiting on threads_disabled" DLOC_PF(" @ ",) "\n" -  COMMA_DLOC_ARGS_OPT)); +  THREADS_FPRINTF (1, +  "Waiting on threads_disabled" DLOC_PF(" @ ",) "\n", +  DLOC_ARGS_OPT);    UNSET_LOCKING_THREAD;    co_wait (&threads_disabled_change, &interpreter_lock);    SET_LOCKING_THREAD;    } while (threads_disabled); -  THREADS_FPRINTF (1, (stderr, -  "Continue after threads_disabled" DLOC_PF(" @ ",) "\n" -  COMMA_DLOC_ARGS_OPT)); +  THREADS_FPRINTF (1, +  "Continue after threads_disabled" DLOC_PF(" @ ",) "\n", +  DLOC_ARGS_OPT);   }      PMOD_EXPORT void pike_lock_interpreter (DLOC_DECL)   {    pike_low_lock_interpreter (DLOC_ARGS_OPT);    if (threads_disabled) threads_disabled_wait (DLOC_ARGS_OPT);   }      PMOD_EXPORT void pike_unlock_interpreter (DLOC_DECL)   {    USE_DLOC_ARGS(); -  THREADS_FPRINTF (1, (stderr, "Releasing iplock" DLOC_PF(" @ ",) "\n" -  COMMA_DLOC_ARGS_OPT)); +  THREADS_FPRINTF (1, "Releasing iplock" DLOC_PF(" @ ",) "\n", +  DLOC_ARGS_OPT);    UNSET_LOCKING_THREAD;    mt_unlock (&interpreter_lock);   }      PMOD_EXPORT void pike_wait_interpreter (COND_T *cond COMMA_DLOC_DECL)   {    int owner = threads_disabled;    pike_low_wait_interpreter (cond COMMA_DLOC_ARGS_OPT);    if (!owner && threads_disabled) threads_disabled_wait (DLOC_ARGS_OPT);   }
pike.git/src/threads.c:589: Inside #if defined(USE_CLOCK_FOR_SLICES) and #if defined(PROFILE_CHECK_THREADS)
   fprintf (stderr, "[%d:%f] pike_init_thread_state: tsc reset\n",    getpid(), get_real_time() * (1.0 / CPU_TIME_TICKS));   #endif   #endif   }      PMOD_EXPORT void pike_swap_out_thread (struct thread_state *ts    COMMA_DLOC_DECL)   {    USE_DLOC_ARGS(); -  THREADS_FPRINTF (2, (stderr, "Swap out %sthread %p" DLOC_PF(" @ ",) "\n", +  THREADS_FPRINTF (2, "Swap out %sthread %p" DLOC_PF(" @ ",) "\n",    ts == Pike_interpreter.thread_state ? "current " : "", -  ts -  COMMA_DLOC_ARGS_OPT)); +  ts, DLOC_ARGS_OPT);      #ifdef PROFILING    if (!ts->swapped) {    cpu_time_t now = get_cpu_time();   #ifdef PROFILING_DEBUG    fprintf(stderr, "%p: Swap out at: %" PRINT_CPU_TIME    " unlocked: %" PRINT_CPU_TIME "\n",    ts, now, ts->state.unlocked_time);   #endif    ts->state.unlocked_time -= now;
pike.git/src/threads.c:614:   #endif       ts->swapped=1;       Pike_interpreter_pointer = NULL;   }      PMOD_EXPORT void pike_swap_in_thread (struct thread_state *ts    COMMA_DLOC_DECL)   { -  THREADS_FPRINTF (2, (stderr, "Swap in thread %p" DLOC_PF(" @ ",) "\n", -  ts COMMA_DLOC_ARGS_OPT)); +  THREADS_FPRINTF (2, "Swap in thread %p" DLOC_PF(" @ ",) "\n", +  ts, DLOC_ARGS_OPT);      #ifdef PIKE_DEBUG    if (Pike_interpreter_pointer)    pike_fatal_dloc ("Thread %"PRINTSIZET"x swapped in "    "over existing thread %"PRINTSIZET"x.\n",    (size_t) ts->id,    (size_t) (Pike_interpreter.thread_state ?    Pike_interpreter.thread_state->id : 0));   #endif   
pike.git/src/threads.c:846: Inside #if defined(PIKE_DEBUG)
   Pike_in_gc);    if (pike_global_buffer.s.str)    pike_fatal_dloc ("Threads allowed while the global dynamic buffer "    "is in use.\n");    ts->debug_flags |= THREAD_DEBUG_LOOSE;   #endif       if (num_threads > 1 && !threads_disabled) {    pike_swap_out_thread (ts COMMA_DLOC_ARGS_OPT);    live_threads++; -  THREADS_FPRINTF (1, (stderr, "Increased live threads to %d\n", -  live_threads)); +  THREADS_FPRINTF (1, "Increased live threads to %d\n", live_threads);    pike_unlock_interpreter (DLOC_ARGS_OPT);    }      #if defined (PIKE_DEBUG) && !(defined(__ia64) && defined(__xlc__))    else {    /* Disabled in xlc 5.5.0.0/ia64 due to a code generation bug. */    THREAD_T self = th_self();    if (threads_disabled && !th_equal(threads_disabled_thread, self))    pike_fatal_dloc ("Threads allowed from a different thread "    "while threads are disabled. "
pike.git/src/threads.c:874:   PMOD_EXPORT void pike_threads_disallow_ext (struct thread_state *ts    COMMA_DLOC_DECL)   {   #ifdef DO_PIKE_CLEANUP    if (!ts) return;   #endif       if (ts->swapped) {    pike_low_lock_interpreter (DLOC_ARGS_OPT);    live_threads--; -  THREADS_FPRINTF (1, (stderr, "Decreased live threads to %d\n", -  live_threads)); +  THREADS_FPRINTF (1, "Decreased live threads to %d\n", live_threads);    co_broadcast (&live_threads_change);    if (threads_disabled) threads_disabled_wait (DLOC_ARGS_OPT);    pike_swap_in_thread (ts COMMA_DLOC_ARGS_OPT);    }       if (UNLIKELY(thread_quanta)) {    ts->interval_start = get_real_time();    }      #ifdef PIKE_DEBUG
pike.git/src/threads.c:898:   #endif   }      PMOD_EXPORT void pike_lock_imutex (IMUTEX_T *im COMMA_DLOC_DECL)   {    struct thread_state *ts = Pike_interpreter.thread_state;       /* If threads are disabled, we already hold the lock. */    if (threads_disabled) return;    -  THREADS_FPRINTF(0, (stderr, "Locking IMutex %p...\n", im)); +  THREADS_FPRINTF(0, "Locking IMutex %p...\n", im);    pike_threads_allow (ts COMMA_DLOC_ARGS_OPT);    mt_lock(&((im)->lock));    pike_threads_disallow (ts COMMA_DLOC_ARGS_OPT); -  THREADS_FPRINTF(1, (stderr, "Locked IMutex %p\n", im)); +  THREADS_FPRINTF(1, "Locked IMutex %p\n", im);   }      PMOD_EXPORT void pike_unlock_imutex (IMUTEX_T *im COMMA_DLOC_DECL)   {    /* If threads are disabled, we already hold the lock. */    if (threads_disabled) return;       USE_DLOC_ARGS(); -  THREADS_FPRINTF(0, (stderr, "Unlocking IMutex %p" DLOC_PF(" @ ",) "\n", -  im COMMA_DLOC_ARGS_OPT)); +  THREADS_FPRINTF(0, "Unlocking IMutex %p" DLOC_PF(" @ ",) "\n", +  im, DLOC_ARGS_OPT);    mt_unlock(&(im->lock));   }      /* This is a variant of init_threads_disable that blocks all other    * threads that might run pike code, but still doesn't block the    * THREADS_ALLOW_UID threads. */   void low_init_threads_disable(void)   {    /* Serious black magic to avoid dead-locks */       if (!threads_disabled) { -  THREADS_FPRINTF(0, -  (stderr, "low_init_threads_disable(): Locking IM's...\n")); +  THREADS_FPRINTF(0, "low_init_threads_disable(): Locking IM's...\n");       if (Pike_interpreter.thread_state) {    /* Threads have been enabled. */       IMUTEX_T *im;       THREADS_ALLOW();       /* Keep this the entire session. */    mt_lock(&interleave_lock);
pike.git/src/threads.c:963:       im = (IMUTEX_T *)interleave_list;       while(im) {    mt_lock(&(im->lock));       im = im->next;    }    }    -  THREADS_FPRINTF(0, (stderr, -  "low_init_threads_disable(): Disabling threads.\n")); +  THREADS_FPRINTF(0, "low_init_threads_disable(): Disabling threads.\n");       threads_disabled = 1;    threads_disabled_start = get_real_time();   #ifdef PIKE_DEBUG    threads_disabled_thread = th_self();   #endif    } else {    threads_disabled++;    }       THREADS_FPRINTF(0, -  (stderr, "low_init_threads_disable(): threads_disabled:%d\n", -  threads_disabled)); +  "low_init_threads_disable(): threads_disabled:%d\n", +  threads_disabled);   }      /*! @decl object(_disable_threads) _disable_threads()    *!    *! This function first posts a notice to all threads that it is time    *! to stop. It then waits until all threads actually *have* stopped,    *! and then then returns a lock object. All other threads will be    *! blocked from running until that object has been freed/destroyed.    *!    *! It's mainly useful to do things that require a temporary uid/gid
pike.git/src/threads.c:1011:    *! @[gethrdtime()]    */   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)); +  live_threads);    low_co_wait_interpreter (&live_threads_change);    } -  THREADS_FPRINTF(0, (stderr, "_disable_threads(): threads now disabled\n")); +  THREADS_FPRINTF(0, "_disable_threads(): threads now disabled\n");    SWAP_IN_CURRENT_THREAD();    }   }      void exit_threads_disable(struct object *UNUSED(o))   { -  THREADS_FPRINTF(0, (stderr, "exit_threads_disable(): threads_disabled:%d\n", -  threads_disabled)); +  THREADS_FPRINTF(0, "exit_threads_disable(): threads_disabled:%d\n", +  threads_disabled);    if(threads_disabled) {    if(!--threads_disabled) {    IMUTEX_T *im = (IMUTEX_T *)interleave_list;    threads_disabled_acc_time += get_real_time() - threads_disabled_start;       /* Order shouldn't matter for unlock, so no need to do it backwards. */    while(im) { -  THREADS_FPRINTF(0, (stderr, -  "exit_threads_disable(): Unlocking IM %p\n", im)); +  THREADS_FPRINTF(0, "exit_threads_disable(): Unlocking IM %p\n", im);    mt_unlock(&(im->lock));    im = im->next;    }       mt_unlock(&interleave_lock);    -  THREADS_FPRINTF(0, (stderr, "exit_threads_disable(): Wake up!\n")); +  THREADS_FPRINTF(0, "exit_threads_disable(): Wake up!\n");    co_broadcast(&threads_disabled_change);   #ifdef PIKE_DEBUG    threads_disabled_thread = 0;   #endif    }   #ifdef PIKE_DEBUG    } else {    Pike_fatal("exit_threads_disable() called too many times!\n");   #endif /* PIKE_DEBUG */    }   }      void init_interleave_mutex(IMUTEX_T *im)   {    mt_init(&(im->lock));    -  THREADS_FPRINTF(0, (stderr, -  "init_interleave_mutex(): init_threads_disable()\n")); +  THREADS_FPRINTF(0, "init_interleave_mutex(): init_threads_disable()\n");       init_threads_disable(NULL);    -  THREADS_FPRINTF(0, (stderr, "init_interleave_mutex(): Locking IM %p\n", im)); +  THREADS_FPRINTF(0, "init_interleave_mutex(): Locking IM %p\n", im);       /* Lock it so that it can be unlocked by exit_threads_disable() */    mt_lock(&(im->lock));       im->next = (IMUTEX_T *)interleave_list;    if (interleave_list) {    interleave_list->prev = im;    }    interleave_list = im;    im->prev = NULL;    -  THREADS_FPRINTF(0, (stderr, -  "init_interleave_mutex(): exit_threads_disable()\n")); +  THREADS_FPRINTF(0, "init_interleave_mutex(): exit_threads_disable()\n");       exit_threads_disable(NULL);   }      void exit_interleave_mutex(IMUTEX_T *im)   {    init_threads_disable(NULL);       if (im->prev) {    im->prev->next = im->next;
pike.git/src/threads.c:1775:   };      /* Thread func starting new Pike-level threads. */   TH_RETURN_TYPE new_thread_func(void *data)   {    struct thread_starter arg = *(struct thread_starter *)data;    struct object *thread_obj;    struct thread_state *thread_state;    JMP_BUF back;    -  THREADS_FPRINTF(0, (stderr,"new_thread_func(): Thread %p created...\n", -  arg.thread_state)); +  THREADS_FPRINTF(0, "new_thread_func(): Thread %p created...\n", +  arg.thread_state);      #ifdef HAVE_BROKEN_LINUX_THREAD_EUID    /* Work-around for Linux's pthreads not propagating the    * effective uid & gid.    */    if (!geteuid()) {   #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)    /* The sete?id calls will clear the dumpable state that we might    * have set with system.dumpable. */    int current = prctl(PR_GET_DUMPABLE);
pike.git/src/threads.c:1850:    /* After signalling the status change to the spawning thread we may    * now wait if threads are disabled. */    if (threads_disabled) {    SWAP_OUT_CURRENT_THREAD();    threads_disabled_wait (DLOC);    SWAP_IN_CURRENT_THREAD();    }       DEBUG_CHECK_THREAD();    -  THREADS_FPRINTF(0, (stderr,"new_thread_func(): Thread %p inited\n", -  arg.thread_state)); +  THREADS_FPRINTF(0, "new_thread_func(): Thread %p inited\n", +  arg.thread_state);       if(SETJMP(back))    {    if(throw_severity <= THROW_ERROR) {    if (thread_state->thread_obj) {    /* Copy the thrown exit value to the thread_state here,    * if the thread hasn't been destructed. */    assign_svalue(&thread_state->result, &throw_value);    }   
pike.git/src/threads.c:1902:       DEBUG_CHECK_THREAD();       if(thread_state->thread_locals != NULL) {    free_mapping(thread_state->thread_locals);    thread_state->thread_locals = NULL;    }       co_broadcast(&thread_state->status_change);    -  THREADS_FPRINTF(0, (stderr,"new_thread_func(): Thread %p done\n", -  arg.thread_state)); +  THREADS_FPRINTF(0, "new_thread_func(): Thread %p done\n", arg.thread_state);       /* This thread is now officially dead. */       while(Pike_fp)    POP_PIKE_FRAME();       reset_evaluator();       low_cleanup_interpret(&thread_state->state);   
pike.git/src/threads.c:2038:    /* Wait for the thread to start properly.    * so that we can avoid races.    *    * The main race is the one on current_object,    * since it at this point only has one reference.    *    * We also want the stuff in arg to be copied properly    * before we exit the function...    */    SWAP_OUT_CURRENT_THREAD(); -  THREADS_FPRINTF(0, (stderr, "f_thread_create %p waiting...\n", -  thread_state)); +  THREADS_FPRINTF(0, "f_thread_create %p waiting...\n", thread_state);    while (thread_state->status == THREAD_NOT_STARTED)    low_co_wait_interpreter (&thread_state->status_change); -  THREADS_FPRINTF(0, (stderr, "f_thread_create %p continue\n", thread_state)); +  THREADS_FPRINTF(0, "f_thread_create %p continue\n", thread_state);    SWAP_IN_CURRENT_THREAD();    } else {    low_cleanup_interpret(&thread_state->state);    free_array(arg.args);    Pike_error("Failed to create thread (errno = %d).\n", tmp);    }    -  THREADS_FPRINTF(0, (stderr, "f_thread_create %p done\n", thread_state)); +  THREADS_FPRINTF(0, "f_thread_create %p done\n", thread_state);   }      /*! @endclass    */      #ifdef UNIX_THREADS   /*! @decl void thread_set_concurrency(int concurrency)    *!    *! @fixme    *! Document this function
pike.git/src/threads.c:2275:    default:    bad_arg_error("lock", Pike_sp-args, args, 2, "int(0..2)", Pike_sp+1-args,    "Unknown mutex locking style: %"PRINTPIKEINT"d\n",type);          case 0:    case 2:    if(m->key && OB2KEY(m->key)->owner == Pike_interpreter.thread_state)    {    THREADS_FPRINTF(0, -  (stderr, "Recursive LOCK k:%p, m:%p(%p), t:%p\n", +  "Recursive LOCK k:%p, m:%p(%p), t:%p\n",    OB2KEY(m->key), m, OB2KEY(m->key)->mut, -  Pike_interpreter.thread_state)); +  Pike_interpreter.thread_state);       if(type==0) Pike_error("Recursive mutex locks!\n");       pop_n_elems(args);    push_int(0);    return;    }    case 1:    break;    }
pike.git/src/threads.c:2306:    if(m->key)    {    m->num_waiting++;    if(threads_disabled)    {    free_object(o);    Pike_error("Cannot wait for mutexes when threads are disabled!\n");    }    do    { -  THREADS_FPRINTF(1, (stderr,"WAITING TO LOCK m:%p\n",m)); +  THREADS_FPRINTF(1, "WAITING TO LOCK m:%p\n", m);    SWAP_OUT_CURRENT_THREAD();    co_wait_interpreter(& m->condition);    SWAP_IN_CURRENT_THREAD();    check_threads_etc();    }while(m->key);    m->num_waiting--;    }      #ifdef PICKY_MUTEX    if (!Pike_fp->current_object->prog) {
pike.git/src/threads.c:2330: Inside #if defined(PICKY_MUTEX)
   Pike_error ("Mutex was destructed while waiting for lock.\n");    }   #endif       m->key=o;    OB2KEY(o)->mut=m;    add_ref (OB2KEY(o)->mutex_obj = Pike_fp->current_object);       DEBUG_CHECK_THREAD();    -  THREADS_FPRINTF(1, (stderr, "LOCK k:%p, m:%p(%p), t:%p\n", +  THREADS_FPRINTF(1, "LOCK k:%p, m:%p(%p), t:%p\n",    OB2KEY(o), m, OB2KEY(m->key)->mut, -  Pike_interpreter.thread_state)); +  Pike_interpreter.thread_state);    pop_n_elems(args);    push_object(o);   }      /*! @decl MutexKey trylock()    *! @decl MutexKey trylock(int type)    *!    *! This function performs the same operation as @[lock()], but if the mutex    *! is already locked, it will return zero instead of sleeping until it's    *! unlocked.
pike.git/src/threads.c:2455:    co_init(& THIS_MUTEX->condition);    THIS_MUTEX->key=0;    THIS_MUTEX->num_waiting = 0;   }      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)); +  THREADS_FPRINTF(1, "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")); +  THREADS_FPRINTF(1, "Destructed mutex is in use - delaying cleanup\n");    }    else {   #ifdef PIKE_DEBUG    if (m->num_waiting)    Pike_error ("key/num_waiting confusion.\n");   #endif    co_destroy(& m->condition);    }   #else    if(key) {    m->key=0;    destruct(key); /* Will destroy m->condition if m->num_waiting is zero. */    if(m->num_waiting)    { -  THREADS_FPRINTF(1, (stderr, "Destructed mutex is being waited on.\n")); +  THREADS_FPRINTF(1, "Destructed mutex is being waited on.\n");    /* exit_mutex_key_obj has already signalled, but since the    * waiting threads will throw an error instead of making a new    * 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 *UNUSED(o))   {    struct mutex_storage *m = THIS_MUTEX;    struct object *key = m->key;    -  THREADS_FPRINTF(1, (stderr, "DESTROYING MUTEX m:%p\n", THIS_MUTEX)); +  THREADS_FPRINTF(1, "DESTROYING MUTEX m:%p\n", THIS_MUTEX);       if(key) {    m->key=0;    destruct(key); /* Will destroy m->condition if m->num_waiting is zero. */    }    else {   #ifdef PIKE_DEBUG    if (m->num_waiting)    Pike_error ("key/num_waiting confusion.\n");   #endif
pike.git/src/threads.c:2528:    *!    *! 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 *UNUSED(o))   { -  THREADS_FPRINTF(1, (stderr, "KEY k:%p, t:%p\n", -  THIS_KEY, Pike_interpreter.thread_state)); +  THREADS_FPRINTF(1, "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;    THIS_KEY->owner_obj = Pike_interpreter.thread_state->thread_obj;    if (THIS_KEY->owner_obj)    add_ref(THIS_KEY->owner_obj);    THIS_KEY->initialized=1;   }      void exit_mutex_key_obj(struct object *DEBUGUSED(o))   { -  THREADS_FPRINTF(1, (stderr, "UNLOCK k:%p m:(%p) t:%p o:%p\n", +  THREADS_FPRINTF(1, "UNLOCK k:%p m:(%p) t:%p o:%p\n",    THIS_KEY, THIS_KEY->mut, -  Pike_interpreter.thread_state, THIS_KEY->owner)); +  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    /* Note: mut->key can be NULL if our corresponding mutex    * has been destructed.    */    if(mut->key && (mut->key != o))
pike.git/src/threads.c:2890:   {    struct thread_state *th=THIS_THREAD;    int th_status;       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 " -  "(state:%d).\n", th, th->status)); +  THREADS_FPRINTF(0, "Thread->wait(): Waiting for thread_state %p " +  "(state:%d).\n", th, th->status);    while(th->status < THREAD_EXITED) {    SWAP_OUT_CURRENT_THREAD();    co_wait_interpreter(&th->status_change);    SWAP_IN_CURRENT_THREAD();    check_threads_etc();    THREADS_FPRINTF(0, -  (stderr, "Thread->wait(): Waiting for thread_state %p " -  "(state:%d).\n", th, th->status)); +  "Thread->wait(): Waiting for thread_state %p " +  "(state:%d).\n", th, th->status);    }       th_status = th->status;       assign_svalue_no_free(Pike_sp, &th->result);    Pike_sp++;    dmalloc_touch_svalue(Pike_sp-1);       th->waiting--;   
pike.git/src/threads.c:3336:    mt_unlock( &rosie );    new_farmer( fun, here );   }      /*    * Glue code.    */      void low_th_init(void)   { -  THREADS_FPRINTF(0, (stderr, "Initializing threads.\n")); +  THREADS_FPRINTF(0, "Initializing threads.\n");       really_low_th_init();       mt_init( & interpreter_lock);    mt_init( & interpreter_lock_wanted);    low_mt_lock_interpreter();    mt_init( & thread_table_lock);    mt_init( & interleave_lock);    mt_init( & rosie);    co_init( & live_threads_change);