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
23int 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