diff options
| author | Paul Eggert | 2012-06-22 14:17:42 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-06-22 14:17:42 -0700 |
| commit | d35af63cd671563fd188c3b0a1ef30067027c7aa (patch) | |
| tree | c9e01847ccf788e23794684da9331c3e0defd0d3 /src | |
| parent | f143bfe38b43ad0a9d817f05c25e418982dca06f (diff) | |
| download | emacs-d35af63cd671563fd188c3b0a1ef30067027c7aa.tar.gz emacs-d35af63cd671563fd188c3b0a1ef30067027c7aa.zip | |
Support higher-resolution time stamps.
Fixes: debbugs:9000
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 169 | ||||
| -rw-r--r-- | src/Makefile.in | 4 | ||||
| -rw-r--r-- | src/alloc.c | 12 | ||||
| -rw-r--r-- | src/atimer.c | 22 | ||||
| -rw-r--r-- | src/buffer.c | 8 | ||||
| -rw-r--r-- | src/buffer.h | 12 | ||||
| -rw-r--r-- | src/dired.c | 11 | ||||
| -rw-r--r-- | src/dispextern.h | 6 | ||||
| -rw-r--r-- | src/dispnew.c | 130 | ||||
| -rw-r--r-- | src/editfns.c | 290 | ||||
| -rw-r--r-- | src/fileio.c | 79 | ||||
| -rw-r--r-- | src/fns.c | 2 | ||||
| -rw-r--r-- | src/gtkutil.c | 12 | ||||
| -rw-r--r-- | src/image.c | 17 | ||||
| -rw-r--r-- | src/keyboard.c | 188 | ||||
| -rw-r--r-- | src/lisp.h | 3 | ||||
| -rw-r--r-- | src/lread.c | 10 | ||||
| -rw-r--r-- | src/msdos.c | 11 | ||||
| -rw-r--r-- | src/nsterm.h | 3 | ||||
| -rw-r--r-- | src/nsterm.m | 75 | ||||
| -rw-r--r-- | src/process.c | 222 | ||||
| -rw-r--r-- | src/process.h | 4 | ||||
| -rw-r--r-- | src/sysdep.c | 227 | ||||
| -rw-r--r-- | src/sysselect.h | 3 | ||||
| -rw-r--r-- | src/systime.h | 159 | ||||
| -rw-r--r-- | src/term.c | 20 | ||||
| -rw-r--r-- | src/undo.c | 23 | ||||
| -rw-r--r-- | src/w32.c | 45 | ||||
| -rw-r--r-- | src/xdisp.c | 18 | ||||
| -rw-r--r-- | src/xgselect.c | 23 | ||||
| -rw-r--r-- | src/xgselect.h | 4 | ||||
| -rw-r--r-- | src/xmenu.c | 8 | ||||
| -rw-r--r-- | src/xselect.c | 22 | ||||
| -rw-r--r-- | src/xterm.c | 73 |
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 @@ | |||
| 1 | 2012-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 | |||
| 1 | 2012-06-22 Chong Yidong <cyd@gnu.org> | 170 | 2012-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@ | |||
| 153 | M17N_FLT_CFLAGS = @M17N_FLT_CFLAGS@ | 153 | M17N_FLT_CFLAGS = @M17N_FLT_CFLAGS@ |
| 154 | M17N_FLT_LIBS = @M17N_FLT_LIBS@ | 154 | M17N_FLT_LIBS = @M17N_FLT_LIBS@ |
| 155 | 155 | ||
| 156 | LIB_CLOCK_GETTIME=@LIB_CLOCK_GETTIME@ | ||
| 157 | |||
| 156 | DBUS_CFLAGS = @DBUS_CFLAGS@ | 158 | DBUS_CFLAGS = @DBUS_CFLAGS@ |
| 157 | DBUS_LIBS = @DBUS_LIBS@ | 159 | DBUS_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. |
| 386 | LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \ | 388 | LIBES = $(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 | |||
| 5834 | from (abs POSITION). If POSITION is positive, point was at the front | 5834 | from (abs POSITION). If POSITION is positive, point was at the front |
| 5835 | of the text being deleted; if negative, point was at the end. | 5835 | of the text being deleted; if negative, point was at the end. |
| 5836 | 5836 | ||
| 5837 | An entry (t HIGH . LOW) indicates that the buffer previously had | 5837 | An 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 | 5838 | unmodified; (HIGH LOW USEC PSEC) is in the same style as (current-time) |
| 5839 | of the visited file's modification time, as of that time. If the | 5839 | and is the visited file's modification time, as of that time. If the |
| 5840 | modification time of the most recent save is different, this entry is | 5840 | modification time of the most recent save is different, this entry is |
| 5841 | obsolete. | 5841 | obsolete. |
| 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 | |||
| 19 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | 19 | along 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; | |||
| 68 | typedef XImagePtr XImagePtr_or_DC; | 68 | typedef 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 |
| 72 | typedef int Cursor; | 76 | typedef 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 *); | |||
| 137 | static void adjust_frame_glyphs_for_frame_redisplay (struct frame *); | 137 | static 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 | ||
| 153 | static EMACS_TIME preemption_period; | 142 | static EMACS_TIME preemption_period; |
| 154 | static EMACS_TIME preemption_next_check; | 143 | static 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. */ | ||
| 5973 | void | ||
| 5974 | duration_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 | |||
| 6002 | DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0, | 5941 | DEFUN ("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. |
| 6004 | SECONDS may be a floating-point value, meaning that you can wait for a | 5943 | SECONDS may be a floating-point value, meaning that you can wait for a |
| 6005 | fraction of a second. Optional second arg MILLISECONDS specifies an | 5944 | fraction of a second. Optional second arg MILLISECONDS specifies an |
| 6006 | additional wait period, in milliseconds; this may be useful if your | 5945 | additional wait period, in milliseconds; this is for backwards compatibility. |
| 6007 | Emacs 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. | |||
| 6046 | Lisp_Object | 5978 | Lisp_Object |
| 6047 | sit_for (Lisp_Object timeout, int reading, int do_display) | 5979 | sit_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; | |||
| 73 | extern Lisp_Object w32_get_internal_run_time (void); | 73 | extern Lisp_Object w32_get_internal_run_time (void); |
| 74 | #endif | 74 | #endif |
| 75 | 75 | ||
| 76 | static void time_overflow (void) NO_RETURN; | 76 | static Lisp_Object format_time_string (char const *, ptrdiff_t, EMACS_TIME, |
| 77 | static Lisp_Object format_time_string (char const *, ptrdiff_t, Lisp_Object, | 77 | int, struct tm *); |
| 78 | int, time_t *, struct tm *); | ||
| 79 | static int tm_diff (struct tm *, struct tm *); | 78 | static int tm_diff (struct tm *, struct tm *); |
| 80 | static void update_buffer_properties (ptrdiff_t, ptrdiff_t); | 79 | static 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. */ |
| 1381 | static void | 1380 | void |
| 1382 | time_overflow (void) | 1381 | time_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. */ | ||
| 1389 | static EMACS_INT | 1387 | static EMACS_INT |
| 1390 | hi_time (time_t t) | 1388 | hi_time (time_t t) |
| 1391 | { | 1389 | { |
| @@ -1413,40 +1411,33 @@ lo_time (time_t t) | |||
| 1413 | 1411 | ||
| 1414 | DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0, | 1412 | DEFUN ("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. |
| 1416 | The time is returned as a list of three integers. The first has the | 1414 | The time is returned as a list of integers (HIGH LOW USEC PSEC). |
| 1417 | most significant 16 bits of the seconds, while the second has the | 1415 | HIGH has the most significant bits of the seconds, while LOW has the |
| 1418 | least significant 16 bits. The third integer gives the microsecond | 1416 | least significant 16 bits. USEC and PSEC are the microsecond and |
| 1419 | count. | 1417 | picosecond counts. */) |
| 1420 | |||
| 1421 | The microsecond count is zero on systems that do not provide | ||
| 1422 | resolution 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 | ||
| 1433 | DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time, | 1426 | DEFUN ("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. |
| 1436 | The time is returned as a list of three integers. The first has the | 1429 | The time is returned as a list (HIGH LOW USEC PSEC), using the same |
| 1437 | most significant 16 bits of the seconds, while the second has the | 1430 | style as (current-time). |
| 1438 | least significant 16 bits. The third integer gives the microsecond | ||
| 1439 | count. | ||
| 1440 | 1431 | ||
| 1441 | On systems that can't determine the run time, `get-internal-run-time' | 1432 | On systems that can't determine the run time, `get-internal-run-time' |
| 1442 | does the same thing as `current-time'. The microsecond count is zero | 1433 | does the same thing as `current-time'. */) |
| 1443 | on 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. */ |
| 1478 | Lisp_Object | 1467 | static Lisp_Object |
| 1468 | make_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. */ | ||
| 1475 | static Lisp_Object | ||
| 1479 | make_time (time_t t) | 1476 | make_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. */ | ||
| 1485 | Lisp_Object | ||
| 1486 | make_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. */ |
| 1497 | static int | ||
| 1498 | disassemble_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. */ | ||
| 1490 | int | 1537 | int |
| 1491 | lisp_time_argument (Lisp_Object specified_time, time_t *result, int *usec) | 1538 | decode_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. */ | ||
| 1579 | EMACS_TIME | ||
| 1580 | lisp_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. */ | ||
| 1597 | static time_t | ||
| 1598 | lisp_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. |
| 1556 | If SPECIFIED-TIME is given, it is the time to convert to float | 1616 | If SPECIFIED-TIME is given, it is the time to convert to float |
| 1557 | instead of the current time. The argument should have the form | 1617 | instead 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 | 1619 | you can use times from `current-time' and from `file-attributes'. |
| 1560 | have the form (HIGH . LOW), but this is considered obsolete. | 1620 | SPECIFIED-TIME can also have the form (HIGH . LOW), but this is |
| 1621 | considered obsolete. | ||
| 1561 | 1622 | ||
| 1562 | WARNING: Since the result is floating point, it may not be exact. | 1623 | WARNING: Since the result is floating point, it may not be exact. |
| 1563 | If precise time stamps are required, use either `current-time', | 1624 | If precise time stamps are required, use either `current-time', |
| 1564 | or (if you need time as a string) `format-time-string'. */) | 1625 | or (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 | ||
| 1626 | DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0, | 1686 | DEFUN ("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. |
| 1628 | TIME is specified as (HIGH LOW . IGNORED), as returned by | 1688 | TIME 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) |
| 1630 | is also still accepted. | 1690 | is also still accepted. |
| 1631 | The third, optional, argument UNIVERSAL, if non-nil, means describe TIME | 1691 | The 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". | |||
| 1679 | usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) | 1739 | usage: (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 | ||
| 1692 | static Lisp_Object | 1752 | static Lisp_Object |
| 1693 | format_time_string (char const *format, ptrdiff_t formatlen, | 1753 | format_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 | |||
| 1758 | DOW and ZONE.) */) | 1813 | DOW 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 | |||
| 1919 | but this is considered obsolete. */) | 1970 | but 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 | |||
| 1994 | the data it can't find. */) | 2042 | the 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, | |||
| 5127 | Next attempt to save will certainly not complain of a discrepancy. */) | 5122 | Next 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. */) | |||
| 5135 | DEFUN ("visited-file-modtime", Fvisited_file_modtime, | 5130 | DEFUN ("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. |
| 5138 | The value is a list of the form (HIGH LOW), like the time values that | 5133 | The 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 |
| 5140 | modification time, this function returns 0. If the visited file | 5135 | modification time, this function returns 0. If the visited file |
| 5141 | doesn't exist, HIGH will be -1. | 5136 | doesn't exist, HIGH will be -1. |
| 5142 | See Info node `(elisp)Modification Time' for more details. */) | 5137 | See 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 | ||
| 5150 | DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime, | 5145 | DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime, |
| @@ -5154,12 +5149,12 @@ Useful if the buffer was not read from the file normally | |||
| 5154 | or if the file itself has been changed for some known benign reason. | 5149 | or if the file itself has been changed for some known benign reason. |
| 5155 | An argument specifies the modification time value to use | 5150 | An 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 | } |
| @@ -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) | |||
| 1062 | void | 1062 | void |
| 1063 | prepare_image_for_display (struct frame *f, struct image *img) | 1063 | prepare_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 | |||
| 2093 | bind_polling_period (int n) | 2094 | bind_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 | ||
| 2225 | static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, int *used_mouse_menu, | 2226 | static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, int *used_mouse_menu, |
| 2226 | struct timeval *end_time); | 2227 | EMACS_TIME *end_time); |
| 2227 | static void record_char (Lisp_Object c); | 2228 | static void record_char (Lisp_Object c); |
| 2228 | 2229 | ||
| 2229 | static Lisp_Object help_form_saved_window_configs; | 2230 | static Lisp_Object help_form_saved_window_configs; |
| @@ -2275,7 +2276,7 @@ do { if (polling_stopped_here) start_polling (); \ | |||
| 2275 | Lisp_Object | 2276 | Lisp_Object |
| 2276 | read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps, | 2277 | read_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) | |||
| 3783 | static Lisp_Object | 3784 | static Lisp_Object |
| 3784 | kbd_buffer_get_event (KBOARD **kbp, | 3785 | kbd_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) | |||
| 4278 | static void | 4280 | static void |
| 4279 | timer_stop_idle (void) | 4281 | timer_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) | |||
| 4286 | static void | 4288 | static void |
| 4287 | timer_resume_idle (void) | 4289 | timer_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). */ |
| 4301 | Lisp_Object pending_funcalls; | 4303 | Lisp_Object pending_funcalls; |
| 4302 | 4304 | ||
| 4305 | /* If TIMER is a valid timer, return nonzero and place its value into | ||
| 4306 | *RESULT. Otherwise return zero. */ | ||
| 4307 | static int | ||
| 4308 | decode_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 | ||
| 4529 | DEFUN ("current-idle-time", Fcurrent_idle_time, Scurrent_idle_time, 0, 0, 0, | 4521 | DEFUN ("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. |
| 4531 | The value when Emacs is idle is a list of three integers. The first has | 4523 | The value when Emacs is idle is a list of four integers (HIGH LOW USEC PSEC) |
| 4532 | the most significant 16 bits of the seconds, while the second has the least | 4524 | in the same style as (current-time). |
| 4533 | significant 16 bits. The third integer gives the microsecond count. | ||
| 4534 | 4525 | ||
| 4535 | The value when Emacs is not idle is nil. | 4526 | The value when Emacs is not idle is nil. |
| 4536 | 4527 | ||
| 4537 | The microsecond count is zero on systems that do not provide | 4528 | NSEC is a multiple of the system clock resolution. */) |
| 4538 | resolution 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 | ||
| 10737 | void | 10725 | void |
| 10738 | set_waiting_for_input (struct timeval *time_to_clear) | 10726 | set_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); | |||
| 2954 | EXFUN (Fwiden, 0); | 2954 | EXFUN (Fwiden, 0); |
| 2955 | EXFUN (Fuser_login_name, 1); | 2955 | EXFUN (Fuser_login_name, 1); |
| 2956 | EXFUN (Fsystem_name, 0); | 2956 | EXFUN (Fsystem_name, 0); |
| 2957 | extern void time_overflow (void) NO_RETURN; | ||
| 2957 | EXFUN (Fcurrent_time, 0); | 2958 | EXFUN (Fcurrent_time, 0); |
| 2958 | EXFUN (Fget_internal_run_time, 0); | 2959 | EXFUN (Fget_internal_run_time, 0); |
| 2959 | extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, int); | 2960 | extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, int); |
| @@ -3244,7 +3245,7 @@ EXFUN (Fkill_process, 2); | |||
| 3244 | EXFUN (Fwaiting_for_user_input_p, 0); | 3245 | EXFUN (Fwaiting_for_user_input_p, 0); |
| 3245 | extern Lisp_Object Qprocessp; | 3246 | extern Lisp_Object Qprocessp; |
| 3246 | extern void kill_buffer_processes (Lisp_Object); | 3247 | extern void kill_buffer_processes (Lisp_Object); |
| 3247 | extern int wait_reading_process_output (int, int, int, int, | 3248 | extern 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 */ |
| 826 | extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds, | 826 | extern 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); | ||
| 828 | extern unsigned long ns_get_rgb_color (struct frame *f, | 829 | extern 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); |
| 830 | extern NSPoint last_mouse_motion_position; | 831 | extern 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; | |||
| 183 | static NSTimer *fd_entry = nil; | 183 | static NSTimer *fd_entry = nil; |
| 184 | static NSTimer *scroll_repeat_entry = nil; | 184 | static NSTimer *scroll_repeat_entry = nil; |
| 185 | static fd_set select_readfds, t_readfds; | 185 | static fd_set select_readfds, t_readfds; |
| 186 | static struct timeval select_timeout; | ||
| 187 | static int select_nfds; | 186 | static int select_nfds; |
| 188 | static NSAutoreleasePool *outerpool; | 187 | static NSAutoreleasePool *outerpool; |
| 189 | static struct input_event *emacs_event = NULL; | 188 | static struct input_event *emacs_event = NULL; |
| @@ -381,67 +380,30 @@ ns_init_paths (void) | |||
| 381 | } | 380 | } |
| 382 | } | 381 | } |
| 383 | 382 | ||
| 384 | |||
| 385 | static int | ||
| 386 | timeval_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 | |||
| 416 | static void | 383 | static void |
| 417 | ns_timeout (int usecs) | 384 | ns_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 | ||
| 3538 | int | 3500 | int |
| 3539 | ns_select (int nfds, fd_set *readfds, fd_set *writefds, | 3501 | ns_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. | |||
| 3961 | Return non-nil if we received any output before the timeout expired. */) | 3958 | Return 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 | ||
| 4242 | static inline int | ||
| 4243 | select_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 | ||
| 4287 | int | 4289 | int |
| 4288 | wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | 4290 | wait_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 | ||
| 6846 | int | 6860 | int |
| 6847 | wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | 6861 | wait_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. */ | ||
| 120 | struct utimbuf { | ||
| 121 | long actime; | ||
| 122 | long modtime; | ||
| 123 | }; | ||
| 124 | #endif | ||
| 125 | #endif | ||
| 126 | 113 | ||
| 127 | static int emacs_get_tty (int, struct emacs_tty *); | 114 | static int emacs_get_tty (int, struct emacs_tty *); |
| 128 | static int emacs_set_tty (int, struct emacs_tty *, int); | 115 | static 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 | |||
| 2078 | int | ||
| 2079 | gettimeofday (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. */ | ||
| 2095 | struct timeval | ||
| 2096 | make_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. */ | ||
| 2129 | int | 2121 | int |
| 2130 | set_file_times (const char *filename, EMACS_TIME atime, EMACS_TIME mtime) | 2122 | set_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 |
| 2598 | static void | 2584 | static EMACS_TIME |
| 2599 | time_from_jiffies (unsigned long long tval, long hz, | 2585 | time_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 | ||
| 2614 | static Lisp_Object | 2611 | static Lisp_Object |
| 2615 | ltime_from_jiffies (unsigned long long tval, long hz) | 2612 | ltime_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 | ||
| 2627 | static void | 2618 | static EMACS_TIME |
| 2628 | get_up_time (time_t *sec, unsigned *usec) | 2619 | get_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. | |||
| 16 | You should have received a copy of the GNU General Public License | 16 | You should have received a copy of the GNU General Public License |
| 17 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | 17 | along 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 | ||
| 135 | extern int set_file_times (const char *, EMACS_TIME, EMACS_TIME); | 97 | /* defined in sysdep.c */ |
| 98 | extern int set_file_times (int, const char *, EMACS_TIME, EMACS_TIME); | ||
| 99 | extern struct timeval make_timeval (EMACS_TIME); | ||
| 136 | 100 | ||
| 137 | /* defined in keyboard.c */ | 101 | /* defined in keyboard.c */ |
| 138 | extern void set_waiting_for_input (EMACS_TIME *); | 102 | extern 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 */ |
| 145 | extern Lisp_Object make_time (time_t); | 109 | extern Lisp_Object make_lisp_time (EMACS_TIME); |
| 146 | extern int lisp_time_argument (Lisp_Object, time_t *, int *); | 110 | extern int decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object, |
| 111 | Lisp_Object, EMACS_TIME *, int *); | ||
| 112 | extern 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. */ | ||
| 2616 | static Time | ||
| 2617 | timeval_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 (); |
| @@ -318,8 +318,10 @@ is_windows_9x (void) | |||
| 318 | return s_b_ret; | 318 | return s_b_ret; |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | static 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. */ |
| 324 | Lisp_Object | 326 | Lisp_Object |
| 325 | w32_get_internal_run_time (void) | 327 | w32_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 | ||
| 4073 | static Lisp_Object | 4061 | ltime (ULONGLONG time_100ns) |
| 4074 | ltime (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 | ||
| 4083 | static int | 4073 | static int |
| 4084 | process_times (HANDLE h_proc, Lisp_Object *ctime, Lisp_Object *etime, | 4074 | process_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 | ||
| 35 | int | 35 | int |
| 36 | xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | 36 | xg_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 | ||
| 33 | extern void xgselect_initialize (void); | 34 | extern 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) | |||
| 1139 | static void | 1139 | static void |
| 1140 | wait_for_property_change (struct prop_location *location) | 1140 | wait_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 | |||
| 3084 | static int | ||
| 3085 | timeval_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 | |||
| 3113 | static void | 3071 | static void |
| 3114 | XTflash (struct frame *f) | 3072 | XTflash (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 (¤t, 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 | ||
| 3284 | static void | 3235 | static void |
| 3285 | XTtoggle_invisible_pointer (FRAME_PTR f, int invisible) | 3236 | XTtoggle_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; |