* 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:
@@ -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
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user