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
WaitObjectGroup(Model::ThreadWaitObject ** waitObjects,int32 count)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
~WaitObjectGroup()30 ThreadModel::WaitObjectGroup::~WaitObjectGroup()
31 {
32 delete[] fWaitObjects;
33 }
34
35
36 // #pragma mark - ThreadModel
37
38
ThreadModel(Model * model,Model::Thread * thread)39 ThreadModel::ThreadModel(Model* model, Model::Thread* thread)
40 :
41 fModel(model),
42 fThread(thread),
43 fWaitObjectGroups(10, true)
44 {
45 }
46
47
~ThreadModel()48 ThreadModel::~ThreadModel()
49 {
50 }
51
52
53 ThreadModel::WaitObjectGroup*
AddWaitObjectGroup(const BObjectList<Model::ThreadWaitObject> & waitObjects,int32 start,int32 end)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
AddSchedulingEvent(const system_profiler_event_header * eventHeader)90 ThreadModel::AddSchedulingEvent(const system_profiler_event_header* eventHeader)
91 {
92 return fSchedulingEvents.AddItem(eventHeader);
93 }
94
95
96 int32
FindSchedulingEvent(nanotime_t time)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