blob: e9c76b98636d33f250737f7c7fa06f3a233e041d [file] [log] [blame]
Alex Perrycb7da4b2019-08-28 19:35:56 -07001#ifndef AOS_REALTIME_H_
2#define AOS_REALTIME_H_
3
Brian Silverman6a54ff32020-04-28 16:41:39 -07004#include <sched.h>
Austin Schuhde973292021-10-12 18:09:49 -07005
Philipp Schrader36d77932024-02-01 18:31:19 -08006#include <ostream>
James Kuszmaul57c2baa2020-01-19 14:52:52 -08007#include <string_view>
Alex Perrycb7da4b2019-08-28 19:35:56 -07008
Austin Schuh99f7c6a2024-06-25 22:07:44 -07009#include "absl/log/check.h"
10#include "absl/log/log.h"
11#include "absl/strings/str_format.h"
12
13// Stringifies the cpu_set_t for LOG().
14template <typename Sink>
15void AbslStringify(Sink &sink, const cpu_set_t &cpuset) {
16 sink.Append("{CPUs ");
17 bool first_found = false;
18 for (int i = 0; i < CPU_SETSIZE; ++i) {
19 if (CPU_ISSET(i, &cpuset)) {
20 if (first_found) {
21 sink.Append(", ");
22 }
23 absl::Format(&sink, "%d", i);
24 first_found = true;
25 }
26 }
27 sink.Append("}");
28}
Austin Schuhcc6070c2020-10-10 20:25:56 -070029
Alex Perrycb7da4b2019-08-28 19:35:56 -070030namespace aos {
31
32// Locks everything into memory and sets the limits. This plus InitNRT are
33// everything you need to do before SetCurrentThreadRealtimePriority will make
34// your thread RT. Called as part of ShmEventLoop::Run()
35void InitRT();
36
Alex Perrycb7da4b2019-08-28 19:35:56 -070037// Sets up this process to write core dump files.
38// This is called by Init*, but it's here for other files that want this
39// behavior without calling Init*.
40void WriteCoreDumps();
41
42void LockAllMemory();
43
James Kuszmaulb4874eb2020-01-18 17:50:35 -080044void ExpandStackSize();
45
Austin Schuh094d09b2020-11-20 23:26:52 -080046// Sets the name of the current thread.
47// This will displayed by `top -H`, dump_rtprio, and show up in logs.
48// name can have a maximum of 16 characters.
49void SetCurrentThreadName(const std::string_view name);
50
Austin Schuh9014e3b2020-11-21 14:26:07 -080051// Creates a cpu_set_t from a list of CPUs.
52inline cpu_set_t MakeCpusetFromCpus(std::initializer_list<int> cpus) {
53 cpu_set_t result;
54 CPU_ZERO(&result);
55 for (int cpu : cpus) {
56 CPU_SET(cpu, &result);
57 }
58 return result;
59}
60
Austin Schuh070019a2022-12-20 22:23:09 -080061// Returns the affinity representing all the CPUs.
62inline cpu_set_t DefaultAffinity() {
63 cpu_set_t result;
64 for (int i = 0; i < CPU_SETSIZE; ++i) {
65 CPU_SET(i, &result);
66 }
67 return result;
68}
69
Austin Schuhde973292021-10-12 18:09:49 -070070// Returns the current thread's CPU affinity.
71cpu_set_t GetCurrentThreadAffinity();
72
Austin Schuh094d09b2020-11-20 23:26:52 -080073// Sets the current thread's scheduling affinity.
74void SetCurrentThreadAffinity(const cpu_set_t &cpuset);
75
76// Everything below here needs AOS to be initialized before it will work
77// properly.
78
79// Sets the current thread's realtime priority.
80void SetCurrentThreadRealtimePriority(int priority);
81
Austin Schuh77f3f222022-06-10 16:49:21 -070082// Unsets all threads realtime priority in preparation for exploding.
83void FatalUnsetRealtimePriority();
84
Austin Schuh094d09b2020-11-20 23:26:52 -080085// Sets the current thread back down to non-realtime priority.
86void UnsetCurrentThreadRealtimePriority();
87
Austin Schuh62288252020-11-18 23:26:04 -080088// Registers our hooks which crash on RT malloc.
89void RegisterMallocHook();
90
Austin Schuhcc6070c2020-10-10 20:25:56 -070091// CHECKs that we are (or are not) running on the RT scheduler. Useful for
92// enforcing that operations which are or are not bounded shouldn't be run. This
93// works both in simulation and when running against the real target.
94void CheckRealtime();
95void CheckNotRealtime();
96
97// Marks that we are or are not running on the realtime scheduler. Returns the
98// previous state.
99//
100// Note: this shouldn't be used directly. The event loop primitives should be
101// used instead.
102bool MarkRealtime(bool realtime);
103
104// Class which restores the current RT state when destructed.
105class ScopedRealtimeRestorer {
106 public:
107 ScopedRealtimeRestorer();
108 ~ScopedRealtimeRestorer() { MarkRealtime(prior_); }
109
110 private:
111 const bool prior_;
112};
113
114// Class which marks us as on the RT scheduler until it goes out of scope.
115// Note: this shouldn't be needed for most applications.
116class ScopedRealtime {
117 public:
118 ScopedRealtime() : prior_(MarkRealtime(true)) {}
119 ~ScopedRealtime() {
120 CHECK(MarkRealtime(prior_)) << ": Priority was modified";
121 }
122
123 private:
124 const bool prior_;
125};
126
127// Class which marks us as not on the RT scheduler until it goes out of scope.
128// Note: this shouldn't be needed for most applications.
129class ScopedNotRealtime {
130 public:
131 ScopedNotRealtime() : prior_(MarkRealtime(false)) {}
132 ~ScopedNotRealtime() {
133 CHECK(!MarkRealtime(prior_)) << ": Priority was modified";
134 }
135
136 private:
137 const bool prior_;
138};
139
Alex Perrycb7da4b2019-08-28 19:35:56 -0700140} // namespace aos
141
142#endif // AOS_REALTIME_H_