From 4e890d3456660b066fa67941130a12856a2d389e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 7 Dec 2009 11:46:01 +0000 Subject: [PATCH] * Added a WaitingObjects page to the debug analyzer; I don't consider it finished yet (it's a simple list of all waiting object groups, but should be a tree), but it might already be helpful enough. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34532 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/debuganalyzer/gui/Jamfile | 1 + .../debuganalyzer/gui/main_window/Jamfile | 1 + .../gui/main_window/MainWindow.cpp | 4 + .../gui/main_window/MainWindow.h | 2 + .../gui/main_window/WaitObjectsPage.cpp | 151 ++++++++++++++++++ .../gui/main_window/WaitObjectsPage.h | 34 ++++ src/apps/debuganalyzer/model/Model.cpp | 69 +++++++- src/apps/debuganalyzer/model/Model.h | 58 ++++++- 8 files changed, 314 insertions(+), 6 deletions(-) create mode 100644 src/apps/debuganalyzer/gui/main_window/WaitObjectsPage.cpp create mode 100644 src/apps/debuganalyzer/gui/main_window/WaitObjectsPage.h diff --git a/src/apps/debuganalyzer/gui/Jamfile b/src/apps/debuganalyzer/gui/Jamfile index 98b6dafda5..b4c480d721 100644 --- a/src/apps/debuganalyzer/gui/Jamfile +++ b/src/apps/debuganalyzer/gui/Jamfile @@ -25,5 +25,6 @@ MergeObject DebugAnalyzer_gui.o HaikuSubInclude chart ; HaikuSubInclude main_window ; +#HaikuSubInclude model ; HaikuSubInclude table ; HaikuSubInclude thread_window ; diff --git a/src/apps/debuganalyzer/gui/main_window/Jamfile b/src/apps/debuganalyzer/gui/main_window/Jamfile index aaca246d8a..d045a19373 100644 --- a/src/apps/debuganalyzer/gui/main_window/Jamfile +++ b/src/apps/debuganalyzer/gui/main_window/Jamfile @@ -17,4 +17,5 @@ MergeObject DebugAnalyzer_gui_main_window.o SchedulingPage.cpp TeamsPage.cpp ThreadsPage.cpp + WaitObjectsPage.cpp ; diff --git a/src/apps/debuganalyzer/gui/main_window/MainWindow.cpp b/src/apps/debuganalyzer/gui/main_window/MainWindow.cpp index 4a149fee79..8a6071d256 100644 --- a/src/apps/debuganalyzer/gui/main_window/MainWindow.cpp +++ b/src/apps/debuganalyzer/gui/main_window/MainWindow.cpp @@ -26,6 +26,7 @@ #include "main_window/SchedulingPage.h" #include "main_window/TeamsPage.h" #include "main_window/ThreadsPage.h" +#include "main_window/WaitObjectsPage.h" #include "thread_window/ThreadWindow.h" @@ -39,6 +40,7 @@ MainWindow::MainWindow(DataSource* dataSource) fTeamsPage(NULL), fThreadsPage(NULL), fSchedulingPage(NULL), + fWaitObjectsPage(NULL), fModel(NULL), fModelLoader(NULL), fSubWindowManager(NULL) @@ -57,6 +59,7 @@ MainWindow::MainWindow(DataSource* dataSource) fMainTabView->AddTab(fTeamsPage = new TeamsPage(this)); fMainTabView->AddTab(fThreadsPage = new ThreadsPage(this)); fMainTabView->AddTab(fSchedulingPage = new SchedulingPage(this)); + fMainTabView->AddTab(fWaitObjectsPage = new WaitObjectsPage(this)); // create a model loader, if we have a data source if (dataSource != NULL) @@ -204,4 +207,5 @@ MainWindow::_SetModel(Model* model) fTeamsPage->SetModel(fModel); fThreadsPage->SetModel(fModel); fSchedulingPage->SetModel(fModel); + fWaitObjectsPage->SetModel(fModel); } diff --git a/src/apps/debuganalyzer/gui/main_window/MainWindow.h b/src/apps/debuganalyzer/gui/main_window/MainWindow.h index afc9856738..c7ec34f013 100644 --- a/src/apps/debuganalyzer/gui/main_window/MainWindow.h +++ b/src/apps/debuganalyzer/gui/main_window/MainWindow.h @@ -35,6 +35,7 @@ private: class TeamsPage; class ThreadsPage; class SchedulingPage; + class WaitObjectsPage; private: void _SetModel(Model* model); @@ -45,6 +46,7 @@ private: TeamsPage* fTeamsPage; ThreadsPage* fThreadsPage; SchedulingPage* fSchedulingPage; + WaitObjectsPage* fWaitObjectsPage; Model* fModel; ModelLoader* fModelLoader; SubWindowManager* fSubWindowManager; diff --git a/src/apps/debuganalyzer/gui/main_window/WaitObjectsPage.cpp b/src/apps/debuganalyzer/gui/main_window/WaitObjectsPage.cpp new file mode 100644 index 0000000000..b11ad65d9b --- /dev/null +++ b/src/apps/debuganalyzer/gui/main_window/WaitObjectsPage.cpp @@ -0,0 +1,151 @@ +/* + * Copyright 2009, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "main_window/WaitObjectsPage.h" + +#include + +#include + +#include + +#include "table/TableColumns.h" + + +// #pragma mark - WaitObjectsTableModel + + +class MainWindow::WaitObjectsPage::WaitObjectsTableModel : public TableModel { +public: + WaitObjectsTableModel(Model* model) + : + fModel(model) + { + } + + virtual int32 CountColumns() const + { + return 6; + } + + virtual int32 CountRows() const + { + return fModel->CountWaitObjectGroups(); + } + + virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, BVariant& value) + { + Model::WaitObjectGroup* group = fModel->WaitObjectGroupAt(rowIndex); + if (group == NULL) + return false; + + switch (columnIndex) { + case 0: + value.SetTo(_TypeToString(group->Type()), + B_VARIANT_DONT_COPY_DATA); + return true; + case 1: + value.SetTo(group->Name(), B_VARIANT_DONT_COPY_DATA); + return true; + case 4: + value.SetTo(group->Waits()); + return true; + case 5: + value.SetTo(group->TotalWaitTime()); + return true; + default: + return false; + } + } + +private: + static const char* _TypeToString(uint32 type) + { + switch (type) { + case THREAD_BLOCK_TYPE_SEMAPHORE: + return "semaphore"; + case THREAD_BLOCK_TYPE_CONDITION_VARIABLE: + return "condition"; + case THREAD_BLOCK_TYPE_MUTEX: + return "mutex"; + case THREAD_BLOCK_TYPE_RW_LOCK: + return "rw lock"; + case THREAD_BLOCK_TYPE_OTHER: + return "other"; + case THREAD_BLOCK_TYPE_SNOOZE: + return "snooze"; + case THREAD_BLOCK_TYPE_SIGNAL: + return "signal"; + default: + return "unknown"; + } + } + +private: + Model* fModel; +}; + + +// #pragma mark - WaitObjectsPage + + +MainWindow::WaitObjectsPage::WaitObjectsPage(MainWindow* parent) + : + BGroupView(B_VERTICAL), + fParent(parent), + fWaitObjectsTable(NULL), + fWaitObjectsTableModel(NULL), + fModel(NULL) +{ + SetName("WaitObjects"); + + fWaitObjectsTable = new Table("waiting objects list", 0); + AddChild(fWaitObjectsTable->ToView()); + + fWaitObjectsTable->AddColumn(new StringTableColumn(0, "Type", 80, 40, 1000, + B_TRUNCATE_END, B_ALIGN_LEFT)); + fWaitObjectsTable->AddColumn(new StringTableColumn(1, "Name", 80, 40, 1000, + B_TRUNCATE_END, B_ALIGN_LEFT)); +// fWaitObjectsTable->AddColumn(new StringTableColumn(2, "Object", 80, 40, 1000, +// B_TRUNCATE_END, B_ALIGN_LEFT)); +// fWaitObjectsTable->AddColumn(new StringTableColumn(3, "Referenced", 80, 40, +// 1000, B_TRUNCATE_END, B_ALIGN_LEFT)); + fWaitObjectsTable->AddColumn(new Int64TableColumn(4, "Waits", 80, 40, + 1000, B_TRUNCATE_END, B_ALIGN_RIGHT)); + fWaitObjectsTable->AddColumn(new BigtimeTableColumn(5, "Wait Time", 80, + 40, 1000, false, B_TRUNCATE_END, B_ALIGN_RIGHT)); +} + + +MainWindow::WaitObjectsPage::~WaitObjectsPage() +{ + fWaitObjectsTable->SetTableModel(NULL); + delete fWaitObjectsTableModel; +} + + +void +MainWindow::WaitObjectsPage::SetModel(Model* model) +{ + if (model == fModel) + return; + + if (fModel != NULL) { + fWaitObjectsTable->SetTableModel(NULL); + delete fWaitObjectsTableModel; + fWaitObjectsTableModel = NULL; + } + + fModel = model; + + if (fModel != NULL) { + fWaitObjectsTableModel + = new(std::nothrow) WaitObjectsTableModel(fModel); + fWaitObjectsTable->SetTableModel(fWaitObjectsTableModel); + fWaitObjectsTable->ResizeAllColumnsToPreferred(); + } +} diff --git a/src/apps/debuganalyzer/gui/main_window/WaitObjectsPage.h b/src/apps/debuganalyzer/gui/main_window/WaitObjectsPage.h new file mode 100644 index 0000000000..8118a76bb0 --- /dev/null +++ b/src/apps/debuganalyzer/gui/main_window/WaitObjectsPage.h @@ -0,0 +1,34 @@ +/* + * Copyright 2009, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef MAIN_WAIT_OBJECTS_PAGE_H +#define MAIN_WAIT_OBJECTS_PAGE_H + + +#include + +#include "table/Table.h" + +#include "main_window/MainWindow.h" + + +class MainWindow::WaitObjectsPage : public BGroupView { +public: + WaitObjectsPage(MainWindow* parent); + virtual ~WaitObjectsPage(); + + void SetModel(Model* model); + +private: + class WaitObjectsTableModel; + + MainWindow* fParent; + Table* fWaitObjectsTable; + WaitObjectsTableModel* fWaitObjectsTableModel; + Model* fModel; +}; + + +#endif // MAIN_WAIT_OBJECTS_PAGE_H diff --git a/src/apps/debuganalyzer/model/Model.cpp b/src/apps/debuganalyzer/model/Model.cpp index 87c532afe2..29c7f8c736 100644 --- a/src/apps/debuganalyzer/model/Model.cpp +++ b/src/apps/debuganalyzer/model/Model.cpp @@ -3,6 +3,7 @@ * Distributed under the terms of the MIT License. */ + #include "Model.h" #include @@ -18,7 +19,9 @@ Model::WaitObject::WaitObject(const system_profiler_wait_object_info* event) : - fEvent(event) + fEvent(event), + fWaits(0), + fTotalWaitTime(0) { } @@ -28,12 +31,23 @@ Model::WaitObject::~WaitObject() } +void +Model::WaitObject::AddWait(bigtime_t waitTime) +{ + fWaits++; + fTotalWaitTime += waitTime; +} + + // #pragma mark - WaitObjectGroup Model::WaitObjectGroup::WaitObjectGroup(WaitObject* waitObject) + : + fWaits(-1), + fTotalWaitTime(-1) { - fWaitObjects.Add(waitObject); + fWaitObjects.AddItem(waitObject); } @@ -42,6 +56,41 @@ Model::WaitObjectGroup::~WaitObjectGroup() } +int64 +Model::WaitObjectGroup::Waits() +{ + if (fWaits < 0) + _ComputeWaits(); + + return fWaits; +} + + +bigtime_t +Model::WaitObjectGroup::TotalWaitTime() +{ + if (fTotalWaitTime < 0) + _ComputeWaits(); + + return fTotalWaitTime; +} + + +void +Model::WaitObjectGroup::_ComputeWaits() +{ + fWaits = 0; + fTotalWaitTime = 0; + + for (int32 i = fWaitObjects.CountItems(); i-- > 0;) { + WaitObject* waitObject = fWaitObjects.ItemAt(i); + + fWaits += waitObject->Waits(); + fTotalWaitTime += waitObject->TotalWaitTime(); + } +} + + // #pragma mark - ThreadWaitObject @@ -64,6 +113,8 @@ Model::ThreadWaitObject::AddWait(bigtime_t waitTime) { fWaits++; fTotalWaitTime += waitTime; + + fWaitObject->AddWait(waitTime); } @@ -577,6 +628,20 @@ Model::AddWaitObject(const system_profiler_wait_object_info* event, } +int32 +Model::CountWaitObjectGroups() const +{ + return fWaitObjectGroups.CountItems(); +} + + +Model::WaitObjectGroup* +Model::WaitObjectGroupAt(int32 index) const +{ + return fWaitObjectGroups.ItemAt(index); +} + + Model::WaitObjectGroup* Model::WaitObjectGroupFor(uint32 type, addr_t object) const { diff --git a/src/apps/debuganalyzer/model/Model.h b/src/apps/debuganalyzer/model/Model.h index cbc9f77f4a..35a1aeef60 100644 --- a/src/apps/debuganalyzer/model/Model.h +++ b/src/apps/debuganalyzer/model/Model.h @@ -82,6 +82,9 @@ public: const system_profiler_wait_object_info* event, WaitObjectGroup** _waitObjectGroup); + + int32 CountWaitObjectGroups() const; + WaitObjectGroup* WaitObjectGroupAt(int32 index) const; WaitObjectGroup* WaitObjectGroupFor(uint32 type, addr_t object) const; @@ -136,7 +139,7 @@ struct Model::type_and_object { }; -class Model::WaitObject : public SinglyLinkedListLinkImpl { +class Model::WaitObject { public: WaitObject( const system_profiler_wait_object_info* @@ -148,6 +151,11 @@ public: inline const char* Name() const; inline addr_t ReferencedObject(); + inline int64 Waits() const; + inline bigtime_t TotalWaitTime() const; + + void AddWait(bigtime_t waitTime); + static inline int CompareByTypeObject(const WaitObject* a, const WaitObject* b); static inline int CompareWithTypeObject( @@ -156,6 +164,10 @@ public: private: const system_profiler_wait_object_info* fEvent; + +private: + int64 fWaits; + bigtime_t fTotalWaitTime; }; @@ -168,8 +180,14 @@ public: inline addr_t Object() const; inline const char* Name() const; + int64 Waits(); + bigtime_t TotalWaitTime(); + inline WaitObject* MostRecentWaitObject() const; + inline int32 CountWaitObjects() const; + inline Model::WaitObject* WaitObjectAt(int32 index) const; + inline void AddWaitObject(WaitObject* waitObject); static inline int CompareByTypeObject(const WaitObjectGroup* a, @@ -179,10 +197,14 @@ public: const WaitObjectGroup* group); private: - typedef SinglyLinkedList WaitObjectList; + typedef BObjectList WaitObjectList; + + void _ComputeWaits(); private: WaitObjectList fWaitObjects; + int64 fWaits; + bigtime_t fTotalWaitTime; }; @@ -528,6 +550,20 @@ Model::WaitObject::ReferencedObject() } +int64 +Model::WaitObject::Waits() const +{ + return fWaits; +} + + +bigtime_t +Model::WaitObject::TotalWaitTime() const +{ + return fTotalWaitTime; +} + + /*static*/ int Model::WaitObject::CompareByTypeObject(const WaitObject* a, const WaitObject* b) { @@ -580,14 +616,28 @@ Model::WaitObjectGroup::Name() const Model::WaitObject* Model::WaitObjectGroup::MostRecentWaitObject() const { - return fWaitObjects.Head(); + return fWaitObjects.ItemAt(fWaitObjects.CountItems() - 1); +} + + +int32 +Model::WaitObjectGroup::CountWaitObjects() const +{ + return fWaitObjects.CountItems(); +} + + +Model::WaitObject* +Model::WaitObjectGroup::WaitObjectAt(int32 index) const +{ + return fWaitObjects.ItemAt(index); } void Model::WaitObjectGroup::AddWaitObject(WaitObject* waitObject) { - fWaitObjects.Add(waitObject); + fWaitObjects.AddItem(waitObject); }