/* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #ifndef MODEL_H #define MODEL_H #include #include #include #include #include #include #include #include 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 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 CPUList; typedef BObjectList TeamList; typedef BObjectList ThreadList; typedef BObjectList WaitObjectGroupList; typedef BObjectList IOSchedulerList; typedef BObjectList 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 WaitObjectList; void _ComputeWaits(); private: WaitObjectList fWaitObjects; int64 fWaits; nanotime_t fTotalWaitTime; }; class Model::ThreadWaitObject : public SinglyLinkedListLinkImpl { 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& 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 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 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 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; // 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