unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Fix for slow process output processing (please test).
@ 2003-12-16  1:21 Kim F. Storm
  2003-12-16  2:14 ` David Kastrup
                   ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Kim F. Storm @ 2003-12-16  1:21 UTC (permalink / raw)



David Kastrup and others have reported very slow processing of process
output, particularly with the Linux kernel's scheduler giving emacs
too much attention while starving the processing producing the output.

Below is a patch which introduces a small delay on reading output from
such processes, without using global delays in processing other events
(this is done by temporarily removing the process' file descriptor from
the call to select and use a short timeout on the select instead.

I have not yet tested this extensively, but would like some feedback
on whether it actually does have the intended positive effect on the
processing of process output.  Could people who have experienced
these problems pls. try the patch and give me feedback.

The patch is against CVS emacs at the time of "server shutdown".

++kfs


*** process.h.~1.24.~	2003-09-01 17:45:56.000000000 +0200
--- process.h	2003-12-16 00:39:22.000000000 +0100
***************
*** 101,106 ****
--- 101,115 ----
         generated, and can be changed by the function
         `set-process-fileter-multibyte'. */
      Lisp_Object filter_multibyte;
+     /* Hysteresis to try to read process output in larger blocks.
+        On some systems, e.g. the Linux kernel, emacs is seen as 
+        an interactive app also when reading process output, meaning
+        that process output can be read in as little as 1 byte at a
+        time.  Value is micro-seconds to delay reading output from
+        this process.  Range is 0 .. 50000.  */
+     Lisp_Object read_output_delay;
+     /* Skip reading this process on next read.  */
+     Lisp_Object read_output_skip;
  };
  
  /* Every field in the preceding structure except for the first two

*** process.c.~1.417.~	2003-11-16 22:25:47.000000000 +0100
--- process.c	2003-12-16 02:00:47.000000000 +0100
***************
*** 260,265 ****
--- 260,282 ----
  #undef DATAGRAM_SOCKETS
  #endif
  
+ #ifdef EMACS_HAS_USECS
+ 
+ #define READ_OUTPUT_DELAY_INCREMENT 10000
+ #define READ_OUTPUT_DELAY_MAX       (READ_OUTPUT_DELAY_INCREMENT * 5)
+ #define READ_OUTPUT_DELAY_MAX_MAX   (READ_OUTPUT_DELAY_INCREMENT * 7)
+ 
+ /* Number of processes which might be delayed.  */
+ 
+ static int process_output_delay_count;
+ 
+ /* Non-zero if any process has non-nil process_output_skip.  */
+ 
+ static int process_output_skip;
+ #else
+ #define process_output_delay_count 0
+ #endif
+ 
  
  #include "sysselect.h"
  
***************
*** 573,578 ****
--- 590,600 ----
    p->status = Qrun;
    p->mark = Fmake_marker ();
  
+ #ifdef READ_OUTPUT_DELAY_INCREMENT
+   XSETFASTINT (p->read_output_delay, 0);
+   p->read_output_skip = Qnil;
+ #endif
+ 
    /* If name is already in use, modify it until it is unused.  */
  
    name1 = name;
***************
*** 3588,3593 ****
--- 3610,3625 ----
    inchannel = XINT (p->infd);
    outchannel = XINT (p->outfd);
  
