core/sched_switch: fix crash with no active thread
Contribution description
The function sched_switch() was implemented with the assumption that there will always be an active thread. This was true until threadless idle was implemented for Cortex M MCUs: If no thread is runnable and the running thread exists, there will be no active thread. If from ISR a thread is then unblocked, sched_switch() will be called without an active thread.
This handles the corner case explicitly when the module core_idle_thread is not used (in other words: for threadless idle).
Implementation choice
I first wanted to avoid adding the check for this very unlikely corner case to this hot path, and rather have in cpu_switch_context_exit() of the only offender to make sure to set the active thread to something reasonable. However, switching to a non-runnable thread without running it is something that I have no elegant, simple and maintainable solution for. So I decided to rather add a simple and maintainable check into a hot path.
Testing procedure
See https://github.com/RIOT-OS/RIOT/issues/20812
Issues/PRs references
Fixes https://github.com/RIOT-OS/RIOT/issues/20812
Murdock results
:heavy_check_mark: PASSED
03081de47048884988f8a3b8446f98e0e69f3d8b fixup! core/sched_switch: fix crash with no active thread
| Success | Failures | Total | Runtime |
|---|---|---|---|
| 10197 | 0 | 10197 | 16m:05s |
Artifacts
I suppose we can close this now?
If I recall correctly, the same issue could be triggered when calling sched_switch() by setting thread flags from IRQ context.
So, not yet. Maybe calling thread_yield_higher() directly is also the better approach there, but I haven't really looked.