Commit c89021d1 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Added labelled thread names to help with some debugging activity. Right now,

the only platform that it works on is linux (using the prctl API to set the
names of the threads). Other platforms are setup to build properly if the
flag is set, but their thread names are not currently set.

Patch by Mark Lam from Hewlett-Packard Development Company, LP

Review URL: http://codereview.chromium.org/6070009


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6141 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c28bde77
...@@ -47,7 +47,8 @@ static const int kTickSamplesBufferChunksCount = 16; ...@@ -47,7 +47,8 @@ static const int kTickSamplesBufferChunksCount = 16;
ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator) ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator)
: generator_(generator), : Thread("v8:ProfEvntProc"),
generator_(generator),
running_(true), running_(true),
ticks_buffer_(sizeof(TickSampleEventRecord), ticks_buffer_(sizeof(TickSampleEventRecord),
kTickSamplesBufferChunkSize, kTickSamplesBufferChunkSize,
......
...@@ -98,7 +98,8 @@ class RemoteDebugger { ...@@ -98,7 +98,8 @@ class RemoteDebugger {
class ReceiverThread: public i::Thread { class ReceiverThread: public i::Thread {
public: public:
explicit ReceiverThread(RemoteDebugger* remote_debugger) explicit ReceiverThread(RemoteDebugger* remote_debugger)
: remote_debugger_(remote_debugger) {} : Thread("d8:ReceiverThrd"),
remote_debugger_(remote_debugger) {}
~ReceiverThread() {} ~ReceiverThread() {}
void Run(); void Run();
...@@ -112,7 +113,8 @@ class ReceiverThread: public i::Thread { ...@@ -112,7 +113,8 @@ class ReceiverThread: public i::Thread {
class KeyboardThread: public i::Thread { class KeyboardThread: public i::Thread {
public: public:
explicit KeyboardThread(RemoteDebugger* remote_debugger) explicit KeyboardThread(RemoteDebugger* remote_debugger)
: remote_debugger_(remote_debugger) {} : Thread("d8:KeyboardThrd"),
remote_debugger_(remote_debugger) {}
~KeyboardThread() {} ~KeyboardThread() {}
void Run(); void Run();
......
...@@ -599,7 +599,8 @@ void Shell::RunShell() { ...@@ -599,7 +599,8 @@ void Shell::RunShell() {
class ShellThread : public i::Thread { class ShellThread : public i::Thread {
public: public:
ShellThread(int no, i::Vector<const char> files) ShellThread(int no, i::Vector<const char> files)
: no_(no), files_(files) { } : Thread("d8:ShellThread"),
no_(no), files_(files) { }
virtual void Run(); virtual void Run();
private: private:
int no_; int no_;
......
...@@ -44,7 +44,8 @@ class DebuggerAgentSession; ...@@ -44,7 +44,8 @@ class DebuggerAgentSession;
class DebuggerAgent: public Thread { class DebuggerAgent: public Thread {
public: public:
explicit DebuggerAgent(const char* name, int port) explicit DebuggerAgent(const char* name, int port)
: name_(StrDup(name)), port_(port), : Thread(name),
name_(StrDup(name)), port_(port),
server_(OS::CreateSocket()), terminate_(false), server_(OS::CreateSocket()), terminate_(false),
session_access_(OS::CreateMutex()), session_(NULL), session_access_(OS::CreateMutex()), session_(NULL),
terminate_now_(OS::CreateSemaphore(0)), terminate_now_(OS::CreateSemaphore(0)),
...@@ -90,7 +91,8 @@ class DebuggerAgent: public Thread { ...@@ -90,7 +91,8 @@ class DebuggerAgent: public Thread {
class DebuggerAgentSession: public Thread { class DebuggerAgentSession: public Thread {
public: public:
DebuggerAgentSession(DebuggerAgent* agent, Socket* client) DebuggerAgentSession(DebuggerAgent* agent, Socket* client)
: agent_(agent), client_(client) {} : Thread("v8:DbgAgntSessn"),
agent_(agent), client_(client) {}
void DebuggerMessage(Vector<uint16_t> message); void DebuggerMessage(Vector<uint16_t> message);
void Shutdown(); void Shutdown();
......
...@@ -3037,7 +3037,8 @@ void LockingCommandMessageQueue::Clear() { ...@@ -3037,7 +3037,8 @@ void LockingCommandMessageQueue::Clear() {
MessageDispatchHelperThread::MessageDispatchHelperThread() MessageDispatchHelperThread::MessageDispatchHelperThread()
: sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()), : Thread("v8:MsgDispHelpr"),
sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()),
already_signalled_(false) { already_signalled_(false) {
} }
......
...@@ -276,7 +276,8 @@ void SlidingStateWindow::AddState(StateTag state) { ...@@ -276,7 +276,8 @@ void SlidingStateWindow::AddState(StateTag state) {
// Profiler implementation. // Profiler implementation.
// //
Profiler::Profiler() Profiler::Profiler()
: head_(0), : Thread("v8:Profiler"),
head_(0),
tail_(0), tail_(0),
overflow_(false), overflow_(false),
buffer_semaphore_(OS::CreateSemaphore(0)), buffer_semaphore_(OS::CreateSemaphore(0)),
......
...@@ -411,6 +411,12 @@ bool ThreadHandle::IsValid() const { ...@@ -411,6 +411,12 @@ bool ThreadHandle::IsValid() const {
Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) { Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
set_name("v8:<unknown>");
}
Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
set_names(name);
} }
...@@ -430,6 +436,12 @@ static void* ThreadEntry(void* arg) { ...@@ -430,6 +436,12 @@ static void* ThreadEntry(void* arg) {
} }
void Thread::set_name(const char* name) {
strncpy(name_, name, sizeof(name_));
name_[sizeof(name_) - 1] = '\0';
}
void Thread::Start() { void Thread::Start() {
pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this); pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
ASSERT(IsValid()); ASSERT(IsValid());
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <pthread.h> #include <pthread.h>
#include <semaphore.h> #include <semaphore.h>
#include <signal.h> #include <signal.h>
#include <sys/prctl.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/syscall.h> #include <sys/syscall.h>
...@@ -551,6 +552,12 @@ bool ThreadHandle::IsValid() const { ...@@ -551,6 +552,12 @@ bool ThreadHandle::IsValid() const {
Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) { Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
set_name("v8:<unknown>");
}
Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
set_name(name);
} }
...@@ -563,6 +570,7 @@ static void* ThreadEntry(void* arg) { ...@@ -563,6 +570,7 @@ static void* ThreadEntry(void* arg) {
// This is also initialized by the first argument to pthread_create() but we // This is also initialized by the first argument to pthread_create() but we
// don't know which thread will run first (the original thread or the new // don't know which thread will run first (the original thread or the new
// one) so we initialize it here too. // one) so we initialize it here too.
prctl(PR_SET_NAME, thread->name(), 0, 0, 0);
thread->thread_handle_data()->thread_ = pthread_self(); thread->thread_handle_data()->thread_ = pthread_self();
ASSERT(thread->IsValid()); ASSERT(thread->IsValid());
thread->Run(); thread->Run();
...@@ -570,6 +578,12 @@ static void* ThreadEntry(void* arg) { ...@@ -570,6 +578,12 @@ static void* ThreadEntry(void* arg) {
} }
void Thread::set_name(const char* name) {
strncpy(name_, name, sizeof(name_));
name_[sizeof(name_) - 1] = '\0';
}
void Thread::Start() { void Thread::Start() {
pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this); pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
ASSERT(IsValid()); ASSERT(IsValid());
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
// Platform specific code for MacOS goes here. For the POSIX comaptible parts // Platform specific code for MacOS goes here. For the POSIX comaptible parts
// the implementation is in platform-posix.cc. // the implementation is in platform-posix.cc.
#include <dlfcn.h>
#include <string>
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <mach/mach_init.h> #include <mach/mach_init.h>
...@@ -411,6 +413,12 @@ bool ThreadHandle::IsValid() const { ...@@ -411,6 +413,12 @@ bool ThreadHandle::IsValid() const {
Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) { Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
set_name("v8:<unknown>");
}
Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
set_name(name);
} }
...@@ -418,18 +426,42 @@ Thread::~Thread() { ...@@ -418,18 +426,42 @@ Thread::~Thread() {
} }
static void SetThreadName(const char* name) {
// pthread_setname_np is only available in 10.6 or later, so test
// for it at runtime.
int (*dynamic_pthread_setname_np)(const char*);
*reinterpret_cast<void**>(&dynamic_pthread_setname_np) =
dlsym(RTLD_DEFAULT, "pthread_setname_np");
if (!dynamic_pthread_setname_np)
return;
// Mac OS X does not expose the length limit of the name, so hardcode it.
const int kMaxNameLength = 63;
std::string shortened_name = std::string(name).substr(0, kMaxNameLength);
dynamic_pthread_setname_np(shortened_name.c_str());
}
static void* ThreadEntry(void* arg) { static void* ThreadEntry(void* arg) {
Thread* thread = reinterpret_cast<Thread*>(arg); Thread* thread = reinterpret_cast<Thread*>(arg);
// This is also initialized by the first argument to pthread_create() but we // This is also initialized by the first argument to pthread_create() but we
// don't know which thread will run first (the original thread or the new // don't know which thread will run first (the original thread or the new
// one) so we initialize it here too. // one) so we initialize it here too.
thread->thread_handle_data()->thread_ = pthread_self(); thread->thread_handle_data()->thread_ = pthread_self();
SetThreadName(thread->name());
ASSERT(thread->IsValid()); ASSERT(thread->IsValid());
thread->Run(); thread->Run();
return NULL; return NULL;
} }
void Thread::set_name(const char* name) {
strncpy(name_, name, sizeof(name_));
name_[sizeof(name_) - 1] = '\0';
}
void Thread::Start() { void Thread::Start() {
pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this); pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
} }
......
...@@ -335,6 +335,13 @@ bool ThreadHandle::IsValid() const { ...@@ -335,6 +335,13 @@ bool ThreadHandle::IsValid() const {
Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) { Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
set_name("v8:<unknown>");
UNIMPLEMENTED();
}
Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
set_name(name);
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
...@@ -344,6 +351,12 @@ Thread::~Thread() { ...@@ -344,6 +351,12 @@ Thread::~Thread() {
} }
void Thread::set_name(const char* name) {
strncpy(name_, name, sizeof(name_));
name_[sizeof(name_) - 1] = '\0';
}
void Thread::Start() { void Thread::Start() {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
......
...@@ -387,6 +387,12 @@ bool ThreadHandle::IsValid() const { ...@@ -387,6 +387,12 @@ bool ThreadHandle::IsValid() const {
Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) { Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
set_name("v8:<unknown>");
}
Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
set_name(name);
} }
...@@ -406,6 +412,12 @@ static void* ThreadEntry(void* arg) { ...@@ -406,6 +412,12 @@ static void* ThreadEntry(void* arg) {
} }
void Thread::set_name(const char* name) {
strncpy(name_, name, sizeof(name_));
name_[sizeof(name_) - 1] = '\0';
}
void Thread::Start() { void Thread::Start() {
pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this); pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
ASSERT(IsValid()); ASSERT(IsValid());
......
...@@ -401,6 +401,12 @@ bool ThreadHandle::IsValid() const { ...@@ -401,6 +401,12 @@ bool ThreadHandle::IsValid() const {
Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) { Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
set_name("v8:<unknown>");
}
Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
set_name(name);
} }
...@@ -420,6 +426,12 @@ static void* ThreadEntry(void* arg) { ...@@ -420,6 +426,12 @@ static void* ThreadEntry(void* arg) {
} }
void Thread::set_name(const char* name) {
strncpy(name_, name, sizeof(name_));
name_[sizeof(name_) - 1] = '\0';
}
void Thread::Start() { void Thread::Start() {
pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this); pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
ASSERT(IsValid()); ASSERT(IsValid());
......
...@@ -1463,6 +1463,19 @@ class Thread::PlatformData : public Malloced { ...@@ -1463,6 +1463,19 @@ class Thread::PlatformData : public Malloced {
Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) { Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
data_ = new PlatformData(kNoThread); data_ = new PlatformData(kNoThread);
set_name("v8:<unknown>");
}
Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
data_ = new PlatformData(kNoThread);
set_name(name);
}
void Thread::set_name(const char* name) {
strncpy(name_, name, sizeof(name_));
name_[sizeof(name_) - 1] = '\0';
} }
......
...@@ -387,6 +387,7 @@ class Thread: public ThreadHandle { ...@@ -387,6 +387,7 @@ class Thread: public ThreadHandle {
// Create new thread. // Create new thread.
Thread(); Thread();
explicit Thread(const char* name);
virtual ~Thread(); virtual ~Thread();
// Start new thread by calling the Run() method in the new thread. // Start new thread by calling the Run() method in the new thread.
...@@ -395,6 +396,10 @@ class Thread: public ThreadHandle { ...@@ -395,6 +396,10 @@ class Thread: public ThreadHandle {
// Wait until thread terminates. // Wait until thread terminates.
void Join(); void Join();
inline const char* name() const {
return name_;
}
// Abstract method for run handler. // Abstract method for run handler.
virtual void Run() = 0; virtual void Run() = 0;
...@@ -417,8 +422,16 @@ class Thread: public ThreadHandle { ...@@ -417,8 +422,16 @@ class Thread: public ThreadHandle {
static void YieldCPU(); static void YieldCPU();
private: private:
void set_name(const char *name);
class PlatformData; class PlatformData;
PlatformData* data_; PlatformData* data_;
// The thread name length is limited to 16 based on Linux's implementation of
// prctl().
static const int kMaxThreadNameLength = 16;
char name_[kMaxThreadNameLength];
DISALLOW_COPY_AND_ASSIGN(Thread); DISALLOW_COPY_AND_ASSIGN(Thread);
}; };
......
...@@ -170,7 +170,9 @@ void Top::InitializeThreadLocal() { ...@@ -170,7 +170,9 @@ void Top::InitializeThreadLocal() {
// into for use by a stacks only core dump (aka minidump). // into for use by a stacks only core dump (aka minidump).
class PreallocatedMemoryThread: public Thread { class PreallocatedMemoryThread: public Thread {
public: public:
PreallocatedMemoryThread() : keep_running_(true) { PreallocatedMemoryThread()
: Thread("v8:PreallocMem"),
keep_running_(true) {
wait_for_ever_semaphore_ = OS::CreateSemaphore(0); wait_for_ever_semaphore_ = OS::CreateSemaphore(0);
data_ready_semaphore_ = OS::CreateSemaphore(0); data_ready_semaphore_ = OS::CreateSemaphore(0);
} }
......
...@@ -380,7 +380,8 @@ ContextSwitcher* ContextSwitcher::singleton_ = NULL; ...@@ -380,7 +380,8 @@ ContextSwitcher* ContextSwitcher::singleton_ = NULL;
ContextSwitcher::ContextSwitcher(int every_n_ms) ContextSwitcher::ContextSwitcher(int every_n_ms)
: keep_going_(true), : Thread("v8:CtxtSwitcher"),
keep_going_(true),
sleep_ms_(every_n_ms) { sleep_ms_(every_n_ms) {
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment