- (let ((time-base (ash 1 16)))
- ;; Use floating point, taking care to not lose precision.
- (let* ((float-time-base (float time-base))
- (million 1000000.0)
- (time-usec (+ (* million
- (+ (* float-time-base (nth 0 time))
- (nth 1 time)))
- (nth 2 time)))
- (secs-usec (* million secs))
- (mod-usec (mod time-usec secs-usec))
- (next-usec (+ (- time-usec mod-usec) secs-usec))
- (time-base-million (* float-time-base million)))
- (list (floor next-usec time-base-million)
- (floor (mod next-usec time-base-million) million)
- (floor (mod next-usec million))))))
-
-(defun timer-relative-time (time secs &optional usecs)
- "Advance TIME by SECS seconds and optionally USECS microseconds.
-SECS may be either an integer or a floating point number."
+ (let* ((trillion 1e12)
+ (time-sec (+ (nth 1 time)
+ (* 65536.0 (nth 0 time))))
+ (delta-sec (mod (- time-sec) secs))
+ (next-sec (+ time-sec (ffloor delta-sec)))
+ (next-sec-psec (ffloor (* trillion (mod delta-sec 1))))
+ (sub-time-psec (+ (or (nth 3 time) 0)
+ (* 1e6 (nth 2 time))))
+ (psec-diff (- sub-time-psec next-sec-psec)))
+ (if (and (<= next-sec time-sec) (< 0 psec-diff))
+ (setq next-sec-psec (+ sub-time-psec
+ (mod (- psec-diff) (* trillion secs)))))
+ (setq next-sec (+ next-sec (floor next-sec-psec trillion)))
+ (setq next-sec-psec (mod next-sec-psec trillion))
+ (list (floor next-sec 65536)
+ (floor (mod next-sec 65536))
+ (floor next-sec-psec 1000000)
+ (floor (mod next-sec-psec 1000000)))))
+
+(defun timer-relative-time (time secs &optional usecs psecs)
+ "Advance TIME by SECS seconds and optionally USECS nanoseconds
+and PSECS picoseconds. SECS may be either an integer or a
+floating point number."