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 setCurrentThreadName(const std::string &name);
|
||||
static std::string getCurrentThreadName();
|
||||
|
||||
static void collectGarbage();
|
||||
|
||||
static size_t getRunningTaskCount();
|
||||
|
@ -78,7 +78,8 @@ namespace hex {
|
||||
[[nodiscard]] std::string encodeByteString(const std::vector<u8> &bytes);
|
||||
[[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) {
|
||||
if (from < to) std::swap(from, to);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include <jthread.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#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)
|
||||
: 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());
|
||||
}
|
||||
|
||||
|
||||
void TaskManager::init() {
|
||||
const auto threadCount = std::thread::hardware_concurrency();
|
||||
|
||||
@ -235,7 +209,7 @@ namespace hex {
|
||||
std::shared_ptr<Task> 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
|
||||
@ -255,7 +229,7 @@ namespace hex {
|
||||
|
||||
try {
|
||||
// Set the thread name to the name of the task
|
||||
setThreadName(Lang(task->m_unlocalizedName));
|
||||
TaskManager::setCurrentThreadName(Lang(task->m_unlocalizedName));
|
||||
|
||||
// Execute the task
|
||||
task->m_function(*task);
|
||||
@ -391,4 +365,41 @@ namespace hex {
|
||||
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 <fmt/chrono.h>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#include <Windows.h>
|
||||
@ -72,10 +73,18 @@ namespace hex::log::impl {
|
||||
else
|
||||
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();
|
||||
fmt::print(dest, "{}", std::string(projectNameLength > 10 ? 0 : 10 - projectNameLength, ' '));
|
||||
constexpr static auto MaxTagLength = 25;
|
||||
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) {
|
||||
|
@ -550,6 +550,60 @@ namespace hex {
|
||||
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) {
|
||||
u32 sign = float16 >> 15;
|
||||
u32 exponent = (float16 >> 10) & 0x1F;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <future>
|
||||
#include <numeric>
|
||||
#include <random>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
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
|
||||
// otherwise run it in this thread and wait for it to finish
|
||||
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 {
|
||||
runTask();
|
||||
}
|
||||
@ -199,6 +203,8 @@ namespace hex::init {
|
||||
|
||||
std::future<bool> WindowSplash::processTasksAsync() {
|
||||
return std::async(std::launch::async, [this] {
|
||||
TaskManager::setCurrentThreadName("Init Tasks");
|
||||
|
||||
auto startTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
// Loop over all registered init tasks
|
||||
|
@ -246,6 +246,7 @@ namespace {
|
||||
* @return Exit code
|
||||
*/
|
||||
int main(int argc, char **argv) {
|
||||
TaskManager::setCurrentThreadName("Main");
|
||||
Window::initNative();
|
||||
crash::setupCrashHandlers();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user