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