Skip to content

Add the async_run macro #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Function|Description
*async_call(func, state)*|Asynchronously call `func(state)` and return true if done executing (optional). You can also simply call `func(state)`directly which returns true/false.
*async_init(state)*|Initialize async subroutine state
*async_done(state)*|Returns true if async subroutine has completed execution, otherwise false
*async_run(cond)*|Runs your async function(s) from a non async function separated by `&` or `\|` to specify when all or one complete respectively

# Examples

Expand Down
7 changes: 7 additions & 0 deletions async/async.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
* Pulled from: https://github.com/naasking/async.h
*
* Author: Sandro Magi <[email protected]>
* Contributor: Paul Sorensen <[email protected]>
*/

/**
Expand Down Expand Up @@ -135,4 +136,10 @@ struct async { async_state; };
*/
#define async_call(f, state) (async_done(state) || (f)(state))

/**
* Wait until the condition succeeds from a non-async function
* @param cond The condition that must be satisfied before execution can proceed
*/
#define async_run(cond) while(!(cond))

#endif
18 changes: 4 additions & 14 deletions async/example-buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,19 +146,9 @@ example_buffer(void)

async_init(&driver_pt);

while (!driver_thread(&driver_pt)) {

/*
* When running this example on a multitasking system, we must
* give other processes a chance to run too and therefore we call
* usleep() resp. Sleep() here. On a dedicated embedded system,
* we usually do not need to do this.
*/
#ifdef _WIN32
Sleep(0);
#else
usleep(10);
#endif
}
async_run(
driver_thread(&driver_pt)
);

return 0;
}
19 changes: 4 additions & 15 deletions async/example-codelock.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,21 +367,10 @@ example_codelock(void)
/*
* Schedule the two asyncs until the codelock_thread() exits.
*/
while(!codelock_thread(&codelock_pt)) {
input_thread(&input_pt);

/*
* When running this example on a multitasking system, we must
* give other processes a chance to run too and therefore we call
* usleep() resp. Sleep() here. On a dedicated embedded system,
* we usually do not need to do this.
*/
#ifdef _WIN32
Sleep(0);
#else
usleep(10);
#endif
}
async_run(
codelock_thread(&codelock_pt) &
input_thread(&input_pt)
);

return 0;
}
Expand Down
43 changes: 32 additions & 11 deletions async/example-small.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/**
* This is a very small example that shows how to use
* async.h. The program consists of two async subroutines that wait
* for each other to toggle a variable.
* for each other to toggle a variable. This continues while a third async
* subroutine counts down from a provided starting integer.
*/

/* We must always include async.h in our asyncs code. */
Expand All @@ -10,7 +11,7 @@
#include <stdio.h> /* For printf(). */

/* Two flags that the two async functions use. */
static int async1_flag, async2_flag;
static int async1_flag, async2_flag, counter;

/**
* The first async function. A async function must always
Expand Down Expand Up @@ -71,27 +72,47 @@ async2(struct async *pt)
async_end;
}

/**
* An async function to decrement the global countdown
*/
static async
countdown(struct async *pt)
{
async_begin(pt);

/* Yield control to other functions while the counter is above 0 */
while (counter-- >= 0) {
async_yield;
}

async_end;
}

/**
* Finally, we have the main loop. Here is where the asyncs are
* initialized and scheduled. First, however, we define the
* async state variables pt1 and pt2, which hold the state of
* the two asyncs.
* async state variables pt1, pt2, and count, which hold the state of
* the 3 asyncs.
*/
static struct async pt1, pt2;
static struct async pt1, pt2, count;
void
example_small(int i)
{
/* Initialize the async state variables with async_init(). */
async_init(&pt1);
async_init(&pt2);
async_init(&count);

counter = i;

/*
* Then we schedule the two asyncs by repeatedly calling their
* async functions and passing a pointer to the async
* Then we schedule the three asyncs by repeatedly calling their async
* functions via the `async_run` macro and passing a pointer to the async
* state variables as arguments.
*/
while (--i >= 0) {
async1(&pt1);
async2(&pt2);
}
async_run(
countdown(&count) |
async1(&pt1) |
async2(&pt2)
);
}