8#include "unfair_mutex.hpp"
16enum class system_status_type : uint32_t {
17 log_level_debug = 0x01,
18 log_level_info = 0x02,
19 log_level_statistics = 0x04,
20 log_level_trace = 0x08,
21 log_level_warning = 0x10,
22 log_level_audit = 0x20,
23 log_level_error = 0x40,
24 log_level_fatal = 0x80,
31[[nodiscard]]
constexpr system_status_type operator&(system_status_type
const &lhs, system_status_type
const &rhs)
noexcept
33 return static_cast<system_status_type
>(
static_cast<uint32_t
>(lhs) &
static_cast<uint32_t
>(rhs));
36[[nodiscard]]
constexpr system_status_type operator|(system_status_type
const &lhs, system_status_type
const &rhs)
noexcept
38 return static_cast<system_status_type
>(
static_cast<uint32_t
>(lhs) |
static_cast<uint32_t
>(rhs));
41[[nodiscard]]
constexpr system_status_type operator~(system_status_type
const &rhs)
noexcept
43 return static_cast<system_status_type
>(~static_cast<uint32_t>(rhs));
46[[nodiscard]]
constexpr uint8_t to_log_level(system_status_type
const &rhs)
noexcept
48 return static_cast<uint8_t
>(rhs);
69inline unfair_mutex system_status_mutex;
70static_assert(
decltype(system_status)::is_always_lock_free);
72template<
typename InitFunc,
typename DeinitFunc>
73tt_no_inline
bool system_status_start_subsystem(system_status_type subsystem, InitFunc init_function, DeinitFunc deinit_function)
75 tt_axiom(std::popcount(
static_cast<uint32_t
>(subsystem)) == 1);
76 ttlet
lock = std::scoped_lock(system_status_mutex);
78 ttlet current_state = system_status.load();
80 if (
static_cast<bool>(current_state & system_status_type::shutdown)) {
84 if (
static_cast<bool>(current_state & subsystem)) {
88 system_status_deinit_list.emplace_back(std::forward<DeinitFunc>(deinit_function));
90 std::forward<InitFunc>(init_function)();
92 system_status.store(current_state | subsystem);
101inline void system_status_set_log_level(uint8_t log_level)
noexcept
103 ttlet
lock = std::scoped_lock(detail::system_status_mutex);
105 auto current_status =
static_cast<uint32_t
>(system_status.load());
106 current_status >>= 8;
107 current_status <<= 8;
108 current_status |= log_level;
109 system_status.store(
static_cast<system_status_type
>(current_status));
124template<
typename InitFunc,
typename DeinitFunc>
125bool system_status_start_subsystem(system_status_type subsystem, InitFunc init_function, DeinitFunc deinit_function)
127 tt_axiom(std::popcount(
static_cast<uint32_t
>(subsystem)) == 1);
129 if (!
static_cast<bool>(system_status.load(std::memory_order::relaxed) & subsystem)) {
130 [[unlikely]]
return detail::system_status_start_subsystem(subsystem, init_function, deinit_function);
143inline void system_status_shutdown() noexcept
145 detail::system_status_mutex.lock();
146 system_status = system_status | system_status_type::shutdown;
148 while (!detail::system_status_deinit_list.empty()) {
149 auto deinit =
std::move(detail::system_status_deinit_list.back());
150 detail::system_status_deinit_list.pop_back();
152 detail::system_status_mutex.unlock();
154 detail::system_status_mutex.lock();
156 detail::system_status_mutex.unlock();