mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
refactor(subsystems&ime): RAII lifecycle
This commit is contained in:
@@ -35,7 +35,7 @@ static std::string BuildFatalReport(const char* title, std::string_view text, co
|
||||
|
||||
static int DbgReport(const char* title, std::string_view text, const char* file, int line) {
|
||||
Log::WriteFatal(BuildFatalReport(title, text, file, line));
|
||||
SubsystemsListSingleton::Instance()->ShutdownAll();
|
||||
Subsystems::EmergencyShutdownActive();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
#include "common/commonSubsystem.h"
|
||||
|
||||
#include "common/byteBuffer.h" // IWYU pragma: associated
|
||||
#include "common/common.h" // IWYU pragma: associated
|
||||
#include "common/debug.h" // IWYU pragma: associated
|
||||
#include "common/hash.h" // IWYU pragma: associated
|
||||
#include "common/magicEnum.h" // IWYU pragma: associated
|
||||
#include "common/singleton.h" // IWYU pragma: associated
|
||||
#include "common/virtualMemory.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
KYTY_SUBSYSTEM_INIT(Common) {
|
||||
VirtualMemory::Init();
|
||||
}
|
||||
|
||||
KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(Common) {}
|
||||
|
||||
KYTY_SUBSYSTEM_DESTROY(Common) {}
|
||||
|
||||
} // namespace Common
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef KYTY_COMMON_COMMON_SUBSYSTEM_H_
|
||||
#define KYTY_COMMON_COMMON_SUBSYSTEM_H_
|
||||
|
||||
#include "common/subsystems.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
KYTY_SUBSYSTEM_DEFINE(Common);
|
||||
|
||||
} // namespace Common
|
||||
|
||||
#endif /* KYTY_COMMON_COMMON_SUBSYSTEM_H_ */
|
||||
@@ -9,15 +9,15 @@ namespace Config {
|
||||
|
||||
static std::unique_ptr<ConfigOptions> g_config;
|
||||
|
||||
KYTY_SUBSYSTEM_INIT(Config) {
|
||||
void Initialize() {
|
||||
EXIT_IF(g_config != nullptr);
|
||||
|
||||
g_config = std::make_unique<ConfigOptions>();
|
||||
}
|
||||
|
||||
KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(Config) {}
|
||||
|
||||
KYTY_SUBSYSTEM_DESTROY(Config) {}
|
||||
void Shutdown() {
|
||||
g_config.reset();
|
||||
}
|
||||
|
||||
void Load(const ConfigOptions& cfg) {
|
||||
EXIT_IF(g_config == nullptr);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define KYTY_COMMON_EMULATOR_CONFIG_H_
|
||||
|
||||
#include "common/common.h"
|
||||
#include "common/subsystems.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
@@ -10,7 +9,14 @@
|
||||
|
||||
namespace Config {
|
||||
|
||||
KYTY_SUBSYSTEM_DEFINE(Config);
|
||||
void Initialize();
|
||||
void Shutdown();
|
||||
|
||||
struct Lifecycle {
|
||||
static constexpr const char* name = "Config";
|
||||
static constexpr auto initialize = Config::Initialize;
|
||||
static constexpr auto shutdown = Config::Shutdown;
|
||||
};
|
||||
|
||||
enum class ShaderOptimizationType { None, Size, Performance };
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ void WriteFatal(fmt::text_style style, std::string_view text) {
|
||||
Flush();
|
||||
}
|
||||
|
||||
KYTY_SUBSYSTEM_INIT(Log) {
|
||||
void Initialize() {
|
||||
g_initialized = true;
|
||||
switch (Config::GetPrintfDirection()) {
|
||||
case Config::OutputDirection::Silent: g_direction = Direction::Silent; break;
|
||||
@@ -161,13 +161,7 @@ KYTY_SUBSYSTEM_INIT(Log) {
|
||||
SetupLogger();
|
||||
}
|
||||
|
||||
KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(Log) {
|
||||
Flush();
|
||||
std::lock_guard lock(g_logger_mutex);
|
||||
g_logger.reset();
|
||||
}
|
||||
|
||||
KYTY_SUBSYSTEM_DESTROY(Log) {
|
||||
void Shutdown() {
|
||||
Flush();
|
||||
std::lock_guard lock(g_logger_mutex);
|
||||
g_logger.reset();
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define KYTY_COMMON_LOGGING_LOG_H_
|
||||
|
||||
#include "common/common.h"
|
||||
#include "common/subsystems.h"
|
||||
|
||||
#include <fmt/color.h>
|
||||
#include <fmt/printf.h>
|
||||
@@ -10,7 +9,15 @@
|
||||
|
||||
namespace Log {
|
||||
|
||||
KYTY_SUBSYSTEM_DEFINE(Log);
|
||||
void Initialize();
|
||||
void Shutdown();
|
||||
|
||||
struct Lifecycle {
|
||||
static constexpr const char* name = "Log";
|
||||
static constexpr auto initialize = Log::Initialize;
|
||||
static constexpr auto shutdown = Log::Shutdown;
|
||||
static constexpr auto emergency_shutdown = Log::Shutdown;
|
||||
};
|
||||
|
||||
enum class Direction { Silent, Console, File };
|
||||
|
||||
|
||||
+5
-14
@@ -1,7 +1,6 @@
|
||||
#include "common/profiler.h"
|
||||
|
||||
#include "common/emulatorConfig.h"
|
||||
#include "common/subsystems.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <common/TracyProtocol.hpp>
|
||||
@@ -55,13 +54,7 @@ void SetThreadName(const char* name) {
|
||||
}
|
||||
}
|
||||
|
||||
void Close() {
|
||||
if (tracy::ProfilerAvailable()) {
|
||||
tracy::ShutdownProfiler();
|
||||
}
|
||||
}
|
||||
|
||||
KYTY_SUBSYSTEM_INIT(Profiler) {
|
||||
void Initialize() {
|
||||
switch (Config::GetProfilerDirection()) {
|
||||
case Config::ProfilerDirection::Network:
|
||||
if (!tracy::ProfilerAvailable()) {
|
||||
@@ -78,12 +71,10 @@ KYTY_SUBSYSTEM_INIT(Profiler) {
|
||||
}
|
||||
}
|
||||
|
||||
KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(Profiler) {
|
||||
Close();
|
||||
}
|
||||
|
||||
KYTY_SUBSYSTEM_DESTROY(Profiler) {
|
||||
Close();
|
||||
void Shutdown() {
|
||||
if (tracy::ProfilerAvailable()) {
|
||||
tracy::ShutdownProfiler();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Profiler
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define KYTY_COMMON_PROFILER_H_
|
||||
|
||||
#include "common/common.h"
|
||||
#include "common/subsystems.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
@@ -42,7 +41,15 @@ private:
|
||||
void EndBlock();
|
||||
void SetThreadName(const char* name);
|
||||
|
||||
KYTY_SUBSYSTEM_DEFINE(Profiler);
|
||||
void Initialize();
|
||||
void Shutdown();
|
||||
|
||||
struct Lifecycle {
|
||||
static constexpr const char* name = "Profiler";
|
||||
static constexpr auto initialize = Profiler::Initialize;
|
||||
static constexpr auto shutdown = Profiler::Shutdown;
|
||||
static constexpr auto emergency_shutdown = Profiler::Shutdown;
|
||||
};
|
||||
|
||||
} // namespace Profiler
|
||||
|
||||
|
||||
+25
-214
@@ -1,232 +1,43 @@
|
||||
#include "common/subsystems.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace Common {
|
||||
|
||||
class SubsystemPrivate {
|
||||
public:
|
||||
SubsystemPrivate() = default;
|
||||
virtual ~SubsystemPrivate() = default;
|
||||
static Subsystems* g_active_subsystems = nullptr;
|
||||
|
||||
KYTY_CLASS_NO_COPY(SubsystemPrivate);
|
||||
Subsystems::Subsystems(bool print): m_print(print) {
|
||||
m_active.reserve(16);
|
||||
g_active_subsystems = this;
|
||||
}
|
||||
|
||||
bool failed {false};
|
||||
std::string fail_msg;
|
||||
};
|
||||
|
||||
class SubsystemsListPrivate {
|
||||
public:
|
||||
explicit SubsystemsListPrivate(SubsystemsList& p): parent(p) {}
|
||||
|
||||
virtual ~SubsystemsListPrivate() = default;
|
||||
|
||||
void SetArgs(int argc, char** argv) {
|
||||
this->m_argc = argc;
|
||||
this->m_argv = argv;
|
||||
Subsystems::~Subsystems() {
|
||||
Destroy();
|
||||
if (g_active_subsystems == this) {
|
||||
g_active_subsystems = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Add(Subsystem* s, std::initializer_list<Subsystem*> deps) {
|
||||
EXIT_IF(!s);
|
||||
|
||||
const char* name = s->Id();
|
||||
|
||||
EXIT_IF(FindByName(name) != nullptr);
|
||||
|
||||
auto nl = std::make_unique<SubsListStruct>();
|
||||
|
||||
nl->s = s;
|
||||
nl->name = name;
|
||||
nl->deps = nullptr;
|
||||
nl->next = std::move(list);
|
||||
nl->prev_init = nullptr;
|
||||
|
||||
auto* node = nl.get();
|
||||
list = std::move(nl);
|
||||
|
||||
for (auto* dep: deps) {
|
||||
const char* str = dep->Id();
|
||||
|
||||
auto l = std::make_unique<DepsListStruct>();
|
||||
l->dep_name = str;
|
||||
l->next = std::move(node->deps);
|
||||
|
||||
node->deps = std::move(l);
|
||||
void Subsystems::Destroy() {
|
||||
for (auto it = m_active.rbegin(); it != m_active.rend(); ++it) {
|
||||
if (it->shutdown != nullptr) {
|
||||
it->shutdown();
|
||||
}
|
||||
|
||||
node->initialized = false;
|
||||
}
|
||||
m_active.clear();
|
||||
}
|
||||
|
||||
bool InitAll(bool print_msg) {
|
||||
while (SubsListStruct* n = FindNextToInitialize()) {
|
||||
n->s->Init(&parent);
|
||||
|
||||
if (n->s->m_p->failed) {
|
||||
fail_msg = n->s->m_p->fail_msg.c_str();
|
||||
fail_name = n->name;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (print_msg) {
|
||||
printf("Initialized: %s\n", n->name);
|
||||
}
|
||||
|
||||
n->initialized = true;
|
||||
|
||||
SubsListStruct* last = last_init;
|
||||
last_init = n;
|
||||
n->prev_init = last;
|
||||
void Subsystems::EmergencyShutdown() {
|
||||
for (auto it = m_active.rbegin(); it != m_active.rend(); ++it) {
|
||||
if (it->emergency_shutdown != nullptr) {
|
||||
it->emergency_shutdown();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
m_active.clear();
|
||||
}
|
||||
|
||||
void DestroyAll(bool print_msg) {
|
||||
for (SubsListStruct* n = last_init; n != nullptr; n = n->prev_init) {
|
||||
n->s->Destroy(&parent);
|
||||
n->initialized = false;
|
||||
|
||||
if (print_msg) {
|
||||
printf("Destroyed: %s\n", n->name);
|
||||
}
|
||||
}
|
||||
|
||||
last_init = nullptr;
|
||||
void Subsystems::EmergencyShutdownActive() {
|
||||
if (g_active_subsystems != nullptr) {
|
||||
g_active_subsystems->EmergencyShutdown();
|
||||
}
|
||||
|
||||
void ShutdownAll() {
|
||||
for (SubsListStruct* n = last_init; n != nullptr; n = n->prev_init) {
|
||||
n->s->UnexpectedShutdown(&parent);
|
||||
n->initialized = false;
|
||||
}
|
||||
|
||||
last_init = nullptr;
|
||||
}
|
||||
|
||||
struct DepsListStruct {
|
||||
const char* dep_name;
|
||||
std::unique_ptr<DepsListStruct> next;
|
||||
};
|
||||
|
||||
struct SubsListStruct {
|
||||
Subsystem* s;
|
||||
const char* name;
|
||||
std::unique_ptr<DepsListStruct> deps;
|
||||
std::unique_ptr<SubsListStruct> next;
|
||||
SubsListStruct* prev_init;
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
[[nodiscard]] SubsListStruct* FindByName(const char* name) const {
|
||||
for (SubsListStruct* n = list.get(); n != nullptr; n = n->next.get()) {
|
||||
if (std::strcmp(n->name, name) == 0) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] SubsListStruct* FindNextToInitialize() const {
|
||||
for (SubsListStruct* n = list.get(); n != nullptr; n = n->next.get()) {
|
||||
if (n->initialized) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DepsListStruct* d = n->deps.get();
|
||||
for (; d != nullptr; d = d->next.get()) {
|
||||
SubsListStruct* s = FindByName(d->dep_name);
|
||||
if ((s == nullptr) || !s->initialized) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (d == nullptr) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
KYTY_CLASS_NO_COPY(SubsystemsListPrivate);
|
||||
|
||||
std::unique_ptr<SubsListStruct> list;
|
||||
SubsListStruct* last_init = nullptr;
|
||||
int m_argc = 0;
|
||||
char** m_argv = nullptr;
|
||||
const char* fail_msg = nullptr;
|
||||
const char* fail_name = nullptr;
|
||||
SubsystemsList& parent;
|
||||
};
|
||||
|
||||
SubsystemsList::SubsystemsList(): m_p(std::make_unique<SubsystemsListPrivate>(*this)) {}
|
||||
|
||||
SubsystemsList::~SubsystemsList() = default;
|
||||
|
||||
void SubsystemsList::Add(Subsystem* s, std::initializer_list<Subsystem*> deps) {
|
||||
m_p->Add(s, deps);
|
||||
}
|
||||
|
||||
bool SubsystemsList::InitAll(bool print_msg) {
|
||||
return m_p->InitAll(print_msg);
|
||||
}
|
||||
|
||||
void SubsystemsList::DestroyAll(bool print_msg) {
|
||||
m_p->DestroyAll(print_msg);
|
||||
}
|
||||
|
||||
int* SubsystemsList::GetArgc() {
|
||||
return &m_p->m_argc;
|
||||
}
|
||||
|
||||
char** SubsystemsList::GetArgv() {
|
||||
return m_p->m_argv;
|
||||
}
|
||||
|
||||
Subsystem::Subsystem(): m_p(std::make_unique<SubsystemPrivate>()) {}
|
||||
|
||||
Subsystem::~Subsystem() = default;
|
||||
|
||||
void Subsystem::Fail(const char* format, ...) {
|
||||
va_list args {};
|
||||
va_start(args, format);
|
||||
|
||||
va_list args_copy {};
|
||||
va_copy(args_copy, args);
|
||||
int len = std::vsnprintf(nullptr, 0, format, args_copy);
|
||||
va_end(args_copy);
|
||||
|
||||
if (len > 0) {
|
||||
std::string msg(static_cast<size_t>(len) + 1, '\0');
|
||||
std::vsnprintf(msg.data(), msg.size(), format, args);
|
||||
m_p->fail_msg = msg.c_str();
|
||||
m_p->failed = true;
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
const char* SubsystemsList::GetFailName() const {
|
||||
return m_p->fail_name;
|
||||
}
|
||||
|
||||
const char* SubsystemsList::GetFailMsg() const {
|
||||
return m_p->fail_msg;
|
||||
}
|
||||
|
||||
void SubsystemsList::SetArgs(int argc, char* argv[]) {
|
||||
m_p->SetArgs(argc, argv);
|
||||
}
|
||||
|
||||
void SubsystemsList::ShutdownAll() {
|
||||
m_p->ShutdownAll();
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
|
||||
+41
-70
@@ -2,90 +2,61 @@
|
||||
#define KYTY_COMMON_SUBSYSTEMS_H_
|
||||
|
||||
#include "common/common.h"
|
||||
#include "common/singleton.h"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
namespace Common {
|
||||
|
||||
class Subsystem;
|
||||
class SubsystemsListPrivate;
|
||||
class SubsystemPrivate;
|
||||
|
||||
class SubsystemsList {
|
||||
class Subsystems {
|
||||
public:
|
||||
SubsystemsList();
|
||||
virtual ~SubsystemsList();
|
||||
void SetArgs(int argc, char* argv[]);
|
||||
using Callback = void (*)();
|
||||
|
||||
// void Add(Subsystem* s, const char* name, ...);
|
||||
void Add(Subsystem* s, std::initializer_list<Subsystem*> deps);
|
||||
explicit Subsystems(bool print = false);
|
||||
~Subsystems();
|
||||
|
||||
bool InitAll(bool print_msg = false);
|
||||
void DestroyAll(bool print_msg = false);
|
||||
template <typename Lifecycle>
|
||||
void Initialize() {
|
||||
Lifecycle::initialize();
|
||||
m_active.push_back({ShutdownCallback<Lifecycle>(), EmergencyCallback<Lifecycle>()});
|
||||
if (m_print) {
|
||||
std::printf("Initialized: %s\n", Lifecycle::name);
|
||||
}
|
||||
}
|
||||
|
||||
int* GetArgc();
|
||||
char** GetArgv();
|
||||
void Destroy();
|
||||
void EmergencyShutdown();
|
||||
|
||||
[[nodiscard]] const char* GetFailName() const;
|
||||
[[nodiscard]] const char* GetFailMsg() const;
|
||||
static void EmergencyShutdownActive();
|
||||
|
||||
void ShutdownAll();
|
||||
|
||||
static SubsystemsList* Instance() { return Common::Singleton<SubsystemsList>::Instance(); }
|
||||
|
||||
KYTY_CLASS_NO_COPY(SubsystemsList);
|
||||
KYTY_CLASS_NO_COPY(Subsystems);
|
||||
|
||||
private:
|
||||
std::unique_ptr<SubsystemsListPrivate> m_p;
|
||||
template <typename Lifecycle>
|
||||
static consteval Callback ShutdownCallback() {
|
||||
if constexpr (requires { Lifecycle::shutdown; }) {
|
||||
return Lifecycle::shutdown;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename Lifecycle>
|
||||
static consteval Callback EmergencyCallback() {
|
||||
if constexpr (requires { Lifecycle::emergency_shutdown; }) {
|
||||
return Lifecycle::emergency_shutdown;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct Entry {
|
||||
Callback shutdown;
|
||||
Callback emergency_shutdown;
|
||||
};
|
||||
|
||||
std::vector<Entry> m_active;
|
||||
bool m_print;
|
||||
};
|
||||
|
||||
using SubsystemsListSingleton = Common::Singleton<SubsystemsList>;
|
||||
|
||||
class Subsystem {
|
||||
public:
|
||||
Subsystem();
|
||||
virtual ~Subsystem();
|
||||
|
||||
virtual const char* Id() = 0;
|
||||
virtual void Init(SubsystemsList* parent) = 0;
|
||||
virtual void Destroy(SubsystemsList* parent) = 0;
|
||||
virtual void UnexpectedShutdown(SubsystemsList* parent) = 0;
|
||||
|
||||
friend class SubsystemsListPrivate;
|
||||
|
||||
KYTY_CLASS_NO_COPY(Subsystem);
|
||||
|
||||
protected:
|
||||
void Fail(const char* format, ...) KYTY_FORMAT_PRINTF(2, 3);
|
||||
|
||||
private:
|
||||
std::unique_ptr<SubsystemPrivate> m_p;
|
||||
};
|
||||
|
||||
#define KYTY_SUBSYSTEM_DEFINE(s) \
|
||||
class s##Subsystem: public Common::Subsystem { \
|
||||
public: \
|
||||
static Subsystem* Instance() { return Common::Singleton<s##Subsystem>::Instance(); } \
|
||||
const char* Id() { return #s; } \
|
||||
void Init(Common::SubsystemsList* parent); \
|
||||
void Destroy(Common::SubsystemsList* parent); \
|
||||
void UnexpectedShutdown(Common::SubsystemsList* parent); \
|
||||
}; \
|
||||
typedef Common::Singleton<s##Subsystem> s##SubsystemSingleton;
|
||||
|
||||
#define KYTY_SUBSYSTEM_INIT(s) \
|
||||
void s##Subsystem::Init([[maybe_unused]] Common::SubsystemsList* parent)
|
||||
#define KYTY_SUBSYSTEM_DESTROY(s) \
|
||||
void s##Subsystem::Destroy([[maybe_unused]] Common::SubsystemsList* parent)
|
||||
#define KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(s) \
|
||||
void s##Subsystem::UnexpectedShutdown([[maybe_unused]] Common::SubsystemsList* parent)
|
||||
|
||||
// #define KYTY_SUBSYSTEM_ADD(list, s, ...) list.push_back(s##SubsystemSingleton::Instance(), #s,
|
||||
// __VA_ARGS__); #define KYTY_SUBSYSTEM_ADD2(list, ...) list.Add2(s##SubsystemSingleton::Instance(),
|
||||
// __VA_ARGS__);
|
||||
|
||||
} // namespace Common
|
||||
|
||||
#endif /* KYTY_COMMON_SUBSYSTEMS_H_ */
|
||||
|
||||
@@ -252,15 +252,11 @@ static thread_id_t g_main_thread;
|
||||
static int g_main_thread_int;
|
||||
static std::atomic<int> g_thread_counter = 0;
|
||||
|
||||
KYTY_SUBSYSTEM_INIT(Threads) {
|
||||
void InitializeThreads() {
|
||||
g_main_thread = std::this_thread::get_id();
|
||||
g_main_thread_int = Thread::GetThreadIdUnique();
|
||||
}
|
||||
|
||||
KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(Threads) {}
|
||||
|
||||
KYTY_SUBSYSTEM_DESTROY(Threads) {}
|
||||
|
||||
Thread::Thread(thread_func_t func, void* arg)
|
||||
: m_thread(std::make_unique<ThreadPrivate>(func, arg)) {
|
||||
while (!m_thread->started) {
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
#define KYTY_COMMON_THREADS_H_
|
||||
|
||||
#include "common/common.h"
|
||||
#include "common/subsystems.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace Common {
|
||||
|
||||
KYTY_SUBSYSTEM_DEFINE(Threads);
|
||||
void InitializeThreads();
|
||||
|
||||
using thread_func_t = void (*)(void*);
|
||||
using wait_poll_func_t = void (*)();
|
||||
|
||||
Reference in New Issue
Block a user