11#include "../utility/utility.hpp"
14#include "../macros.hpp"
22hi_export_module(hikogui.concurrency.subsystem);
25hi_export
namespace hi {
inline namespace v1 {
39hi_no_inline
typename T::value_type start_subsystem(
41 typename T::value_type off_value,
42 typename T::value_type (*init_function)(),
43 void (*deinit_function)())
44 requires(is_atomic_v<T>)
46 hi_assert_not_null(init_function);
47 hi_assert_not_null(deinit_function);
50 auto const old_value = check_variable.load(std::memory_order::acquire);
51 if (old_value != off_value) {
62 auto new_value = init_function();
64 if (new_value != off_value) {
66 check_variable.store(new_value, std::memory_order::release);
72hi_no_inline
inline bool start_subsystem(
global_state_type state_bit,
bool (*init_function)(),
void (*deinit_function)())
74 hi_assert(std::popcount(std::to_underlying(state_bit)) == 1);
75 hi_assert_not_null(init_function);
76 hi_assert_not_null(deinit_function);
78 auto const lock = std::scoped_lock(subsystem_mutex);
80 auto const old_state =
global_state.load(std::memory_order::acquire);
86 }
else if (to_bool(old_state & state_bit)) {
91 if (init_function()) {
92 subsystem_deinit_list.emplace_back(deinit_function);
119 typename T::value_type off_value,
120 typename T::value_type (*init_function)(),
121 void (*deinit_function)())
122 requires(is_atomic_v<T>)
127 auto const old_value = check_variable.load(std::memory_order::relaxed);
128 if (old_value == off_value) {
129 return detail::start_subsystem(check_variable, off_value, init_function, deinit_function);
131 [[likely]]
return old_value;
153 if (not to_bool(
global_state.load(std::memory_order::relaxed) & state_bit)) {
154 return detail::start_subsystem(state_bit, init_function, deinit_function);
156 [[likely]]
return true;
178 requires(is_atomic_v<T>)
181 typename T::value_type off_value,
182 typename T::value_type (*init_function)(),
183 void (*deinit_function)())
185 auto old_value = check_variable.load(std::memory_order::acquire);
186 if (old_value == off_value) {
187 auto tmp = detail::start_subsystem(check_variable, off_value, init_function, deinit_function);
188 hi_assert(tmp != off_value);
191 [[likely]]
return old_value;
205 hi_assert_not_null(deinit_function);
207 auto const lock = std::scoped_lock(detail::subsystem_mutex);
209 std::erase(detail::subsystem_deinit_list, deinit_function);
210 return deinit_function();
233 detail::subsystem_mutex.lock();
234 global_state |= global_state_type::system_is_shutting_down;
236 while (!detail::subsystem_deinit_list.empty()) {
237 auto deinit =
std::move(detail::subsystem_deinit_list.back());
238 hi_assert_not_null(deinit);
239 detail::subsystem_deinit_list.pop_back();
241 detail::subsystem_mutex.unlock();
243 detail::subsystem_mutex.lock();
245 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:36
std::vector< void(*)()> subsystem_deinit_list
A list of deinit function to be called on shutdown.
Definition subsystem.hpp:30
Definition of the unfair_recursive_mutex.
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:262
bool is_system_running() noexcept
Check if the HikoGUI system is running.
Definition global_state.hpp:211
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:179
void shutdown_system() noexcept
Shutdown the system.
Definition subsystem.hpp:231
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:117
std::atomic< global_state_type > global_state
The global state of the hikogui framework.
Definition global_state.hpp:203
global_state_type
The flag-type used for global state.
Definition global_state.hpp:32
void stop_subsystem(void(*deinit_function)())
Stop a sub-system.
Definition subsystem.hpp:203
void start_system() noexcept
Start the system.
Definition subsystem.hpp:218
The HikoGUI namespace.
Definition array_generic.hpp:20
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
An unfair recursive-mutex This is a fast implementation of a recursive-mutex which does not fairly ar...
Definition unfair_recursive_mutex.hpp:42