mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Refactored sub-seconds normalizations
* separated argument to `timespec2timew` from `timespec` to seconds and nano-seconds. * unified nano-seconds and micro-seconds normalizations.
This commit is contained in:
parent
2a02b61fae
commit
a5567350f7
Notes:
git
2021-04-01 12:00:46 +09:00
Merged: https://github.com/ruby/ruby/pull/4343 Merged-By: nobu <nobu@ruby-lang.org>
1 changed files with 21 additions and 40 deletions
61
time.c
61
time.c
|
@ -1844,13 +1844,13 @@ time_modify(VALUE time)
|
|||
}
|
||||
|
||||
static wideval_t
|
||||
timespec2timew(struct timespec *ts)
|
||||
timenano2timew(time_t sec, long nsec)
|
||||
{
|
||||
wideval_t timew;
|
||||
|
||||
timew = rb_time_magnify(TIMET2WV(ts->tv_sec));
|
||||
if (ts->tv_nsec)
|
||||
timew = wadd(timew, wmulquoll(WINT2WV(ts->tv_nsec), TIME_SCALE, 1000000000));
|
||||
timew = rb_time_magnify(TIMET2WV(sec));
|
||||
if (nsec)
|
||||
timew = wadd(timew, wmulquoll(WINT2WV(nsec), TIME_SCALE, 1000000000));
|
||||
return timew;
|
||||
}
|
||||
|
||||
|
@ -1918,7 +1918,7 @@ time_init_now(rb_execution_context_t *ec, VALUE time, VALUE zone)
|
|||
tobj->tm_got=0;
|
||||
tobj->timew = WINT2FIXWV(0);
|
||||
rb_timespec_now(&ts);
|
||||
tobj->timew = timespec2timew(&ts);
|
||||
tobj->timew = timenano2timew(ts.tv_sec, ts.tv_nsec);
|
||||
|
||||
if (!NIL_P(zone)) {
|
||||
time_zonelocal(time, zone);
|
||||
|
@ -2409,26 +2409,26 @@ time_init_args(rb_execution_context_t *ec, VALUE time, VALUE year, VALUE mon, VA
|
|||
}
|
||||
|
||||
static void
|
||||
time_overflow_p(time_t *secp, long *nsecp)
|
||||
subsec_normalize(time_t *secp, long *subsecp, const long maxsubsec)
|
||||
{
|
||||
time_t sec = *secp;
|
||||
long nsec = *nsecp;
|
||||
long subsec = *subsecp;
|
||||
long sec2;
|
||||
|
||||
if (nsec >= 1000000000) { /* nsec positive overflow */
|
||||
sec2 = nsec / 1000000000;
|
||||
if (UNLIKELY(subsec >= maxsubsec)) { /* subsec positive overflow */
|
||||
sec2 = subsec / maxsubsec;
|
||||
if (TIMET_MAX - sec2 < sec) {
|
||||
rb_raise(rb_eRangeError, "out of Time range");
|
||||
}
|
||||
nsec -= sec2 * 1000000000;
|
||||
subsec -= sec2 * maxsubsec;
|
||||
sec += sec2;
|
||||
}
|
||||
else if (nsec < 0) { /* nsec negative overflow */
|
||||
sec2 = NDIV(nsec,1000000000); /* negative div */
|
||||
else if (UNLIKELY(subsec < 0)) { /* subsec negative overflow */
|
||||
sec2 = NDIV(subsec, maxsubsec); /* negative div */
|
||||
if (sec < TIMET_MIN - sec2) {
|
||||
rb_raise(rb_eRangeError, "out of Time range");
|
||||
}
|
||||
nsec -= sec2 * 1000000000;
|
||||
subsec -= sec2 * maxsubsec;
|
||||
sec += sec2;
|
||||
}
|
||||
#ifndef NEGATIVE_TIME_T
|
||||
|
@ -2436,17 +2436,17 @@ time_overflow_p(time_t *secp, long *nsecp)
|
|||
rb_raise(rb_eArgError, "time must be positive");
|
||||
#endif
|
||||
*secp = sec;
|
||||
*nsecp = nsec;
|
||||
*subsecp = subsec;
|
||||
}
|
||||
|
||||
#define time_usec_normalize(secp, usecp) subsec_normalize(secp, usecp, 1000000)
|
||||
#define time_nsec_normalize(secp, nsecp) subsec_normalize(secp, nsecp, 1000000000)
|
||||
|
||||
static wideval_t
|
||||
nsec2timew(time_t sec, long nsec)
|
||||
{
|
||||
struct timespec ts;
|
||||
time_overflow_p(&sec, &nsec);
|
||||
ts.tv_sec = sec;
|
||||
ts.tv_nsec = nsec;
|
||||
return timespec2timew(&ts);
|
||||
time_nsec_normalize(&sec, &nsec);
|
||||
return timenano2timew(sec, nsec);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -2465,27 +2465,8 @@ time_new_timew(VALUE klass, wideval_t timew)
|
|||
VALUE
|
||||
rb_time_new(time_t sec, long usec)
|
||||
{
|
||||
wideval_t timew;
|
||||
|
||||
if (usec >= 1000000) {
|
||||
long sec2 = usec / 1000000;
|
||||
if (sec > TIMET_MAX - sec2) {
|
||||
rb_raise(rb_eRangeError, "out of Time range");
|
||||
}
|
||||
usec -= sec2 * 1000000;
|
||||
sec += sec2;
|
||||
}
|
||||
else if (usec < 0) {
|
||||
long sec2 = NDIV(usec,1000000); /* negative div */
|
||||
if (sec < TIMET_MIN - sec2) {
|
||||
rb_raise(rb_eRangeError, "out of Time range");
|
||||
}
|
||||
usec -= sec2 * 1000000;
|
||||
sec += sec2;
|
||||
}
|
||||
|
||||
timew = nsec2timew(sec, usec * 1000);
|
||||
return time_new_timew(rb_cTime, timew);
|
||||
time_usec_normalize(&sec, &usec);
|
||||
return time_new_timew(rb_cTime, timenano2timew(sec, usec * 1000));
|
||||
}
|
||||
|
||||
/* returns localtime time object */
|
||||
|
|
Loading…
Reference in a new issue