diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-01 11:51:06 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-01 20:56:52 -0600 |
commit | ec80ab676556a45150380338b64c0d0cf26f2141 (patch) | |
tree | 8dccd4a178fe4a1fa668293ca8d3476806657d25 /libcr/include | |
parent | 5cbc2d4a3e3b279667e26774ad1cd37682bdbf28 (diff) |
libcr: expose cr_{disable,enable}_interrupts
Diffstat (limited to 'libcr/include')
-rw-r--r-- | libcr/include/libcr/coroutine.h | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/libcr/include/libcr/coroutine.h b/libcr/include/libcr/coroutine.h index 0c5eac3..458e74e 100644 --- a/libcr/include/libcr/coroutine.h +++ b/libcr/include/libcr/coroutine.h @@ -113,8 +113,6 @@ void cr_yield(void); void cr_pause_and_yield(void); /** cr_unpause() marks a coroutine as runnable that has previously marked itself as non-runnable with cr_pause_and_yield(). */ void cr_unpause(cid_t); -/** cr_unpause_from_intrhandler() is like cr_unpause(), but safe to call from a interrupt handler that might race with the coroutine actually pausing itself. */ -void cr_unpause_from_intrhandler(cid_t); /** cr_end() is a counterpart to cr_begin(), but is really just cr_exit(). */ #define cr_end cr_exit @@ -126,9 +124,49 @@ cid_t cr_getcid(void); * another as paused; a coroutine may only do those things to itself. */ -/* While the following are defined here unconditionally, the - * implementations are #if'd on CONFIG_COROUTINE_MEASURE_STACK. +/* dealing with interrupts ****************************************************/ + +/** + * "Disable" interrupts. Interrupts that come in while disabled will + * be placed in a "pending" queue. + * + * This is fast on bare-metal, but slow on an OS (because on an OS it + * uses a syscall). + */ +#define cr_disable_interrupts() do { \ + _cr_plat_disable_interrupts(); \ + asm volatile ("":::"memory"); \ + } while (0) +void _cr_plat_disable_interrupts(void); + +/** + * Enable interrupts. Any "pending" interrupts that came in while + * interrupts were disabled will have their handlers called. + * + * This is fast on bare-metal, but slow on an OS (because on an OS it + * uses a syscall). */ +#define cr_enable_interrupts() do { \ + asm volatile ("":::"memory"); \ + _cr_plat_enable_interrupts(); \ + } while (0) +void _cr_plat_enable_interrupts(void); + +/** + * cr_unpause_from_intrhandler() is like cr_unpause(), but safe to + * call from a interrupt handler that might race with the coroutine + * actually pausing itself. + * + * It is also safe to call from a regular coroutine, but compared to + * regular cr_unpause() it is less capable of detecting programming + * errors. So don't do that? + */ +void cr_unpause_from_intrhandler(cid_t); + +/* answering questions about coroutines ***************************************/ + +/* While the following are defined here unconditionally, the + * implementations are #if'd on CONFIG_COROUTINE_MEASURE_STACK. */ struct cr_cid_info { size_t stack_cap; |