pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:407:    if (th_running) {    THREAD_T self;    if (!debug_is_locked)    pike_fatal_dloc ("Interpreter not locked.\n");    self = th_self();    if (!th_equal (debug_locking_thread, self))    pike_fatal_dloc ("Interpreter not locked by this thread.\n");    }   }    + static unsigned LONGEST thread_swaps = 0; + static unsigned LONGEST check_threads_calls = 0; + static unsigned LONGEST check_threads_yields = 0; + static unsigned LONGEST check_threads_swaps = 0; + static void f__thread_swaps (INT32 args) +  {push_ulongest (thread_swaps);} + static void f__check_threads_calls (INT32 args) +  {push_ulongest (check_threads_calls);} + static void f__check_threads_yields (INT32 args) +  {push_ulongest (check_threads_yields);} + static void f__check_threads_swaps (INT32 args) +  {push_ulongest (check_threads_swaps);} +    #else      #define SET_LOCKING_THREAD 0   #define UNSET_LOCKING_THREAD 0   static INLINE void check_interpreter_lock (DLOC_DECL) {}      #endif      PMOD_EXPORT INLINE void pike_low_lock_interpreter (DLOC_DECL)   {
pike.git/src/threads.c:525:      PMOD_EXPORT void pike_init_thread_state (struct thread_state *ts)   {    Pike_interpreter.thread_state = ts;    ts->state = Pike_interpreter;    ts->id = th_self();    ts->status = THREAD_RUNNING;    ts->swapped = 0;   #ifdef PIKE_DEBUG    ts->debug_flags = 0; +  thread_swaps++;   #endif   #ifdef USE_CLOCK_FOR_SLICES    /* Initialize thread_start_clock to zero instead of clock() since we    * don't know for how long the thread already has run. */    thread_start_clock = 0;    last_clocked_thread = ts->id;   #ifdef RDTSC    prev_tsc = 0;   #endif   #endif
pike.git/src/threads.c:607: Inside #if defined(PROFILING) and #if defined(PIKE_DEBUG)
   " %" PRINT_CPU_TIME " < %" PRINT_CPU_TIME    "\n", now, -Pike_interpreter.unlocked_time);    }   #endif    ts->state.unlocked_time += now;    }   #endif       ts->swapped=0;    Pike_interpreter=ts->state; + #ifdef PIKE_DEBUG +  thread_swaps++; + #endif      #ifdef USE_CLOCK_FOR_SLICES    if (last_clocked_thread != ts->id) {    thread_start_clock = clock();    last_clocked_thread = ts->id;   #ifdef RDTSC    RDTSC (prev_tsc);    prev_clock = thread_start_clock;   #endif    }
pike.git/src/threads.c:1279: Inside #if defined(PROFILE_CHECK_THREADS)
   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. */    static double tsc_tgt_mean = 0.0, tsc_tgt_m2 = 0.0;    static unsigned long tps = 0, tps_int_n = 0; /* TSC intervals per slice. */    static double tps_int_mean = 0.0, tps_int_m2 = 0.0;    calls++;   #endif + #ifdef PIKE_DEBUG +  check_threads_calls++; + #endif      #if defined (USE_CLOCK_FOR_SLICES) && defined (PIKE_DEBUG)    if (last_clocked_thread != th_self())    Pike_fatal ("Stale thread %08lx in last_clocked_thread (self is %08lx)\n",    (unsigned long) last_clocked_thread, (unsigned long) th_self());   #endif      #if defined(RDTSC) && defined(USE_CLOCK_FOR_SLICES)    /* We can get here as often as 30+ thousand times per second;    let's try to avoid doing as many clock(3)/times(2) syscalls
pike.git/src/threads.c:1510:    else if (clock_now - thread_start_clock < (clock_t) (CLOCKS_PER_SEC / 20))    return;    }   #else    static int div_;    if(div_++ & 255)    return;   #endif       do_yield:; + #ifdef PIKE_DEBUG +  check_threads_yields++; + #endif      #ifdef PROFILE_CHECK_THREADS    {    static long last_time;    struct timeval now;      #ifdef USE_CLOCK_FOR_SLICES    if (thread_start_clock) {    double slice_time =    (double) (clock() - thread_start_clock) / CLOCKS_PER_SEC;
pike.git/src/threads.c:1546: Inside #if defined(PROFILE_CHECK_THREADS)
   tsc_tgt_mean,    tsc_tgt_n > 1 ? sqrt (tsc_tgt_m2 / (tsc_tgt_n - 1)) : 0.0,    tps_int_mean,    tps_int_n > 1 ? sqrt (tps_int_m2 / (tps_int_n - 1)) : 0.0);    last_time = (unsigned long) now.tv_sec;    calls = clock_checks = no_clock_advs = 0;    }    }   #endif    +  { + #ifdef PIKE_DEBUG +  unsigned LONGEST old_thread_swaps = thread_swaps; + #endif    pike_thread_yield(); -  + #ifdef PIKE_DEBUG +  if (thread_swaps != old_thread_swaps) +  check_threads_swaps++; + #endif    } -  + }      PMOD_EXPORT void pike_thread_yield(void)   {    DEBUG_CHECK_THREAD();       THREADS_ALLOW();    /* Allow other threads to run */    /* FIXME: Ought to use condition vars or something to get another    * thread to run. yield functions are notoriously unreliable and    * poorly defined. It might not really yield we need it to. It might
pike.git/src/threads.c:3117:      void th_init(void)   {    ptrdiff_t mutex_key_offset;      #ifdef UNIX_THREADS       ADD_EFUN("thread_set_concurrency",f_thread_set_concurrency,tFunc(tInt,tVoid), OPT_SIDE_EFFECT);   #endif    + #ifdef PIKE_DEBUG +  ADD_EFUN("_thread_swaps", f__thread_swaps, +  tFunc(tVoid,tInt), OPT_SIDE_EFFECT); +  ADD_EFUN("_check_threads_calls", f__check_threads_calls, +  tFunc(tVoid,tInt), OPT_SIDE_EFFECT); +  ADD_EFUN("_check_threads_yields", f__check_threads_yields, +  tFunc(tVoid,tInt), OPT_SIDE_EFFECT); +  ADD_EFUN("_check_threads_swaps", f__check_threads_swaps, +  tFunc(tVoid,tInt), OPT_SIDE_EFFECT); + #endif +     START_NEW_PROGRAM_ID(THREAD_MUTEX_KEY);    mutex_key_offset = ADD_STORAGE(struct key_storage);    /* This is needed to allow the gc to find the possible circular reference.    * It also allows a thread to take over ownership of a key.    */    PIKE_MAP_VARIABLE("_owner",    mutex_key_offset + OFFSETOF(key_storage, owner_obj),    tObjIs_THREAD_ID, T_OBJECT, 0);    PIKE_MAP_VARIABLE("_mutex", mutex_key_offset + OFFSETOF(key_storage, mutex_obj),    tObjIs_THREAD_MUTEX, T_OBJECT, ID_PROTECTED|ID_PRIVATE);