1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef THREAD_MODEL_H
6#define THREAD_MODEL_H
7
8
9#include <string.h>
10
11#include "Model.h"
12
13
14class ThreadModel {
15public:
16			struct type_and_name;
17			class WaitObjectGroup;
18
19public:
20								ThreadModel(Model* model,
21									Model::Thread* thread);
22								~ThreadModel();
23
24			Model*				GetModel() const	{ return fModel; }
25			Model::Thread*		GetThread() const	{ return fThread; }
26
27			WaitObjectGroup*	AddWaitObjectGroup(
28									const BObjectList<Model::ThreadWaitObject>&
29										waitObjects,
30									int32 start, int32 end);
31	inline	int32				CountWaitObjectGroups() const;
32	inline	WaitObjectGroup*	WaitObjectGroupAt(int32 index) const;
33
34			bool				AddSchedulingEvent(
35									const system_profiler_event_header*
36										eventHeader);
37	inline	int32				CountSchedulingEvents() const;
38	inline	const system_profiler_event_header* SchedulingEventAt(
39									int32 index) const;
40			int32				FindSchedulingEvent(nanotime_t time);
41
42private:
43			typedef BObjectList<WaitObjectGroup> WaitObjectGroupList;
44			typedef BObjectList<const system_profiler_event_header> EventList;
45
46private:
47			Model*				fModel;
48			Model::Thread*		fThread;
49			WaitObjectGroupList	fWaitObjectGroups;
50			EventList			fSchedulingEvents;
51};
52
53
54struct ThreadModel::type_and_name {
55	uint32		type;
56	const char*	name;
57};
58
59
60class ThreadModel::WaitObjectGroup {
61public:
62								WaitObjectGroup(
63									Model::ThreadWaitObject** waitObjects,
64									int32 count);
65								~WaitObjectGroup();
66
67	inline	uint32				Type() const;
68	inline	const char*			Name() const;
69	inline	addr_t				Object() const;
70
71	inline	int64				Waits() const;
72	inline	nanotime_t			TotalWaitTime() const;
73
74	inline	int32				CountWaitObjects() const;
75	inline	Model::ThreadWaitObject* WaitObjectAt(int32 index) const;
76
77	static inline int			CompareByTypeName(const WaitObjectGroup* a,
78									const WaitObjectGroup* b);
79	static inline int			CompareWithTypeName(
80									const type_and_name* key,
81									const WaitObjectGroup* group);
82
83private:
84			Model::ThreadWaitObject** fWaitObjects;
85			int32				fCount;
86			int64				fWaits;
87			nanotime_t			fTotalWaitTime;
88};
89
90
91// #pragma mark - ThreadModel
92
93
94int32
95ThreadModel::CountWaitObjectGroups() const
96{
97	return fWaitObjectGroups.CountItems();
98}
99
100
101ThreadModel::WaitObjectGroup*
102ThreadModel::WaitObjectGroupAt(int32 index) const
103{
104	return fWaitObjectGroups.ItemAt(index);
105}
106
107
108int32
109ThreadModel::CountSchedulingEvents() const
110{
111	return fSchedulingEvents.CountItems();
112}
113
114
115const system_profiler_event_header*
116ThreadModel::SchedulingEventAt(int32 index) const
117{
118	return fSchedulingEvents.ItemAt(index);
119}
120
121
122// #pragma mark - WaitObjectGroup
123
124
125uint32
126ThreadModel::WaitObjectGroup::Type() const
127{
128	return fWaitObjects[0]->Type();
129}
130
131
132const char*
133ThreadModel::WaitObjectGroup::Name() const
134{
135	return fWaitObjects[0]->Name();
136}
137
138
139addr_t
140ThreadModel::WaitObjectGroup::Object() const
141{
142	return fWaitObjects[0]->Object();
143}
144
145
146int64
147ThreadModel::WaitObjectGroup::Waits() const
148{
149	return fWaits;
150}
151
152
153nanotime_t
154ThreadModel::WaitObjectGroup::TotalWaitTime() const
155{
156	return fTotalWaitTime;
157}
158
159
160int32
161ThreadModel::WaitObjectGroup::CountWaitObjects() const
162{
163	return fCount;
164}
165
166
167Model::ThreadWaitObject*
168ThreadModel::WaitObjectGroup::WaitObjectAt(int32 index) const
169{
170	return index >= 0 && index < fCount ? fWaitObjects[index] : NULL;
171}
172
173
174/*static*/ int
175ThreadModel::WaitObjectGroup::CompareByTypeName(const WaitObjectGroup* a,
176	const WaitObjectGroup* b)
177{
178	type_and_name key;
179	key.type = a->Type();
180	key.name = a->Name();
181	return CompareWithTypeName(&key, b);
182}
183
184
185/*static*/ int
186ThreadModel::WaitObjectGroup::CompareWithTypeName(const type_and_name* key,
187	const WaitObjectGroup* group)
188{
189	if (key->type != group->Type())
190		return key->type < group->Type() ? -1 : 1;
191
192	return strcmp(key->name, group->Name());
193}
194
195
196#endif	// THREAD_MODEL_h
197