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>
61
time.c
61
time.c
@ -1844,13 +1844,13 @@ time_modify(VALUE time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static wideval_t
|
static wideval_t
|
||||||
timespec2timew(struct timespec *ts)
|
timenano2timew(time_t sec, long nsec)
|
||||||
{
|
{
|
||||||
wideval_t timew;
|
wideval_t timew;
|
||||||
|
|
||||||
timew = rb_time_magnify(TIMET2WV(ts->tv_sec));
|
timew = rb_time_magnify(TIMET2WV(sec));
|
||||||
if (ts->tv_nsec)
|
if (nsec)
|
||||||
timew = wadd(timew, wmulquoll(WINT2WV(ts->tv_nsec), TIME_SCALE, 1000000000));
|
timew = wadd(timew, wmulquoll(WINT2WV(nsec), TIME_SCALE, 1000000000));
|
||||||
return timew;
|
return timew;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1918,7 +1918,7 @@ time_init_now(rb_execution_context_t *ec, VALUE time, VALUE zone)
|
|||||||
tobj->tm_got=0;
|
tobj->tm_got=0;
|
||||||
tobj->timew = WINT2FIXWV(0);
|
tobj->timew = WINT2FIXWV(0);
|
||||||
rb_timespec_now(&ts);
|
rb_timespec_now(&ts);
|
||||||
tobj->timew = timespec2timew(&ts);
|
tobj->timew = timenano2timew(ts.tv_sec, ts.tv_nsec);
|
||||||
|
|
||||||
if (!NIL_P(zone)) {
|
if (!NIL_P(zone)) {
|
||||||
time_zonelocal(time, 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
|
static void
|
||||||
time_overflow_p(time_t *secp, long *nsecp)
|
subsec_normalize(time_t *secp, long *subsecp, const long maxsubsec)
|
||||||
{
|
{
|
||||||
time_t sec = *secp;
|
time_t sec = *secp;
|
||||||
long nsec = *nsecp;
|
long subsec = *subsecp;
|
||||||
long sec2;
|
long sec2;
|
||||||
|
|
||||||
if (nsec >= 1000000000) { /* nsec positive overflow */
|
if (UNLIKELY(subsec >= maxsubsec)) { /* subsec positive overflow */
|
||||||
sec2 = nsec / 1000000000;
|
sec2 = subsec / maxsubsec;
|
||||||
if (TIMET_MAX - sec2 < sec) {
|
if (TIMET_MAX - sec2 < sec) {
|
||||||
rb_raise(rb_eRangeError, "out of Time range");
|
rb_raise(rb_eRangeError, "out of Time range");
|
||||||
}
|
}
|
||||||
nsec -= sec2 * 1000000000;
|
subsec -= sec2 * maxsubsec;
|
||||||
sec += sec2;
|
sec += sec2;
|
||||||
}
|
}
|
||||||
else if (nsec < 0) { /* nsec negative overflow */
|
else if (UNLIKELY(subsec < 0)) { /* subsec negative overflow */
|
||||||
sec2 = NDIV(nsec,1000000000); /* negative div */
|
sec2 = NDIV(subsec, maxsubsec); /* negative div */
|
||||||
if (sec < TIMET_MIN - sec2) {
|
if (sec < TIMET_MIN - sec2) {
|
||||||
rb_raise(rb_eRangeError, "out of Time range");
|
rb_raise(rb_eRangeError, "out of Time range");
|
||||||
}
|
}
|
||||||
nsec -= sec2 * 1000000000;
|
subsec -= sec2 * maxsubsec;
|
||||||
sec += sec2;
|
sec += sec2;
|
||||||
}
|
}
|
||||||
#ifndef NEGATIVE_TIME_T
|
#ifndef NEGATIVE_TIME_T
|
||||||
@ -2436,17 +2436,17 @@ time_overflow_p(time_t *secp, long *nsecp)
|
|||||||
rb_raise(rb_eArgError, "time must be positive");
|
rb_raise(rb_eArgError, "time must be positive");
|
||||||
#endif
|
#endif
|
||||||
*secp = sec;
|
*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
|
static wideval_t
|
||||||
nsec2timew(time_t sec, long nsec)
|
nsec2timew(time_t sec, long nsec)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
time_nsec_normalize(&sec, &nsec);
|
||||||
time_overflow_p(&sec, &nsec);
|
return timenano2timew(sec, nsec);
|
||||||
ts.tv_sec = sec;
|
|
||||||
ts.tv_nsec = nsec;
|
|
||||||
return timespec2timew(&ts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -2465,27 +2465,8 @@ time_new_timew(VALUE klass, wideval_t timew)
|
|||||||
VALUE
|
VALUE
|
||||||
rb_time_new(time_t sec, long usec)
|
rb_time_new(time_t sec, long usec)
|
||||||
{
|
{
|
||||||
wideval_t timew;
|
time_usec_normalize(&sec, &usec);
|
||||||
|
return time_new_timew(rb_cTime, timenano2timew(sec, usec * 1000));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns localtime time object */
|
/* returns localtime time object */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user