Embedded Template Library 1.0
Loading...
Searching...
No Matches
scheduler.h
1/******************************************************************************
2The MIT License(MIT)
3
4Embedded Template Library.
5https://github.com/ETLCPP/etl
6https://www.etlcpp.com
7
8Copyright(c) 2017 John Wellbelove
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files(the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions :
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26SOFTWARE.
27******************************************************************************/
28
29#ifndef ETL_SCHEDULER_INCLUDED
30#define ETL_SCHEDULER_INCLUDED
31
32#include "platform.h"
33#include "vector.h"
34#include "nullptr.h"
35#include "error_handler.h"
36#include "exception.h"
37#include "task.h"
38#include "type_traits.h"
39#include "function.h"
40
41#include <stdint.h>
42
43namespace etl
44{
45 //***************************************************************************
47 //***************************************************************************
57
58 //***************************************************************************
60 //***************************************************************************
62 {
63 public:
64
66 : etl::scheduler_exception(ETL_ERROR_TEXT("scheduler:no tasks", ETL_SCHEDULER_FILE_ID"A"), file_name_, line_number_)
67 {
68 }
69 };
70
71 //***************************************************************************
73 //***************************************************************************
75 {
76 public:
77
79 : etl::scheduler_exception(ETL_ERROR_TEXT("scheduler:null task", ETL_SCHEDULER_FILE_ID"B"), file_name_, line_number_)
80 {
81 }
82 };
83
84 //***************************************************************************
86 //***************************************************************************
88 {
89 public:
90
92 : etl::scheduler_exception(ETL_ERROR_TEXT("scheduler:too many tasks", ETL_SCHEDULER_FILE_ID"C"), file_name_, line_number_)
93 {
94 }
95 };
96
97 //***************************************************************************
101 //***************************************************************************
103 {
104 bool schedule_tasks(etl::ivector<etl::task*>& task_list)
105 {
106 bool idle = true;
107
108 for (size_t index = 0UL; index < task_list.size(); ++index)
109 {
110 etl::task& task = *(task_list[index]);
111
112 if (task.task_request_work() > 0)
113 {
115 idle = false;
116 }
117 }
118
119 return idle;
120 }
121 };
122
125
126 //***************************************************************************
130 //***************************************************************************
132 {
133 bool schedule_tasks(etl::ivector<etl::task*>& task_list)
134 {
135 bool idle = true;
136
137 for (size_t index = 0UL; index < task_list.size(); ++index)
138 {
139 etl::task& task = *(task_list[index]);
140
141 while (task.task_request_work() > 0)
142 {
144 idle = false;
145 }
146 }
147
148 return idle;
149 }
150 };
151
154
155 //***************************************************************************
159 //***************************************************************************
161 {
162 bool schedule_tasks(etl::ivector<etl::task*>& task_list)
163 {
164 bool idle = true;
165
166 size_t index = 0UL;
167 while (index < task_list.size())
168 {
169 etl::task& task = *(task_list[index]);
170
171 if (task.task_request_work() > 0)
172 {
174 idle = false;
175 break;
176 }
177 else
178 {
179 ++index;
180 }
181 }
182
183 return idle;
184 }
185 };
186
187 //***************************************************************************
192 //***************************************************************************
194 {
195 bool schedule_tasks(etl::ivector<etl::task*>& task_list)
196 {
197 bool idle = true;
198
199 size_t most_index = 0UL;
201
202 for (size_t index = 0UL; index < task_list.size(); ++index)
203 {
204 etl::task& task = *(task_list[index]);
205
207
208 if (n_work > most_work)
209 {
210 most_index = index;
212 idle = false;
213 }
214 }
215
216 if (!idle)
217 {
218 task_list[most_index]->task_process_work();
219 }
220
221 return idle;
222 }
223 };
224
225 //***************************************************************************
227 //***************************************************************************
229 {
230 public:
231
232 //*******************************************
233 // Virtuals.
234 //*******************************************
235 virtual void start() = 0;
236
237 virtual ~ischeduler()
238 {
239 }
240
241 //*******************************************
243 //*******************************************
245 {
246 p_idle_callback = &callback;
247 }
248
249 //*******************************************
251 //*******************************************
253 {
254 p_watchdog_callback = &callback;
255 }
256
257 //*******************************************
259 //*******************************************
261 {
262 scheduler_running = scheduler_running_;
263 }
264
265 //*******************************************
267 //*******************************************
269 {
270 return scheduler_running;
271 }
272
273 //*******************************************
275 //*******************************************
277 {
278 scheduler_exit = true;
279 }
280
281 //*******************************************
284 //*******************************************
286 {
288
289 if (!task_list.full())
290 {
291 typename task_list_t::iterator itask = etl::upper_bound(task_list.begin(),
292 task_list.end(),
294 compare_priority());
295
296 task_list.insert(itask, &task);
297
299 }
300 }
301
302 //*******************************************
306 //*******************************************
307 template <typename TSize>
309 {
310 for (TSize i = 0; i < size; ++i)
311 {
312 ETL_ASSERT((p_tasks[i] != ETL_NULLPTR), ETL_ERROR(etl::scheduler_null_task_exception));
313 add_task(*(p_tasks[i]));
314 }
315 }
316
317 protected:
318
319 //*******************************************
321 //*******************************************
323 : scheduler_running(false),
324 scheduler_exit(false),
325 p_idle_callback(ETL_NULLPTR),
326 p_watchdog_callback(ETL_NULLPTR),
327 task_list(task_list_)
328 {
329 }
330
331 bool scheduler_running;
332 bool scheduler_exit;
333 etl::ifunction<void>* p_idle_callback;
334 etl::ifunction<void>* p_watchdog_callback;
335
336 private:
337
338 //*******************************************
339 // Used to order tasks in descending priority.
340 //*******************************************
341 struct compare_priority
342 {
343 bool operator()(etl::task_priority_t priority, etl::task* ptask) const
344 {
345 return priority > ptask->get_task_priority();
346 }
347 };
348
349 typedef etl::ivector<etl::task*> task_list_t;
350 task_list_t& task_list;
351 };
352
353 //***************************************************************************
355 //***************************************************************************
356 template <typename TSchedulerPolicy, size_t MAX_TASKS_>
357 class scheduler : public etl::ischeduler, protected TSchedulerPolicy
358 {
359 public:
360
361 enum
362 {
363 MAX_TASKS = MAX_TASKS_,
364 };
365
366 scheduler()
367 : ischeduler(task_list)
368 {
369 }
370
371 //*******************************************
373 //*******************************************
374 void start()
375 {
376 ETL_ASSERT(task_list.size() > 0, ETL_ERROR(etl::scheduler_no_tasks_exception));
377
378 scheduler_running = true;
379
380 while (!scheduler_exit)
381 {
382 if (scheduler_running)
383 {
384 bool idle = TSchedulerPolicy::schedule_tasks(task_list);
385
386 if (p_watchdog_callback)
387 {
388 (*p_watchdog_callback)();
389 }
390
391 if (idle && p_idle_callback)
392 {
393 (*p_idle_callback)();
394 }
395 }
396 }
397 }
398
399 private:
400
401 typedef etl::vector<etl::task*, MAX_TASKS> task_list_t;
402 task_list_t task_list;
403 };
404}
405
406#endif
Definition callback.h:45
Scheduler base.
Definition scheduler.h:229
void add_task_list(etl::task **p_tasks, TSize size)
Definition scheduler.h:308
ischeduler(etl::ivector< etl::task * > &task_list_)
Constructor.
Definition scheduler.h:322
void set_watchdog_callback(etl::ifunction< void > &callback)
Set the watchdog callback.
Definition scheduler.h:252
void exit_scheduler()
Force the scheduler to exit.
Definition scheduler.h:276
void set_scheduler_running(bool scheduler_running_)
Set the running state for the scheduler.
Definition scheduler.h:260
void add_task(etl::task &task)
Definition scheduler.h:285
void set_idle_callback(etl::ifunction< void > &callback)
Set the idle callback.
Definition scheduler.h:244
bool scheduler_is_running() const
Get the running state for the scheduler.
Definition scheduler.h:268
Base exception class for scheduler.
Definition scheduler.h:49
'No tasks' exception.
Definition scheduler.h:62
'Null tasks' exception.
Definition scheduler.h:75
'Too many tasks' exception.
Definition scheduler.h:88
Scheduler.
Definition scheduler.h:358
void start()
Start the scheduler.
Definition scheduler.h:374
Task.
Definition task.h:59
virtual void on_task_added()
Called when the task has been added to the scheduler.
Definition task.h:92
virtual uint32_t task_request_work() const =0
etl::task_priority_t get_task_priority() const
Definition task.h:117
virtual void task_process_work()=0
Called to get the task to do work.
#define ETL_ASSERT(b, e)
Definition error_handler.h:316
Definition exception.h:47
iterator begin()
Definition vector.h:100
iterator end()
Definition vector.h:118
bool full() const
Definition vector.h:996
iterator insert(const_iterator position, const_reference value)
Definition vector.h:579
bitset_ext
Definition absolute.h:38
ETL_DEPRECATED typedef scheduler_policy_sequential_multiple scheduler_policy_sequencial_multiple
Typedef for backwards compatibility with miss-spelt struct name.
Definition scheduler.h:153
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1187
pair holds two objects of arbitrary type
Definition utility.h:164
Definition scheduler.h:161
Definition scheduler.h:194
Definition scheduler.h:103