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:
parent
8cd416d9e6
commit
ef8252e1e0
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue