* 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
This commit is contained in:
Axel Dörfler
2009-12-07 11:46:01 +00:00
parent e55886c3a3
commit 4e890d3456
8 changed files with 314 additions and 6 deletions
+1
View File
@@ -25,5 +25,6 @@ MergeObject DebugAnalyzer_gui.o
HaikuSubInclude chart ;
HaikuSubInclude main_window ;
#HaikuSubInclude model ;
HaikuSubInclude table ;
HaikuSubInclude thread_window ;
@@ -17,4 +17,5 @@ MergeObject DebugAnalyzer_gui_main_window.o
SchedulingPage.cpp
TeamsPage.cpp
ThreadsPage.cpp
WaitObjectsPage.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);
}
@@ -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;
@@ -0,0 +1,151 @@
/*
* Copyright 2009, Axel Dörfler, [email protected].
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "main_window/WaitObjectsPage.h"
#include <stdio.h>
#include <new>
#include <thread_defs.h>
#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();
}
}
@@ -0,0 +1,34 @@
/*
* Copyright 2009, Axel Dörfler, [email protected].
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef MAIN_WAIT_OBJECTS_PAGE_H
#define MAIN_WAIT_OBJECTS_PAGE_H
#include <GroupView.h>
#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
+67 -2
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License.
*/
#include "Model.h"
#include <new>
@@ -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
{
+54 -4
View File
@@ -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<WaitObject> {
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<WaitObject> WaitObjectList;
typedef BObjectList<WaitObject> 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);
}