]> git.eshelyaron.com Git - emacs.git/commitdiff
Optimize tty display updates (bug#57727)
authorGerd Möllmann <gerd@gnu.org>
Sun, 11 Sep 2022 09:42:18 +0000 (11:42 +0200)
committerGerd Möllmann <gerd@gnu.org>
Sat, 17 Sep 2022 13:33:10 +0000 (15:33 +0200)
* src/dispnew.c (update_frame_1): Don'f flush if tty's
output_buffer_size is non-zero.
* src/sysdep.c (init_sys_modes): Setvbuf depending on the tty's
output_buffer_size.
* src/term.c (Ftty__set_output_buffer_size, Ftty__output_buffer_size):
Low-level interface for setting and retrieving a tty's output buffer
size.
(syms_of_term): Defsubr the new functions.
* src/termchar.h (struct tty_display_info): New member
output_buffer_size.
* stc/NEWS: Describe the change.

etc/NEWS
src/dispnew.c
src/sysdep.c
src/term.c
src/termchar.h

index a6a8883593b1143144dfb8b31e4f3fae81e76272..cd14bcf69b5045a50162ebd89b6b416079170676 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -777,6 +777,16 @@ doesn't support.  It is most useful with the Linux console and similar
 terminals, where Emacs has a reliable way of determining which
 characters have glyphs in the font loaded into the terminal's memory.
 
+---
+*** New functions to set terminal output buffer size.
+The new functions 'tty--set-output-buffer-size' and
+'tty--output-buffer-size' allow setting and retrieving the output
+buffer size of a terminal device.  The default buffer size is and has
+always been BUFSIZ, which is defined in your system's stdio.h.  When
+you set a buffer size with 'tty--set-output-buffer-size', this also
+prevents Emacs from explicitly flushing the tty output stream, except
+at the end of display update.
+
 ** ERT
 
 +++
index 8932f103f1f95e2c4622bb9d36b76d456c705123..b786f0f1ba420b9aff41f007534c7a0d69435ebd 100644 (file)
@@ -4929,7 +4929,9 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
     {
       if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
        {
-         if (FRAME_TERMCAP_P (f))
+         /* Note that output_buffer_size being 0 means that we want the
+            old default behavior of flushing output every now and then.  */
+         if (FRAME_TERMCAP_P (f) && FRAME_TTY (f)->output_buffer_size == 0)
            {
              /* Flush out every so many lines.
                 Also flush out if likely to have more than 1k buffered
index efd9638b07aeeb6c1c5c40653295c43513de819c..abb385d1388bc2656539136ad31234af4d606630 100644 (file)
@@ -1304,7 +1304,10 @@ init_sys_modes (struct tty_display_info *tty_out)
     }
 #endif /* F_GETOWN */
 
-  setvbuf (tty_out->output, NULL, _IOFBF, BUFSIZ);
+  const size_t buffer_size = (tty_out->output_buffer_size
+                             ? tty_out->output_buffer_size
+                             : BUFSIZ);
+  setvbuf (tty_out->output, NULL, _IOFBF, buffer_size);
 
   if (tty_out->terminal->set_terminal_modes_hook)
     tty_out->terminal->set_terminal_modes_hook (tty_out->terminal);
index 2e43d89232f9bf10118424a74035e32f59465c29..231324d002a13488d43c23517bcf6216b4ad063d 100644 (file)
@@ -2400,6 +2400,42 @@ frame's terminal). */)
   return Qnil;
 }
 
+DEFUN ("tty--set-output-buffer-size", Ftty__set_output_buffer_size,
+       Stty__set_output_buffer_size, 1, 2, 0, doc:
+       /* Set the output buffer size for a TTY.
+
+SIZE zero means use the system's default value.  If SIZE is
+non-zero, this also avoids flushing the output stream.
+
+TTY may be a terminal object, a frame, or nil (meaning the selected
+frame's terminal).
+
+This function temporarily suspends and resumes the terminal
+device.  */)
+  (Lisp_Object size, Lisp_Object tty)
+{
+  if (!TYPE_RANGED_FIXNUMP (size_t, size))
+    error ("Invalid output buffer size");
+  Fsuspend_tty (tty);
+  struct terminal *terminal = decode_tty_terminal (tty);
+  terminal->display_info.tty->output_buffer_size = XFIXNUM (size);
+  return Fresume_tty (tty);
+}
+
+DEFUN ("tty--output-buffer-size", Ftty__output_buffer_size,
+       Stty__output_buffer_size, 0, 1, 0, doc:
+       /* Return the output buffer size of TTY.
+
+TTY may be a terminal object, a frame, or nil (meaning the selected
+frame's terminal).
+
+A value of zero means TTY uses the system's default value.  */)
+  (Lisp_Object tty)
+{
+  struct terminal *terminal = decode_tty_terminal (tty);
+  return make_fixnum (terminal->display_info.tty->output_buffer_size);
+}
+
 \f
 /***********************************************************************
                               Mouse
@@ -4556,6 +4592,8 @@ trigger redisplay.  */);
   defsubr (&Stty_top_frame);
   defsubr (&Ssuspend_tty);
   defsubr (&Sresume_tty);
+  defsubr (&Stty__set_output_buffer_size);
+  defsubr (&Stty__output_buffer_size);
 #ifdef HAVE_GPM
   defsubr (&Sgpm_mouse_start);
   defsubr (&Sgpm_mouse_stop);
index 49560dbc2ad1c2beb46f3167d40a2535f13477c6..0f1724641135eeadc0ff382f5fcec3e9da5fe009 100644 (file)
@@ -53,6 +53,11 @@ struct tty_display_info
   FILE *output;                 /* The stream to be used for terminal output.
                                    NULL if the terminal is suspended. */
 
+  /* Size of output buffer.  A value of zero means use the default of
+     BUFIZE.  If non-zero, also minimize writes to the tty by avoiding
+     calls to flush.  */
+  size_t output_buffer_size;
+
   FILE *termscript;             /* If nonzero, send all terminal output
                                    characters to this stream also.  */