diff --git a/src/builtin_functions.c b/src/builtin_functions.c index a8dea8b41fd1b21270b2e56c8ec3df7a22a0dd73..dc39bd43c79f5aebfc9067e5a7da2e5a783dd78f 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -8078,6 +8078,46 @@ PMOD_EXPORT void f_gethrtime(INT32 args) } } +/*! @decl int gethrdtime(void|int nsec) + *! + *! Return the high resolution real time spent with threads disabled + *! since the Pike interpreter was started. The time is normally + *! returned in microseconds, but if the optional argument @[nsec] + *! is nonzero it's returned in nanoseconds. + *! + *! @note + *! The actual accuracy on many systems is significantly less than + *! microseconds or nanoseconds. See @[System.REAL_TIME_RESOLUTION]. + *! + *! @seealso + *! @[_disable_threads()], @[gethrtime()] + */ +static void f_gethrdtime(INT32 args) +{ + int nsec = args && !UNSAFE_IS_ZERO(Pike_sp-args); + cpu_time_t time = threads_disabled_acc_time; + pop_n_elems(args); + + if (threads_disabled) { + time += get_real_time() - threads_disabled_start; + } + if (nsec) { + push_int64(time); +#ifndef LONG_CPU_TIME + push_int(1000000000 / CPU_TIME_TICKS); + o_multiply(); +#endif + } else { +#if CPU_TIME_TICKS_LOW > 1000000 + push_int64(time / (CPU_TIME_TICKS / 1000000)); +#else + push_int64 (time); + push_int (1000000 / CPU_TIME_TICKS); + o_multiply(); +#endif + } +} + #ifdef PROFILING /*! @decl array(int|mapping(string:array(int))) @ *! get_profiling_info(program prog) @@ -9572,6 +9612,8 @@ void init_builtin_efuns(void) tFunc(tOr(tInt,tVoid),tInt), OPT_EXTERNAL_DEPEND); ADD_EFUN("gethrtime", f_gethrtime, tFunc(tOr(tInt,tVoid),tInt), OPT_EXTERNAL_DEPEND); + ADD_EFUN("gethrdtime", f_gethrdtime, + tFunc(tOr(tInt,tVoid),tInt), OPT_EXTERNAL_DEPEND); #ifdef PROFILING ADD_EFUN("get_profiling_info", f_get_prof_info, diff --git a/src/threads.c b/src/threads.c index 4abd32c1e2cdc56f4838169af8d95296e6790553..80f9c78fbc8ec9e1a5d8af60ccd2902609dc538f 100644 --- a/src/threads.c +++ b/src/threads.c @@ -935,6 +935,9 @@ void low_init_threads_disable(void) *! memory structures, since those are only destructed by the periodic *! gc. (This advice applies to mutex locks in general, for that *! matter.) + *! + *! @seealso + *! @[gethrdtime()] */ void init_threads_disable(struct object *UNUSED(o)) {