haiku/src/apps/debuganalyzer/model/Model.h

1574 lines
29 KiB
C++

/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef MODEL_H
#define MODEL_H
#include <stdlib.h>
#include <OS.h>
#include <String.h>
#include <ObjectList.h>
#include <Referenceable.h>
#include <util/OpenHashTable.h>
#include <system_profiler_defs.h>
#include <util/SinglyLinkedList.h>
enum ThreadState {
RUNNING,
STILL_RUNNING,
PREEMPTED,
READY,
WAITING,
UNKNOWN
};
const char* thread_state_name(ThreadState state);
const char* wait_object_type_name(uint32 type);
class Model : public BReferenceable {
public:
struct creation_time_id;
struct type_and_object;
class CPU;
struct IOOperation;
struct IORequest;
class IOScheduler;
class WaitObjectGroup;
class WaitObject;
class ThreadWaitObject;
class ThreadWaitObjectGroup;
class Team;
class Thread;
struct CompactThreadSchedulingState;
struct ThreadSchedulingState;
struct ThreadSchedulingStateDefinition;
typedef BOpenHashTable<ThreadSchedulingStateDefinition>
ThreadSchedulingStateTable;
class SchedulingState;
class CompactSchedulingState;
public:
Model(const char* dataSourceName,
void* eventData, size_t eventDataSize,
system_profiler_event_header** events,
size_t eventCount);
~Model();
inline const char* DataSourceName() const;
inline void* EventData() const;
inline size_t EventDataSize() const;
inline system_profiler_event_header** Events() const;
inline size_t CountEvents() const;
size_t ClosestEventIndex(nanotime_t eventTime) const;
// finds the greatest event with event
// time >= eventTime; may return
// CountEvents()
bool AddAssociatedData(void* data);
void RemoveAssociatedData(void* data);
void LoadingFinished();
inline nanotime_t BaseTime() const;
void SetBaseTime(nanotime_t time);
inline nanotime_t LastEventTime() const;
void SetLastEventTime(nanotime_t time);
inline nanotime_t IdleTime() const;
inline int32 CountCPUs() const;
bool SetCPUCount(int32 count);
inline CPU* CPUAt(int32 index) const;
int32 CountTeams() const;
Team* TeamAt(int32 index) const;
Team* TeamByID(team_id id) const;
Team* AddTeam(
const system_profiler_team_added* event,
nanotime_t time);
int32 CountThreads() const;
Thread* ThreadAt(int32 index) const;
Thread* ThreadByID(thread_id id) const;
Thread* AddThread(
const system_profiler_thread_added* event,
nanotime_t time);
WaitObject* AddWaitObject(
const system_profiler_wait_object_info*
event,
WaitObjectGroup** _waitObjectGroup);
int32 CountWaitObjectGroups() const;
WaitObjectGroup* WaitObjectGroupAt(int32 index) const;
WaitObjectGroup* WaitObjectGroupFor(uint32 type,
addr_t object) const;
ThreadWaitObject* AddThreadWaitObject(thread_id threadID,
WaitObject* waitObject,
ThreadWaitObjectGroup**
_threadWaitObjectGroup);
ThreadWaitObjectGroup* ThreadWaitObjectGroupFor(
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);
// must be added in order (of time)
const CompactSchedulingState* ClosestSchedulingState(
nanotime_t eventTime) const;
// returns the closest previous state
private:
typedef BObjectList<CPU> CPUList;
typedef BObjectList<Team> TeamList;
typedef BObjectList<Thread> ThreadList;
typedef BObjectList<WaitObjectGroup> WaitObjectGroupList;
typedef BObjectList<IOScheduler> IOSchedulerList;
typedef BObjectList<CompactSchedulingState> SchedulingStateList;
private:
static int _CompareEventTimeSchedulingState(
const nanotime_t* time,
const CompactSchedulingState* state);
private:
BString fDataSourceName;
void* fEventData;
system_profiler_event_header** fEvents;
size_t fEventDataSize;
size_t fEventCount;
int32 fCPUCount;
nanotime_t fBaseTime;
nanotime_t fLastEventTime;
nanotime_t fIdleTime;
CPUList fCPUs;
TeamList fTeams; // sorted by ID
ThreadList fThreads; // sorted by ID
WaitObjectGroupList fWaitObjectGroups;
IOSchedulerList fIOSchedulers;
SchedulingStateList fSchedulingStates;
BList fAssociatedData;
};
struct Model::creation_time_id {
nanotime_t time;
thread_id id;
};
struct Model::type_and_object {
uint32 type;
addr_t object;
};
class Model::CPU {
public:
CPU();
inline nanotime_t IdleTime() const;
void SetIdleTime(nanotime_t time);
private:
nanotime_t fIdleTime;
};
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);
inline nanotime_t StartedTime() const;
inline nanotime_t FinishedTime() const;
inline bool IsFinished() const;
inline off_t Offset() const;
inline size_t Length() const;
inline bool IsWrite() const;
inline status_t Status() const;
inline size_t BytesTransferred() const;
};
struct Model::IORequest {
system_profiler_io_request_scheduled* scheduledEvent;
system_profiler_io_request_finished* finishedEvent;
size_t operationCount;
IOOperation operations[0];
IORequest(
system_profiler_io_request_scheduled*
scheduledEvent,
system_profiler_io_request_finished*
finishedEvent,
size_t operationCount);
~IORequest();
static IORequest* Create(
system_profiler_io_request_scheduled*
scheduledEvent,
system_profiler_io_request_finished*
finishedEvent,
size_t operationCount);
void Delete();
inline nanotime_t ScheduledTime() const;
inline nanotime_t FinishedTime() const;
inline bool IsFinished() const;
inline int32 Scheduler() const;
inline off_t Offset() const;
inline size_t Length() const;
inline bool IsWrite() const;
inline uint8 Priority() const;
inline status_t Status() const;
inline size_t BytesTransferred() const;
static inline bool TimeLess(const IORequest* a,
const IORequest* b);
static inline bool SchedulerTimeLess(const IORequest* a,
const IORequest* b);
static inline int CompareSchedulerTime(const IORequest* a,
const IORequest* b);
};
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(
const system_profiler_wait_object_info*
event);
~WaitObject();
inline uint32 Type() const;
inline addr_t Object() const;
inline const char* Name() const;
inline addr_t ReferencedObject();
inline int64 Waits() const;
inline nanotime_t TotalWaitTime() const;
void AddWait(nanotime_t waitTime);
static inline int CompareByTypeObject(const WaitObject* a,
const WaitObject* b);
static inline int CompareWithTypeObject(
const type_and_object* key,
const WaitObject* object);
private:
const system_profiler_wait_object_info* fEvent;
private:
int64 fWaits;
nanotime_t fTotalWaitTime;
};
class Model::WaitObjectGroup {
public:
WaitObjectGroup(WaitObject* waitObject);
~WaitObjectGroup();
inline uint32 Type() const;
inline addr_t Object() const;
inline const char* Name() const;
int64 Waits();
nanotime_t TotalWaitTime();
inline WaitObject* MostRecentWaitObject() const;
inline int32 CountWaitObjects() const;
inline Model::WaitObject* WaitObjectAt(int32 index) const;
inline void AddWaitObject(WaitObject* waitObject);
static inline int CompareByTypeObject(const WaitObjectGroup* a,
const WaitObjectGroup* b);
static inline int CompareWithTypeObject(
const type_and_object* key,
const WaitObjectGroup* group);
private:
typedef BObjectList<WaitObject> WaitObjectList;
void _ComputeWaits();
private:
WaitObjectList fWaitObjects;
int64 fWaits;
nanotime_t fTotalWaitTime;
};
class Model::ThreadWaitObject
: public SinglyLinkedListLinkImpl<ThreadWaitObject> {
public:
ThreadWaitObject(WaitObject* waitObject);
~ThreadWaitObject();
inline WaitObject* GetWaitObject() const;
inline uint32 Type() const;
inline addr_t Object() const;
inline const char* Name() const;
inline addr_t ReferencedObject();
inline int64 Waits() const;
inline nanotime_t TotalWaitTime() const;
void AddWait(nanotime_t waitTime);
private:
WaitObject* fWaitObject;
int64 fWaits;
nanotime_t fTotalWaitTime;
};
class Model::ThreadWaitObjectGroup {
public:
ThreadWaitObjectGroup(
ThreadWaitObject* threadWaitObject);
~ThreadWaitObjectGroup();
inline uint32 Type() const;
inline addr_t Object() const;
inline const char* Name() const;
inline ThreadWaitObject* MostRecentThreadWaitObject() const;
inline WaitObject* MostRecentWaitObject() const;
inline void AddWaitObject(
ThreadWaitObject* threadWaitObject);
bool GetThreadWaitObjects(
BObjectList<ThreadWaitObject>& objects);
static inline int CompareByTypeObject(
const ThreadWaitObjectGroup* a,
const ThreadWaitObjectGroup* b);
static inline int CompareWithTypeObject(
const type_and_object* key,
const ThreadWaitObjectGroup* group);
private:
typedef SinglyLinkedList<ThreadWaitObject> ThreadWaitObjectList;
private:
ThreadWaitObjectList fWaitObjects;
};
class Model::Team {
public:
Team(const system_profiler_team_added* event,
nanotime_t time);
~Team();
inline team_id ID() const;
inline const char* Name() const;
inline nanotime_t CreationTime() const;
inline nanotime_t DeletionTime() const;
bool AddThread(Thread* thread);
inline void SetDeletionTime(nanotime_t time);
static inline int CompareByID(const Team* a, const Team* b);
static inline int CompareWithID(const team_id* id,
const Team* team);
private:
typedef BObjectList<Thread> ThreadList;
private:
const system_profiler_team_added* fCreationEvent;
nanotime_t fCreationTime;
nanotime_t fDeletionTime;
ThreadList fThreads; // sorted by creation time, ID
};
class Model::Thread {
public:
Thread(Team* team,
const system_profiler_thread_added* event,
nanotime_t time);
~Thread();
inline thread_id ID() const;
inline const char* Name() const;
inline Team* GetTeam() const;
inline int32 Index() const;
inline void SetIndex(int32 index);
inline system_profiler_event_header** Events() const;
inline size_t CountEvents() const;
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);
size_t ClosestRequestStartIndex(
nanotime_t minRequestStartTime) const;
// Returns the index of the first request
// with a start time >= minRequestStartTime.
// minRequestStartTime is absolute, not
// base time relative.
inline nanotime_t CreationTime() const;
inline nanotime_t DeletionTime() const;
inline int64 Runs() const;
inline nanotime_t TotalRunTime() const;
inline int64 Reruns() const;
inline nanotime_t TotalRerunTime() const;
inline int64 Latencies() const;
inline nanotime_t TotalLatency() const;
inline int64 Preemptions() const;
inline int64 Waits() const;
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;
inline ThreadWaitObjectGroup* ThreadWaitObjectGroupAt(int32 index) const;
inline void SetDeletionTime(nanotime_t time);
void AddRun(nanotime_t runTime);
void AddRerun(nanotime_t runTime);
void AddLatency(nanotime_t latency);
void AddPreemption(nanotime_t runTime);
void AddWait(nanotime_t waitTime);
void AddUnspecifiedWait(nanotime_t waitTime);
ThreadWaitObject* AddThreadWaitObject(WaitObject* waitObject,
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);
static inline int CompareByCreationTimeID(const Thread* a,
const Thread* b);
static inline int CompareWithCreationTimeID(
const creation_time_id* key,
const Thread* thread);
private:
typedef BObjectList<ThreadWaitObjectGroup>
ThreadWaitObjectGroupList;
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;
nanotime_t fDeletionTime;
int64 fRuns;
nanotime_t fTotalRunTime;
nanotime_t fMinRunTime;
nanotime_t fMaxRunTime;
int64 fLatencies;
nanotime_t fTotalLatency;
nanotime_t fMinLatency;
nanotime_t fMaxLatency;
int64 fReruns;
nanotime_t fTotalRerunTime;
nanotime_t fMinRerunTime;
nanotime_t fMaxRerunTime;
int64 fWaits;
nanotime_t fTotalWaitTime;
nanotime_t fUnspecifiedWaitTime;
int64 fIOCount;
nanotime_t fIOTime;
int64 fPreemptions;
int32 fIndex;
ThreadWaitObjectGroupList fWaitObjectGroups;
};
struct Model::CompactThreadSchedulingState {
nanotime_t lastTime;
Model::Thread* thread;
ThreadWaitObject* waitObject;
ThreadState state;
uint8 priority;
public:
thread_id ID() const { return thread->ID(); }
inline CompactThreadSchedulingState& operator=(
const CompactThreadSchedulingState& other);
};
struct Model::ThreadSchedulingState : CompactThreadSchedulingState {
ThreadSchedulingState* next;
public:
inline ThreadSchedulingState(
const CompactThreadSchedulingState& other);
inline ThreadSchedulingState(Thread* thread);
};
struct Model::ThreadSchedulingStateDefinition {
typedef thread_id KeyType;
typedef ThreadSchedulingState ValueType;
size_t HashKey(thread_id key) const
{ return (size_t)key; }
size_t Hash(const ThreadSchedulingState* value) const
{ return (size_t)value->ID(); }
bool Compare(thread_id key, const ThreadSchedulingState* value) const
{ return key == value->ID(); }
ThreadSchedulingState*& GetLink(ThreadSchedulingState* value) const
{ return value->next; }
};
class Model::SchedulingState {
public:
inline SchedulingState();
virtual ~SchedulingState();
status_t Init();
status_t Init(const CompactSchedulingState* state);
void Clear();
inline nanotime_t LastEventTime() const { return fLastEventTime; }
inline void SetLastEventTime(nanotime_t time);
inline ThreadSchedulingState* LookupThread(thread_id threadID) const;
inline void InsertThread(ThreadSchedulingState* thread);
inline void RemoveThread(ThreadSchedulingState* thread);
inline const ThreadSchedulingStateTable& ThreadStates() const;
protected:
virtual void DeleteThread(ThreadSchedulingState* thread);
private:
nanotime_t fLastEventTime;
ThreadSchedulingStateTable fThreadStates;
};
class Model::CompactSchedulingState {
public:
static CompactSchedulingState* Create(const SchedulingState& state,
off_t eventOffset);
void Delete();
inline off_t EventOffset() const;
inline nanotime_t LastEventTime() const;
inline int32 CountThreadsStates() const;
inline const CompactThreadSchedulingState* ThreadStateAt(int32 index)
const;
private:
friend class BObjectList<CompactSchedulingState>;
// work-around for our private destructor
private:
CompactSchedulingState();
inline ~CompactSchedulingState() {}
private:
nanotime_t fLastEventTime;
off_t fEventOffset;
int32 fThreadCount;
CompactThreadSchedulingState fThreadStates[0];
};
// #pragma mark - Model
const char*
Model::DataSourceName() const
{
return fDataSourceName.String();
}
void*
Model::EventData() const
{
return fEventData;
}
size_t
Model::EventDataSize() const
{
return fEventDataSize;
}
system_profiler_event_header**
Model::Events() const
{
return fEvents;
}
size_t
Model::CountEvents() const
{
return fEventCount;
}
nanotime_t
Model::BaseTime() const
{
return fBaseTime;
}
nanotime_t
Model::LastEventTime() const
{
return fLastEventTime;
}
nanotime_t
Model::IdleTime() const
{
return fIdleTime;
}
int32
Model::CountCPUs() const
{
return fCPUCount;
}
Model::CPU*
Model::CPUAt(int32 index) const
{
return fCPUs.ItemAt(index);
}
// #pragma mark - CPU
nanotime_t
Model::CPU::IdleTime() const
{
return fIdleTime;
}
// #pragma mark - IOOperation
nanotime_t
Model::IOOperation::StartedTime() const
{
return startedEvent->time;
}
nanotime_t
Model::IOOperation::FinishedTime() const
{
return finishedEvent != NULL ? finishedEvent->time : 0;
}
bool
Model::IOOperation::IsFinished() const
{
return finishedEvent != NULL;
}
off_t
Model::IOOperation::Offset() const
{
return startedEvent->offset;
}
size_t
Model::IOOperation::Length() const
{
return startedEvent->length;
}
bool
Model::IOOperation::IsWrite() const
{
return startedEvent->write;
}
status_t
Model::IOOperation::Status() const
{
return finishedEvent != NULL ? finishedEvent->status : B_OK;
}
size_t
Model::IOOperation::BytesTransferred() const
{
return finishedEvent != NULL ? finishedEvent->transferred : 0;
}
/*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
nanotime_t
Model::IORequest::ScheduledTime() const
{
return scheduledEvent->time;
}
nanotime_t
Model::IORequest::FinishedTime() const
{
return finishedEvent != NULL ? finishedEvent->time : 0;
}
bool
Model::IORequest::IsFinished() const
{
return finishedEvent != NULL;
}
int32
Model::IORequest::Scheduler() const
{
return scheduledEvent->scheduler;
}
off_t
Model::IORequest::Offset() const
{
return scheduledEvent->offset;
}
size_t
Model::IORequest::Length() const
{
return scheduledEvent->length;
}
bool
Model::IORequest::IsWrite() const
{
return scheduledEvent->write;
}
uint8
Model::IORequest::Priority() const
{
return scheduledEvent->priority;
}
status_t
Model::IORequest::Status() const
{
return finishedEvent != NULL ? finishedEvent->status : B_OK;
}
size_t
Model::IORequest::BytesTransferred() const
{
return finishedEvent != NULL ? finishedEvent->transferred : 0;
}
/*static*/ bool
Model::IORequest::TimeLess(const IORequest* a, const IORequest* b)
{
return a->scheduledEvent->time < b->scheduledEvent->time;
}
/*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;
}
/*static*/ int
Model::IORequest::CompareSchedulerTime(const IORequest* a, const IORequest* b)
{
int32 cmp = a->scheduledEvent->scheduler - b->scheduledEvent->scheduler;
if (cmp != 0)
return cmp < 0;
nanotime_t timeCmp = a->scheduledEvent->time - b->scheduledEvent->time;
if (timeCmp == 0)
return 0;
return timeCmp < 0 ? -1 : 1;
}
// #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
uint32
Model::WaitObject::Type() const
{
return fEvent->type;
}
addr_t
Model::WaitObject::Object() const
{
return fEvent->object;
}
const char*
Model::WaitObject::Name() const
{
return fEvent->name;
}
addr_t
Model::WaitObject::ReferencedObject()
{
return fEvent->referenced_object;
}
int64
Model::WaitObject::Waits() const
{
return fWaits;
}
nanotime_t
Model::WaitObject::TotalWaitTime() const
{
return fTotalWaitTime;
}
/*static*/ int
Model::WaitObject::CompareByTypeObject(const WaitObject* a, const WaitObject* b)
{
type_and_object key;
key.type = a->Type();
key.object = a->Object();
return CompareWithTypeObject(&key, b);
}
/*static*/ int
Model::WaitObject::CompareWithTypeObject(const type_and_object* key,
const WaitObject* object)
{
if (key->type == object->Type()) {
if (key->object == object->Object())
return 0;
return key->object < object->Object() ? -1 : 1;
}
return key->type < object->Type() ? -1 : 1;
}
// #pragma mark - WaitObjectGroup
uint32
Model::WaitObjectGroup::Type() const
{
return MostRecentWaitObject()->Type();
}
addr_t
Model::WaitObjectGroup::Object() const
{
return MostRecentWaitObject()->Object();
}
const char*
Model::WaitObjectGroup::Name() const
{
return MostRecentWaitObject()->Name();
}
Model::WaitObject*
Model::WaitObjectGroup::MostRecentWaitObject() const
{
return fWaitObjects.ItemAt(fWaitObjects.CountItems() - 1);
}
int32
Model::WaitObjectGroup::CountWaitObjects() const
{
return fWaitObjects.CountItems();
}
Model::WaitObject*
Model::WaitObjectGroup::WaitObjectAt(int32 index) const
{
return fWaitObjects.ItemAt(index);
}
void
Model::WaitObjectGroup::AddWaitObject(WaitObject* waitObject)
{
fWaitObjects.AddItem(waitObject);
}
/*static*/ int
Model::WaitObjectGroup::CompareByTypeObject(
const WaitObjectGroup* a, const WaitObjectGroup* b)
{
return WaitObject::CompareByTypeObject(a->MostRecentWaitObject(),
b->MostRecentWaitObject());
}
/*static*/ int
Model::WaitObjectGroup::CompareWithTypeObject(const type_and_object* key,
const WaitObjectGroup* group)
{
return WaitObject::CompareWithTypeObject(key,
group->MostRecentWaitObject());
}
// #pragma mark - ThreadWaitObject
Model::WaitObject*
Model::ThreadWaitObject::GetWaitObject() const
{
return fWaitObject;
}
uint32
Model::ThreadWaitObject::Type() const
{
return fWaitObject->Type();
}
addr_t
Model::ThreadWaitObject::Object() const
{
return fWaitObject->Object();
}
const char*
Model::ThreadWaitObject::Name() const
{
return fWaitObject->Name();
}
addr_t
Model::ThreadWaitObject::ReferencedObject()
{
return fWaitObject->ReferencedObject();
}
int64
Model::ThreadWaitObject::Waits() const
{
return fWaits;
}
nanotime_t
Model::ThreadWaitObject::TotalWaitTime() const
{
return fTotalWaitTime;
}
// #pragma mark - ThreadWaitObjectGroup
uint32
Model::ThreadWaitObjectGroup::Type() const
{
return MostRecentThreadWaitObject()->Type();
}
addr_t
Model::ThreadWaitObjectGroup::Object() const
{
return MostRecentThreadWaitObject()->Object();
}
const char*
Model::ThreadWaitObjectGroup::Name() const
{
return MostRecentThreadWaitObject()->Name();
}
Model::ThreadWaitObject*
Model::ThreadWaitObjectGroup::MostRecentThreadWaitObject() const
{
return fWaitObjects.Head();
}
Model::WaitObject*
Model::ThreadWaitObjectGroup::MostRecentWaitObject() const
{
return MostRecentThreadWaitObject()->GetWaitObject();
}
void
Model::ThreadWaitObjectGroup::AddWaitObject(ThreadWaitObject* threadWaitObject)
{
fWaitObjects.Add(threadWaitObject);
}
/*static*/ int
Model::ThreadWaitObjectGroup::CompareByTypeObject(
const ThreadWaitObjectGroup* a, const ThreadWaitObjectGroup* b)
{
return WaitObject::CompareByTypeObject(a->MostRecentWaitObject(),
b->MostRecentWaitObject());
}
/*static*/ int
Model::ThreadWaitObjectGroup::CompareWithTypeObject(const type_and_object* key,
const ThreadWaitObjectGroup* group)
{
return WaitObject::CompareWithTypeObject(key,
group->MostRecentWaitObject());
}
// #pragma mark - Team
team_id
Model::Team::ID() const
{
return fCreationEvent->team;
}
const char*
Model::Team::Name() const
{
return fCreationEvent->name;
// TODO: We should probably return the last exec name!
}
nanotime_t
Model::Team::CreationTime() const
{
return fCreationTime;
}
nanotime_t
Model::Team::DeletionTime() const
{
return fDeletionTime;
}
void
Model::Team::SetDeletionTime(nanotime_t time)
{
fDeletionTime = time;
}
/*static*/ int
Model::Team::CompareByID(const Team* a, const Team* b)
{
return a->ID() - b->ID();
}
/*static*/ int
Model::Team::CompareWithID(const team_id* id, const Team* team)
{
return *id - team->ID();
}
// #pragma mark - Thread
thread_id
Model::Thread::ID() const
{
return fCreationEvent->thread;
}
const char*
Model::Thread::Name() const
{
return fCreationEvent->name;
}
Model::Team*
Model::Thread::GetTeam() const
{
return fTeam;
}
nanotime_t
Model::Thread::CreationTime() const
{
return fCreationTime;
}
nanotime_t
Model::Thread::DeletionTime() const
{
return fDeletionTime;
}
int32
Model::Thread::Index() const
{
return fIndex;
}
void
Model::Thread::SetIndex(int32 index)
{
fIndex = index;
}
system_profiler_event_header**
Model::Thread::Events() const
{
return fEvents;
}
size_t
Model::Thread::CountEvents() const
{
return fEventCount;
}
Model::IORequest**
Model::Thread::IORequests() const
{
return fIORequests;
}
size_t
Model::Thread::CountIORequests() const
{
return fIORequestCount;
}
int64
Model::Thread::Runs() const
{
return fRuns;
}
nanotime_t
Model::Thread::TotalRunTime() const
{
return fTotalRunTime;
}
int64
Model::Thread::Reruns() const
{
return fReruns;
}
nanotime_t
Model::Thread::TotalRerunTime() const
{
return fTotalRerunTime;
}
int64
Model::Thread::Latencies() const
{
return fLatencies;
}
nanotime_t
Model::Thread::TotalLatency() const
{
return fTotalLatency;
}
int64
Model::Thread::Preemptions() const
{
return fPreemptions;
}
int64
Model::Thread::Waits() const
{
return fWaits;
}
nanotime_t
Model::Thread::TotalWaitTime() const
{
return fTotalWaitTime;
}
nanotime_t
Model::Thread::UnspecifiedWaitTime() const
{
return fUnspecifiedWaitTime;
}
int64
Model::Thread::IOCount() const
{
return fIOCount;
}
nanotime_t
Model::Thread::IOTime() const
{
return fIOTime;
}
int32
Model::Thread::CountThreadWaitObjectGroups() const
{
return fWaitObjectGroups.CountItems();
}
Model::ThreadWaitObjectGroup*
Model::Thread::ThreadWaitObjectGroupAt(int32 index) const
{
return fWaitObjectGroups.ItemAt(index);
}
void
Model::Thread::SetDeletionTime(nanotime_t time)
{
fDeletionTime = time;
}
/*static*/ int
Model::Thread::CompareByID(const Thread* a, const Thread* b)
{
return a->ID() - b->ID();
}
/*static*/ int
Model::Thread::CompareWithID(const thread_id* id, const Thread* thread)
{
return *id - thread->ID();
}
/*static*/ int
Model::Thread::CompareByCreationTimeID(const Thread* a, const Thread* b)
{
creation_time_id key;
key.time = a->fCreationTime;
key.id = a->ID();
return CompareWithCreationTimeID(&key, b);
}
/*static*/ int
Model::Thread::CompareWithCreationTimeID(const creation_time_id* key,
const Thread* thread)
{
nanotime_t cmp = key->time - thread->fCreationTime;
if (cmp == 0)
return key->id - thread->ID();
return cmp < 0 ? -1 : 1;
}
// #pragma mark - CompactThreadSchedulingState
Model::CompactThreadSchedulingState&
Model::CompactThreadSchedulingState::operator=(
const CompactThreadSchedulingState& other)
{
lastTime = other.lastTime;
thread = other.thread;
waitObject = other.waitObject;
state = other.state;
priority = other.priority;
return *this;
}
// #pragma mark - ThreadSchedulingState
Model::ThreadSchedulingState::ThreadSchedulingState(
const CompactThreadSchedulingState& other)
{
this->CompactThreadSchedulingState::operator=(other);
}
Model::ThreadSchedulingState::ThreadSchedulingState(Thread* thread)
{
lastTime = 0;
this->thread = thread;
waitObject = NULL;
state = UNKNOWN;
}
// #pragma mark - SchedulingState
Model::SchedulingState::SchedulingState()
:
fLastEventTime(-1)
{
}
void
Model::SchedulingState::SetLastEventTime(nanotime_t time)
{
fLastEventTime = time;
}
Model::ThreadSchedulingState*
Model::SchedulingState::LookupThread(thread_id threadID) const
{
return fThreadStates.Lookup(threadID);
}
void
Model::SchedulingState::InsertThread(ThreadSchedulingState* thread)
{
fThreadStates.Insert(thread);
}
void
Model::SchedulingState::RemoveThread(ThreadSchedulingState* thread)
{
fThreadStates.Remove(thread);
}
const Model::ThreadSchedulingStateTable&
Model::SchedulingState::ThreadStates() const
{
return fThreadStates;
}
// #pragma mark - CompactSchedulingState
off_t
Model::CompactSchedulingState::EventOffset() const
{
return fEventOffset;
}
nanotime_t
Model::CompactSchedulingState::LastEventTime() const
{
return fLastEventTime;
}
int32
Model::CompactSchedulingState::CountThreadsStates() const
{
return fThreadCount;
}
const Model::CompactThreadSchedulingState*
Model::CompactSchedulingState::ThreadStateAt(int32 index) const
{
return index >= 0 && index < fThreadCount ? &fThreadStates[index] : NULL;
}
#endif // MODEL_H