Project

General

Profile

Feature #8809 » clock_getres.patch

akr (Akira Tanaka), 08/22/2013 11:33 PM

View differences:

process.c (working copy)
return make_clock_result(&ts, unit);
}
/*
* call-seq:
* Process.clock_getres(clock_id [, unit]) -> number
*
* Returns a time resolution returned by POSIX clock_getres() function.
*
* +clock_id+ specifies a kind of clock.
* See the document of +Process.clock_gettime+ for details.
*
* +clock_id+ can be a symbol as +Process.clock_gettime+.
* However the result may not be accurate.
* For example, +Process.clock_getres(:SUS_GETTIMEOFDAY_BASED_CLOCK_REALTIME, :nanosecond)+
* returns 1000, always.
*
* If the given +clock_id+ is not supported, Errno::EINVAL is raised.
*
* +unit+ specifies a type of the return value.
* +Process.clock_getres+ accepts +unit+ as +Process.clock_gettime+.
* The default value, +:float_second+, is also same as
* +Process.clock_gettime+.
*
* +Process.clock_getres+ also accepts +:hertz+ as +unit+.
* +:hertz+ means a the reciprocal of +:float_second+.
*
* +:hertz+ can be used to obtain the exact value of
* the clock ticks per second for times() function and
* CLOCK_PER_SEC for clock() function.
*
* +Process.clock_getres(:POSIX_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)+
* returns the clock ticks per second.
*
* +Process.clock_getres(:ISO_C_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)+
* returns CLOCK_PER_SEC.
*
* p Process.clock_getres(Process::CLOCK_MONOTONIC)
* #=> 1.0e-09
*
*/
VALUE
rb_clock_getres(int argc, VALUE *argv)
{
struct timespec ts;
VALUE clk_id, unit;
int ret;
double hertz;
rb_scan_args(argc, argv, "11", &clk_id, &unit);
if (SYMBOL_P(clk_id)) {
#ifdef RUBY_SUS_GETTIMEOFDAY_BASED_CLOCK_REALTIME
if (clk_id == RUBY_SUS_GETTIMEOFDAY_BASED_CLOCK_REALTIME) {
ts.tv_sec = 0;
ts.tv_nsec = 1000;
goto success;
}
#endif
#ifdef RUBY_ISO_C_TIME_BASED_CLOCK_REALTIME
if (clk_id == RUBY_ISO_C_TIME_BASED_CLOCK_REALTIME) {
ts.tv_sec = 1;
ts.tv_nsec = 0;
goto success;
}
#endif
#ifdef RUBY_SUS_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID
if (clk_id == RUBY_SUS_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID) {
ts.tv_sec = 0;
ts.tv_nsec = 1000;
goto success;
}
#endif
#ifdef RUBY_POSIX_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID
if (clk_id == RUBY_POSIX_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID) {
hertz = get_clk_tck();
goto success_hertz;
}
#endif
#ifdef RUBY_ISO_C_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID
if (clk_id == RUBY_ISO_C_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID) {
hertz = CLOCKS_PER_SEC;
goto success_hertz;
}
#endif
#ifdef RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC
/* not yet */
#endif
}
else {
#if defined(HAVE_CLOCK_GETTIME)
clockid_t c;
c = NUM2CLOCKID(clk_id);
ret = clock_getres(c, &ts);
if (ret == -1)
rb_sys_fail("clock_getres");
goto success;
#endif
}
/* EINVAL emulates clock_getres behavior when clock_id is invalid. */
errno = EINVAL;
rb_sys_fail(0);
success_hertz:
if (unit == ID2SYM(rb_intern("hertz"))) {
return DBL2NUM(hertz);
}
else {
double ns;
ns = 1e9 / hertz;
ts.tv_sec = (time_t)(ns*1e-9);
ts.tv_nsec = ns - ts.tv_sec*1e9;
return make_clock_result(&ts, unit);
}
success:
if (unit == ID2SYM(rb_intern("hertz"))) {
hertz = 1e9 / (ts.tv_sec * 1e9 + ts.tv_nsec);
return DBL2NUM(hertz);
}
else {
return make_clock_result(&ts, unit);
}
}
VALUE rb_mProcess;
VALUE rb_mProcUID;
VALUE rb_mProcGID;
......
rb_define_const(rb_mProcess, "CLOCK_SECOND", CLOCKID2NUM(CLOCK_SECOND));
#endif
rb_define_module_function(rb_mProcess, "clock_gettime", rb_clock_gettime, -1);
rb_define_module_function(rb_mProcess, "clock_getres", rb_clock_getres, -1);
#if defined(HAVE_TIMES) || defined(_WIN32)
rb_cProcessTms = rb_struct_define("Tms", "utime", "stime", "cutime", "cstime", NULL);
(1-1/3)