summaryrefslogtreecommitdiff
path: root/coroutine.h
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-09-26 19:36:54 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-09-26 19:36:54 -0600
commit71e1a86a033c380f85dd300d788af63bfef25bab (patch)
tree07aa53d5a933ba51535a78972edbfe0cd95a31c5 /coroutine.h
parentf5da707e77ee954b12f3c961012e4f40fa4e1bd3 (diff)
wip reorg
Diffstat (limited to 'coroutine.h')
-rw-r--r--coroutine.h130
1 files changed, 0 insertions, 130 deletions
diff --git a/coroutine.h b/coroutine.h
deleted file mode 100644
index 4d83181..0000000
--- a/coroutine.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* coroutine.h - Simple embeddable coroutine implementation
- *
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
- * SPDX-Licence-Identifier: AGPL-3.0-or-later
- */
-
-/**
- * A coroutine is a cooperatively-multitasked form of threading.
- *
- * This coroutine.{h,c} form a lightweight coroutine implementation
- * for non-multithreaded environments (only one coroutine may be
- * running at a time (so no m:n scheduling), coroutine_{add,main} may
- * not be called concurrently with eachother).
- *
- * Unlike many other lightweight or embeddable coroutine
- * implementations, coroutine.{h,c} allow coroutines to use the stack
- * as normal C functions and do not forbid switch() blocks in
- * coroutines.
- *
- * See also: coroutine_rpc.h is a request/response system built on top
- * of coroutine.{h,c}.
- *
- * See also: coroutine_chan.h is a 1-way channel system built on top
- * of coroutine.{h,c}.
- */
-#ifndef _COROUTINE_H_
-#define _COROUTINE_H_
-
-#include <stddef.h> /* for size_t */
-#include <stdbool.h> /* for bool */
-
-/* typedefs *******************************************************************/
-
-/**
- * A cid_t is a "coroutine ID", used to refer to a coroutine.
- *
- * May be reused if a coroutine exits.
- *
- * Valid IDs are `1 <= cid <= COROUTINE_NUM`; `0` is used for
- * "none/invalid".
- */
-typedef size_t cid_t;
-
-/**
- * The root function for a coroutine; a coroutine function should be
- * declared as
- *
- * COROUTINE myfunc(void *_args) {
- * myargtype *args = args;
- * cr_begin();
- *
- * ...
- *
- * cr_end();
- * }
- *
- * The function MUST NOT ever return (GCC enforces this); call
- * cr_exit() or cr_end() instead of returning.
- *
- * When creating a coroutine with coroutine_add(), the bit before
- * cr_begin() runs before coroutine_add() returns; if `_args` points
- * to a place on another coroutine's stack that may go away, then this
- * is an opportunity to copy it to this coroutine's stack. Otherwise
- * you shouldn't do anything else before calling cr_begin().
- * Specifically, coroutine_add() and
- * cr_{yield,pause_and_yield,exit,end}() are explicitly forbidden to
- * call from within a coroutine before cr_begin() (note that the
- * cr_rpc_*() and cr_chan_*() macros call these functions).
- */
-typedef void (*cr_fn_t)(void *args);
-#define COROUTINE __attribute__ ((noreturn)) void
-
-/* managing coroutines ********************************************************/
-
-/**
- * Call `fn(args)` in a new coroutine with stack size `stack_size`.
- *
- * See the doc comment on c_fn_t for the requirements imposed on fn.
- *
- * May be called from outside any coroutine (before calling
- * coroutine_main()) or from inside of a coroutine (after it cas
- * called cr_begin()).
- *
- * Returns the cid of the newly-created coroutine. May return 0 if
- * there are already COROUTINE_NUM active coroutines.
- */
-cid_t coroutine_add_with_stack_size(size_t stack_size, cr_fn_t fn, void *args);
-
-/**
- * Like coroutine_add_with_stack_size(), but uses a default stack size so
- * you don't need to think about it.
- */
-#define coroutine_add(fn, args) coroutine_add_with_stack_size(0, fn, args)
-
-/**
- * The main scheduler loop.
- *
- * "Should" never return, but will print a message to stderr and
- * return if the program has deadlocked and there are no runnable
- * coroutines. So be sure to call coroutine_add() at least once
- * before calling this.
- */
-void coroutine_main(void);
-
-/* inside of coroutines *******************************************************/
-
-/** cr_begin() goes at the beginning of a coroutine, after it has initialized its stack. */
-void cr_begin( void);
-/** cr_exit() terminates the currently-running coroutine. */
-__attribute__ ((noreturn)) void cr_exit(void);
-/** cr_yield() switches to another coroutine (if there is another runnable coroutine to switch to). */
-void cr_yield(void);
-/** cr_pause_and_yield() marks the current coroutine as not-runnable and switches to another coroutine. */
-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_sighandler() is like cr_unpause(), but safe to call from a signal handler that might race with the coroutine actually pausing itself. */
-void cr_unpause_from_sighandler(cid_t);
-/** cr_end() is a counterpart to cr_begin(), but is really just cr_exit(). */
-#define cr_end cr_exit
-
-/** cr_getcid() returns the cid of the currently-running coroutine. */
-cid_t cr_getcid(void);
-
-/**
- * It is not possible for one coroutine to kill another or to mark
- * another as paused; a coroutine may only do those things to itself.
- */
-
-#endif /* _COROUTINE_H_ */