8#include "unfair_recursive_mutex.hpp"
9#include "type_traits.hpp"
26enum class system_status_type { not_started, running, shutdown };
28inline system_status_type system_status = system_status_type::not_started;
32inline std::vector<void (*)()> subsystem_deinit_list;
38inline unfair_recursive_mutex subsystem_mutex;
40template<
typename T>
requires(is_atomic_v<T>)
41tt_no_inline
typename T::value_type start_subsystem(
43 typename T::value_type off_value,
44 typename T::value_type (*init_function)(),
45 void (*deinit_function)())
47 ttlet
lock = std::scoped_lock(subsystem_mutex);
49 auto old_value = check_variable.load(std::memory_order::acquire);
50 if (old_value != off_value) {
55 if (system_status != system_status_type::running) {
61 auto new_value = init_function();
63 if (new_value != off_value) {
64 subsystem_deinit_list.emplace_back(deinit_function);
65 check_variable.store(new_value, std::memory_order::release);
87requires(is_atomic_v<T>)
typename T::value_type start_subsystem(
89 typename T::value_type off_value,
90 typename T::value_type (*init_function)(),
91 void (*deinit_function)())
96 auto old_value = check_variable.load(std::memory_order::relaxed);
97 if (old_value == off_value) {
98 return detail::start_subsystem(check_variable, off_value, init_function, deinit_function);
100 [[likely]]
return old_value;
121requires(is_atomic_v<T>)
typename T::value_type start_subsystem_or_terminate(
123 typename T::value_type off_value,
124 typename T::value_type (*init_function)(),
125 void (*deinit_function)())
127 auto old_value = check_variable.load(std::memory_order::acquire);
128 if (old_value == off_value) {
129 auto tmp = detail::start_subsystem(check_variable, off_value, init_function, deinit_function);
130 tt_assert(tmp != off_value);
133 [[likely]]
return old_value;
144inline void stop_subsystem(
void (*deinit_function)())
146 ttlet
lock = std::scoped_lock(detail::subsystem_mutex);
148 std::erase(detail::subsystem_deinit_list, deinit_function);
149 return deinit_function();
155inline void start_system() noexcept
157 ttlet
lock = std::scoped_lock(detail::subsystem_mutex);
158 detail::system_status = detail::system_status_type::running;
161[[nodiscard]]
inline bool system_shutting_down() noexcept
163 return detail::system_status == detail::system_status_type::shutdown;
172inline void shutdown_system() noexcept
174 detail::subsystem_mutex.lock();
175 detail::system_status = detail::system_status_type::shutdown;
177 while (!detail::subsystem_deinit_list.empty()) {
178 auto deinit =
std::move(detail::subsystem_deinit_list.back());
179 detail::subsystem_deinit_list.pop_back();
181 detail::subsystem_mutex.unlock();
183 detail::subsystem_mutex.lock();
185 detail::subsystem_mutex.unlock();