summaryrefslogtreecommitdiff
path: root/libcr/include
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-01 11:51:06 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-01 20:56:52 -0600
commitec80ab676556a45150380338b64c0d0cf26f2141 (patch)
tree8dccd4a178fe4a1fa668293ca8d3476806657d25 /libcr/include
parent5cbc2d4a3e3b279667e26774ad1cd37682bdbf28 (diff)
libcr: expose cr_{disable,enable}_interrupts
Diffstat (limited to 'libcr/include')
-rw-r--r--libcr/include/libcr/coroutine.h46
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;