summaryrefslogtreecommitdiff
path: root/libcr/include
diff options
context:
space:
mode:
Diffstat (limited to 'libcr/include')
-rw-r--r--libcr/include/libcr/coroutine.h35
1 files changed, 15 insertions, 20 deletions
diff --git a/libcr/include/libcr/coroutine.h b/libcr/include/libcr/coroutine.h
index 95f9ba0..8aeab7e 100644
--- a/libcr/include/libcr/coroutine.h
+++ b/libcr/include/libcr/coroutine.h
@@ -94,12 +94,8 @@ cid_t coroutine_add(const char *name, cr_fn_t fn, void *args);
/**
* The main scheduler loop.
- *
- * "Should" never return, but will print a message and return if there
- * are no coroutines (there were no calls to coroutine_add(), or all
- * coroutines cr_exit()).
*/
-void coroutine_main(void);
+__attribute__ ((noreturn)) void coroutine_main(void);
/* inside of coroutines *******************************************************/
@@ -132,34 +128,33 @@ cid_t cr_getcid(void);
*
* This is fast on bare-metal, but slow on an OS (because on an OS it
* uses a syscall).
+ *
+ * Returns whether interrupts were enabled before the call.
*/
-#define cr_disable_interrupts() do { \
- _cr_plat_disable_interrupts(); \
- asm volatile ("":::"memory"); \
- } while (0)
-void _cr_plat_disable_interrupts(void);
+#define cr_save_and_disable_interrupts() ({ \
+ bool was_enabled = _cr_plat_save_and_disable_interrupts(); \
+ asm volatile ("":::"memory"); \
+ was_enabled; \
+ })
+bool _cr_plat_save_and_disable_interrupts(void);
/**
- * Enable interrupts. Any "pending" interrupts that came in while
+ * Re-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(); \
+#define cr_restore_interrupts(enable) do { \
+ asm volatile ("":::"memory"); \
+ if (enable) \
+ _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?
+ * call from a interrupt handler.
*/
void cr_unpause_from_intrhandler(cid_t);