xref: /aosp_15_r20/external/federated-compute/fcp/base/scheduler.h (revision 14675a029014e728ec732f129a32e299b2da0601)
1 /*
2  * Copyright 2018 Google LLC
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef FCP_BASE_SCHEDULER_H_
18 #define FCP_BASE_SCHEDULER_H_
19 
20 /**
21  * Overview
22  * ========
23  *
24  * A simple implementation of a scheduler (thread pool). Allows to schedule
25  * tasks and futures.
26  */
27 
28 #include <functional>
29 #include <memory>
30 
31 #include "fcp/base/monitoring.h"
32 #include "fcp/base/move_to_lambda.h"
33 
34 namespace fcp {
35 
36 /**
37  * A Worker allows to schedule tasks which are executed sequentially.
38  * Workers are created from a Scheduler.
39  *
40  * Lifetime and destruction:
41  *
42  *   - The scheduler from which a worker is created must not be destructed
43  *     before the worker.
44  *
45  *   - The worker must not be destructed before all its tasks are finished.
46  */
47 class Worker {
48  public:
49   virtual ~Worker() = default;
50   Worker() = default;
51 
52   Worker(Worker const&) = delete;
53   Worker& operator=(Worker const&) = delete;
54 
55   /**
56    * Schedules a task on this worker. Tasks are executed strictly sequentially
57    * in the order they are scheduled.
58    */
59   virtual void Schedule(std::function<void()> task) = 0;
60 };
61 
62 /**
63  * A Scheduler which allows to schedule 'tasks'.
64  *
65  * Lifetime and destruction:
66  *
67  *   - A Scheduler *must* be idle (no active or pending work) at destruction
68  *     time. See WaitUntilIdle.
69  *
70  *   - Implies: A Scheduler *must not* be destructed by one of its own tasks
71  *
72  *   - Implies: Task closures may safely hold raw pointers to their thread pool.
73  *     They should *not* have ownership (via a smart-pointer or similar).
74  */
75 class Scheduler {
76  public:
77   virtual ~Scheduler() = default;
78   Scheduler() = default;
79 
80   Scheduler(Scheduler const&) = delete;
81   Scheduler& operator=(Scheduler const&) = delete;
82 
83   /**
84    * Creates a new Worker based on this scheduler.
85    */
86   virtual std::unique_ptr<Worker> CreateWorker();
87 
88   /**
89    * Schedules a task that will execute on the scheduler.
90    */
91   virtual void Schedule(std::function<void()> task) = 0;
92 
93   /**
94    * Waits until there are no tasks running or pending.
95    *
96    * In this state, the thread pool will not restart working until some
97    * external entity is scheduling new tasks, as work caused by tasks spawning
98    * other tasks has ceased.
99    */
100   virtual void WaitUntilIdle() = 0;
101 };
102 
103 /**
104  * Creates a scheduler using a fixed-size pool of threads to run tasks.
105  */
106 std::unique_ptr<Scheduler> CreateThreadPoolScheduler(std::size_t thread_count);
107 
108 }  // namespace fcp
109 
110 #endif  // FCP_BASE_SCHEDULER_H_
111