Beginnings of a graphical tool for analyzing the output of scheduling_recorder.

Doesn't do anything yet.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30255 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-04-19 00:31:03 +00:00
parent b6b82488df
commit 3dc9bfd17e
13 changed files with 491 additions and 0 deletions

View File

@ -11,6 +11,7 @@ HaikuSubInclude charactermap ;
HaikuSubInclude clock ;
HaikuSubInclude codycam ;
HaikuSubInclude cortex ;
HaikuSubInclude debuganalyzer ;
HaikuSubInclude deskbar ;
HaikuSubInclude deskcalc ;
HaikuSubInclude diskprobe ;

View File

@ -0,0 +1,49 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include <stdlib.h>
#include <new>
#include <Application.h>
#include "MainWindow.h"
static const char* const kSignature = "application/x-vnd.Haiku-DebugAnalyzer";
class DebugAnalyzer : public BApplication {
public:
DebugAnalyzer()
:
BApplication(kSignature)
{
}
virtual void ReadyToRun()
{
MainWindow* window;
try {
window = new MainWindow;
} catch (std::bad_alloc) {
exit(1);
}
window->Show();
}
private:
};
int
main(int argc, const char* const* argv)
{
DebugAnalyzer app;
app.Run();
return 0;
}

View File

@ -0,0 +1,18 @@
resource(1, "BEOS:APP_SIG") #'MIMS' "application/x-vnd.Haiku-DebugAnalyzer";
resource app_version {
major = 1,
middle = 0,
minor = 0,
variety = B_APPV_BETA,
internal = 0,
short_info = "DebugAnalyzer",
long_info = "DebugAnalyzer ©2009 Haiku, Inc."
};
resource app_flags B_SINGLE_LAUNCH;
// TODO: Please give me a nice icon!

View File

@ -0,0 +1,16 @@
SubDir HAIKU_TOP src apps debuganalyzer ;
UsePrivateHeaders debug interface shared ;
UsePrivateSystemHeaders ;
Application DebugAnalyzer
:
DebugAnalyzer.cpp
MainModel.cpp
MainModelLoader.cpp
MainWindow.cpp
ThreadsPage.cpp
: libcolumnlistview.a libdebug.so be
: DebugAnalyzer.rdef
;

View File

@ -0,0 +1,16 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "MainModel.h"
MainModel::MainModel()
{
}
MainModel::~MainModel()
{
}

View File

@ -0,0 +1,19 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef MAIN_MODEL_H
#define MAIN_MODEL_H
class MainModel {
public:
MainModel();
~MainModel();
private:
};
#endif // MAIN_MODEL_H

View File

