* Model: Added classes IOOperation and IORequest, and extended Thread to own a
list of IORequests. * ModelLoader: Process the I/O request and operation related events and create the per-thread list of requests. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34732 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -75,6 +75,45 @@ Model::CPU::SetIdleTime(nanotime_t time)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - IORequest
|
||||
|
||||
|
||||
/*static*/ Model::IORequest*
|
||||
Model::IORequest::Create(system_profiler_io_request_scheduled* scheduledEvent,
|
||||
system_profiler_io_request_finished* finishedEvent, size_t operationCount)
|
||||
{
|
||||
void* memory = malloc(
|
||||
sizeof(IORequest) + operationCount * sizeof(IOOperation));
|
||||
if (memory == NULL)
|
||||
return NULL;
|
||||
|
||||
return new(memory) IORequest(scheduledEvent, finishedEvent, operationCount);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Model::IORequest::Delete()
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
|
||||
Model::IORequest::IORequest(
|
||||
system_profiler_io_request_scheduled* scheduledEvent,
|
||||
system_profiler_io_request_finished* finishedEvent, size_t operationCount)
|
||||
:
|
||||
scheduledEvent(scheduledEvent),
|
||||
finishedEvent(finishedEvent),
|
||||
operationCount(operationCount)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Model::IORequest::~IORequest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - WaitObject
|
||||
|
||||
|
||||
@@ -241,6 +280,8 @@ Model::Thread::Thread(Team* team, const system_profiler_thread_added* event,
|
||||
:
|
||||
fEvents(NULL),
|
||||
fEventCount(0),
|
||||
fIORequests(NULL),
|
||||
fIORequestCount(0),
|
||||
fTeam(team),
|
||||
fCreationEvent(event),
|
||||
fCreationTime(time),
|
||||
@@ -260,6 +301,8 @@ Model::Thread::Thread(Team* team, const system_profiler_thread_added* event,
|
||||
fWaits(0),
|
||||
fTotalWaitTime(0),
|
||||
fUnspecifiedWaitTime(0),
|
||||
fIOCount(0),
|
||||
fIOTime(0),
|
||||
fPreemptions(0),
|
||||
fIndex(-1),
|
||||
fWaitObjectGroups(20, true)
|
||||
@@ -269,6 +312,13 @@ Model::Thread::Thread(Team* team, const system_profiler_thread_added* event,
|
||||
|
||||
Model::Thread::~Thread()
|
||||
{
|
||||
if (fIORequests != NULL) {
|
||||
for (size_t i = 0; i < fIORequestCount; i++)
|
||||
fIORequests[i]->Delete();
|
||||
|
||||
delete[] fIORequests;
|
||||
}
|
||||
|
||||
delete[] fEvents;
|
||||
}
|
||||
|
||||
@@ -282,6 +332,14 @@ Model::Thread::SetEvents(system_profiler_event_header** events,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Model::Thread::SetIORequests(IORequest** requests, size_t requestCount)
|
||||
{
|
||||
fIORequests = requests;
|
||||
fIORequestCount = requestCount;
|
||||
}
|
||||
|
||||
|
||||
Model::ThreadWaitObjectGroup*
|
||||
Model::Thread::ThreadWaitObjectGroupFor(uint32 type, addr_t object) const
|
||||
{
|
||||
@@ -395,6 +453,14 @@ Model::Thread::AddThreadWaitObject(WaitObject* waitObject,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Model::Thread::SetIOs(int64 count, nanotime_t time)
|
||||
{
|
||||
fIOCount = count;
|
||||
fIOTime = time;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - SchedulingState
|
||||
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ public:
|
||||
struct creation_time_id;
|
||||
struct type_and_object;
|
||||
class CPU;
|
||||
struct IOOperation;
|
||||
struct IORequest;
|
||||
class WaitObjectGroup;
|
||||
class WaitObject;
|
||||
class ThreadWaitObject;
|
||||
@@ -176,6 +178,40 @@ private:
|
||||
};
|
||||
|
||||
|
||||
struct Model::IOOperation {
|
||||
system_profiler_io_operation_started* startedEvent;
|
||||
system_profiler_io_operation_finished* finishedEvent;
|
||||
};
|
||||
|
||||
|
||||
struct Model::IORequest {
|
||||
system_profiler_io_request_scheduled* scheduledEvent;
|
||||
system_profiler_io_request_finished* finishedEvent;
|
||||
size_t operationCount;
|
||||
IOOperation operations[0];
|
||||
|
||||
static IORequest* Create(
|
||||
system_profiler_io_request_scheduled*
|
||||
scheduledEvent,
|
||||
system_profiler_io_request_finished*
|
||||
finishedEvent,
|
||||
size_t operationCount);
|
||||
void Delete();
|
||||
|
||||
static inline bool SchedulerTimeLess(const IORequest* a,
|
||||
const IORequest* b);
|
||||
|
||||
private:
|
||||
IORequest(
|
||||
system_profiler_io_request_scheduled*
|
||||
scheduledEvent,
|
||||
system_profiler_io_request_finished*
|
||||
finishedEvent,
|
||||
size_t operationCount);
|
||||
~IORequest();
|
||||
};
|
||||
|
||||
|
||||
class Model::WaitObject {
|
||||
public:
|
||||
WaitObject(
|
||||
@@ -354,6 +390,11 @@ public:
|
||||
void SetEvents(system_profiler_event_header** events,
|
||||
size_t eventCount);
|
||||
|
||||
inline IORequest** IORequests() const;
|
||||
inline size_t CountIORequests() const;
|
||||
void SetIORequests(IORequest** requests,
|
||||
size_t requestCount);
|
||||
|
||||
inline nanotime_t CreationTime() const;
|
||||
inline nanotime_t DeletionTime() const;
|
||||
|
||||
@@ -368,6 +409,9 @@ public:
|
||||
inline nanotime_t TotalWaitTime() const;
|
||||
inline nanotime_t UnspecifiedWaitTime() const;
|
||||
|
||||
inline int64 IOCount() const;
|
||||
inline nanotime_t IOTime() const;
|
||||
|
||||
ThreadWaitObjectGroup* ThreadWaitObjectGroupFor(uint32 type,
|
||||
addr_t object) const;
|
||||
inline int32 CountThreadWaitObjectGroups() const;
|
||||
@@ -386,6 +430,8 @@ public:
|
||||
ThreadWaitObjectGroup**
|
||||
_threadWaitObjectGroup);
|
||||
|
||||
void SetIOs(int64 count, nanotime_t time);
|
||||
|
||||
static inline int CompareByID(const Thread* a, const Thread* b);
|
||||
static inline int CompareWithID(const thread_id* id,
|
||||
const Thread* thread);
|
||||
@@ -404,6 +450,9 @@ private:
|
||||
system_profiler_event_header** fEvents;
|
||||
size_t fEventCount;
|
||||
|
||||
IORequest** fIORequests;
|
||||
size_t fIORequestCount;
|
||||
|
||||
Team* fTeam;
|
||||
const system_profiler_thread_added* fCreationEvent;
|
||||
nanotime_t fCreationTime;
|
||||
@@ -428,6 +477,9 @@ private:
|
||||
nanotime_t fTotalWaitTime;
|
||||
nanotime_t fUnspecifiedWaitTime;
|
||||
|
||||
int64 fIOCount;
|
||||
nanotime_t fIOTime;
|
||||
|
||||
int64 fPreemptions;
|
||||
|
||||
int32 fIndex;
|
||||
@@ -620,6 +672,20 @@ Model::CPU::IdleTime() const
|
||||
// #pragma mark - WaitObject
|
||||
|
||||
|
||||
/*static*/ bool
|
||||
Model::IORequest::SchedulerTimeLess(const IORequest* a, const IORequest* b)
|
||||
{
|
||||
int32 cmp = a->scheduledEvent->scheduler - b->scheduledEvent->scheduler;
|
||||
if (cmp != 0)
|
||||
return cmp < 0;
|
||||
|
||||
return a->scheduledEvent->time < b->scheduledEvent->time;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - WaitObject
|
||||
|
||||
|
||||
uint32
|
||||
Model::WaitObject::Type() const
|
||||
{
|
||||
@@ -991,6 +1057,20 @@ Model::Thread::CountEvents() const
|
||||
}
|
||||
|
||||
|
||||
Model::IORequest**
|
||||
Model::Thread::IORequests() const
|
||||
{
|
||||
return fIORequests;
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
Model::Thread::CountIORequests() const
|
||||
{
|
||||
return fIORequestCount;
|
||||
}
|
||||
|
||||
|
||||
int64
|
||||
Model::Thread::Runs() const
|
||||
{
|
||||
@@ -1061,6 +1141,20 @@ Model::Thread::UnspecifiedWaitTime() const
|
||||
}
|
||||
|
||||
|
||||
int64
|
||||
Model::Thread::IOCount() const
|
||||
{
|
||||
return fIOCount;
|
||||
}
|
||||
|
||||
|
||||
nanotime_t
|
||||
Model::Thread::IOTime() const
|
||||
{
|
||||
return fIOTime;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Model::Thread::CountThreadWaitObjectGroups() const
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <new>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
@@ -60,6 +61,108 @@ struct ModelLoader::CPUInfo {
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - IOOperation
|
||||
|
||||
|
||||
struct ModelLoader::IOOperation : DoublyLinkedListLinkImpl<IOOperation> {
|
||||
io_operation_started* startedEvent;
|
||||
io_operation_finished* finishedEvent;
|
||||
|
||||
IOOperation(io_operation_started* startedEvent)
|
||||
:
|
||||
startedEvent(startedEvent),
|
||||
finishedEvent(NULL)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - IORequest
|
||||
|
||||
|
||||
struct ModelLoader::IORequest : DoublyLinkedListLinkImpl<IORequest> {
|
||||
io_request_scheduled* scheduledEvent;
|
||||
io_request_finished* finishedEvent;
|
||||
IOOperationList operations;
|
||||
size_t operationCount;
|
||||
IORequest* hashNext;
|
||||
|
||||
IORequest(io_request_scheduled* scheduledEvent)
|
||||
:
|
||||
scheduledEvent(scheduledEvent),
|
||||
finishedEvent(NULL),
|
||||
operationCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
~IORequest()
|
||||
{
|
||||
while (IOOperation* operation = operations.RemoveHead())
|
||||
delete operation;
|
||||
}
|
||||
|
||||
void AddOperation(IOOperation* operation)
|
||||
{
|
||||
operations.Add(operation);
|
||||
operationCount++;
|
||||
}
|
||||
|
||||
IOOperation* FindOperation(void* address) const
|
||||
{
|
||||
for (IOOperationList::ConstReverseIterator it
|
||||
= operations.GetReverseIterator();
|
||||
IOOperation* operation = it.Next();) {
|
||||
if (operation->startedEvent->operation == address)
|
||||
return operation;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Model::IORequest* CreateModelRequest() const
|
||||
{
|
||||
size_t operationCount = operations.Count();
|
||||
|
||||
Model::IORequest* modelRequest = Model::IORequest::Create(
|
||||
scheduledEvent, finishedEvent, operationCount);
|
||||
if (modelRequest == NULL)
|
||||
return NULL;
|
||||
|
||||
size_t index = 0;
|
||||
for (IOOperationList::ConstIterator it = operations.GetIterator();
|
||||
IOOperation* operation = it.Next();) {
|
||||
Model::IOOperation& modelOperation
|
||||
= modelRequest->operations[index++];
|
||||
modelOperation.startedEvent = operation->startedEvent;
|
||||
modelOperation.finishedEvent = operation->finishedEvent;
|
||||
}
|
||||
|
||||
return modelRequest;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - IORequestHashDefinition
|
||||
|
||||
|
||||
struct ModelLoader::IORequestHashDefinition {
|
||||
typedef void* KeyType;
|
||||
typedef IORequest ValueType;
|
||||
|
||||
size_t HashKey(KeyType key) const
|
||||
{ return (size_t)key; }
|
||||
|
||||
size_t Hash(const IORequest* value) const
|
||||
{ return HashKey(value->scheduledEvent->request); }
|
||||
|
||||
bool Compare(KeyType key, const IORequest* value) const
|
||||
{ return key == value->scheduledEvent->request; }
|
||||
|
||||
IORequest*& GetLink(IORequest* value) const
|
||||
{ return value->hashNext; }
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - ExtendedThreadSchedulingState
|
||||
|
||||
|
||||
@@ -78,6 +181,11 @@ struct ModelLoader::ExtendedThreadSchedulingState
|
||||
~ExtendedThreadSchedulingState()
|
||||
{
|
||||
delete[] fEvents;
|
||||
|
||||
while (IORequest* request = fIORequests.RemoveHead())
|
||||
delete request;
|
||||
while (IORequest* request = fPendingIORequests.RemoveHead())
|
||||
delete request;
|
||||
}
|
||||
|
||||
system_profiler_event_header** Events() const
|
||||
@@ -119,10 +227,59 @@ struct ModelLoader::ExtendedThreadSchedulingState
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddIORequest(IORequest* request)
|
||||
{
|
||||
fPendingIORequests.Add(request);
|
||||
}
|
||||
|
||||
void IORequestFinished(IORequest* request)
|
||||
{
|
||||
fPendingIORequests.Remove(request);
|
||||
fIORequests.Add(request);
|
||||
}
|
||||
|
||||
bool PrepareThreadIORequests(Model::IORequest**& _requests,
|
||||
size_t& _requestCount)
|
||||
{
|
||||
fIORequests.MoveFrom(&fPendingIORequests);
|
||||
size_t requestCount = fIORequests.Count();
|
||||
|
||||
if (requestCount == 0) {
|
||||
_requests = NULL;
|
||||
_requestCount = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
Model::IORequest** requests
|
||||
= new(std::nothrow) Model::IORequest*[requestCount];
|
||||
if (requests == NULL)
|
||||
return false;
|
||||
|
||||
size_t index = 0;
|
||||
while (IORequest* request = fIORequests.RemoveHead()) {
|
||||
ObjectDeleter<IORequest> requestDeleter(request);
|
||||
|
||||
Model::IORequest* modelRequest = request->CreateModelRequest();
|
||||
if (modelRequest == NULL) {
|
||||
for (size_t i = 0; i < index; i++)
|
||||
requests[i]->Delete();
|
||||
return false;
|
||||
}
|
||||
|
||||
requests[index++] = modelRequest;
|
||||
}
|
||||
|
||||
_requests = requests;
|
||||
_requestCount = requestCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
system_profiler_event_header** fEvents;
|
||||
size_t fEventIndex;
|
||||
size_t fEventCount;
|
||||
IORequestList fIORequests;
|
||||
IORequestList fPendingIORequests;
|
||||
};
|
||||
|
||||
|
||||
@@ -168,7 +325,9 @@ ModelLoader::ModelLoader(DataSource* dataSource,
|
||||
AbstractModelLoader(target, targetCookie),
|
||||
fModel(NULL),
|
||||
fDataSource(dataSource),
|
||||
fCPUInfos(NULL)
|
||||
fCPUInfos(NULL),
|
||||
fState(NULL),
|
||||
fIORequests(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -178,6 +337,8 @@ ModelLoader::~ModelLoader()
|
||||
delete[] fCPUInfos;
|
||||
delete fDataSource;
|
||||
delete fModel;
|
||||
delete fState;
|
||||
delete fIORequests;
|
||||
}
|
||||
|
||||
|
||||
@@ -211,10 +372,16 @@ ModelLoader::PrepareForLoading()
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// create CPU info array
|
||||
fCPUInfos = new(std::nothrow) CPUInfo[kMaxCPUCount];
|
||||
if (fCPUInfos == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
// create IORequest hash table
|
||||
fIORequests = new(std::nothrow) IORequestTable;
|
||||
if (fIORequests == NULL || fIORequests->Init() != B_OK)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -243,6 +410,18 @@ ModelLoader::FinishLoading(bool success)
|
||||
|
||||
delete[] fCPUInfos;
|
||||
fCPUInfos = NULL;
|
||||
|
||||
if (fIORequests != NULL) {
|
||||
IORequest* request = fIORequests->Clear(true);
|
||||
while (request != NULL) {
|
||||
IORequest* next = request->hashNext;
|
||||
delete request;
|
||||
request = next;
|
||||
}
|
||||
|
||||
delete fIORequests;
|
||||
fIORequests = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -340,7 +519,7 @@ ModelLoader::_Load()
|
||||
|
||||
fModel->SetLastEventTime(fState->LastEventTime());
|
||||
|
||||
if (!_SetThreadEvents())
|
||||
if (!_SetThreadEvents() || !_SetThreadIORequests())
|
||||
return B_NO_MEMORY;
|
||||
|
||||
fModel->LoadingFinished();
|
||||
@@ -530,10 +709,20 @@ ModelLoader::_ProcessEvent(uint32 event, uint32 cpu, const void* buffer,
|
||||
|
||||
case B_SYSTEM_PROFILER_IO_SCHEDULER_ADDED:
|
||||
case B_SYSTEM_PROFILER_IO_SCHEDULER_REMOVED:
|
||||
// TODO: Handle!
|
||||
break;
|
||||
|
||||
case B_SYSTEM_PROFILER_IO_REQUEST_SCHEDULED:
|
||||
_HandleIORequestScheduled((io_request_scheduled*)buffer);
|
||||
break;
|
||||
case B_SYSTEM_PROFILER_IO_REQUEST_FINISHED:
|
||||
_HandleIORequestFinished((io_request_finished*)buffer);
|
||||
break;
|
||||
case B_SYSTEM_PROFILER_IO_OPERATION_STARTED:
|
||||
_HandleIOOperationStarted((io_operation_started*)buffer);
|
||||
break;
|
||||
case B_SYSTEM_PROFILER_IO_OPERATION_FINISHED:
|
||||
_HandleIOOperationFinished((io_operation_finished*)buffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -628,6 +817,67 @@ ModelLoader::_SetThreadEvents()
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ModelLoader::_SetThreadIORequests()
|
||||
{
|
||||
for (int32 i = 0; Model::Thread* thread = fModel->ThreadAt(i); i++) {
|
||||
ExtendedThreadSchedulingState* state
|
||||
= fState->LookupThread(thread->ID());
|
||||
Model::IORequest** requests;
|
||||
size_t requestCount;
|
||||
if (!state->PrepareThreadIORequests(requests, requestCount))
|
||||
return false;
|
||||
if (requestCount > 0)
|
||||
_SetThreadIORequests(thread, requests, requestCount);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ModelLoader::_SetThreadIORequests(Model::Thread* thread,
|
||||
Model::IORequest** requests, size_t requestCount)
|
||||
{
|
||||
// compute some totals
|
||||
int64 ioCount = 0;
|
||||
nanotime_t ioTime = 0;
|
||||
|
||||
// sort requests by scheduler and start time
|
||||
std::sort(requests, requests + requestCount,
|
||||
Model::IORequest::SchedulerTimeLess);
|
||||
|
||||
nanotime_t endTime = fBaseTime + fModel->LastEventTime();
|
||||
|
||||
// compute the summed up I/O times
|
||||
nanotime_t ioStart = requests[0]->scheduledEvent->time;
|
||||
nanotime_t previousEnd = requests[0]->finishedEvent != NULL
|
||||
? requests[0]->finishedEvent->time : endTime;
|
||||
int32 scheduler = requests[0]->scheduledEvent->scheduler;
|
||||
|
||||
for (size_t i = 1; i < requestCount; i++) {
|
||||
system_profiler_io_request_scheduled* scheduledEvent
|
||||
= requests[i]->scheduledEvent;
|
||||
if (scheduledEvent->scheduler != scheduler
|
||||
|| scheduledEvent->time >= previousEnd) {
|
||||
ioCount++;
|
||||
ioTime += previousEnd - ioStart;
|
||||
ioStart = scheduledEvent->time;
|
||||
}
|
||||
|
||||
previousEnd = requests[i]->finishedEvent != NULL
|
||||
? requests[i]->finishedEvent->time : endTime;
|
||||
}
|
||||
|
||||
ioCount++;
|
||||
ioTime += previousEnd - ioStart;
|
||||
|
||||
// set the computed values
|
||||
thread->SetIORequests(requests, requestCount);
|
||||
thread->SetIOs(ioCount, ioTime);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ModelLoader::_HandleTeamAdded(system_profiler_team_added* event)
|
||||
{
|
||||
@@ -858,6 +1108,75 @@ ModelLoader::_HandleWaitObjectInfo(system_profiler_wait_object_info* event)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ModelLoader::_HandleIORequestScheduled(io_request_scheduled* event)
|
||||
{
|
||||
IORequest* request = fIORequests->Lookup(event->request);
|
||||
if (request != NULL) {
|
||||
printf("Duplicate schedule event for I/O request %p\n", event->request);
|
||||
return;
|
||||
}
|
||||
|
||||
ExtendedThreadSchedulingState* thread = fState->LookupThread(event->thread);
|
||||
if (thread == NULL) {
|
||||
printf("I/O request for unknown thread %ld\n", event->thread);
|
||||
return;
|
||||
}
|
||||
|
||||
request = new(std::nothrow) IORequest(event);
|
||||
if (request == NULL)
|
||||
throw std::bad_alloc();
|
||||
|
||||
fIORequests->Insert(request);
|
||||
thread->AddIORequest(request);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ModelLoader::_HandleIORequestFinished(io_request_finished* event)
|
||||
{
|
||||
IORequest* request = fIORequests->Lookup(event->request);
|
||||
if (request == NULL)
|
||||
return;
|
||||
|
||||
request->finishedEvent = event;
|
||||
|
||||
fIORequests->Remove(request);
|
||||
fState->LookupThread(request->scheduledEvent->thread)
|
||||
->IORequestFinished(request);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ModelLoader::_HandleIOOperationStarted(io_operation_started* event)
|
||||
{
|
||||
IORequest* request = fIORequests->Lookup(event->request);
|
||||
if (request == NULL)
|
||||
return;
|
||||
|
||||
IOOperation* operation = new(std::nothrow) IOOperation(event);
|
||||
if (operation == NULL)
|
||||
throw std::bad_alloc();
|
||||
|
||||
request->AddOperation(operation);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ModelLoader::_HandleIOOperationFinished(io_operation_finished* event)
|
||||
{
|
||||
IORequest* request = fIORequests->Lookup(event->request);
|
||||
if (request == NULL)
|
||||
return;
|
||||
|
||||
IOOperation* operation = request->FindOperation(event->operation);
|
||||
if (operation == NULL)
|
||||
return;
|
||||
|
||||
operation->finishedEvent = event;
|
||||
}
|
||||
|
||||
|
||||
ModelLoader::ExtendedThreadSchedulingState*
|
||||
ModelLoader::_AddThread(system_profiler_thread_added* event)
|
||||
{
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#define MAIN_MODEL_LOADER_H
|
||||
|
||||
|
||||
#include <util/DoublyLinkedList.h>
|
||||
|
||||
#include "AbstractModelLoader.h"
|
||||
#include "Model.h"
|
||||
|
||||
@@ -39,11 +41,22 @@ private:
|
||||
thread_enqueued_in_run_queue;
|
||||
typedef system_profiler_thread_removed_from_run_queue
|
||||
thread_removed_from_run_queue;
|
||||
typedef system_profiler_io_request_scheduled io_request_scheduled;
|
||||
typedef system_profiler_io_request_finished io_request_finished;
|
||||
typedef system_profiler_io_operation_started io_operation_started;
|
||||
typedef system_profiler_io_operation_finished io_operation_finished;
|
||||
|
||||
struct CPUInfo;
|
||||
struct IOOperation;
|
||||
struct IORequest;
|
||||
struct IORequestHashDefinition;
|
||||
struct ExtendedThreadSchedulingState;
|
||||
struct ExtendedSchedulingState;
|
||||
|
||||
typedef DoublyLinkedList<ModelLoader::IOOperation> IOOperationList;
|
||||
typedef DoublyLinkedList<ModelLoader::IORequest> IORequestList;
|
||||
typedef BOpenHashTable<IORequestHashDefinition> IORequestTable;
|
||||
|
||||
private:
|
||||
status_t _Load();
|
||||
status_t _ReadDebugEvents(void** _eventData,
|
||||
@@ -55,6 +68,10 @@ private:
|
||||
status_t _ProcessEvent(uint32 event, uint32 cpu,
|
||||
const void* buffer, size_t size);
|
||||
bool _SetThreadEvents();
|
||||
bool _SetThreadIORequests();
|
||||
void _SetThreadIORequests(Model::Thread* thread,
|
||||
Model::IORequest** requests,
|
||||
size_t requestCount);
|
||||
|
||||
inline void _UpdateLastEventTime(nanotime_t time);
|
||||
|
||||
@@ -76,6 +93,14 @@ private:
|
||||
thread_removed_from_run_queue* event);
|
||||
void _HandleWaitObjectInfo(
|
||||
system_profiler_wait_object_info* event);
|
||||
void _HandleIORequestScheduled(
|
||||
io_request_scheduled* event);
|
||||
void _HandleIORequestFinished(
|
||||
io_request_finished* event);
|
||||
void _HandleIOOperationStarted(
|
||||
io_operation_started* event);
|
||||
void _HandleIOOperationFinished(
|
||||
io_operation_finished* event);
|
||||
|
||||
ExtendedThreadSchedulingState* _AddThread(
|
||||
system_profiler_thread_added* event);
|
||||
@@ -91,6 +116,7 @@ private:
|
||||
CPUInfo* fCPUInfos;
|
||||
nanotime_t fBaseTime;
|
||||
ExtendedSchedulingState* fState;
|
||||
IORequestTable* fIORequests;
|
||||
uint32 fMaxCPUIndex;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user