1 // Copyright 2020 The Marl Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Example of a task that creates and waits on sub tasks.
16
17 #include "marl/defer.h"
18 #include "marl/scheduler.h"
19 #include "marl/waitgroup.h"
20
21 #include <cstdio>
22
main()23 int main() {
24 // Create a marl scheduler using the 4 hardware threads.
25 // Bind this scheduler to the main thread so we can call marl::schedule()
26 marl::Scheduler::Config cfg;
27 cfg.setWorkerThreadCount(4);
28
29 marl::Scheduler scheduler(cfg);
30 scheduler.bind();
31 defer(scheduler.unbind()); // Automatically unbind before returning.
32
33 // marl::schedule() requires the scheduler to be bound to the current thread
34 // (see above). The scheduler ensures that tasks are run on a thread with the
35 // same scheduler automatically bound, so we don't need to call
36 // marl::Scheduler::bind() again below.
37
38 // Sequence of task events:
39 // __________________________________________________________
40 // | |
41 // | ---> [task B] ---- |
42 // | / \ |
43 // | [task A] -----> [task A: wait] -----> [task A: resume] |
44 // | \ / |
45 // | ---> [task C] ---- |
46 // |__________________________________________________________|
47
48 // Create a WaitGroup for waiting for task A to finish.
49 // This has an initial count of 1 (A)
50 marl::WaitGroup a_wg(1);
51
52 // Schedule task A
53 marl::schedule([=] {
54 defer(a_wg.done()); // Decrement a_wg when task A is done
55
56 printf("Hello from task A\n");
57 printf("Starting tasks B and C...\n");
58
59 // Create a WaitGroup for waiting on task B and C to finish.
60 // This has an initial count of 2 (B + C)
61 marl::WaitGroup bc_wg(2);
62
63 // Schedule task B
64 marl::schedule([=] {
65 defer(bc_wg.done()); // Decrement bc_wg when task B is done
66 printf("Hello from task B\n");
67 });
68
69 // Schedule task C
70 marl::schedule([=] {
71 defer(bc_wg.done()); // Decrement bc_wg when task C is done
72 printf("Hello from task C\n");
73 });
74
75 // Wait for tasks B and C to finish.
76 bc_wg.wait();
77 });
78
79 // Wait for task A (and so B and C) to finish.
80 a_wg.wait();
81
82 printf("Task A has finished\n");
83 }
84