+ #ifdef READ_OUTPUT_DELAY_INCREMENT
+   if (XINT (p->read_output_delay) > 0)
+     {
+       if (--process_output_delay_count < 0)
+ 	process_output_delay_count = 0;
+       XSETINT (p->read_output_delay, 0);
+       p->read_output_skip = Qnil;
+     }
+ #endif
+       
    if (inchannel >= 0)
      {
        /* Beware SIGCHLD hereabouts. */
***************
*** 3973,3979 ****
    register int channel, nfds;
    static SELECT_TYPE Available;
    static SELECT_TYPE Connecting;
!   int check_connect, no_avail;
    int xerrno;
    Lisp_Object proc;
    EMACS_TIME timeout, end_time;
--- 4005,4011 ----
    register int channel, nfds;
    static SELECT_TYPE Available;
    static SELECT_TYPE Connecting;
!   int check_connect, check_delay, no_avail;
    int xerrno;
    Lisp_Object proc;
    EMACS_TIME timeout, end_time;
***************
*** 4202,4208 ****
        if (!NILP (wait_for_cell))
  	{
  	  Available = non_process_wait_mask;
! 	  check_connect = 0;
  	}
        else
  	{
--- 4234,4240 ----
        if (!NILP (wait_for_cell))
  	{
  	  Available = non_process_wait_mask;
! 	  check_connect = check_delay = 0;
  	}
        else
  	{
***************
*** 4211,4216 ****
--- 4243,4249 ----
  	  else
  	    Available = input_wait_mask;
  	  check_connect = (num_pending_connects > 0);
+ 	  check_delay = process_output_delay_count;
  	}
  
        /* If frame size has changed or the window is newly mapped,
***************
*** 4236,4241 ****
--- 4269,4302 ----
  	{
  	  if (check_connect)
  	    Connecting = connect_wait_mask;
+ 
+ #ifdef READ_OUTPUT_DELAY_INCREMENT
+ 	  if (process_output_skip && check_delay > 0)
+ 	    {
+ 	      int usecs = EMACS_USECS (timeout);
+ 	      if (EMACS_SECS (timeout) > 0 || usecs > READ_OUTPUT_DELAY_MAX)
+ 		usecs = READ_OUTPUT_DELAY_MAX;
+ 	      for (channel = 0; check_delay > 0 && channel <= max_process_desc; channel++)
+ 		{
+ 		  proc = chan_process[channel];
+ 		  if (NILP (proc))
+ 		    continue;
+ 		  if (XPROCESS (proc)->read_output_delay > 0)
+ 		    {
+ 		      check_delay--;
+ 		      if (NILP (XPROCESS (proc)->read_output_skip))
+ 			continue;
+ 		      FD_CLR (channel, &Available);
+ 		      XPROCESS (proc)->read_output_skip = Qnil;
+ 		      if (XINT (XPROCESS (proc)->read_output_delay) < usecs)
+ 			usecs = XINT (XPROCESS (proc)->read_output_delay);
+ 		    }
+ 		}
+ 	      EMACS_SET_SECS_USECS (timeout, 0, usecs);
+ 	      process_output_skip = 0;
+ 	    }
+ #endif
+ 
  	  nfds = select (max (max_process_desc, max_keyboard_desc) + 1,
  			 &Available,
  			 (check_connect ? &Connecting : (SELECT_TYPE *)0),
***************
*** 4689,4695 ****
    else
  #endif
    if (proc_buffered_char[channel] < 0)
!     nbytes = emacs_read (channel, chars + carryover, readmax - carryover);
    else
      {
        chars[carryover] = proc_buffered_char[channel];
--- 4750,4785 ----
    else
  #endif
    if (proc_buffered_char[channel] < 0)
!     {
!       nbytes = emacs_read (channel, chars + carryover, readmax - carryover);
! #ifdef READ_OUTPUT_DELAY_INCREMENT
!       if (!NETCONN1_P (p))
! 	{
! 	  int delay = XINT (p->read_output_delay);
! 	  if (nbytes < readmax - carryover)
! 	    {
! 	      if (delay < READ_OUTPUT_DELAY_MAX_MAX)
! 		{
! 		  if (delay == 0)
! 		    process_output_delay_count++;
! 		  delay += READ_OUTPUT_DELAY_INCREMENT;
! 		}
! 	    }
! 	  else if (delay > 0)
! 	    {
! 	      delay -= READ_OUTPUT_DELAY_INCREMENT;
! 	      if (delay == 0)
! 		process_output_delay_count--;
! 	    }
! 	  XSETINT (p->read_output_delay, delay);
! 	  if (delay)
! 	    {
! 	      p->read_output_skip = Qt;
! 	      process_output_skip = 1;
! 	    }
! 	}
! #endif
!     }
    else
      {
        chars[carryover] = proc_buffered_char[channel];
***************
*** 6503,6508 ****
--- 6593,6603 ----
    FD_ZERO (&non_process_wait_mask);
    max_process_desc = 0;
  
+ #ifdef READ_OUTPUT_DELAY_INCREMENT
+   process_output_delay_count = 0;
+   process_output_skip = 0;
+ #endif
+ 
    FD_SET (0, &input_wait_mask);
  
    Vprocess_alist = Qnil;

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2004-01-07  0:40 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-12-16  1:21 Fix for slow process output processing (please test) Kim F. Storm
2003-12-16  2:14 ` David Kastrup
2003-12-16  3:34 ` David Kastrup
2003-12-16 10:23   ` Kim F. Storm
2003-12-16 11:51     ` David Kastrup
2003-12-16 13:24       ` Kim F. Storm
2004-01-03 15:12         ` David Kastrup
2004-01-04 23:00           ` Kim F. Storm
2004-01-03 22:07 ` Eric Hanchrow
2004-01-04 22:42   ` Kim F. Storm
2004-01-05 15:57     ` David Kastrup
2004-01-05 19:09       ` Eli Zaretskii
2004-01-05 19:39         ` David Kastrup
2004-01-05 19:52         ` Jason Rumney
2004-01-05 23:28           ` Kim F. Storm
2004-01-05 23:16             ` Jason Rumney
2004-01-05 23:44               ` David Kastrup
2004-01-06  0:23                 ` Jason Rumney
2004-01-07  0:40               ` Kim F. Storm
2004-01-05 23:35       ` Kim F. Storm
2004-01-05 22:50         ` David Kastrup
2004-01-06  0:09           ` Kim F. Storm

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).