aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2020-03-08 00:16:17 -0800
committerPaul Eggert2020-03-08 00:16:49 -0800
commit0a3682a566d5563e3d57defe49359cee236e0274 (patch)
tree8f92050411786fdaca5bd7476644c61bcba12377 /src
parentb16ba4041db928826df5f58e9bfac9fb38208145 (diff)
downloademacs-0a3682a566d5563e3d57defe49359cee236e0274.tar.gz
emacs-0a3682a566d5563e3d57defe49359cee236e0274.zip
* src/timefns.c: Add comments.
Diffstat (limited to 'src')
-rw-r--r--src/timefns.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/timefns.c b/src/timefns.c
index a08d3b816ff..8e2bb214ed8 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -491,11 +491,14 @@ timespec_mpz (struct timespec t)
491static Lisp_Object 491static Lisp_Object
492timespec_ticks (struct timespec t) 492timespec_ticks (struct timespec t)
493{ 493{
494 /* For speed, use intmax_t arithmetic if it will do. */
494 intmax_t accum; 495 intmax_t accum;
495 if (FASTER_TIMEFNS 496 if (FASTER_TIMEFNS
496 && !INT_MULTIPLY_WRAPV (t.tv_sec, TIMESPEC_HZ, &accum) 497 && !INT_MULTIPLY_WRAPV (t.tv_sec, TIMESPEC_HZ, &accum)
497 && !INT_ADD_WRAPV (t.tv_nsec, accum, &accum)) 498 && !INT_ADD_WRAPV (t.tv_nsec, accum, &accum))
498 return make_int (accum); 499 return make_int (accum);
500
501 /* Fall back on bignum arithmetic. */
499 timespec_mpz (t); 502 timespec_mpz (t);
500 return make_integer_mpz (); 503 return make_integer_mpz ();
501} 504}
@@ -505,12 +508,17 @@ timespec_ticks (struct timespec t)
505static Lisp_Object 508static Lisp_Object
506lisp_time_hz_ticks (struct lisp_time t, Lisp_Object hz) 509lisp_time_hz_ticks (struct lisp_time t, Lisp_Object hz)
507{ 510{
511 /* For speed, just return TICKS if T is (TICKS . HZ). */
508 if (FASTER_TIMEFNS && EQ (t.hz, hz)) 512 if (FASTER_TIMEFNS && EQ (t.hz, hz))
509 return t.ticks; 513 return t.ticks;
514
515 /* Check HZ for validity. */
510 if (FIXNUMP (hz)) 516 if (FIXNUMP (hz))
511 { 517 {
512 if (XFIXNUM (hz) <= 0) 518 if (XFIXNUM (hz) <= 0)
513 invalid_hz (hz); 519 invalid_hz (hz);
520
521 /* For speed, use intmax_t arithmetic if it will do. */
514 intmax_t ticks; 522 intmax_t ticks;
515 if (FASTER_TIMEFNS && FIXNUMP (t.ticks) && FIXNUMP (t.hz) 523 if (FASTER_TIMEFNS && FIXNUMP (t.ticks) && FIXNUMP (t.hz)
516 && !INT_MULTIPLY_WRAPV (XFIXNUM (t.ticks), XFIXNUM (hz), &ticks)) 524 && !INT_MULTIPLY_WRAPV (XFIXNUM (t.ticks), XFIXNUM (hz), &ticks))
@@ -520,6 +528,7 @@ lisp_time_hz_ticks (struct lisp_time t, Lisp_Object hz)
520 else if (! (BIGNUMP (hz) && 0 < mpz_sgn (*xbignum_val (hz)))) 528 else if (! (BIGNUMP (hz) && 0 < mpz_sgn (*xbignum_val (hz))))
521 invalid_hz (hz); 529 invalid_hz (hz);
522 530
531 /* Fall back on bignum arithmetic. */
523 mpz_mul (mpz[0], 532 mpz_mul (mpz[0],
524 *bignum_integer (&mpz[0], t.ticks), 533 *bignum_integer (&mpz[0], t.ticks),
525 *bignum_integer (&mpz[1], hz)); 534 *bignum_integer (&mpz[1], hz));
@@ -533,9 +542,13 @@ lisp_time_seconds (struct lisp_time t)
533{ 542{
534 if (!FASTER_TIMEFNS) 543 if (!FASTER_TIMEFNS)
535 return lisp_time_hz_ticks (t, make_fixnum (1)); 544 return lisp_time_hz_ticks (t, make_fixnum (1));
545
546 /* For speed, use EMACS_INT arithmetic if it will do. */
536 if (FIXNUMP (t.ticks) && FIXNUMP (t.hz)) 547 if (FIXNUMP (t.ticks) && FIXNUMP (t.hz))
537 return make_fixnum (XFIXNUM (t.ticks) / XFIXNUM (t.hz) 548 return make_fixnum (XFIXNUM (t.ticks) / XFIXNUM (t.hz)
538 - (XFIXNUM (t.ticks) % XFIXNUM (t.hz) < 0)); 549 - (XFIXNUM (t.ticks) % XFIXNUM (t.hz) < 0));
550
551 /* For speed, inline what lisp_time_hz_ticks would do. */
539 mpz_fdiv_q (mpz[0], 552 mpz_fdiv_q (mpz[0],
540 *bignum_integer (&mpz[0], t.ticks), 553 *bignum_integer (&mpz[0], t.ticks),
541 *bignum_integer (&mpz[1], t.hz)); 554 *bignum_integer (&mpz[1], t.hz));
@@ -1116,21 +1129,22 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
1116 (subtract ? mpz_submul : mpz_addmul) (*iticks, *fa, *nb); 1129 (subtract ? mpz_submul : mpz_addmul) (*iticks, *fa, *nb);
1117 1130
1118 /* Normalize iticks/ihz by dividing both numerator and 1131 /* Normalize iticks/ihz by dividing both numerator and
1119 denominator by ig = gcd (iticks, ihz). However, if that 1132 denominator by ig = gcd (iticks, ihz). For speed, though,
1120 would cause the denominator to become less than hzmin, 1133 skip this division if ihz = 1. */
1121 rescale the denominator upwards from its ordinary value by
1122 multiplying numerator and denominator so that the denominator
1123 becomes at least hzmin. This rescaling avoids returning a
1124 timestamp that is less precise than both a and b, or a
1125 timestamp that looks obsolete when that might be a problem. */
1126 mpz_t *ig = &mpz[3]; 1134 mpz_t *ig = &mpz[3];
1127 mpz_gcd (*ig, *iticks, *ihz); 1135 mpz_gcd (*ig, *iticks, *ihz);
1128
1129 if (!FASTER_TIMEFNS || mpz_cmp_ui (*ig, 1) > 0) 1136 if (!FASTER_TIMEFNS || mpz_cmp_ui (*ig, 1) > 0)
1130 { 1137 {
1131 mpz_divexact (*iticks, *iticks, *ig); 1138 mpz_divexact (*iticks, *iticks, *ig);
1132 mpz_divexact (*ihz, *ihz, *ig); 1139 mpz_divexact (*ihz, *ihz, *ig);
1133 1140
1141 /* However, if dividing the denominator by ig would cause the
1142 denominator to become less than hzmin, rescale the denominator
1143 upwards by multiplying the normalized numerator and denominator
1144 so that the resulting denominator becomes at least hzmin.
1145 This rescaling avoids returning a timestamp that is less precise
1146 than both a and b, or a timestamp that looks obsolete when that
1147 might be a problem. */
1134 if (!FASTER_TIMEFNS || mpz_cmp (*ihz, *hzmin) < 0) 1148 if (!FASTER_TIMEFNS || mpz_cmp (*ihz, *hzmin) < 0)
1135 { 1149 {
1136 /* Rescale straightforwardly. Although this might not 1150 /* Rescale straightforwardly. Although this might not
@@ -1144,6 +1158,8 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
1144 mpz_mul (*ihz, *ihz, *rescale); 1158 mpz_mul (*ihz, *ihz, *rescale);
1145 } 1159 }
1146 } 1160 }
1161
1162 /* mpz[0] and iticks now correspond to the (HZ . TICKS) pair. */
1147 hz = make_integer_mpz (); 1163 hz = make_integer_mpz ();
1148 mpz_swap (mpz[0], *iticks); 1164 mpz_swap (mpz[0], *iticks);
1149 ticks = make_integer_mpz (); 1165 ticks = make_integer_mpz ();