Project

General

Profile

Feature #8809 ยป clock_getres-3.patch

akr (Akira Tanaka), 08/24/2013 10:41 AM

View differences:

process.c (working copy)
6751 6751
    return DBL2NUM(d);
6752 6752
}
6753 6753

  
6754
static VALUE
6755
timetick2dblnum_reciprocal(struct timetick *ttp,
6756
    timetick_int_t *numerators, int num_numerators,
6757
    timetick_int_t *denominators, int num_denominators)
6758
{
6759
    double d;
6760
    int i;
6761

  
6762
    reduce_factors(numerators, num_numerators,
6763
                   denominators, num_denominators);
6764

  
6765
    d = 1.0;
6766
    for (i = 0; i < num_denominators; i++)
6767
        d *= denominators[i];
6768
    for (i = 0; i < num_numerators; i++)
6769
        d /= numerators[i];
6770
    d /= ttp->giga_count * 1e9 + ttp->count;
6771

  
6772
    return DBL2NUM(d);
6773
}
6774

  
6754 6775
#define NDIV(x,y) (-(-((x)+1)/(y))-1)
6755 6776
#define DIV(n,d) ((n)<0 ? NDIV((n),(d)) : (n)/(d))
6756 6777

  
......
7078 7099
    return make_clock_result(&tt, numerators, num_numerators, denominators, num_denominators, unit);
7079 7100
}
7080 7101

  
7102
/*
7103
 *  call-seq:
7104
 *     Process.clock_getres(clock_id [, unit])   -> number
7105
 *
7106
 *  Returns the time resolution returned by POSIX clock_getres() function.
7107
 *
7108
 *  +clock_id+ specifies a kind of clock.
7109
 *  See the document of +Process.clock_gettime+ for details.
7110
 *
7111
 *  +clock_id+ can be a symbol as +Process.clock_gettime+.
7112
 *  However the result may not be accurate.
7113
 *  For example, +Process.clock_getres(:GETTIMEOFDAY_BASED_CLOCK_REALTIME)+
7114
 *  returns 1.0e-06 which means 1 micro second, but actual resolution can be more coarse.
7115
 *
7116
 *  If the given +clock_id+ is not supported, Errno::EINVAL is raised.
7117
 *
7118
 *  +unit+ specifies a type of the return value.
7119
 *  +Process.clock_getres+ accepts +unit+ as +Process.clock_gettime+.
7120
 *  The default value, +:float_second+, is also same as
7121
 *  +Process.clock_gettime+.
7122
 *
7123
 *  +Process.clock_getres+ also accepts +:hertz+ as +unit+.
7124
 *  +:hertz+ means a the reciprocal of +:float_second+.
7125
 *
7126
 *  +:hertz+ can be used to obtain the exact value of
7127
 *  the clock ticks per second for times() function and
7128
 *  CLOCK_PER_SEC for clock() function.
7129
 *
7130
 *  +Process.clock_getres(:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)+
7131
 *  returns the clock ticks per second.
7132
 *
7133
 *  +Process.clock_getres(:CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz)+
7134
 *  returns CLOCK_PER_SEC.
7135
 *
7136
 *    p Process.clock_getres(Process::CLOCK_MONOTONIC)
7137
 *    #=> 1.0e-09
7138
 *
7139
 */
