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