From c9b1b3b0658c24a02ae9c7efbda332cc6f473a64 Mon Sep 17 00:00:00 2001 From: "B. Scott Michel" Date: Tue, 18 Mar 2025 17:18:56 -0700 Subject: [PATCH] SCP: Remove Win32 console output overhead Don't repeatedly call GetConsoleMode() on Win32 each time sim_console_write() is called. Use an output function pointer to invoke WriteConsoleA (console output) or WriteFile (output is not a console). The console output destination doesn't change during the lifetime of the simulator, so avoid extraneous overhead for each character output (sometimes strings, but mostly characters.) --- sim_console.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/sim_console.c b/sim_console.c index 1c0e82d4b..f9fdca336 100644 --- a/sim_console.c +++ b/sim_console.c @@ -3483,9 +3483,12 @@ return SCPE_OK; #include #include #define RAW_MODE 0 +typedef BOOL (WINAPI *std_output_writer_fn)(HANDLE, const void *, DWORD, LPDWORD, LPVOID); + static HANDLE std_input; static HANDLE std_output; static HANDLE std_error; +static std_output_writer_fn std_output_writer = NULL; static DWORD saved_input_mode; static DWORD saved_output_mode; static DWORD saved_error_mode; @@ -3537,12 +3540,19 @@ SetConsoleCtrlHandler( ControlHandler, TRUE ); std_input = GetStdHandle (STD_INPUT_HANDLE); std_output = GetStdHandle (STD_OUTPUT_HANDLE); std_error = GetStdHandle (STD_ERROR_HANDLE); + if ((std_input) && /* Not Background process? */ (std_input != INVALID_HANDLE_VALUE)) GetConsoleMode (std_input, &saved_input_mode); /* Save Input Mode */ if ((std_output) && /* Not Background process? */ - (std_output != INVALID_HANDLE_VALUE)) - GetConsoleMode (std_output, &saved_output_mode); /* Save Output Mode */ + (std_output != INVALID_HANDLE_VALUE)) { /* Save Output Mode */ + std_output_writer = GetConsoleMode(std_output, &saved_output_mode) + ? WriteConsoleA + : (std_output_writer_fn) WriteFile; +} else { + /* Default to something resonable... */ + std_output_writer = (std_output_writer_fn) WriteFile; +} if ((std_error) && /* Not Background process? */ (std_error != INVALID_HANDLE_VALUE)) GetConsoleMode (std_error, &saved_error_mode); /* Save Output Mode */ @@ -3690,16 +3700,15 @@ return (WAIT_OBJECT_0 == WaitForSingleObject (std_input, ms_timeout)); static uint8 out_buf[ESC_HOLD_MAX]; /* Buffered characters pending output */ static int32 out_ptr = 0; -static void sim_console_write(uint8 *outbuf, int32 outsz) +static inline void sim_console_write(uint8 *outbuf, int32 outsz) { DWORD unused; - DWORD mode; + BOOL result; - if (GetConsoleMode(std_output, &mode)) { - WriteConsoleA(std_output, outbuf, outsz, &unused, NULL); - } else { - BOOL result = WriteFile(std_output, outbuf, outsz, &unused, NULL); - } + /* Useful to see the return value from std_output_writer. */ + result = std_output_writer(std_output, outbuf, outsz, &unused, NULL); + /* But squelch the set-but-not-used warnings. */ + (void) result; } static t_stat sim_out_hold_svc (UNIT *uptr)