mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-30 04:10:54 -08:00
Merge from origin/emacs-27
0a3682a566* src/timefns.c: Add comments.b16ba4041d; lisp/emacs-lisp/seq.el: Explain why we don't use cl-lib ...3cbf4cb796Eliminate use of cl-concatenate in 'seq' package363d927086Fix bug with JIT stealth timers818333c85a* doc/lispref/os.texi (time-subtract): Doc fix.
This commit is contained in:
commit
4415534ef0
5 changed files with 37 additions and 18 deletions
|
|
@ -1979,10 +1979,9 @@ The result is @code{nil} if either argument is a NaN.
|
|||
|
||||
@defun time-subtract t1 t2
|
||||
This returns the time difference @var{t1} @minus{} @var{t2} between
|
||||
two time values, normally as a Lisp timestamp but as a float
|
||||
if either argument is infinite or a NaN@.
|
||||
When the result is a timestamp, it is exact and its clock
|
||||
two time values, as a Lisp time value. The result is exact and its clock
|
||||
resolution is no worse than the worse of its two arguments' resolutions.
|
||||
The result is floating-point only if it is infinite or a NaN.
|
||||
If you need the difference in units
|
||||
of elapsed seconds, you can convert it with @code{time-convert} or
|
||||
@code{float-time}. @xref{Time Conversion}.
|
||||
|
|
|
|||
|
|
@ -556,11 +556,7 @@ too large if positive or too small if negative)."
|
|||
(defun cl-concatenate (type &rest sequences)
|
||||
"Concatenate, into a sequence of type TYPE, the argument SEQUENCEs.
|
||||
\n(fn TYPE SEQUENCE...)"
|
||||
(pcase type
|
||||
('vector (apply #'vconcat sequences))
|
||||
('string (apply #'concat sequences))
|
||||
('list (apply #'append (append sequences '(nil))))
|
||||
(_ (error "Not a sequence type name: %S" type))))
|
||||
(seq-concatenate type sequences))
|
||||
|
||||
;;; List functions.
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,10 @@
|
|||
|
||||
(eval-when-compile (require 'cl-generic))
|
||||
|
||||
;; We used to use some sequence functions from cl-lib, but this
|
||||
;; dependency was swapped around so that it will be easier to make
|
||||
;; seq.el preloaded in the future. See also Bug#39761#26.
|
||||
|
||||
(defmacro seq-doseq (spec &rest body)
|
||||
"Loop over a sequence.
|
||||
Evaluate BODY with VAR bound to each element of SEQUENCE, in turn.
|
||||
|
|
@ -285,7 +289,11 @@ sorted. FUNCTION must be a function of one argument."
|
|||
TYPE must be one of following symbols: vector, string or list.
|
||||
|
||||
\n(fn TYPE SEQUENCE...)"
|
||||
(apply #'cl-concatenate type (seq-map #'seq-into-sequence sequences)))
|
||||
(pcase type
|
||||
('vector (apply #'vconcat sequences))
|
||||
('string (apply #'concat sequences))
|
||||
('list (apply #'append (append sequences '(nil))))
|
||||
(_ (error "Not a sequence type name: %S" type))))
|
||||
|
||||
(cl-defgeneric seq-into-sequence (sequence)
|
||||
"Convert SEQUENCE into a sequence.
|
||||
|
|
|
|||
|
|
@ -378,7 +378,7 @@ This function returns a timer object which you can use in
|
|||
(decoded-time-year now)
|
||||
(decoded-time-zone now)))))))
|
||||
|
||||
(or (consp time)
|
||||
(or (time-equal-p time time)
|
||||
(error "Invalid time format"))
|
||||
|
||||
(let ((timer (timer-create)))
|
||||
|
|
|
|||
|
|
@ -491,11 +491,14 @@ timespec_mpz (struct timespec t)
|
|||
static Lisp_Object
|
||||
timespec_ticks (struct timespec t)
|
||||
{
|
||||
/* For speed, use intmax_t arithmetic if it will do. */
|
||||
intmax_t accum;
|
||||
if (FASTER_TIMEFNS
|
||||
&& !INT_MULTIPLY_WRAPV (t.tv_sec, TIMESPEC_HZ, &accum)
|
||||
&& !INT_ADD_WRAPV (t.tv_nsec, accum, &accum))
|
||||
return make_int (accum);
|
||||
|
||||
/* Fall back on bignum arithmetic. */
|
||||
timespec_mpz (t);
|
||||
return make_integer_mpz ();
|
||||
}
|
||||
|
|
@ -505,12 +508,17 @@ timespec_ticks (struct timespec t)
|
|||
static Lisp_Object
|
||||
lisp_time_hz_ticks (struct lisp_time t, Lisp_Object hz)
|
||||
{
|
||||
/* For speed, just return TICKS if T is (TICKS . HZ). */
|
||||
if (FASTER_TIMEFNS && EQ (t.hz, hz))
|
||||
return t.ticks;
|
||||
|
||||
/* Check HZ for validity. */
|
||||
if (FIXNUMP (hz))
|
||||
{
|
||||
if (XFIXNUM (hz) <= 0)
|
||||
invalid_hz (hz);
|
||||
|
||||
/* For speed, use intmax_t arithmetic if it will do. */
|
||||
intmax_t ticks;
|
||||
if (FASTER_TIMEFNS && FIXNUMP (t.ticks) && FIXNUMP (t.hz)
|
||||
&& !INT_MULTIPLY_WRAPV (XFIXNUM (t.ticks), XFIXNUM (hz), &ticks))
|
||||
|
|
@ -520,6 +528,7 @@ lisp_time_hz_ticks (struct lisp_time t, Lisp_Object hz)
|
|||
else if (! (BIGNUMP (hz) && 0 < mpz_sgn (*xbignum_val (hz))))
|
||||
invalid_hz (hz);
|
||||
|
||||
/* Fall back on bignum arithmetic. */
|
||||
mpz_mul (mpz[0],
|
||||
*bignum_integer (&mpz[0], t.ticks),
|
||||
*bignum_integer (&mpz[1], hz));
|
||||
|
|
@ -533,9 +542,13 @@ lisp_time_seconds (struct lisp_time t)
|
|||
{
|
||||
if (!FASTER_TIMEFNS)
|
||||
return lisp_time_hz_ticks (t, make_fixnum (1));
|
||||
|
||||
/* For speed, use EMACS_INT arithmetic if it will do. */
|
||||
if (FIXNUMP (t.ticks) && FIXNUMP (t.hz))
|
||||
return make_fixnum (XFIXNUM (t.ticks) / XFIXNUM (t.hz)
|
||||
- (XFIXNUM (t.ticks) % XFIXNUM (t.hz) < 0));
|
||||
|
||||
/* For speed, inline what lisp_time_hz_ticks would do. */
|
||||
mpz_fdiv_q (mpz[0],
|
||||
*bignum_integer (&mpz[0], t.ticks),
|
||||
*bignum_integer (&mpz[1], t.hz));
|
||||
|
|
@ -1122,21 +1135,22 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
|
|||
(subtract ? mpz_submul : mpz_addmul) (*iticks, *fa, *nb);
|
||||
|
||||
/* Normalize iticks/ihz by dividing both numerator and
|
||||
denominator by ig = gcd (iticks, ihz). However, if that
|
||||
would cause the denominator to become less than hzmin,
|
||||
rescale the denominator upwards from its ordinary value by
|
||||
multiplying numerator and denominator so that the denominator
|
||||
becomes at least hzmin. This rescaling avoids returning a
|
||||
timestamp that is less precise than both a and b, or a
|
||||
timestamp that looks obsolete when that might be a problem. */
|
||||
denominator by ig = gcd (iticks, ihz). For speed, though,
|
||||
skip this division if ihz = 1. */
|
||||
mpz_t *ig = &mpz[3];
|
||||
mpz_gcd (*ig, *iticks, *ihz);
|
||||
|
||||
if (!FASTER_TIMEFNS || mpz_cmp_ui (*ig, 1) > 0)
|
||||
{
|
||||
mpz_divexact (*iticks, *iticks, *ig);
|
||||
mpz_divexact (*ihz, *ihz, *ig);
|
||||
|
||||
/* However, if dividing the denominator by ig would cause the
|
||||
denominator to become less than hzmin, rescale the denominator
|
||||
upwards by multiplying the normalized numerator and denominator
|
||||
so that the resulting denominator becomes at least hzmin.
|
||||
This rescaling avoids returning a timestamp that is less precise
|
||||
than both a and b, or a timestamp that looks obsolete when that
|
||||
might be a problem. */
|
||||
if (!FASTER_TIMEFNS || mpz_cmp (*ihz, *hzmin) < 0)
|
||||
{
|
||||
/* Rescale straightforwardly. Although this might not
|
||||
|
|
@ -1150,6 +1164,8 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
|
|||
mpz_mul (*ihz, *ihz, *rescale);
|
||||
}
|
||||
}
|
||||
|
||||
/* mpz[0] and iticks now correspond to the (HZ . TICKS) pair. */
|
||||
hz = make_integer_mpz ();
|
||||
mpz_swap (mpz[0], *iticks);
|
||||
ticks = make_integer_mpz ();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue