Skip to content

Commit 4f1a498

Browse files
committed
Add example-print-after
1 parent 7ade482 commit 4f1a498

File tree

5 files changed

+146
-1
lines changed

5 files changed

+146
-1
lines changed

README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,60 @@ Function|Description
2828

2929
# Examples
3030

31+
The following is a sample program where multiple coroutines print they are starting, sleep for a specified time, and
32+
print they slept the specified time
33+
```c
34+
#include "async.h"
35+
#include "async-time.h"
36+
37+
struct print_after_state
38+
{
39+
async_state;
40+
struct async_sleep_state async_sleep_state;
41+
};
42+
43+
static async print_after(struct print_after_state *state, unsigned int duration)
44+
{
45+
async_begin(state);
46+
47+
printf("Starting %d second counter...\n", duration);
48+
async_yield;
49+
printf("Yield from %d second counter demo'd!\n", duration);
50+
async_init(&state->async_sleep_state);
51+
await(async_sleep(&state->async_sleep_state, duration * 1000));
52+
printf("Slept: %d seconds\n", duration);
53+
54+
async_end;
55+
}
56+
57+
int example_print_after(void)
58+
{
59+
struct print_after_state a = {}, b = {}, c = {};
60+
61+
async_run(
62+
print_after(&a, 3) &
63+
print_after(&b, 5) &
64+
print_after(&c, 1)
65+
);
66+
67+
return 0;
68+
}
69+
```
70+
71+
Prints the following and runs a total of 5 seconds:
72+
73+
```
74+
Starting 3 second counter...
75+
Starting 5 second counter...
76+
Starting 1 second counter...
77+
Yield from 3 second counter demo'd!
78+
Yield from 5 second counter demo'd!
79+
Yield from 1 second counter demo'd!
80+
Slept: 1 seconds
81+
Slept: 3 seconds
82+
Slept: 5 seconds
83+
```
84+
3185
I ported the examples found in the protothreads distribution to async.h. Here
3286
is the async.h equivalent of the protothreads sample on the home page:
3387
```c

async/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CC = gcc
22
CCFlags = -Wall
33
BUILD_DIR = build
44

5-
SRC = async-time.c example-buffer.c example-codelock.c example-small.c main.c
5+
SRC = async-time.c example-buffer.c example-codelock.c example-print-after.c example-small.c main.c
66
OBJ = $(patsubst %.c,$(BUILD_DIR)/%.o,$(SRC))
77

88
all : $(OBJ)

async/example-print-after.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
* This is a another small example that shows how to use parts of async.h.
3+
* The program consists of an async subroutine which does the following:
4+
*
5+
* 1. Prints that is starting a coroutine with a provided delay
6+
* 2. Demonstrates yielding from a subroutine
7+
* 3. Sleeps for a specified amount of time
8+
* 4. Prints the duration it slept before completion
9+
*
10+
* This program also shows the use of the `async_run` macro for running
11+
* async coroutines from a regular function
12+
*/
13+
#include <stdio.h>
14+
#include <sys/time.h>
15+
#include <unistd.h>
16+
17+
#include "async.h"
18+
#include "async-time.h"
19+
20+
/**
21+
* This structure is required because there will be an internal call to another
22+
* async function (async_sleep) which contains its own state. Rather than having
23+
* each state live in the top-level function call, this struct contains will
24+
* save the state uniquely for each call.
25+
*/
26+
struct print_after_state
27+
{
28+
async_state;
29+
struct async_sleep_state async_sleep_state;
30+
};
31+
32+
/**
33+
* print_after takes a duration of time to sleep
34+
*
35+
* This demonstrates how async_yield works and also how multiple subroutines
36+
* seemingly operate simultaneously
37+
*/
38+
static async print_after(struct print_after_state *state, unsigned int duration)
39+
{
40+
/* Declare the beginning of the async subroutine */
41+
async_begin(state);
42+
43+
/* This print line will show in the order in which the coroutines are called
44+
However, each of coroutines will print this line before "Yield from..."
45+
line is printed. This demonstrates how the async_yield operates by yielding
46+
control to the next coroutine. */
47+
printf("Starting %d second counter...\n", duration);
48+
async_yield;
49+
printf("Yield from %d second counter demo'd!\n", duration);
50+
51+
/* This will initialize the async_sleep_state to 0 */
52+
async_init(&state->async_sleep_state);
53+
/* Asynchronously sleep for the specified duration */
54+
await(async_sleep(&state->async_sleep_state, duration * 1000));
55+
56+
/* This coroutine demonstration has slept for the provided duration */
57+
printf("Slept: %d seconds\n", duration);
58+
59+
/* Declare the end of the async subroutine */
60+
async_end;
61+
}
62+
63+
/**
64+
* This is the main function for this example.
65+
*
66+
* This demo will be using 3 coroutines and each require their own state.
67+
* Each print_after call will print that they are starting in the order in which
68+
* they are called, yield control, then sleep the specified duration before
69+
* printing they have completed
70+
*/
71+
int example_print_after(void)
72+
{
73+
/* Create 3 states. Memsetting each to zero like this effectively initialize
74+
each state at once */
75+
struct print_after_state a = {}, b = {}, c = {};
76+
77+
/* Because we are not in an async portion of code, we cannot call 'await'.
78+
In order to gather and call our coroutines, we will use 'async_run' to run
79+
each. The & operator is used when you each call to run until completion,
80+
while the | operator is used when only want each call to run until the first
81+
completion occurs */
82+
async_run(
83+
print_after(&a, 3) &
84+
print_after(&b, 5) &
85+
print_after(&c, 1)
86+
);
87+
88+
return 0;
89+
}

async/examples.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
extern void example_small(int);
55
extern int example_buffer(void);
66
extern int example_codelock(void);
7+
extern int example_print_after(void);
78

89
#endif

async/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ int main(void) {
55
example_small(200);
66
example_buffer();
77
example_codelock();
8+
example_print_after();
89
return 0;
910
}

0 commit comments

Comments
 (0)