1
0
mirror of synced 2024-11-28 09:30:51 +01:00

impr: Include thread name in log

This commit is contained in:
WerWolv 2024-01-09 10:39:06 +01:00
parent 4668f429fb
commit 874bac7de2
7 changed files with 119 additions and 34 deletions

View File

@ -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();

View File

@ -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);

View File

@ -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
}
}

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -246,6 +246,7 @@ namespace {
* @return Exit code
*/
int main(int argc, char **argv) {
TaskManager::setCurrentThreadName("Main");
Window::initNative();
crash::setupCrashHandlers();