mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* process.c (reduce_factors): New function.
(timetick2dblnum): Use reduce_factors. (timetick2integer): Ditto. (make_clock_result): Follow the above change. (rb_clock_gettime): Ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42669 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
f0bf7f7518
commit
ca0b5118a5
2 changed files with 114 additions and 59 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
Fri Aug 23 21:37:28 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* process.c (reduce_factors): New function.
|
||||||
|
(timetick2dblnum): Use reduce_factors.
|
||||||
|
(timetick2integer): Ditto.
|
||||||
|
(make_clock_result): Follow the above change.
|
||||||
|
(rb_clock_gettime): Ditto.
|
||||||
|
|
||||||
Fri Aug 23 21:00:55 2013 Tanaka Akira <akr@fsij.org>
|
Fri Aug 23 21:00:55 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* process.c (timetick_int_t): Renamed from timetick_giga_count_t.
|
* process.c (timetick_int_t): Renamed from timetick_giga_count_t.
|
||||||
|
|
161
process.c
161
process.c
|
@ -6709,73 +6709,123 @@ reduce_fraction(timetick_int_t *np, timetick_int_t *dp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
reduce_factors(timetick_int_t *numerators, int num_numerators,
|
||||||
|
timetick_int_t *denominators, int num_denominators)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
for (i = 0; i < num_numerators; i++) {
|
||||||
|
if (numerators[i] == 1)
|
||||||
|
continue;
|
||||||
|
for (j = 0; j < num_denominators; j++) {
|
||||||
|
if (denominators[j] == 1)
|
||||||
|
continue;
|
||||||
|
reduce_fraction(&numerators[i], &denominators[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct timetick {
|
struct timetick {
|
||||||
timetick_int_t giga_count;
|
timetick_int_t giga_count;
|
||||||
int32_t count; /* 0 .. 999999999 */
|
int32_t count; /* 0 .. 999999999 */
|
||||||
};
|
};
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
timetick2dblnum(struct timetick *ttp, timetick_int_t numerator, timetick_int_t denominator, timetick_int_t factor)
|
timetick2dblnum(struct timetick *ttp,
|
||||||
|
timetick_int_t *numerators, int num_numerators,
|
||||||
|
timetick_int_t *denominators, int num_denominators)
|
||||||
{
|
{
|
||||||
if (factor != 1 && denominator != 1)
|
double d;
|
||||||
reduce_fraction(&factor, &denominator);
|
int i;
|
||||||
if (numerator != 1 && denominator != 1)
|
|
||||||
reduce_fraction(&numerator, &denominator);
|
reduce_factors(numerators, num_numerators,
|
||||||
return DBL2NUM(((ttp->giga_count * 1e9 + ttp->count) * numerator * factor) / denominator);
|
denominators, num_denominators);
|
||||||
|
|
||||||
|
d = ttp->giga_count * 1e9 + ttp->count;
|
||||||
|
|
||||||
|
for (i = 0; i < num_numerators; i++)
|
||||||
|
d *= numerators[i];
|
||||||
|
for (i = 0; i < num_denominators; i++)
|
||||||
|
d /= denominators[i];
|
||||||
|
|
||||||
|
return DBL2NUM(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NDIV(x,y) (-(-((x)+1)/(y))-1)
|
#define NDIV(x,y) (-(-((x)+1)/(y))-1)
|
||||||
#define DIV(n,d) ((n)<0 ? NDIV((n),(d)) : (n)/(d))
|
#define DIV(n,d) ((n)<0 ? NDIV((n),(d)) : (n)/(d))
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
timetick2integer(struct timetick *ttp, timetick_int_t numerator, timetick_int_t denominator, timetick_int_t factor)
|
timetick2integer(struct timetick *ttp,
|
||||||
|
timetick_int_t *numerators, int num_numerators,
|
||||||
|
timetick_int_t *denominators, int num_denominators)
|
||||||
{
|
{
|
||||||
VALUE v;
|
VALUE v;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (denominator != 1 && factor != 1)
|
reduce_factors(numerators, num_numerators,
|
||||||
reduce_fraction(&factor, &denominator);
|
denominators, num_denominators);
|
||||||
if (denominator != 1 && numerator != 1)
|
|
||||||
reduce_fraction(&numerator, &denominator);
|
|
||||||
|
|
||||||
if (!MUL_OVERFLOW_SIGNED_INTEGER_P(1000000000, ttp->giga_count,
|
if (!MUL_OVERFLOW_SIGNED_INTEGER_P(1000000000, ttp->giga_count,
|
||||||
TIMETICK_INT_MIN, TIMETICK_INT_MAX-ttp->count)) {
|
TIMETICK_INT_MIN, TIMETICK_INT_MAX-ttp->count)) {
|
||||||
timetick_int_t t = ttp->giga_count * 1000000000 + ttp->count;
|
timetick_int_t t = ttp->giga_count * 1000000000 + ttp->count;
|
||||||
if (!MUL_OVERFLOW_SIGNED_INTEGER_P(numerator, t,
|
for (i = 0; i < num_numerators; i++) {
|
||||||
TIMETICK_INT_MIN, TIMETICK_INT_MAX)) {
|
timetick_int_t factor = numerators[i];
|
||||||
t *= numerator;
|
if (MUL_OVERFLOW_SIGNED_INTEGER_P(factor, t,
|
||||||
if (!MUL_OVERFLOW_SIGNED_INTEGER_P(factor, t,
|
TIMETICK_INT_MIN, TIMETICK_INT_MAX))
|
||||||
TIMETICK_INT_MIN, TIMETICK_INT_MAX)) {
|
goto generic;
|
||||||
t *= factor;
|
t *= factor;
|
||||||
t = DIV(t, denominator);
|
}
|
||||||
|
for (i = 0; i < num_denominators; i++) {
|
||||||
|
t = DIV(t, denominators[i]);
|
||||||
|
}
|
||||||
return TIMETICK_INT2NUM(t);
|
return TIMETICK_INT2NUM(t);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
generic:
|
||||||
v = TIMETICK_INT2NUM(ttp->giga_count);
|
v = TIMETICK_INT2NUM(ttp->giga_count);
|
||||||
v = rb_funcall(v, '*', 1, LONG2FIX(1000000000));
|
v = rb_funcall(v, '*', 1, LONG2FIX(1000000000));
|
||||||
v = rb_funcall(v, '+', 1, LONG2FIX(ttp->count));
|
v = rb_funcall(v, '+', 1, LONG2FIX(ttp->count));
|
||||||
v = rb_funcall(v, '*', 1, TIMETICK_INT2NUM(numerator));
|
for (i = 0; i < num_numerators; i++) {
|
||||||
|
timetick_int_t factor = numerators[i];
|
||||||
|
if (factor == 1)
|
||||||
|
continue;
|
||||||
v = rb_funcall(v, '*', 1, TIMETICK_INT2NUM(factor));
|
v = rb_funcall(v, '*', 1, TIMETICK_INT2NUM(factor));
|
||||||
v = rb_funcall(v, '/', 1, TIMETICK_INT2NUM(denominator)); /* Ruby's '/' is div. */
|
}
|
||||||
|
for (i = 0; i < num_denominators; i++) {
|
||||||
|
v = rb_funcall(v, '/', 1, TIMETICK_INT2NUM(denominators[i])); /* Ruby's '/' is div. */
|
||||||
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
make_clock_result(struct timetick *ttp, timetick_int_t numerator, timetick_int_t denominator, VALUE unit)
|
make_clock_result(struct timetick *ttp,
|
||||||
|
timetick_int_t *numerators, int num_numerators,
|
||||||
|
timetick_int_t *denominators, int num_denominators,
|
||||||
|
VALUE unit)
|
||||||
{
|
{
|
||||||
if (unit == ID2SYM(rb_intern("nanosecond")))
|
if (unit == ID2SYM(rb_intern("nanosecond"))) {
|
||||||
return timetick2integer(ttp, numerator, denominator, 1000000000);
|
numerators[num_numerators++] = 1000000000;
|
||||||
else if (unit == ID2SYM(rb_intern("microsecond")))
|
return timetick2integer(ttp, numerators, num_numerators, denominators, num_denominators);
|
||||||
return timetick2integer(ttp, numerator, denominator, 1000000);
|
}
|
||||||
else if (unit == ID2SYM(rb_intern("millisecond")))
|
else if (unit == ID2SYM(rb_intern("microsecond"))) {
|
||||||
return timetick2integer(ttp, numerator, denominator, 1000);
|
numerators[num_numerators++] = 1000000;
|
||||||
else if (unit == ID2SYM(rb_intern("float_microsecond")))
|
return timetick2integer(ttp, numerators, num_numerators, denominators, num_denominators);
|
||||||
return timetick2dblnum(ttp, numerator, denominator, 1000000);
|
}
|
||||||
else if (unit == ID2SYM(rb_intern("float_millisecond")))
|
else if (unit == ID2SYM(rb_intern("millisecond"))) {
|
||||||
return timetick2dblnum(ttp, numerator, denominator, 1000);
|
numerators[num_numerators++] = 1000;
|
||||||
else if (NIL_P(unit) || unit == ID2SYM(rb_intern("float_second")))
|
return timetick2integer(ttp, numerators, num_numerators, denominators, num_denominators);
|
||||||
return timetick2dblnum(ttp, numerator, denominator, 1);
|
}
|
||||||
|
else if (unit == ID2SYM(rb_intern("float_microsecond"))) {
|
||||||
|
numerators[num_numerators++] = 1000000;
|
||||||
|
return timetick2dblnum(ttp, numerators, num_numerators, denominators, num_denominators);
|
||||||
|
}
|
||||||
|
else if (unit == ID2SYM(rb_intern("float_millisecond"))) {
|
||||||
|
numerators[num_numerators++] = 1000;
|
||||||
|
return timetick2dblnum(ttp, numerators, num_numerators, denominators, num_denominators);
|
||||||
|
}
|
||||||
|
else if (NIL_P(unit) || unit == ID2SYM(rb_intern("float_second"))) {
|
||||||
|
return timetick2dblnum(ttp, numerators, num_numerators, denominators, num_denominators);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
rb_raise(rb_eArgError, "unexpected unit: %"PRIsVALUE, unit);
|
rb_raise(rb_eArgError, "unexpected unit: %"PRIsVALUE, unit);
|
||||||
}
|
}
|
||||||
|
@ -6890,8 +6940,10 @@ rb_clock_gettime(int argc, VALUE *argv)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
struct timetick tt;
|
struct timetick tt;
|
||||||
timetick_int_t numerator;
|
timetick_int_t numerators[2];
|
||||||
timetick_int_t denominator;
|
timetick_int_t denominators[2];
|
||||||
|
int num_numerators = 0;
|
||||||
|
int num_denominators = 0;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "11", &clk_id, &unit);
|
rb_scan_args(argc, argv, "11", &clk_id, &unit);
|
||||||
|
|
||||||
|
@ -6910,9 +6962,8 @@ rb_clock_gettime(int argc, VALUE *argv)
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
rb_sys_fail("gettimeofday");
|
rb_sys_fail("gettimeofday");
|
||||||
tt.giga_count = tv.tv_sec;
|
tt.giga_count = tv.tv_sec;
|
||||||
tt.count = tv.tv_usec * 1000;
|
tt.count = (int32_t)tv.tv_usec * 1000;
|
||||||
numerator = 1;
|
denominators[num_denominators++] = 1000000000;
|
||||||
denominator = 1000000000;
|
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6924,8 +6975,7 @@ rb_clock_gettime(int argc, VALUE *argv)
|
||||||
rb_sys_fail("time");
|
rb_sys_fail("time");
|
||||||
tt.giga_count = t;
|
tt.giga_count = t;
|
||||||
tt.count = 0;
|
tt.count = 0;
|
||||||
numerator = 1;
|
denominators[num_denominators++] = 1000000000;
|
||||||
denominator = 1000000000;
|
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6934,7 +6984,7 @@ rb_clock_gettime(int argc, VALUE *argv)
|
||||||
ID2SYM(rb_intern("SUS_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID"))
|
ID2SYM(rb_intern("SUS_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID"))
|
||||||
if (clk_id == RUBY_SUS_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID) {
|
if (clk_id == RUBY_SUS_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID) {
|
||||||
struct rusage usage;
|
struct rusage usage;
|
||||||
long usec;
|
int32_t usec;
|
||||||
ret = getrusage(RUSAGE_SELF, &usage);
|
ret = getrusage(RUSAGE_SELF, &usage);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
rb_sys_fail("getrusage");
|
rb_sys_fail("getrusage");
|
||||||
|
@ -6945,8 +6995,7 @@ rb_clock_gettime(int argc, VALUE *argv)
|
||||||
usec -= 1000000;
|
usec -= 1000000;
|
||||||
}
|
}
|
||||||
tt.count = usec * 1000;
|
tt.count = usec * 1000;
|
||||||
numerator = 1;
|
denominators[num_denominators++] = 1000000000;
|
||||||
denominator = 1000000000;
|
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -6961,14 +7010,13 @@ rb_clock_gettime(int argc, VALUE *argv)
|
||||||
rb_sys_fail("times");
|
rb_sys_fail("times");
|
||||||
utime = (unsigned_clock_t)buf.tms_utime;
|
utime = (unsigned_clock_t)buf.tms_utime;
|
||||||
stime = (unsigned_clock_t)buf.tms_stime;
|
stime = (unsigned_clock_t)buf.tms_stime;
|
||||||
tt.count = (utime % 1000000000) + (stime % 1000000000);
|
tt.count = (int32_t)((utime % 1000000000) + (stime % 1000000000));
|
||||||
tt.giga_count = (utime / 1000000000) + (stime / 1000000000);
|
tt.giga_count = (utime / 1000000000) + (stime / 1000000000);
|
||||||
if (1000000000 <= tt.count) {
|
if (1000000000 <= tt.count) {
|
||||||
tt.count -= 1000000000;
|
tt.count -= 1000000000;
|
||||||
tt.giga_count++;
|
tt.giga_count++;
|
||||||
}
|
}
|
||||||
numerator = 1;
|
denominators[num_denominators++] = get_clk_tck();
|
||||||
denominator = get_clk_tck();
|
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -6983,10 +7031,9 @@ rb_clock_gettime(int argc, VALUE *argv)
|
||||||
if (c == (clock_t)-1)
|
if (c == (clock_t)-1)
|
||||||
rb_sys_fail("clock");
|
rb_sys_fail("clock");
|
||||||
uc = (unsigned_clock_t)c;
|
uc = (unsigned_clock_t)c;
|
||||||
tt.count = uc % 1000000000;
|
tt.count = (int32_t)(uc % 1000000000);
|
||||||
tt.giga_count = uc / 1000000000;
|
tt.giga_count = uc / 1000000000;
|
||||||
numerator = 1;
|
denominators[num_denominators++] = CLOCKS_PER_SEC;
|
||||||
denominator = CLOCKS_PER_SEC;
|
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7000,10 +7047,11 @@ rb_clock_gettime(int argc, VALUE *argv)
|
||||||
(void) mach_timebase_info(&sTimebaseInfo);
|
(void) mach_timebase_info(&sTimebaseInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
tt.count = t % 1000000000;
|
tt.count = (int32_t)(t % 1000000000);
|
||||||
tt.giga_count = t / 1000000000;
|
tt.giga_count = t / 1000000000;
|
||||||
numerator = sTimebaseInfo.numer;
|
numerators[num_numerators++] = sTimebaseInfo.numer;
|
||||||
denominator = sTimebaseInfo.denom * (timetick_int_t)1000000000;
|
denominators[num_denominators++] = sTimebaseInfo.denom;
|
||||||
|
denominators[num_denominators++] = 1000000000;
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -7016,10 +7064,9 @@ rb_clock_gettime(int argc, VALUE *argv)
|
||||||
ret = clock_gettime(c, &ts);
|
ret = clock_gettime(c, &ts);
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
rb_sys_fail("clock_gettime");
|
rb_sys_fail("clock_gettime");
|
||||||
tt.count = ts.tv_nsec;
|
tt.count = (int32_t)ts.tv_nsec;
|
||||||
tt.giga_count = ts.tv_sec;
|
tt.giga_count = ts.tv_sec;
|
||||||
numerator = 1;
|
denominators[num_denominators++] = 1000000000;
|
||||||
denominator = 1000000000;
|
|
||||||
goto success;
|
goto success;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -7028,7 +7075,7 @@ rb_clock_gettime(int argc, VALUE *argv)
|
||||||
rb_sys_fail(0);
|
rb_sys_fail(0);
|
||||||
|
|
||||||
success:
|
success:
|
||||||
return make_clock_result(&tt, numerator, denominator, unit);
|
return make_clock_result(&tt, numerators, num_numerators, denominators, num_denominators, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE rb_mProcess;
|
VALUE rb_mProcess;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue