impr: Include thread name in log
This commit is contained in:
parent
4668f429fb
commit
874bac7de2
@ -154,6 +154,9 @@ namespace hex {
|
|||||||
*/
|
*/
|
||||||
static void runWhenTasksFinished(const std::function<void()> &function);
|
static void runWhenTasksFinished(const std::function<void()> &function);
|
||||||
|
|
||||||
|
static void setCurrentThreadName(const std::string &name);
|
||||||
|
static std::string getCurrentThreadName();
|
||||||
|
|
||||||
static void collectGarbage();
|
static void collectGarbage();
|
||||||
|
|
||||||
static size_t getRunningTaskCount();
|
static size_t getRunningTaskCount();
|
||||||
|
@ -78,7 +78,8 @@ namespace hex {
|
|||||||
[[nodiscard]] std::string encodeByteString(const std::vector<u8> &bytes);
|
[[nodiscard]] std::string encodeByteString(const std::vector<u8> &bytes);
|
||||||
[[nodiscard]] std::vector<u8> decodeByteString(const std::string &string);
|
[[nodiscard]] std::vector<u8> decodeByteString(const std::string &string);
|
||||||
|
|
||||||
std::wstring utf8ToUtf16(const std::string& utf8);
|
[[nodiscard]] std::wstring utf8ToUtf16(const std::string& utf8);
|
||||||
|
[[nodiscard]] std::string utf16ToUtf8(const std::wstring& utf16);
|
||||||
|
|
||||||
[[nodiscard]] constexpr u64 extract(u8 from, u8 to, const std::unsigned_integral auto &value) {
|
[[nodiscard]] constexpr u64 extract(u8 from, u8 to, const std::unsigned_integral auto &value) {
|
||||||
if (from < to) std::swap(from, to);
|
if (from < to) std::swap(from, to);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <jthread.hpp>
|
#include <jthread.hpp>
|
||||||
|
#include <hex/helpers/utils.hpp>
|
||||||
|
|
||||||
#if defined(OS_WINDOWS)
|
#if defined(OS_WINDOWS)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@ -31,32 +32,6 @@ namespace hex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void setThreadName(const std::string &name) {
|
|
||||||
#if defined(OS_WINDOWS)
|
|
||||||
typedef struct tagTHREADNAME_INFO {
|
|
||||||
DWORD dwType;
|
|
||||||
LPCSTR szName;
|
|
||||||
DWORD dwThreadID;
|
|
||||||
DWORD dwFlags;
|
|
||||||
} THREADNAME_INFO;
|
|
||||||
|
|
||||||
THREADNAME_INFO info;
|
|
||||||
info.dwType = 0x1000;
|
|
||||||
info.szName = name.c_str();
|
|
||||||
info.dwThreadID = ::GetCurrentThreadId();
|
|
||||||
info.dwFlags = 0;
|
|
||||||
|
|
||||||
constexpr static DWORD MS_VC_EXCEPTION = 0x406D1388;
|
|
||||||
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), reinterpret_cast<ULONG_PTR*>(&info));
|
|
||||||
#elif defined(OS_LINUX)
|
|
||||||
pthread_setname_np(pthread_self(), name.c_str());
|
|
||||||
#elif defined(OS_WEB)
|
|
||||||
hex::unused(name);
|
|
||||||
#elif defined(OS_MACOS)
|
|
||||||
pthread_setname_np(name.c_str());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Task::Task(UnlocalizedString unlocalizedName, u64 maxValue, bool background, std::function<void(Task &)> function)
|
Task::Task(UnlocalizedString unlocalizedName, u64 maxValue, bool background, std::function<void(Task &)> function)
|
||||||
: m_unlocalizedName(std::move(unlocalizedName)), m_maxValue(maxValue), m_function(std::move(function)), m_background(background) { }
|
: m_unlocalizedName(std::move(unlocalizedName)), m_maxValue(maxValue), m_function(std::move(function)), m_background(background) { }
|
||||||
|
|
||||||
@ -222,7 +197,6 @@ namespace hex {
|
|||||||
return u32((task->getValue() * 100) / task->getMaxValue());
|
return u32((task->getValue() * 100) / task->getMaxValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TaskManager::init() {
|
void TaskManager::init() {
|
||||||
const auto threadCount = std::thread::hardware_concurrency();
|
const auto threadCount = std::thread::hardware_concurrency();
|
||||||
|
|
||||||
@ -235,7 +209,7 @@ namespace hex {
|
|||||||
std::shared_ptr<Task> task;
|
std::shared_ptr<Task> task;
|
||||||
|
|
||||||
// Set the thread name to "Idle Task" while waiting for a task
|
// Set the thread name to "Idle Task" while waiting for a task
|
||||||
setThreadName("Idle Task");
|
TaskManager::setCurrentThreadName("Idle Task");
|
||||||
|
|
||||||
{
|
{
|
||||||
// Wait for a task to be added to the queue
|
// Wait for a task to be added to the queue
|
||||||
@ -255,7 +229,7 @@ namespace hex {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Set the thread name to the name of the task
|
// Set the thread name to the name of the task
|
||||||
setThreadName(Lang(task->m_unlocalizedName));
|
TaskManager::setCurrentThreadName(Lang(task->m_unlocalizedName));
|
||||||
|
|
||||||
// Execute the task
|
// Execute the task
|
||||||
task->m_function(*task);
|
task->m_function(*task);
|
||||||
@ -391,4 +365,41 @@ namespace hex {
|
|||||||
s_tasksFinishedCallbacks.push_back(function);
|
s_tasksFinishedCallbacks.push_back(function);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TaskManager::setCurrentThreadName(const std::string &name) {
|
||||||
|
#if defined(OS_WINDOWS)
|
||||||
|
auto longName = hex::utf8ToUtf16(name);
|
||||||
|
::SetThreadDescription(::GetCurrentThread(), longName.c_str());
|
||||||
|
#elif defined(OS_LINUX)
|
||||||
|
pthread_setname_np(pthread_self(), name.c_str());
|
||||||
|
#elif defined(OS_WEB)
|
||||||
|
hex::unused(name);
|
||||||
|
#elif defined(OS_MACOS)
|
||||||
|
pthread_setname_np(name.c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TaskManager::getCurrentThreadName() {
|
||||||
|
#if defined(OS_WINDOWS)
|
||||||
|
PWSTR name;
|
||||||
|
if (SUCCEEDED(::GetThreadDescription(::GetCurrentThread(), &name))) {
|
||||||
|
auto utf8Name = hex::utf16ToUtf8(name);
|
||||||
|
LocalFree(name);
|
||||||
|
|
||||||
|
return utf8Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
#elif defined(OS_MACOS) || defined(OS_LINUX)
|
||||||
|
std::array<char, 256> name;
|
||||||
|
pthread_getname_np(pthread_self(), name.data(), name.size());
|
||||||
|
|
||||||
|
return name;
|
||||||
|
#elif defined(OS_WEB)
|
||||||
|
return "";
|
||||||
|
#else
|
||||||
|
return "";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <fmt/chrono.h>
|
#include <fmt/chrono.h>
|
||||||
|
#include <hex/api/task_manager.hpp>
|
||||||
|
|
||||||
#if defined(OS_WINDOWS)
|
#if defined(OS_WINDOWS)
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
@ -72,10 +73,18 @@ namespace hex::log::impl {
|
|||||||
else
|
else
|
||||||
fmt::print(dest, ts, "{0} ", level);
|
fmt::print(dest, ts, "{0} ", level);
|
||||||
|
|
||||||
fmt::print(dest, "[{0}] ", projectName);
|
std::string projectThreadTag = projectName;
|
||||||
|
if (auto threadName = TaskManager::getCurrentThreadName(); !threadName.empty())
|
||||||
|
projectThreadTag += fmt::format("|{0}", threadName);
|
||||||
|
|
||||||
auto projectNameLength = std::string_view(projectName).length();
|
constexpr static auto MaxTagLength = 25;
|
||||||
fmt::print(dest, "{}", std::string(projectNameLength > 10 ? 0 : 10 - projectNameLength, ' '));
|
if (projectThreadTag.length() > MaxTagLength)
|
||||||
|
projectThreadTag.resize(MaxTagLength);
|
||||||
|
|
||||||
|
fmt::print(dest, "[{0}] ", projectThreadTag);
|
||||||
|
|
||||||
|
const auto projectNameLength = projectThreadTag.length();
|
||||||
|
fmt::print(dest, "{0}", std::string(projectNameLength > MaxTagLength ? 0 : MaxTagLength - projectNameLength, ' '));
|
||||||
}
|
}
|
||||||
|
|
||||||
void assertionHandler(bool expr, const char* exprString, const char* file, int line) {
|
void assertionHandler(bool expr, const char* exprString, const char* file, int line) {
|
||||||
|
@ -550,6 +550,60 @@ namespace hex {
|
|||||||
return utf16;
|
return utf16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string utf16ToUtf8(const std::wstring& utf16) {
|
||||||
|
std::vector<u32> unicodes;
|
||||||
|
|
||||||
|
for (size_t index = 0; index < utf16.size();) {
|
||||||
|
u32 unicode = 0;
|
||||||
|
|
||||||
|
wchar_t wch = utf16[index];
|
||||||
|
index += 1;
|
||||||
|
|
||||||
|
if (wch < 0xD800 || wch > 0xDFFF) {
|
||||||
|
unicode = static_cast<u32>(wch);
|
||||||
|
} else if (wch >= 0xD800 && wch <= 0xDBFF) {
|
||||||
|
if (index == utf16.size())
|
||||||
|
return "";
|
||||||
|
|
||||||
|
wchar_t nextWch = utf16[index];
|
||||||
|
index += 1;
|
||||||
|
|
||||||
|
if (nextWch < 0xDC00 || nextWch > 0xDFFF)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
unicode = static_cast<u32>(((wch - 0xD800) << 10) + (nextWch - 0xDC00) + 0x10000);
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
unicodes.push_back(unicode);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string utf8;
|
||||||
|
|
||||||
|
for (auto unicode : unicodes) {
|
||||||
|
if (unicode <= 0x7F) {
|
||||||
|
utf8 += static_cast<char>(unicode);
|
||||||
|
} else if (unicode <= 0x7FF) {
|
||||||
|
utf8 += static_cast<char>(0xC0 | ((unicode >> 6) & 0x1F));
|
||||||
|
utf8 += static_cast<char>(0x80 | (unicode & 0x3F));
|
||||||
|
} else if (unicode <= 0xFFFF) {
|
||||||
|
utf8 += static_cast<char>(0xE0 | ((unicode >> 12) & 0x0F));
|
||||||
|
utf8 += static_cast<char>(0x80 | ((unicode >> 6) & 0x3F));
|
||||||
|
utf8 += static_cast<char>(0x80 | (unicode & 0x3F));
|
||||||
|
} else if (unicode <= 0x10FFFF) {
|
||||||
|
utf8 += static_cast<char>(0xF0 | ((unicode >> 18) & 0x07));
|
||||||
|
utf8 += static_cast<char>(0x80 | ((unicode >> 12) & 0x3F));
|
||||||
|
utf8 += static_cast<char>(0x80 | ((unicode >> 6) & 0x3F));
|
||||||
|
utf8 += static_cast<char>(0x80 | (unicode & 0x3F));
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return utf8;
|
||||||
|
}
|
||||||
|
|
||||||
float float16ToFloat32(u16 float16) {
|
float float16ToFloat32(u16 float16) {
|
||||||
u32 sign = float16 >> 15;
|
u32 sign = float16 >> 15;
|
||||||
u32 exponent = (float16 >> 10) & 0x1F;
|
u32 exponent = (float16 >> 10) & 0x1F;
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <future>
|
#include <future>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
#include <hex/api/task_manager.hpp>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
using namespace std::literals::chrono_literals;
|
using namespace std::literals::chrono_literals;
|
||||||
@ -191,7 +192,10 @@ namespace hex::init {
|
|||||||
// If the task can be run asynchronously, run it in a separate thread
|
// If the task can be run asynchronously, run it in a separate thread
|
||||||
// otherwise run it in this thread and wait for it to finish
|
// otherwise run it in this thread and wait for it to finish
|
||||||
if (task.async) {
|
if (task.async) {
|
||||||
std::thread([runTask = std::move(runTask)]{ runTask(); }).detach();
|
std::thread([name = task.name, runTask = std::move(runTask)] {
|
||||||
|
TaskManager::setCurrentThreadName(name);
|
||||||
|
runTask();
|
||||||
|
}).detach();
|
||||||
} else {
|
} else {
|
||||||
runTask();
|
runTask();
|
||||||
}
|
}
|
||||||
@ -199,6 +203,8 @@ namespace hex::init {
|
|||||||
|
|
||||||
std::future<bool> WindowSplash::processTasksAsync() {
|
std::future<bool> WindowSplash::processTasksAsync() {
|
||||||
return std::async(std::launch::async, [this] {
|
return std::async(std::launch::async, [this] {
|
||||||
|
TaskManager::setCurrentThreadName("Init Tasks");
|
||||||
|
|
||||||
auto startTime = std::chrono::high_resolution_clock::now();
|
auto startTime = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
// Loop over all registered init tasks
|
// Loop over all registered init tasks
|
||||||
|
@ -246,6 +246,7 @@ namespace {
|
|||||||
* @return Exit code
|
* @return Exit code
|
||||||
*/
|
*/
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
TaskManager::setCurrentThreadName("Main");
|
||||||
Window::initNative();
|
Window::initNative();
|
||||||
crash::setupCrashHandlers();
|
crash::setupCrashHandlers();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user