Add automatically-generated names to threads
This commit is contained in:
@@ -149,6 +149,7 @@ extern uint32_t plat_language_code(char *langcode);
|
|||||||
extern void plat_language_code_r(uint32_t lcid, char *outbuf, int len);
|
extern void plat_language_code_r(uint32_t lcid, char *outbuf, int len);
|
||||||
extern void plat_get_cpu_string(char *outbuf, uint8_t len);
|
extern void plat_get_cpu_string(char *outbuf, uint8_t len);
|
||||||
extern double plat_get_dpi(void);
|
extern double plat_get_dpi(void);
|
||||||
|
extern void plat_set_thread_name(void *thread, const char *name);
|
||||||
|
|
||||||
/* Resource management. */
|
/* Resource management. */
|
||||||
extern void set_language(uint32_t id);
|
extern void set_language(uint32_t id);
|
||||||
|
@@ -28,7 +28,7 @@ extern "C" {
|
|||||||
# define event_t plat_event_t
|
# define event_t plat_event_t
|
||||||
# define mutex_t plat_mutex_t
|
# define mutex_t plat_mutex_t
|
||||||
|
|
||||||
# define thread_create plat_thread_create
|
# define thread_create_named plat_thread_create_named
|
||||||
# define thread_wait plat_thread_wait
|
# define thread_wait plat_thread_wait
|
||||||
# define thread_create_event plat_thread_create_event
|
# define thread_create_event plat_thread_create_event
|
||||||
# define thread_set_event plat_thread_set_event
|
# define thread_set_event plat_thread_set_event
|
||||||
@@ -48,7 +48,8 @@ typedef void thread_t;
|
|||||||
typedef void event_t;
|
typedef void event_t;
|
||||||
typedef void mutex_t;
|
typedef void mutex_t;
|
||||||
|
|
||||||
extern thread_t *thread_create(void (*thread_func)(void *param), void *param);
|
#define thread_create(thread_func, param) thread_create_named((thread_func), (param), #thread_func)
|
||||||
|
extern thread_t *thread_create_named(void (*thread_func)(void *param), void *param, const char *name);
|
||||||
extern int thread_wait(thread_t *arg);
|
extern int thread_wait(thread_t *arg);
|
||||||
extern event_t *thread_create_event(void);
|
extern event_t *thread_create_event(void);
|
||||||
extern void thread_set_event(event_t *arg);
|
extern void thread_set_event(event_t *arg);
|
||||||
|
@@ -94,6 +94,7 @@ main_thread_fn()
|
|||||||
int frames;
|
int frames;
|
||||||
|
|
||||||
QThread::currentThread()->setPriority(QThread::HighestPriority);
|
QThread::currentThread()->setPriority(QThread::HighestPriority);
|
||||||
|
plat_set_thread_name(NULL, "main_thread_fn");
|
||||||
framecountx = 0;
|
framecountx = 0;
|
||||||
// title_update = 1;
|
// title_update = 1;
|
||||||
old_time = elapsed_timer.elapsed();
|
old_time = elapsed_timer.elapsed();
|
||||||
|
@@ -50,6 +50,7 @@
|
|||||||
#include "qt_util.hpp"
|
#include "qt_util.hpp"
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
|
# include <pthread.h>
|
||||||
# include <sys/mman.h>
|
# include <sys/mman.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -742,3 +743,47 @@ plat_get_dpi(void)
|
|||||||
{
|
{
|
||||||
return util::screenOfWidget(main_window)->devicePixelRatio();
|
return util::screenOfWidget(main_window)->devicePixelRatio();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
plat_set_thread_name(void *thread, const char *name)
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
/* SetThreadDescription was added in 14393. Revisit if we ever start requiring 10. */
|
||||||
|
static void *kernel32_handle = NULL;
|
||||||
|
static HRESULT(WINAPI *pSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription) = NULL;
|
||||||
|
static dllimp_t kernel32_imports[] = {
|
||||||
|
// clang-format off
|
||||||
|
{ "SetThreadDescription", &pSetThreadDescription },
|
||||||
|
{ NULL, NULL }
|
||||||
|
// clang-format on
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!kernel32_handle) {
|
||||||
|
kernel32_handle = dynld_module("kernel32.dll", kernel32_imports);
|
||||||
|
if (!kernel32_handle) {
|
||||||
|
kernel32_handle = kernel32_imports; /* dummy pointer to store that we tried */
|
||||||
|
pSetThreadDescription = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSetThreadDescription) {
|
||||||
|
size_t len = strlen(name) + 1;
|
||||||
|
wchar_t wname[len];
|
||||||
|
mbstowcs(wname, name, len);
|
||||||
|
pSetThreadDescription(thread ? (HANDLE) thread : GetCurrentThread(), wname);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# ifdef Q_OS_DARWIN
|
||||||
|
char truncated[64];
|
||||||
|
# else
|
||||||
|
char truncated[16];
|
||||||
|
# endif
|
||||||
|
strncpy(truncated, name, sizeof(truncated) - 1);
|
||||||
|
# ifdef Q_OS_DARWIN
|
||||||
|
if (!thread)
|
||||||
|
pthread_setname_np(truncated);
|
||||||
|
# else
|
||||||
|
pthread_setname_np(thread ? (pthread_t) thread : pthread_self(), truncated);
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@@ -14,9 +14,10 @@ struct event_cpp11_t {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
thread_t *
|
thread_t *
|
||||||
thread_create(void (*thread_rout)(void *param), void *param)
|
thread_create_named(void (*thread_rout)(void *param), void *param, const char *name)
|
||||||
{
|
{
|
||||||
auto thread = new std::thread([thread_rout, param] {
|
auto thread = new std::thread([thread_rout, param, name] {
|
||||||
|
plat_set_thread_name(NULL, name);
|
||||||
thread_rout(param);
|
thread_rout(param);
|
||||||
});
|
});
|
||||||
return thread;
|
return thread;
|
||||||
|
@@ -45,6 +45,9 @@
|
|||||||
#include <86box/ui.h>
|
#include <86box/ui.h>
|
||||||
#include <86box/gdbstub.h>
|
#include <86box/gdbstub.h>
|
||||||
|
|
||||||
|
#define __USE_GNU 1 /* shouldn't be done, yet it is */
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
static int first_use = 1;
|
static int first_use = 1;
|
||||||
static uint64_t StartingTime;
|
static uint64_t StartingTime;
|
||||||
static uint64_t Frequency;
|
static uint64_t Frequency;
|
||||||
@@ -1379,6 +1382,23 @@ plat_get_cpu_string(char *outbuf, uint8_t len) {
|
|||||||
strncpy(outbuf, cpu_string, len);
|
strncpy(outbuf, cpu_string, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
plat_set_thread_name(void *thread, const char *name)
|
||||||
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
char truncated[64];
|
||||||
|
#else
|
||||||
|
char truncated[16];
|
||||||
|
#endif
|
||||||
|
strncpy(truncated, name, sizeof(truncated) - 1);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (!thread)
|
||||||
|
pthread_setname_np(truncated);
|
||||||
|
#else
|
||||||
|
pthread_setname_np(thread ? (pthread_t) thread : pthread_self(), truncated);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Converts back the language code to LCID */
|
/* Converts back the language code to LCID */
|
||||||
void
|
void
|
||||||
plat_language_code_r(uint32_t lcid, char *outbuf, int len)
|
plat_language_code_r(uint32_t lcid, char *outbuf, int len)
|
||||||
|
@@ -32,7 +32,7 @@ thread_run_wrapper(thread_param *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
thread_t *
|
thread_t *
|
||||||
thread_create(void (*thread_rout)(void *param), void *param)
|
thread_create(void (*thread_rout)(void *param), void *param, const char *name)
|
||||||
{
|
{
|
||||||
pthread_t *thread = malloc(sizeof(pthread_t));
|
pthread_t *thread = malloc(sizeof(pthread_t));
|
||||||
thread_param *thrparam = malloc(sizeof(thread_param));
|
thread_param *thrparam = malloc(sizeof(thread_param));
|
||||||
@@ -40,6 +40,7 @@ thread_create(void (*thread_rout)(void *param), void *param)
|
|||||||
thrparam->param = param;
|
thrparam->param = param;
|
||||||
|
|
||||||
pthread_create(thread, NULL, (void *(*) (void *) ) thread_run_wrapper, thrparam);
|
pthread_create(thread, NULL, (void *(*) (void *) ) thread_run_wrapper, thrparam);
|
||||||
|
plat_set_thread_name(thread, name);
|
||||||
|
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
@@ -51,6 +51,7 @@
|
|||||||
#include <86box/path.h>
|
#include <86box/path.h>
|
||||||
#define GLOBAL
|
#define GLOBAL
|
||||||
#include <86box/plat.h>
|
#include <86box/plat.h>
|
||||||
|
#include <86box/plat_dynld.h>
|
||||||
#include <86box/thread.h>
|
#include <86box/thread.h>
|
||||||
#include <86box/ui.h>
|
#include <86box/ui.h>
|
||||||
#ifdef USE_VNC
|
#ifdef USE_VNC
|
||||||
@@ -1276,6 +1277,35 @@ plat_get_cpu_string(char *outbuf, uint8_t len) {
|
|||||||
strncpy(outbuf, cpu_string, len);
|
strncpy(outbuf, cpu_string, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
plat_set_thread_name(void *thread, const char *name)
|
||||||
|
{
|
||||||
|
/* SetThreadDescription was added in 14393. Revisit if we ever start requiring 10. */
|
||||||
|
static void *kernel32_handle = NULL;
|
||||||
|
static HRESULT(WINAPI *pSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription) = NULL;
|
||||||
|
static dllimp_t kernel32_imports[] = {
|
||||||
|
// clang-format off
|
||||||
|
{ "SetThreadDescription", &pSetThreadDescription },
|
||||||
|
{ NULL, NULL }
|
||||||
|
// clang-format on
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!kernel32_handle) {
|
||||||
|
kernel32_handle = dynld_module("kernel32.dll", kernel32_imports);
|
||||||
|
if (!kernel32_handle) {
|
||||||
|
kernel32_handle = kernel32_imports; /* dummy pointer to store that we tried */
|
||||||
|
pSetThreadDescription = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSetThreadDescription) {
|
||||||
|
size_t len = strlen(name) + 1;
|
||||||
|
wchar_t wname[len];
|
||||||
|
mbstowcs(wname, name, len);
|
||||||
|
pSetThreadDescription(thread ? (HANDLE) thread : GetCurrentThread(), wname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
take_screenshot(void)
|
take_screenshot(void)
|
||||||
{
|
{
|
||||||
|
@@ -37,9 +37,10 @@ typedef struct {
|
|||||||
} win_event_t;
|
} win_event_t;
|
||||||
|
|
||||||
thread_t *
|
thread_t *
|
||||||
thread_create(void (*func)(void *param), void *param)
|
thread_create(void (*func)(void *param), void *param, const char *name)
|
||||||
{
|
{
|
||||||
uintptr_t bt = _beginthread(func, 0, param);
|
uintptr_t bt = _beginthread(func, 0, param);
|
||||||
|
plat_set_thread_name(bt, name);
|
||||||
return ((thread_t *) bt);
|
return ((thread_t *) bt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user