2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
6 #include "ThreadModelLoader.h"
12 #include <AutoLocker.h>
13 #include <DebugEventStream.h>
15 #include "ThreadModel.h"
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());
32 ThreadModelLoader::ThreadModelLoader(Model
* model
, Model::Thread
* thread
,
33 const BMessenger
& target
, void* targetCookie
)
35 AbstractModelLoader(target
, targetCookie
),
43 ThreadModelLoader::~ThreadModelLoader()
50 ThreadModelLoader::DetachModel()
52 AutoLocker
<BLocker
> locker(fLock
);
54 if (fThreadModel
== NULL
|| fLoading
)
57 ThreadModel
* model
= fThreadModel
;
65 ThreadModelLoader::PrepareForLoading()
72 ThreadModelLoader::Load()
83 ThreadModelLoader::FinishLoading(bool success
)
93 ThreadModelLoader::_Load()
96 fThreadModel
= new(std::nothrow
) ThreadModel(fModel
, fThread
);
97 if (fThreadModel
== NULL
)
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
))
112 // sort them by type and name
113 waitObjects
.SortItems(&compare_by_type_and_name
);
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
);
123 for (; k
< waitObjectCount
; k
++) {
124 if (compare_by_type_and_name(firstObject
, waitObjects
.ItemAt(k
))
130 if (fThreadModel
->AddWaitObjectGroup(waitObjects
, i
, k
) == NULL
)
137 thread_id threadID
= fThread
->ID();
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;
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
)
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
;
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
;
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
;
190 fThreadModel
->AddSchedulingEvent(header
);
192 // periodically check whether we're supposed to abort
193 if (++count
% 32 == 0) {
194 AutoLocker
<BLocker
> locker(fLock
);