unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#57727: 29.0.50; Optimize tty display updates
@ 2022-09-11 10:03 Gerd Möllmann
  2022-09-11 11:18 ` Lars Ingebrigtsen
                   ` (3 more replies)
  0 siblings, 4 replies; 19+ messages in thread
From: Gerd Möllmann @ 2022-09-11 10:03 UTC (permalink / raw)
  To: 57727

[-- Attachment #1: Type: text/plain, Size: 819 bytes --]

This is a wishlist item for the implementation of what was discussed
recently on emacs-devel, namely using a larger output buffer, and
avoiding fflush as a means of improving tty display update speed.

The patch below is my first take on that.  It adds a low-level interface
consisting of two functions tty--set-output-buffer-size and
tty-output-buffer-size to change and retrieve the output buffer size of
a device.  A buffer size of 0 is taken to mean "do what we did since
1991, and a non-zero value is used as the buffer size set with setvbuf.

Default is currently to do everything as it always was.  One has to do
something like

  (tty--set-output-buffer-size (* 64 1024))

to change to the new behavior.

Feedback welcome, especially for the default, i.e. leaving everything
as-is, and for the Lisp interface.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch for master --]
[-- Type: text/x-patch, Size: 4577 bytes --]

From 597d17f6ecc866328e3c5c3438b1d7fec3b2bbea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Gerd=20M=C3=B6llmann?= <gerd@gnu.org>
Date: Sun, 11 Sep 2022 11:42:18 +0200
Subject: [PATCH] Optimize tty display updates

* 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.
---
 src/dispnew.c  |  4 +++-
 src/sysdep.c   |  5 ++++-
 src/term.c     | 39 +++++++++++++++++++++++++++++++++++++++
 src/termchar.h |  5 +++++
 4 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/src/dispnew.c b/src/dispnew.c
index 8932f103f1..b786f0f1ba 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -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
diff --git a/src/sysdep.c b/src/sysdep.c
index efd9638b07..abb385d138 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -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);
diff --git a/src/term.c b/src/term.c
index 2e43d89232..8e19c96672 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2400,6 +2400,43 @@ DEFUN ("resume-tty", Fresume_tty, Sresume_tty, 0, 1, 0,
   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) <= 0 ? 0 : 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 +4593,8 @@ syms_of_term (void)
   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);
diff --git a/src/termchar.h b/src/termchar.h
index 49560dbc2a..0f17246411 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -53,6 +53,11 @@ #define EMACS_TERMCHAR_H
   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.  */
 
-- 
2.37.3


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

end of thread, other threads:[~2022-09-18  5:34 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-11 10:03 bug#57727: 29.0.50; Optimize tty display updates Gerd Möllmann
2022-09-11 11:18 ` Lars Ingebrigtsen
2022-09-12  6:02   ` Gerd Möllmann
2022-09-12 11:21     ` Eli Zaretskii
2022-09-11 13:49 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-09-12  6:33   ` Gerd Möllmann
2022-09-12 11:29     ` Eli Zaretskii
2022-09-12 11:52       ` Gerd Möllmann
2022-09-12 13:15         ` Gerd Möllmann
2022-09-12 14:18     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-09-13  5:53       ` Gerd Möllmann
2022-09-13 11:33         ` Eli Zaretskii
2022-09-13 11:36           ` Lars Ingebrigtsen
2022-09-13 12:44             ` Gerd Möllmann
2022-09-13 13:48         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-09-13 13:53           ` Gerd Möllmann
2022-09-17 13:34 ` Gerd Möllmann
2022-09-17 21:09 ` Basil L. Contovounesios via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-09-18  5:34   ` Gerd Möllmann

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).