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
+ }
0 commit comments