diff options
Diffstat (limited to 'libcr')
-rw-r--r-- | libcr/coroutine.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/libcr/coroutine.c b/libcr/coroutine.c index 129f4da..73460b7 100644 --- a/libcr/coroutine.c +++ b/libcr/coroutine.c @@ -1,6 +1,6 @@ /* libcr/coroutine.c - Simple embeddable coroutine implementation * - * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ @@ -158,9 +158,19 @@ static_assert(CONFIG_COROUTINE_NUM > 1); #define _CR_SIG_GDB SIGWINCH #endif +#if CONFIG_COROUTINE_VALGRIND + /* Hack around a bug in Valgrind where it runs the + * sigsuspend(tmp_sigmask)-triggered handler function with the + * original mask, not the `tmp_mask`. */ + static bool _cr_plat_in_sigsuspend = false; +#endif + bool cr_plat_is_in_intrhandler(void) { +#if CONFIG_COROUTINE_VALGRIND + if (_cr_plat_in_sigsuspend) + return true; +#endif sigset_t cur_mask; - sigfillset(&cur_mask); sigprocmask(0, NULL, &cur_mask); if (sigismember(&cur_mask, _CR_SIG_SENTINEL)) /* Interrupts are disabled, so we cannot be in @@ -184,10 +194,13 @@ static_assert(CONFIG_COROUTINE_NUM > 1); assert(!_cr_plat_are_interrupts_enabled()); sigset_t set; sigemptyset(&set); +#if CONFIG_COROUTINE_VALGRIND + _cr_plat_in_sigsuspend = true; +#endif sigsuspend(&set); - - sigfillset(&set); - sigprocmask(SIG_SETMASK, &set, NULL); +#if CONFIG_COROUTINE_VALGRIND + _cr_plat_in_sigsuspend = false; +#endif } bool _cr_plat_save_and_disable_interrupts(void) { assert(!cr_plat_is_in_intrhandler()); |