pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:30:   #include "program_id.h"   #include "gc.h"   #include "main.h"   #include "module_support.h"   #include "pike_types.h"   #include "operators.h"   #include "bignum.h"   #include "signal_handler.h"   #include "backend.h"   #include "pike_rusage.h" + #include "pike_cpulib.h"      #include <errno.h>      #ifdef HAVE_SYS_PRCTL_H   #include <sys/prctl.h>   #endif /* HAVE_SYS_PRCTL_H */      #ifdef HAVE_SYS_TIME_H   #include <sys/time.h>   #endif
pike.git/src/threads.c:1240:   }   #endif      PMOD_EXPORT int count_pike_threads(void)   {    return num_pike_threads;   }      /* #define PROFILE_CHECK_THREADS */    + #if defined(HAVE_RDTSC) && defined(USE_CLOCK_FOR_SLICES) + static int use_tsc_for_slices; + #endif +    static void check_threads(struct callback *cb, void *arg, void * arg2)   {   #ifdef PROFILE_CHECK_THREADS    static unsigned long calls = 0;    calls++;   #endif      #ifndef HAVE_NO_YIELD    /* If we have no yield we can't cut calls here since it's possible    * that a thread switch will take place only occasionally in the
pike.git/src/threads.c:1271: Inside #if undefined(HAVE_NO_YIELD) and #if defined(HAVE_RDTSC) && defined(USE_CLOCK_FOR_SLICES)
   by using the TSC. We'll skip any further checks until the    number of cycles passed comes close to what it was the last    time when we decided to yield. */      #define GETCYCLES(v) do { \    unsigned __l, __h; \    __asm__ __volatile__ ("rdtsc" : "=a" (__l), "=d" (__h)); \    (v)= __l | (((INT64)__h)<<32); \   } while (0)    - #define CPUID2(c, a, d) do { \ -  unsigned __c, __b; \ -  __asm__ __volatile__ ("cpuid" : "=a" ((a)), "=d" ((d)), \ -  "=b" (__b), "=c" (__c) \ -  : "0" ((c))); \ - } while (0) -  +     {    static INT64 target, mincycles=1000*1000; -  static int use_tsc; +     INT64 now;    clock_t elapsed;    -  +  if (use_tsc_for_slices) {    if (!target) { -  int a, d; -  -  CPUID2(1, a, d); -  use_tsc = d&0x10; -  target = 1; -  -  if (use_tsc) +     GETCYCLES(target);    }    -  if (use_tsc) { +     GETCYCLES(now);       if ((target-now)>0) {    if ((target-now)>mincycles) -  use_tsc = 0; /* The counter jumped back too far; TSC unusable */ +  use_tsc_for_slices = 0; /* The counter jumped back too far; TSC unusable */    else    return;    }    }       elapsed = clock() - thread_start_clock;       if (elapsed < (clock_t) (CLOCKS_PER_SEC/30)) {    mincycles |= 0xffff;    if ((now-target)<=(mincycles<<4))
pike.git/src/threads.c:2950:    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);    co_init( & threads_disabled_change);    thread_table_init();    + #if defined(HAVE_RDTSC) && defined(USE_CLOCK_FOR_SLICES) +  { +  INT32 cpuid[4]; +  x86_get_cpuid (1, cpuid); +  /* fprintf (stderr, "cpuid 1: %x\n", cpuid[2]); */ +  use_tsc_for_slices = cpuid[2] & 0x10; /* TSC exists */ +  if (use_tsc_for_slices) { +  x86_get_cpuid (0x80000007, cpuid); +  /* fprintf (stderr, "cpuid 0x80000007: %x\n", cpuid[2]); */ +  use_tsc_for_slices = cpuid[2] & 0x100; /* TSC is invariant */ +  } +  /* fprintf (stderr, "use tsc: %d\n", use_tsc_for_slices); */ +  } + #endif +     th_running = 1;   }      static struct object *backend_thread_obj = NULL;      void th_init(void)   {    ptrdiff_t mutex_key_offset;      #ifdef UNIX_THREADS