µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
os-sched.h
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ distribution.
3 * (https://github.com/micro-os-plus)
4 * Copyright (c) 2016 Liviu Ionescu.
5 *
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use,
10 * copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following
13 * conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28#ifndef CMSIS_PLUS_RTOS_OS_SCHED_H_
29#define CMSIS_PLUS_RTOS_OS_SCHED_H_
30
31// ----------------------------------------------------------------------------
32
33#if defined(__cplusplus)
34
35// ----------------------------------------------------------------------------
36
39
40// ----------------------------------------------------------------------------
41
42#pragma GCC diagnostic push
43
44#if defined(__clang__)
45#pragma clang diagnostic ignored "-Wc++98-compat"
46#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
47#endif
48
49// ----------------------------------------------------------------------------
50
51namespace os
52{
53 namespace rtos
54 {
55 namespace scheduler
56 {
57
65 extern bool is_started_;
66
67#if !defined(OS_USE_RTOS_PORT_SCHEDULER)
68 extern bool is_preemptive_;
69 extern thread* volatile current_thread_;
70 extern internal::ready_threads_list ready_threads_list_;
71#endif /* !defined(OS_USE_RTOS_PORT_SCHEDULER) */
72
73 extern internal::terminated_threads_list terminated_threads_list_;
74
87 initialize (void);
88
96 [[noreturn]] void
97 start (void);
98
106 bool
107 started (void);
108
115 state_t
116 lock (void);
117
124 state_t
125 unlock (void);
126
132 state_t
133 locked (state_t state);
134
142 bool
143 locked (void);
144
152 bool
153 preemptive (void);
154
160 bool
161 preemptive (bool state);
162
163 // ----------------------------------------------------------------------
164
169 void
170 internal_switch_threads (void);
171
176 // ======================================================================
182 {
183 public:
184
196
201 // The rule of five.
202 critical_section (const critical_section&) = delete;
205 operator= (const critical_section&) = delete;
207 operator= (critical_section&&) = delete;
208
217
222 protected:
223
236 const state_t state_;
237
245 };
246
247 // ======================================================================
248
254 {
255 public:
256
268
273 // The rule of five.
274 uncritical_section (const uncritical_section&) = delete;
277 operator= (const uncritical_section&) = delete;
279 operator= (uncritical_section&&) = delete;
280
289
294 protected:
295
308 const state_t state_;
309
317 };
318
319 // ======================================================================
320
326 {
327 public:
328
339 constexpr
340 lockable ();
341
346 // The rule of five.
347 lockable (const lockable&) = delete;
348 lockable (lockable&&) = delete;
349 lockable&
350 operator= (const lockable&) = delete;
351 lockable&
352 operator= (lockable&&) = delete;
353
361 ~lockable ();
362
367 public:
368
381 void
382 lock (void);
383
390 bool
391 try_lock (void);
392
400 void
401 unlock (void);
402
407 protected:
408
421 state_t state_ = 0;
422
430 };
431
432 // ----------------------------------------------------------------------
433
437 namespace statistics
438 {
439#if defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CONTEXT_SWITCHES)
440
446 context_switches (void);
447
452 extern rtos::statistics::counter_t context_switches_;
453
458#endif /* defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CONTEXT_SWITCHES) */
459
460#if defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CPU_CYCLES)
461
468 cpu_cycles (void);
469
474 extern clock::timestamp_t switch_timestamp_;
475 extern rtos::statistics::duration_t cpu_cycles_;
476
481#endif /* defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CPU_CYCLES) */
482
483#if defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CONTEXT_SWITCHES) \
484 || defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CPU_CYCLES)
485
492 cpu_cycles (void);
493
494#endif /* defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CONTEXT_SWITCHES) \
495 || defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CPU_CYCLES) */
496
497 } /* namespace statistics */
498 } /* namespace scheduler */
499
500 namespace interrupts
501 {
509 bool
510 in_handler_mode (void);
511
512 // ======================================================================
513
514 // TODO: define all levels of critical sections
515 // (kernel, real-time(level), complete)
516
517 // TODO: make template, parameter IRQ level
518
524 {
525 public:
526
538
543 // The rule of five.
544 critical_section (const critical_section&) = delete;
547 operator= (const critical_section&) = delete;
549 operator= (critical_section&&) = delete;
550
559
564 public:
565
577 static state_t
578 enter (void);
579
586 static void
587 exit (state_t state);
588
593 protected:
594
607 const state_t state_;
608
616 };
617
618 // ======================================================================
619
625 {
626 public:
627
639
644 // The rule of five.
645 uncritical_section (const uncritical_section&) = delete;
648 operator= (const uncritical_section&) = delete;
650 operator= (uncritical_section&&) = delete;
651
660
665 public:
666
678 static state_t
679 enter (void);
680
687 static void
688 exit (state_t state);
689
694 protected:
695
708 const state_t state_;
709
717 };
718
719 // ======================================================================
720
726 {
727 public:
728
739 constexpr
740 lockable ();
741
745 ~lockable ();
746
751 // The rule of five.
752 lockable (const lockable&) = delete;
753 lockable (lockable&&) = delete;
754 lockable&
755 operator= (const lockable&) = delete;
756 lockable&
757 operator= (lockable&&) = delete;
758
767 public:
768
781 void
782 lock (void);
783
790 bool
791 try_lock (void);
792
800 void
801 unlock (void);
802
807 protected:
808
821 state_t state_;
822
831 };
832
833 } /* namespace interrupts */
834 } /* namespace rtos */
835} /* namespace os */
836
837// ===== Inline & template implementations ====================================
838
839namespace os
840{
841 namespace rtos
842 {
843 namespace scheduler
844 {
852 inline bool
853 started (void)
854 {
855 return is_started_;
856 }
857
864 inline bool
866 {
867#if !defined(OS_USE_RTOS_PORT_SCHEDULER)
868 return is_preemptive_;
869#else
871#endif
872 }
873
881 inline bool
882 locked (void)
883 {
884 return port::scheduler::locked ();
885 }
886
894 inline state_t
895 lock (void)
896 {
897 return port::scheduler::lock ();
898 }
899
907 inline state_t
908 unlock (void)
909 {
910 return port::scheduler::unlock ();
911 }
912
924 inline state_t
926 {
927 return port::scheduler::locked (state);
928 }
929
936 inline
938 state_ (lock ())
939 {
940#if defined(OS_TRACE_RTOS_SCHEDULER)
941 trace::printf (" {c ");
942#endif
943 }
944
952 inline
954 {
955#if defined(OS_TRACE_RTOS_SCHEDULER)
956 trace::printf (" c} ");
957#endif
958 locked (state_);
959 }
960
967 inline
969 state_ (unlock ())
970 {
971#if defined(OS_TRACE_RTOS_SCHEDULER)
972 trace::printf (" {u ");
973#endif
974 }
975
983 inline
985 {
986#if defined(OS_TRACE_RTOS_SCHEDULER)
987 trace::printf (" u} ");
988#endif
989 locked (state_);
990 }
991
995 constexpr
997 state_ (port::scheduler::state::init)
998 {
999 ;
1000 }
1001
1005 inline
1007 {
1008 ;
1009 }
1010
1014 inline void
1016 {
1017 state_ = scheduler::lock ();
1018 }
1019
1027 inline bool
1029 {
1030 state_ = scheduler::lock ();
1031 return true;
1032 }
1033
1037 inline void
1039 {
1040 scheduler::locked (state_);
1041 }
1042
1043 namespace statistics
1044 {
1045#if defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CONTEXT_SWITCHES)
1046
1063 {
1064 return context_switches_;
1065 }
1066
1067#endif /* defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CONTEXT_SWITCHES) */
1068
1069#if defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CPU_CYCLES)
1070
1088 {
1089 return cpu_cycles_;
1090 }
1091
1092#endif /* defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CPU_CYCLES) */
1093
1094#if defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CONTEXT_SWITCHES) \
1095 || defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CPU_CYCLES)
1096
1109 inline void
1110 clear (void) {
1111#if defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CONTEXT_SWITCHES)
1112 context_switches_ = 0;
1113#endif /* defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CONTEXT_SWITCHES) */
1114
1115#if defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CPU_CYCLES)
1116 cpu_cycles_ = 0;
1117#endif /* defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CPU_CYCLES) */
1118 }
1119
1120#endif /* defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CONTEXT_SWITCHES) \
1121 || defined(OS_INCLUDE_RTOS_STATISTICS_THREAD_CPU_CYCLES) */
1122
1123 } /* namespace statistics */
1124
1125 } /* namespace scheduler */
1126
1127 // ========================================================================
1128
1129 namespace interrupts
1130 {
1134 inline bool
1135 __attribute__((always_inline))
1137 {
1139 }
1140
1144 inline
1145 __attribute__((always_inline))
1147 state_ (enter ())
1148 {
1149 ;
1150 }
1151
1155 inline
1156 __attribute__((always_inline))
1158 {
1159 exit (state_);
1160 }
1161
1165 inline state_t
1166 __attribute__((always_inline))
1167 critical_section::enter (void)
1168 {
1170 }
1171
1175 inline void
1176 __attribute__((always_inline))
1178 {
1180 }
1181
1182 // ======================================================================
1183
1187 inline
1188 __attribute__((always_inline))
1190 state_ (enter ())
1191 {
1192 ;
1193 }
1194
1198 inline
1199 __attribute__((always_inline))
1201 {
1202 exit (state_);
1203 }
1204
1208 inline state_t
1209 __attribute__((always_inline))
1211 {
1213 }
1214
1218 inline void
1219 __attribute__((always_inline))
1221 {
1223 }
1224
1225 // ======================================================================
1226
1230 constexpr
1232 state_ (port::interrupts::state::init)
1233 {
1234 ;
1235 }
1236
1240 inline
1241 __attribute__((always_inline))
1243 {
1244 ;
1245 }
1246
1250 inline void
1251 __attribute__((always_inline))
1252 lockable::lock (void)
1253 {
1254 state_ = critical_section::enter ();
1255 }
1256
1264 inline bool
1265 __attribute__((always_inline))
1266 lockable::try_lock (void)
1267 {
1268 state_ = critical_section::enter ();
1269 return true;
1270 }
1271
1275 inline void
1276 __attribute__((always_inline))
1277 lockable::unlock (void)
1278 {
1279 critical_section::exit (state_);
1280 }
1281
1282 // ========================================================================
1283 }
1284
1285 } /* namespace rtos */
1286} /* namespace os */
1287
1288#pragma GCC diagnostic pop
1289
1290// ----------------------------------------------------------------------------
1291
1292#endif /* __cplusplus */
1293
1294// ----------------------------------------------------------------------------
1295
1296#endif /* CMSIS_PLUS_RTOS_OS_SCHED_H_ */
Interrupts critical section RAII helper.
Definition os-sched.h:524
critical_section()
Enter an interrupts critical section.
Definition os-sched.h:1146
static void exit(state_t state)
Exit the interrupts critical section.
Definition os-sched.h:1177
~critical_section()
Exit the interrupts critical section.
Definition os-sched.h:1157
static state_t enter(void)
Enter an interrupts critical section.
Definition os-sched.h:1167
Interrupts standard locker.
Definition os-sched.h:726
void lock(void)
Lock the interrupts.
Definition os-sched.h:1252
~lockable()
Destruct the interrupts lock.
Definition os-sched.h:1242
bool try_lock(void)
Try to lock the interrupts.
Definition os-sched.h:1266
void unlock(void)
Unlock the interrupts.
Definition os-sched.h:1277
constexpr lockable()
Construct an interrupts lock.
Definition os-sched.h:1231
Interrupts critical section RAII helper.
Definition os-sched.h:625
~uncritical_section()
Exit the interrupts uncritical section.
Definition os-sched.h:1200
static state_t enter(void)
Enter interrupts uncritical section.
Definition os-sched.h:1210
static void exit(state_t state)
Exit interrupts uncritical section.
Definition os-sched.h:1220
uncritical_section()
Enter an interrupts uncritical section.
Definition os-sched.h:1189
static rtos::interrupts::state_t enter(void)
static void exit(rtos::interrupts::state_t state)
static void exit(rtos::interrupts::state_t state)
static rtos::interrupts::state_t enter(void)
Scheduler critical section RAII helper.
Definition os-sched.h:182
critical_section()
Enter a critical section.
Definition os-sched.h:937
~critical_section()
Exit a critical section.
Definition os-sched.h:953
Scheduler standard locker.
Definition os-sched.h:326
void unlock(void)
Unlock the scheduler.
Definition os-sched.h:1038
constexpr lockable()
Construct a lockable object instance.
Definition os-sched.h:996
void lock(void)
Lock the scheduler.
Definition os-sched.h:1015
~lockable()
Destruct the lockable object instance.
Definition os-sched.h:1006
bool try_lock(void)
Try to lock the scheduler.
Definition os-sched.h:1028
Scheduler uncritical section RAII helper.
Definition os-sched.h:254
uncritical_section()
Enter a critical section.
Definition os-sched.h:968
~uncritical_section()
Exit a critical section.
Definition os-sched.h:984
Standard thread.
void exit(int code)
Definition exit.c:84
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:74
port::clock::timestamp_t timestamp_t
Type of variables holding clock time stamps.
Definition os-clocks.h:92
port::interrupts::state_t state_t
Type of variables holding interrupts statu codes.
Definition os-decls.h:257
bool in_handler_mode(void)
Check if the CPU is in handler mode.
Definition os-sched.h:1136
port::scheduler::state_t unlock(void)
port::scheduler::state_t lock(void)
rtos::statistics::duration_t cpu_cycles(void)
Get the total duration of all threads.
Definition os-sched.h:1087
rtos::statistics::counter_t context_switches(void)
Get the total number of context switches.
Definition os-sched.h:1062
port::scheduler::state_t state_t
Type of variables holding scheduler state codes.
Definition os-decls.h:216
state_t unlock(void)
Unlock the scheduler.
Definition os-sched.h:908
void start(void)
Start the RTOS scheduler.
Definition os-core.cpp:190
bool started(void)
Check if the scheduler was started.
Definition os-sched.h:853
state_t lock(void)
Lock the scheduler.
Definition os-sched.h:895
result_t initialize(void)
Initialise the RTOS scheduler.
Definition os-core.cpp:161
bool preemptive(void)
Check if the scheduler is in preemptive mode.
Definition os-sched.h:865
bool locked(void)
Check if the scheduler is locked.
Definition os-sched.h:882
uint64_t duration_t
Type of variables holding durations in CPU cycles.
Definition os-decls.h:236
uint64_t counter_t
Type of variables holding context switches counters.
Definition os-decls.h:231
uint32_t result_t
Type of values returned by RTOS functions.
Definition os-decls.h:110
System namespace.