[前][次][番号順一覧][スレッド一覧]

ruby-changes:65721

From: Nobuyoshi <ko1@a...>
Date: Thu, 1 Apr 2021 12:00:34 +0900 (JST)
Subject: [ruby-changes:65721] a5567350f7 (master): Refactored sub-seconds normalizations

https://git.ruby-lang.org/ruby.git/commit/?id=a5567350f7

From a5567350f706d6c72b2d4e0cdc95ceff80e87bbf Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Thu, 1 Apr 2021 12:00:10 +0900
Subject: Refactored sub-seconds normalizations

* separated argument to `timespec2timew` from `timespec` to seconds and
  nano-seconds.

* unified nano-seconds and micro-seconds normalizations.
---
 time.c | 61 +++++++++++++++++++++----------------------------------------
 1 file changed, 21 insertions(+), 40 deletions(-)

diff --git a/time.c b/time.c
index bfcce8e..e24bb5a 100644
--- a/time.c
+++ b/time.c
@@ -1844,13 +1844,13 @@ time_modify(VALUE time) https://github.com/ruby/ruby/blob/trunk/time.c#L1844
 }
 
 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) https://github.com/ruby/ruby/blob/trunk/time.c#L1918
     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 https://github.com/ruby/ruby/blob/trunk/time.c#L2409
 }
 
 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) https://github.com/ruby/ruby/blob/trunk/time.c#L2436
 	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) https://github.com/ruby/ruby/blob/trunk/time.c#L2465
 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 */
-- 
cgit v1.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]