Add the thread's scheduling events to the thread model.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30507 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-04-30 12:27:04 +00:00
parent 8cd416d9e6
commit ef8252e1e0
2 changed files with 97 additions and 3 deletions

View File

@ -5,9 +5,12 @@
#include "ThreadModelLoader.h" #include "ThreadModelLoader.h"
#include <stdio.h>
#include <new> #include <new>
#include <AutoLocker.h> #include <AutoLocker.h>
#include <DebugEventStream.h>
#include "ThreadModel.h" #include "ThreadModel.h"
@ -110,12 +113,14 @@ ThreadModelLoader::_Load()
waitObjects.SortItems(&compare_by_type_and_name); waitObjects.SortItems(&compare_by_type_and_name);
// create the groups // create the groups
int32 count = waitObjects.CountItems(); int32 waitObjectCount = waitObjects.CountItems();
for (int32 i = 0; i < count; i++) { printf("%ld wait objects\n", waitObjectCount);
for (int32 i = 0; i < waitObjectCount;) {
printf("new wait object group at %ld\n", i);
// collect the objects for this group // collect the objects for this group
Model::ThreadWaitObject* firstObject = waitObjects.ItemAt(i); Model::ThreadWaitObject* firstObject = waitObjects.ItemAt(i);
int32 k = i + 1; int32 k = i + 1;
for (; k < count; k++) { for (; k < waitObjectCount; k++) {
if (compare_by_type_and_name(firstObject, waitObjects.ItemAt(k)) if (compare_by_type_and_name(firstObject, waitObjects.ItemAt(k))
!= 0) { != 0) {
break; break;
@ -124,6 +129,88 @@ ThreadModelLoader::_Load()
if (fThreadModel->AddWaitObjectGroup(waitObjects, i, k) == NULL) if (fThreadModel->AddWaitObjectGroup(waitObjects, i, k) == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
i = k;
}
// create a debug input stream
BDebugEventInputStream input;
uint8* eventData = (uint8*)fModel->EventData();
status_t error = input.SetTo(eventData, fModel->EventDataSize(), false);
if (error != B_OK)
return error;
// process the events
thread_id threadID = fThread->ID();
bool done = false;
uint32 count = 0;
while (!done) {
// get next event
uint32 eventType;
uint32 cpu;
const void* buffer;
off_t streamOffset;
ssize_t bufferSize = input.ReadNextEvent(&eventType, &cpu, &buffer,
&streamOffset);
if (bufferSize < 0)
return bufferSize;
if (buffer == NULL)
break;
// process the event
bool keepEvent = false;
switch (eventType) {
case B_SYSTEM_PROFILER_THREAD_REMOVED:
{
system_profiler_thread_removed* event
= (system_profiler_thread_removed*)buffer;
if (event->thread == threadID)
done = true;
break;
}
case B_SYSTEM_PROFILER_THREAD_SCHEDULED:
{
system_profiler_thread_scheduled* event
= (system_profiler_thread_scheduled*)buffer;
keepEvent = event->thread == threadID
|| event->previous_thread == threadID ;
break;
}
case B_SYSTEM_PROFILER_THREAD_ENQUEUED_IN_RUN_QUEUE:
{
thread_enqueued_in_run_queue* event
= (thread_enqueued_in_run_queue*)buffer;
keepEvent = event->thread == threadID;
break;
}
case B_SYSTEM_PROFILER_THREAD_REMOVED_FROM_RUN_QUEUE:
{
thread_removed_from_run_queue* event
= (thread_removed_from_run_queue*)buffer;
keepEvent = event->thread == threadID;
break;
}
default:
break;
}
if (keepEvent) {
fThreadModel->AddSchedulingEvent(
(system_profiler_event_header*)(eventData + streamOffset));
}
// periodically check whether we're supposed to abort
if (++count % 32 == 0) {
AutoLocker<BLocker> locker(fLock);
if (fAborted)
return B_ERROR;
}
} }
return B_OK; return B_OK;

View File

@ -30,6 +30,13 @@ protected:
virtual status_t Load(); virtual status_t Load();
virtual void FinishLoading(bool success); virtual void FinishLoading(bool success);
private:
// shorthands for the longish structure names
typedef system_profiler_thread_enqueued_in_run_queue
thread_enqueued_in_run_queue;
typedef system_profiler_thread_removed_from_run_queue
thread_removed_from_run_queue;
private: private:
status_t _Load(); status_t _Load();