Rudimentary task system in portable C, based on Tom Duff's switch-based coroutine trick and a stack of environment structs.  
More...
 | 
| #define  | ADD_EVENTS(x) | 
|   | 
| #define  | ADD_DBG(d,  x) | 
|   | 
| #define  | ADD_T_EV(when,  file,  state,  what) | 
|   | 
| #define  | ADD_WAIT_EV(when,  file,  state,  what,  milli) | 
|   | 
| #define  | TASK_POOL_ELEMS   1000 | 
|   | 
| #define  | MAXTASKS   1000 | 
|   | 
| #define  | _ep   ((struct env *)(stack->sp->ptr)) | 
|   | 
| #define  | TASK_ALLOC(pool,  type)   (task_allocate(pool, (unsigned int)sizeof(type))) | 
|   | 
| #define  | TASK_DEBUG(x) | 
|   | 
| #define  | FINALLY     task_cleanup: | 
|   | 
| #define  | ON_STACK_TOP   (stack->sp == stack->stack_top + 1) | 
|   | 
| #define  | TERM_CHECK     if (ON_STACK_TOP && stack->terminate) goto task_cleanup | 
|   | 
| #define  | TERMINATE   goto task_cleanup | 
|   | 
| #define  | TASK_BEGIN | 
|   | 
| #define  | TASK_END | 
|   | 
| #define  | TASK_RETURN(x) | 
|   | 
| #define  | TASK_DUMP_ERR | 
|   | 
| #define  | TASK_FAIL | 
|   | 
| #define  | TASK_YIELD | 
|   | 
| #define  | TASK_DEACTIVATE | 
|   | 
| #define  | TASK_DELAY(t) | 
|   | 
| #define  | TASK_DELAY_UNTIL(t) | 
|   | 
| #define  | TASK_WAIT(queue) | 
|   | 
| #define  | TIMED_TASK_WAIT(queue,  t) | 
|   | 
| #define  | CHANNEL_GET(channel,  ptr,  type) | 
|   | 
| #define  | CHANNEL_PEEK(channel,  ptr,  type) | 
|   | 
| #define  | CHANNEL_GET_REVERSE(channel,  ptr,  type) | 
|   | 
| #define  | TASK_CALL(funcall) | 
|   | 
| #define  | DECL_ENV   struct env { | 
|   | 
| #define  | ENV_INIT   void init() { | 
|   | 
| #define  | END_ENV_INIT   } | 
|   | 
| #define  | END_ENV | 
|   | 
| #define  | LOCK_FD(fd,  op) | 
|   | 
| #define  | UNLOCK_FD(fd,  op)   unlock_fd(fd, stack, op) | 
|   | 
| #define  | xstr(s)   #s | 
|   | 
 | 
