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;
ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator)
: generator_(generator),
: Thread("v8:ProfEvntProc"),
generator_(generator),
running_(true),
ticks_buffer_(sizeof(TickSampleEventRecord),
kTickSamplesBufferChunkSize,
......
......@@ -98,7 +98,8 @@ class RemoteDebugger {
class ReceiverThread: public i::Thread {
public:
explicit ReceiverThread(RemoteDebugger* remote_debugger)
: remote_debugger_(remote_debugger) {}
: Thread("d8:ReceiverThrd"),
remote_debugger_(remote_debugger) {}
~ReceiverThread() {}
void Run();
......@@ -112,7 +113,8 @@ class ReceiverThread: public i::Thread {
class KeyboardThread: public i::Thread {
public:
explicit KeyboardThread(RemoteDebugger* remote_debugger)
: remote_debugger_(remote_debugger) {}
: Thread("d8:KeyboardThrd"),
remote_debugger_(remote_debugger) {}
~KeyboardThread() {}
void Run();
......
......@@ -599,7 +599,8 @@ void Shell::RunShell() {
class ShellThread : public i::Thread {
public:
ShellThread(int no, i::Vector<const char> files)
: no_(no), files_(files) { }
: Thread("d8:ShellThread"),
no_(no), files_(files) { }
virtual void Run();
private:
int no_;
......
......@@ -44,7 +44,8 @@ class DebuggerAgentSession;
class DebuggerAgent: public Thread {
public:
explicit DebuggerAgent(const char* name, int port)
: name_(StrDup(name)), port_(port),
: Thread(name),
name_(StrDup(name)), port_(port),
server_(OS::CreateSocket()), terminate_(false),
session_access_(OS::CreateMutex()), session_(NULL),
terminate_now_(OS::CreateSemaphore(0)),
......@@ -90,7 +91,8 @@ class DebuggerAgent: public Thread {
class DebuggerAgentSession: public Thread {
public:
DebuggerAgentSession(DebuggerAgent* agent, Socket* client)
: agent_(agent), client_(client) {}
: Thread("v8:DbgAgntSessn"),
agent_(agent), client_(client) {}
void DebuggerMessage(Vector<uint16_t> message);
void Shutdown();
......
......@@ -3037,7 +3037,8 @@ void LockingCommandMessageQueue::Clear() {
MessageDispatchHelperThread::MessageDispatchHelperThread()
: sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()),
: Thread("v8:MsgDispHelpr"),
sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()),
already_signalled_(false) {
}
......
......@@ -276,7 +276,8 @@ void SlidingStateWindow::AddState(StateTag state) {
// Profiler implementation.
//
Profiler::Profiler()
: head_(0),
: Thread("v8:Profiler"),
head_(0),
tail_(0),
overflow_(false),
buffer_semaphore_(OS::CreateSemaphore(0)),
......
......@@ -411,6 +411,12 @@ bool ThreadHandle::IsValid() const {
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) {
}
void Thread::set_name(const char* name) {
strncpy(name_, name, sizeof(name_));
name_[sizeof(name_) - 1] = '\0';
}
void Thread::Start() {
pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
ASSERT(IsValid());
......
......@@ -31,6 +31,7 @@
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/prctl.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/syscall.h>
......@@ -551,6 +552,12 @@ bool ThreadHandle::IsValid() const {
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) {
// 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
// one) so we initialize it here too.
prctl(PR_SET_NAME, thread->name(), 0, 0, 0);
thread->thread_handle_data()->thread_ = pthread_self();
ASSERT(thread->IsValid());
thread->Run();
......@@ -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() {
pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
ASSERT(IsValid());
......
......@@ -28,6 +28,8 @@
// Platform specific code for MacOS goes here. For the POSIX comaptible parts
// the implementation is in platform-posix.cc.
#include <dlfcn.h>
#include <string>
#include <unistd.h>
#include <sys/mman.h>
#include <mach/mach_init.h>
......@@ -411,6 +413,12 @@ bool ThreadHandle::IsValid() const {
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() {
}
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) {
Thread* thread = reinterpret_cast<Thread*>(arg);
// 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
// one) so we initialize it here too.
thread->thread_handle_data()->thread_ = pthread_self();
SetThreadName(thread->name());
ASSERT(thread->IsValid());
thread->Run();
return NULL;
}
void Thread::set_name(const char* name) {
strncpy(name_, name, sizeof(name_));
name_[sizeof(name_) - 1] = '\0';
}
void Thread::Start() {
pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
}
......
......@@ -335,6 +335,13 @@ bool ThreadHandle::IsValid() const {
Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
set_name("v8:<unknown>");
UNIMPLEMENTED();
}
Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
set_name(name);
UNIMPLEMENTED();
}
......@@ -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() {
UNIMPLEMENTED();
}
......
......@@ -387,6 +387,12 @@ bool ThreadHandle::IsValid() const {
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) {
}
void Thread::set_name(const char* name) {
strncpy(name_, name, sizeof(name_));
name_[sizeof(name_) - 1] = '\0';
}
void Thread::Start() {
pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
ASSERT(IsValid());
......
......@@ -401,6 +401,12 @@ bool ThreadHandle::IsValid() const {
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) {
}
void Thread::set_name(const char* name) {
strncpy(name_, name, sizeof(name_));
name_[sizeof(name_) - 1] = '\0';
}
void Thread::Start() {
pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
ASSERT(IsValid());
......
......@@ -1463,6 +1463,19 @@ class Thread::PlatformData : public Malloced {
Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
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 {
// Create new thread.
Thread();
explicit Thread(const char* name);
virtual ~Thread();
// Start new thread by calling the Run() method in the new thread.
......@@ -395,6 +396,10 @@ class Thread: public ThreadHandle {
// Wait until thread terminates.
void Join();
inline const char* name() const {
return name_;
}
// Abstract method for run handler.
virtual void Run() = 0;
......@@ -417,8 +422,16 @@ class Thread: public ThreadHandle {
static void YieldCPU();
private:
void set_name(const char *name);
class PlatformData;
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);
};
......
......@@ -170,7 +170,9 @@ void Top::InitializeThreadLocal() {
// into for use by a stacks only core dump (aka minidump).
class PreallocatedMemoryThread: public Thread {
public:
PreallocatedMemoryThread() : keep_running_(true) {
PreallocatedMemoryThread()
: Thread("v8:PreallocMem"),
keep_running_(true) {
wait_for_ever_semaphore_ = OS::CreateSemaphore(0);
data_ready_semaphore_ = OS::CreateSemaphore(0);
}
......
......@@ -380,7 +380,8 @@ ContextSwitcher* ContextSwitcher::singleton_ = NULL;
ContextSwitcher::ContextSwitcher(int every_n_ms)
: keep_going_(true),
: Thread("v8:CtxtSwitcher"),
keep_going_(true),
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