xref: /haiku/src/apps/debuganalyzer/model/Model.h (revision 2c69b5b6c0e7b481a0c43366a1942a6055cbb864)
1 /*
2  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef MODEL_H
6 #define MODEL_H
7 
8 
9 #include <stdlib.h>
10 
11 #include <OS.h>
12 #include <String.h>
13 
14 #include <ObjectList.h>
15 #include <Referenceable.h>
16 #include <util/OpenHashTable.h>
17 
18 #include <system_profiler_defs.h>
19 #include <util/SinglyLinkedList.h>
20 
21 
22 enum ThreadState {
23 	RUNNING,
24 	STILL_RUNNING,
25 	PREEMPTED,
26 	READY,
27 	WAITING,
28 	UNKNOWN
29 };
30 
31 
32 class Model : public Referenceable {
33 public:
34 			struct creation_time_id;
35 			struct type_and_object;
36 			class WaitObjectGroup;
37 			class WaitObject;
38 			class ThreadWaitObject;
39 			class ThreadWaitObjectGroup;
40 			class Team;
41 			class Thread;
42 			struct CompactThreadSchedulingState;
43 			struct ThreadSchedulingState;
44 			struct ThreadSchedulingStateDefinition;
45 			typedef BOpenHashTable<ThreadSchedulingStateDefinition>
46 				ThreadSchedulingStateTable;
47 			class SchedulingState;
48 			class CompactSchedulingState;
49 
50 public:
51 								Model(const char* dataSourceName,
52 									void* eventData, size_t eventDataSize);
53 								~Model();
54 
55 	inline	const char*			DataSourceName() const;
56 	inline	void*				EventData() const;
57 	inline	size_t				EventDataSize() const;
58 
59 			void				LoadingFinished();
60 
61 	inline	bigtime_t			BaseTime() const;
62 			void				SetBaseTime(bigtime_t time);
63 
64 	inline	bigtime_t			LastEventTime() const;
65 			void				SetLastEventTime(bigtime_t time);
66 
67 			int32				CountTeams() const;
68 			Team*				TeamAt(int32 index) const;
69 			Team*				TeamByID(team_id id) const;
70 			Team*				AddTeam(
71 									const system_profiler_team_added* event,
72 									bigtime_t time);
73 
74 			int32				CountThreads() const;
75 			Thread*				ThreadAt(int32 index) const;
76 			Thread*				ThreadByID(thread_id id) const;
77 			Thread*				AddThread(
78 									const system_profiler_thread_added* event,
79 									bigtime_t time);
80 
81 			WaitObject*			AddWaitObject(
82 									const system_profiler_wait_object_info*
83 										event,
84 									WaitObjectGroup** _waitObjectGroup);
85 			WaitObjectGroup*	WaitObjectGroupFor(uint32 type,
86 									addr_t object) const;
87 
88 			ThreadWaitObject*	AddThreadWaitObject(thread_id threadID,
89 									WaitObject* waitObject,
90 									ThreadWaitObjectGroup**
91 										_threadWaitObjectGroup);
92 			ThreadWaitObjectGroup* ThreadWaitObjectGroupFor(
93 									thread_id threadID, uint32 type,
94 									addr_t object) const;
95 
96 			bool				AddSchedulingStateSnapshot(
97 									const SchedulingState& state,
98 									off_t eventOffset);
99 									// must be added in order (of time)
100 			const CompactSchedulingState* ClosestSchedulingState(
101 									bigtime_t eventTime) const;
102 									// returns the closest previous state
103 
104 private:
105 			typedef BObjectList<Team> TeamList;
106 			typedef BObjectList<Thread> ThreadList;
107 			typedef BObjectList<WaitObjectGroup> WaitObjectGroupList;
108 			typedef BObjectList<CompactSchedulingState> SchedulingStateList;
109 
110 private:
111 	static	int			_CompareEventTimeSchedulingState(const bigtime_t* time,
112 							const CompactSchedulingState* state);
113 
114 private:
115 			BString				fDataSourceName;
116 			void*				fEventData;
117 			size_t				fEventDataSize;
118 			bigtime_t			fBaseTime;
119 			bigtime_t			fLastEventTime;
120 			TeamList			fTeams;		// sorted by ID
121 			ThreadList			fThreads;	// sorted by ID
122 			WaitObjectGroupList	fWaitObjectGroups;
123 			SchedulingStateList	fSchedulingStates;
124 };
125 
126 
127 struct Model::creation_time_id {
128 	bigtime_t	time;
129 	thread_id	id;
130 };
131 
132 
133 struct Model::type_and_object {
134 	uint32		type;
135 	addr_t		object;
136 };
137 
138 
139 class Model::WaitObject : public SinglyLinkedListLinkImpl<WaitObject> {
140 public:
141 								WaitObject(
142 									const system_profiler_wait_object_info*
143 										event);
144 								~WaitObject();
145 
146 	inline	uint32				Type() const;
147 	inline	addr_t				Object() const;
148 	inline	const char*			Name() const;
149 	inline	addr_t				ReferencedObject();
150 
151 	static inline int			CompareByTypeObject(const WaitObject* a,
152 									const WaitObject* b);
153 	static inline int			CompareWithTypeObject(
154 									const type_and_object* key,
155 									const WaitObject* object);
156 
157 private:
158 			const system_profiler_wait_object_info* fEvent;
159 };
160 
161 
162 class Model::WaitObjectGroup {
163 public:
164 								WaitObjectGroup(WaitObject* waitObject);
165 								~WaitObjectGroup();
166 
167 	inline	uint32				Type() const;
168 	inline	addr_t				Object() const;
169 	inline	const char*			Name() const;
170 
171 	inline	WaitObject*			MostRecentWaitObject() const;
172 
173 	inline	void				AddWaitObject(WaitObject* waitObject);
174 
175 	static inline int			CompareByTypeObject(const WaitObjectGroup* a,
176 									const WaitObjectGroup* b);
177 	static inline int			CompareWithTypeObject(
178 									const type_and_object* key,
179 									const WaitObjectGroup* group);
180 
181 private:
182 			typedef SinglyLinkedList<WaitObject> WaitObjectList;
183 
184 private:
185 			WaitObjectList		fWaitObjects;
186 };
187 
188 
189 class Model::ThreadWaitObject
190 	: public SinglyLinkedListLinkImpl<ThreadWaitObject> {
191 public:
192 								ThreadWaitObject(WaitObject* waitObject);
193 								~ThreadWaitObject();
194 
195 	inline	WaitObject*			GetWaitObject() const;
196 
197 	inline	uint32				Type() const;
198 	inline	addr_t				Object() const;
199 	inline	const char*			Name() const;
200 	inline	addr_t				ReferencedObject();
201 
202 	inline	int64				Waits() const;
203 	inline	bigtime_t			TotalWaitTime() const;
204 
205 			void				AddWait(bigtime_t waitTime);
206 
207 private:
208 			WaitObject*			fWaitObject;
209 			int64				fWaits;
210 			bigtime_t			fTotalWaitTime;
211 };
212 
213 
214 class Model::ThreadWaitObjectGroup {
215 public:
216 								ThreadWaitObjectGroup(
217 									ThreadWaitObject* threadWaitObject);
218 								~ThreadWaitObjectGroup();
219 
220 	inline	ThreadWaitObject*	MostRecentThreadWaitObject() const;
221 	inline	WaitObject*			MostRecentWaitObject() const;
222 
223 	inline	void				AddWaitObject(
224 									ThreadWaitObject* threadWaitObject);
225 
226 			bool				GetThreadWaitObjects(
227 									BObjectList<ThreadWaitObject>& objects);
228 
229 	static inline int			CompareByTypeObject(
230 									const ThreadWaitObjectGroup* a,
231 									const ThreadWaitObjectGroup* b);
232 	static inline int			CompareWithTypeObject(
233 									const type_and_object* key,
234 									const ThreadWaitObjectGroup* group);
235 
236 private:
237 			typedef SinglyLinkedList<ThreadWaitObject> ThreadWaitObjectList;
238 
239 private:
240 			ThreadWaitObjectList fWaitObjects;
241 };
242 
243 
244 class Model::Team {
245 public:
246 								Team(const system_profiler_team_added* event,
247 									bigtime_t time);
248 								~Team();
249 
250 	inline	team_id				ID() const;
251 	inline	const char*			Name() const;
252 
253 	inline	bigtime_t			CreationTime() const;
254 	inline	bigtime_t			DeletionTime() const;
255 
256 			bool				AddThread(Thread* thread);
257 
258 	inline	void				SetDeletionTime(bigtime_t time);
259 
260 	static inline int			CompareByID(const Team* a, const Team* b);
261 	static inline int			CompareWithID(const team_id* id,
262 									const Team* team);
263 
264 private:
265 			typedef BObjectList<Thread> ThreadList;
266 
267 private:
268 			const system_profiler_team_added* fCreationEvent;
269 			bigtime_t			fCreationTime;
270 			bigtime_t			fDeletionTime;
271 			ThreadList			fThreads;	// sorted by creation time, ID
272 };
273 
274 
275 class Model::Thread {
276 public:
277 								Thread(Team* team,
278 									const system_profiler_thread_added* event,
279 									bigtime_t time);
280 								~Thread();
281 
282 	inline	thread_id			ID() const;
283 	inline	const char*			Name() const;
284 	inline	Team*				GetTeam() const;
285 
286 	inline	int32				Index() const;
287 	inline	void				SetIndex(int32 index);
288 
289 	inline	bigtime_t			CreationTime() const;
290 	inline	bigtime_t			DeletionTime() const;
291 
292 	inline	int64				Runs() const;
293 	inline	bigtime_t			TotalRunTime() const;
294 	inline	int64				Reruns() const;
295 	inline	bigtime_t			TotalRerunTime() const;
296 	inline	int64				Latencies() const;
297 	inline	bigtime_t			TotalLatency() const;
298 	inline	int64				Preemptions() const;
299 	inline	int64				Waits() const;
300 	inline	bigtime_t			TotalWaitTime() const;
301 	inline	bigtime_t			UnspecifiedWaitTime() const;
302 
303 			ThreadWaitObjectGroup* ThreadWaitObjectGroupFor(uint32 type,
304 									addr_t object) const;
305 	inline	int32				CountThreadWaitObjectGroups() const;
306 	inline	ThreadWaitObjectGroup* ThreadWaitObjectGroupAt(int32 index) const;
307 
308 	inline	void				SetDeletionTime(bigtime_t time);
309 
310 			void				AddRun(bigtime_t runTime);
311 			void				AddRerun(bigtime_t runTime);
312 			void				AddLatency(bigtime_t latency);
313 			void				AddPreemption(bigtime_t runTime);
314 			void				AddWait(bigtime_t waitTime);
315 			void				AddUnspecifiedWait(bigtime_t waitTime);
316 
317 			ThreadWaitObject*	AddThreadWaitObject(WaitObject* waitObject,
318 									ThreadWaitObjectGroup**
319 										_threadWaitObjectGroup);
320 
321 	static inline int			CompareByID(const Thread* a, const Thread* b);
322 	static inline int			CompareWithID(const thread_id* id,
323 									const Thread* thread);
324 
325 	static inline int			CompareByCreationTimeID(const Thread* a,
326 									const Thread* b);
327 	static inline int			CompareWithCreationTimeID(
328 									const creation_time_id* key,
329 									const Thread* thread);
330 
331 private:
332 			typedef BObjectList<ThreadWaitObjectGroup>
333 				ThreadWaitObjectGroupList;
334 
335 private:
336 			Team*				fTeam;
337 			const system_profiler_thread_added* fCreationEvent;
338 			bigtime_t			fCreationTime;
339 			bigtime_t			fDeletionTime;
340 
341 			int64				fRuns;
342 			bigtime_t			fTotalRunTime;
343 			bigtime_t			fMinRunTime;
344 			bigtime_t			fMaxRunTime;
345 
346 			int64				fLatencies;
347 			bigtime_t			fTotalLatency;
348 			bigtime_t			fMinLatency;
349 			bigtime_t			fMaxLatency;
350 
351 			int64				fReruns;
352 			bigtime_t			fTotalRerunTime;
353 			bigtime_t			fMinRerunTime;
354 			bigtime_t			fMaxRerunTime;
355 
356 			int64				fWaits;
357 			bigtime_t			fTotalWaitTime;
358 			bigtime_t			fUnspecifiedWaitTime;
359 
360 			int64				fPreemptions;
361 
362 			int32				fIndex;
363 
364 			ThreadWaitObjectGroupList fWaitObjectGroups;
365 };
366 
367 
368 struct Model::CompactThreadSchedulingState {
369 			bigtime_t			lastTime;
370 			Model::Thread*		thread;
371 			ThreadWaitObject*	waitObject;
372 			ThreadState			state;
373 
374 public:
375 			thread_id			ID() const	{ return thread->ID(); }
376 
377 	inline	CompactThreadSchedulingState& operator=(
378 									const CompactThreadSchedulingState& other);
379 };
380 
381 
382 struct Model::ThreadSchedulingState : CompactThreadSchedulingState {
383 			ThreadSchedulingState* next;
384 
385 public:
386 	inline						ThreadSchedulingState(
387 									const CompactThreadSchedulingState& other);
388 	inline						ThreadSchedulingState(Thread* thread);
389 };
390 
391 
392 struct Model::ThreadSchedulingStateDefinition {
393 	typedef thread_id				KeyType;
394 	typedef	ThreadSchedulingState	ValueType;
395 
396 	size_t HashKey(thread_id key) const
397 		{ return (size_t)key; }
398 
399 	size_t Hash(const ThreadSchedulingState* value) const
400 		{ return (size_t)value->ID(); }
401 
402 	bool Compare(thread_id key, const ThreadSchedulingState* value) const
403 		{ return key == value->ID(); }
404 
405 	ThreadSchedulingState*& GetLink(ThreadSchedulingState* value) const
406 		{ return value->next; }
407 };
408 
409 
410 class Model::SchedulingState {
411 public:
412 	inline						SchedulingState();
413 								~SchedulingState();
414 
415 			status_t			Init();
416 			status_t			Init(const CompactSchedulingState* state);
417 			void				Clear();
418 
419 	inline	bigtime_t			LastEventTime() const { return fLastEventTime; }
420 	inline	void				SetLastEventTime(bigtime_t time);
421 
422 	inline	ThreadSchedulingState* LookupThread(thread_id threadID) const;
423 	inline	void				InsertThread(ThreadSchedulingState* thread);
424 	inline	void				RemoveThread(ThreadSchedulingState* thread);
425 	inline	const ThreadSchedulingStateTable& ThreadStates() const;
426 
427 private:
428 			bigtime_t			fLastEventTime;
429 			ThreadSchedulingStateTable fThreadStates;
430 };
431 
432 
433 class Model::CompactSchedulingState {
434 public:
435 	static	CompactSchedulingState* Create(const SchedulingState& state,
436 									off_t eventOffset);
437 			void				Delete();
438 
439 	inline	off_t				EventOffset() const;
440 	inline	bigtime_t			LastEventTime() const;
441 
442 	inline	int32				CountThreadsStates() const;
443 	inline	const CompactThreadSchedulingState* ThreadStateAt(int32 index)
444 									const;
445 
446 private:
447 	friend class BObjectList<CompactSchedulingState>;
448 		// work-around for our private destructor
449 
450 private:
451 								CompactSchedulingState();
452 	inline						~CompactSchedulingState() {}
453 
454 private:
455 			bigtime_t			fLastEventTime;
456 			off_t				fEventOffset;
457 			int32				fThreadCount;
458 			CompactThreadSchedulingState fThreadStates[0];
459 };
460 
461 
462 // #pragma mark - Model
463 
464 
465 const char*
466 Model::DataSourceName() const
467 {
468 	return fDataSourceName.String();
469 }
470 
471 
472 void*
473 Model::EventData() const
474 {
475 	return fEventData;
476 }
477 
478 
479 size_t
480 Model::EventDataSize() const
481 {
482 	return fEventDataSize;
483 }
484 
485 
486 bigtime_t
487 Model::BaseTime() const
488 {
489 	return fBaseTime;
490 }
491 
492 
493 bigtime_t
494 Model::LastEventTime() const
495 {
496 	return fLastEventTime;
497 }
498 
499 
500 // #pragma mark - WaitObject
501 
502 
503 uint32
504 Model::WaitObject::Type() const
505 {
506 	return fEvent->type;
507 }
508 
509 
510 addr_t
511 Model::WaitObject::Object() const
512 {
513 	return fEvent->object;
514 }
515 
516 
517 const char*
518 Model::WaitObject::Name() const
519 {
520 	return fEvent->name;
521 }
522 
523 
524 addr_t
525 Model::WaitObject::ReferencedObject()
526 {
527 	return fEvent->referenced_object;
528 }
529 
530 
531 /*static*/ int
532 Model::WaitObject::CompareByTypeObject(const WaitObject* a, const WaitObject* b)
533 {
534 	type_and_object key;
535 	key.type = a->Type();
536 	key.object = a->Object();
537 
538 	return CompareWithTypeObject(&key, b);
539 }
540 
541 
542 /*static*/ int
543 Model::WaitObject::CompareWithTypeObject(const type_and_object* key,
544 	const WaitObject* object)
545 {
546 	if (key->type == object->Type()) {
547 		if (key->object == object->Object())
548 			return 0;
549 		return key->object < object->Object() ? -1 : 1;
550 	}
551 
552 	return key->type < object->Type() ? -1 : 1;
553 }
554 
555 
556 // #pragma mark - WaitObjectGroup
557 
558 
559 uint32
560 Model::WaitObjectGroup::Type() const
561 {
562 	return MostRecentWaitObject()->Type();
563 }
564 
565 
566 addr_t
567 Model::WaitObjectGroup::Object() const
568 {
569 	return MostRecentWaitObject()->Object();
570 }
571 
572 
573 const char*
574 Model::WaitObjectGroup::Name() const
575 {
576 	return MostRecentWaitObject()->Name();
577 }
578 
579 
580 Model::WaitObject*
581 Model::WaitObjectGroup::MostRecentWaitObject() const
582 {
583 	return fWaitObjects.Head();
584 }
585 
586 
587 void
588 Model::WaitObjectGroup::AddWaitObject(WaitObject* waitObject)
589 {
590 	fWaitObjects.Add(waitObject);
591 }
592 
593 
594 /*static*/ int
595 Model::WaitObjectGroup::CompareByTypeObject(
596 	const WaitObjectGroup* a, const WaitObjectGroup* b)
597 {
598 	return WaitObject::CompareByTypeObject(a->MostRecentWaitObject(),
599 		b->MostRecentWaitObject());
600 }
601 
602 
603 /*static*/ int
604 Model::WaitObjectGroup::CompareWithTypeObject(const type_and_object* key,
605 	const WaitObjectGroup* group)
606 {
607 	return WaitObject::CompareWithTypeObject(key,
608 		group->MostRecentWaitObject());
609 }
610 
611 
612 // #pragma mark - ThreadWaitObject
613 
614 
615 Model::WaitObject*
616 Model::ThreadWaitObject::GetWaitObject() const
617 {
618 	return fWaitObject;
619 }
620 
621 
622 uint32
623 Model::ThreadWaitObject::Type() const
624 {
625 	return fWaitObject->Type();
626 }
627 
628 
629 addr_t
630 Model::ThreadWaitObject::Object() const
631 {
632 	return fWaitObject->Object();
633 }
634 
635 
636 const char*
637 Model::ThreadWaitObject::Name() const
638 {
639 	return fWaitObject->Name();
640 }
641 
642 
643 addr_t
644 Model::ThreadWaitObject::ReferencedObject()
645 {
646 	return fWaitObject->ReferencedObject();
647 }
648 
649 
650 int64
651 Model::ThreadWaitObject::Waits() const
652 {
653 	return fWaits;
654 }
655 
656 
657 bigtime_t
658 Model::ThreadWaitObject::TotalWaitTime() const
659 {
660 	return fTotalWaitTime;
661 }
662 
663 
664 // #pragma mark - ThreadWaitObjectGroup
665 
666 
667 Model::ThreadWaitObject*
668 Model::ThreadWaitObjectGroup::MostRecentThreadWaitObject() const
669 {
670 	return fWaitObjects.Head();
671 }
672 
673 
674 Model::WaitObject*
675 Model::ThreadWaitObjectGroup::MostRecentWaitObject() const
676 {
677 	return MostRecentThreadWaitObject()->GetWaitObject();
678 }
679 
680 
681 void
682 Model::ThreadWaitObjectGroup::AddWaitObject(ThreadWaitObject* threadWaitObject)
683 {
684 	fWaitObjects.Add(threadWaitObject);
685 }
686 
687 
688 /*static*/ int
689 Model::ThreadWaitObjectGroup::CompareByTypeObject(
690 	const ThreadWaitObjectGroup* a, const ThreadWaitObjectGroup* b)
691 {
692 	return WaitObject::CompareByTypeObject(a->MostRecentWaitObject(),
693 		b->MostRecentWaitObject());
694 }
695 
696 
697 /*static*/ int
698 Model::ThreadWaitObjectGroup::CompareWithTypeObject(const type_and_object* key,
699 	const ThreadWaitObjectGroup* group)
700 {
701 	return WaitObject::CompareWithTypeObject(key,
702 		group->MostRecentWaitObject());
703 }
704 
705 
706 // #pragma mark - Team
707 
708 
709 team_id
710 Model::Team::ID() const
711 {
712 	return fCreationEvent->team;
713 }
714 
715 
716 const char*
717 Model::Team::Name() const
718 {
719 	return fCreationEvent->name;
720 		// TODO: We should probably return the last exec name!
721 }
722 
723 
724 bigtime_t
725 Model::Team::CreationTime() const
726 {
727 	return fCreationTime;
728 }
729 
730 
731 bigtime_t
732 Model::Team::DeletionTime() const
733 {
734 	return fDeletionTime;
735 }
736 
737 
738 void
739 Model::Team::SetDeletionTime(bigtime_t time)
740 {
741 	fDeletionTime = time;
742 }
743 
744 
745 /*static*/ int
746 Model::Team::CompareByID(const Team* a, const Team* b)
747 {
748 	return a->ID() - b->ID();
749 }
750 
751 
752 /*static*/ int
753 Model::Team::CompareWithID(const team_id* id, const Team* team)
754 {
755 	return *id - team->ID();
756 }
757 
758 
759 // #pragma mark - Thread
760 
761 
762 thread_id
763 Model::Thread::ID() const
764 {
765 	return fCreationEvent->thread;
766 }
767 
768 
769 const char*
770 Model::Thread::Name() const
771 {
772 	return fCreationEvent->name;
773 }
774 
775 
776 Model::Team*
777 Model::Thread::GetTeam() const
778 {
779 	return fTeam;
780 }
781 
782 
783 bigtime_t
784 Model::Thread::CreationTime() const
785 {
786 	return fCreationTime;
787 }
788 
789 
790 bigtime_t
791 Model::Thread::DeletionTime() const
792 {
793 	return fDeletionTime;
794 }
795 
796 
797 int32
798 Model::Thread::Index() const
799 {
800 	return fIndex;
801 }
802 
803 
804 void
805 Model::Thread::SetIndex(int32 index)
806 {
807 	fIndex = index;
808 }
809 
810 
811 int64
812 Model::Thread::Runs() const
813 {
814 	return fRuns;
815 }
816 
817 
818 bigtime_t
819 Model::Thread::TotalRunTime() const
820 {
821 	return fTotalRunTime;
822 }
823 
824 
825 int64
826 Model::Thread::Reruns() const
827 {
828 	return fReruns;
829 }
830 
831 
832 bigtime_t
833 Model::Thread::TotalRerunTime() const
834 {
835 	return fTotalRerunTime;
836 }
837 
838 
839 int64
840 Model::Thread::Latencies() const
841 {
842 	return fLatencies;
843 }
844 
845 
846 bigtime_t
847 Model::Thread::TotalLatency() const
848 {
849 	return fTotalLatency;
850 }
851 
852 
853 int64
854 Model::Thread::Preemptions() const
855 {
856 	return fPreemptions;
857 }
858 
859 
860 int64
861 Model::Thread::Waits() const
862 {
863 	return fWaits;
864 }
865 
866 
867 bigtime_t
868 Model::Thread::TotalWaitTime() const
869 {
870 	return fTotalWaitTime;
871 }
872 
873 
874 bigtime_t
875 Model::Thread::UnspecifiedWaitTime() const
876 {
877 	return fUnspecifiedWaitTime;
878 }
879 
880 
881 int32
882 Model::Thread::CountThreadWaitObjectGroups() const
883 {
884 	return fWaitObjectGroups.CountItems();
885 }
886 
887 
888 Model::ThreadWaitObjectGroup*
889 Model::Thread::ThreadWaitObjectGroupAt(int32 index) const
890 {
891 	return fWaitObjectGroups.ItemAt(index);
892 }
893 
894 
895 void
896 Model::Thread::SetDeletionTime(bigtime_t time)
897 {
898 	fDeletionTime = time;
899 }
900 
901 
902 /*static*/ int
903 Model::Thread::CompareByID(const Thread* a, const Thread* b)
904 {
905 	return a->ID() - b->ID();
906 }
907 
908 
909 /*static*/ int
910 Model::Thread::CompareWithID(const thread_id* id, const Thread* thread)
911 {
912 	return *id - thread->ID();
913 }
914 
915 
916 /*static*/ int
917 Model::Thread::CompareByCreationTimeID(const Thread* a, const Thread* b)
918 {
919 	creation_time_id key;
920 	key.time = a->fCreationTime;
921 	key.id = a->ID();
922 	return CompareWithCreationTimeID(&key, b);
923 }
924 
925 
926 /*static*/ int
927 Model::Thread::CompareWithCreationTimeID(const creation_time_id* key,
928 	const Thread* thread)
929 {
930 	bigtime_t cmp = key->time - thread->fCreationTime;
931 	if (cmp == 0)
932 		return key->id - thread->ID();
933 	return cmp < 0 ? -1 : 1;
934 }
935 
936 
937 // #pragma mark - CompactThreadSchedulingState
938 
939 
940 Model::CompactThreadSchedulingState&
941 Model::CompactThreadSchedulingState::operator=(
942 	const CompactThreadSchedulingState& other)
943 {
944 	lastTime = other.lastTime;
945 	thread = other.thread;
946 	waitObject = other.waitObject;
947 	state = other.state;
948 	return *this;
949 }
950 
951 
952 // #pragma mark - ThreadSchedulingState
953 
954 
955 Model::ThreadSchedulingState::ThreadSchedulingState(
956 	const CompactThreadSchedulingState& other)
957 {
958 	this->CompactThreadSchedulingState::operator=(other);
959 }
960 
961 
962 Model::ThreadSchedulingState::ThreadSchedulingState(Thread* thread)
963 {
964 	lastTime = 0;
965 	this->thread = thread;
966 	waitObject = NULL;
967 	state = UNKNOWN;
968 }
969 
970 
971 // #pragma mark - SchedulingState
972 
973 
974 Model::SchedulingState::SchedulingState()
975 	:
976 	fLastEventTime(-1)
977 {
978 }
979 
980 
981 void
982 Model::SchedulingState::SetLastEventTime(bigtime_t time)
983 {
984 	fLastEventTime = time;
985 }
986 
987 
988 Model::ThreadSchedulingState*
989 Model::SchedulingState::LookupThread(thread_id threadID) const
990 {
991 	return fThreadStates.Lookup(threadID);
992 }
993 
994 
995 void
996 Model::SchedulingState::InsertThread(ThreadSchedulingState* thread)
997 {
998 	fThreadStates.Insert(thread);
999 }
1000 
1001 
1002 void
1003 Model::SchedulingState::RemoveThread(ThreadSchedulingState* thread)
1004 {
1005 	fThreadStates.Remove(thread);
1006 }
1007 
1008 
1009 const Model::ThreadSchedulingStateTable&
1010 Model::SchedulingState::ThreadStates() const
1011 {
1012 	return fThreadStates;
1013 }
1014 
1015 
1016 // #pragma mark - CompactSchedulingState
1017 
1018 
1019 off_t
1020 Model::CompactSchedulingState::EventOffset() const
1021 {
1022 	return fEventOffset;
1023 }
1024 
1025 
1026 bigtime_t
1027 Model::CompactSchedulingState::LastEventTime() const
1028 {
1029 	return fLastEventTime;
1030 }
1031 
1032 
1033 int32
1034 Model::CompactSchedulingState::CountThreadsStates() const
1035 {
1036 	return fThreadCount;
1037 }
1038 
1039 
1040 const Model::CompactThreadSchedulingState*
1041 Model::CompactSchedulingState::ThreadStateAt(int32 index) const
1042 {
1043 	return index >= 0 && index < fThreadCount ? &fThreadStates[index] : NULL;
1044 }
1045 
1046 
1047 #endif	// MODEL_H
1048