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/process.c | |
| parent | f143bfe38b43ad0a9d817f05c25e418982dca06f (diff) | |
| download | emacs-d35af63cd671563fd188c3b0a1ef30067027c7aa.tar.gz emacs-d35af63cd671563fd188c3b0a1ef30067027c7aa.zip | |
Support higher-resolution time stamps.
Fixes: debbugs:9000
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 222 |
1 files changed, 121 insertions, 101 deletions
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) |