@ -0,0 +1,186 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "MainModelLoader.h"
#include <new>
#include <AutoDeleter.h>
#include <AutoLocker.h>
#include <DebugEventStream.h>
#include "MainModel.h"
#include "MessageCodes.h"
MainModelLoader::MainModelLoader()
:
fLock("main model loader"),
fModel(NULL),
fInput(NULL),
fTarget(),
fLoaderThread(-1),
fLoading(false),
fAborted(false)
{
}
MainModelLoader::~MainModelLoader()
{
if (fLoaderThread >= 0) {
Abort();
wait_for_thread(fLoaderThread, NULL);
}
delete fInput;
delete fModel;
}
status_t
MainModelLoader::StartLoading(BDataIO& input, const BMessenger& target)
{
// check initialization
status_t error = fLock.InitCheck();
if (error != B_OK)
return error;
AutoLocker<BLocker> locker(fLock);
if (fModel != NULL)
return B_BAD_VALUE;
// create a model
MainModel* model = new(std::nothrow) MainModel;
if (model == NULL)
return B_NO_MEMORY;
ObjectDeleter<MainModel> modelDeleter(model);
// create a debug input stream
BDebugEventInputStream* inputStream
= new(std::nothrow) BDebugEventInputStream;
if (inputStream == NULL)
return B_NO_MEMORY;
ObjectDeleter<BDebugEventInputStream> inputDeleter(inputStream);
error = inputStream->SetTo(&input);
if (error != B_OK)
return error;
// spawn the loader thread
fLoaderThread = spawn_thread(&_LoaderEntry, "main model loader",
B_NORMAL_PRIORITY, this);
if (fLoaderThread < 0)
return fLoaderThread;
modelDeleter.Detach();
inputDeleter.Detach();
fModel = model;
fInput = inputStream;
fLoading = true;
fAborted = false;
resume_thread(fLoaderThread);
return B_OK;
}
void
MainModelLoader::Abort()
{
AutoLocker<BLocker> locker(fLock);
if (!fLoading || fAborted)
return;
fAborted = true;
}
MainModel*
MainModelLoader::DetachModel()
{
AutoLocker<BLocker> locker(fLock);
if (fModel == NULL || fLoading)
return NULL;
MainModel* model = fModel;
fModel = NULL;
return model;
}
/*static*/ status_t
MainModelLoader::_LoaderEntry(void* data)
{
return ((MainModelLoader*)data)->_Loader();
}
status_t
MainModelLoader::_Loader()
{
bool success = false;
uint32 count = 0;
try {
while (true) {
// get next event
const system_profiler_event_header* header;
ssize_t bufferSize = fInput->ReadNextEvent(&header);
if (bufferSize < 0) {
success = bufferSize == B_ENTRY_NOT_FOUND;
break;
}
// process the event
status_t error = _ProcessEvent(header, bufferSize);
if (error != B_OK)
break;
if (++count % 32 == 0) {
AutoLocker<BLocker> locker(fLock);
if (fAborted)
break;
}
}
} catch (...) {
}
// clean up and notify the target
AutoLocker<BLocker> locker(fLock);
delete fInput;
fInput = NULL;
if (success) {
fTarget.SendMessage(MSG_MODEL_LOADED_SUCCESSFULLY);
} else {
delete fModel;
fModel = NULL;
fTarget.SendMessage(
fAborted ? MSG_MODEL_LOADED_ABORTED : MSG_MODEL_LOADED_FAILED);
}
fLoading = false;
return B_OK;
}
status_t
MainModelLoader::_ProcessEvent(const system_profiler_event_header* header,
size_t size)
{
// TODO: Implement!
return B_ERROR;
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef MAIN_MODEL_LOADER_H
#define MAIN_MODEL_LOADER_H
#include <Locker.h>
#include <Messenger.h>
class BDataIO;
class BDebugEventInputStream;
class MainModel;
struct system_profiler_event_header;
class MainModelLoader {
public:
MainModelLoader();
~MainModelLoader();
status_t StartLoading(BDataIO& input,
const BMessenger& target);
void Abort();
MainModel* DetachModel();
private:
static status_t _LoaderEntry(void* data);
status_t _Loader();
status_t _ProcessEvent(
const system_profiler_event_header* header,
size_t size);
private:
BLocker fLock;
MainModel* fModel;
BDebugEventInputStream* fInput;
BMessenger fTarget;
thread_id fLoaderThread;
bool fLoading;
bool fAborted;
};
#endif // MAIN_MODEL_LOADER_H

View File

@ -0,0 +1,35 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "MainWindow.h"
#include <GroupLayoutBuilder.h>
#include <TabView.h>
#include "ThreadsPage.h"
MainWindow::MainWindow()
:
BWindow(BRect(50, 50, 599, 499), "DebugAnalyzer", B_DOCUMENT_WINDOW,
B_ASYNCHRONOUS_CONTROLS),
fMainTabView(NULL)
{
BGroupLayout* rootLayout = new BGroupLayout(B_VERTICAL);
SetLayout(rootLayout);
fMainTabView = new BTabView("main tab view");
BGroupLayoutBuilder(rootLayout)
.Add(fMainTabView);
fMainTabView->AddTab(new BView("Teams", 0));
fMainTabView->AddTab(new ThreadsPage);
}
MainWindow::~MainWindow()
{
}

View File

@ -0,0 +1,25 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H
#include <Window.h>
class BTabView;
class MainWindow : public BWindow {
public:
MainWindow();
virtual ~MainWindow();
private:
BTabView* fMainTabView;
};
#endif // MAIN_WINDOW_H

View File

@ -0,0 +1,16 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef MESSAGE_CODES_H
#define MESSAGE_CODES_H
enum {
MSG_MODEL_LOADED_SUCCESSFULLY = 'mlsc',
MSG_MODEL_LOADED_FAILED = 'mlfl',
MSG_MODEL_LOADED_ABORTED = 'mlab'
};
#endif // MESSAGE_CODES_H

View File

@ -0,0 +1,38 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "ThreadsPage.h"
#include <ColumnTypes.h>
ThreadsPage::ThreadsPage()
:
BGroupView(B_VERTICAL),
fThreadsListView(NULL)
{
SetName("Threads");
fThreadsListView = new BColumnListView("threads list", 0);
AddChild(fThreadsListView);
fThreadsListView->AddColumn(new BStringColumn("Thread", 40, 20, 1000,
B_TRUNCATE_END, B_ALIGN_RIGHT), 0);
fThreadsListView->AddColumn(new BStringColumn("Name", 80, 40, 1000,
B_TRUNCATE_END, B_ALIGN_LEFT), 1);
fThreadsListView->AddColumn(new BStringColumn("Run Time", 80, 20, 1000,
B_TRUNCATE_END, B_ALIGN_RIGHT), 2);
fThreadsListView->AddColumn(new BStringColumn("Wait Time", 80, 20, 1000,
B_TRUNCATE_END, B_ALIGN_RIGHT), 3);
fThreadsListView->AddColumn(new BStringColumn("Latencies", 80, 20, 1000,
B_TRUNCATE_END, B_ALIGN_RIGHT), 4);
fThreadsListView->AddColumn(new BStringColumn("Preemptions", 80, 20, 1000,
B_TRUNCATE_END, B_ALIGN_RIGHT), 5);
}
ThreadsPage::~ThreadsPage()
{
}

View File

@ -0,0 +1,25 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef THREADS_PAGE_H
#define THREADS_PAGE_H
#include <GroupView.h>
class BColumnListView;
class ThreadsPage : public BGroupView {
public:
ThreadsPage();
virtual ~ThreadsPage();
private:
BColumnListView* fThreadsListView;
};
#endif // THREADS_PAGE_H