2012-03-27 21:39:13 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <windows.h>
|
2017-08-29 20:41:50 +00:00
|
|
|
#ifdef __MINGW32__
|
|
|
|
#include <excpt.h>
|
|
|
|
#endif
|
2014-06-29 10:44:07 +00:00
|
|
|
#define TLS_SUPPORTED
|
2016-10-12 09:13:16 +00:00
|
|
|
#elif defined(__ANDROID__)
|
2014-06-29 10:44:07 +00:00
|
|
|
#define TLS_SUPPORTED
|
2012-03-27 21:39:13 +00:00
|
|
|
#endif
|
2014-06-29 10:44:07 +00:00
|
|
|
|
|
|
|
#include "base/basictypes.h"
|
|
|
|
#include "base/logging.h"
|
2013-04-13 19:22:03 +00:00
|
|
|
#include "thread/threadutil.h"
|
2012-03-27 21:39:13 +00:00
|
|
|
|
2016-10-12 09:13:16 +00:00
|
|
|
#ifdef __ANDROID__
|
2015-07-19 14:21:24 +00:00
|
|
|
#include <pthread.h>
|
|
|
|
#endif
|
|
|
|
|
2014-06-29 10:44:07 +00:00
|
|
|
#ifdef TLS_SUPPORTED
|
|
|
|
static __THREAD const char *curThreadName;
|
|
|
|
#endif
|
|
|
|
|
2017-08-31 20:15:05 +00:00
|
|
|
#ifdef __MINGW32__
|
|
|
|
#include <pshpack8.h>
|
|
|
|
typedef struct {
|
|
|
|
DWORD dwType;
|
|
|
|
LPCSTR szName;
|
|
|
|
DWORD dwThreadID;
|
|
|
|
DWORD dwFlags;
|
|
|
|
} THREADNAME_INFO;
|
|
|
|
#include <poppack.h>
|
|
|
|
|
|
|
|
static EXCEPTION_DISPOSITION NTAPI ignore_handler(EXCEPTION_RECORD *rec,
|
|
|
|
void *frame, CONTEXT *ctx,
|
|
|
|
void *disp)
|
|
|
|
{
|
|
|
|
return ExceptionContinueExecution;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-06-29 10:44:07 +00:00
|
|
|
void setCurrentThreadName(const char* threadName) {
|
2012-03-27 21:39:13 +00:00
|
|
|
#ifdef _WIN32
|
2014-06-29 10:44:07 +00:00
|
|
|
// Set the debugger-visible threadname through an unholy magic hack
|
2012-03-27 21:39:13 +00:00
|
|
|
static const DWORD MS_VC_EXCEPTION = 0x406D1388;
|
2017-08-31 20:15:05 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(_WIN32) && defined(__MINGW32__)
|
|
|
|
// Thread information for VS compatible debugger. -1 sets current thread.
|
|
|
|
THREADNAME_INFO ti;
|
|
|
|
ti.dwType = 0x1000;
|
|
|
|
ti.szName = threadName;
|
|
|
|
ti.dwThreadID = -1;
|
|
|
|
|
|
|
|
// Push an exception handler to ignore all following exceptions
|
|
|
|
NT_TIB *tib = ((NT_TIB*)NtCurrentTeb());
|
|
|
|
EXCEPTION_REGISTRATION_RECORD rec;
|
|
|
|
rec.Next = tib->ExceptionList;
|
|
|
|
rec.Handler = ignore_handler;
|
|
|
|
tib->ExceptionList = &rec;
|
|
|
|
|
|
|
|
// Visual Studio and compatible debuggers receive thread names from the
|
|
|
|
// program through a specially crafted exception
|
|
|
|
RaiseException(MS_VC_EXCEPTION, 0, sizeof(ti) / sizeof(ULONG_PTR),
|
|
|
|
(ULONG_PTR*)&ti);
|
|
|
|
|
|
|
|
// Pop exception handler
|
|
|
|
tib->ExceptionList = tib->ExceptionList->Next;
|
|
|
|
#elif defined(_WIN32)
|
2012-03-27 21:39:13 +00:00
|
|
|
#pragma pack(push,8)
|
2014-06-29 10:44:07 +00:00
|
|
|
struct THREADNAME_INFO {
|
2012-03-27 21:39:13 +00:00
|
|
|
DWORD dwType; // must be 0x1000
|
|
|
|
LPCSTR szName; // pointer to name (in user addr space)
|
|
|
|
DWORD dwThreadID; // thread ID (-1=caller thread)
|
|
|
|
DWORD dwFlags; // reserved for future use, must be zero
|
|
|
|
} info;
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
|
|
|
info.dwType = 0x1000;
|
2014-06-29 10:44:07 +00:00
|
|
|
info.szName = threadName;
|
2012-03-27 21:39:13 +00:00
|
|
|
info.dwThreadID = -1; //dwThreadID;
|
|
|
|
info.dwFlags = 0;
|
|
|
|
|
2017-08-29 20:41:50 +00:00
|
|
|
#ifdef __MINGW32__
|
|
|
|
__try1 (ehandler)
|
|
|
|
#else
|
2012-03-27 21:39:13 +00:00
|
|
|
__try
|
2017-08-29 20:41:50 +00:00
|
|
|
#endif
|
2012-03-27 21:39:13 +00:00
|
|
|
{
|
|
|
|
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
|
|
|
|
}
|
2017-08-29 20:41:50 +00:00
|
|
|
#ifdef __MINGW32__
|
|
|
|
__except1
|
|
|
|
#else
|
2012-03-27 21:39:13 +00:00
|
|
|
__except(EXCEPTION_CONTINUE_EXECUTION)
|
2017-08-29 20:41:50 +00:00
|
|
|
#endif
|
2012-03-27 21:39:13 +00:00
|
|
|
{}
|
|
|
|
#else
|
2015-07-19 14:21:24 +00:00
|
|
|
|
2016-10-12 09:13:16 +00:00
|
|
|
#if defined(__ANDROID__)
|
2015-07-19 14:21:24 +00:00
|
|
|
pthread_setname_np(pthread_self(), threadName);
|
|
|
|
// #else
|
|
|
|
// pthread_setname_np(thread_name);
|
|
|
|
#endif
|
|
|
|
|
2012-03-27 21:39:13 +00:00
|
|
|
// Do nothing
|
2014-06-29 10:44:07 +00:00
|
|
|
#endif
|
|
|
|
// Set the locally known threadname using a thread local variable.
|
|
|
|
#ifdef TLS_SUPPORTED
|
|
|
|
curThreadName = threadName;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void AssertCurrentThreadName(const char *threadName) {
|
|
|
|
#ifdef TLS_SUPPORTED
|
|
|
|
if (strcmp(curThreadName, threadName) != 0) {
|
|
|
|
ELOG("Thread name assert failed: Expected %s, was %s", threadName, curThreadName);
|
|
|
|
}
|
2012-03-27 21:39:13 +00:00
|
|
|
#endif
|
|
|
|
}
|