From: Gerd Möllmann Date: Sun, 11 Sep 2022 09:42:18 +0000 (+0200) Subject: Optimize tty display updates (bug#57727) X-Git-Tag: emacs-29.0.90~1856^2~422 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=cbac94b4aeecdf57e2a1f3e95e27ec76505ae964;p=emacs.git Optimize tty display updates (bug#57727) * 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. --- diff --git a/etc/NEWS b/etc/NEWS index a6a8883593b..cd14bcf69b5 100644 --- 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 +++ diff --git a/src/dispnew.c b/src/dispnew.c index 8932f103f1f..b786f0f1ba4 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 efd9638b07a..abb385d1388 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 2e43d89232f..231324d002a 100644 --- a/src/term.c +++ b/src/term.c @@ -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); +} + /*********************************************************************** 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); diff --git a/src/termchar.h b/src/termchar.h index 49560dbc2ad..0f172464113 100644 --- a/src/termchar.h +++ b/src/termchar.h @@ -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. */