* 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
|
||||
|
||||
|
||||
@@ -601,6 +613,7 @@ Model::Model(const char* dataSourceName, void* eventData, size_t eventDataSize,
|
||||
fTeams(20, true),
|
||||
fThreads(20, true),
|
||||
fWaitObjectGroups(20, true),
|
||||
fIOSchedulers(10, true),
|
||||
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
|
||||
Model::AddSchedulingStateSnapshot(const SchedulingState& state,
|
||||
off_t eventOffset)
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
class CPU;
|
||||
struct IOOperation;
|
||||
struct IORequest;
|
||||
class IOScheduler;
|
||||
class WaitObjectGroup;
|
||||
class WaitObject;
|
||||
class ThreadWaitObject;
|
||||
@@ -116,6 +117,12 @@ public:
|
||||
thread_id threadID, uint32 type,
|
||||
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(
|
||||
const SchedulingState& state,
|
||||
off_t eventOffset);
|
||||
@@ -129,6 +136,7 @@ private:
|
||||
typedef BObjectList<Team> TeamList;
|
||||
typedef BObjectList<Thread> ThreadList;
|
||||
typedef BObjectList<WaitObjectGroup> WaitObjectGroupList;
|
||||
typedef BObjectList<IOScheduler> IOSchedulerList;
|
||||
typedef BObjectList<CompactSchedulingState> SchedulingStateList;
|
||||
|
||||
private:
|
||||
@@ -150,6 +158,7 @@ private:
|
||||
TeamList fTeams; // sorted by ID
|
||||
ThreadList fThreads; // sorted by ID
|
||||
WaitObjectGroupList fWaitObjectGroups;
|
||||
IOSchedulerList fIOSchedulers;
|
||||
SchedulingStateList fSchedulingStates;
|
||||
};
|
||||
|
||||
@@ -181,6 +190,9 @@ private:
|
||||
struct Model::IOOperation {
|
||||
system_profiler_io_operation_started* startedEvent;
|
||||
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);
|
||||
void Delete();
|
||||
|
||||
static inline bool TimeLess(const IORequest* a,
|
||||
const IORequest* b);
|
||||
static inline bool SchedulerTimeLess(const IORequest* a,
|
||||
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 {
|
||||
public:
|
||||
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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -708,8 +708,12 @@ ModelLoader::_ProcessEvent(uint32 event, uint32 cpu, const void* buffer,
|
||||
break;
|
||||
|
||||
case B_SYSTEM_PROFILER_IO_SCHEDULER_ADDED:
|
||||
_HandleIOSchedulerAdded(
|
||||
(system_profiler_io_scheduler_added*)buffer);
|
||||
break;
|
||||
|
||||
case B_SYSTEM_PROFILER_IO_SCHEDULER_REMOVED:
|
||||
// TODO: Handle!
|
||||
// not so interesting
|
||||
break;
|
||||
|
||||
case B_SYSTEM_PROFILER_IO_REQUEST_SCHEDULED:
|
||||
@@ -872,6 +876,9 @@ ModelLoader::_SetThreadIORequests(Model::Thread* thread,
|
||||
ioCount++;
|
||||
ioTime += previousEnd - ioStart;
|
||||
|
||||
// sort requests by start time
|
||||
std::sort(requests, requests + requestCount, Model::IORequest::TimeLess);
|
||||
|
||||
// set the computed values
|
||||
thread->SetIORequests(requests, requestCount);
|
||||
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
|
||||
ModelLoader::_HandleIORequestScheduled(io_request_scheduled* event)
|
||||
{
|
||||
@@ -1123,6 +1145,11 @@ ModelLoader::_HandleIORequestScheduled(io_request_scheduled* event)
|
||||
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);
|
||||
if (request == NULL)
|
||||
throw std::bad_alloc();
|
||||
@@ -1151,8 +1178,11 @@ void
|
||||
ModelLoader::_HandleIOOperationStarted(io_operation_started* event)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
IOOperation* operation = new(std::nothrow) IOOperation(event);
|
||||
if (operation == NULL)
|
||||
@@ -1166,12 +1196,18 @@ void
|
||||
ModelLoader::_HandleIOOperationFinished(io_operation_finished* event)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
IOOperation* operation = request->FindOperation(event->operation);
|
||||
if (operation == NULL)
|
||||
if (operation == NULL) {
|
||||
printf("ModelLoader::_HandleIOOperationFinished(): operation %p not "
|
||||
"found\n", event->operation);
|
||||
return;
|
||||
}
|
||||
|
||||
operation->finishedEvent = event;
|
||||
}
|
||||
|
||||
@@ -93,6 +93,8 @@ private:
|
||||
thread_removed_from_run_queue* event);
|
||||
void _HandleWaitObjectInfo(
|
||||
system_profiler_wait_object_info* event);
|
||||
void _HandleIOSchedulerAdded(
|
||||
system_profiler_io_scheduler_added* event);
|
||||
void _HandleIORequestScheduled(
|
||||
io_request_scheduled* event);
|
||||
void _HandleIORequestFinished(
|
||||
|
||||
Reference in New Issue
Block a user