Skip to content

Commit

Permalink
revised internals to avoid mandatory async_call
Browse files Browse the repository at this point in the history
  • Loading branch information
naasking committed Feb 5, 2020
1 parent 11f199a commit d7a15c3
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 24 deletions.
34 changes: 13 additions & 21 deletions async/async.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ typedef enum ASYNC_EVT { ASYNC_INIT = 0, ASYNC_DONE = UINT_MAX } async;
/*
* Declare the async state
*/
#define async_state unsigned _async_kcont
#define async_state unsigned _async_k

/*
* Core async structure, optional to use.
Expand All @@ -77,12 +77,12 @@ struct async { async_state; };
/*
* Mark the start of an async subroutine
*/
#define async_begin(k) switch((k)->_async_kcont) { case 0:
#define async_begin(k) unsigned *_k = &(k)->_async_k; switch(*_k) { default:

/*
* Mark the end of a async subroutine
*/
#define async_end default: return ASYNC_DONE; }
#define async_end *_k=ASYNC_DONE; case ASYNC_DONE: return 1; }

/*
* Wait until the condition succeeds
Expand All @@ -92,42 +92,34 @@ struct async { async_state; };
/*
* Wait while the condition succeeds (optional)
*/
#define await_while(cond) case __LINE__: if (cond) return __LINE__
#define await_while(cond) *_k = __LINE__; case __LINE__: if (cond) return 0

/*
* Yield execution
*/
#define async_yield return __LINE__; case __LINE__:
#define async_yield *_k = __LINE__; return 0; case __LINE__:

/*
* Exit the current async subroutine
*/
#define async_exit return ASYNC_DONE
#define async_exit *_k = ASYNC_DONE; return 1

/*
* Initialize a new async computation
*/
#define async_init(state) (state)->_async_kcont=ASYNC_INIT
#define async_init(state) (state)->_async_k=ASYNC_INIT

/*
* Check if async subroutine is done
*/
#define async_done(state) (state)->_async_kcont==ASYNC_DONE
#define async_done(state) (state)->_async_k==ASYNC_DONE

/*
* Resume a running async computation and check for completion
* Resume a running async computation and check for completion (optional)
*
* You can simply call the function itself which will return true
* if the async call is complete, or false if it's still in progress.
*/
#define async_call(f, state) (async_done(state) || ASYNC_DONE==((state)->_async_kcont = (f)(state)))

typedef struct {
async_state;
void *p;
} async_env;
async_env stack;

#define async_begin0(x) stack.p = (x); switch(stack.async_kcont__) { case 0:
#define await0(cond) case __LINE__: if (!(cond)) return __LINE__
#define async_call0(f, env) async_done(env) || ASYNC_DONE==(stack.async_kcont__=f(args))
#define async_end0 default:; }
#define async_call(f, state) (async_done(state) || (f)(state))

#endif
2 changes: 1 addition & 1 deletion async/example-buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ example_buffer(void)

async_init(&driver_pt);

while (!async_call(driver_thread, &driver_pt)) {
while (!driver_thread(&driver_pt)) {

/*
* When running this example on a multitasking system, we must
Expand Down
4 changes: 2 additions & 2 deletions async/example-codelock.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,8 @@ example_codelock(void)
/*
* Schedule the two asyncs until the codelock_thread() exits.
*/
while(!async_call(codelock_thread, &codelock_pt)) {
async_call(input_thread, &input_pt);
while(!codelock_thread(&codelock_pt)) {
input_thread(&input_pt);

/*
* When running this example on a multitasking system, we must
Expand Down

0 comments on commit d7a15c3

Please sign in to comment.