Skip to content

Commit 309332a

Browse files
mattnchrisbra
authored andcommitted
patch 9.2.0274: BSU/ESU are output directly to the terminal
Problem: BSU/ESU are output directly to the terminal Solution: Route them through out_buf() and flush the output directly, increase the OUT_SIZE terminal buffer (Yasuhiro Matsumoto) Route synchronized-output control sequences through out_buf and flush explicitly at protocol boundaries, instead of forcing BSU/ESU through ui_write() directly. Also increase the terminal output buffer from 2047 to 8191 bytes so large redraws are emitted in fewer writes. The important guarantee here is terminal-visible ordering: BSU must reach the terminal before the batched redraw bytes, ESU must reach the terminal after them, and FLUSH must emit ESU and BSU together, then flush immediately. Benchmark: PTY redraw workload with TERM=xterm-256color, long wrapped lines, cursorline, listchars, horizontal scrolling, and repeated redraw!. write syscalls: 8514 -> 5094 (-40.2%) wall time: 0.568s -> 0.495s (-12.9%) on valid runs in this environment closes: #19862 Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent ac18dff commit 309332a

2 files changed

Lines changed: 19 additions & 11 deletions

File tree

src/term.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2807,7 +2807,7 @@ termcapinit(char_u *name)
28072807
/*
28082808
* The number of calls to ui_write is reduced by using "out_buf".
28092809
*/
2810-
#define OUT_SIZE 2047
2810+
#define OUT_SIZE 8191
28112811

28122812
// add one to allow mch_write() in os_win32.c to append a NUL
28132813
static char_u out_buf[OUT_SIZE + 1];
@@ -8059,12 +8059,19 @@ term_set_win_resize(bool state)
80598059
* Enable or disable synchronized output if possible. Specification can be found
80608060
* here:
80618061
* https://github.com/contour-terminal/vt-extensions/blob/master/synchronized-output.md
8062+
*
8063+
* BSU/ESU do not need to bypass out_buf and go straight to ui_write().
8064+
* What matters is the order in which they reach the terminal:
8065+
* - BSU must be emitted before the batched redraw bytes.
8066+
* - ESU must be emitted after those redraw bytes.
8067+
* - A FLUSH must emit ESU and BSU together, then flush immediately.
8068+
* As long as out_flush() is done at those boundaries, putting BSU/ESU in
8069+
* out_buf reduces small writes without changing the observable protocol.
80628070
*/
80638071
void
80648072
term_set_sync_output(int flags)
80658073
{
80668074
bool allowed;
8067-
char_u *str;
80688075
#ifdef FEAT_GUI
80698076
bool in_gui = gui.in_use;
80708077
#else
@@ -8075,12 +8082,13 @@ term_set_sync_output(int flags)
80758082

80768083
if (flags & TERM_SYNC_OUTPUT_FLUSH)
80778084
{
8078-
// Tell terminal to display screen contents
8085+
// Tell terminal to display screen contents, then resume batching.
80798086
if (allowed && !in_gui && sync_output_state > 0 && *T_ESU != NUL &&
80808087
*T_BSU != NUL)
80818088
{
8082-
ui_write((char_u *)T_ESU, (int)STRLEN(T_ESU), true);
8083-
ui_write((char_u *)T_BSU, (int)STRLEN(T_BSU), true);
8089+
out_str_nf(T_ESU);
8090+
out_str_nf(T_BSU);
8091+
out_flush();
80848092
}
80858093
return;
80868094
}
@@ -8090,7 +8098,8 @@ term_set_sync_output(int flags)
80908098
{
80918099
if (sync_output_state > 0 && *T_ESU != NUL)
80928100
{
8093-
ui_write((char_u *)T_ESU, (int)STRLEN(T_ESU), true);
8101+
out_str_nf(T_ESU);
8102+
out_flush();
80948103
sync_output_state = 0;
80958104
}
80968105
return;
@@ -8105,7 +8114,7 @@ term_set_sync_output(int flags)
81058114
{
81068115
if (sync_output_state++ > 0)
81078116
return;
8108-
str = T_BSU;
8117+
out_str_nf(T_BSU);
81098118
}
81108119
else if (flags & TERM_SYNC_OUTPUT_DISABLE)
81118120
{
@@ -8115,15 +8124,12 @@ term_set_sync_output(int flags)
81158124
// all drawing output is sent to the terminal within the
81168125
// BSU..ESU window. Without this, the drawing data remaining in
81178126
// out_buf would be sent after ESU, outside the sync batch.
8127+
out_str_nf(T_ESU);
81188128
out_flush();
8119-
str = T_ESU;
81208129
}
81218130
else
81228131
{
81238132
siemsg("Unknown sync output value %d", flags);
81248133
return;
81258134
}
8126-
8127-
// Directly write to terminal instead of using output buffer
8128-
ui_write((char_u *)str, (int)STRLEN(str), true);
81298135
}

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,8 @@ static char *(features[]) =
734734

735735
static int included_patches[] =
736736
{ /* Add new patch number below this line */
737+
/**/
738+
274,
737739
/**/
738740
273,
739741
/**/

0 commit comments

Comments
 (0)