| static void  | set_int_arg (task_arg *arg, int value) | 
|   | 
| static int  | get_int_arg (task_arg arg) | 
|   | 
| static void  | set_long_arg (task_arg *arg, long value) | 
|   | 
| static long  | get_long_arg (task_arg arg) | 
|   | 
| static void  | set_uint_arg (task_arg *arg, unsigned int value) | 
|   | 
| static unsigned int  | get_uint_arg (task_arg arg) | 
|   | 
| static void  | set_ulong_arg (task_arg *arg, unsigned long value) | 
|   | 
| static void  | set_ulong_long_arg (task_arg *arg, unsigned long long value) | 
|   | 
| static unsigned long  | get_ulong_arg (task_arg arg) | 
|   | 
| static unsigned long long  | get_ulong_long_arg (task_arg arg) | 
|   | 
| static void  | set_float_arg (task_arg *arg, float value) | 
|   | 
| static float  | get_float_arg (task_arg arg) | 
|   | 
| static void  | set_double_arg (task_arg *arg, double value) | 
|   | 
| static double  | get_double_arg (task_arg arg) | 
|   | 
| static void  | set_string_arg (task_arg *arg, char const *value) | 
|   | 
| static void  | set_void_arg (task_arg *arg, void *value) | 
|   | 
| static char const *  | get_string_arg (task_arg arg) | 
|   | 
| static void *  | get_void_arg (task_arg arg) | 
|   | 
| static task_arg  | int_arg (int i) | 
|   | 
| static task_arg  | uint_arg (unsigned int i) | 
|   | 
| static task_arg  | ulong_arg (unsigned long l) | 
|   | 
| static task_arg  | ulong_long_arg (unsigned long long ll) | 
|   | 
| static task_arg  | double_arg (double i) | 
|   | 
| static task_arg  | string_arg (char const *v) | 
|   | 
| static task_arg  | void_arg (void *v) | 
|   | 
| static task_arg  | end_arg () | 
|   | 
| channel *  | channel_init (channel *c, unsigned int type) | 
|   | 
| void  | channel_put (channel *c, linkage *data) | 
|   | 
| void  | channel_put_front (channel *c, linkage *data) | 
|   | 
| void *  | task_allocate (task_env *p, unsigned int bytes) | 
|   | Allocate bytes from pool, initialized to zero.  More...
  | 
|   | 
| void  | reset_state (task_env *p) | 
|   | 
| void  | pushp (task_env *p, void *ptr) | 
|   | 
| void  | popp (task_env *p) | 
|   | 
| double  | seconds () | 
|   | 
| double  | task_now () | 
|   | 
| void  | task_delay_until (double time) | 
|   | 
| unsigned long long int  | get_time_since_the_epoch () | 
|   | Return time in microseconds.  More...
  | 
|   | 
| int  | unblock_fd (int fd) | 
|   | 
| int  | block_fd (int fd) | 
|   | 
| result  | con_read (connection_descriptor const *rfd, void *buf, int n) | 
|   | 
| result  | con_pipe_read (connection_descriptor const *rfd, void *buf, int n) | 
|   | 
| int  | task_read (connection_descriptor const *con, void *buf, int n, int64_t *ret, connnection_read_method read_function=con_read) | 
|   | 
| result  | con_write (connection_descriptor const *wfd, void *buf, int n) | 
|   | 
| result  | con_pipe_write (connection_descriptor const *wfd, void *buf, int n) | 
|   | 
| int  | task_write (connection_descriptor const *con, void *buf, uint32_t n, int64_t *ret) | 
|   | 
| int  | is_locked (int fd) | 
|   | 
| int  | lock_fd (int fd, task_env *t, int lock) | 
|   | 
| int  | unlock_fd (int fd, task_env *t, int lock) | 
|   | 
| void  | task_sys_init () | 
|   | 
| task_env *  | task_new (task_func func, task_arg arg, const char *name, int debug) | 
|   | 
| void  | task_loop () | 
|   | 
| void  | task_wait (task_env *t, linkage *queue) | 
|   | 
| void  | task_wakeup (linkage *queue) | 
|   | 
| task_env *  | task_terminate (task_env *t) | 
|   | 
| void  | set_task (task_env **p, task_env *t) | 
|   | 
| void  | task_terminate_all () | 
|   | 
| void  | remove_and_wakeup (int i) | 
|   | 
| int  | is_only_task () | 
|   | 
| task_env *  | task_activate (task_env *t) | 
|   | 
| task_env *  | task_deactivate (task_env *t) | 
|   | 
| const char *  | task_name () | 
|   | 
| task_env *  | wait_io (task_env *t, int fd, int op) | 
|   | 
| result  | set_nodelay (int fd) | 
|   | 
| task_env *  | timed_wait_io (task_env *t, int fd, int op, double timeout) | 
|   | 
Rudimentary task system in portable C, based on Tom Duff's switch-based coroutine trick and a stack of environment structs. 
(continuations?) Nonblocking IO and event handling need to be rewritten for each new OS.