pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:9:      /* #define PICKY_MUTEX */      #ifdef _REENTRANT      #include "pike_error.h"      /* Define to get a debug trace of thread operations. Debug levels can be 0-2. */   /* #define VERBOSE_THREADS_DEBUG 1 */    + /* #define PROFILE_CHECK_THREADS */ +    #ifndef CONFIGURE_TEST      #include "threads.h"   #include "array.h"   #include "mapping.h"   #include "object.h"   #include "pike_macros.h"   #include "callback.h"   #include "builtin_functions.h"   #include "constants.h"
pike.git/src/threads.c:548:    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 + #ifdef 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)   {    THREADS_FPRINTF (2, (stderr, "Swap out %sthread %p" DLOC_PF(" @ ",) "\n",    ts == Pike_interpreter.thread_state ? "current " : "",    ts    COMMA_DLOC_ARGS_OPT));   
pike.git/src/threads.c:1280: Inside #if defined(PIKE_DEBUG)
   }    fprintf(stderr,"-----------------------\n");   }   #endif      PMOD_EXPORT int count_pike_threads(void)   {    return num_pike_threads;   }    - /* #define PROFILE_CHECK_THREADS */ -  +    static void check_threads(struct callback *cb, void *arg, void * arg2)   {   #ifdef PROFILE_CHECK_THREADS -  static unsigned long calls = 0, clock_checks = 0, no_clock_advs = 0; +  static unsigned long calls = 0, yields = 0; +  static unsigned long clock_checks = 0, no_clock_advs = 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. */    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
pike.git/src/threads.c:1330: Inside #if defined(RDTSC) && defined(USE_CLOCK_FOR_SLICES)
   RDTSC(tsc_now);    tsc_elapsed = tsc_now - prev_tsc;       if (tsc_elapsed < target_int) {    if (tsc_elapsed < 0) {    /* The counter jumped back in time, so reset and continue. In    * the worst case this keeps happening all the time, and then    * the only effect is that we always fall back to    * clock(3). */   #ifdef PROFILE_CHECK_THREADS -  fprintf (stderr, "TSC backward jump detected (now: %"PRINTINT64"d, " -  "prev: %"PRINTINT64"d, target_int: %"PRINTINT64"d) - " -  "resetting\n", tsc_now, prev_tsc, target_int); +  fprintf (stderr, "[%d:%f] TSC backward jump detected " +  "(now: %"PRINTINT64"d, prev: %"PRINTINT64"d, " +  "target_int: %"PRINTINT64"d) - resetting\n", +  getpid(), get_real_time() * (1.0 / CPU_TIME_TICKS), +  tsc_now, prev_tsc, target_int);   #endif    target_int = TSC_START_INTERVAL;    prev_tsc = 0;    }    else    return;    }      #ifdef PROFILE_CHECK_THREADS    if (prev_tsc) {
pike.git/src/threads.c:1393: Inside #if defined(RDTSC) && defined(USE_CLOCK_FOR_SLICES)
   * effect that the actual tsc intervals will be closer to    * 1/200 sec. */    INT64 new_target_int =    (tsc_elapsed * (CLOCKS_PER_SEC / 400)) / tsc_interval_time;    if (new_target_int < target_int << 1)    target_int = new_target_int;    else {    /* The most likely cause for this is high variance in the    * interval lengths due to low clock(3) resolution. */   #ifdef PROFILE_CHECK_THREADS -  fprintf (stderr, "TSC suspect forward jump detected " -  "(prev int: %"PRINTINT64"d, " -  "calculated int: %"PRINTINT64"d) - " -  "capping\n", target_int, new_target_int); +  fprintf (stderr, "[%d:%f] Capping large TSC interval increase " +  "(from %"PRINTINT64"d to %"PRINTINT64"d)\n", +  getpid(), get_real_time() * (1.0 / CPU_TIME_TICKS), +  target_int, new_target_int);   #endif    /* The + 1 is paranoia just in case it has become zero somehow. */    target_int = (target_int << 1) + 1;    }    prev_tsc = tsc_now;    prev_clock = clock_now;   #ifdef PROFILE_CHECK_THREADS    {    double delta = target_int - tsc_tgt_mean;    tsc_tgt_n++;
pike.git/src/threads.c:1433: Inside #if defined(RDTSC) && defined(USE_CLOCK_FOR_SLICES)
   prev_clock = clock_now;    }    target_int += tsc_elapsed;   #ifdef PROFILE_CHECK_THREADS    no_clock_advs++;   #endif    }    }    else {   #ifdef PROFILE_CHECK_THREADS -  fprintf (stderr, "Warning: Encountered zero prev_tsc.\n"); +  fprintf (stderr, "[%d:%f] Warning: Encountered zero prev_tsc " +  "(thread_start_clock: %"PRINTINT64"d, " +  "clock_now: %"PRINTINT64"d)\n", +  getpid(), get_real_time() * (1.0 / CPU_TIME_TICKS), +  (INT64) thread_start_clock, (INT64) clock_now);   #endif    prev_tsc = tsc_now;    }       if (clock_now - thread_start_clock < 0)    /* clock counter has wrapped since the start of the time    * slice. Let's reset and yield. */    thread_start_clock = 0;    else if (clock_now - thread_start_clock <    (clock_t) (CLOCKS_PER_SEC / 20))
pike.git/src/threads.c:1552: Inside #if defined(PIKE_DEBUG)
   do_yield:;   #ifdef PIKE_DEBUG    check_threads_yields++;   #endif      #ifdef PROFILE_CHECK_THREADS    {    static long last_time;    struct timeval now;    +  yields++; +    #ifdef USE_CLOCK_FOR_SLICES    if (thread_start_clock) {    double slice_time =    (double) (clock() - thread_start_clock) / CLOCKS_PER_SEC;    double delta = slice_time - slice_int_mean;    slice_int_n++;    slice_int_mean += delta / slice_int_n;    slice_int_m2 += delta * (slice_time - slice_int_mean);    }   #endif       GETTIMEOFDAY (&now);    if (now.tv_sec > last_time) { -  fprintf (stderr, "check_threads: %lu calls, %lu clocks, %lu no advs, " -  "slice %.3f:%.1e, tsc int %.2e:%.1e, tsc tgt %.2e:%.1e, tps %g:%.1e\n", -  calls, clock_checks, no_clock_advs, +  fprintf (stderr, "[%d:%f] check_threads: %lu calls, " +  "%lu clocks, %lu no advs, %lu yields" +  ", slice %.3f:%.1e, tsc int %.2e:%.1e, tsc tgt %.2e:%.1e" +  ", tps %g:%.1e\n", +  getpid(), get_real_time() * (1.0 / CPU_TIME_TICKS), +  calls, clock_checks, no_clock_advs, yields,    slice_int_mean,    slice_int_n > 1 ? sqrt (slice_int_m2 / (slice_int_n - 1)) : 0.0,    tsc_int_mean,    tsc_int_n > 1 ? sqrt (tsc_int_m2 / (tsc_int_n - 1)) : 0.0,    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; +  calls = yields = clock_checks = no_clock_advs = 0;    }    }   #endif       {   #ifdef PIKE_DEBUG    unsigned LONGEST old_thread_swaps = thread_swaps;   #endif    pike_thread_yield();   #ifdef PIKE_DEBUG