BTRFS: Implement BTree::Path and change _Find.
[haiku.git] / src / apps / debuganalyzer / model_loader / ThreadModelLoader.cpp
blob3ff9a47fa0ca4ec919c5a04558ede19ea01ba655
1 /*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
6 #include "ThreadModelLoader.h"
8 #include <stdio.h>
10 #include <new>
12 #include <AutoLocker.h>
13 #include <DebugEventStream.h>
15 #include "ThreadModel.h"
18 static int
19 compare_by_type_and_name(const Model::ThreadWaitObject* a,
20 const Model::ThreadWaitObject* b)
22 if (a->Type() != b->Type())
23 return a->Type() < b->Type() ? -1 : 1;
25 return strcmp(a->Name(), b->Name());
29 // #pragma mark -
32 ThreadModelLoader::ThreadModelLoader(Model* model, Model::Thread* thread,
33 const BMessenger& target, void* targetCookie)
35 AbstractModelLoader(target, targetCookie),
36 fModel(model),
37 fThread(thread),
38 fThreadModel(NULL)
43 ThreadModelLoader::~ThreadModelLoader()
45 delete fThreadModel;
49 ThreadModel*
50 ThreadModelLoader::DetachModel()
52 AutoLocker<BLocker> locker(fLock);
54 if (fThreadModel == NULL || fLoading)
55 return NULL;
57 ThreadModel* model = fThreadModel;
58 fThreadModel = NULL;
60 return model;
64 status_t
65 ThreadModelLoader::PrepareForLoading()
67 return B_OK;
71 status_t
72 ThreadModelLoader::Load()
74 try {
75 return _Load();
76 } catch(...) {
77 return B_ERROR;
82 void
83 ThreadModelLoader::FinishLoading(bool success)
85 if (!success) {
86 delete fThreadModel;
87 fThreadModel = NULL;
92 status_t
93 ThreadModelLoader::_Load()
95 // create a model
96 fThreadModel = new(std::nothrow) ThreadModel(fModel, fThread);
97 if (fThreadModel == NULL)
98 return B_NO_MEMORY;
100 // collect all wait objects
101 BObjectList<Model::ThreadWaitObject> waitObjects;
103 int32 groupCount = fThread->CountThreadWaitObjectGroups();
104 for (int32 i = 0; i < groupCount; i++) {
105 Model::ThreadWaitObjectGroup* group
106 = fThread->ThreadWaitObjectGroupAt(i);
108 if (!group->GetThreadWaitObjects(waitObjects))
109 return B_NO_MEMORY;
112 // sort them by type and name
113 waitObjects.SortItems(&compare_by_type_and_name);
115 // create the groups
116 int32 waitObjectCount = waitObjects.CountItems();
117 printf("%" B_PRId32 " wait objects\n", waitObjectCount);
118 for (int32 i = 0; i < waitObjectCount;) {
119 printf("new wait object group at %" B_PRId32 "\n", i);
120 // collect the objects for this group
121 Model::ThreadWaitObject* firstObject = waitObjects.ItemAt(i);
122 int32 k = i + 1;
123 for (; k < waitObjectCount; k++) {
124 if (compare_by_type_and_name(firstObject, waitObjects.ItemAt(k))
125 != 0) {
126 break;
130 if (fThreadModel->AddWaitObjectGroup(waitObjects, i, k) == NULL)
131 return B_NO_MEMORY;
133 i = k;
136 // filter the events
137 thread_id threadID = fThread->ID();
138 bool done = false;
139 uint32 count = 0;
141 system_profiler_event_header** events = fModel->Events();
142 size_t eventCount = fModel->CountEvents();
143 for (size_t i = 0; i < eventCount; i++) {
144 system_profiler_event_header* header = events[i];
145 void* buffer = header + 1;
147 // process the event
148 bool keepEvent = false;
150 switch (header->event) {
151 case B_SYSTEM_PROFILER_THREAD_REMOVED:
153 system_profiler_thread_removed* event
154 = (system_profiler_thread_removed*)buffer;
155 if (event->thread == threadID)
156 done = true;
157 break;
160 case B_SYSTEM_PROFILER_THREAD_SCHEDULED:
162 system_profiler_thread_scheduled* event
163 = (system_profiler_thread_scheduled*)buffer;
164 keepEvent = event->thread == threadID
165 || event->previous_thread == threadID ;
166 break;
169 case B_SYSTEM_PROFILER_THREAD_ENQUEUED_IN_RUN_QUEUE:
171 thread_enqueued_in_run_queue* event
172 = (thread_enqueued_in_run_queue*)buffer;
173 keepEvent = event->thread == threadID;
174 break;
177 case B_SYSTEM_PROFILER_THREAD_REMOVED_FROM_RUN_QUEUE:
179 thread_removed_from_run_queue* event
180 = (thread_removed_from_run_queue*)buffer;
181 keepEvent = event->thread == threadID;
182 break;
185 default:
186 break;
189 if (keepEvent)
190 fThreadModel->AddSchedulingEvent(header);
192 // periodically check whether we're supposed to abort
193 if (++count % 32 == 0) {
194 AutoLocker<BLocker> locker(fLock);
195 if (fAborted)
196 return B_ERROR;
200 return B_OK;