pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:43:   #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    + cpu_time_t thread_quanta = 0; +    PMOD_EXPORT int live_threads = 0;   PMOD_EXPORT COND_T live_threads_change;   PMOD_EXPORT COND_T threads_disabled_change;      #else   #include "pike_threadlib.h"   #endif /* !CONFIGURE_TEST */      #ifndef PIKE_THREAD_C_STACK_SIZE   #define PIKE_THREAD_C_STACK_SIZE (256 * 1024)
pike.git/src/threads.c:373: Inside #if defined(PIKE_DEBUG)
  PMOD_EXPORT const char msg_thr_allow_in_gc[] =    "Threads allowed during garbage collection (pass %d).\n";   PMOD_EXPORT const char msg_thr_allow_in_disabled[] =    "Threads allowed from a different thread "    "while threads are disabled. "    "(self: %"PRINTSIZET"x, disabler: %"PRINTSIZET"x)\n";   PMOD_EXPORT const char msg_global_dynbuf_in_use[] =    "Threads allowed while the global dynamic buffer is in use.\n";   #endif    + PMOD_EXPORT void check_thread_quanta(struct thread_state *ts) + { +  cpu_time_t now = get_real_time(); +  +  if (((now - ts->interval_start) > thread_quanta) && +  (ts->thread_obj)) { +  ref_push_object(ts->thread_obj); +  push_int64(now - ts->interval_start); +  ts->interval_start = now; + #ifndef LONG_CPU_TIME +  push_int(1000000000 / CPU_TIME_TICKS); +  o_multiply(); + #endif +  SAFE_APPLY_MASTER("thread_quanta_exceeded", 2); +  pop_stack(); +  } + } +    struct thread_local   {    INT32 id;   };      static volatile IMUTEX_T *interleave_list = NULL;      /* 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. */
pike.git/src/threads.c:1326:   {    pop_n_elems(args);    if (Pike_interpreter.thread_state) {    ref_push_object(Pike_interpreter.thread_state->thread_obj);    } else {    /* Threads not enabled yet/anylonger */    push_undefined();    }   }    + /*! @decl int(0..) get_thread_quanta() +  *! +  *! @returns +  *! Returns the current thread quanta in nanoseconds. +  *! +  *! @seealso +  *! @[set_thread_quanta()], @[gethrtime()] +  */ + static void f_get_thread_quanta(INT32 args) + { +  pop_n_elems(args); +  push_int64(thread_quanta); + #ifndef LONG_CPU_TIME_T +  /* Convert from ticks. */ +  push_int(1000000000 / CPU_TIME_TICKS); +  o_multiply(); + #endif + } +  + /*! @decl int(0..) set_thread_quanta(int(0..) ns) +  *! +  *! Set the thread quanta. +  *! +  *! @param ns +  *! New thread quanta in nanoseconds. +  *! A value of zero (default) disables the thread quanta checks. +  *! +  *! When enabled @[MasterObject.thread_quanta_exceeded()] will +  *! be called when a thread has spent more time than the quanta +  *! without allowing another thread to run. +  *! +  *! @note +  *! Setting a non-zero value that is too small to allow for +  *! @[MasterObject.thread_quanta_exceeded()] to run is NOT a +  *! good idea. +  *! +  *! @returns +  *! Returns the previous thread quanta in nanoseconds. +  *! +  *! @seealso +  *! @[set_thread_quanta()], @[gethrtime()] +  */ + static void f_set_thread_quanta(INT32 args) + { +  LONGEST ns = 0; +  + #ifndef LONG_CPU_TIME_T +  /* Convert to ticks. */ +  push_int(1000000000 / CPU_TIME_TICKS); +  o_divide(); + #endif +  get_all_args("set_thread_quanta", args, "%l", &ns); +  pop_n_elems(args); +  +  push_int64(thread_quanta); + #ifndef LONG_CPU_TIME_T +  /* Convert from ticks. */ +  push_int(1000000000 / CPU_TIME_TICKS); +  o_multiply(); + #endif +  +  if (ns <= 0) ns = 0; +  +  thread_quanta = ns; +  +  if (Pike_interpreter.thread_state) { +  Pike_interpreter.thread_state->interval_start = get_real_time(); +  } + } +    #define THIS_MUTEX ((struct mutex_storage *)(CURRENT_STORAGE))         /* Note:    * No reference is kept to the key object, it is destructed if the    * mutex is destructed. The key pointer is set to zero by the    * key object when the key is destructed.    */      struct mutex_storage
pike.git/src/threads.c:2649:    add_global_program("thread_create", thread_id_prog);       ADD_EFUN("this_thread",f_this_thread,    tFunc(tNone,tObjIs_THREAD_ID),    OPT_EXTERNAL_DEPEND);       ADD_EFUN("all_threads",f_all_threads,    tFunc(tNone,tArr(tObjIs_THREAD_ID)),    OPT_EXTERNAL_DEPEND);    +  ADD_EFUN("get_thread_quanta", f_get_thread_quanta, +  tFunc(tNone, tInt), +  OPT_EXTERNAL_DEPEND); +  +  ADD_EFUN("set_thread_quanta", f_set_thread_quanta, +  tFunc(tInt, tInt), +  OPT_EXTERNAL_DEPEND); +     /* Some constants... */    add_integer_constant("THREAD_NOT_STARTED", THREAD_NOT_STARTED, 0);    add_integer_constant("THREAD_RUNNING", THREAD_RUNNING, 0);    add_integer_constant("THREAD_EXITED", THREAD_EXITED, 0);       backend_thread_obj = fast_clone_object(thread_id_prog);    INIT_THREAD_STATE((struct thread_state *)(backend_thread_obj->storage +    thread_storage_offset));    thread_table_insert(Pike_interpreter.thread_state);   }