* 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:
Ingo Weinhold
2009-12-21 21:05:36 +00:00
parent 1c12dcb598
commit 934a8d0113
4 changed files with 172 additions and 5 deletions
+53
View File
@@ -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)
+77 -1
View File
@@ -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(