7140
VALUE
7141
rb_clock_getres(int argc, VALUE *argv)
7142
{
7143
    VALUE clk_id, unit;
7144
    int ret;
7145

  
7146
    struct timetick tt;
7147
    timetick_int_t numerators[2];
7148
    timetick_int_t denominators[2];
7149
    int num_numerators = 0;
7150
    int num_denominators = 0;
7151

  
7152
    rb_scan_args(argc, argv, "11", &clk_id, &unit);
7153

  
7154
    if (SYMBOL_P(clk_id)) {
7155
#ifdef RUBY_GETTIMEOFDAY_BASED_CLOCK_REALTIME
7156
        if (clk_id == RUBY_GETTIMEOFDAY_BASED_CLOCK_REALTIME) {
7157
            tt.giga_count = 0;
7158
            tt.count = 1000;
7159
            denominators[num_denominators++] = 1000000000;
7160
            goto success;
7161
        }
7162
#endif
7163

  
7164
#ifdef RUBY_TIME_BASED_CLOCK_REALTIME
7165
        if (clk_id == RUBY_TIME_BASED_CLOCK_REALTIME) {
7166
            tt.giga_count = 1;
7167
            tt.count = 0;
7168
            denominators[num_denominators++] = 1000000000;
7169
            goto success;
7170
        }
7171
#endif
7172

  
7173
#ifdef RUBY_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID
7174
        if (clk_id == RUBY_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID) {
7175
            tt.giga_count = 0;
7176
            tt.count = 1000;
7177
            denominators[num_denominators++] = 1000000000;
7178
            goto success;
7179
        }
7180
#endif
7181

  
7182
#ifdef RUBY_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID
7183
        if (clk_id == RUBY_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID) {
7184
            tt.count = 1;
7185
            tt.giga_count = 0;
7186
            denominators[num_denominators++] = get_clk_tck();
7187
            goto success;
7188
        }
7189
#endif
7190

  
7191
#ifdef RUBY_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID
7192
        if (clk_id == RUBY_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID) {
7193
            tt.count = 1;
7194
            tt.giga_count = 0;
7195
            denominators[num_denominators++] = CLOCKS_PER_SEC;
7196
            goto success;
7197
        }
7198
#endif
7199

  
7200
#ifdef RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC
7201
        /* not yet */
7202
#endif
7203
    }
7204
    else {
7205
#if defined(HAVE_CLOCK_GETRES)
7206
        struct timespec ts;
7207
        clockid_t c;
7208
        c = NUM2CLOCKID(clk_id);
7209
        ret = clock_getres(c, &ts);
7210
        if (ret == -1)
7211
            rb_sys_fail("clock_getres");
7212
        tt.count = (int32_t)ts.tv_nsec;
7213
        tt.giga_count = ts.tv_sec;
7214
        denominators[num_denominators++] = 1000000000;
7215
        goto success;
7216
#endif
7217
    }
7218
    /* EINVAL emulates clock_getres behavior when clock_id is invalid. */
7219
    errno = EINVAL;
7220
    rb_sys_fail(0);
7221

  
7222
  success:
7223
    if (unit == ID2SYM(rb_intern("hertz"))) {
7224
        return timetick2dblnum_reciprocal(&tt, numerators, num_numerators, denominators, num_denominators);
7225
    }
7226
    else {
7227
        return make_clock_result(&tt, numerators, num_numerators, denominators, num_denominators, unit);
7228
    }
7229
}
7230

  
7081 7231
VALUE rb_mProcess;
7082 7232
VALUE rb_mProcUID;
7083 7233
VALUE rb_mProcGID;
......
7405 7555
    rb_define_const(rb_mProcess, "CLOCK_SECOND", CLOCKID2NUM(CLOCK_SECOND));
7406 7556
#endif
7407 7557
    rb_define_module_function(rb_mProcess, "clock_gettime", rb_clock_gettime, -1);
7558
    rb_define_module_function(rb_mProcess, "clock_getres", rb_clock_getres, -1);
7408 7559

  
7409 7560
#if defined(HAVE_TIMES) || defined(_WIN32)
7410 7561
    rb_cProcessTms = rb_struct_define("Tms", "utime", "stime", "cutime", "cstime", NULL);
configure.in (working copy)
1866 1866
	AC_DEFINE(HAVE_CLOCK_GETTIME, 1)
1867 1867
    fi
1868 1868
fi
1869
AC_CHECK_FUNCS(clock_getres) # clock_getres should be tested after clock_gettime test including librt test.
1869 1870

  
1870 1871
AC_CACHE_CHECK(for unsetenv returns a value, rb_cv_unsetenv_return_value,
1871 1872
  [AC_TRY_COMPILE([