This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH] Speed up "gdb -tui" output
- From: Pedro Alves <palves at redhat dot com>
- To: Eli Zaretskii <eliz at gnu dot org>, Doug Evans <dje at google dot com>
- Cc: gdb-patches at sourceware dot org
- Date: Wed, 07 Jan 2015 22:29:51 +0000
- Subject: Re: [PATCH] Speed up "gdb -tui" output
- Authentication-results: sourceware.org; auth=none
- References: <83zj9v7urq dot fsf at gnu dot org> <CADPb22Q7oD3K-dYkngEPDBbV++mLCKifTEmvJczQ=0h2FX0yXA at mail dot gmail dot com> <54AD4E22 dot 1010106 at redhat dot com> <83mw5u79t7 dot fsf at gnu dot org> <CADPb22QqTE+yq9RSRmvBiu0tdy++8S40D8xzKi6k8nLYmiN48g at mail dot gmail dot com> <83fvbm784e dot fsf at gnu dot org> <CADPb22T=uuHjDrsxrOyjh2XS0=wf_HxkxNGYHC_hAsvr7saJjw at mail dot gmail dot com> <83a91u75fe dot fsf at gnu dot org>
On 01/07/2015 07:32 PM, Eli Zaretskii wrote:
> So? How does this help? The stderr problem is simple, but what do
> you do with stdout and stdlog? Especially when tui_file_fputs is
> called one character at a time in most cases.
I'm confused on that the confusion is. :-)
I think something like this should work. I'm not really seeing a point
for those fflush(stdout)'s, btw. Note that tui_stream->ts_filestream is
only ever used in tui_file_isatty; it's never written to.
>From 2b4d8cfb56d67f9eded113a120dc5c18ea3781cc Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Wed, 7 Jan 2015 19:50:48 +0000
Subject: [PATCH] TUI emulate line buffering
when printing to stdout, only refresh the console window when either a
new line is seen or when an explicit flush is requested.
---
gdb/tui/tui-file.c | 5 +++--
gdb/tui/tui-io.c | 53 +++++++++++++++++++++++++++++++++++++++++++++--------
gdb/tui/tui-io.h | 10 ++++++++--
3 files changed, 56 insertions(+), 12 deletions(-)
diff --git a/gdb/tui/tui-file.c b/gdb/tui/tui-file.c
index b32cfa6..932df46 100644
--- a/gdb/tui/tui-file.c
+++ b/gdb/tui/tui-file.c
@@ -178,7 +178,7 @@ tui_file_fputs (const char *linebuffer, struct ui_file *file)
}
else
{
- tui_puts (linebuffer);
+ tui_puts_file (file, linebuffer);
}
}
@@ -239,7 +239,8 @@ tui_file_flush (struct ui_file *file)
case astring:
break;
case afile:
- fflush (stream->ts_filestream);
+ if (file == tui_stdout)
+ tui_flush_stdout ();
break;
}
}
diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
index 233e7a6..e7c5583 100644
--- a/gdb/tui/tui-io.c
+++ b/gdb/tui/tui-io.c
@@ -118,7 +118,7 @@ key_is_command_char (int ch)
/* #undef TUI_USE_PIPE_FOR_READLINE */
/* TUI output files. */
-static struct ui_file *tui_stdout;
+struct ui_file *tui_stdout;
static struct ui_file *tui_stderr;
struct ui_out *tui_out;
@@ -148,6 +148,17 @@ static char *tui_rl_saved_prompt;
static unsigned int tui_handle_resize_during_io (unsigned int);
+static void tui_puts (const char *string);
+
+void
+tui_flush_stdout (void)
+{
+ WINDOW *w;
+
+ w = TUI_CMD_WIN->generic.handle;
+ wrefresh (w);
+}
+
static void
tui_putc (char c)
{
@@ -158,9 +169,13 @@ tui_putc (char c)
tui_puts (buf);
}
-/* Print the string in the curses command window. */
-void
-tui_puts (const char *string)
+/* Print the string in the curses command window. If LINEBUFFERED,
+ we're printing to stdout, and so like stdio, should only flush when
+ we see a new line. If LINEBUFFERED is false, we'll flush after
+ printing the whole string. */
+
+static void
+tui_puts_maybe_buffered (const char *string, int linebuffered)
{
static int tui_skip_line = -1;
char c;
@@ -182,15 +197,36 @@ tui_puts (const char *string)
}
else if (c == '\n')
tui_skip_line = -1;
+
+ if (linebuffered && c == '\n')
+ wrefresh (w);
}
getyx (w, TUI_CMD_WIN->detail.command_info.cur_line,
TUI_CMD_WIN->detail.command_info.curch);
TUI_CMD_WIN->detail.command_info.start_line
= TUI_CMD_WIN->detail.command_info.cur_line;
- /* We could defer the following. */
- wrefresh (w);
- fflush (stdout);
+ if (!linebuffered)
+ wrefresh (w);
+}
+
+/* Print the string in the curses command window, as if printing to
+ stdout. */
+
+static void
+tui_puts (const char *string)
+{
+ tui_puts_maybe_buffered (string, 1);
+}
+
+/* Print the string in the curses command window. FILE indicates
+ which file the caller is printing to. If gdb_stdout, then emulate
+ line buffering. */
+
+void
+tui_puts_file (struct ui_file *file, const char *string)
+{
+ tui_puts_maybe_buffered (string, file == tui_stdout);
}
/* Readline callback.
@@ -279,7 +315,6 @@ tui_redisplay_readline (void)
TUI_CMD_WIN->detail.command_info.start_line -= height - 1;
wrefresh (w);
- fflush(stdout);
}
/* Readline callback to prepare the terminal. It is called once each
@@ -412,6 +447,7 @@ tui_rl_display_match_list (char **matches, int len, int max)
/* Screen dimension correspond to the TUI command window. */
int screenwidth = TUI_CMD_WIN->generic.width;
+ WINDOW *w = TUI_CMD_WIN->generic.handle;
/* If there are many items, then ask the user if she really wants to
see them all. */
@@ -422,6 +458,7 @@ tui_rl_display_match_list (char **matches, int len, int max)
xsnprintf (msg, sizeof (msg),
"\nDisplay all %d possibilities? (y or n)", len);
tui_puts (msg);
+ tui_flush_stdout ();
if (get_y_or_n () == 0)
{
tui_puts ("\n");
diff --git a/gdb/tui/tui-io.h b/gdb/tui/tui-io.h
index 8f96cfe..81d4337 100644
--- a/gdb/tui/tui-io.h
+++ b/gdb/tui/tui-io.h
@@ -24,8 +24,13 @@
struct ui_out;
-/* Print the string in the curses command window. */
-extern void tui_puts (const char *);
+/* Print the string in the curses command window. FILE indicates
+ which file the caller is printing to. If gdb_stdout, then emulate
+ line buffering. */
+extern void tui_puts_file (struct ui_file *file, const char *string);
+
+/* Flush console output. */
+extern void tui_flush_stdout (void);
/* Setup the IO for curses or non-curses mode. */
extern void tui_setup_io (int mode);
@@ -41,6 +46,7 @@ extern int tui_getc (FILE *);
changed the edited text. */
extern void tui_redisplay_readline (void);
+extern struct ui_file *tui_stdout;
extern struct ui_out *tui_out;
extern struct ui_out *tui_old_uiout;
--
1.9.3