* Model: Added class IOScheduler, a list of IOSchedulers, and a methods to
access it.
* ModelLoader:
- Also add IOSchedulers to the model.
- Sort the per thread list of IORequests by start time.
- Added a bit of output in the _HandleIO*() methods when we don't know a
request or operation.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34738 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -114,6 +114,18 @@ Model::IORequest::~IORequest()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - IOScheduler
|
||||||
|
|
||||||
|
|
||||||
|
Model::IOScheduler::IOScheduler(system_profiler_io_scheduler_added* event,
|
||||||
|
int32 index)
|
||||||
|
:
|
||||||
|
fAddedEvent(event),
|
||||||
|
fIndex(index)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - WaitObject
|
// #pragma mark - WaitObject
|
||||||
|
|
||||||
|
|
||||||
@@ -601,6 +613,7 @@ Model::Model(const char* dataSourceName, void* eventData, size_t eventDataSize,
|
|||||||
fTeams(20, true),
|
fTeams(20, true),
|
||||||
fThreads(20, true),
|
fThreads(20, true),
|
||||||
fWaitObjectGroups(20, true),
|
fWaitObjectGroups(20, true),
|
||||||
|
fIOSchedulers(10, true),
|
||||||
fSchedulingStates(100)
|
fSchedulingStates(100)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -899,6 +912,46 @@ Model::ThreadWaitObjectGroupFor(thread_id threadID, uint32 type, addr_t object)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
Model::CountIOSchedulers() const
|
||||||
|
{
|
||||||
|
return fIOSchedulers.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Model::IOScheduler*
|
||||||
|
Model::IOSchedulerAt(int32 index) const
|
||||||
|
{
|
||||||
|
return fIOSchedulers.ItemAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Model::IOScheduler*
|
||||||
|
Model::IOSchedulerByID(int32 id) const
|
||||||
|
{
|
||||||
|
for (int32 i = 0; IOScheduler* scheduler = fIOSchedulers.ItemAt(i); i++) {
|
||||||
|
if (scheduler->ID() == id)
|
||||||
|
return scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Model::IOScheduler*
|
||||||
|
Model::AddIOScheduler(system_profiler_io_scheduler_added* event)
|
||||||
|
{
|
||||||
|
IOScheduler* scheduler = new(std::nothrow) IOScheduler(event,
|
||||||
|
fIOSchedulers.CountItems());
|
||||||
|
if (scheduler == NULL || !fIOSchedulers.AddItem(scheduler)) {
|
||||||
|
delete scheduler;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Model::AddSchedulingStateSnapshot(const SchedulingState& state,
|
Model::AddSchedulingStateSnapshot(const SchedulingState& state,
|
||||||
off_t eventOffset)
|
off_t eventOffset)
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public:
|
|||||||
class CPU;
|
class CPU;
|
||||||
struct IOOperation;
|
struct IOOperation;
|
||||||
struct IORequest;
|
struct IORequest;
|
||||||
|
class IOScheduler;
|
||||||
class WaitObjectGroup;
|
class WaitObjectGroup;
|
||||||
class WaitObject;
|
class WaitObject;
|
||||||
class ThreadWaitObject;
|
class ThreadWaitObject;
|
||||||
@@ -116,6 +117,12 @@ public:
|
|||||||
thread_id threadID, uint32 type,
|
thread_id threadID, uint32 type,
|
||||||
addr_t object) const;
|
addr_t object) const;
|
||||||
|
|
||||||
|
int32 CountIOSchedulers() const;
|
||||||
|
IOScheduler* IOSchedulerAt(int32 index) const;
|
||||||
|
IOScheduler* IOSchedulerByID(int32 id) const;
|
||||||
|
IOScheduler* AddIOScheduler(
|
||||||
|
system_profiler_io_scheduler_added* event);
|
||||||
|
|
||||||
bool AddSchedulingStateSnapshot(
|
bool AddSchedulingStateSnapshot(
|
||||||
const SchedulingState& state,
|
const SchedulingState& state,
|
||||||
off_t eventOffset);
|
off_t eventOffset);
|
||||||
@@ -129,6 +136,7 @@ private:
|
|||||||
typedef BObjectList<Team> TeamList;
|
typedef BObjectList<Team> TeamList;
|
||||||
typedef BObjectList<Thread> ThreadList;
|
typedef BObjectList<Thread> ThreadList;
|
||||||
typedef BObjectList<WaitObjectGroup> WaitObjectGroupList;
|
typedef BObjectList<WaitObjectGroup> WaitObjectGroupList;
|
||||||
|
typedef BObjectList<IOScheduler> IOSchedulerList;
|
||||||
typedef BObjectList<CompactSchedulingState> SchedulingStateList;
|
typedef BObjectList<CompactSchedulingState> SchedulingStateList;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -150,6 +158,7 @@ private:
|
|||||||
TeamList fTeams; // sorted by ID
|
TeamList fTeams; // sorted by ID
|
||||||
ThreadList fThreads; // sorted by ID
|
ThreadList fThreads; // sorted by ID
|
||||||
WaitObjectGroupList fWaitObjectGroups;
|
WaitObjectGroupList fWaitObjectGroups;
|
||||||
|
IOSchedulerList fIOSchedulers;
|
||||||
SchedulingStateList fSchedulingStates;
|
SchedulingStateList fSchedulingStates;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -181,6 +190,9 @@ private:
|
|||||||
struct Model::IOOperation {
|
struct Model::IOOperation {
|
||||||
system_profiler_io_operation_started* startedEvent;
|
system_profiler_io_operation_started* startedEvent;
|
||||||
system_profiler_io_operation_finished* finishedEvent;
|
system_profiler_io_operation_finished* finishedEvent;
|
||||||
|
|
||||||
|
static inline int CompareByTime(const IOOperation* a,
|
||||||
|
const IOOperation* b);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -198,6 +210,8 @@ struct Model::IORequest {
|
|||||||
size_t operationCount);
|
size_t operationCount);
|
||||||
void Delete();
|
void Delete();
|
||||||
|
|
||||||
|
static inline bool TimeLess(const IORequest* a,
|
||||||
|
const IORequest* b);
|
||||||
static inline bool SchedulerTimeLess(const IORequest* a,
|
static inline bool SchedulerTimeLess(const IORequest* a,
|
||||||
const IORequest* b);
|
const IORequest* b);
|
||||||
|
|
||||||
@@ -212,6 +226,22 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Model::IOScheduler {
|
||||||
|
public:
|
||||||
|
IOScheduler(
|
||||||
|
system_profiler_io_scheduler_added* event,
|
||||||
|
int32 index);
|
||||||
|
|
||||||
|
inline int32 ID() const;
|
||||||
|
inline const char* Name() const;
|
||||||
|
inline int32 Index() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
system_profiler_io_scheduler_added* fAddedEvent;
|
||||||
|
int32 fIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Model::WaitObject {
|
class Model::WaitObject {
|
||||||
public:
|
public:
|
||||||
WaitObject(
|
WaitObject(
|
||||||
@@ -669,7 +699,29 @@ Model::CPU::IdleTime() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - WaitObject
|
// #pragma mark - IOOperation
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ int
|
||||||
|
Model::IOOperation::CompareByTime(const IOOperation* a, const IOOperation* b)
|
||||||
|
{
|
||||||
|
nanotime_t timeA = a->startedEvent->time;
|
||||||
|
nanotime_t timeB = b->startedEvent->time;
|
||||||
|
|
||||||
|
if (timeA < timeB)
|
||||||
|
return -1;
|
||||||
|
return timeA == timeB ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - IORequest
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ bool
|
||||||
|
Model::IORequest::TimeLess(const IORequest* a, const IORequest* b)
|
||||||
|
{
|
||||||
|
return a->scheduledEvent->time < b->scheduledEvent->time;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/ bool
|
/*static*/ bool
|
||||||
@@ -683,6 +735,30 @@ Model::IORequest::SchedulerTimeLess(const IORequest* a, const IORequest* b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - IOScheduler
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
Model::IOScheduler::ID() const
|
||||||
|
{
|
||||||
|
return fAddedEvent->scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
Model::IOScheduler::Name() const
|
||||||
|
{
|
||||||
|
return fAddedEvent->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
Model::IOScheduler::Index() const
|
||||||
|
{
|
||||||
|
return fIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - WaitObject
|
// #pragma mark - WaitObject
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -708,8 +708,12 @@ ModelLoader::_ProcessEvent(uint32 event, uint32 cpu, const void* buffer,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case B_SYSTEM_PROFILER_IO_SCHEDULER_ADDED:
|
case B_SYSTEM_PROFILER_IO_SCHEDULER_ADDED:
|
||||||
|
_HandleIOSchedulerAdded(
|
||||||
|
(system_profiler_io_scheduler_added*)buffer);
|
||||||
|
break;
|
||||||
|
|
||||||
case B_SYSTEM_PROFILER_IO_SCHEDULER_REMOVED:
|
case B_SYSTEM_PROFILER_IO_SCHEDULER_REMOVED:
|
||||||
// TODO: Handle!
|
// not so interesting
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_SYSTEM_PROFILER_IO_REQUEST_SCHEDULED:
|
case B_SYSTEM_PROFILER_IO_REQUEST_SCHEDULED:
|
||||||
@@ -872,6 +876,9 @@ ModelLoader::_SetThreadIORequests(Model::Thread* thread,
|
|||||||
ioCount++;
|
ioCount++;
|
||||||
ioTime += previousEnd - ioStart;
|
ioTime += previousEnd - ioStart;
|
||||||
|
|
||||||
|
// sort requests by start time
|
||||||
|
std::sort(requests, requests + requestCount, Model::IORequest::TimeLess);
|
||||||
|
|
||||||
// set the computed values
|
// set the computed values
|
||||||
thread->SetIORequests(requests, requestCount);
|
thread->SetIORequests(requests, requestCount);
|
||||||
thread->SetIOs(ioCount, ioTime);
|
thread->SetIOs(ioCount, ioTime);
|
||||||
@@ -1108,6 +1115,21 @@ ModelLoader::_HandleWaitObjectInfo(system_profiler_wait_object_info* event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ModelLoader::_HandleIOSchedulerAdded(system_profiler_io_scheduler_added* event)
|
||||||
|
{
|
||||||
|
Model::IOScheduler* scheduler = fModel->IOSchedulerByID(event->scheduler);
|
||||||
|
if (scheduler != NULL) {
|
||||||
|
printf("Duplicate added event for I/O scheduler %ld\n",
|
||||||
|
event->scheduler);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fModel->AddIOScheduler(event) == NULL)
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ModelLoader::_HandleIORequestScheduled(io_request_scheduled* event)
|
ModelLoader::_HandleIORequestScheduled(io_request_scheduled* event)
|
||||||
{
|
{
|
||||||
@@ -1123,6 +1145,11 @@ ModelLoader::_HandleIORequestScheduled(io_request_scheduled* event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fModel->IOSchedulerByID(event->scheduler) == NULL) {
|
||||||
|
printf("I/O requests for unknown scheduler %ld\n", event->scheduler);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
request = new(std::nothrow) IORequest(event);
|
request = new(std::nothrow) IORequest(event);
|
||||||
if (request == NULL)
|
if (request == NULL)
|
||||||
throw std::bad_alloc();
|
throw std::bad_alloc();
|
||||||
@@ -1151,8 +1178,11 @@ void
|
|||||||
ModelLoader::_HandleIOOperationStarted(io_operation_started* event)
|
ModelLoader::_HandleIOOperationStarted(io_operation_started* event)
|
||||||
{
|
{
|
||||||
IORequest* request = fIORequests->Lookup(event->request);
|
IORequest* request = fIORequests->Lookup(event->request);
|
||||||
if (request == NULL)
|
if (request == NULL) {
|
||||||
|
printf("ModelLoader::_HandleIOOperationStarted(): I/O request for operation %p not found\n",
|
||||||
|
event->operation);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IOOperation* operation = new(std::nothrow) IOOperation(event);
|
IOOperation* operation = new(std::nothrow) IOOperation(event);
|
||||||
if (operation == NULL)
|
if (operation == NULL)
|
||||||
@@ -1166,12 +1196,18 @@ void
|
|||||||
ModelLoader::_HandleIOOperationFinished(io_operation_finished* event)
|
ModelLoader::_HandleIOOperationFinished(io_operation_finished* event)
|
||||||
{
|
{
|
||||||
IORequest* request = fIORequests->Lookup(event->request);
|
IORequest* request = fIORequests->Lookup(event->request);
|
||||||
if (request == NULL)
|
if (request == NULL) {
|
||||||
|
printf("ModelLoader::_HandleIOOperationFinished(): I/O request for "
|
||||||
|
"operation %p not found\n", event->operation);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IOOperation* operation = request->FindOperation(event->operation);
|
IOOperation* operation = request->FindOperation(event->operation);
|
||||||
if (operation == NULL)
|
if (operation == NULL) {
|
||||||
|
printf("ModelLoader::_HandleIOOperationFinished(): operation %p not "
|
||||||
|
"found\n", event->operation);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
operation->finishedEvent = event;
|
operation->finishedEvent = event;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ private:
|
|||||||
thread_removed_from_run_queue* event);
|
thread_removed_from_run_queue* event);
|
||||||
void _HandleWaitObjectInfo(
|
void _HandleWaitObjectInfo(
|
||||||
system_profiler_wait_object_info* event);
|
system_profiler_wait_object_info* event);
|
||||||
|
void _HandleIOSchedulerAdded(
|
||||||
|
system_profiler_io_scheduler_added* event);
|
||||||
void _HandleIORequestScheduled(
|
void _HandleIORequestScheduled(
|
||||||
io_request_scheduled* event);
|
io_request_scheduled* event);
|
||||||
void _HandleIORequestFinished(
|
void _HandleIORequestFinished(
|
||||||
|
|||||||
Reference in New Issue
Block a user