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