You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While trying to fully understand what kernel services can be used in what context, in support of #18970 and possibly #21111, I noticed what appears to be an anomaly.
My current assessment from code and documentation is that an operation cannot be invoked from an ISR if (reference thread states):
It transitions the current thread to Waiting (per documentation and implementation of e.g. k_sem_take())
It transitions the current thread to Ready (per assert in k_yield())
It transitions the current thread to Suspended (per assert inz_tick_sleep())
The latter is one that doesn't fit.
k_sleep(t) for a non-zero t will invoke z_ticks_sleep() which asserts if it's called from interrupt context.
k_sleep(K_FOREVER) will instead invoke k_thread_suspend(_current) which is (not dis-) allowed from interrupt context.
Questions:
(A) Is this behavior as intended? (my vote is k_sleep(K_FOREVER) in interrupt context should be disallowed.)
(B) What is the precise set of conditions under which an operation cannot be invoked from an ISR?
(C) Is that set of conditions different from the set under which an operation cannot be invoked from a pre-kernel init function?
The text was updated successfully, but these errors were encountered:
@pabigot this just seems like an omission, k_sleep() and all its variants should assert if called from interrupt context, it makes no sense to call this API from an ISR.
What is the precise set of conditions under which an operation cannot be invoked from an ISR?
Actions are forbidden in an ISR if they would put the caller to sleep, since we are not in context of any particular thread. Other OSes have the same policy Zephyr is not special here.
Is that set of conditions different from the set under which an operation cannot be invoked from a pre-kernel init function?
Pre-kernel functions have the same restriction about sleeping (no thread context) plus certain data structures may not have been initialized like drivers and kernel objects. I do believe this is documented.
@andrewboie Thanks, that's clear and I can make it work in the API terminology. I was getting wrapped around an axle because it seemed that k_sem_give(), which can be invoked from an ISR (I believe) could, when invoked by a preemptible thread, cause its caller to sleep, but that's because it's a reschedule point rather than because the function itself might sleep.
While trying to fully understand what kernel services can be used in what context, in support of #18970 and possibly #21111, I noticed what appears to be an anomaly.
My current assessment from code and documentation is that an operation cannot be invoked from an ISR if (reference thread states):
k_sem_take()
)k_yield()
)z_tick_sleep()
)The latter is one that doesn't fit.
k_sleep(t)
for a non-zerot
will invokez_ticks_sleep()
which asserts if it's called from interrupt context.k_sleep(K_FOREVER)
will instead invokek_thread_suspend(_current)
which is (not dis-) allowed from interrupt context.Questions:
(A) Is this behavior as intended? (my vote is
k_sleep(K_FOREVER)
in interrupt context should be disallowed.)(B) What is the precise set of conditions under which an operation cannot be invoked from an ISR?
(C) Is that set of conditions different from the set under which an operation cannot be invoked from a pre-kernel init function?
The text was updated successfully, but these errors were encountered: