aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2012-06-22 14:17:42 -0700
committerPaul Eggert2012-06-22 14:17:42 -0700
commitd35af63cd671563fd188c3b0a1ef30067027c7aa (patch)
treec9e01847ccf788e23794684da9331c3e0defd0d3 /src
parentf143bfe38b43ad0a9d817f05c25e418982dca06f (diff)
downloademacs-d35af63cd671563fd188c3b0a1ef30067027c7aa.tar.gz
emacs-d35af63cd671563fd188c3b0a1ef30067027c7aa.zip
Support higher-resolution time stamps.
Fixes: debbugs:9000
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog169
-rw-r--r--src/Makefile.in4
-rw-r--r--src/alloc.c12
-rw-r--r--src/atimer.c22
-rw-r--r--src/buffer.c8
-rw-r--r--src/buffer.h12
-rw-r--r--src/dired.c11
-rw-r--r--src/dispextern.h6
-rw-r--r--src/dispnew.c130
-rw-r--r--src/editfns.c290
-rw-r--r--src/fileio.c79
-rw-r--r--src/fns.c2
-rw-r--r--src/gtkutil.c12
-rw-r--r--src/image.c17
-rw-r--r--src/keyboard.c188
-rw-r--r--src/lisp.h3
-rw-r--r--src/lread.c10
-rw-r--r--src/msdos.c11
-rw-r--r--src/nsterm.h3
-rw-r--r--src/nsterm.m75
-rw-r--r--src/process.c222
-rw-r--r--src/process.h4
-rw-r--r--src/sysdep.c227
-rw-r--r--src/sysselect.h3
-rw-r--r--src/systime.h159
-rw-r--r--src/term.c20
-rw-r--r--src/undo.c23
-rw-r--r--src/w32.c45
-rw-r--r--src/xdisp.c18
-rw-r--r--src/xgselect.c23
-rw-r--r--src/xgselect.h4
-rw-r--r--src/xmenu.c8
-rw-r--r--src/xselect.c22
-rw-r--r--src/xterm.c73
34 files changed, 962 insertions, 953 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index a5e10fe9473..65424205f34 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,172 @@
12012-06-22 Paul Eggert <eggert@cs.ucla.edu>
2
3 Support higher-resolution time stamps (Bug#9000).
4 The time stamps are only nanosecond-resolution at the C level,
5 since that's the best that any real-world system supports now.
6 But they are picosecond-resolution at the Lisp level, as that's
7 easy, and leaves room for future OS improvements.
8
9 * Makefile.in (LIB_CLOCK_GETTIME): New macro.
10 (LIBES): Use it.
11
12 * alloc.c (Fgarbage_collect): Port to higher-res time stamps.
13 Don't get current time unless it's needed.
14
15 * atimer.c: Include <sys/time.h> unconditionally, since gnulib
16 now provides it if it's absent.
17 (start_atimer): Port to higher-res time stamps.
18 Check for time stamp overflow. Don't get current time more
19 often than is needed.
20
21 * buffer.h (struct buffer): Buffer modtime now has high resolution.
22 Include systime.h, not time.h.
23 (NONEXISTENT_MODTIME_NSECS, UNKNOWN_MODTIME_NSECS): New macros.
24
25 * dired.c: Include stat-time.h.
26 (Ffile-attributes): File times now have higher resolution.
27
28 * dispextern.h [HAVE_WINDOW_SYSTEM]: Include systime.h.
29 (struct image): Timestamp now has higher resolution.
30
31 * dispnew.c (PERIODIC_PREEMPTION_CHECKING): Remove, as Emacs always
32 has at least microseconds now. All uses removed.
33 (update_frame, update_single_window, update_window, update_frame_1)
34 (Fsleep_for, sit_for): Port to higher-resolution time stamps.
35
36 * editfns.c (time_overflow): Now extern.
37 (Fcurrent_time, Fget_internal_run_time, make_time, lisp_time_argument)
38 (float-time, Fformat_time_string, Fcurrent_time_string)
39 (Fcurrent_time_zone): Accept and generate higher-resolution
40 time stamps.
41 (make_time_tail, make_lisp_time, dissassemble_lisp_time)
42 (decode_time_components, lisp_seconds_argument): New functions.
43 (make_time): Now static.
44 (lisp_time_argument): Now returns EMACS_TIME. New arg ppsec.
45 Report an error if the time is invalid, rather than having the caller
46 do that.
47
48 * fileio.c: Include <stat-time.h>
49 (Fcopy_file): Copy higher-resolution time stamps.
50 Prefer to set the time stamp via a file descriptor if that works.
51 (Fset_file_times, Finsert_file_contents, Fwrite_region)
52 (Fverify_visited_file_modtime, Fclear_visited_file_modtime)
53 (Fvisited_file_modtime, Fset_visited_file_modtime):
54 Support higher-resolution time stamps.
55
56 * fns.c (Frandom): Use nanoseconds, not microseconds, for seed.
57
58 * gtkutil.c (xg_maybe_add_timer): Port to higher-res time stamps.
59
60 * image.c (prepare_image_for_display, clear_image_cache)
61 (lookup_image): Port to higer-resolution time stamps.
62
63 * keyboard.c (start_polling, bind_polling_period):
64 Check for time stamp overflow.
65 (read_char, kbd_buffer_get_event, timer_start_idle)
66 (timer_stop_idle, timer_resume_idle, timer_check_2, timer_check)
67 (Fcurrent_idle_time, init_keyboard, set_waiting_for_input):
68 Port to higher-resolution time stamps. Do not assume time_t is signed.
69 (decode_timer): New function. Timers are now vectors of length 9,
70 not 8, to accommodate the picosecond component.
71 (timer_check_2): Use it.
72
73 * nsterm.m (select_timeout, timeval_subtract): Remove.
74 (ns_timeout): Use Emacs's facilities for time stamp arithmetic,
75 as they're a bit more accurate and handle overflow better.
76 (ns_select): Change prototype to be compatible with pselect.
77 (ns_select, ns_term_shutdown): Port to ns-resolution time stamps.
78 * nsterm.h (ns_select): Adjust prototype.
79
80 * msdos.c (EMACS_TIME_ZERO_OR_NEG_P): Remove, as it assumes
81 us-resolution time stamps.
82 (sys_select): Use the new EMACS_TIME_SIGN macro instead.
83
84 * lread.c (read_filtered_event): Port to ns-resolution time stamps.
85
86 * lisp.h (time_overflow): New decl.
87 (wait_reading_process_output): First arg is now intmax_t, not int,
88 to accommodate larger waits.
89
90 * process.h (struct Lisp_Process.read_output_delay):
91 Now counts nanoseconds, not microseconds.
92 * process.c (ADAPTIVE_READ_BUFFERING): Don't worry about
93 EMACS_HAS_USECS.
94 (READ_OUTPUT_DELAY_INCREMENT, Faccept_process_output)
95 (wait_reading_process_output):
96 Port to ns-resolution time stamps.
97 (Faccept_process_output, wait_reading_process_output):
98 Check for time stamp overflow. Do not assume time_t is signed.
99 (select_wrapper): Remove; we now use pselect.
100 (Fprocess_attributes): Now generates ns-resolution time stamps.
101
102 * sysdep.c: Include utimens.h. Don't include utime.h
103 or worry about struct utimbuf; gnulib does that for us now.
104 (gettimeofday): Remove; gnulib provides a substitute.
105 (make_timeval): New function.
106 (set_file_times): Now sets ns-resolution time stamps.
107 New arg FD; all uses changed.
108 (time_from_jiffies, ltime_from_jiffies, get_up_time)
109 (system_process_attributes):
110 Now returns ns-resolution time stamp. All uses changed.
111 Check for time stamp overflow.
112
113 * sysselect.h: Don't depend on HAVE_SYS_SELECT_H; gnulib
114 provides a substitute now.
115
116 * systime.h: Include timespec.h rather than sys/time.h and time.h,
117 since it guarantees struct timespec.
118 (EMACS_TIME): Now struct timespec, so that we can support
119 ns-resolution time stamps.
120 (EMACS_TIME_RESOLUTION, LOG10_EMACS_TIME_RESOLUTION): New macros.
121 (EMACS_HAS_USECS): Remove; Emacs always has sub-second time stamps now.
122 (EMACS_USECS): Remove.
123 (EMACS_SET_USECS): The underlying time stamp now has ns resolution,
124 so multiply the arg by 1000 before storing it.
125 (EMACS_NSECS, EMACS_SECS_ADDR, EMACS_SET_NSECS, EMACS_SET_SECS_NSECS):
126 New macros.
127 (EMACS_GET_TIME, EMACS_ADD_TIME, EMACS_SUB_TIME):
128 Port to ns-resolution time stamps.
129 (EMACS_TIME_NEG_P): Remove; replaced by....
130 (EMACS_TIME_SIGN): New macro.
131 (EMACS_SET_INVALID_TIME, EMACS_TIME_VALID_P)
132 (EMACS_TIME_FROM_DOUBLE, EMACS_TIME_TO_DOUBLE): New macros.
133 (set_file_times, make_time, lisp_time_argument): Adjust signature.
134 (make_timeval, make_lisp_time, decode_time_components): New decls.
135 (EMACS_TIME_CMP): Remove; no longer used. Plus, it was buggy, in
136 that it mishandled time_t overflow. You can't compare by subtracting!
137 (EMACS_TIME_EQ, EMACS_TIME_NE, EMACS_TIME_GT, EMACS_TIME_GE)
138 (EMACS_TIME_LT, EMACS_TIME_LE): Rewrite in terms of timespec_cmp.
139
140 * term.c: Include <sys/time.h>.
141 (timeval_to_Time): New function, for proper overflow wraparound.
142 (term_mouse_position, term_mouse_click): Use it.
143
144 * undo.c (record_first_change): Support higher-resolution time stamps
145 in the undo buffer.
146 (Fprimitive_undo): Use them when restoring time stamps.
147
148 * w32.c (ltime, U64_TO_LISP_TIME, process_times, emacs_gnutls_pull)
149 (w32_get_internal_run_time):
150 Port to higher-resolution Emacs time stamps.
151 (ltime): Now accepts single 64-bit integer, as that's more convenient
152 for callers.
153
154 * xdisp.c (start_hourglass): Port to ns-resolution time stamps.
155
156 * xgselect.c, xgselect.h (xg_select): Add sigmask argument,
157 for compatibility with pselect. Support ns-resolution time stamps.
158
159 * xmenu.c (x_menu_wait_for_event): Support ns-resolution time stamps.
160
161 * xselect.c (wait_for_property_change, x_get_foreign_selection):
162 Check for time stamp overflow, and support ns-resolution time stamps.
163
164 * xterm.c: Don't include sys/time.h; gnulib does that for us now.
165 Don't worry about whether HAVE_TIMEVAL and HAVE_SELECT are set.
166 (timeval_subtract): Remove; no longer needed.
167 (XTflash, XTring_bell, x_wait_for_event):
168 Port to ns-resolution time stamps. Don't assume time_t is signed.
169
12012-06-22 Chong Yidong <cyd@gnu.org> 1702012-06-22 Chong Yidong <cyd@gnu.org>
2 171
3 * xdisp.c (x_consider_frame_title): Revert last change. 172 * xdisp.c (x_consider_frame_title): Revert last change.
diff --git a/src/Makefile.in b/src/Makefile.in
index 47c7d5cfbc2..40cfe94c707 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -153,6 +153,8 @@ LIBOTF_LIBS = @LIBOTF_LIBS@
153M17N_FLT_CFLAGS = @M17N_FLT_CFLAGS@ 153M17N_FLT_CFLAGS = @M17N_FLT_CFLAGS@
154M17N_FLT_LIBS = @M17N_FLT_LIBS@ 154M17N_FLT_LIBS = @M17N_FLT_LIBS@
155 155
156LIB_CLOCK_GETTIME=@LIB_CLOCK_GETTIME@
157
156DBUS_CFLAGS = @DBUS_CFLAGS@ 158DBUS_CFLAGS = @DBUS_CFLAGS@
157DBUS_LIBS = @DBUS_LIBS@ 159DBUS_LIBS = @DBUS_LIBS@
158## dbusbind.o if HAVE_DBUS, else empty. 160## dbusbind.o if HAVE_DBUS, else empty.
@@ -384,7 +386,7 @@ otherobj= $(TERMCAP_OBJ) $(PRE_ALLOC_OBJ) $(GMALLOC_OBJ) $(RALLOC_OBJ) \
384## duplicated symbols. If the standard libraries were compiled 386## duplicated symbols. If the standard libraries were compiled
385## with GCC, we might need LIB_GCC again after them. 387## with GCC, we might need LIB_GCC again after them.
386LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \ 388LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \
387 $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(DBUS_LIBS) \ 389 $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) $(DBUS_LIBS) \
388 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ 390 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
389 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ 391 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
390 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ 392 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
diff --git a/src/alloc.c b/src/alloc.c
index aba76386dd6..490632f282f 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -5669,12 +5669,14 @@ See Info node `(elisp)Garbage Collection'. */)
5669 } 5669 }
5670 5670
5671 /* Accumulate statistics. */ 5671 /* Accumulate statistics. */
5672 EMACS_GET_TIME (t2);
5673 EMACS_SUB_TIME (t3, t2, t1);
5674 if (FLOATP (Vgc_elapsed)) 5672 if (FLOATP (Vgc_elapsed))
5675 Vgc_elapsed = make_float (XFLOAT_DATA (Vgc_elapsed) + 5673 {
5676 EMACS_SECS (t3) + 5674 EMACS_GET_TIME (t2);
5677 EMACS_USECS (t3) * 1.0e-6); 5675 EMACS_SUB_TIME (t3, t2, t1);
5676 Vgc_elapsed = make_float (XFLOAT_DATA (Vgc_elapsed)
5677 + EMACS_TIME_TO_DOUBLE (t3));
5678 }
5679
5678 gcs_done++; 5680 gcs_done++;
5679 5681
5680 return Flist (sizeof total / sizeof *total, total); 5682 return Flist (sizeof total / sizeof *total, total);
diff --git a/src/atimer.c b/src/atimer.c
index 48f22fe0e3e..e72bc305753 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -26,10 +26,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26#include "blockinput.h" 26#include "blockinput.h"
27#include "atimer.h" 27#include "atimer.h"
28#include <unistd.h> 28#include <unistd.h>
29
30#ifdef HAVE_SYS_TIME_H
31#include <sys/time.h> 29#include <sys/time.h>
32#endif
33 30
34/* Free-list of atimer structures. */ 31/* Free-list of atimer structures. */
35 32
@@ -94,7 +91,8 @@ start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn,
94 /* Round TIME up to the next full second if we don't have 91 /* Round TIME up to the next full second if we don't have
95 itimers. */ 92 itimers. */
96#ifndef HAVE_SETITIMER 93#ifndef HAVE_SETITIMER
97 if (EMACS_USECS (timestamp) != 0) 94 if (EMACS_NSECS (timestamp) != 0
95 && EMACS_SECS (timestamp) < TYPE_MAXIMUM (time_t))
98 { 96 {
99 EMACS_SET_USECS (timestamp, 0); 97 EMACS_SET_USECS (timestamp, 0);
100 EMACS_SET_SECS (timestamp, EMACS_SECS (timestamp) + 1); 98 EMACS_SET_SECS (timestamp, EMACS_SECS (timestamp) + 1);
@@ -294,18 +292,21 @@ set_alarm (void)
294 292
295 /* Determine s/us till the next timer is ripe. */ 293 /* Determine s/us till the next timer is ripe. */
296 EMACS_GET_TIME (now); 294 EMACS_GET_TIME (now);
297 EMACS_SUB_TIME (timestamp, atimers->expiration, now);
298 295
299#ifdef HAVE_SETITIMER
300 /* Don't set the interval to 0; this disables the timer. */ 296 /* Don't set the interval to 0; this disables the timer. */
301 if (EMACS_TIME_LE (atimers->expiration, now)) 297 if (EMACS_TIME_LE (atimers->expiration, now))
302 { 298 {
303 EMACS_SET_SECS (timestamp, 0); 299 EMACS_SET_SECS (timestamp, 0);
304 EMACS_SET_USECS (timestamp, 1000); 300 EMACS_SET_USECS (timestamp, 1000);
305 } 301 }
302 else
303 EMACS_SUB_TIME (timestamp, atimers->expiration, now);
304
305
306#ifdef HAVE_SETITIMER
306 307
307 memset (&it, 0, sizeof it); 308 memset (&it, 0, sizeof it);
308 it.it_value = timestamp; 309 it.it_value = make_timeval (timestamp);
309 setitimer (ITIMER_REAL, &it, 0); 310 setitimer (ITIMER_REAL, &it, 0);
310#else /* not HAVE_SETITIMER */ 311#else /* not HAVE_SETITIMER */
311 alarm (max (EMACS_SECS (timestamp), 1)); 312 alarm (max (EMACS_SECS (timestamp), 1));
@@ -341,11 +342,10 @@ run_timers (void)
341{ 342{
342 EMACS_TIME now; 343 EMACS_TIME now;
343 344
344 EMACS_GET_TIME (now);
345
346 while (atimers 345 while (atimers
347 && (pending_atimers = interrupt_input_blocked) == 0 346 && (pending_atimers = interrupt_input_blocked) == 0
348 && EMACS_TIME_LE (atimers->expiration, now)) 347 && (EMACS_GET_TIME (now),
348 EMACS_TIME_LE (atimers->expiration, now)))
349 { 349 {
350 struct atimer *t; 350 struct atimer *t;
351 351
@@ -363,8 +363,6 @@ run_timers (void)
363 t->next = free_atimers; 363 t->next = free_atimers;
364 free_atimers = t; 364 free_atimers = t;
365 } 365 }
366
367 EMACS_GET_TIME (now);
368 } 366 }
369 367
370 if (! atimers) 368 if (! atimers)
diff --git a/src/buffer.c b/src/buffer.c
index e501c9b73cc..89a4e26fb73 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -709,7 +709,7 @@ reset_buffer (register struct buffer *b)
709 BVAR (b, filename) = Qnil; 709 BVAR (b, filename) = Qnil;
710 BVAR (b, file_truename) = Qnil; 710 BVAR (b, file_truename) = Qnil;
711 BVAR (b, directory) = (current_buffer) ? BVAR (current_buffer, directory) : Qnil; 711 BVAR (b, directory) = (current_buffer) ? BVAR (current_buffer, directory) : Qnil;
712 b->modtime = 0; 712 EMACS_SET_SECS_NSECS (b->modtime, 0, UNKNOWN_MODTIME_NSECS);
713 b->modtime_size = -1; 713 b->modtime_size = -1;
714 XSETFASTINT (BVAR (b, save_length), 0); 714 XSETFASTINT (BVAR (b, save_length), 0);
715 b->last_window_start = 1; 715 b->last_window_start = 1;
@@ -5834,9 +5834,9 @@ An entry (TEXT . POSITION) represents the deletion of the string TEXT
5834from (abs POSITION). If POSITION is positive, point was at the front 5834from (abs POSITION). If POSITION is positive, point was at the front
5835of the text being deleted; if negative, point was at the end. 5835of the text being deleted; if negative, point was at the end.
5836 5836
5837An entry (t HIGH . LOW) indicates that the buffer previously had 5837An entry (t HIGH LOW USEC PSEC) indicates that the buffer was previously
5838\"unmodified\" status. HIGH and LOW are the high and low 16-bit portions 5838unmodified; (HIGH LOW USEC PSEC) is in the same style as (current-time)
5839of the visited file's modification time, as of that time. If the 5839and is the visited file's modification time, as of that time. If the
5840modification time of the most recent save is different, this entry is 5840modification time of the most recent save is different, this entry is
5841obsolete. 5841obsolete.
5842 5842
diff --git a/src/buffer.h b/src/buffer.h
index 8e0604e90c2..97b45e15387 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -19,6 +19,7 @@ You should have received a copy of the GNU General Public License
19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21#include <sys/types.h> /* for off_t, time_t */ 21#include <sys/types.h> /* for off_t, time_t */
22#include "systime.h" /* for EMACS_TIME */
22 23
23/* Accessing the parameters of the current buffer. */ 24/* Accessing the parameters of the current buffer. */
24 25
@@ -529,10 +530,13 @@ struct buffer
529 char local_flags[MAX_PER_BUFFER_VARS]; 530 char local_flags[MAX_PER_BUFFER_VARS];
530 531
531 /* Set to the modtime of the visited file when read or written. 532 /* Set to the modtime of the visited file when read or written.
532 -1 means visited file was nonexistent. 533 EMACS_NSECS (modtime) == NONEXISTENT_MODTIME_NSECS means
533 0 means visited file modtime unknown; in no case complain 534 visited file was nonexistent. EMACS_NSECS (modtime) ==
534 about any mismatch on next save attempt. */ 535 UNKNOWN_MODTIME_NSECS means visited file modtime unknown;
535 time_t modtime; 536 in no case complain about any mismatch on next save attempt. */
537#define NONEXISTENT_MODTIME_NSECS (-1)
538#define UNKNOWN_MODTIME_NSECS (-2)
539 EMACS_TIME modtime;
536 /* Size of the file when modtime was set. This is used to detect the 540 /* Size of the file when modtime was set. This is used to detect the
537 case where the file grew while we were reading it, so the modtime 541 case where the file grew while we were reading it, so the modtime
538 is still the same (since it's rounded up to seconds) but we're actually 542 is still the same (since it's rounded up to seconds) but we're actually
diff --git a/src/dired.c b/src/dired.c
index 1ce236d5674..b319072aa33 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -62,6 +62,7 @@ extern struct direct *readdir (DIR *);
62#endif /* HAVE_DIRENT_H */ 62#endif /* HAVE_DIRENT_H */
63 63
64#include <filemode.h> 64#include <filemode.h>
65#include <stat-time.h>
65 66
66#ifdef MSDOS 67#ifdef MSDOS
67#define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0) 68#define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0)
@@ -893,8 +894,8 @@ Elements of the attribute list are:
893 2. File uid as a string or a number. If a string value cannot be 894 2. File uid as a string or a number. If a string value cannot be
894 looked up, a numeric value, either an integer or a float, is returned. 895 looked up, a numeric value, either an integer or a float, is returned.
895 3. File gid, likewise. 896 3. File gid, likewise.
896 4. Last access time, as a list of two integers. 897 4. Last access time, as a list of integers (HIGH LOW USEC PSEC) in the
897 First integer has high-order 16 bits of time, second has low 16 bits. 898 same style as (current-time).
898 (See a note below about access time on FAT-based filesystems.) 899 (See a note below about access time on FAT-based filesystems.)
899 5. Last modification time, likewise. This is the time of the last 900 5. Last modification time, likewise. This is the time of the last
900 change to the file's contents. 901 change to the file's contents.
@@ -979,9 +980,9 @@ so last access time will always be midnight of that day. */)
979 else 980 else
980 values[3] = make_fixnum_or_float (s.st_gid); 981 values[3] = make_fixnum_or_float (s.st_gid);
981 982
982 values[4] = make_time (s.st_atime); 983 values[4] = make_lisp_time (get_stat_atime (&s));
983 values[5] = make_time (s.st_mtime); 984 values[5] = make_lisp_time (get_stat_mtime (&s));
984 values[6] = make_time (s.st_ctime); 985 values[6] = make_lisp_time (get_stat_ctime (&s));
985 986
986 /* If the file size is a 4-byte type, assume that files of sizes in 987 /* If the file size is a 4-byte type, assume that files of sizes in
987 the 2-4 GiB range wrap around to negative values, as this is a 988 the 2-4 GiB range wrap around to negative values, as this is a
diff --git a/src/dispextern.h b/src/dispextern.h
index fc7bec97f7a..63c23b8962f 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -68,6 +68,10 @@ typedef Pixmap XImagePtr;
68typedef XImagePtr XImagePtr_or_DC; 68typedef XImagePtr XImagePtr_or_DC;
69#endif 69#endif
70 70
71#ifdef HAVE_WINDOW_SYSTEM
72# include "systime.h"
73#endif
74
71#ifndef HAVE_WINDOW_SYSTEM 75#ifndef HAVE_WINDOW_SYSTEM
72typedef int Cursor; 76typedef int Cursor;
73#define No_Cursor (0) 77#define No_Cursor (0)
@@ -2780,7 +2784,7 @@ struct image
2780{ 2784{
2781 /* The time in seconds at which the image was last displayed. Set 2785 /* The time in seconds at which the image was last displayed. Set
2782 in prepare_image_for_display. */ 2786 in prepare_image_for_display. */
2783 time_t timestamp; 2787 EMACS_TIME timestamp;
2784 2788
2785 /* Pixmaps of the image. */ 2789 /* Pixmaps of the image. */
2786 Pixmap pixmap, mask; 2790 Pixmap pixmap, mask;
diff --git a/src/dispnew.c b/src/dispnew.c
index ad675f6e098..5582607ff6a 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -137,24 +137,11 @@ static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
137static void adjust_frame_glyphs_for_frame_redisplay (struct frame *); 137static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
138 138
139 139
140/* Define PERIODIC_PREEMPTION_CHECKING to 1, if micro-second timers
141 are supported, so we can check for input during redisplay at
142 regular intervals. */
143#ifdef EMACS_HAS_USECS
144#define PERIODIC_PREEMPTION_CHECKING 1
145#else
146#define PERIODIC_PREEMPTION_CHECKING 0
147#endif
148
149#if PERIODIC_PREEMPTION_CHECKING
150
151/* Redisplay preemption timers. */ 140/* Redisplay preemption timers. */
152 141
153static EMACS_TIME preemption_period; 142static EMACS_TIME preemption_period;
154static EMACS_TIME preemption_next_check; 143static EMACS_TIME preemption_next_check;
155 144
156#endif
157
158/* Nonzero upon entry to redisplay means do not assume anything about 145/* Nonzero upon entry to redisplay means do not assume anything about
159 current contents of actual terminal frame; clear and redraw it. */ 146 current contents of actual terminal frame; clear and redraw it. */
160 147
@@ -3221,14 +3208,12 @@ update_frame (struct frame *f, int force_p, int inhibit_hairy_id_p)
3221 3208
3222 if (redisplay_dont_pause) 3209 if (redisplay_dont_pause)
3223 force_p = 1; 3210 force_p = 1;
3224#if PERIODIC_PREEMPTION_CHECKING
3225 else if (NILP (Vredisplay_preemption_period)) 3211 else if (NILP (Vredisplay_preemption_period))
3226 force_p = 1; 3212 force_p = 1;
3227 else if (!force_p && NUMBERP (Vredisplay_preemption_period)) 3213 else if (!force_p && NUMBERP (Vredisplay_preemption_period))
3228 { 3214 {
3229 EMACS_TIME tm; 3215 EMACS_TIME tm;
3230 double p = XFLOATINT (Vredisplay_preemption_period); 3216 double p = XFLOATINT (Vredisplay_preemption_period);
3231 int sec, usec;
3232 3217
3233 if (detect_input_pending_ignore_squeezables ()) 3218 if (detect_input_pending_ignore_squeezables ())
3234 { 3219 {
@@ -3236,14 +3221,10 @@ update_frame (struct frame *f, int force_p, int inhibit_hairy_id_p)
3236 goto do_pause; 3221 goto do_pause;
3237 } 3222 }
3238 3223
3239 sec = (int) p;
3240 usec = (p - sec) * 1000000;
3241
3242 EMACS_GET_TIME (tm); 3224 EMACS_GET_TIME (tm);
3243 EMACS_SET_SECS_USECS (preemption_period, sec, usec); 3225 preemption_period = EMACS_TIME_FROM_DOUBLE (p);
3244 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period); 3226 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
3245 } 3227 }
3246#endif
3247 3228
3248 if (FRAME_WINDOW_P (f)) 3229 if (FRAME_WINDOW_P (f))
3249 { 3230 {
@@ -3327,9 +3308,7 @@ update_frame (struct frame *f, int force_p, int inhibit_hairy_id_p)
3327#endif 3308#endif
3328 } 3309 }
3329 3310
3330#if PERIODIC_PREEMPTION_CHECKING
3331 do_pause: 3311 do_pause:
3332#endif
3333 /* Reset flags indicating that a window should be updated. */ 3312 /* Reset flags indicating that a window should be updated. */
3334 set_window_update_flags (root_window, 0); 3313 set_window_update_flags (root_window, 0);
3335 3314
@@ -3382,23 +3361,17 @@ update_single_window (struct window *w, int force_p)
3382 3361
3383 if (redisplay_dont_pause) 3362 if (redisplay_dont_pause)
3384 force_p = 1; 3363 force_p = 1;
3385#if PERIODIC_PREEMPTION_CHECKING
3386 else if (NILP (Vredisplay_preemption_period)) 3364 else if (NILP (Vredisplay_preemption_period))
3387 force_p = 1; 3365 force_p = 1;
3388 else if (!force_p && NUMBERP (Vredisplay_preemption_period)) 3366 else if (!force_p && NUMBERP (Vredisplay_preemption_period))
3389 { 3367 {
3390 EMACS_TIME tm; 3368 EMACS_TIME tm;
3391 double p = XFLOATINT (Vredisplay_preemption_period); 3369 double p = XFLOATINT (Vredisplay_preemption_period);
3392 int sec, usec;
3393
3394 sec = (int) p;
3395 usec = (p - sec) * 1000000;
3396 3370
3397 EMACS_GET_TIME (tm); 3371 EMACS_GET_TIME (tm);
3398 EMACS_SET_SECS_USECS (preemption_period, sec, usec); 3372 preemption_period = EMACS_TIME_FROM_DOUBLE (p);
3399 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period); 3373 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
3400 } 3374 }
3401#endif
3402 3375
3403 /* Update W. */ 3376 /* Update W. */
3404 update_begin (f); 3377 update_begin (f);
@@ -3644,10 +3617,9 @@ update_window (struct window *w, int force_p)
3644#if PERIODIC_PREEMPTION_CHECKING 3617#if PERIODIC_PREEMPTION_CHECKING
3645 if (!force_p) 3618 if (!force_p)
3646 { 3619 {
3647 EMACS_TIME tm, dif; 3620 EMACS_TIME tm;
3648 EMACS_GET_TIME (tm); 3621 EMACS_GET_TIME (tm);
3649 EMACS_SUB_TIME (dif, preemption_next_check, tm); 3622 if (EMACS_TIME_LT (preemption_next_check, tm))
3650 if (EMACS_TIME_NEG_P (dif))
3651 { 3623 {
3652 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period); 3624 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
3653 if (detect_input_pending_ignore_squeezables ()) 3625 if (detect_input_pending_ignore_squeezables ())
@@ -4750,10 +4722,9 @@ update_frame_1 (struct frame *f, int force_p, int inhibit_id_p)
4750#if PERIODIC_PREEMPTION_CHECKING 4722#if PERIODIC_PREEMPTION_CHECKING
4751 if (!force_p) 4723 if (!force_p)
4752 { 4724 {
4753 EMACS_TIME tm, dif; 4725 EMACS_TIME tm;
4754 EMACS_GET_TIME (tm); 4726 EMACS_GET_TIME (tm);
4755 EMACS_SUB_TIME (dif, preemption_next_check, tm); 4727 if (EMACS_TIME_LT (preemption_next_check, tm))
4756 if (EMACS_TIME_NEG_P (dif))
4757 { 4728 {
4758 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period); 4729 EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
4759 if (detect_input_pending_ignore_squeezables ()) 4730 if (detect_input_pending_ignore_squeezables ())
@@ -5967,48 +5938,14 @@ bitch_at_user (void)
5967 Sleeping, Waiting 5938 Sleeping, Waiting
5968 ***********************************************************************/ 5939 ***********************************************************************/
5969 5940
5970/* Convert a positive value DURATION to a seconds count *PSEC plus a
5971 microseconds count *PUSEC, rounding up. On overflow return the
5972 maximal value. */
5973void
5974duration_to_sec_usec (double duration, int *psec, int *pusec)
5975{
5976 int MILLION = 1000000;
5977 int sec = INT_MAX, usec = MILLION - 1;
5978
5979 if (duration < INT_MAX + 1.0)
5980 {
5981 int s = duration;
5982 double usdouble = (duration - s) * MILLION;
5983 int usfloor = usdouble;
5984 int usceil = usfloor + (usfloor < usdouble);
5985
5986 if (usceil < MILLION)
5987 {
5988 sec = s;
5989 usec = usceil;
5990 }
5991 else if (sec < INT_MAX)
5992 {
5993 sec = s + 1;
5994 usec = 0;
5995 }
5996 }
5997
5998 *psec = sec;
5999 *pusec = usec;
6000}
6001
6002DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0, 5941DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
6003 doc: /* Pause, without updating display, for SECONDS seconds. 5942 doc: /* Pause, without updating display, for SECONDS seconds.
6004SECONDS may be a floating-point value, meaning that you can wait for a 5943SECONDS may be a floating-point value, meaning that you can wait for a
6005fraction of a second. Optional second arg MILLISECONDS specifies an 5944fraction of a second. Optional second arg MILLISECONDS specifies an
6006additional wait period, in milliseconds; this may be useful if your 5945additional wait period, in milliseconds; this is for backwards compatibility.
6007Emacs was built without floating point support.
6008\(Not all operating systems support waiting for a fraction of a second.) */) 5946\(Not all operating systems support waiting for a fraction of a second.) */)
6009 (Lisp_Object seconds, Lisp_Object milliseconds) 5947 (Lisp_Object seconds, Lisp_Object milliseconds)
6010{ 5948{
6011 int sec, usec;
6012 double duration = extract_float (seconds); 5949 double duration = extract_float (seconds);
6013 5950
6014 if (!NILP (milliseconds)) 5951 if (!NILP (milliseconds))
@@ -6017,17 +5954,12 @@ Emacs was built without floating point support.
6017 duration += XINT (milliseconds) / 1000.0; 5954 duration += XINT (milliseconds) / 1000.0;
6018 } 5955 }
6019 5956
6020 if (! (0 < duration)) 5957 if (0 < duration)
6021 return Qnil; 5958 {
6022 5959 EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (duration);
6023 duration_to_sec_usec (duration, &sec, &usec); 5960 wait_reading_process_output (min (EMACS_SECS (t), INTMAX_MAX),
6024 5961 EMACS_NSECS (t), 0, 0, Qnil, NULL, 0);
6025#ifndef EMACS_HAS_USECS 5962 }
6026 if (sec == 0 && usec != 0)
6027 error ("Millisecond `sleep-for' not supported on %s", SYSTEM_TYPE);
6028#endif
6029
6030 wait_reading_process_output (sec, usec, 0, 0, Qnil, NULL, 0);
6031 5963
6032 return Qnil; 5964 return Qnil;
6033} 5965}
@@ -6046,7 +5978,8 @@ Emacs was built without floating point support.
6046Lisp_Object 5978Lisp_Object
6047sit_for (Lisp_Object timeout, int reading, int do_display) 5979sit_for (Lisp_Object timeout, int reading, int do_display)
6048{ 5980{
6049 int sec, usec; 5981 intmax_t sec;
5982 int nsec;
6050 5983
6051 swallow_events (do_display); 5984 swallow_events (do_display);
6052 5985
@@ -6057,26 +5990,39 @@ sit_for (Lisp_Object timeout, int reading, int do_display)
6057 if (do_display >= 2) 5990 if (do_display >= 2)
6058 redisplay_preserve_echo_area (2); 5991 redisplay_preserve_echo_area (2);
6059 5992
6060 if (EQ (timeout, Qt)) 5993 if (INTEGERP (timeout))
6061 { 5994 {
6062 sec = 0; 5995 sec = XINT (timeout);
6063 usec = 0; 5996 if (! (0 < sec))
5997 return Qt;
5998 nsec = 0;
6064 } 5999 }
6065 else 6000 else if (FLOATP (timeout))
6066 { 6001 {
6067 double duration = extract_float (timeout); 6002 double seconds = XFLOAT_DATA (timeout);
6068 6003 if (! (0 < seconds))
6069 if (! (0 < duration))
6070 return Qt; 6004 return Qt;
6071 6005 else
6072 duration_to_sec_usec (duration, &sec, &usec); 6006 {
6007 EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (seconds);
6008 sec = min (EMACS_SECS (t), INTMAX_MAX);
6009 nsec = EMACS_NSECS (t);
6010 }
6011 }
6012 else if (EQ (timeout, Qt))
6013 {
6014 sec = 0;
6015 nsec = 0;
6073 } 6016 }
6017 else
6018 wrong_type_argument (Qnumberp, timeout);
6019
6074 6020
6075#ifdef SIGIO 6021#ifdef SIGIO
6076 gobble_input (0); 6022 gobble_input (0);
6077#endif 6023#endif
6078 6024
6079 wait_reading_process_output (sec, usec, reading ? -1 : 1, do_display, 6025 wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display,
6080 Qnil, NULL, 0); 6026 Qnil, NULL, 0);
6081 6027
6082 return detect_input_pending () ? Qnil : Qt; 6028 return detect_input_pending () ? Qnil : Qt;
diff --git a/src/editfns.c b/src/editfns.c
index 1fb20b07e70..63e77004f8b 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -73,9 +73,8 @@ extern char **environ;
73extern Lisp_Object w32_get_internal_run_time (void); 73extern Lisp_Object w32_get_internal_run_time (void);
74#endif 74#endif
75 75
76static void time_overflow (void) NO_RETURN; 76static Lisp_Object format_time_string (char const *, ptrdiff_t, EMACS_TIME,
77static Lisp_Object format_time_string (char const *, ptrdiff_t, Lisp_Object, 77 int, struct tm *);
78 int, time_t *, struct tm *);
79static int tm_diff (struct tm *, struct tm *); 78static int tm_diff (struct tm *, struct tm *);
80static void update_buffer_properties (ptrdiff_t, ptrdiff_t); 79static void update_buffer_properties (ptrdiff_t, ptrdiff_t);
81 80
@@ -1378,14 +1377,13 @@ DEFUN ("emacs-pid", Femacs_pid, Semacs_pid, 0, 0, 0,
1378#endif 1377#endif
1379 1378
1380/* Report that a time value is out of range for Emacs. */ 1379/* Report that a time value is out of range for Emacs. */
1381static void 1380void
1382time_overflow (void) 1381time_overflow (void)
1383{ 1382{
1384 error ("Specified time is not representable"); 1383 error ("Specified time is not representable");
1385} 1384}
1386 1385
1387/* Return the upper part of the time T (everything but the bottom 16 bits), 1386/* Return the upper part of the time T (everything but the bottom 16 bits). */
1388 making sure that it is representable. */
1389static EMACS_INT 1387static EMACS_INT
1390hi_time (time_t t) 1388hi_time (time_t t)
1391{ 1389{
@@ -1413,40 +1411,33 @@ lo_time (time_t t)
1413 1411
1414DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0, 1412DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0,
1415 doc: /* Return the current time, as the number of seconds since 1970-01-01 00:00:00. 1413 doc: /* Return the current time, as the number of seconds since 1970-01-01 00:00:00.
1416The time is returned as a list of three integers. The first has the 1414The time is returned as a list of integers (HIGH LOW USEC PSEC).
1417most significant 16 bits of the seconds, while the second has the 1415HIGH has the most significant bits of the seconds, while LOW has the
1418least significant 16 bits. The third integer gives the microsecond 1416least significant 16 bits. USEC and PSEC are the microsecond and
1419count. 1417picosecond counts. */)
1420
1421The microsecond count is zero on systems that do not provide
1422resolution finer than a second. */)
1423 (void) 1418 (void)
1424{ 1419{
1425 EMACS_TIME t; 1420 EMACS_TIME t;
1426 1421
1427 EMACS_GET_TIME (t); 1422 EMACS_GET_TIME (t);
1428 return list3 (make_number (hi_time (EMACS_SECS (t))), 1423 return make_lisp_time (t);
1429 make_number (lo_time (EMACS_SECS (t))),
1430 make_number (EMACS_USECS (t)));
1431} 1424}
1432 1425
1433DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time, 1426DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time,
1434 0, 0, 0, 1427 0, 0, 0,
1435 doc: /* Return the current run time used by Emacs. 1428 doc: /* Return the current run time used by Emacs.
1436The time is returned as a list of three integers. The first has the 1429The time is returned as a list (HIGH LOW USEC PSEC), using the same
1437most significant 16 bits of the seconds, while the second has the 1430style as (current-time).
1438least significant 16 bits. The third integer gives the microsecond
1439count.
1440 1431
1441On systems that can't determine the run time, `get-internal-run-time' 1432On systems that can't determine the run time, `get-internal-run-time'
1442does the same thing as `current-time'. The microsecond count is zero 1433does the same thing as `current-time'. */)
1443on systems that do not provide resolution finer than a second. */)
1444 (void) 1434 (void)
1445{ 1435{
1446#ifdef HAVE_GETRUSAGE 1436#ifdef HAVE_GETRUSAGE
1447 struct rusage usage; 1437 struct rusage usage;
1448 time_t secs; 1438 time_t secs;
1449 int usecs; 1439 int usecs;
1440 EMACS_TIME t;
1450 1441
1451 if (getrusage (RUSAGE_SELF, &usage) < 0) 1442 if (getrusage (RUSAGE_SELF, &usage) < 0)
1452 /* This shouldn't happen. What action is appropriate? */ 1443 /* This shouldn't happen. What action is appropriate? */
@@ -1460,10 +1451,8 @@ on systems that do not provide resolution finer than a second. */)
1460 usecs -= 1000000; 1451 usecs -= 1000000;
1461 secs++; 1452 secs++;
1462 } 1453 }
1463 1454 EMACS_SET_SECS_USECS (t, secs, usecs);
1464 return list3 (make_number (hi_time (secs)), 1455 return make_lisp_time (t);
1465 make_number (lo_time (secs)),
1466 make_number (usecs));
1467#else /* ! HAVE_GETRUSAGE */ 1456#else /* ! HAVE_GETRUSAGE */
1468#ifdef WINDOWSNT 1457#ifdef WINDOWSNT
1469 return w32_get_internal_run_time (); 1458 return w32_get_internal_run_time ();
@@ -1474,80 +1463,151 @@ on systems that do not provide resolution finer than a second. */)
1474} 1463}
1475 1464
1476 1465
1477/* Make a Lisp list that represents the time T. */ 1466/* Make a Lisp list that represents the time T with fraction TAIL. */
1478Lisp_Object 1467static Lisp_Object
1468make_time_tail (time_t t, Lisp_Object tail)
1469{
1470 return Fcons (make_number (hi_time (t)),
1471 Fcons (make_number (lo_time (t)), tail));
1472}
1473
1474/* Make a Lisp list that represents the system time T. */
1475static Lisp_Object
1479make_time (time_t t) 1476make_time (time_t t)
1480{ 1477{
1481 return list2 (make_number (hi_time (t)), 1478 return make_time_tail (t, Qnil);
1482 make_number (lo_time (t))); 1479}
1480
1481/* Make a Lisp list that represents the Emacs time T. T may be an
1482 invalid time, with a slightly negative tv_nsec value such as
1483 UNKNOWN_MODTIME_NSECS; in that case, the Lisp list contains a
1484 correspondingly negative picosecond count. */
1485Lisp_Object
1486make_lisp_time (EMACS_TIME t)
1487{
1488 int ns = EMACS_NSECS (t);
1489 return make_time_tail (EMACS_SECS (t),
1490 list2 (make_number (ns / 1000),
1491 make_number (ns % 1000 * 1000)));
1483} 1492}
1484 1493
1485/* Decode a Lisp list SPECIFIED_TIME that represents a time. 1494/* Decode a Lisp list SPECIFIED_TIME that represents a time.
1486 If SPECIFIED_TIME is nil, use the current time. 1495 Set *PHIGH, *PLOW, *PUSEC, *PPSEC to its parts; do not check their values.
1487 Set *RESULT to seconds since the Epoch.
1488 If USEC is not null, set *USEC to the microseconds component.
1489 Return nonzero if successful. */ 1496 Return nonzero if successful. */
1497static int
1498disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh,
1499 Lisp_Object *plow, Lisp_Object *pusec,
1500 Lisp_Object *ppsec)
1501{
1502 if (CONSP (specified_time))
1503 {
1504 Lisp_Object low = XCDR (specified_time);
1505 Lisp_Object usec = make_number (0);
1506 Lisp_Object psec = make_number (0);
1507 if (CONSP (low))
1508 {
1509 Lisp_Object low_tail = XCDR (low);
1510 low = XCAR (low);
1511 if (CONSP (low_tail))
1512 {
1513 usec = XCAR (low_tail);
1514 low_tail = XCDR (low_tail);
1515 if (CONSP (low_tail))
1516 psec = XCAR (low_tail);
1517 }
1518 else if (!NILP (low_tail))
1519 usec = low_tail;
1520 }
1521
1522 *phigh = XCAR (specified_time);
1523 *plow = low;
1524 *pusec = usec;
1525 *ppsec = psec;
1526 return 1;
1527 }
1528
1529 return 0;
1530}
1531
1532/* From the time components HIGH, LOW, USEC and PSEC taken from a Lisp
1533 list, generate the corresponding EMACS_TIME value *RESULT, and
1534 if RESULT_PSEC is not null store into *RESULT_PSEC the
1535 (nonnegative) difference in picoseconds between the input time and
1536 the returned time. Return nonzero if successful. */
1490int 1537int
1491lisp_time_argument (Lisp_Object specified_time, time_t *result, int *usec) 1538decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
1539 Lisp_Object psec, EMACS_TIME *result, int *result_psec)
1492{ 1540{
1541 EMACS_INT hi, lo, us, ps;
1542 time_t sec;
1543 if (! (INTEGERP (high) && INTEGERP (low)
1544 && INTEGERP (usec) && INTEGERP (psec)))
1545 return 0;
1546 hi = XINT (high);
1547 lo = XINT (low);
1548 us = XINT (usec);
1549 ps = XINT (psec);
1550
1551 /* Normalize out-of-range lower-order components by carrying
1552 each overflow into the next higher-order component. */
1553 us += ps / 1000000 - (ps % 1000000 < 0);
1554 lo += us / 1000000 - (us % 1000000 < 0);
1555 hi += lo >> 16;
1556 ps = ps % 1000000 + 1000000 * (ps % 1000000 < 0);
1557 us = us % 1000000 + 1000000 * (us % 1000000 < 0);
1558 lo &= (1 << 16) - 1;
1559
1560 /* Check for overflow in the highest-order component. */
1561 if (! ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> 16 <= hi : 0 <= hi)
1562 && hi <= TIME_T_MAX >> 16))
1563 return 0;
1564
1565 sec = hi;
1566 EMACS_SET_SECS_NSECS (*result, (sec << 16) + lo, us * 1000 + ps / 1000);
1567 if (result_psec)
1568 *result_psec = ps % 1000;
1569 return 1;
1570}
1571
1572/* Decode a Lisp list SPECIFIED_TIME that represents a time.
1573 If SPECIFIED_TIME is nil, use the current time.
1574 Round the time down to the nearest EMACS_TIME value, and
1575 if PPSEC is not null store into *PPSEC the (nonnegative) difference in
1576 picoseconds between the input time and the returned time.
1577 Return seconds since the Epoch.
1578 Signal an error if unsuccessful. */
1579EMACS_TIME
1580lisp_time_argument (Lisp_Object specified_time, int *ppsec)
1581{
1582 EMACS_TIME t;
1493 if (NILP (specified_time)) 1583 if (NILP (specified_time))
1584 EMACS_GET_TIME (t);
1585 else
1494 { 1586 {
1495 if (usec) 1587 Lisp_Object high, low, usec, psec;
1496 { 1588 if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec)
1497 EMACS_TIME t; 1589 && decode_time_components (high, low, usec, psec, &t, ppsec)))
1498 1590 error ("Invalid time specification");
1499 EMACS_GET_TIME (t);
1500 *usec = EMACS_USECS (t);
1501 *result = EMACS_SECS (t);
1502 return 1;
1503 }
1504 else
1505 return time (result) != -1;
1506 } 1591 }
1592 return t;
1593}
1594
1595/* Like lisp_time_argument, except decode only the seconds part,
1596 and do not check the subseconds part, and always round down. */
1597static time_t
1598lisp_seconds_argument (Lisp_Object specified_time)
1599{
1600 if (NILP (specified_time))
1601 return time (NULL);
1507 else 1602 else
1508 { 1603 {
1509 Lisp_Object high, low; 1604 Lisp_Object high, low, usec, psec;
1510 EMACS_INT hi; 1605 EMACS_TIME t;
1511 high = Fcar (specified_time); 1606 if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec)
1512 CHECK_NUMBER (high); 1607 && decode_time_components (high, low, make_number (0),
1513 low = Fcdr (specified_time); 1608 make_number (0), &t, 0)))
1514 if (CONSP (low)) 1609 error ("Invalid time specification");
1515 { 1610 return EMACS_SECS (t);
1516 if (usec)
1517 {
1518 Lisp_Object usec_l = Fcdr (low);
1519 if (CONSP (usec_l))
1520 usec_l = Fcar (usec_l);
1521 if (NILP (usec_l))
1522 *usec = 0;
1523 else
1524 {
1525 CHECK_NUMBER (usec_l);
1526 if (! (0 <= XINT (usec_l) && XINT (usec_l) < 1000000))
1527 return 0;
1528 *usec = XINT (usec_l);
1529 }
1530 }
1531 low = Fcar (low);
1532 }
1533 else if (usec)
1534 *usec = 0;
1535 CHECK_NUMBER (low);
1536 hi = XINT (high);
1537
1538 /* Check for overflow, helping the compiler for common cases
1539 where no runtime check is needed, and taking care not to
1540 convert negative numbers to unsigned before comparing them. */
1541 if (! ((TYPE_SIGNED (time_t)
1542 ? (TIME_T_MIN >> 16 <= MOST_NEGATIVE_FIXNUM
1543 || TIME_T_MIN >> 16 <= hi)
1544 : 0 <= hi)
1545 && (MOST_POSITIVE_FIXNUM <= TIME_T_MAX >> 16
1546 || hi <= TIME_T_MAX >> 16)))
1547 return 0;
1548
1549 *result = (hi << 16) + (XINT (low) & 0xffff);
1550 return 1;
1551 } 1611 }
1552} 1612}
1553 1613
@@ -1555,22 +1615,22 @@ DEFUN ("float-time", Ffloat_time, Sfloat_time, 0, 1, 0,
1555 doc: /* Return the current time, as a float number of seconds since the epoch. 1615 doc: /* Return the current time, as a float number of seconds since the epoch.
1556If SPECIFIED-TIME is given, it is the time to convert to float 1616If SPECIFIED-TIME is given, it is the time to convert to float
1557instead of the current time. The argument should have the form 1617instead of the current time. The argument should have the form
1558(HIGH LOW) or (HIGH LOW USEC). Thus, you can use times obtained from 1618(HIGH LOW) or (HIGH LOW USEC) or (HIGH LOW USEC PSEC). Thus,
1559`current-time' and from `file-attributes'. SPECIFIED-TIME can also 1619you can use times from `current-time' and from `file-attributes'.
1560have the form (HIGH . LOW), but this is considered obsolete. 1620SPECIFIED-TIME can also have the form (HIGH . LOW), but this is
1621considered obsolete.
1561 1622
1562WARNING: Since the result is floating point, it may not be exact. 1623WARNING: Since the result is floating point, it may not be exact.
1563If precise time stamps are required, use either `current-time', 1624If precise time stamps are required, use either `current-time',
1564or (if you need time as a string) `format-time-string'. */) 1625or (if you need time as a string) `format-time-string'. */)
1565 (Lisp_Object specified_time) 1626 (Lisp_Object specified_time)
1566{ 1627{
1567 time_t sec; 1628 int psec;
1568 int usec; 1629 EMACS_TIME t = lisp_time_argument (specified_time, &psec);
1569 1630 double ps = (1000 * 1000 * 1000 <= INTMAX_MAX / 1000
1570 if (! lisp_time_argument (specified_time, &sec, &usec)) 1631 ? EMACS_NSECS (t) * (intmax_t) 1000 + psec
1571 error ("Invalid time specification"); 1632 : EMACS_NSECS (t) * 1e3 + psec);
1572 1633 return make_float (EMACS_SECS (t) + ps / 1e12);
1573 return make_float ((sec * 1e6 + usec) / 1e6);
1574} 1634}
1575 1635
1576/* Write information into buffer S of size MAXSIZE, according to the 1636/* Write information into buffer S of size MAXSIZE, according to the
@@ -1625,7 +1685,7 @@ emacs_nmemftime (char *s, size_t maxsize, const char *format,
1625 1685
1626DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0, 1686DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0,
1627 doc: /* Use FORMAT-STRING to format the time TIME, or now if omitted. 1687 doc: /* Use FORMAT-STRING to format the time TIME, or now if omitted.
1628TIME is specified as (HIGH LOW . IGNORED), as returned by 1688TIME is specified as (HIGH LOW USEC PSEC), as returned by
1629`current-time' or `file-attributes'. The obsolete form (HIGH . LOW) 1689`current-time' or `file-attributes'. The obsolete form (HIGH . LOW)
1630is also still accepted. 1690is also still accepted.
1631The third, optional, argument UNIVERSAL, if non-nil, means describe TIME 1691The third, optional, argument UNIVERSAL, if non-nil, means describe TIME
@@ -1679,41 +1739,36 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z".
1679usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) 1739usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */)
1680 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) 1740 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal)
1681{ 1741{
1682 time_t t; 1742 EMACS_TIME t = lisp_time_argument (timeval, 0);
1683 struct tm tm; 1743 struct tm tm;
1684 1744
1685 CHECK_STRING (format_string); 1745 CHECK_STRING (format_string);
1686 format_string = code_convert_string_norecord (format_string, 1746 format_string = code_convert_string_norecord (format_string,
1687 Vlocale_coding_system, 1); 1747 Vlocale_coding_system, 1);
1688 return format_time_string (SSDATA (format_string), SBYTES (format_string), 1748 return format_time_string (SSDATA (format_string), SBYTES (format_string),
1689 timeval, ! NILP (universal), &t, &tm); 1749 t, ! NILP (universal), &tm);
1690} 1750}
1691 1751
1692static Lisp_Object 1752static Lisp_Object
1693format_time_string (char const *format, ptrdiff_t formatlen, 1753format_time_string (char const *format, ptrdiff_t formatlen,
1694 Lisp_Object timeval, int ut, time_t *tval, struct tm *tmp) 1754 EMACS_TIME t, int ut, struct tm *tmp)
1695{ 1755{
1696 char buffer[4000]; 1756 char buffer[4000];
1697 char *buf = buffer; 1757 char *buf = buffer;
1698 ptrdiff_t size = sizeof buffer; 1758 ptrdiff_t size = sizeof buffer;
1699 size_t len; 1759 size_t len;
1700 Lisp_Object bufstring; 1760 Lisp_Object bufstring;
1701 int usec; 1761 int ns = EMACS_NSECS (t);
1702 int ns;
1703 struct tm *tm; 1762 struct tm *tm;
1704 USE_SAFE_ALLOCA; 1763 USE_SAFE_ALLOCA;
1705 1764
1706 if (! lisp_time_argument (timeval, tval, &usec))
1707 error ("Invalid time specification");
1708 ns = usec * 1000;
1709
1710 while (1) 1765 while (1)
1711 { 1766 {
1712 BLOCK_INPUT; 1767 BLOCK_INPUT;
1713 1768
1714 synchronize_system_time_locale (); 1769 synchronize_system_time_locale ();
1715 1770
1716 tm = ut ? gmtime (tval) : localtime (tval); 1771 tm = ut ? gmtime (EMACS_SECS_ADDR (t)) : localtime (EMACS_SECS_ADDR (t));
1717 if (! tm) 1772 if (! tm)
1718 { 1773 {
1719 UNBLOCK_INPUT; 1774 UNBLOCK_INPUT;
@@ -1758,17 +1813,13 @@ east of Greenwich. (Note that Common Lisp has different meanings for
1758DOW and ZONE.) */) 1813DOW and ZONE.) */)
1759 (Lisp_Object specified_time) 1814 (Lisp_Object specified_time)
1760{ 1815{
1761 time_t time_spec; 1816 time_t time_spec = lisp_seconds_argument (specified_time);
1762 struct tm save_tm; 1817 struct tm save_tm;
1763 struct tm *decoded_time; 1818 struct tm *decoded_time;
1764 Lisp_Object list_args[9]; 1819 Lisp_Object list_args[9];
1765 1820
1766 if (! lisp_time_argument (specified_time, &time_spec, NULL))
1767 error ("Invalid time specification");
1768
1769 BLOCK_INPUT; 1821 BLOCK_INPUT;
1770 decoded_time = localtime (&time_spec); 1822 decoded_time = localtime (&time_spec);
1771 /* Make a copy, in case a signal handler modifies TZ or the struct. */
1772 if (decoded_time) 1823 if (decoded_time)
1773 save_tm = *decoded_time; 1824 save_tm = *decoded_time;
1774 UNBLOCK_INPUT; 1825 UNBLOCK_INPUT;
@@ -1919,14 +1970,11 @@ Thus, you can use times obtained from `current-time' and from
1919but this is considered obsolete. */) 1970but this is considered obsolete. */)
1920 (Lisp_Object specified_time) 1971 (Lisp_Object specified_time)
1921{ 1972{
1922 time_t value; 1973 time_t value = lisp_seconds_argument (specified_time);
1923 struct tm *tm; 1974 struct tm *tm;
1924 char buf[sizeof "Mon Apr 30 12:49:17 " + INT_STRLEN_BOUND (int) + 1]; 1975 char buf[sizeof "Mon Apr 30 12:49:17 " + INT_STRLEN_BOUND (int) + 1];
1925 int len IF_LINT (= 0); 1976 int len IF_LINT (= 0);
1926 1977
1927 if (! lisp_time_argument (specified_time, &value, NULL))
1928 error ("Invalid time specification");
1929
1930 /* Convert to a string in ctime format, except without the trailing 1978 /* Convert to a string in ctime format, except without the trailing
1931 newline, and without the 4-digit year limit. Don't use asctime 1979 newline, and without the 4-digit year limit. Don't use asctime
1932 or ctime, as they might dump core if the year is outside the 1980 or ctime, as they might dump core if the year is outside the
@@ -1994,17 +2042,17 @@ in this case, `current-time-zone' returns a list containing nil for
1994the data it can't find. */) 2042the data it can't find. */)
1995 (Lisp_Object specified_time) 2043 (Lisp_Object specified_time)
1996{ 2044{
1997 time_t value; 2045 EMACS_TIME value;
1998 int offset; 2046 int offset;
1999 struct tm *t; 2047 struct tm *t;
2000 struct tm localtm; 2048 struct tm localtm;
2001 Lisp_Object zone_offset, zone_name; 2049 Lisp_Object zone_offset, zone_name;
2002 2050
2003 zone_offset = Qnil; 2051 zone_offset = Qnil;
2004 zone_name = format_time_string ("%Z", sizeof "%Z" - 1, specified_time, 2052 EMACS_SET_SECS_NSECS (value, lisp_seconds_argument (specified_time), 0);
2005 0, &value, &localtm); 2053 zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value, 0, &localtm);
2006 BLOCK_INPUT; 2054 BLOCK_INPUT;
2007 t = gmtime (&value); 2055 t = gmtime (EMACS_SECS_ADDR (value));
2008 if (t) 2056 if (t)
2009 offset = tm_diff (&localtm, t); 2057 offset = tm_diff (&localtm, t);
2010 UNBLOCK_INPUT; 2058 UNBLOCK_INPUT;
diff --git a/src/fileio.c b/src/fileio.c
index 8b69ed5eae4..824a92148cb 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -76,6 +76,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
76#endif 76#endif
77 77
78#include "systime.h" 78#include "systime.h"
79#include <stat-time.h>
79 80
80#ifdef HPUX 81#ifdef HPUX
81#include <netio.h> 82#include <netio.h>
@@ -1931,7 +1932,7 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */)
1931 /* Ensure file is writable while its modified time is set. */ 1932 /* Ensure file is writable while its modified time is set. */
1932 attributes = GetFileAttributes (filename); 1933 attributes = GetFileAttributes (filename);
1933 SetFileAttributes (filename, attributes & ~FILE_ATTRIBUTE_READONLY); 1934 SetFileAttributes (filename, attributes & ~FILE_ATTRIBUTE_READONLY);
1934 if (set_file_times (filename, now, now)) 1935 if (set_file_times (-1, filename, now, now))
1935 { 1936 {
1936 /* Restore original attributes. */ 1937 /* Restore original attributes. */
1937 SetFileAttributes (filename, attributes); 1938 SetFileAttributes (filename, attributes);
@@ -2054,24 +2055,21 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */)
2054 } 2055 }
2055#endif 2056#endif
2056 2057
2057 /* Closing the output clobbers the file times on some systems. */
2058 if (emacs_close (ofd) < 0)
2059 report_file_error ("I/O error", Fcons (newname, Qnil));
2060
2061 if (input_file_statable_p) 2058 if (input_file_statable_p)
2062 { 2059 {
2063 if (!NILP (keep_time)) 2060 if (!NILP (keep_time))
2064 { 2061 {
2065 EMACS_TIME atime, mtime; 2062 EMACS_TIME atime = get_stat_atime (&st);
2066 EMACS_SET_SECS_USECS (atime, st.st_atime, 0); 2063 EMACS_TIME mtime = get_stat_mtime (&st);
2067 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0); 2064 if (set_file_times (ofd, SSDATA (encoded_newname), atime, mtime))
2068 if (set_file_times (SSDATA (encoded_newname),
2069 atime, mtime))
2070 xsignal2 (Qfile_date_error, 2065 xsignal2 (Qfile_date_error,
2071 build_string ("Cannot set file date"), newname); 2066 build_string ("Cannot set file date"), newname);
2072 } 2067 }
2073 } 2068 }
2074 2069
2070 if (emacs_close (ofd) < 0)
2071 report_file_error ("I/O error", Fcons (newname, Qnil));
2072
2075 emacs_close (ifd); 2073 emacs_close (ifd);
2076 2074
2077#ifdef MSDOS 2075#ifdef MSDOS
@@ -3034,11 +3032,7 @@ Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of
3034{ 3032{
3035 Lisp_Object absname, encoded_absname; 3033 Lisp_Object absname, encoded_absname;
3036 Lisp_Object handler; 3034 Lisp_Object handler;
3037 time_t sec; 3035 EMACS_TIME t = lisp_time_argument (timestamp, 0);
3038 int usec;
3039
3040 if (! lisp_time_argument (timestamp, &sec, &usec))
3041 error ("Invalid time specification");
3042 3036
3043 absname = Fexpand_file_name (filename, BVAR (current_buffer, directory)); 3037 absname = Fexpand_file_name (filename, BVAR (current_buffer, directory));
3044 3038
@@ -3051,12 +3045,7 @@ Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of
3051 encoded_absname = ENCODE_FILE (absname); 3045 encoded_absname = ENCODE_FILE (absname);
3052 3046
3053 { 3047 {
3054 EMACS_TIME t; 3048 if (set_file_times (-1, SSDATA (encoded_absname), t, t))
3055
3056 EMACS_SET_SECS (t, sec);
3057 EMACS_SET_USECS (t, usec);
3058
3059 if (set_file_times (SSDATA (encoded_absname), t, t))
3060 { 3049 {
3061#ifdef DOS_NT 3050#ifdef DOS_NT
3062 struct stat st; 3051 struct stat st;
@@ -4205,7 +4194,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
4205 4194
4206 if (NILP (handler)) 4195 if (NILP (handler))
4207 { 4196 {
4208 current_buffer->modtime = st.st_mtime; 4197 current_buffer->modtime = get_stat_mtime (&st);
4209 current_buffer->modtime_size = st.st_size; 4198 current_buffer->modtime_size = st.st_size;
4210 BVAR (current_buffer, filename) = orig_filename; 4199 BVAR (current_buffer, filename) = orig_filename;
4211 } 4200 }
@@ -4365,7 +4354,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
4365 } 4354 }
4366 4355
4367 if (!NILP (visit) 4356 if (!NILP (visit)
4368 && current_buffer->modtime == -1) 4357 && EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS)
4369 { 4358 {
4370 /* If visiting nonexistent file, return nil. */ 4359 /* If visiting nonexistent file, return nil. */
4371 errno = save_errno; 4360 errno = save_errno;
@@ -4803,7 +4792,7 @@ This calls `write-region-annotate-functions' at the start, and
4803 next attempt to save. */ 4792 next attempt to save. */
4804 if (visiting) 4793 if (visiting)
4805 { 4794 {
4806 current_buffer->modtime = st.st_mtime; 4795 current_buffer->modtime = get_stat_mtime (&st);
4807 current_buffer->modtime_size = st.st_size; 4796 current_buffer->modtime_size = st.st_size;
4808 } 4797 }
4809 4798
@@ -5080,6 +5069,7 @@ See Info node `(elisp)Modification Time' for more details. */)
5080 struct stat st; 5069 struct stat st;
5081 Lisp_Object handler; 5070 Lisp_Object handler;
5082 Lisp_Object filename; 5071 Lisp_Object filename;
5072 EMACS_TIME mtime, diff, one_second;
5083 5073
5084 if (NILP (buf)) 5074 if (NILP (buf))
5085 b = current_buffer; 5075 b = current_buffer;
@@ -5090,7 +5080,7 @@ See Info node `(elisp)Modification Time' for more details. */)
5090 } 5080 }
5091 5081
5092 if (!STRINGP (BVAR (b, filename))) return Qt; 5082 if (!STRINGP (BVAR (b, filename))) return Qt;
5093 if (b->modtime == 0) return Qt; 5083 if (EMACS_NSECS (b->modtime) == UNKNOWN_MODTIME_NSECS) return Qt;
5094 5084
5095 /* If the file name has special constructs in it, 5085 /* If the file name has special constructs in it,
5096 call the corresponding file handler. */ 5086 call the corresponding file handler. */
@@ -5101,20 +5091,25 @@ See Info node `(elisp)Modification Time' for more details. */)
5101 5091
5102 filename = ENCODE_FILE (BVAR (b, filename)); 5092 filename = ENCODE_FILE (BVAR (b, filename));
5103 5093
5104 if (stat (SSDATA (filename), &st) < 0) 5094 if (stat (SSDATA (filename), &st) == 0)
5095 mtime = get_stat_mtime (&st);
5096 else
5105 { 5097 {
5106 /* If the file doesn't exist now and didn't exist before, 5098 /* If the file doesn't exist now and didn't exist before,
5107 we say that it isn't modified, provided the error is a tame one. */ 5099 we say that it isn't modified, provided the error is a tame one. */
5108 if (errno == ENOENT || errno == EACCES || errno == ENOTDIR) 5100 int ns = (errno == ENOENT || errno == EACCES || errno == ENOTDIR
5109 st.st_mtime = -1; 5101 ? NONEXISTENT_MODTIME_NSECS
5110 else 5102 : UNKNOWN_MODTIME_NSECS);
5111 st.st_mtime = 0; 5103 EMACS_SET_SECS_NSECS (mtime, 0, ns);
5112 } 5104 }
5113 if ((st.st_mtime == b->modtime 5105 if ((EMACS_TIME_EQ (mtime, b->modtime)
5114 /* If both are positive, accept them if they are off by one second. */ 5106 /* If both exist, accept them if they are off by one second. */
5115 || (st.st_mtime > 0 && b->modtime > 0 5107 || (EMACS_TIME_VALID_P (mtime) && EMACS_TIME_VALID_P (b->modtime)
5116 && (st.st_mtime - 1 == b->modtime 5108 && ((EMACS_TIME_LT (mtime, b->modtime)
5117 || st.st_mtime == b->modtime - 1))) 5109 ? EMACS_SUB_TIME (diff, b->modtime, mtime)
5110 : EMACS_SUB_TIME (diff, mtime, b->modtime)),
5111 EMACS_SET_SECS_NSECS (one_second, 1, 0),
5112 EMACS_TIME_LE (diff, one_second))))
5118 && (st.st_size == b->modtime_size 5113 && (st.st_size == b->modtime_size
5119 || b->modtime_size < 0)) 5114 || b->modtime_size < 0))
5120 return Qt; 5115 return Qt;
@@ -5127,7 +5122,7 @@ DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
5127Next attempt to save will certainly not complain of a discrepancy. */) 5122Next attempt to save will certainly not complain of a discrepancy. */)
5128 (void) 5123 (void)
5129{ 5124{
5130 current_buffer->modtime = 0; 5125 EMACS_SET_SECS_NSECS (current_buffer->modtime, 0, UNKNOWN_MODTIME_NSECS);
5131 current_buffer->modtime_size = -1; 5126 current_buffer->modtime_size = -1;
5132 return Qnil; 5127 return Qnil;
5133} 5128}
@@ -5135,16 +5130,16 @@ Next attempt to save will certainly not complain of a discrepancy. */)
5135DEFUN ("visited-file-modtime", Fvisited_file_modtime, 5130DEFUN ("visited-file-modtime", Fvisited_file_modtime,
5136 Svisited_file_modtime, 0, 0, 0, 5131 Svisited_file_modtime, 0, 0, 0,
5137 doc: /* Return the current buffer's recorded visited file modification time. 5132 doc: /* Return the current buffer's recorded visited file modification time.
5138The value is a list of the form (HIGH LOW), like the time values that 5133The value is a list of the form (HIGH LOW USEC PSEC), like the time values that
5139`file-attributes' returns. If the current buffer has no recorded file 5134`file-attributes' returns. If the current buffer has no recorded file
5140modification time, this function returns 0. If the visited file 5135modification time, this function returns 0. If the visited file
5141doesn't exist, HIGH will be -1. 5136doesn't exist, HIGH will be -1.
5142See Info node `(elisp)Modification Time' for more details. */) 5137See Info node `(elisp)Modification Time' for more details. */)
5143 (void) 5138 (void)
5144{ 5139{
5145 if (! current_buffer->modtime) 5140 if (EMACS_NSECS (current_buffer->modtime) < 0)
5146 return make_number (0); 5141 return make_number (0);
5147 return make_time (current_buffer->modtime); 5142 return make_lisp_time (current_buffer->modtime);
5148} 5143}
5149 5144
5150DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime, 5145DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
@@ -5154,12 +5149,12 @@ Useful if the buffer was not read from the file normally
5154or if the file itself has been changed for some known benign reason. 5149or if the file itself has been changed for some known benign reason.
5155An argument specifies the modification time value to use 5150An argument specifies the modification time value to use
5156\(instead of that of the visited file), in the form of a list 5151\(instead of that of the visited file), in the form of a list
5157\(HIGH . LOW) or (HIGH LOW). */) 5152\(HIGH LOW USEC PSEC) as returned by `current-time'. */)
5158 (Lisp_Object time_list) 5153 (Lisp_Object time_list)
5159{ 5154{
5160 if (!NILP (time_list)) 5155 if (!NILP (time_list))
5161 { 5156 {
5162 CONS_TO_INTEGER (time_list, time_t, current_buffer->modtime); 5157 current_buffer->modtime = lisp_time_argument (time_list, 0);
5163 current_buffer->modtime_size = -1; 5158 current_buffer->modtime_size = -1;
5164 } 5159 }
5165 else 5160 else
@@ -5181,7 +5176,7 @@ An argument specifies the modification time value to use
5181 5176
5182 if (stat (SSDATA (filename), &st) >= 0) 5177 if (stat (SSDATA (filename), &st) >= 0)
5183 { 5178 {
5184 current_buffer->modtime = st.st_mtime; 5179 current_buffer->modtime = get_stat_mtime (&st);
5185 current_buffer->modtime_size = st.st_size; 5180 current_buffer->modtime_size = st.st_size;
5186 } 5181 }
5187 } 5182 }
diff --git a/src/fns.c b/src/fns.c
index 676e53ccbd8..515cd28328b 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -80,7 +80,7 @@ Other values of LIMIT are ignored. */)
80 { 80 {
81 EMACS_TIME t; 81 EMACS_TIME t;
82 EMACS_GET_TIME (t); 82 EMACS_GET_TIME (t);
83 seed_random (getpid () ^ EMACS_SECS (t) ^ EMACS_USECS (t)); 83 seed_random (getpid () ^ EMACS_SECS (t) ^ EMACS_NSECS (t));
84 } 84 }
85 85
86 if (NATNUMP (limit) && XFASTINT (limit) != 0) 86 if (NATNUMP (limit) && XFASTINT (limit) != 0)
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 4cf421b6616..51c56e49540 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1612,16 +1612,16 @@ xg_maybe_add_timer (gpointer data)
1612{ 1612{
1613 struct xg_dialog_data *dd = (struct xg_dialog_data *) data; 1613 struct xg_dialog_data *dd = (struct xg_dialog_data *) data;
1614 EMACS_TIME next_time = timer_check (); 1614 EMACS_TIME next_time = timer_check ();
1615 long secs = EMACS_SECS (next_time);
1616 long usecs = EMACS_USECS (next_time);
1617 1615
1618 dd->timerid = 0; 1616 dd->timerid = 0;
1619 1617
1620 if (secs >= 0 && usecs >= 0 && secs < ((guint)-1)/1000) 1618 if (EMACS_TIME_VALID_P (next_time))
1621 { 1619 {
1622 dd->timerid = g_timeout_add (secs * 1000 + usecs/1000, 1620 time_t s = EMACS_SECS (next_time);
1623 xg_maybe_add_timer, 1621 int per_ms = EMACS_TIME_RESOLUTION / 1000;
1624 dd); 1622 int ms = (EMACS_NSECS (next_time) + per_ms - 1) / per_ms;
1623 if (s <= ((guint) -1 - ms) / 1000)
1624 dd->timerid = g_timeout_add (s * 1000 + ms, xg_maybe_add_timer, dd);
1625 } 1625 }
1626 return FALSE; 1626 return FALSE;
1627} 1627}
diff --git a/src/image.c b/src/image.c
index 103f0a7feb6..47b14a333e9 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1062,11 +1062,8 @@ check_image_size (struct frame *f, int width, int height)
1062void 1062void
1063prepare_image_for_display (struct frame *f, struct image *img) 1063prepare_image_for_display (struct frame *f, struct image *img)
1064{ 1064{
1065 EMACS_TIME t;
1066
1067 /* We're about to display IMG, so set its timestamp to `now'. */ 1065 /* We're about to display IMG, so set its timestamp to `now'. */
1068 EMACS_GET_TIME (t); 1066 EMACS_GET_TIME (img->timestamp);
1069 img->timestamp = EMACS_SECS (t);
1070 1067
1071 /* If IMG doesn't have a pixmap yet, load it now, using the image 1068 /* If IMG doesn't have a pixmap yet, load it now, using the image
1072 type dependent loader function. */ 1069 type dependent loader function. */
@@ -1514,8 +1511,8 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1514 else if (INTEGERP (Vimage_cache_eviction_delay)) 1511 else if (INTEGERP (Vimage_cache_eviction_delay))
1515 { 1512 {
1516 /* Free cache based on timestamp. */ 1513 /* Free cache based on timestamp. */
1517 EMACS_TIME t; 1514 EMACS_TIME old, t;
1518 double old, delay; 1515 double delay;
1519 ptrdiff_t nimages = 0; 1516 ptrdiff_t nimages = 0;
1520 1517
1521 for (i = 0; i < c->used; ++i) 1518 for (i = 0; i < c->used; ++i)
@@ -1530,12 +1527,12 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1530 delay = max (delay, 1); 1527 delay = max (delay, 1);
1531 1528
1532 EMACS_GET_TIME (t); 1529 EMACS_GET_TIME (t);
1533 old = EMACS_SECS (t) - delay; 1530 EMACS_SUB_TIME (old, t, EMACS_TIME_FROM_DOUBLE (delay));
1534 1531
1535 for (i = 0; i < c->used; ++i) 1532 for (i = 0; i < c->used; ++i)
1536 { 1533 {
1537 struct image *img = c->images[i]; 1534 struct image *img = c->images[i];
1538 if (img && img->timestamp < old) 1535 if (img && EMACS_TIME_LT (img->timestamp, old))
1539 { 1536 {
1540 free_image (f, img); 1537 free_image (f, img);
1541 ++nfreed; 1538 ++nfreed;
@@ -1708,7 +1705,6 @@ lookup_image (struct frame *f, Lisp_Object spec)
1708{ 1705{
1709 struct image *img; 1706 struct image *img;
1710 EMACS_UINT hash; 1707 EMACS_UINT hash;
1711 EMACS_TIME now;
1712 1708
1713 /* F must be a window-system frame, and SPEC must be a valid image 1709 /* F must be a window-system frame, and SPEC must be a valid image
1714 specification. */ 1710 specification. */
@@ -1802,8 +1798,7 @@ lookup_image (struct frame *f, Lisp_Object spec)
1802 } 1798 }
1803 1799
1804 /* We're using IMG, so set its timestamp to `now'. */ 1800 /* We're using IMG, so set its timestamp to `now'. */
1805 EMACS_GET_TIME (now); 1801 EMACS_GET_TIME (img->timestamp);
1806 img->timestamp = EMACS_SECS (now);
1807 1802
1808 /* Value is the image id. */ 1803 /* Value is the image id. */
1809 return img->id; 1804 return img->id;
diff --git a/src/keyboard.c b/src/keyboard.c
index 3e197ab4938..9b80c5c7019 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -2020,12 +2020,13 @@ start_polling (void)
2020 if (poll_timer == NULL 2020 if (poll_timer == NULL
2021 || EMACS_SECS (poll_timer->interval) != polling_period) 2021 || EMACS_SECS (poll_timer->interval) != polling_period)
2022 { 2022 {
2023 time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t)));
2023 EMACS_TIME interval; 2024 EMACS_TIME interval;
2024 2025
2025 if (poll_timer) 2026 if (poll_timer)
2026 cancel_atimer (poll_timer); 2027 cancel_atimer (poll_timer);
2027 2028
2028 EMACS_SET_SECS_USECS (interval, polling_period, 0); 2029 EMACS_SET_SECS_USECS (interval, period, 0);
2029 poll_timer = start_atimer (ATIMER_CONTINUOUS, interval, 2030 poll_timer = start_atimer (ATIMER_CONTINUOUS, interval,
2030 poll_for_input, NULL); 2031 poll_for_input, NULL);
2031 } 2032 }
@@ -2093,7 +2094,7 @@ void
2093bind_polling_period (int n) 2094bind_polling_period (int n)
2094{ 2095{
2095#ifdef POLL_FOR_INPUT 2096#ifdef POLL_FOR_INPUT
2096 int new = polling_period; 2097 EMACS_INT new = polling_period;
2097 2098
2098 if (n > new) 2099 if (n > new)
2099 new = n; 2100 new = n;
@@ -2223,7 +2224,7 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object,
2223/* Input of single characters from keyboard */ 2224/* Input of single characters from keyboard */
2224 2225
2225static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, int *used_mouse_menu, 2226static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, int *used_mouse_menu,
2226 struct timeval *end_time); 2227 EMACS_TIME *end_time);
2227static void record_char (Lisp_Object c); 2228static void record_char (Lisp_Object c);
2228 2229
2229static Lisp_Object help_form_saved_window_configs; 2230static Lisp_Object help_form_saved_window_configs;
@@ -2275,7 +2276,7 @@ do { if (polling_stopped_here) start_polling (); \
2275Lisp_Object 2276Lisp_Object
2276read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, 2277read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
2277 Lisp_Object prev_event, 2278 Lisp_Object prev_event,
2278 int *used_mouse_menu, struct timeval *end_time) 2279 int *used_mouse_menu, EMACS_TIME *end_time)
2279{ 2280{
2280 volatile Lisp_Object c; 2281 volatile Lisp_Object c;
2281 ptrdiff_t jmpcount; 2282 ptrdiff_t jmpcount;
@@ -3783,7 +3784,7 @@ clear_event (struct input_event *event)
3783static Lisp_Object 3784static Lisp_Object
3784kbd_buffer_get_event (KBOARD **kbp, 3785kbd_buffer_get_event (KBOARD **kbp,
3785 int *used_mouse_menu, 3786 int *used_mouse_menu,
3786 struct timeval *end_time) 3787 EMACS_TIME *end_time)
3787{ 3788{
3788 Lisp_Object obj; 3789 Lisp_Object obj;
3789 3790
@@ -3857,8 +3858,9 @@ kbd_buffer_get_event (KBOARD **kbp,
3857 else 3858 else
3858 { 3859 {
3859 EMACS_SUB_TIME (duration, *end_time, duration); 3860 EMACS_SUB_TIME (duration, *end_time, duration);
3860 wait_reading_process_output (EMACS_SECS (duration), 3861 wait_reading_process_output (min (EMACS_SECS (duration),
3861 EMACS_USECS (duration), 3862 INTMAX_MAX),
3863 EMACS_NSECS (duration),
3862 -1, 1, Qnil, NULL, 0); 3864 -1, 1, Qnil, NULL, 0);
3863 } 3865 }
3864 } 3866 }
@@ -4253,7 +4255,7 @@ timer_start_idle (void)
4253 Lisp_Object timers; 4255 Lisp_Object timers;
4254 4256
4255 /* If we are already in the idle state, do nothing. */ 4257 /* If we are already in the idle state, do nothing. */
4256 if (! EMACS_TIME_NEG_P (timer_idleness_start_time)) 4258 if (EMACS_TIME_VALID_P (timer_idleness_start_time))
4257 return; 4259 return;
4258 4260
4259 EMACS_GET_TIME (timer_idleness_start_time); 4261 EMACS_GET_TIME (timer_idleness_start_time);
@@ -4267,7 +4269,7 @@ timer_start_idle (void)
4267 4269
4268 timer = XCAR (timers); 4270 timer = XCAR (timers);
4269 4271
4270 if (!VECTORP (timer) || ASIZE (timer) != 8) 4272 if (!VECTORP (timer) || ASIZE (timer) != 9)
4271 continue; 4273 continue;
4272 ASET (timer, 0, Qnil); 4274 ASET (timer, 0, Qnil);
4273 } 4275 }
@@ -4278,7 +4280,7 @@ timer_start_idle (void)
4278static void 4280static void
4279timer_stop_idle (void) 4281timer_stop_idle (void)
4280{ 4282{
4281 EMACS_SET_SECS_USECS (timer_idleness_start_time, -1, -1); 4283 EMACS_SET_INVALID_TIME (timer_idleness_start_time);
4282} 4284}
4283 4285
4284/* Resume idle timer from last idle start time. */ 4286/* Resume idle timer from last idle start time. */
@@ -4286,7 +4288,7 @@ timer_stop_idle (void)
4286static void 4288static void
4287timer_resume_idle (void) 4289timer_resume_idle (void)
4288{ 4290{
4289 if (! EMACS_TIME_NEG_P (timer_idleness_start_time)) 4291 if (EMACS_TIME_VALID_P (timer_idleness_start_time))
4290 return; 4292 return;
4291 4293
4292 timer_idleness_start_time = timer_last_idleness_start_time; 4294 timer_idleness_start_time = timer_last_idleness_start_time;
@@ -4300,6 +4302,24 @@ struct input_event last_timer_event EXTERNALLY_VISIBLE;
4300 ...). Each element has the form (FUN . ARGS). */ 4302 ...). Each element has the form (FUN . ARGS). */
4301Lisp_Object pending_funcalls; 4303Lisp_Object pending_funcalls;
4302 4304
4305/* If TIMER is a valid timer, return nonzero and place its value into
4306 *RESULT. Otherwise return zero. */
4307static int
4308decode_timer (Lisp_Object timer, EMACS_TIME *result)
4309{
4310 Lisp_Object *vector;
4311
4312 if (! (VECTORP (timer) && ASIZE (timer) == 9))
4313 return 0;
4314 vector = XVECTOR (timer)->contents;
4315 if (! NILP (vector[0]))
4316 return 0;
4317
4318 return decode_time_components (vector[1], vector[2], vector[3], vector[4],
4319 result, 0);
4320}
4321
4322
4303/* Check whether a timer has fired. To prevent larger problems we simply 4323/* Check whether a timer has fired. To prevent larger problems we simply
4304 disregard elements that are not proper timers. Do not make a circular 4324 disregard elements that are not proper timers. Do not make a circular
4305 timer list for the time being. 4325 timer list for the time being.
@@ -4317,17 +4337,16 @@ timer_check_2 (void)
4317{ 4337{
4318 EMACS_TIME nexttime; 4338 EMACS_TIME nexttime;
4319 EMACS_TIME now; 4339 EMACS_TIME now;
4320 EMACS_TIME idleness_now IF_LINT (= {0}); 4340 EMACS_TIME idleness_now;
4321 Lisp_Object timers, idle_timers, chosen_timer; 4341 Lisp_Object timers, idle_timers, chosen_timer;
4322 struct gcpro gcpro1, gcpro2, gcpro3; 4342 struct gcpro gcpro1, gcpro2, gcpro3;
4323 4343
4324 EMACS_SET_SECS (nexttime, -1); 4344 EMACS_SET_INVALID_TIME (nexttime);
4325 EMACS_SET_USECS (nexttime, -1);
4326 4345
4327 /* Always consider the ordinary timers. */ 4346 /* Always consider the ordinary timers. */
4328 timers = Vtimer_list; 4347 timers = Vtimer_list;
4329 /* Consider the idle timers only if Emacs is idle. */ 4348 /* Consider the idle timers only if Emacs is idle. */
4330 if (! EMACS_TIME_NEG_P (timer_idleness_start_time)) 4349 if (EMACS_TIME_VALID_P (timer_idleness_start_time))
4331 idle_timers = Vtimer_idle_list; 4350 idle_timers = Vtimer_idle_list;
4332 else 4351 else
4333 idle_timers = Qnil; 4352 idle_timers = Qnil;
@@ -4345,8 +4364,10 @@ timer_check_2 (void)
4345 if (CONSP (timers) || CONSP (idle_timers)) 4364 if (CONSP (timers) || CONSP (idle_timers))
4346 { 4365 {
4347 EMACS_GET_TIME (now); 4366 EMACS_GET_TIME (now);
4348 if (! EMACS_TIME_NEG_P (timer_idleness_start_time)) 4367 if (EMACS_TIME_VALID_P (timer_idleness_start_time))
4349 EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time); 4368 EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time);
4369 else
4370 EMACS_SET_SECS_NSECS (idleness_now, 0, 0);
4350 } 4371 }
4351 4372
4352 while (CONSP (timers) || CONSP (idle_timers)) 4373 while (CONSP (timers) || CONSP (idle_timers))
@@ -4355,113 +4376,84 @@ timer_check_2 (void)
4355 Lisp_Object timer = Qnil, idle_timer = Qnil; 4376 Lisp_Object timer = Qnil, idle_timer = Qnil;
4356 EMACS_TIME timer_time, idle_timer_time; 4377 EMACS_TIME timer_time, idle_timer_time;
4357 EMACS_TIME difference; 4378 EMACS_TIME difference;
4358 EMACS_TIME timer_difference IF_LINT (= {0}); 4379 EMACS_TIME timer_difference, idle_timer_difference;
4359 EMACS_TIME idle_timer_difference IF_LINT (= {0}); 4380 int ripe, timer_ripe = 0, idle_timer_ripe = 0;
4360 4381
4361 /* Skip past invalid timers and timers already handled. */ 4382 EMACS_SET_INVALID_TIME (timer_difference);
4383 EMACS_SET_INVALID_TIME (idle_timer_difference);
4384
4385 /* Set TIMER and TIMER_DIFFERENCE
4386 based on the next ordinary timer.
4387 TIMER_DIFFERENCE is the distance in time from NOW to when
4388 this timer becomes ripe (negative if it's already ripe).
4389 Skip past invalid timers and timers already handled. */
4362 if (CONSP (timers)) 4390 if (CONSP (timers))
4363 { 4391 {
4364 timer = XCAR (timers); 4392 timer = XCAR (timers);
4365 if (!VECTORP (timer) || ASIZE (timer) != 8) 4393 if (! decode_timer (timer, &timer_time))
4366 { 4394 {
4367 timers = XCDR (timers); 4395 timers = XCDR (timers);
4368 continue; 4396 continue;
4369 } 4397 }
4370 vector = XVECTOR (timer)->contents;
4371 4398
4372 if (!INTEGERP (vector[1]) || !INTEGERP (vector[2]) 4399 timer_ripe = EMACS_TIME_LE (timer_time, now);
4373 || !INTEGERP (vector[3]) 4400 if (timer_ripe)
4374 || ! NILP (vector[0])) 4401 EMACS_SUB_TIME (timer_difference, now, timer_time);
4375 { 4402 else
4376 timers = XCDR (timers); 4403 EMACS_SUB_TIME (timer_difference, timer_time, now);
4377 continue;
4378 }
4379 } 4404 }
4405
4406 /* Likewise for IDLE_TIMER and IDLE_TIMER_DIFFERENCE
4407 based on the next idle timer. */
4380 if (CONSP (idle_timers)) 4408 if (CONSP (idle_timers))
4381 { 4409 {
4382 timer = XCAR (idle_timers); 4410 idle_timer = XCAR (idle_timers);
4383 if (!VECTORP (timer) || ASIZE (timer) != 8) 4411 if (! decode_timer (idle_timer, &idle_timer_time))
4384 {
4385 idle_timers = XCDR (idle_timers);
4386 continue;
4387 }
4388 vector = XVECTOR (timer)->contents;
4389
4390 if (!INTEGERP (vector[1]) || !INTEGERP (vector[2])
4391 || !INTEGERP (vector[3])
4392 || ! NILP (vector[0]))
4393 { 4412 {
4394 idle_timers = XCDR (idle_timers); 4413 idle_timers = XCDR (idle_timers);
4395 continue; 4414 continue;
4396 } 4415 }
4397 }
4398
4399 /* Set TIMER, TIMER_TIME and TIMER_DIFFERENCE
4400 based on the next ordinary timer.
4401 TIMER_DIFFERENCE is the distance in time from NOW to when
4402 this timer becomes ripe (negative if it's already ripe). */
4403 if (CONSP (timers))
4404 {
4405 timer = XCAR (timers);
4406 vector = XVECTOR (timer)->contents;
4407 EMACS_SET_SECS (timer_time,
4408 (XINT (vector[1]) << 16) | (XINT (vector[2])));
4409 EMACS_SET_USECS (timer_time, XINT (vector[3]));
4410 EMACS_SUB_TIME (timer_difference, timer_time, now);
4411 }
4412 4416
4413 /* Set IDLE_TIMER, IDLE_TIMER_TIME and IDLE_TIMER_DIFFERENCE 4417 idle_timer_ripe = EMACS_TIME_LE (idle_timer_time, idleness_now);
4414 based on the next idle timer. */ 4418 if (idle_timer_ripe)
4415 if (CONSP (idle_timers)) 4419 EMACS_SUB_TIME (idle_timer_difference,
4416 { 4420 idleness_now, idle_timer_time);
4417 idle_timer = XCAR (idle_timers); 4421 else
4418 vector = XVECTOR (idle_timer)->contents; 4422 EMACS_SUB_TIME (idle_timer_difference,
4419 EMACS_SET_SECS (idle_timer_time, 4423 idle_timer_time, idleness_now);
4420 (XINT (vector[1]) << 16) | (XINT (vector[2])));
4421 EMACS_SET_USECS (idle_timer_time, XINT (vector[3]));
4422 EMACS_SUB_TIME (idle_timer_difference, idle_timer_time, idleness_now);
4423 } 4424 }
4424 4425
4425 /* Decide which timer is the next timer, 4426 /* Decide which timer is the next timer,
4426 and set CHOSEN_TIMER, VECTOR and DIFFERENCE accordingly. 4427 and set CHOSEN_TIMER, DIFFERENCE, and RIPE accordingly.
4427 Also step down the list where we found that timer. */ 4428 Also step down the list where we found that timer. */
4428 4429
4429 if (CONSP (timers) && CONSP (idle_timers)) 4430 if (EMACS_TIME_VALID_P (timer_difference)
4430 { 4431 && (! EMACS_TIME_VALID_P (idle_timer_difference)
4431 EMACS_TIME temp; 4432 || idle_timer_ripe < timer_ripe
4432 EMACS_SUB_TIME (temp, timer_difference, idle_timer_difference); 4433 || (idle_timer_ripe == timer_ripe
4433 if (EMACS_TIME_NEG_P (temp)) 4434 && (timer_ripe
4434 { 4435 ? EMACS_TIME_LT (idle_timer_difference,
4435 chosen_timer = timer; 4436 timer_difference)
4436 timers = XCDR (timers); 4437 : EMACS_TIME_LT (timer_difference,
4437 difference = timer_difference; 4438 idle_timer_difference)))))
4438 }
4439 else
4440 {
4441 chosen_timer = idle_timer;
4442 idle_timers = XCDR (idle_timers);
4443 difference = idle_timer_difference;
4444 }
4445 }
4446 else if (CONSP (timers))
4447 { 4439 {
4448 chosen_timer = timer; 4440 chosen_timer = timer;
4449 timers = XCDR (timers); 4441 timers = XCDR (timers);
4450 difference = timer_difference; 4442 difference = timer_difference;
4443 ripe = timer_ripe;
4451 } 4444 }
4452 else 4445 else
4453 { 4446 {
4454 chosen_timer = idle_timer; 4447 chosen_timer = idle_timer;
4455 idle_timers = XCDR (idle_timers); 4448 idle_timers = XCDR (idle_timers);
4456 difference = idle_timer_difference; 4449 difference = idle_timer_difference;
4450 ripe = idle_timer_ripe;
4457 } 4451 }
4458 vector = XVECTOR (chosen_timer)->contents;
4459 4452
4460 /* If timer is ripe, run it if it hasn't been run. */ 4453 /* If timer is ripe, run it if it hasn't been run. */
4461 if (EMACS_TIME_NEG_P (difference) 4454 if (ripe)
4462 || (EMACS_SECS (difference) == 0
4463 && EMACS_USECS (difference) == 0))
4464 { 4455 {
4456 vector = XVECTOR (chosen_timer)->contents;
4465 if (NILP (vector[0])) 4457 if (NILP (vector[0]))
4466 { 4458 {
4467 ptrdiff_t count = SPECPDL_INDEX (); 4459 ptrdiff_t count = SPECPDL_INDEX ();
@@ -4508,7 +4500,7 @@ timer_check_2 (void)
4508 timer list for the time being. 4500 timer list for the time being.
4509 4501
4510 Returns the time to wait until the next timer fires. 4502 Returns the time to wait until the next timer fires.
4511 If no timer is active, return -1. 4503 If no timer is active, return an invalid value.
4512 4504
4513 As long as any timer is ripe, we run it. */ 4505 As long as any timer is ripe, we run it. */
4514 4506
@@ -4521,33 +4513,29 @@ timer_check (void)
4521 { 4513 {
4522 nexttime = timer_check_2 (); 4514 nexttime = timer_check_2 ();
4523 } 4515 }
4524 while (EMACS_SECS (nexttime) == 0 && EMACS_USECS (nexttime) == 0); 4516 while (EMACS_SECS (nexttime) == 0 && EMACS_NSECS (nexttime) == 0);
4525 4517
4526 return nexttime; 4518 return nexttime;
4527} 4519}
4528 4520
4529DEFUN ("current-idle-time", Fcurrent_idle_time, Scurrent_idle_time, 0, 0, 0, 4521DEFUN ("current-idle-time", Fcurrent_idle_time, Scurrent_idle_time, 0, 0, 0,
4530 doc: /* Return the current length of Emacs idleness, or nil. 4522 doc: /* Return the current length of Emacs idleness, or nil.
4531The value when Emacs is idle is a list of three integers. The first has 4523The value when Emacs is idle is a list of four integers (HIGH LOW USEC PSEC)
4532the most significant 16 bits of the seconds, while the second has the least 4524in the same style as (current-time).
4533significant 16 bits. The third integer gives the microsecond count.
4534 4525
4535The value when Emacs is not idle is nil. 4526The value when Emacs is not idle is nil.
4536 4527
4537The microsecond count is zero on systems that do not provide 4528NSEC is a multiple of the system clock resolution. */)
4538resolution finer than a second. */)
4539 (void) 4529 (void)
4540{ 4530{
4541 if (! EMACS_TIME_NEG_P (timer_idleness_start_time)) 4531 if (EMACS_TIME_VALID_P (timer_idleness_start_time))
4542 { 4532 {
4543 EMACS_TIME now, idleness_now; 4533 EMACS_TIME now, idleness_now;
4544 4534
4545 EMACS_GET_TIME (now); 4535 EMACS_GET_TIME (now);
4546 EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time); 4536 EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time);
4547 4537
4548 return list3 (make_number ((EMACS_SECS (idleness_now) >> 16) & 0xffff), 4538 return make_lisp_time (idleness_now);
4549 make_number ((EMACS_SECS (idleness_now) >> 0) & 0xffff),
4550 make_number (EMACS_USECS (idleness_now)));
4551 } 4539 }
4552 4540
4553 return Qnil; 4541 return Qnil;
@@ -10735,7 +10723,7 @@ stuff_buffered_input (Lisp_Object stuffstring)
10735} 10723}
10736 10724
10737void 10725void
10738set_waiting_for_input (struct timeval *time_to_clear) 10726set_waiting_for_input (EMACS_TIME *time_to_clear)
10739{ 10727{
10740 input_available_clear_time = time_to_clear; 10728 input_available_clear_time = time_to_clear;
10741 10729
@@ -11358,7 +11346,7 @@ init_keyboard (void)
11358 quit_char = Ctl ('g'); 11346 quit_char = Ctl ('g');
11359 Vunread_command_events = Qnil; 11347 Vunread_command_events = Qnil;
11360 unread_command_char = -1; 11348 unread_command_char = -1;
11361 EMACS_SET_SECS_USECS (timer_idleness_start_time, -1, -1); 11349 EMACS_SET_INVALID_TIME (timer_idleness_start_time);
11362 total_keys = 0; 11350 total_keys = 0;
11363 recent_keys_index = 0; 11351 recent_keys_index = 0;
11364 kbd_fetch_ptr = kbd_buffer; 11352 kbd_fetch_ptr = kbd_buffer;
diff --git a/src/lisp.h b/src/lisp.h
index a88bf10c8bc..dd8cdd348b2 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2954,6 +2954,7 @@ EXFUN (Fnarrow_to_region, 2);
2954EXFUN (Fwiden, 0); 2954EXFUN (Fwiden, 0);
2955EXFUN (Fuser_login_name, 1); 2955EXFUN (Fuser_login_name, 1);
2956EXFUN (Fsystem_name, 0); 2956EXFUN (Fsystem_name, 0);
2957extern void time_overflow (void) NO_RETURN;
2957EXFUN (Fcurrent_time, 0); 2958EXFUN (Fcurrent_time, 0);
2958EXFUN (Fget_internal_run_time, 0); 2959EXFUN (Fget_internal_run_time, 0);
2959extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, int); 2960extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, int);
@@ -3244,7 +3245,7 @@ EXFUN (Fkill_process, 2);
3244EXFUN (Fwaiting_for_user_input_p, 0); 3245EXFUN (Fwaiting_for_user_input_p, 0);
3245extern Lisp_Object Qprocessp; 3246extern Lisp_Object Qprocessp;
3246extern void kill_buffer_processes (Lisp_Object); 3247extern void kill_buffer_processes (Lisp_Object);
3247extern int wait_reading_process_output (int, int, int, int, 3248extern int wait_reading_process_output (intmax_t, int, int, int,
3248 Lisp_Object, 3249 Lisp_Object,
3249 struct Lisp_Process *, 3250 struct Lisp_Process *,
3250 int); 3251 int);
diff --git a/src/lread.c b/src/lread.c
index 96868c2da89..fee97044a73 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -601,17 +601,9 @@ read_filtered_event (int no_switch_frame, int ascii_required,
601 /* Compute timeout. */ 601 /* Compute timeout. */
602 if (NUMBERP (seconds)) 602 if (NUMBERP (seconds))
603 { 603 {
604 EMACS_TIME wait_time;
605 int sec, usec;
606 double duration = extract_float (seconds); 604 double duration = extract_float (seconds);
607 605 EMACS_TIME wait_time = EMACS_TIME_FROM_DOUBLE (duration);
608 if (0 < duration)
609 duration_to_sec_usec (duration, &sec, &usec);
610 else
611 sec = usec = 0;
612
613 EMACS_GET_TIME (end_time); 606 EMACS_GET_TIME (end_time);
614 EMACS_SET_SECS_USECS (wait_time, sec, usec);
615 EMACS_ADD_TIME (end_time, end_time, wait_time); 607 EMACS_ADD_TIME (end_time, end_time, wait_time);
616 } 608 }
617 609
diff --git a/src/msdos.c b/src/msdos.c
index c9bee400020..66911098ce0 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -4070,13 +4070,6 @@ sigprocmask (int how, const sigset_t *new_set, sigset_t *old_set)
4070#ifndef HAVE_SELECT 4070#ifndef HAVE_SELECT
4071#include "sysselect.h" 4071#include "sysselect.h"
4072 4072
4073#ifndef EMACS_TIME_ZERO_OR_NEG_P
4074#define EMACS_TIME_ZERO_OR_NEG_P(time) \
4075 ((long)(time).tv_sec < 0 \
4076 || ((time).tv_sec == 0 \
4077 && (long)(time).tv_usec <= 0))
4078#endif
4079
4080/* This yields the rest of the current time slice to the task manager. 4073/* This yields the rest of the current time slice to the task manager.
4081 It should be called by any code which knows that it has nothing 4074 It should be called by any code which knows that it has nothing
4082 useful to do except idle. 4075 useful to do except idle.
@@ -4145,12 +4138,12 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
4145 4138
4146 /* When seconds wrap around, we assume that no more than 4139 /* When seconds wrap around, we assume that no more than
4147 1 minute passed since last `gettime'. */ 4140 1 minute passed since last `gettime'. */
4148 if (EMACS_TIME_NEG_P (cldiff)) 4141 if (EMACS_TIME_SIGN (cldiff) < 0)
4149 EMACS_SET_SECS (cldiff, EMACS_SECS (cldiff) + 60); 4142 EMACS_SET_SECS (cldiff, EMACS_SECS (cldiff) + 60);
4150 EMACS_SUB_TIME (*timeout, *timeout, cldiff); 4143 EMACS_SUB_TIME (*timeout, *timeout, cldiff);
4151 4144
4152 /* Stop when timeout value crosses zero. */ 4145 /* Stop when timeout value crosses zero. */
4153 if (EMACS_TIME_ZERO_OR_NEG_P (*timeout)) 4146 if (EMACS_TIME_SIGN (*timeout) <= 0)
4154 return 0; 4147 return 0;
4155 cllast = clnow; 4148 cllast = clnow;
4156 dos_yield_time_slice (); 4149 dos_yield_time_slice ();
diff --git a/src/nsterm.h b/src/nsterm.h
index bc535b47d97..9158b78e7ba 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -824,7 +824,8 @@ extern int x_display_pixel_width (struct ns_display_info *);
824 824
825/* This in nsterm.m */ 825/* This in nsterm.m */
826extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds, 826extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds,
827 fd_set *exceptfds, struct timeval *timeout); 827 fd_set *exceptfds, EMACS_TIME *timeout,
828 sigset_t *sigmask);
828extern unsigned long ns_get_rgb_color (struct frame *f, 829extern unsigned long ns_get_rgb_color (struct frame *f,
829 float r, float g, float b, float a); 830 float r, float g, float b, float a);
830extern NSPoint last_mouse_motion_position; 831extern NSPoint last_mouse_motion_position;
diff --git a/src/nsterm.m b/src/nsterm.m
index dd4969a1e2e..bf14e5c83b1 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -183,7 +183,6 @@ static NSTimer *timed_entry = 0;
183static NSTimer *fd_entry = nil; 183static NSTimer *fd_entry = nil;
184static NSTimer *scroll_repeat_entry = nil; 184static NSTimer *scroll_repeat_entry = nil;
185static fd_set select_readfds, t_readfds; 185static fd_set select_readfds, t_readfds;
186static struct timeval select_timeout;
187static int select_nfds; 186static int select_nfds;
188static NSAutoreleasePool *outerpool; 187static NSAutoreleasePool *outerpool;
189static struct input_event *emacs_event = NULL; 188static struct input_event *emacs_event = NULL;
@@ -381,67 +380,30 @@ ns_init_paths (void)
381 } 380 }
382} 381}
383 382
384
385static int
386timeval_subtract (struct timeval *result, struct timeval x, struct timeval y)
387/* --------------------------------------------------------------------------
388 Subtract the `struct timeval' values X and Y, storing the result in RESULT.
389 Return 1 if the difference is negative, otherwise 0.
390 -------------------------------------------------------------------------- */
391{
392 /* Perform the carry for the later subtraction by updating y.
393 This is safer because on some systems
394 the tv_sec member is unsigned. */
395 if (x.tv_usec < y.tv_usec)
396 {
397 int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
398 y.tv_usec -= 1000000 * nsec;
399 y.tv_sec += nsec;
400 }
401 if (x.tv_usec - y.tv_usec > 1000000)
402 {
403 int nsec = (y.tv_usec - x.tv_usec) / 1000000;
404 y.tv_usec += 1000000 * nsec;
405 y.tv_sec -= nsec;
406 }
407
408 /* Compute the time remaining to wait. tv_usec is certainly positive. */
409 result->tv_sec = x.tv_sec - y.tv_sec;
410 result->tv_usec = x.tv_usec - y.tv_usec;
411
412 /* Return indication of whether the result should be considered negative. */
413 return x.tv_sec < y.tv_sec;
414}
415
416static void 383static void
417ns_timeout (int usecs) 384ns_timeout (int usecs)
418/* -------------------------------------------------------------------------- 385/* --------------------------------------------------------------------------
419 Blocking timer utility used by ns_ring_bell 386 Blocking timer utility used by ns_ring_bell
420 -------------------------------------------------------------------------- */ 387 -------------------------------------------------------------------------- */
421{ 388{
422 struct timeval wakeup; 389 EMACS_TIME wakeup, delay;
423 390
424 EMACS_GET_TIME (wakeup); 391 EMACS_GET_TIME (wakeup);
425 392 EMACS_SET_SECS_USECS (delay, 0, usecs);
426 /* Compute time to wait until, propagating carry from usecs. */ 393 EMACS_ADD_TIME (wakeup, wakeup, delay);
427 wakeup.tv_usec += usecs;
428 wakeup.tv_sec += (wakeup.tv_usec / 1000000);
429 wakeup.tv_usec %= 1000000;
430 394
431 /* Keep waiting until past the time wakeup. */ 395 /* Keep waiting until past the time wakeup. */
432 while (1) 396 while (1)
433 { 397 {
434 struct timeval timeout; 398 EMACS_TIME timeout;
435 399
436 EMACS_GET_TIME (timeout); 400 EMACS_GET_TIME (timeout);
437 401 if (EMACS_TIME_LE (wakeup, timeout))
438 /* In effect, timeout = wakeup - timeout.
439 Break if result would be negative. */
440 if (timeval_subtract (&timeout, wakeup, timeout))
441 break; 402 break;
403 EMACS_SUB_TIME (timeout, wakeup, timeout);
442 404
443 /* Try to wait that long--but we might wake up sooner. */ 405 /* Try to wait that long--but we might wake up sooner. */
444 select (0, NULL, NULL, NULL, &timeout); 406 pselect (0, NULL, NULL, NULL, &timeout, NULL);
445 } 407 }
446} 408}
447 409
@@ -3537,7 +3499,7 @@ ns_read_socket (struct terminal *terminal, int expected,
3537 3499
3538int 3500int
3539ns_select (int nfds, fd_set *readfds, fd_set *writefds, 3501ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3540 fd_set *exceptfds, struct timeval *timeout) 3502 fd_set *exceptfds, EMACS_TIME *timeout, sigset_t *sigmask)
3541/* -------------------------------------------------------------------------- 3503/* --------------------------------------------------------------------------
3542 Replacement for select, checking for events 3504 Replacement for select, checking for events
3543 -------------------------------------------------------------------------- */ 3505 -------------------------------------------------------------------------- */
@@ -3545,12 +3507,14 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3545 int result; 3507 int result;
3546 double time; 3508 double time;
3547 NSEvent *ev; 3509 NSEvent *ev;
3510 struct timespec select_timeout;
3511
3548/* NSTRACE (ns_select); */ 3512/* NSTRACE (ns_select); */
3549 3513
3550 if (NSApp == nil || inNsSelect == 1 /* || ([NSApp isActive] == NO && 3514 if (NSApp == nil || inNsSelect == 1 /* || ([NSApp isActive] == NO &&
3551 [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil 3515 [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil
3552 inMode:NSDefaultRunLoopMode dequeue:NO] == nil) */) 3516 inMode:NSDefaultRunLoopMode dequeue:NO] == nil) */)
3553 return select (nfds, readfds, writefds, exceptfds, timeout); 3517 return pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask);
3554 3518
3555 /* Save file descriptor set, which gets overwritten in calls to select () 3519 /* Save file descriptor set, which gets overwritten in calls to select ()
3556 Note, this is called from process.c, and only readfds is ever set */ 3520 Note, this is called from process.c, and only readfds is ever set */
@@ -3563,8 +3527,9 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3563 select_nfds = 0; 3527 select_nfds = 0;
3564 3528
3565 /* Try an initial select for pending data on input files */ 3529 /* Try an initial select for pending data on input files */
3566 select_timeout.tv_sec = select_timeout.tv_usec = 0; 3530 select_timeout.tv_sec = select_timeout.tv_nsec = 0;
3567 result = select (nfds, readfds, writefds, exceptfds, &select_timeout); 3531 result = pselect (nfds, readfds, writefds, exceptfds,
3532 &select_timeout, sigmask);
3568 if (result) 3533 if (result)
3569 return result; 3534 return result;
3570 3535
@@ -3573,7 +3538,7 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3573 3538
3574 /* set a timeout and run the main AppKit event loop while continuing 3539 /* set a timeout and run the main AppKit event loop while continuing
3575 to monitor the files */ 3540 to monitor the files */
3576 time = ((double) timeout->tv_sec) + ((double) timeout->tv_usec)/1000000.0; 3541 time = EMACS_TIME_TO_DOUBLE (*timeout);
3577 timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time 3542 timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time
3578 target: NSApp 3543 target: NSApp
3579 selector: @selector (timeout_handler:) 3544 selector: @selector (timeout_handler:)
@@ -3581,7 +3546,7 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3581 repeats: YES] /* for safe removal */ 3546 repeats: YES] /* for safe removal */
3582 retain]; 3547 retain];
3583 3548
3584 /* set a periodic task to try the select () again */ 3549 /* set a periodic task to try the pselect () again */
3585 fd_entry = [[NSTimer scheduledTimerWithTimeInterval: 0.1 3550 fd_entry = [[NSTimer scheduledTimerWithTimeInterval: 0.1
3586 target: NSApp 3551 target: NSApp
3587 selector: @selector (fd_handler:) 3552 selector: @selector (fd_handler:)
@@ -3623,7 +3588,7 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3623 } 3588 }
3624 else 3589 else
3625 { 3590 {
3626 /* Received back from select () in fd_handler; copy the results */ 3591 /* Received back from pselect () in fd_handler; copy the results */
3627 if (readfds) 3592 if (readfds)
3628 memcpy (readfds, &select_readfds, sizeof (fd_set)); 3593 memcpy (readfds, &select_readfds, sizeof (fd_set));
3629 return t; 3594 return t;
@@ -4603,6 +4568,7 @@ ns_term_shutdown (int sig)
4603 -------------------------------------------------------------------------- */ 4568 -------------------------------------------------------------------------- */
4604{ 4569{
4605 int result; 4570 int result;
4571 struct timespec select_timeout;
4606 /* NSTRACE (fd_handler); */ 4572 /* NSTRACE (fd_handler); */
4607 4573
4608 if (select_nfds == 0) 4574 if (select_nfds == 0)
@@ -4610,9 +4576,8 @@ ns_term_shutdown (int sig)
4610 4576
4611 memcpy (&t_readfds, &select_readfds, sizeof (fd_set)); 4577 memcpy (&t_readfds, &select_readfds, sizeof (fd_set));
4612 4578
4613 select_timeout.tv_sec = select_timeout.tv_usec = 0; 4579 select_timeout.tv_sec = select_timeout.tv_nsec = 0;
4614 result = select (select_nfds, &t_readfds, (SELECT_TYPE *)0, (SELECT_TYPE *)0, 4580 result = pselect (select_nfds, &t_readfds, NULL, NULL, &select_timeout, NULL);
4615 &select_timeout);
4616 if (result) 4581 if (result)
4617 { 4582 {
4618 memcpy (&select_readfds, &t_readfds, sizeof (fd_set)); 4583 memcpy (&select_readfds, &t_readfds, sizeof (fd_set));
diff --git a/src/process.c b/src/process.c
index cb89cae99fe..0ee0e499d6e 100644
--- a/src/process.c
+++ b/src/process.c
@@ -228,13 +228,11 @@ static EMACS_INT update_tick;
228#endif 228#endif
229 229
230#if !defined (ADAPTIVE_READ_BUFFERING) && !defined (NO_ADAPTIVE_READ_BUFFERING) 230#if !defined (ADAPTIVE_READ_BUFFERING) && !defined (NO_ADAPTIVE_READ_BUFFERING)
231#ifdef EMACS_HAS_USECS
232#define ADAPTIVE_READ_BUFFERING 231#define ADAPTIVE_READ_BUFFERING
233#endif 232#endif
234#endif
235 233
236#ifdef ADAPTIVE_READ_BUFFERING 234#ifdef ADAPTIVE_READ_BUFFERING
237#define READ_OUTPUT_DELAY_INCREMENT 10000 235#define READ_OUTPUT_DELAY_INCREMENT (EMACS_TIME_RESOLUTION / 100)
238#define READ_OUTPUT_DELAY_MAX (READ_OUTPUT_DELAY_INCREMENT * 5) 236#define READ_OUTPUT_DELAY_MAX (READ_OUTPUT_DELAY_INCREMENT * 5)
239#define READ_OUTPUT_DELAY_MAX_MAX (READ_OUTPUT_DELAY_INCREMENT * 7) 237#define READ_OUTPUT_DELAY_MAX_MAX (READ_OUTPUT_DELAY_INCREMENT * 7)
240 238
@@ -3291,7 +3289,7 @@ usage: (make-network-process &rest ARGS) */)
3291 { 3289 {
3292 /* Unlike most other syscalls connect() cannot be called 3290 /* Unlike most other syscalls connect() cannot be called
3293 again. (That would return EALREADY.) The proper way to 3291 again. (That would return EALREADY.) The proper way to
3294 wait for completion is select(). */ 3292 wait for completion is pselect(). */
3295 int sc; 3293 int sc;
3296 socklen_t len; 3294 socklen_t len;
3297 SELECT_TYPE fdset; 3295 SELECT_TYPE fdset;
@@ -3299,8 +3297,7 @@ usage: (make-network-process &rest ARGS) */)
3299 FD_ZERO (&fdset); 3297 FD_ZERO (&fdset);
3300 FD_SET (s, &fdset); 3298 FD_SET (s, &fdset);
3301 QUIT; 3299 QUIT;
3302 sc = select (s + 1, (SELECT_TYPE *)0, &fdset, (SELECT_TYPE *)0, 3300 sc = pselect (s + 1, NULL, &fdset, NULL, NULL, NULL);
3303 (EMACS_TIME *)0);
3304 if (sc == -1) 3301 if (sc == -1)
3305 { 3302 {
3306 if (errno == EINTR) 3303 if (errno == EINTR)
@@ -3961,7 +3958,8 @@ If JUST-THIS-ONE is an integer, don't run any timers either.
3961Return non-nil if we received any output before the timeout expired. */) 3958Return non-nil if we received any output before the timeout expired. */)
3962 (register Lisp_Object process, Lisp_Object seconds, Lisp_Object millisec, Lisp_Object just_this_one) 3959 (register Lisp_Object process, Lisp_Object seconds, Lisp_Object millisec, Lisp_Object just_this_one)
3963{ 3960{
3964 int secs = -1, usecs = 0; 3961 intmax_t secs;
3962 int nsecs;
3965 3963
3966 if (! NILP (process)) 3964 if (! NILP (process))
3967 CHECK_PROCESS (process); 3965 CHECK_PROCESS (process);
@@ -3980,17 +3978,36 @@ Return non-nil if we received any output before the timeout expired. */)
3980 } 3978 }
3981 } 3979 }
3982 3980
3981 secs = 0;
3982 nsecs = -1;
3983
3983 if (!NILP (seconds)) 3984 if (!NILP (seconds))
3984 { 3985 {
3985 double duration = extract_float (seconds); 3986 if (INTEGERP (seconds))
3986 if (0 < duration) 3987 {
3987 duration_to_sec_usec (duration, &secs, &usecs); 3988 if (0 < XINT (seconds))
3989 {
3990 secs = XINT (seconds);
3991 nsecs = 0;
3992 }
3993 }
3994 else if (FLOATP (seconds))
3995 {
3996 if (0 < XFLOAT_DATA (seconds))
3997 {
3998 EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (seconds));
3999 secs = min (EMACS_SECS (t), INTMAX_MAX);
4000 nsecs = EMACS_NSECS (t);
4001 }
4002 }
4003 else
4004 wrong_type_argument (Qnumberp, seconds);
3988 } 4005 }
3989 else if (!NILP (process)) 4006 else if (! NILP (process))
3990 secs = 0; 4007 nsecs = 0;
3991 4008
3992 return 4009 return
3993 (wait_reading_process_output (secs, usecs, 0, 0, 4010 (wait_reading_process_output (secs, nsecs, 0, 0,
3994 Qnil, 4011 Qnil,
3995 !NILP (process) ? XPROCESS (process) : NULL, 4012 !NILP (process) ? XPROCESS (process) : NULL,
3996 NILP (just_this_one) ? 0 : 4013 NILP (just_this_one) ? 0 :
@@ -4231,34 +4248,19 @@ wait_reading_process_output_1 (void)
4231{ 4248{
4232} 4249}
4233 4250
4234/* Use a wrapper around select to work around a bug in gdb 5.3.
4235 Normally, the wrapper is optimized away by inlining.
4236
4237 If emacs is stopped inside select, the gdb backtrace doesn't
4238 show the function which called select, so it is practically
4239 impossible to step through wait_reading_process_output. */
4240
4241#ifndef select
4242static inline int
4243select_wrapper (int n, fd_set *rfd, fd_set *wfd, fd_set *xfd, struct timeval *tmo)
4244{
4245 return select (n, rfd, wfd, xfd, tmo);
4246}
4247#define select select_wrapper
4248#endif
4249
4250/* Read and dispose of subprocess output while waiting for timeout to 4251/* Read and dispose of subprocess output while waiting for timeout to
4251 elapse and/or keyboard input to be available. 4252 elapse and/or keyboard input to be available.
4252 4253
4253 TIME_LIMIT is: 4254 TIME_LIMIT is:
4254 timeout in seconds, or 4255 timeout in seconds
4255 zero for no limit, or 4256 If negative, gobble data immediately available but don't wait for any.
4256 -1 means gobble data immediately available but don't wait for any.
4257 4257
4258 MICROSECS is: 4258 NSECS is:
4259 an additional duration to wait, measured in microseconds. 4259 an additional duration to wait, measured in nanoseconds
4260 If this is nonzero and time_limit is 0, then the timeout 4260 If TIME_LIMIT is zero, then:
4261 consists of MICROSECS only. 4261 If NSECS == 0, there is no limit.
4262 If NSECS > 0, the timeout consists of NSEC only.
4263 If NSECS < 0, gobble data immediately, as if TIME_LIMIT were negative.
4262 4264
4263 READ_KBD is a lisp value: 4265 READ_KBD is a lisp value:
4264 0 to ignore keyboard input, or 4266 0 to ignore keyboard input, or
@@ -4285,7 +4287,7 @@ select_wrapper (int n, fd_set *rfd, fd_set *wfd, fd_set *xfd, struct timeval *tm
4285 Otherwise, return true if we received input from any process. */ 4287 Otherwise, return true if we received input from any process. */
4286 4288
4287int 4289int
4288wait_reading_process_output (int time_limit, int microsecs, int read_kbd, 4290wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4289 int do_display, 4291 int do_display,
4290 Lisp_Object wait_for_cell, 4292 Lisp_Object wait_for_cell,
4291 struct Lisp_Process *wait_proc, int just_wait_proc) 4293 struct Lisp_Process *wait_proc, int just_wait_proc)
@@ -4305,7 +4307,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4305 FD_ZERO (&Available); 4307 FD_ZERO (&Available);
4306 FD_ZERO (&Writeok); 4308 FD_ZERO (&Writeok);
4307 4309
4308 if (time_limit == 0 && microsecs == 0 && wait_proc && !NILP (Vinhibit_quit) 4310 if (time_limit == 0 && nsecs == 0 && wait_proc && !NILP (Vinhibit_quit)
4309 && !(CONSP (wait_proc->status) && EQ (XCAR (wait_proc->status), Qexit))) 4311 && !(CONSP (wait_proc->status) && EQ (XCAR (wait_proc->status), Qexit)))
4310 message ("Blocking call to accept-process-output with quit inhibited!!"); 4312 message ("Blocking call to accept-process-output with quit inhibited!!");
4311 4313
@@ -4317,12 +4319,20 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4317 make_number (waiting_for_user_input_p)); 4319 make_number (waiting_for_user_input_p));
4318 waiting_for_user_input_p = read_kbd; 4320 waiting_for_user_input_p = read_kbd;
4319 4321
4322 if (time_limit < 0)
4323 {
4324 time_limit = 0;
4325 nsecs = -1;
4326 }
4327 else if (TYPE_MAXIMUM (time_t) < time_limit)
4328 time_limit = TYPE_MAXIMUM (time_t);
4329
4320 /* Since we may need to wait several times, 4330 /* Since we may need to wait several times,
4321 compute the absolute time to return at. */ 4331 compute the absolute time to return at. */
4322 if (time_limit || microsecs) 4332 if (time_limit || nsecs) /* FIXME neither should be negative, no? */
4323 { 4333 {
4324 EMACS_GET_TIME (end_time); 4334 EMACS_GET_TIME (end_time);
4325 EMACS_SET_SECS_USECS (timeout, time_limit, microsecs); 4335 EMACS_SET_SECS_NSECS (timeout, time_limit, nsecs);
4326 EMACS_ADD_TIME (end_time, end_time, timeout); 4336 EMACS_ADD_TIME (end_time, end_time, timeout);
4327 } 4337 }
4328 4338
@@ -4346,7 +4356,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4346 4356
4347 /* Compute time from now till when time limit is up */ 4357 /* Compute time from now till when time limit is up */
4348 /* Exit if already run out */ 4358 /* Exit if already run out */
4349 if (time_limit == -1) 4359 if (nsecs < 0)
4350 { 4360 {
4351 /* -1 specified for timeout means 4361 /* -1 specified for timeout means
4352 gobble output available now 4362 gobble output available now
@@ -4354,12 +4364,12 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4354 4364
4355 EMACS_SET_SECS_USECS (timeout, 0, 0); 4365 EMACS_SET_SECS_USECS (timeout, 0, 0);
4356 } 4366 }
4357 else if (time_limit || microsecs) 4367 else if (time_limit || nsecs)
4358 { 4368 {
4359 EMACS_GET_TIME (timeout); 4369 EMACS_GET_TIME (timeout);
4360 EMACS_SUB_TIME (timeout, end_time, timeout); 4370 if (EMACS_TIME_LE (end_time, timeout))
4361 if (EMACS_TIME_NEG_P (timeout))
4362 break; 4371 break;
4372 EMACS_SUB_TIME (timeout, end_time, timeout);
4363 } 4373 }
4364 else 4374 else
4365 { 4375 {
@@ -4405,21 +4415,22 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4405 && requeued_events_pending_p ()) 4415 && requeued_events_pending_p ())
4406 break; 4416 break;
4407 4417
4408 if (! EMACS_TIME_NEG_P (timer_delay) && time_limit != -1) 4418 /* If time_limit is negative, we are not going to wait at all. */
4419 if (0 <= nsecs)
4409 { 4420 {
4410 EMACS_TIME difference; 4421 if (EMACS_TIME_VALID_P (timer_delay))
4411 EMACS_SUB_TIME (difference, timer_delay, timeout);
4412 if (EMACS_TIME_NEG_P (difference))
4413 { 4422 {
4414 timeout = timer_delay; 4423 if (EMACS_TIME_LT (timer_delay, timeout))
4415 timeout_reduced_for_timers = 1; 4424 {
4425 timeout = timer_delay;
4426 timeout_reduced_for_timers = 1;
4427 }
4428 }
4429 else
4430 {
4431 /* This is so a breakpoint can be put here. */
4432 wait_reading_process_output_1 ();
4416 } 4433 }
4417 }
4418 /* If time_limit is -1, we are not going to wait at all. */
4419 else if (time_limit != -1)
4420 {
4421 /* This is so a breakpoint can be put here. */
4422 wait_reading_process_output_1 ();
4423 } 4434 }
4424 } 4435 }
4425 4436
@@ -4448,14 +4459,14 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4448 Ctemp = write_mask; 4459 Ctemp = write_mask;
4449 4460
4450 EMACS_SET_SECS_USECS (timeout, 0, 0); 4461 EMACS_SET_SECS_USECS (timeout, 0, 0);
4451 if ((select (max (max_process_desc, max_input_desc) + 1, 4462 if ((pselect (max (max_process_desc, max_input_desc) + 1,
4452 &Atemp, 4463 &Atemp,
4453#ifdef NON_BLOCKING_CONNECT 4464#ifdef NON_BLOCKING_CONNECT
4454 (num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0), 4465 (num_pending_connects > 0 ? &Ctemp : NULL),
4455#else 4466#else
4456 (SELECT_TYPE *)0, 4467 NULL,
4457#endif 4468#endif
4458 (SELECT_TYPE *)0, &timeout) 4469 NULL, &timeout, NULL)
4459 <= 0)) 4470 <= 0))
4460 { 4471 {
4461 /* It's okay for us to do this and then continue with 4472 /* It's okay for us to do this and then continue with
@@ -4578,9 +4589,9 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4578 Vprocess_adaptive_read_buffering is nil. */ 4589 Vprocess_adaptive_read_buffering is nil. */
4579 if (process_output_skip && check_delay > 0) 4590 if (process_output_skip && check_delay > 0)
4580 { 4591 {
4581 int usecs = EMACS_USECS (timeout); 4592 int nsecs = EMACS_NSECS (timeout);
4582 if (EMACS_SECS (timeout) > 0 || usecs > READ_OUTPUT_DELAY_MAX) 4593 if (EMACS_SECS (timeout) > 0 || nsecs > READ_OUTPUT_DELAY_MAX)
4583 usecs = READ_OUTPUT_DELAY_MAX; 4594 nsecs = READ_OUTPUT_DELAY_MAX;
4584 for (channel = 0; check_delay > 0 && channel <= max_process_desc; channel++) 4595 for (channel = 0; check_delay > 0 && channel <= max_process_desc; channel++)
4585 { 4596 {
4586 proc = chan_process[channel]; 4597 proc = chan_process[channel];
@@ -4595,11 +4606,11 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4595 continue; 4606 continue;
4596 FD_CLR (channel, &Available); 4607 FD_CLR (channel, &Available);
4597 XPROCESS (proc)->read_output_skip = 0; 4608 XPROCESS (proc)->read_output_skip = 0;
4598 if (XPROCESS (proc)->read_output_delay < usecs) 4609 if (XPROCESS (proc)->read_output_delay < nsecs)
4599 usecs = XPROCESS (proc)->read_output_delay; 4610 nsecs = XPROCESS (proc)->read_output_delay;
4600 } 4611 }
4601 } 4612 }
4602 EMACS_SET_SECS_USECS (timeout, 0, usecs); 4613 EMACS_SET_SECS_NSECS (timeout, 0, nsecs);
4603 process_output_skip = 0; 4614 process_output_skip = 0;
4604 } 4615 }
4605#endif 4616#endif
@@ -4608,12 +4619,12 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4608#elif defined (HAVE_NS) 4619#elif defined (HAVE_NS)
4609 nfds = ns_select 4620 nfds = ns_select
4610#else 4621#else
4611 nfds = select 4622 nfds = pselect
4612#endif 4623#endif
4613 (max (max_process_desc, max_input_desc) + 1, 4624 (max (max_process_desc, max_input_desc) + 1,
4614 &Available, 4625 &Available,
4615 (check_write ? &Writeok : (SELECT_TYPE *)0), 4626 (check_write ? &Writeok : (SELECT_TYPE *)0),
4616 (SELECT_TYPE *)0, &timeout); 4627 NULL, &timeout, NULL);
4617 4628
4618#ifdef HAVE_GNUTLS 4629#ifdef HAVE_GNUTLS
4619 /* GnuTLS buffers data internally. In lowat mode it leaves 4630 /* GnuTLS buffers data internally. In lowat mode it leaves
@@ -4671,7 +4682,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4671 /* If we woke up due to SIGWINCH, actually change size now. */ 4682 /* If we woke up due to SIGWINCH, actually change size now. */
4672 do_pending_window_change (0); 4683 do_pending_window_change (0);
4673 4684
4674 if (time_limit && nfds == 0 && ! timeout_reduced_for_timers) 4685 if ((time_limit || nsecs) && nfds == 0 && ! timeout_reduced_for_timers)
4675 /* We wanted the full specified time, so return now. */ 4686 /* We wanted the full specified time, so return now. */
4676 break; 4687 break;
4677 if (nfds < 0) 4688 if (nfds < 0)
@@ -4823,7 +4834,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4823 if (wait_channel == channel) 4834 if (wait_channel == channel)
4824 { 4835 {
4825 wait_channel = -1; 4836 wait_channel = -1;
4826 time_limit = -1; 4837 nsecs = -1;
4827 got_some_input = 1; 4838 got_some_input = 1;
4828 } 4839 }
4829 proc = chan_process[channel]; 4840 proc = chan_process[channel];
@@ -5680,11 +5691,8 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5680 5691
5681 /* Put what we should have written in wait_queue. */ 5692 /* Put what we should have written in wait_queue. */
5682 write_queue_push (p, cur_object, cur_buf, cur_len, 1); 5693 write_queue_push (p, cur_object, cur_buf, cur_len, 1);
5683#ifdef EMACS_HAS_USECS 5694 wait_reading_process_output (0, 20 * 1000 * 1000,
5684 wait_reading_process_output (0, 20000, 0, 0, Qnil, NULL, 0); 5695 0, 0, Qnil, NULL, 0);
5685#else
5686 wait_reading_process_output (1, 0, 0, 0, Qnil, NULL, 0);
5687#endif
5688 /* Reread queue, to see what is left. */ 5696 /* Reread queue, to see what is left. */
5689 break; 5697 break;
5690 } 5698 }
@@ -6825,9 +6833,15 @@ extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
6825 Wait for timeout to elapse and/or keyboard input to be available. 6833 Wait for timeout to elapse and/or keyboard input to be available.
6826 6834
6827 time_limit is: 6835 time_limit is:
6828 timeout in seconds, or 6836 timeout in seconds
6829 zero for no limit, or 6837 If negative, gobble data immediately available but don't wait for any.
6830 -1 means gobble data immediately available but don't wait for any. 6838
6839 nsec is:
6840 an additional duration to wait, measured in nanoseconds
6841 If TIME_LIMIT is zero, then:
6842 If NSEC == 0, there is no limit.
6843 If NSEC > 0, the timeout consists of NSEC only.
6844 If NSECS < 0, gobble data immediately, as if TIME_LIMIT were negative.
6831 6845
6832 read_kbd is a Lisp_Object: 6846 read_kbd is a Lisp_Object:
6833 0 to ignore keyboard input, or 6847 0 to ignore keyboard input, or
@@ -6844,7 +6858,7 @@ extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
6844 Return true if we received input from any process. */ 6858 Return true if we received input from any process. */
6845 6859
6846int 6860int
6847wait_reading_process_output (int time_limit, int microsecs, int read_kbd, 6861wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
6848 int do_display, 6862 int do_display,
6849 Lisp_Object wait_for_cell, 6863 Lisp_Object wait_for_cell,
6850 struct Lisp_Process *wait_proc, int just_wait_proc) 6864 struct Lisp_Process *wait_proc, int just_wait_proc)
@@ -6854,11 +6868,19 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
6854 SELECT_TYPE waitchannels; 6868 SELECT_TYPE waitchannels;
6855 int xerrno; 6869 int xerrno;
6856 6870
6871 if (time_limit < 0)
6872 {
6873 time_limit = 0;
6874 nsecs = -1;
6875 }
6876 else if (TYPE_MAXIMUM (time_t) < time_limit)
6877 time_limit = TYPE_MAXIMUM (time_t);
6878
6857 /* What does time_limit really mean? */ 6879 /* What does time_limit really mean? */
6858 if (time_limit || microsecs) 6880 if (time_limit || nsecs) /* FIXME: what if negative? */
6859 { 6881 {
6860 EMACS_GET_TIME (end_time); 6882 EMACS_GET_TIME (end_time);
6861 EMACS_SET_SECS_USECS (timeout, time_limit, microsecs); 6883 EMACS_SET_SECS_NSECS (timeout, time_limit, nsecs);
6862 EMACS_ADD_TIME (end_time, end_time, timeout); 6884 EMACS_ADD_TIME (end_time, end_time, timeout);
6863 } 6885 }
6864 6886
@@ -6884,7 +6906,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
6884 6906
6885 /* Compute time from now till when time limit is up */ 6907 /* Compute time from now till when time limit is up */
6886 /* Exit if already run out */ 6908 /* Exit if already run out */
6887 if (time_limit == -1) 6909 if (nsecs < 0)
6888 { 6910 {
6889 /* -1 specified for timeout means 6911 /* -1 specified for timeout means
6890 gobble output available now 6912 gobble output available now
@@ -6892,12 +6914,12 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
6892 6914
6893 EMACS_SET_SECS_USECS (timeout, 0, 0); 6915 EMACS_SET_SECS_USECS (timeout, 0, 0);
6894 } 6916 }
6895 else if (time_limit || microsecs) 6917 else if (time_limit || nsecs)
6896 { 6918 {
6897 EMACS_GET_TIME (timeout); 6919 EMACS_GET_TIME (timeout);
6898 EMACS_SUB_TIME (timeout, end_time, timeout); 6920 if (EMACS_TIME_LE (end_time, timeout))
6899 if (EMACS_TIME_NEG_P (timeout))
6900 break; 6921 break;
6922 EMACS_SUB_TIME (timeout, end_time, timeout);
6901 } 6923 }
6902 else 6924 else
6903 { 6925 {
@@ -6930,11 +6952,9 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
6930 && requeued_events_pending_p ()) 6952 && requeued_events_pending_p ())
6931 break; 6953 break;
6932 6954
6933 if (! EMACS_TIME_NEG_P (timer_delay) && time_limit != -1) 6955 if (EMACS_TIME_VALID_P (timer_delay) && 0 <= nsecs)
6934 { 6956 {
6935 EMACS_TIME difference; 6957 if (EMACS_TIME_LT (timer_delay, timeout))
6936 EMACS_SUB_TIME (difference, timer_delay, timeout);
6937 if (EMACS_TIME_NEG_P (difference))
6938 { 6958 {
6939 timeout = timer_delay; 6959 timeout = timer_delay;
6940 timeout_reduced_for_timers = 1; 6960 timeout_reduced_for_timers = 1;
@@ -6970,8 +6990,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
6970 FD_ZERO (&waitchannels); 6990 FD_ZERO (&waitchannels);
6971 } 6991 }
6972 else 6992 else
6973 nfds = select (1, &waitchannels, (SELECT_TYPE *)0, (SELECT_TYPE *)0, 6993 nfds = pselect (1, &waitchannels, NULL, NULL, &timeout, NULL);
6974 &timeout);
6975 6994
6976 xerrno = errno; 6995 xerrno = errno;
6977 6996
@@ -6981,7 +7000,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
6981 /* If we woke up due to SIGWINCH, actually change size now. */ 7000 /* If we woke up due to SIGWINCH, actually change size now. */
6982 do_pending_window_change (0); 7001 do_pending_window_change (0);
6983 7002
6984 if (time_limit && nfds == 0 && ! timeout_reduced_for_timers) 7003 if ((time_limit || nsecs) && nfds == 0 && ! timeout_reduced_for_timers)
6985 /* We waited the full specified time, so return now. */ 7004 /* We waited the full specified time, so return now. */
6986 break; 7005 break;
6987 7006
@@ -7284,19 +7303,20 @@ integer or floating point values.
7284 majflt -- number of major page faults (number) 7303 majflt -- number of major page faults (number)
7285 cminflt -- cumulative number of minor page faults (number) 7304 cminflt -- cumulative number of minor page faults (number)
7286 cmajflt -- cumulative number of major page faults (number) 7305 cmajflt -- cumulative number of major page faults (number)
7287 utime -- user time used by the process, in the (HIGH LOW USEC) format 7306 utime -- user time used by the process, in (current-time) format,
7288 stime -- system time used by the process, in the (HIGH LOW USEC) format 7307 which is a list of integers (HIGH LOW USEC PSEC)
7289 time -- sum of utime and stime, in the (HIGH LOW USEC) format 7308 stime -- system time used by the process (current-time)
7290 cutime -- user time used by the process and its children, (HIGH LOW USEC) 7309 time -- sum of utime and stime (current-time)
7291 cstime -- system time used by the process and its children, (HIGH LOW USEC) 7310 cutime -- user time used by the process and its children (current-time)
7292 ctime -- sum of cutime and cstime, in the (HIGH LOW USEC) format 7311 cstime -- system time used by the process and its children (current-time)
7312 ctime -- sum of cutime and cstime (current-time)
7293 pri -- priority of the process (number) 7313 pri -- priority of the process (number)
7294 nice -- nice value of the process (number) 7314 nice -- nice value of the process (number)
7295 thcount -- process thread count (number) 7315 thcount -- process thread count (number)
7296 start -- time the process started, in the (HIGH LOW USEC) format 7316 start -- time the process started (current-time)
7297 vsize -- virtual memory size of the process in KB's (number) 7317 vsize -- virtual memory size of the process in KB's (number)
7298 rss -- resident set size of the process in KB's (number) 7318 rss -- resident set size of the process in KB's (number)
7299 etime -- elapsed time the process is running, in (HIGH LOW USEC) format 7319 etime -- elapsed time the process is running, in (HIGH LOW USEC PSEC) format
7300 pcpu -- percents of CPU time used by the process (floating-point number) 7320 pcpu -- percents of CPU time used by the process (floating-point number)
7301 pmem -- percents of total physical memory used by process's resident set 7321 pmem -- percents of total physical memory used by process's resident set
7302 (floating-point number) 7322 (floating-point number)
diff --git a/src/process.h b/src/process.h
index ae4b6b61c94..649056a99ff 100644
--- a/src/process.h
+++ b/src/process.h
@@ -106,8 +106,8 @@ struct Lisp_Process
106 On some systems, e.g. GNU/Linux, Emacs is seen as 106 On some systems, e.g. GNU/Linux, Emacs is seen as
107 an interactive app also when reading process output, meaning 107 an interactive app also when reading process output, meaning
108 that process output can be read in as little as 1 byte at a 108 that process output can be read in as little as 1 byte at a
109 time. Value is micro-seconds to delay reading output from 109 time. Value is nanoseconds to delay reading output from
110 this process. Range is 0 .. 50000. */ 110 this process. Range is 0 .. 50 * 1000 * 1000. */
111 int read_output_delay; 111 int read_output_delay;
112 /* Should we delay reading output from this process. 112 /* Should we delay reading output from this process.
113 Initialized from `Vprocess_adaptive_read_buffering'. 113 Initialized from `Vprocess_adaptive_read_buffering'.
diff --git a/src/sysdep.c b/src/sysdep.c
index 3356582de0c..8d1c3d0ca3c 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -32,6 +32,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32#include <allocator.h> 32#include <allocator.h>
33#include <careadlinkat.h> 33#include <careadlinkat.h>
34#include <ignore-value.h> 34#include <ignore-value.h>
35#include <utimens.h>
35 36
36#include "lisp.h" 37#include "lisp.h"
37#include "sysselect.h" 38#include "sysselect.h"
@@ -109,20 +110,6 @@ extern char *getwd (char *);
109 110
110#include "syssignal.h" 111#include "syssignal.h"
111#include "systime.h" 112#include "systime.h"
112#ifdef HAVE_UTIME_H
113#include <utime.h>
114#endif
115
116#ifndef HAVE_UTIMES
117#ifndef HAVE_STRUCT_UTIMBUF
118/* We want to use utime rather than utimes, but we couldn't find the
119 structure declaration. We'll use the traditional one. */
120struct utimbuf {
121 long actime;
122 long modtime;
123};
124#endif
125#endif
126 113
127static int emacs_get_tty (int, struct emacs_tty *); 114static int emacs_get_tty (int, struct emacs_tty *);
128static int emacs_set_tty (int, struct emacs_tty *, int); 115static int emacs_set_tty (int, struct emacs_tty *, int);
@@ -2067,30 +2054,6 @@ perror (void)
2067#endif /* HPUX and not HAVE_PERROR */ 2054#endif /* HPUX and not HAVE_PERROR */
2068 2055
2069/* 2056/*
2070 * Gettimeofday. Simulate as much as possible. Only accurate
2071 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2072 * Only needed when subprocesses are defined.
2073 */
2074
2075#ifndef HAVE_GETTIMEOFDAY
2076#ifdef HAVE_TIMEVAL
2077
2078int
2079gettimeofday (struct timeval *tp, struct timezone *tzp)
2080{
2081 extern long time (long);
2082
2083 tp->tv_sec = time ((long *)0);
2084 tp->tv_usec = 0;
2085 if (tzp != 0)
2086 tzp->tz_minuteswest = -1;
2087 return 0;
2088}
2089
2090#endif
2091#endif /* !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL */
2092
2093/*
2094 * This function will go away as soon as all the stubs fixed. (fnf) 2057 * This function will go away as soon as all the stubs fixed. (fnf)
2095 */ 2058 */
2096 2059
@@ -2126,20 +2089,43 @@ closedir (DIR *dirp /* stream from opendir */)
2126#endif /* HAVE_DIRENT_H */ 2089#endif /* HAVE_DIRENT_H */
2127 2090
2128 2091
2092/* Return a struct timeval that is roughly equivalent to T.
2093 Use the least timeval not less than T.
2094 Return an extremal value if the result would overflow. */
2095struct timeval
2096make_timeval (EMACS_TIME t)
2097{
2098 struct timeval tv;
2099 tv.tv_sec = t.tv_sec;
2100 tv.tv_usec = t.tv_nsec / 1000;
2101
2102 if (t.tv_nsec % 1000 != 0)
2103 {
2104 if (tv.tv_usec < 999999)
2105 tv.tv_usec++;
2106 else if (tv.tv_sec < TYPE_MAXIMUM (time_t))
2107 {
2108 tv.tv_sec++;
2109 tv.tv_usec = 0;
2110 }
2111 }
2112
2113 return tv;
2114}
2115
2116/* Set the access and modification time stamps of FD (a.k.a. FILE) to be
2117 ATIME and MTIME, respectively.
2118 FD must be either negative -- in which case it is ignored --
2119 or a file descriptor that is open on FILE.
2120 If FD is nonnegative, then FILE can be NULL. */
2129int 2121int
2130set_file_times (const char *filename, EMACS_TIME atime, EMACS_TIME mtime) 2122set_file_times (int fd, const char *filename,
2131{ 2123 EMACS_TIME atime, EMACS_TIME mtime)
2132#ifdef HAVE_UTIMES 2124{
2133 struct timeval tv[2]; 2125 struct timespec timespec[2];
2134 tv[0] = atime; 2126 timespec[0] = atime;
2135 tv[1] = mtime; 2127 timespec[1] = mtime;
2136 return utimes (filename, tv); 2128 return fdutimens (fd, filename, timespec);
2137#else /* not HAVE_UTIMES */
2138 struct utimbuf utb;
2139 utb.actime = EMACS_SECS (atime);
2140 utb.modtime = EMACS_SECS (mtime);
2141 return utime (filename, &utb);
2142#endif /* not HAVE_UTIMES */
2143} 2129}
2144 2130
2145/* mkdir and rmdir functions, for systems which don't have them. */ 2131/* mkdir and rmdir functions, for systems which don't have them. */
@@ -2595,60 +2581,82 @@ list_system_processes (void)
2595#endif /* !defined (WINDOWSNT) */ 2581#endif /* !defined (WINDOWSNT) */
2596 2582
2597#ifdef GNU_LINUX 2583#ifdef GNU_LINUX
2598static void 2584static EMACS_TIME
2599time_from_jiffies (unsigned long long tval, long hz, 2585time_from_jiffies (unsigned long long tval, long hz)
2600 time_t *sec, unsigned *usec) 2586{
2601{ 2587 unsigned long long s = tval / hz;
2602 unsigned long long ullsec; 2588 unsigned long long frac = tval % hz;
2603 2589 int ns;
2604 *sec = tval / hz; 2590 EMACS_TIME t;
2605 ullsec = *sec; 2591
2606 tval -= ullsec * hz; 2592 if (TYPE_MAXIMUM (time_t) < s)
2607 /* Careful: if HZ > 1 million, then integer division by it yields zero. */ 2593 time_overflow ();
2608 if (hz <= 1000000) 2594 if (LONG_MAX - 1 <= ULLONG_MAX / EMACS_TIME_RESOLUTION
2609 *usec = tval * 1000000 / hz; 2595 || frac <= ULLONG_MAX / EMACS_TIME_RESOLUTION)
2596 ns = frac * EMACS_TIME_RESOLUTION / hz;
2610 else 2597 else
2611 *usec = tval / (hz / 1000000); 2598 {
2599 /* This is reachable only in the unlikely case that HZ * HZ
2600 exceeds ULLONG_MAX. It calculates an approximation that is
2601 guaranteed to be in range. */
2602 long hz_per_ns = (hz / EMACS_TIME_RESOLUTION
2603 + (hz % EMACS_TIME_RESOLUTION != 0));
2604 ns = frac / hz_per_ns;
2605 }
2606
2607 EMACS_SET_SECS_NSECS (t, s, ns);
2608 return t;
2612} 2609}
2613 2610
2614static Lisp_Object 2611static Lisp_Object
2615ltime_from_jiffies (unsigned long long tval, long hz) 2612ltime_from_jiffies (unsigned long long tval, long hz)
2616{ 2613{
2617 time_t sec; 2614 EMACS_TIME t = time_from_jiffies (tval, hz);
2618 unsigned usec; 2615 return make_lisp_time (t);
2619
2620 time_from_jiffies (tval, hz, &sec, &usec);
2621
2622 return list3 (make_number ((sec >> 16) & 0xffff),
2623 make_number (sec & 0xffff),
2624 make_number (usec));
2625} 2616}
2626 2617
2627static void 2618static EMACS_TIME
2628get_up_time (time_t *sec, unsigned *usec) 2619get_up_time (void)
2629{ 2620{
2630 FILE *fup; 2621 FILE *fup;
2622 EMACS_TIME up;
2631 2623
2632 *sec = *usec = 0; 2624 EMACS_SET_SECS_NSECS (up, 0, 0);
2633 2625
2634 BLOCK_INPUT; 2626 BLOCK_INPUT;
2635 fup = fopen ("/proc/uptime", "r"); 2627 fup = fopen ("/proc/uptime", "r");
2636 2628
2637 if (fup) 2629 if (fup)
2638 { 2630 {
2639 double uptime, idletime; 2631 unsigned long long upsec, upfrac, idlesec, idlefrac;
2632 int upfrac_start, upfrac_end, idlefrac_start, idlefrac_end;
2640 2633
2641 /* The numbers in /proc/uptime use C-locale decimal point, but 2634 if (fscanf (fup, "%llu.%n%llu%n %llu.%n%llu%n",
2642 we already set ourselves to the C locale (see `fixup_locale' 2635 &upsec, &upfrac_start, &upfrac, &upfrac_end,
2643 in emacs.c). */ 2636 &idlesec, &idlefrac_start, &idlefrac, &idlefrac_end)
2644 if (2 <= fscanf (fup, "%lf %lf", &uptime, &idletime)) 2637 == 4)
2645 { 2638 {
2646 *sec = uptime; 2639 if (TYPE_MAXIMUM (time_t) < upsec)
2647 *usec = (uptime - *sec) * 1000000; 2640 {
2641 upsec = TYPE_MAXIMUM (time_t);
2642 upfrac = EMACS_TIME_RESOLUTION - 1;
2643 }
2644 else
2645 {
2646 int upfraclen = upfrac_end - upfrac_start;
2647 for (; upfraclen < LOG10_EMACS_TIME_RESOLUTION; upfraclen++)
2648 upfrac *= 10;
2649 for (; LOG10_EMACS_TIME_RESOLUTION < upfraclen; upfraclen--)
2650 upfrac /= 10;
2651 upfrac = min (upfrac, EMACS_TIME_RESOLUTION - 1);
2652 }
2653 EMACS_SET_SECS_NSECS (up, upsec, upfrac);
2648 } 2654 }
2649 fclose (fup); 2655 fclose (fup);
2650 } 2656 }
2651 UNBLOCK_INPUT; 2657 UNBLOCK_INPUT;
2658
2659 return up;
2652} 2660}
2653 2661
2654#define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff) 2662#define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff)
@@ -2748,9 +2756,7 @@ system_process_attributes (Lisp_Object pid)
2748 unsigned long long u_time, s_time, cutime, cstime, start; 2756 unsigned long long u_time, s_time, cutime, cstime, start;
2749 long priority, niceness, rss; 2757 long priority, niceness, rss;
2750 unsigned long minflt, majflt, cminflt, cmajflt, vsize; 2758 unsigned long minflt, majflt, cminflt, cmajflt, vsize;
2751 time_t sec; 2759 EMACS_TIME tnow, tstart, tboot, telapsed, us_time;
2752 unsigned usec;
2753 EMACS_TIME tnow, tstart, tboot, telapsed;
2754 double pcpu, pmem; 2760 double pcpu, pmem;
2755 Lisp_Object attrs = Qnil; 2761 Lisp_Object attrs = Qnil;
2756 Lisp_Object cmd_str, decoded_cmd, tem; 2762 Lisp_Object cmd_str, decoded_cmd, tem;
@@ -2873,35 +2879,18 @@ system_process_attributes (Lisp_Object pid)
2873 attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs); 2879 attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs);
2874 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs); 2880 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs);
2875 EMACS_GET_TIME (tnow); 2881 EMACS_GET_TIME (tnow);
2876 get_up_time (&sec, &usec); 2882 telapsed = get_up_time ();
2877 EMACS_SET_SECS (telapsed, sec);
2878 EMACS_SET_USECS (telapsed, usec);
2879 EMACS_SUB_TIME (tboot, tnow, telapsed); 2883 EMACS_SUB_TIME (tboot, tnow, telapsed);
2880 time_from_jiffies (start, clocks_per_sec, &sec, &usec); 2884 tstart = time_from_jiffies (start, clocks_per_sec);
2881 EMACS_SET_SECS (tstart, sec);
2882 EMACS_SET_USECS (tstart, usec);
2883 EMACS_ADD_TIME (tstart, tboot, tstart); 2885 EMACS_ADD_TIME (tstart, tboot, tstart);
2884 attrs = Fcons (Fcons (Qstart, 2886 attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs);
2885 list3 (make_number
2886 ((EMACS_SECS (tstart) >> 16) & 0xffff),
2887 make_number
2888 (EMACS_SECS (tstart) & 0xffff),
2889 make_number
2890 (EMACS_USECS (tstart)))),
2891 attrs);
2892 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs); 2887 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs);
2893 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs); 2888 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs);
2894 EMACS_SUB_TIME (telapsed, tnow, tstart); 2889 EMACS_SUB_TIME (telapsed, tnow, tstart);
2895 attrs = Fcons (Fcons (Qetime, 2890 attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs);
2896 list3 (make_number 2891 us_time = time_from_jiffies (u_time + s_time, clocks_per_sec);
2897 ((EMACS_SECS (telapsed) >> 16) & 0xffff), 2892 pcpu = (EMACS_TIME_TO_DOUBLE (us_time)
2898 make_number 2893 / EMACS_TIME_TO_DOUBLE (telapsed));
2899 (EMACS_SECS (telapsed) & 0xffff),
2900 make_number
2901 (EMACS_USECS (telapsed)))),
2902 attrs);
2903 time_from_jiffies (u_time + s_time, clocks_per_sec, &sec, &usec);
2904 pcpu = (sec + usec / 1000000.0) / (EMACS_SECS (telapsed) + EMACS_USECS (telapsed) / 1000000.0);
2905 if (pcpu > 1.0) 2894 if (pcpu > 1.0)
2906 pcpu = 1.0; 2895 pcpu = 1.0;
2907 attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs); 2896 attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs);
@@ -3082,27 +3071,13 @@ system_process_attributes (Lisp_Object pid)
3082 Qcstime 3071 Qcstime
3083 Are they available? */ 3072 Are they available? */
3084 3073
3085 attrs = Fcons (Fcons (Qtime, 3074 attrs = Fcons (Fcons (Qtime, make_lisp_time (pinfo.pr_time)), attrs);
3086 list3 (make_number (pinfo.pr_time.tv_sec >> 16), 3075 attrs = Fcons (Fcons (Qctime, make_lisp_time (pinfo.pr_ctime)), attrs);
3087 make_number (pinfo.pr_time.tv_sec & 0xffff),
3088 make_number (pinfo.pr_time.tv_nsec))),
3089 attrs);
3090
3091 attrs = Fcons (Fcons (Qctime,
3092 list3 (make_number (pinfo.pr_ctime.tv_sec >> 16),
3093 make_number (pinfo.pr_ctime.tv_sec & 0xffff),
3094 make_number (pinfo.pr_ctime.tv_nsec))),
3095 attrs);
3096
3097 attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs); 3076 attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs);
3098 attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs); 3077 attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs);
3099 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), attrs); 3078 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), attrs);
3100 3079
3101 attrs = Fcons (Fcons (Qstart, 3080 attrs = Fcons (Fcons (Qstart, make_lisp_time (pinfo.pr_start)), attrs);
3102 list3 (make_number (pinfo.pr_start.tv_sec >> 16),
3103 make_number (pinfo.pr_start.tv_sec & 0xffff),
3104 make_number (pinfo.pr_start.tv_nsec))),
3105 attrs);
3106 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), attrs); 3081 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), attrs);
3107 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), attrs); 3082 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), attrs);
3108 3083
diff --git a/src/sysselect.h b/src/sysselect.h
index f9b9fc00b35..e1e5839cfe4 100644
--- a/src/sysselect.h
+++ b/src/sysselect.h
@@ -16,7 +16,6 @@ GNU General Public License for more details.
16You should have received a copy of the GNU General Public License 16You should have received a copy of the GNU General Public License
17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18 18
19#ifdef HAVE_SYS_SELECT_H
20#if defined (DARWIN_OS) 19#if defined (DARWIN_OS)
21#undef init_process 20#undef init_process
22#endif 21#endif
@@ -24,7 +23,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24#if defined (DARWIN_OS) 23#if defined (DARWIN_OS)
25#define init_process emacs_init_process 24#define init_process emacs_init_process
26#endif 25#endif
27#endif
28 26
29/* The w32 build defines select stuff in w32.h, which is included 27/* The w32 build defines select stuff in w32.h, which is included
30 where w32 needs it, but not where sysselect.h is included. The w32 28 where w32 needs it, but not where sysselect.h is included. The w32
@@ -52,4 +50,3 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
52#if !defined (HAVE_SELECT) 50#if !defined (HAVE_SELECT)
53#define select sys_select 51#define select sys_select
54#endif 52#endif
55
diff --git a/src/systime.h b/src/systime.h
index 9e7a1173a20..dd0d77c827d 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -19,16 +19,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19#ifndef EMACS_SYSTIME_H 19#ifndef EMACS_SYSTIME_H
20#define EMACS_SYSTIME_H 20#define EMACS_SYSTIME_H
21 21
22#ifdef TIME_WITH_SYS_TIME 22#include <timespec.h>
23#include <sys/time.h>
24#include <time.h>
25#else
26#ifdef HAVE_SYS_TIME_H
27#include <sys/time.h>
28#else
29#include <time.h>
30#endif
31#endif
32 23
33#ifdef emacs 24#ifdef emacs
34# ifdef HAVE_X_WINDOWS 25# ifdef HAVE_X_WINDOWS
@@ -48,91 +39,64 @@ typedef unsigned long Time;
48#endif 39#endif
49#endif 40#endif
50 41
51/* EMACS_TIME is the type to use to represent temporal intervals - 42/* The type to use to represent temporal intervals. It can be passed
52 struct timeval on some systems, int on others. It can be passed as 43 as the timeout argument to the pselect system call. */
53 the timeout argument to the select system call. 44#define EMACS_TIME struct timespec
54 45
55 EMACS_SECS (TIME) is an rvalue for the seconds component of TIME. 46/* Resolution of EMACS_TIME time stamps (in units per second), and log
47 base 10 of the resolution. The log must be a positive integer. */
48#define EMACS_TIME_RESOLUTION 1000000000
49#define LOG10_EMACS_TIME_RESOLUTION 9
50
51/* EMACS_SECS (TIME) is an rvalue for the seconds component of TIME.
52 EMACS_SECS_ADDR (time) is the address of the seconds component.
56 EMACS_SET_SECS (TIME, SECONDS) sets that to SECONDS. 53 EMACS_SET_SECS (TIME, SECONDS) sets that to SECONDS.
57 54
58 EMACS_HAS_USECS is defined if EMACS_TIME has a usecs component. 55 EMACS_NSECS (TIME) is an rvalue for the nanoseconds component of TIME.
59 EMACS_USECS (TIME) is an rvalue for the microseconds component of TIME. 56 EMACS_SET_NSECS (TIME, NANOSECONDS) sets that to NANOSECONDS.
60 This returns zero if EMACS_TIME doesn't have a microseconds component.
61 EMACS_SET_USECS (TIME, MICROSECONDS) sets that to MICROSECONDS.
62 This does nothing if EMACS_TIME doesn't have a microseconds component.
63 57
64 EMACS_SET_SECS_USECS (TIME, SECS, USECS) sets both components of TIME. 58 EMACS_SET_SECS_NSECS (TIME, SECS, NSECS) sets both components of TIME. */
59#define EMACS_SECS(time) ((time).tv_sec + 0)
60#define EMACS_NSECS(time) ((time).tv_nsec + 0)
61#define EMACS_SECS_ADDR(time) (&(time).tv_sec)
62#define EMACS_SET_SECS(time, seconds) ((time).tv_sec = (seconds))
63#define EMACS_SET_NSECS(time, ns) ((time).tv_nsec = (ns))
64#define EMACS_SET_SECS_NSECS(time, s, ns) \
65 ((void) (EMACS_SET_SECS (time, s), EMACS_SET_NSECS (time, ns)))
65 66
66 EMACS_GET_TIME (TIME) stores the current system time in TIME, which 67/* Convenience macros for older code that counts microseconds. */
67 should be an lvalue. 68#define EMACS_SET_USECS(time, us) ((void) EMACS_SET_NSECS (time, (us) * 1000))
69#define EMACS_SET_SECS_USECS(time, secs, usecs) \
70 (EMACS_SET_SECS (time, secs), EMACS_SET_USECS (time, usecs))
68 71
69 EMACS_ADD_TIME (DEST, SRC1, SRC2) adds SRC1 to SRC2 and stores the 72/* Set TIME to an invalid time stamp. */
70 result in DEST. SRC should not be negative. 73#define EMACS_SET_INVALID_TIME(time) EMACS_SET_SECS_NSECS(time, 0, -1)
71 74
72 EMACS_SUB_TIME (DEST, SRC1, SRC2) subtracts SRC2 from SRC1 and 75/* Set TIME to the current system time. */
73 stores the result in DEST. SRC should not be negative. 76#define EMACS_GET_TIME(time) gettime (&(time))
74 EMACS_TIME_NEG_P (TIME) is true if TIME is negative.
75 77
76*/ 78/* Put into DEST the result of adding SRC1 to SRC2, or of subtracting
79 SRC2 from SRC1. On overflow, store an extremal value. */
80#define EMACS_ADD_TIME(dest, src1, src2) ((dest) = timespec_add (src1, src2))
81#define EMACS_SUB_TIME(dest, src1, src2) ((dest) = timespec_sub (src1, src2))
77 82
78#ifdef HAVE_TIMEVAL 83/* Return the sign of the valid time stamp TIME, either -1, 0, or 1. */
84#define EMACS_TIME_SIGN(time) timespec_sign (time)
79 85
80#define EMACS_HAS_USECS 86/* Return 1 if TIME is a valid time stamp. */
87#define EMACS_TIME_VALID_P(time) (0 <= (time).tv_nsec)
81 88
82#define EMACS_TIME struct timeval 89/* Convert the double D to the greatest EMACS_TIME not greater than D.
83#define EMACS_SECS(time) ((time).tv_sec + 0) 90 On overflow, return an extremal value. Return the minimum
84#define EMACS_USECS(time) ((time).tv_usec + 0) 91 EMACS_TIME if D is not a number. */
85#define EMACS_SET_SECS(time, seconds) ((time).tv_sec = (seconds)) 92#define EMACS_TIME_FROM_DOUBLE(d) dtotimespec (d)
86#define EMACS_SET_USECS(time, microseconds) ((time).tv_usec = (microseconds))
87
88/* On SVR4, the compiler may complain if given this extra BSD arg. */
89#ifdef GETTIMEOFDAY_ONE_ARGUMENT
90#define EMACS_GET_TIME(time) gettimeofday (&(time))
91#else /* not GETTIMEOFDAY_ONE_ARGUMENT */
92/* Presumably the second arg is ignored. */
93#define EMACS_GET_TIME(time) gettimeofday (&(time), NULL)
94#endif /* not GETTIMEOFDAY_ONE_ARGUMENT */
95
96#define EMACS_ADD_TIME(dest, src1, src2) \
97 do { \
98 (dest).tv_sec = (src1).tv_sec + (src2).tv_sec; \
99 (dest).tv_usec = (src1).tv_usec + (src2).tv_usec; \
100 if ((dest).tv_usec > 1000000) \
101 (dest).tv_usec -= 1000000, (dest).tv_sec++; \
102 } while (0)
103
104#define EMACS_SUB_TIME(dest, src1, src2) \
105 do { \
106 (dest).tv_sec = (src1).tv_sec - (src2).tv_sec; \
107 (dest).tv_usec = (src1).tv_usec - (src2).tv_usec; \
108 if ((dest).tv_usec < 0) \
109 (dest).tv_usec += 1000000, (dest).tv_sec--; \
110 } while (0)
111
112#define EMACS_TIME_NEG_P(time) \
113 ((long)(time).tv_sec < 0 \
114 || ((time).tv_sec == 0 \
115 && (long)(time).tv_usec < 0))
116
117#else /* ! defined (HAVE_TIMEVAL) */
118
119#define EMACS_TIME int
120#define EMACS_SECS(time) (time)
121#define EMACS_USECS(time) 0
122#define EMACS_SET_SECS(time, seconds) ((time) = (seconds))
123#define EMACS_SET_USECS(time, usecs) 0
124
125#define EMACS_GET_TIME(t) ((t) = time ((long *) 0))
126#define EMACS_ADD_TIME(dest, src1, src2) ((dest) = (src1) + (src2))
127#define EMACS_SUB_TIME(dest, src1, src2) ((dest) = (src1) - (src2))
128#define EMACS_TIME_NEG_P(t) ((t) < 0)
129
130#endif /* ! defined (HAVE_TIMEVAL) */
131 93
132#define EMACS_SET_SECS_USECS(time, secs, usecs) \ 94/* Convert the Emacs time T to an approximate double value D. */
133 (EMACS_SET_SECS (time, secs), EMACS_SET_USECS (time, usecs)) 95#define EMACS_TIME_TO_DOUBLE(t) timespectod (t)
134 96
135extern int set_file_times (const char *, EMACS_TIME, EMACS_TIME); 97/* defined in sysdep.c */
98extern int set_file_times (int, const char *, EMACS_TIME, EMACS_TIME);
99extern struct timeval make_timeval (EMACS_TIME);
136 100
137/* defined in keyboard.c */ 101/* defined in keyboard.c */
138extern void set_waiting_for_input (EMACS_TIME *); 102extern void set_waiting_for_input (EMACS_TIME *);
@@ -141,29 +105,20 @@ extern void set_waiting_for_input (EMACS_TIME *);
141 happen when this files is used outside the src directory). 105 happen when this files is used outside the src directory).
142 Use GCPRO1 to determine if lisp.h was included. */ 106 Use GCPRO1 to determine if lisp.h was included. */
143#ifdef GCPRO1 107#ifdef GCPRO1
144/* defined in editfns.c*/ 108/* defined in editfns.c */
145extern Lisp_Object make_time (time_t); 109extern Lisp_Object make_lisp_time (EMACS_TIME);
146extern int lisp_time_argument (Lisp_Object, time_t *, int *); 110extern int decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object,
111 Lisp_Object, EMACS_TIME *, int *);
112extern EMACS_TIME lisp_time_argument (Lisp_Object, int *);
147#endif 113#endif
148 114
149/* Compare times T1 and T2. Value is 0 if T1 and T2 are the same.
150 Value is < 0 if T1 is less than T2. Value is > 0 otherwise. (Cast
151 to long is for those platforms where time_t is an unsigned
152 type, and where otherwise T1 will always be grater than T2.) */
153
154#define EMACS_TIME_CMP(T1, T2) \
155 ((long)EMACS_SECS (T1) - (long)EMACS_SECS (T2) \
156 + (EMACS_SECS (T1) == EMACS_SECS (T2) \
157 ? EMACS_USECS (T1) - EMACS_USECS (T2) \
158 : 0))
159
160/* Compare times T1 and T2 for equality, inequality etc. */ 115/* Compare times T1 and T2 for equality, inequality etc. */
161 116
162#define EMACS_TIME_EQ(T1, T2) (EMACS_TIME_CMP (T1, T2) == 0) 117#define EMACS_TIME_EQ(T1, T2) (timespec_cmp (T1, T2) == 0)
163#define EMACS_TIME_NE(T1, T2) (EMACS_TIME_CMP (T1, T2) != 0) 118#define EMACS_TIME_NE(T1, T2) (timespec_cmp (T1, T2) != 0)
164#define EMACS_TIME_GT(T1, T2) (EMACS_TIME_CMP (T1, T2) > 0) 119#define EMACS_TIME_GT(T1, T2) (timespec_cmp (T1, T2) > 0)
165#define EMACS_TIME_GE(T1, T2) (EMACS_TIME_CMP (T1, T2) >= 0) 120#define EMACS_TIME_GE(T1, T2) (timespec_cmp (T1, T2) >= 0)
166#define EMACS_TIME_LT(T1, T2) (EMACS_TIME_CMP (T1, T2) < 0) 121#define EMACS_TIME_LT(T1, T2) (timespec_cmp (T1, T2) < 0)
167#define EMACS_TIME_LE(T1, T2) (EMACS_TIME_CMP (T1, T2) <= 0) 122#define EMACS_TIME_LE(T1, T2) (timespec_cmp (T1, T2) <= 0)
168 123
169#endif /* EMACS_SYSTIME_H */ 124#endif /* EMACS_SYSTIME_H */
diff --git a/src/term.c b/src/term.c
index 5f807181199..1a2524fd297 100644
--- a/src/term.c
+++ b/src/term.c
@@ -24,6 +24,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24#include <ctype.h> 24#include <ctype.h>
25#include <errno.h> 25#include <errno.h>
26#include <sys/file.h> 26#include <sys/file.h>
27#include <sys/time.h>
27#include <unistd.h> 28#include <unistd.h>
28#include <signal.h> 29#include <signal.h>
29#include <setjmp.h> 30#include <setjmp.h>
@@ -2611,6 +2612,18 @@ term_mouse_movement (FRAME_PTR frame, Gpm_Event *event)
2611 return 0; 2612 return 0;
2612} 2613}
2613 2614
2615/* Return the Time that corresponds to T. Wrap around on overflow. */
2616static Time
2617timeval_to_Time (struct timeval const *t)
2618{
2619 Time s_1000, ms;
2620
2621 s_1000 = t->tv_sec;
2622 s_1000 *= 1000;
2623 ms = t->tv_usec / 1000;
2624 return s_1000 + ms;
2625}
2626
2614/* Return the current position of the mouse. 2627/* Return the current position of the mouse.
2615 2628
2616 Set *f to the frame the mouse is in, or zero if the mouse is in no 2629 Set *f to the frame the mouse is in, or zero if the mouse is in no
@@ -2630,7 +2643,6 @@ term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
2630 Lisp_Object *y, Time *timeptr) 2643 Lisp_Object *y, Time *timeptr)
2631{ 2644{
2632 struct timeval now; 2645 struct timeval now;
2633 Time sec, usec;
2634 2646
2635 *fp = SELECTED_FRAME (); 2647 *fp = SELECTED_FRAME ();
2636 (*fp)->mouse_moved = 0; 2648 (*fp)->mouse_moved = 0;
@@ -2641,9 +2653,7 @@ term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
2641 XSETINT (*x, last_mouse_x); 2653 XSETINT (*x, last_mouse_x);
2642 XSETINT (*y, last_mouse_y); 2654 XSETINT (*y, last_mouse_y);
2643 gettimeofday(&now, 0); 2655 gettimeofday(&now, 0);
2644 sec = now.tv_sec; 2656 *timeptr = timeval_to_Time (&now);
2645 usec = now.tv_usec;
2646 *timeptr = (sec * 1000) + (usec / 1000);
2647} 2657}
2648 2658
2649/* Prepare a mouse-event in *RESULT for placement in the input queue. 2659/* Prepare a mouse-event in *RESULT for placement in the input queue.
@@ -2667,7 +2677,7 @@ term_mouse_click (struct input_event *result, Gpm_Event *event,
2667 } 2677 }
2668 } 2678 }
2669 gettimeofday(&now, 0); 2679 gettimeofday(&now, 0);
2670 result->timestamp = (now.tv_sec * 1000) + (now.tv_usec / 1000); 2680 result->timestamp = timeval_to_Time (&now);
2671 2681
2672 if (event->type & GPM_UP) 2682 if (event->type & GPM_UP)
2673 result->modifiers = up_modifier; 2683 result->modifiers = up_modifier;
diff --git a/src/undo.c b/src/undo.c
index 1cb048690ba..ae9025c298e 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -226,7 +226,7 @@ record_first_change (void)
226 base_buffer = base_buffer->base_buffer; 226 base_buffer = base_buffer->base_buffer;
227 227
228 BVAR (current_buffer, undo_list) = 228 BVAR (current_buffer, undo_list) =
229 Fcons (Fcons (Qt, INTEGER_TO_CONS (base_buffer->modtime)), 229 Fcons (Fcons (Qt, make_lisp_time (base_buffer->modtime)),
230 BVAR (current_buffer, undo_list)); 230 BVAR (current_buffer, undo_list));
231} 231}
232 232
@@ -505,10 +505,23 @@ Return what remains of the list. */)
505 cdr = XCDR (next); 505 cdr = XCDR (next);
506 if (EQ (car, Qt)) 506 if (EQ (car, Qt))
507 { 507 {
508 /* Element (t high . low) records previous modtime. */ 508 /* Element (t . TIME) records previous modtime.
509 Preserve any flag of NONEXISTENT_MODTIME_NSECS or
510 UNKNOWN_MODTIME_NSECS. */
509 struct buffer *base_buffer = current_buffer; 511 struct buffer *base_buffer = current_buffer;
510 time_t mod_time; 512 EMACS_TIME mod_time;
511 CONS_TO_INTEGER (cdr, time_t, mod_time); 513
514 if (CONSP (cdr)
515 && CONSP (XCDR (cdr))
516 && CONSP (XCDR (XCDR (cdr)))
517 && CONSP (XCDR (XCDR (XCDR (cdr))))
518 && INTEGERP (XCAR (XCDR (XCDR (XCDR (cdr)))))
519 && XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) < 0)
520 EMACS_SET_SECS_NSECS
521 (mod_time, 0,
522 XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) / 1000);
523 else
524 mod_time = lisp_time_argument (cdr, 0);
512 525
513 if (current_buffer->base_buffer) 526 if (current_buffer->base_buffer)
514 base_buffer = current_buffer->base_buffer; 527 base_buffer = current_buffer->base_buffer;
@@ -516,7 +529,7 @@ Return what remains of the list. */)
516 /* If this records an obsolete save 529 /* If this records an obsolete save
517 (not matching the actual disk file) 530 (not matching the actual disk file)
518 then don't mark unmodified. */ 531 then don't mark unmodified. */
519 if (mod_time != base_buffer->modtime) 532 if (EMACS_TIME_NE (mod_time, base_buffer->modtime))
520 continue; 533 continue;
521#ifdef CLASH_DETECTION 534#ifdef CLASH_DETECTION
522 Funlock_buffer (); 535 Funlock_buffer ();
diff --git a/src/w32.c b/src/w32.c
index 248a91463e8..dbe7ec1764f 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -318,8 +318,10 @@ is_windows_9x (void)
318 return s_b_ret; 318 return s_b_ret;
319} 319}
320 320
321static Lisp_Object ltime (ULONGLONG);
322
321/* Get total user and system times for get-internal-run-time. 323/* Get total user and system times for get-internal-run-time.
322 Returns a list of three integers if the times are provided by the OS 324 Returns a list of integers if the times are provided by the OS
323 (NT derivatives), otherwise it returns the result of current-time. */ 325 (NT derivatives), otherwise it returns the result of current-time. */
324Lisp_Object 326Lisp_Object
325w32_get_internal_run_time (void) 327w32_get_internal_run_time (void)
@@ -331,27 +333,13 @@ w32_get_internal_run_time (void)
331 if ((*get_process_times_fn) (proc, &create, &exit, &kernel, &user)) 333 if ((*get_process_times_fn) (proc, &create, &exit, &kernel, &user))
332 { 334 {
333 LARGE_INTEGER user_int, kernel_int, total; 335 LARGE_INTEGER user_int, kernel_int, total;
334 int microseconds; 336 int time_100ns;
335 user_int.LowPart = user.dwLowDateTime; 337 user_int.LowPart = user.dwLowDateTime;
336 user_int.HighPart = user.dwHighDateTime; 338 user_int.HighPart = user.dwHighDateTime;
337 kernel_int.LowPart = kernel.dwLowDateTime; 339 kernel_int.LowPart = kernel.dwLowDateTime;
338 kernel_int.HighPart = kernel.dwHighDateTime; 340 kernel_int.HighPart = kernel.dwHighDateTime;
339 total.QuadPart = user_int.QuadPart + kernel_int.QuadPart; 341 total.QuadPart = user_int.QuadPart + kernel_int.QuadPart;
340 /* FILETIME is 100 nanosecond increments, Emacs only wants 342 return ltime (total.QuadPart);
341 microsecond resolution. */
342 total.QuadPart /= 10;
343 microseconds = total.QuadPart % 1000000;
344 total.QuadPart /= 1000000;
345
346 /* Sanity check to make sure we can represent the result. */
347 if (total.HighPart == 0)
348 {
349 int secs = total.LowPart;
350
351 return list3 (make_number ((secs >> 16) & 0xffff),
352 make_number (secs & 0xffff),
353 make_number (microseconds));
354 }
355 } 343 }
356 } 344 }
357 345
@@ -4070,15 +4058,17 @@ restore_privilege (TOKEN_PRIVILEGES *priv)
4070 return ret_val; 4058 return ret_val;
4071} 4059}
4072 4060
4073static Lisp_Object 4061ltime (ULONGLONG time_100ns)
4074ltime (long time_sec, long time_usec)
4075{ 4062{
4076 return list3 (make_number ((time_sec >> 16) & 0xffff), 4063 ULONGLONG time_sec = time_100ns / 10000000;
4064 int subsec = time_100ns % 10000000;
4065 return list4 (make_number (time_sec >> 16),
4077 make_number (time_sec & 0xffff), 4066 make_number (time_sec & 0xffff),
4078 make_number (time_usec)); 4067 make_number (subsec / 10),
4068 make_number (subsec % 10 * 100000));
4079} 4069}
4080 4070
4081#define U64_TO_LISP_TIME(time) ltime ((time) / 1000000L, (time) % 1000000L) 4071#define U64_TO_LISP_TIME(time) ltime (time)
4082 4072
4083static int 4073static int
4084process_times (HANDLE h_proc, Lisp_Object *ctime, Lisp_Object *etime, 4074process_times (HANDLE h_proc, Lisp_Object *ctime, Lisp_Object *etime,
@@ -4097,11 +4087,9 @@ process_times (HANDLE h_proc, Lisp_Object *ctime, Lisp_Object *etime,
4097 GetSystemTimeAsFileTime (&ft_current); 4087 GetSystemTimeAsFileTime (&ft_current);
4098 4088
4099 FILETIME_TO_U64 (tem1, ft_kernel); 4089 FILETIME_TO_U64 (tem1, ft_kernel);
4100 tem1 /= 10L;
4101 *stime = U64_TO_LISP_TIME (tem1); 4090 *stime = U64_TO_LISP_TIME (tem1);
4102 4091
4103 FILETIME_TO_U64 (tem2, ft_user); 4092 FILETIME_TO_U64 (tem2, ft_user);
4104 tem2 /= 10L;
4105 *utime = U64_TO_LISP_TIME (tem2); 4093 *utime = U64_TO_LISP_TIME (tem2);
4106 4094
4107 tem3 = tem1 + tem2; 4095 tem3 = tem1 + tem2;
@@ -4110,13 +4098,13 @@ process_times (HANDLE h_proc, Lisp_Object *ctime, Lisp_Object *etime,
4110 FILETIME_TO_U64 (tem, ft_creation); 4098 FILETIME_TO_U64 (tem, ft_creation);
4111 /* Process no 4 (System) returns zero creation time. */ 4099 /* Process no 4 (System) returns zero creation time. */
4112 if (tem) 4100 if (tem)
4113 tem = (tem - utc_base) / 10L; 4101 tem -= utc_base;
4114 *ctime = U64_TO_LISP_TIME (tem); 4102 *ctime = U64_TO_LISP_TIME (tem);
4115 4103
4116 if (tem) 4104 if (tem)
4117 { 4105 {
4118 FILETIME_TO_U64 (tem3, ft_current); 4106 FILETIME_TO_U64 (tem3, ft_current);
4119 tem = (tem3 - utc_base) / 10L - tem; 4107 tem = (tem3 - utc_base) - tem;
4120 } 4108 }
4121 *etime = U64_TO_LISP_TIME (tem); 4109 *etime = U64_TO_LISP_TIME (tem);
4122 4110
@@ -6275,7 +6263,7 @@ emacs_gnutls_pull (gnutls_transport_ptr_t p, void* buf, size_t sz)
6275{ 6263{
6276 int n, sc, err; 6264 int n, sc, err;
6277 SELECT_TYPE fdset; 6265 SELECT_TYPE fdset;
6278 EMACS_TIME timeout; 6266 struct timeval timeout;
6279 struct Lisp_Process *process = (struct Lisp_Process *)p; 6267 struct Lisp_Process *process = (struct Lisp_Process *)p;
6280 int fd = process->infd; 6268 int fd = process->infd;
6281 6269
@@ -6291,7 +6279,8 @@ emacs_gnutls_pull (gnutls_transport_ptr_t p, void* buf, size_t sz)
6291 if (err == EWOULDBLOCK) 6279 if (err == EWOULDBLOCK)
6292 { 6280 {
6293 /* Set a small timeout. */ 6281 /* Set a small timeout. */
6294 EMACS_SET_SECS_USECS (timeout, 1, 0); 6282 timeout.tv_sec = 1;
6283 timeout.tv_usec = 0;
6295 FD_ZERO (&fdset); 6284 FD_ZERO (&fdset);
6296 FD_SET ((int)fd, &fdset); 6285 FD_SET ((int)fd, &fdset);
6297 6286
diff --git a/src/xdisp.c b/src/xdisp.c
index a0739eb5522..0050d644931 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -29077,18 +29077,20 @@ start_hourglass (void)
29077{ 29077{
29078#if defined (HAVE_WINDOW_SYSTEM) 29078#if defined (HAVE_WINDOW_SYSTEM)
29079 EMACS_TIME delay; 29079 EMACS_TIME delay;
29080 int secs = DEFAULT_HOURGLASS_DELAY, usecs = 0;
29081 29080
29082 cancel_hourglass (); 29081 cancel_hourglass ();
29083 29082
29084 if (NUMBERP (Vhourglass_delay)) 29083 if (INTEGERP (Vhourglass_delay)
29085 { 29084 && XINT (Vhourglass_delay) > 0)
29086 double duration = extract_float (Vhourglass_delay); 29085 EMACS_SET_SECS_NSECS (delay,
29087 if (0 < duration) 29086 min (XINT (Vhourglass_delay), TYPE_MAXIMUM (time_t)),
29088 duration_to_sec_usec (duration, &secs, &usecs); 29087 0);
29089 } 29088 else if (FLOATP (Vhourglass_delay)
29089 && XFLOAT_DATA (Vhourglass_delay) > 0)
29090 delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
29091 else
29092 EMACS_SET_SECS_NSECS (delay, DEFAULT_HOURGLASS_DELAY, 0);
29090 29093
29091 EMACS_SET_SECS_USECS (delay, secs, usecs);
29092 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay, 29094 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29093 show_hourglass, NULL); 29095 show_hourglass, NULL);
29094#endif 29096#endif
diff --git a/src/xgselect.c b/src/xgselect.c
index 9d6a3ba774a..c7348d2c70a 100644
--- a/src/xgselect.c
+++ b/src/xgselect.c
@@ -34,18 +34,18 @@ static ptrdiff_t gfds_size;
34 34
35int 35int
36xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, 36xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
37 EMACS_TIME *timeout) 37 EMACS_TIME *timeout, sigset_t *sigmask)
38{ 38{
39 SELECT_TYPE all_rfds, all_wfds; 39 SELECT_TYPE all_rfds, all_wfds;
40 EMACS_TIME tmo, *tmop = timeout; 40 EMACS_TIME tmo, *tmop = timeout;
41 41
42 GMainContext *context; 42 GMainContext *context;
43 int have_wfds = wfds != NULL; 43 int have_wfds = wfds != NULL;
44 int n_gfds = 0, our_tmo = 0, retval = 0, our_fds = 0, max_fds = fds_lim - 1; 44 int n_gfds = 0, retval = 0, our_fds = 0, max_fds = fds_lim - 1;
45 int i, nfds, tmo_in_millisec; 45 int i, nfds, tmo_in_millisec;
46 46
47 if (!x_in_use) 47 if (!x_in_use)
48 return select (fds_lim, rfds, wfds, efds, timeout); 48 return pselect (fds_lim, rfds, wfds, efds, tmop, sigmask);
49 49
50 if (rfds) memcpy (&all_rfds, rfds, sizeof (all_rfds)); 50 if (rfds) memcpy (&all_rfds, rfds, sizeof (all_rfds));
51 else FD_ZERO (&all_rfds); 51 else FD_ZERO (&all_rfds);
@@ -90,20 +90,13 @@ xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
90 { 90 {
91 EMACS_SET_SECS_USECS (tmo, tmo_in_millisec/1000, 91 EMACS_SET_SECS_USECS (tmo, tmo_in_millisec/1000,
92 1000 * (tmo_in_millisec % 1000)); 92 1000 * (tmo_in_millisec % 1000));
93 if (!timeout) our_tmo = 1; 93 if (!timeout || EMACS_TIME_LT (tmo, *timeout))
94 else 94 tmop = &tmo;
95 {
96 EMACS_TIME difference;
97
98 EMACS_SUB_TIME (difference, tmo, *timeout);
99 if (EMACS_TIME_NEG_P (difference)) our_tmo = 1;
100 }
101
102 if (our_tmo) tmop = &tmo;
103 } 95 }
104 96
105 fds_lim = max_fds + 1; 97 fds_lim = max_fds + 1;
106 nfds = select (fds_lim, &all_rfds, have_wfds ? &all_wfds : NULL, efds, tmop); 98 nfds = pselect (fds_lim, &all_rfds, have_wfds ? &all_wfds : NULL,
99 efds, tmop, sigmask);
107 100
108 if (nfds < 0) 101 if (nfds < 0)
109 retval = nfds; 102 retval = nfds;
@@ -132,7 +125,7 @@ xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
132 } 125 }
133 } 126 }
134 127
135 if (our_fds > 0 || (nfds == 0 && our_tmo)) 128 if (our_fds > 0 || (nfds == 0 && tmop == &tmo))
136 { 129 {
137 130
138 /* If Gtk+ is in use eventually gtk_main_iteration will be called, 131 /* If Gtk+ is in use eventually gtk_main_iteration will be called,
diff --git a/src/xgselect.h b/src/xgselect.h
index 15d7cd5fdd3..8e5614ea972 100644
--- a/src/xgselect.h
+++ b/src/xgselect.h
@@ -28,9 +28,9 @@ extern int xg_select (int max_fds,
28 SELECT_TYPE *rfds, 28 SELECT_TYPE *rfds,
29 SELECT_TYPE *wfds, 29 SELECT_TYPE *wfds,
30 SELECT_TYPE *efds, 30 SELECT_TYPE *efds,
31 EMACS_TIME *timeout); 31 EMACS_TIME *timeout,
32 sigset_t *sigmask);
32 33
33extern void xgselect_initialize (void); 34extern void xgselect_initialize (void);
34 35
35#endif /* XGSELECT_H */ 36#endif /* XGSELECT_H */
36
diff --git a/src/xmenu.c b/src/xmenu.c
index 08b444f09f2..16279053e90 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -392,8 +392,6 @@ x_menu_wait_for_event (void *data)
392 ) 392 )
393 { 393 {
394 EMACS_TIME next_time = timer_check (), *ntp; 394 EMACS_TIME next_time = timer_check (), *ntp;
395 long secs = EMACS_SECS (next_time);
396 long usecs = EMACS_USECS (next_time);
397 SELECT_TYPE read_fds; 395 SELECT_TYPE read_fds;
398 struct x_display_info *dpyinfo; 396 struct x_display_info *dpyinfo;
399 int n = 0; 397 int n = 0;
@@ -407,7 +405,7 @@ x_menu_wait_for_event (void *data)
407 XFlush (dpyinfo->display); 405 XFlush (dpyinfo->display);
408 } 406 }
409 407
410 if (secs < 0 && usecs < 0) 408 if (! EMACS_TIME_VALID_P (next_time))
411 ntp = 0; 409 ntp = 0;
412 else 410 else
413 ntp = &next_time; 411 ntp = &next_time;
@@ -417,9 +415,9 @@ x_menu_wait_for_event (void *data)
417 over an arrow, a timeout scrolls it a bit. Use xg_select so that 415 over an arrow, a timeout scrolls it a bit. Use xg_select so that
418 timeout gets triggered. */ 416 timeout gets triggered. */
419 417
420 xg_select (n + 1, &read_fds, (SELECT_TYPE *)0, (SELECT_TYPE *)0, ntp); 418 xg_select (n + 1, &read_fds, NULL, NULL, ntp);
421#else 419#else
422 select (n + 1, &read_fds, (SELECT_TYPE *)0, (SELECT_TYPE *)0, ntp); 420 pselect (n + 1, &read_fds, NULL, NULL, ntp, NULL);
423#endif 421#endif
424 } 422 }
425} 423}
diff --git a/src/xselect.c b/src/xselect.c
index 49a491d4163..f21c57b44bb 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -1139,7 +1139,6 @@ wait_for_property_change_unwind (Lisp_Object loc)
1139static void 1139static void
1140wait_for_property_change (struct prop_location *location) 1140wait_for_property_change (struct prop_location *location)
1141{ 1141{
1142 int secs, usecs;
1143 ptrdiff_t count = SPECPDL_INDEX (); 1142 ptrdiff_t count = SPECPDL_INDEX ();
1144 1143
1145 if (property_change_reply_object) 1144 if (property_change_reply_object)
@@ -1156,10 +1155,11 @@ wait_for_property_change (struct prop_location *location)
1156 property_change_reply, because property_change_reply_object says so. */ 1155 property_change_reply, because property_change_reply_object says so. */
1157 if (! location->arrived) 1156 if (! location->arrived)
1158 { 1157 {
1159 secs = x_selection_timeout / 1000; 1158 EMACS_INT timeout = max (0, x_selection_timeout);
1160 usecs = (x_selection_timeout % 1000) * 1000; 1159 EMACS_INT secs = timeout / 1000;
1161 TRACE2 (" Waiting %d secs, %d usecs", secs, usecs); 1160 int nsecs = (timeout % 1000) * 1000000;
1162 wait_reading_process_output (secs, usecs, 0, 0, 1161 TRACE2 (" Waiting %"pI"d secs, %d nsecs", secs, nsecs);
1162 wait_reading_process_output (secs, nsecs, 0, 0,
1163 property_change_reply, NULL, 0); 1163 property_change_reply, NULL, 0);
1164 1164
1165 if (NILP (XCAR (property_change_reply))) 1165 if (NILP (XCAR (property_change_reply)))
@@ -1228,7 +1228,8 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
1228 Atom type_atom = (CONSP (target_type) 1228 Atom type_atom = (CONSP (target_type)
1229 ? symbol_to_x_atom (dpyinfo, XCAR (target_type)) 1229 ? symbol_to_x_atom (dpyinfo, XCAR (target_type))
1230 : symbol_to_x_atom (dpyinfo, target_type)); 1230 : symbol_to_x_atom (dpyinfo, target_type));
1231 int secs, usecs; 1231 EMACS_INT timeout, secs;
1232 int nsecs;
1232 1233
1233 if (!FRAME_LIVE_P (f)) 1234 if (!FRAME_LIVE_P (f))
1234 return Qnil; 1235 return Qnil;
@@ -1264,10 +1265,11 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
1264 UNBLOCK_INPUT; 1265 UNBLOCK_INPUT;
1265 1266
1266 /* This allows quits. Also, don't wait forever. */ 1267 /* This allows quits. Also, don't wait forever. */
1267 secs = x_selection_timeout / 1000; 1268 timeout = max (0, x_selection_timeout);
1268 usecs = (x_selection_timeout % 1000) * 1000; 1269 secs = timeout / 1000;
1269 TRACE1 (" Start waiting %d secs for SelectionNotify", secs); 1270 nsecs = (timeout % 1000) * 1000000;
1270 wait_reading_process_output (secs, usecs, 0, 0, 1271 TRACE1 (" Start waiting %"pI"d secs for SelectionNotify", secs);
1272 wait_reading_process_output (secs, nsecs, 0, 0,
1271 reading_selection_reply, NULL, 0); 1273 reading_selection_reply, NULL, 0);
1272 TRACE1 (" Got event = %d", !NILP (XCAR (reading_selection_reply))); 1274 TRACE1 (" Got event = %d", !NILP (XCAR (reading_selection_reply)));
1273 1275
diff --git a/src/xterm.c b/src/xterm.c
index fec661625f2..cb7aac2838c 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -85,10 +85,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
85#include <X11/Shell.h> 85#include <X11/Shell.h>
86#endif 86#endif
87 87
88#ifdef HAVE_SYS_TIME_H
89#include <sys/time.h>
90#endif
91
92#include <unistd.h> 88#include <unistd.h>
93 89
94#ifdef USE_GTK 90#ifdef USE_GTK
@@ -3072,44 +3068,6 @@ x_clear_frame (struct frame *f)
3072 3068
3073/* Invert the middle quarter of the frame for .15 sec. */ 3069/* Invert the middle quarter of the frame for .15 sec. */
3074 3070
3075/* We use the select system call to do the waiting, so we have to make
3076 sure it's available. If it isn't, we just won't do visual bells. */
3077
3078#if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3079
3080
3081/* Subtract the `struct timeval' values X and Y, storing the result in
3082 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3083
3084static int
3085timeval_subtract (struct timeval *result, struct timeval x, struct timeval y)
3086{
3087 /* Perform the carry for the later subtraction by updating y. This
3088 is safer because on some systems the tv_sec member is unsigned. */
3089 if (x.tv_usec < y.tv_usec)
3090 {
3091 int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
3092 y.tv_usec -= 1000000 * nsec;
3093 y.tv_sec += nsec;
3094 }
3095
3096 if (x.tv_usec - y.tv_usec > 1000000)
3097 {
3098 int nsec = (y.tv_usec - x.tv_usec) / 1000000;
3099 y.tv_usec += 1000000 * nsec;
3100 y.tv_sec -= nsec;
3101 }
3102
3103 /* Compute the time remaining to wait. tv_usec is certainly
3104 positive. */
3105 result->tv_sec = x.tv_sec - y.tv_sec;
3106 result->tv_usec = x.tv_usec - y.tv_usec;
3107
3108 /* Return indication of whether the result should be considered
3109 negative. */
3110 return x.tv_sec < y.tv_sec;
3111}
3112
3113static void 3071static void
3114XTflash (struct frame *f) 3072XTflash (struct frame *f)
3115{ 3073{
@@ -3210,34 +3168,29 @@ XTflash (struct frame *f)
3210 x_flush (f); 3168 x_flush (f);
3211 3169
3212 { 3170 {
3213 struct timeval wakeup; 3171 EMACS_TIME wakeup, delay;
3214 3172
3215 EMACS_GET_TIME (wakeup); 3173 EMACS_GET_TIME (wakeup);
3216 3174 EMACS_SET_SECS_NSECS (delay, 0, 150 * 1000 * 1000);
3217 /* Compute time to wait until, propagating carry from usecs. */ 3175 EMACS_ADD_TIME (wakeup, wakeup, delay);
3218 wakeup.tv_usec += 150000;
3219 wakeup.tv_sec += (wakeup.tv_usec / 1000000);
3220 wakeup.tv_usec %= 1000000;
3221 3176
3222 /* Keep waiting until past the time wakeup or any input gets 3177 /* Keep waiting until past the time wakeup or any input gets
3223 available. */ 3178 available. */
3224 while (! detect_input_pending ()) 3179 while (! detect_input_pending ())
3225 { 3180 {
3226 struct timeval current; 3181 EMACS_TIME current, timeout;
3227 struct timeval timeout;
3228 3182
3229 EMACS_GET_TIME (current); 3183 EMACS_GET_TIME (current);
3230 3184
3231 /* Break if result would be negative. */ 3185 /* Break if result would not be positive. */
3232 if (timeval_subtract (&current, wakeup, current)) 3186 if (EMACS_TIME_LE (wakeup, current))
3233 break; 3187 break;
3234 3188
3235 /* How long `select' should wait. */ 3189 /* How long `select' should wait. */
3236 timeout.tv_sec = 0; 3190 EMACS_SET_SECS_NSECS (timeout, 0, 10 * 1000 * 1000);
3237 timeout.tv_usec = 10000;
3238 3191
3239 /* Try to wait that long--but we might wake up sooner. */ 3192 /* Try to wait that long--but we might wake up sooner. */
3240 select (0, NULL, NULL, NULL, &timeout); 3193 pselect (0, NULL, NULL, NULL, &timeout, NULL);
3241 } 3194 }
3242 } 3195 }
3243 3196
@@ -3278,8 +3231,6 @@ XTflash (struct frame *f)
3278 UNBLOCK_INPUT; 3231 UNBLOCK_INPUT;
3279} 3232}
3280 3233
3281#endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
3282
3283 3234
3284static void 3235static void
3285XTtoggle_invisible_pointer (FRAME_PTR f, int invisible) 3236XTtoggle_invisible_pointer (FRAME_PTR f, int invisible)
@@ -3306,11 +3257,9 @@ XTring_bell (struct frame *f)
3306{ 3257{
3307 if (FRAME_X_DISPLAY (f)) 3258 if (FRAME_X_DISPLAY (f))
3308 { 3259 {
3309#if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3310 if (visible_bell) 3260 if (visible_bell)
3311 XTflash (f); 3261 XTflash (f);
3312 else 3262 else
3313#endif
3314 { 3263 {
3315 BLOCK_INPUT; 3264 BLOCK_INPUT;
3316 XBell (FRAME_X_DISPLAY (f), 0); 3265 XBell (FRAME_X_DISPLAY (f), 0);
@@ -8878,9 +8827,11 @@ x_wait_for_event (struct frame *f, int eventtype)
8878 FD_SET (fd, &fds); 8827 FD_SET (fd, &fds);
8879 8828
8880 EMACS_GET_TIME (time_now); 8829 EMACS_GET_TIME (time_now);
8881 EMACS_SUB_TIME (tmo, tmo_at, time_now); 8830 if (EMACS_TIME_LT (tmo_at, time_now))
8831 break;
8882 8832
8883 if (EMACS_TIME_NEG_P (tmo) || select (fd+1, &fds, NULL, NULL, &tmo) == 0) 8833 EMACS_SUB_TIME (tmo, tmo_at, time_now);
8834 if (pselect (fd + 1, &fds, NULL, NULL, &tmo, NULL) == 0)
8884 break; /* Timeout */ 8835 break; /* Timeout */
8885 } 8836 }
8886 pending_event_wait.f = 0; 8837 pending_event_wait.f = 0;