Skip to content

Commit 87af1a4

Browse files
maribucrasbe
andcommitted
cpu/native: fix lockup on libucontext
The `setcontext()` implementation of glibc does restore the signal mask to the target thread during the switch, libucontext [does not][1] [1]: https://man.archlinux.org/man/libucontext.3.en#CAVEATS Instead, we just manually enable signals again just before the call to `setcontext()`. With this, tests like `tests/core/mutex_canel` or `tests/core/irq` now pass on `native64` when using libucontext. Co-authored-by: crasbe <crasbe@gmail.com>
1 parent b8c553c commit 87af1a4

3 files changed

Lines changed: 18 additions & 1 deletion

File tree

cpu/native/cpu.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,17 @@ void _isr_switch_to_user(void) {
7878
/* Now we want to go to _native_isr_leave before resuming execution at _native_user_fptr. */
7979
_context_set_fptr(context, (uintptr_t)_native_isr_leave);
8080

81+
/* libucontext does not restore signal mask on setcontext() [1], so we
82+
* need to enable signals again to not get locked up
83+
*
84+
* [1]: https://man.archlinux.org/man/libucontext.3.en#CAVEATS
85+
*/
86+
if (IS_ACTIVE(USE_LIBUCONTEXT)) {
87+
if (sigprocmask(SIG_SETMASK, &_native_sig_set, NULL) == -1) {
88+
err(EXIT_FAILURE, "irq_enable: sigprocmask");
89+
}
90+
}
91+
8192
if (setcontext(context) == -1) {
8293
err(EXIT_FAILURE, "_isr_schedule_and_switch: setcontext");
8394
}

cpu/native/include/native_internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ void native_cpu_init(void);
8686
*/
8787
extern volatile bool _native_interrupts_enabled;
8888

89+
/**
90+
* @brief Signal set during "IRQs enabled"
91+
* @internal
92+
*/
93+
extern sigset_t _native_sig_set;
94+
8995
/**
9096
* @brief Pipe yielding signals
9197
* @private

cpu/native/irq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ ucontext_t *_native_current_context = NULL;
4040

4141
volatile uintptr_t _native_user_fptr;
4242

43-
static sigset_t _native_sig_set;
43+
sigset_t _native_sig_set;
4444
static sigset_t _native_sig_set_dint;
4545
volatile int _native_pending_signals;
4646
int _signal_pipe_fd[2];

0 commit comments

Comments
 (0)