xref: /haiku/src/apps/debuganalyzer/model/ThreadModel.cpp (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
1 /*
2  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "ThreadModel.h"
8 
9 #include <new>
10 
11 
12 // #pragma mark - WaitObjectGroup
13 
14 
15 ThreadModel::WaitObjectGroup::WaitObjectGroup(
16 	Model::ThreadWaitObject** waitObjects, int32 count)
17 	:
18 	fWaitObjects(waitObjects),
19 	fCount(count),
20 	fWaits(0),
21 	fTotalWaitTime(0)
22 {
23 	for (int32 i = 0; i < fCount; i++) {
24 		fWaits += fWaitObjects[i]->Waits();
25 		fTotalWaitTime += fWaitObjects[i]->TotalWaitTime();
26 	}
27 }
28 
29 
30 ThreadModel::WaitObjectGroup::~WaitObjectGroup()
31 {
32 	delete[] fWaitObjects;
33 }
34 
35 
36 // #pragma mark - ThreadModel
37 
38 
39 ThreadModel::ThreadModel(Model* model, Model::Thread* thread)
40 	:
41 	fModel(model),
42 	fThread(thread),
43 	fWaitObjectGroups(10, true)
44 {
45 }
46 
47 
48 ThreadModel::~ThreadModel()
49 {
50 }
51 
52 
53 ThreadModel::WaitObjectGroup*
54 ThreadModel::AddWaitObjectGroup(
55 	const BObjectList<Model::ThreadWaitObject>& waitObjects, int32 start,
56 	int32 end)
57 {
58 	// check params
59 	int32 count = end - start;
60 	if (start < 0 || count <= 0 || waitObjects.CountItems() < end)
61 		return NULL;
62 
63 	// create an array of the wait object
64 	Model::ThreadWaitObject** objects
65 		= new(std::nothrow) Model::ThreadWaitObject*[count];
66 	if (objects == NULL)
67 		return NULL;
68 
69 	for (int32 i = 0; i < count; i++)
70 		objects[i] = waitObjects.ItemAt(start + i);
71 
72 	// create and add the group
73 	WaitObjectGroup* group = new(std::nothrow) WaitObjectGroup(objects, count);
74 	if (group == NULL) {
75 		delete[] objects;
76 		return NULL;
77 	}
78 
79 	if (!fWaitObjectGroups.BinaryInsert(group,
80 			&WaitObjectGroup::CompareByTypeName)) {
81 		delete group;
82 		return NULL;
83 	}
84 
85 	return group;
86 }
87 
88 
89 bool
90 ThreadModel::AddSchedulingEvent(const system_profiler_event_header* eventHeader)
91 {
92 	return fSchedulingEvents.AddItem(eventHeader);
93 }
94 
95 
96 int32
97 ThreadModel::FindSchedulingEvent(nanotime_t time)
98 {
99 	if (time < 0)
100 		return 0;
101 
102 	time += fModel->BaseTime();
103 
104 	int32 lower = 0;
105 	int32 upper = CountSchedulingEvents() - 1;
106 
107 	while (lower < upper) {
108 		int32 mid = (lower + upper) / 2;
109 		const system_profiler_event_header* header = SchedulingEventAt(mid);
110 		system_profiler_thread_scheduling_event* event
111 			=  (system_profiler_thread_scheduling_event*)(header + 1);
112 		if (event->time < time)
113 			lower = mid + 1;
114 		else
115 			upper = mid;
116 	}
117 
118 	// We've found the first event that has a time >= the given time. If its
119 	// time is >, we rather return the previous event.
120 	if (lower > 0) {
121 		const system_profiler_event_header* header = SchedulingEventAt(lower);
122 		system_profiler_thread_scheduling_event* event
123 			=  (system_profiler_thread_scheduling_event*)(header + 1);
124 		if (event->time > time)
125 			lower--;
126 	}
127 
128 	return lower;
129 }
130