8#include "unfair_recursive_mutex.hpp"
10#include "global_state.hpp"
23inline std::vector<void (*)()> subsystem_deinit_list;
29inline unfair_recursive_mutex subsystem_mutex;
32requires(is_atomic_v<T>) tt_no_inline
typename T::value_type start_subsystem(
34 typename T::value_type off_value,
35 typename T::value_type (*init_function)(),
36 void (*deinit_function)())
38 ttlet
lock = std::scoped_lock(subsystem_mutex);
40 auto old_value = check_variable.load(std::memory_order::acquire);
41 if (old_value != off_value) {
46 if (not is_system_running()) {
52 auto new_value = init_function();
54 if (new_value != off_value) {
55 subsystem_deinit_list.emplace_back(deinit_function);
56 check_variable.store(new_value, std::memory_order::release);
62tt_no_inline
inline bool start_subsystem(global_state_type state_bit,
bool (*init_function)(),
void (*deinit_function)())
64 tt_axiom(std::popcount(to_underlying(state_bit)) == 1);
65 ttlet
lock = std::scoped_lock(subsystem_mutex);
67 ttlet old_state = global_state.load(std::memory_order::acquire);
68 if (not is_system_running(old_state)) {
73 }
else if (to_bool(old_state & state_bit)) {
78 if (init_function()) {
79 subsystem_deinit_list.emplace_back(deinit_function);
80 global_state_enable(state_bit, std::memory_order::release);
103requires(is_atomic_v<T>)
typename T::value_type start_subsystem(
105 typename T::value_type off_value,
106 typename T::value_type (*init_function)(),
107 void (*deinit_function)())
112 auto old_value = check_variable.load(std::memory_order::relaxed);
113 if (old_value == off_value) {
114 return detail::start_subsystem(check_variable, off_value, init_function, deinit_function);
116 [[likely]]
return old_value;
132inline bool start_subsystem(global_state_type state_bit,
bool (*init_function)(),
void (*deinit_function)())
137 if (not to_bool(global_state.load(std::memory_order::relaxed) & state_bit)) {
138 return detail::start_subsystem(state_bit, init_function, deinit_function);
140 [[likely]]
return true;
161requires(is_atomic_v<T>)
typename T::value_type start_subsystem_or_terminate(
163 typename T::value_type off_value,
164 typename T::value_type (*init_function)(),
165 void (*deinit_function)())
167 auto old_value = check_variable.load(std::memory_order::acquire);
168 if (old_value == off_value) {
169 auto tmp = detail::start_subsystem(check_variable, off_value, init_function, deinit_function);
170 tt_assert(tmp != off_value);
173 [[likely]]
return old_value;
184inline void stop_subsystem(
void (*deinit_function)())
186 ttlet
lock = std::scoped_lock(detail::subsystem_mutex);
188 std::erase(detail::subsystem_deinit_list, deinit_function);
189 return deinit_function();
195inline void start_system() noexcept
197 global_state |= global_state_type::system_is_running;
206inline void shutdown_system() noexcept
208 detail::subsystem_mutex.lock();
209 global_state |= global_state_type::system_is_shutting_down;
211 while (!detail::subsystem_deinit_list.empty()) {
212 auto deinit =
std::move(detail::subsystem_deinit_list.back());
213 detail::subsystem_deinit_list.pop_back();
215 detail::subsystem_mutex.unlock();
217 detail::subsystem_mutex.lock();
219 detail::subsystem_mutex.unlock();