From 959f77402fec9788bb2249933674cb5fd30517e3 Mon Sep 17 00:00:00 2001 From: Frank Halasz Date: Tue, 27 May 2025 20:23:06 -0700 Subject: [PATCH] Fix Issue#2164 - mouse does not work on WSL1. Root cause is that, like cygwin, WSL1 does not support setitimer(ITIMER_VIRTRUAL ...). Trouble is cannot detect WSL1 using any preprocessor macros and anyway don't want to create yet another platform to run through the whole github actions release process. So in the case of MAIKO_OS_LINUX, we now detect setitimer failure and use emulated timer when such failure occurs. So unlike CYGWIN and Emscripten, the decsion to use emulated timers for WSL1 is made at runtime not compile time. This will add a very small overhead to all non-WSL1 Linux runs but should not effect any other platforms. --- src/main.c | 4 ++-- src/timer.c | 12 +++++++++++- src/xc.c | 19 +++++++++++++------ 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/main.c b/src/main.c index 590424a..788c1ae 100644 --- a/src/main.c +++ b/src/main.c @@ -315,7 +315,7 @@ const char *nethubHelpstring = const char *nethubHelpstring = ""; #endif -#if defined(MAIKO_EMULATE_TIMER_INTERRUPTS) || defined(MAIKO_EMULATE_ASYNC_INTERRUPTS) +#if MAIKO_OS_LINUX || defined(MAIKO_EMULATE_TIMER_INTERRUPTS) || defined(MAIKO_EMULATE_ASYNC_INTERRUPTS) extern int insnsCountdownForTimerAsyncEmulation; #endif @@ -601,7 +601,7 @@ int main(int argc, char *argv[]) } #endif /* MAIKO_ENABLE_NETHUB */ -#if defined(MAIKO_EMULATE_TIMER_INTERRUPTS) || defined(MAIKO_EMULATE_ASYNC_INTERRUPTS) +#if MAIKO_OS_LINUX || defined(MAIKO_EMULATE_TIMER_INTERRUPTS) || defined(MAIKO_EMULATE_ASYNC_INTERRUPTS) else if (!strcmp(argv[i], "-intr-emu-insns")) { if (argc > ++i) { errno = 0; diff --git a/src/timer.c b/src/timer.c index fed42f7..c1ece00 100644 --- a/src/timer.c +++ b/src/timer.c @@ -454,6 +454,11 @@ static void int_timer_service(int sig) /* */ /************************************************************************/ +#if MAIKO_OS_LINUX + // for WSL1, which doesn't support setitimer(ITIMER_VIRTUAL ...) + int linux_emulate_timer = 0; +#endif /* MAIKO_OS_LINUX */ + static void int_timer_init(void) { @@ -489,6 +494,11 @@ static void int_timer_init(void) /* then attach a timer to it and turn it loose */ timert.it_interval.tv_sec = timert.it_value.tv_sec = 0; timert.it_interval.tv_usec = timert.it_value.tv_usec = TIMER_INTERVAL; + +#if MAIKO_OS_LINUX + // (For WSL1) Capture error output from setittimer to indicate need to emulate timer + linux_emulate_timer = +#endif /* MAIKO_OS_LINUX */ setitimer(ITIMER_VIRTUAL, &timert, NULL); DBPRINT(("Timer interval set to %ld usec\n", (long)timert.it_value.tv_usec)); @@ -499,7 +509,7 @@ static void int_timer_init(void) /* */ /* */ /* */ -/* */ +/* /* */ /* */ /* */ diff --git a/src/xc.c b/src/xc.c index bfb1b92..4ac20d8 100644 --- a/src/xc.c +++ b/src/xc.c @@ -173,7 +173,7 @@ static const int n_mask_array[16] = { extern int TIMER_INTERVAL; -#if defined(MAIKO_EMULATE_TIMER_INTERRUPTS) || defined(MAIKO_EMULATE_ASYNC_INTERRUPTS) +#if MAIKO_OS_LINUX || defined(MAIKO_EMULATE_TIMER_INTERRUPTS) || defined(MAIKO_EMULATE_ASYNC_INTERRUPTS) # if !defined(MAIKO_TIMER_ASYNC_EMULATION_INSNS_COUNTDOWN) # define MAIKO_TIMER_ASYNC_EMULATION_INSNS_COUNTDOWN 20000 @@ -181,7 +181,9 @@ extern int TIMER_INTERVAL; int insnsCountdownForTimerAsyncEmulation = MAIKO_TIMER_ASYNC_EMULATION_INSNS_COUNTDOWN; static int pseudoTimerAsyncCountdown = MAIKO_TIMER_ASYNC_EMULATION_INSNS_COUNTDOWN; - +#if MAIKO_OS_LINUX +extern int linux_emulate_timer; +#endif /* MAIKO_OS_LINUX */ #endif void dispatch(void) { @@ -282,10 +284,12 @@ nextopcode: #endif /* PCTRACE */ /* quick_stack_check();*/ /* JDS 2/12/98 */ - -#if defined(MAIKO_EMULATE_TIMER_INTERRUPTS) || defined(MAIKO_EMULATE_ASYNC_INTERRUPTS) - if (--pseudoTimerAsyncCountdown <= 0) { - Irq_Stk_Check = 0; +#if MAIKO_OS_LINUX || defined(MAIKO_EMULATE_TIMER_INTERRUPTS) || defined(MAIKO_EMULATE_ASYNC_INTERRUPTS) +#if MAIKO_OS_LINUX + if (linux_emulate_timer) { +#endif /* MAIKO_OS_LINUX */ + if (--pseudoTimerAsyncCountdown <= 0) { + Irq_Stk_Check = 0; Irq_Stk_End = 0; #if defined(MAIKO_EMULATE_ASYNC_INTERRUPTS) IO_Signalled = TRUE; @@ -294,6 +298,9 @@ nextopcode: emscripten_sleep(1); #endif pseudoTimerAsyncCountdown = insnsCountdownForTimerAsyncEmulation; +#if MAIKO_OS_LINUX + } +#endif /* MAIKO_OS_LINUX */ } #endif