diff --git a/src/apps/debuganalyzer/model_loader/ThreadModelLoader.cpp b/src/apps/debuganalyzer/model_loader/ThreadModelLoader.cpp index 5fa79e4548..e3e90e437b 100644 --- a/src/apps/debuganalyzer/model_loader/ThreadModelLoader.cpp +++ b/src/apps/debuganalyzer/model_loader/ThreadModelLoader.cpp @@ -5,9 +5,12 @@ #include "ThreadModelLoader.h" +#include + #include #include +#include #include "ThreadModel.h" @@ -110,12 +113,14 @@ ThreadModelLoader::_Load() waitObjects.SortItems(&compare_by_type_and_name); // create the groups - int32 count = waitObjects.CountItems(); - for (int32 i = 0; i < count; i++) { + int32 waitObjectCount = waitObjects.CountItems(); +printf("%ld wait objects\n", waitObjectCount); + for (int32 i = 0; i < waitObjectCount;) { +printf("new wait object group at %ld\n", i); // collect the objects for this group Model::ThreadWaitObject* firstObject = waitObjects.ItemAt(i); int32 k = i + 1; - for (; k < count; k++) { + for (; k < waitObjectCount; k++) { if (compare_by_type_and_name(firstObject, waitObjects.ItemAt(k)) != 0) { break; @@ -124,6 +129,88 @@ ThreadModelLoader::_Load() if (fThreadModel->AddWaitObjectGroup(waitObjects, i, k) == NULL) return B_NO_MEMORY; + + i = k; + } + + // create a debug input stream + BDebugEventInputStream input; + uint8* eventData = (uint8*)fModel->EventData(); + status_t error = input.SetTo(eventData, fModel->EventDataSize(), false); + if (error != B_OK) + return error; + + // process the events + thread_id threadID = fThread->ID(); + bool done = false; + uint32 count = 0; + + while (!done) { + // get next event + uint32 eventType; + uint32 cpu; + const void* buffer; + off_t streamOffset; + ssize_t bufferSize = input.ReadNextEvent(&eventType, &cpu, &buffer, + &streamOffset); + if (bufferSize < 0) + return bufferSize; + if (buffer == NULL) + break; + + // process the event + bool keepEvent = false; + + switch (eventType) { + case B_SYSTEM_PROFILER_THREAD_REMOVED: + { + system_profiler_thread_removed* event + = (system_profiler_thread_removed*)buffer; + if (event->thread == threadID) + done = true; + break; + } + + case B_SYSTEM_PROFILER_THREAD_SCHEDULED: + { + system_profiler_thread_scheduled* event + = (system_profiler_thread_scheduled*)buffer; + keepEvent = event->thread == threadID + || event->previous_thread == threadID ; + break; + } + + case B_SYSTEM_PROFILER_THREAD_ENQUEUED_IN_RUN_QUEUE: + { + thread_enqueued_in_run_queue* event + = (thread_enqueued_in_run_queue*)buffer; + keepEvent = event->thread == threadID; + break; + } + + case B_SYSTEM_PROFILER_THREAD_REMOVED_FROM_RUN_QUEUE: + { + thread_removed_from_run_queue* event + = (thread_removed_from_run_queue*)buffer; + keepEvent = event->thread == threadID; + break; + } + + default: + break; + } + + if (keepEvent) { + fThreadModel->AddSchedulingEvent( + (system_profiler_event_header*)(eventData + streamOffset)); + } + + // periodically check whether we're supposed to abort + if (++count % 32 == 0) { + AutoLocker locker(fLock); + if (fAborted) + return B_ERROR; + } } return B_OK; diff --git a/src/apps/debuganalyzer/model_loader/ThreadModelLoader.h b/src/apps/debuganalyzer/model_loader/ThreadModelLoader.h index e1787d37f9..61cca73035 100644 --- a/src/apps/debuganalyzer/model_loader/ThreadModelLoader.h +++ b/src/apps/debuganalyzer/model_loader/ThreadModelLoader.h @@ -30,6 +30,13 @@ protected: virtual status_t Load(); virtual void FinishLoading(bool success); +private: + // shorthands for the longish structure names + typedef system_profiler_thread_enqueued_in_run_queue + thread_enqueued_in_run_queue; + typedef system_profiler_thread_removed_from_run_queue + thread_removed_from_run_queue; + private: status_t _Load();