* Also pass the team arguments and thread names with the respective system

profiling events.
* profile: Avoid using get_{team,thread}_info() in common code paths. The
  system profiling mode is asynchronous, so the team or thread in question
  could already be gone.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30193 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-04-16 10:02:33 +00:00
parent 1370f1b69e
commit 1b9d2885d3
7 changed files with 74 additions and 33 deletions

View File

@ -38,6 +38,7 @@ struct system_profiler_event_header {
// B_SYSTEM_PROFILER_TEAM_ADDED
struct system_profiler_team_added {
team_id team;
char args[1];
};
// B_SYSTEM_PROFILER_TEAM_REMOVED
@ -48,12 +49,15 @@ struct system_profiler_team_removed {
// B_SYSTEM_PROFILER_TEAM_EXEC
struct system_profiler_team_exec {
team_id team;
char thread_name[B_OS_NAME_LENGTH];
char args[1];
};
// B_SYSTEM_PROFILER_THREAD_ADDED
struct system_profiler_thread_added {
team_id team;
thread_id thread;
char name[B_OS_NAME_LENGTH];
};
// B_SYSTEM_PROFILER_THREAD_REMOVED

View File

@ -32,11 +32,11 @@ enum {
Team::Team()
:
fID(-1),
fNubPort(-1),
fThreads(),
fImages(20, false)
{
fInfo.team = -1;
fDebugContext.nub_port = -1;
}
@ -47,7 +47,7 @@ Team::~Team()
destroy_debug_context(&fDebugContext);
if (fNubPort >= 0)
remove_team_debugger(fInfo.team);
remove_team_debugger(fID);
for (int32 i = 0; Image* image = fImages.ItemAt(i); i++)
image->RemoveReference();
@ -58,10 +58,14 @@ status_t
Team::Init(team_id teamID, port_id debuggerPort)
{
// get team info
status_t error = get_team_info(teamID, &fInfo);
team_info teamInfo;
status_t error = get_team_info(teamID, &teamInfo);
if (error != B_OK)
return error;
fID = teamID;
fArgs = teamInfo.args;
// install ourselves as the team debugger
fNubPort = install_team_debugger(teamID, debuggerPort);
if (fNubPort < 0) {
@ -90,7 +94,8 @@ Team::Init(team_id teamID, port_id debuggerPort)
status_t
Team::Init(system_profiler_team_added* addedInfo)
{
fInfo.team = addedInfo->team;
fID = addedInfo->team;
fArgs = addedInfo->args;
return B_OK;
}
@ -177,7 +182,7 @@ Team::RemoveThread(Thread* thread)
void
Team::Exec(int32 event)
Team::Exec(int32 event, const char* args, const char* threadName)
{
// remove all non-kernel images
int32 imageCount = fImages.CountItems();
@ -187,11 +192,13 @@ Team::Exec(int32 event)
_RemoveImage(i, event);
}
fArgs = args;
// update the main thread
ThreadList::Iterator it = fThreads.GetIterator();
while (Thread* thread = it.Next()) {
if (thread->ID() == ID()) {
thread->UpdateInfo();
thread->UpdateInfo(threadName);
break;
}
}

View File

@ -5,6 +5,8 @@
#ifndef TEAM_H
#define TEAM_H
#include <String.h>
#include <debug_support.h>
#include <ObjectList.h>
#include <util/DoublyLinkedList.h>
@ -26,7 +28,8 @@ public:
void RemoveThread(Thread* thread);
void Exec(int32 event);
void Exec(int32 event, const char* args,
const char* threadName);
status_t AddImage(SharedImage* sharedImage,
const image_info& imageInfo, team_id owner,
@ -47,7 +50,8 @@ private:
private:
typedef DoublyLinkedList<Thread> ThreadList;
team_info fInfo;
team_id fID;
BString fArgs;
port_id fNubPort;
debug_context fDebugContext;
ThreadList fThreads;
@ -68,7 +72,7 @@ Team::Images() const
team_id
Team::ID() const
{
return fInfo.team;
return fID;
}

View File

@ -44,9 +44,10 @@ ThreadImage::Init()
// #pragma mark - Thread
Thread::Thread(const thread_info& info, Team* team)
Thread::Thread(thread_id threadID, const char* name, Team* team)
:
fInfo(info),
fID(threadID),
fName(name),
fTeam(team),
fSampleArea(-1),
fSamples(NULL),
@ -73,11 +74,9 @@ Thread::SetProfileResult(ThreadProfileResult* result)
void
Thread::UpdateInfo()
Thread::UpdateInfo(const char* name)
{
thread_info info;
if (get_thread_info(ID(), &info) == B_OK)
fInfo = info;
fName = name;
}

View File

@ -5,6 +5,8 @@
#ifndef THREAD_H
#define THREAD_H
#include <String.h>
#include <util/DoublyLinkedList.h>
#include "Image.h"
@ -37,7 +39,8 @@ protected:
class Thread : public DoublyLinkedListLinkImpl<Thread> {
public:
Thread(const thread_info& info, Team* team);
Thread(thread_id threadID, const char* name,
Team* team);
~Thread();
inline thread_id ID() const;
@ -48,7 +51,7 @@ public:
inline ThreadProfileResult* ProfileResult() const;
void SetProfileResult(ThreadProfileResult* result);
void UpdateInfo();
void UpdateInfo(const char* name);
void SetSampleArea(area_id area, addr_t* samples);
void SetInterval(bigtime_t interval);
@ -66,7 +69,8 @@ private:
typedef DoublyLinkedList<ThreadImage> ImageList;
private:
thread_info fInfo;
thread_id fID;
BString fName;
::Team* fTeam;
area_id fSampleArea;
addr_t* fSamples;
@ -169,14 +173,14 @@ ThreadImage::TotalHits() const
thread_id
Thread::ID() const
{
return fInfo.thread;
return fID;
}
const char*
Thread::Name() const
{
return fInfo.name;
return fName.String();
}

View File

@ -121,23 +121,28 @@ public:
status_t AddThread(thread_id threadID)
{
if (FindThread(threadID) != NULL)
return B_BAD_VALUE;
thread_info threadInfo;
status_t error = get_thread_info(threadID, &threadInfo);
if (error != B_OK)
return error;
Team* team = FindTeam(threadInfo.team);
return AddThread(threadInfo.team, threadID, threadInfo.name);
}
status_t AddThread(team_id teamID, thread_id threadID, const char* name)
{
if (FindThread(threadID) != NULL)
return B_BAD_VALUE;
Team* team = FindTeam(teamID);
if (team == NULL)
return B_BAD_TEAM_ID;
Thread* thread = new(std::nothrow) Thread(threadInfo, team);
Thread* thread = new(std::nothrow) Thread(threadID, name, team);
if (thread == NULL)
return B_NO_MEMORY;
error = _CreateThreadProfileResult(thread);
status_t error = _CreateThreadProfileResult(thread);
if (error != B_OK) {
delete thread;
return error;
@ -455,10 +460,10 @@ process_event_buffer(ThreadManager& threadManager, uint8* buffer,
case B_SYSTEM_PROFILER_TEAM_EXEC:
{
system_profiler_team_exec* event
= (system_profiler_team_exec*)event;
= (system_profiler_team_exec*)buffer;
if (Team* team = threadManager.FindTeam(event->team))
team->Exec(0);
team->Exec(0, event->args, event->thread_name);
break;
}
@ -467,7 +472,8 @@ process_event_buffer(ThreadManager& threadManager, uint8* buffer,
system_profiler_thread_added* event
= (system_profiler_thread_added*)buffer;
threadManager.AddThread(event->thread);
threadManager.AddThread(event->team, event->thread,
event->name);
break;
}
@ -803,8 +809,16 @@ main(int argc, const char* const* argv)
quitLoop = message.origin.team == teamID;
break;
case B_DEBUGGER_MESSAGE_TEAM_EXEC:
if (Team* team = threadManager.FindTeam(message.origin.team))
team->Exec(message.team_exec.image_event);
if (Team* team = threadManager.FindTeam(message.origin.team)) {
team_info teamInfo;
thread_info threadInfo;
if (get_team_info(message.origin.team, &teamInfo) == B_OK
&& get_thread_info(message.origin.team, &threadInfo)
== B_OK) {
team->Exec(message.team_exec.image_event, teamInfo.args,
threadInfo.name);
}
}
break;
case B_DEBUGGER_MESSAGE_THREAD_CREATED:

View File

@ -404,13 +404,16 @@ SystemProfiler::_TeamAdded(struct team* team)
{
InterruptsSpinLocker locker(fLock);
size_t argsLen = strlen(team->args);
system_profiler_team_added* event = (system_profiler_team_added*)
_AllocateBuffer(sizeof(system_profiler_team_added),
_AllocateBuffer(sizeof(system_profiler_team_added) + argsLen,
B_SYSTEM_PROFILER_TEAM_ADDED, 0, 0);
if (event == NULL)
return false;
event->team = team->id;
strcpy(event->args, team->args);
fHeader->size = fBufferSize;
@ -442,13 +445,18 @@ SystemProfiler::_TeamExec(struct team* team)
{
InterruptsSpinLocker locker(fLock);
size_t argsLen = strlen(team->args);
system_profiler_team_exec* event = (system_profiler_team_exec*)
_AllocateBuffer(sizeof(system_profiler_team_exec),
_AllocateBuffer(sizeof(system_profiler_team_exec) + argsLen,
B_SYSTEM_PROFILER_TEAM_EXEC, 0, 0);
if (event == NULL)
return false;
event->team = team->id;
strlcpy(event->thread_name, team->main_thread->name,
sizeof(event->thread_name));
strcpy(event->args, team->args);
fHeader->size = fBufferSize;
@ -469,6 +477,7 @@ SystemProfiler::_ThreadAdded(struct thread* thread)
event->team = thread->team->id;
event->thread = thread->id;
strlcpy(event->name, thread->name, sizeof(event->name));
fHeader->size = fBufferSize;