11#include "../utility/module.hpp"
21namespace hi {
inline namespace v1 {
35hi_no_inline
typename T::value_type start_subsystem(
37 typename T::value_type off_value,
38 typename T::value_type (*init_function)(),
39 void (*deinit_function)())
40 requires(is_atomic_v<T>)
46 hilet old_value = check_variable.load(std::memory_order::acquire);
47 if (old_value != off_value) {
58 auto new_value = init_function();
60 if (new_value != off_value) {
62 check_variable.store(new_value, std::memory_order::release);
68hi_no_inline
inline bool start_subsystem(
global_state_type state_bit,
bool (*init_function)(),
void (*deinit_function)())
70 hi_assert(std::popcount(to_underlying(state_bit)) == 1);
74 hilet lock = std::scoped_lock(subsystem_mutex);
82 }
else if (to_bool(old_state & state_bit)) {
87 if (init_function()) {
88 subsystem_deinit_list.emplace_back(deinit_function);
115 typename T::value_type off_value,
116 typename T::value_type (*init_function)(),
117 void (*deinit_function)())
118 requires(is_atomic_v<T>)
123 hilet old_value = check_variable.load(std::memory_order::relaxed);
124 if (old_value == off_value) {
125 return detail::start_subsystem(check_variable, off_value, init_function, deinit_function);
127 [[likely]]
return old_value;
149 if (not to_bool(
global_state.load(std::memory_order::relaxed) & state_bit)) {
150 return detail::start_subsystem(state_bit, init_function, deinit_function);
152 [[likely]]
return true;
174 requires(is_atomic_v<T>)
177 typename T::value_type off_value,
178 typename T::value_type (*init_function)(),
179 void (*deinit_function)())
181 auto old_value = check_variable.load(std::memory_order::acquire);
182 if (old_value == off_value) {
183 auto tmp = detail::start_subsystem(check_variable, off_value, init_function, deinit_function);
187 [[likely]]
return old_value;
203 hilet lock = std::scoped_lock(detail::subsystem_mutex);
205 std::erase(detail::subsystem_deinit_list, deinit_function);
206 return deinit_function();
229 detail::subsystem_mutex.lock();
230 global_state |= global_state_type::system_is_shutting_down;
232 while (!detail::subsystem_deinit_list.empty()) {
233 auto deinit =
std::move(detail::subsystem_deinit_list.back());
235 detail::subsystem_deinit_list.pop_back();
237 detail::subsystem_mutex.unlock();
239 detail::subsystem_mutex.lock();
241 detail::subsystem_mutex.unlock();
An atomic access global variable for quick access to state of the system.
unfair_recursive_mutex subsystem_mutex
Mutex to be held when writing to system_status or accessing system_status_deinit_list.
Definition subsystem.hpp:32
std::vector< void(*)()> subsystem_deinit_list
A list of deinit function to be called on shutdown.
Definition subsystem.hpp:26
Definition of the unfair_recursive_mutex.
#define hi_assert(expression,...)
Assert if expression is true.
Definition assert.hpp:199
#define hi_assert_not_null(x,...)
Assert if an expression is not nullptr.
Definition assert.hpp:238
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
bool global_state_enable(global_state_type subsystem, std::memory_order order=std::memory_order::seq_cst) noexcept
Enable a subsystem.
Definition global_state.hpp:257
bool is_system_running() noexcept
Check if the HikoGUI system is running.
Definition global_state.hpp:206
T::value_type start_subsystem_or_terminate(T &check_variable, typename T::value_type off_value, typename T::value_type(*init_function)(), void(*deinit_function)())
Start a sub-system.
Definition subsystem.hpp:175
void shutdown_system() noexcept
Shutdown the system.
Definition subsystem.hpp:227
T::value_type start_subsystem(T &check_variable, typename T::value_type off_value, typename T::value_type(*init_function)(), void(*deinit_function)())
Start a sub-system.
Definition subsystem.hpp:113
std::atomic< global_state_type > global_state
The global state of the hikogui framework.
Definition global_state.hpp:198
global_state_type
The flag-type used for global state.
Definition global_state.hpp:27
void stop_subsystem(void(*deinit_function)())
Stop a sub-system.
Definition subsystem.hpp:199
void start_system() noexcept
Start the system.
Definition subsystem.hpp:214
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
An unfair recursive-mutex This is a fast implementation of a recursive-mutex which does not fairly ar...
Definition unfair_recursive_mutex.hpp:37