Project

General

Profile

Feature #8809 ยป clock_getres.patch

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

View differences:

process.c (working copy)
6945 6945
    return make_clock_result(&ts, unit);
6946 6946
}
6947 6947

  
6948
/*
6949
 *  call-seq:
6950
 *     Process.clock_getres(clock_id [, unit])   -> number
6951
 *
6952
 *  Returns a time resolution returned by POSIX clock_getres() function.
6953
 *
6954
 *  +clock_id+ specifies a kind of clock.
6955
 *  See the document of +Process.clock_gettime+ for details.
6956
 *
6957
 *  +clock_id+ can be a symbol as +Process.clock_gettime+.
6958
 *  However the result may not be accurate.
6959
 *  For example, +Process.clock_getres(:SUS_GETTIMEOFDAY_BASED_CLOCK_REALTIME, :nanosecond)+
6960
 *  returns 1000, always.
6961
 *
6962
 *  If the given +clock_id+ is not supported, Errno::EINVAL is raised.
6963
 *
6964
 *  +unit+ specifies a type of the return value.
6965
 *  +Process.clock_getres+ accepts +unit+ as +Process.clock_gettime+.
6966
 *  The default value, +:float_second+, is also same as
6967
 *  +Process.clock_gettime+.
6968
 *
6969
 *  +Process.clock_getres+ also accepts +:hertz+ as +unit+.
6970
 *  +:hertz+ means a the reciprocal of +:float_second+.
6971
 *
6972
 *  +:hertz+ can be used to obtain the exact value of
6973
 *  the clock ticks per second for times() function and
6974
 *  CLOCK_PER_SEC for clock() function.
6975
 *
6976
 *  +Process.clock_getres(:POSIX_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)+
6977
 *  returns the clock ticks per second.
6978
 *
6979
 *  +Process.clock_getres(:ISO_C_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)+
6980
 *  returns CLOCK_PER_SEC.
6981
 *
6982
 *    p Process.clock_getres(Process::CLOCK_MONOTONIC)
6983
 *    #=> 1.0e-09
6984
 *
6985
 */
6986
VALUE
6987
rb_clock_getres(int argc, VALUE *argv)
6988
{
6989
    struct timespec ts;
6990
    VALUE clk_id, unit;
6991
    int ret;
6992
    double hertz;
6993

  
6994
    rb_scan_args(argc, argv, "11", &clk_id, &unit);
6995

  
6996
    if (SYMBOL_P(clk_id)) {
6997
#ifdef RUBY_SUS_GETTIMEOFDAY_BASED_CLOCK_REALTIME
6998
        if (clk_id == RUBY_SUS_GETTIMEOFDAY_BASED_CLOCK_REALTIME) {
6999
            ts.tv_sec = 0;
7000
            ts.tv_nsec = 1000;
7001
            goto success;
7002
        }
7003
#endif
7004

  
7005
#ifdef RUBY_ISO_C_TIME_BASED_CLOCK_REALTIME
7006
        if (clk_id == RUBY_ISO_C_TIME_BASED_CLOCK_REALTIME) {
7007
            ts.tv_sec = 1;
7008
            ts.tv_nsec = 0;
7009
            goto success;
7010
        }
7011
#endif
7012

  
7013
#ifdef RUBY_SUS_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID
7014
        if (clk_id == RUBY_SUS_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID) {
7015
            ts.tv_sec = 0;
7016
            ts.tv_nsec = 1000;
7017
            goto success;
7018
        }
7019
#endif
7020

  
7021
#ifdef RUBY_POSIX_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID
7022
        if (clk_id == RUBY_POSIX_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID) {
7023
            hertz = get_clk_tck();
7024
            goto success_hertz;
7025
        }
7026
#endif
7027

  
7028
#ifdef RUBY_ISO_C_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID
7029
        if (clk_id == RUBY_ISO_C_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID) {
7030
            hertz = CLOCKS_PER_SEC;
7031
            goto success_hertz;
7032
        }
7033
#endif
7034

  
7035
#ifdef RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC
7036
        /* not yet */
7037
#endif
7038
    }
7039
    else {
7040
#if defined(HAVE_CLOCK_GETTIME)
7041
        clockid_t c;
7042
        c = NUM2CLOCKID(clk_id);
7043
        ret = clock_getres(c, &ts);
7044
        if (ret == -1)
7045
            rb_sys_fail("clock_getres");
7046
        goto success;
7047
#endif
7048
    }
7049
    /* EINVAL emulates clock_getres behavior when clock_id is invalid. */
7050
    errno = EINVAL;
7051
    rb_sys_fail(0);
7052

  
7053
  success_hertz:
7054
    if (unit == ID2SYM(rb_intern("hertz"))) {
7055
        return DBL2NUM(hertz);
7056
    }
7057
    else {
7058
        double ns;
7059
        ns = 1e9 / hertz;
7060
        ts.tv_sec = (time_t)(ns*1e-9);
7061
        ts.tv_nsec = ns - ts.tv_sec*1e9;
7062
        return make_clock_result(&ts, unit);
7063
    }
7064

  
7065
  success:
7066
    if (unit == ID2SYM(rb_intern("hertz"))) {
7067
        hertz = 1e9 / (ts.tv_sec * 1e9 + ts.tv_nsec);
7068
        return DBL2NUM(hertz);
7069
    }
7070
    else {
7071
        return make_clock_result(&ts, unit);
7072
    }
7073
}
7074

  
6948 7075
VALUE rb_mProcess;
6949 7076
VALUE rb_mProcUID;
6950 7077
VALUE rb_mProcGID;
......
7270 7397
    rb_define_const(rb_mProcess, "CLOCK_SECOND", CLOCKID2NUM(CLOCK_SECOND));
7271 7398
#endif
7272 7399
    rb_define_module_function(rb_mProcess, "clock_gettime", rb_clock_gettime, -1);
7400
    rb_define_module_function(rb_mProcess, "clock_getres", rb_clock_getres, -1);
7273 7401

  
7274 7402
#if defined(HAVE_TIMES) || defined(_WIN32)
7275 7403
    rb_cProcessTms = rb_struct_define("Tms", "utime", "stime", "cutime", "cstime", NULL);