all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: no-spam@cua.dk (Kim F. Storm)
Subject: Fix for slow process output processing (please test).
Date: 16 Dec 2003 02:21:35 +0100	[thread overview]
Message-ID: <m3zndtimlc.fsf@kfs-l.imdomain.dk> (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;

             reply	other threads:[~2003-12-16  1:21 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-12-16  1:21 Kim F. Storm [this message]
2003-12-16  2:14 ` Fix for slow process output processing (please test) 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m3zndtimlc.fsf@kfs-l.imdomain.dk \
    --to=no-spam@cua.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.