diff --git a/src/apps/Jamfile b/src/apps/Jamfile index d0ca6c1175..26dfdae63c 100644 --- a/src/apps/Jamfile +++ b/src/apps/Jamfile @@ -11,6 +11,7 @@ HaikuSubInclude charactermap ; HaikuSubInclude clock ; HaikuSubInclude codycam ; HaikuSubInclude cortex ; +HaikuSubInclude debuganalyzer ; HaikuSubInclude deskbar ; HaikuSubInclude deskcalc ; HaikuSubInclude diskprobe ; diff --git a/src/apps/debuganalyzer/DebugAnalyzer.cpp b/src/apps/debuganalyzer/DebugAnalyzer.cpp new file mode 100644 index 0000000000..f1387b8753 --- /dev/null +++ b/src/apps/debuganalyzer/DebugAnalyzer.cpp @@ -0,0 +1,49 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include + +#include + +#include + +#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; +} diff --git a/src/apps/debuganalyzer/DebugAnalyzer.rdef b/src/apps/debuganalyzer/DebugAnalyzer.rdef new file mode 100644 index 0000000000..d6093bdec6 --- /dev/null +++ b/src/apps/debuganalyzer/DebugAnalyzer.rdef @@ -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! diff --git a/src/apps/debuganalyzer/Jamfile b/src/apps/debuganalyzer/Jamfile new file mode 100644 index 0000000000..509bb1a553 --- /dev/null +++ b/src/apps/debuganalyzer/Jamfile @@ -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 +; diff --git a/src/apps/debuganalyzer/MainModel.cpp b/src/apps/debuganalyzer/MainModel.cpp new file mode 100644 index 0000000000..db80c91837 --- /dev/null +++ b/src/apps/debuganalyzer/MainModel.cpp @@ -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() +{ +} diff --git a/src/apps/debuganalyzer/MainModel.h b/src/apps/debuganalyzer/MainModel.h new file mode 100644 index 0000000000..deee05292a --- /dev/null +++ b/src/apps/debuganalyzer/MainModel.h @@ -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 diff --git a/src/apps/debuganalyzer/MainModelLoader.cpp b/src/apps/debuganalyzer/MainModelLoader.cpp new file mode 100644 index 0000000000..39b3e7f621 --- /dev/null +++ b/src/apps/debuganalyzer/MainModelLoader.cpp @@ -0,0 +1,186 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include "MainModelLoader.h" + +#include + +#include +#include +#include + +#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 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 modelDeleter(model); + + // create a debug input stream + BDebugEventInputStream* inputStream + = new(std::nothrow) BDebugEventInputStream; + if (inputStream == NULL) + return B_NO_MEMORY; + ObjectDeleter 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 locker(fLock); + + if (!fLoading || fAborted) + return; + + fAborted = true; +} + + +MainModel* +MainModelLoader::DetachModel() +{ + AutoLocker 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 locker(fLock); + if (fAborted) + break; + } + } + } catch (...) { + } + + // clean up and notify the target + AutoLocker 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; +} diff --git a/src/apps/debuganalyzer/MainModelLoader.h b/src/apps/debuganalyzer/MainModelLoader.h new file mode 100644 index 0000000000..f635dd0f16 --- /dev/null +++ b/src/apps/debuganalyzer/MainModelLoader.h @@ -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 +#include + + +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 diff --git a/src/apps/debuganalyzer/MainWindow.cpp b/src/apps/debuganalyzer/MainWindow.cpp new file mode 100644 index 0000000000..af645f0a7d --- /dev/null +++ b/src/apps/debuganalyzer/MainWindow.cpp @@ -0,0 +1,35 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include "MainWindow.h" + +#include +#include + +#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() +{ +} diff --git a/src/apps/debuganalyzer/MainWindow.h b/src/apps/debuganalyzer/MainWindow.h new file mode 100644 index 0000000000..609dd4698d --- /dev/null +++ b/src/apps/debuganalyzer/MainWindow.h @@ -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 + + +class BTabView; + + +class MainWindow : public BWindow { +public: + MainWindow(); + virtual ~MainWindow(); + +private: + BTabView* fMainTabView; +}; + + + +#endif // MAIN_WINDOW_H diff --git a/src/apps/debuganalyzer/MessageCodes.h b/src/apps/debuganalyzer/MessageCodes.h new file mode 100644 index 0000000000..e91699303a --- /dev/null +++ b/src/apps/debuganalyzer/MessageCodes.h @@ -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 diff --git a/src/apps/debuganalyzer/ThreadsPage.cpp b/src/apps/debuganalyzer/ThreadsPage.cpp new file mode 100644 index 0000000000..98e110b541 --- /dev/null +++ b/src/apps/debuganalyzer/ThreadsPage.cpp @@ -0,0 +1,38 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include "ThreadsPage.h" + +#include + + +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() +{ +} diff --git a/src/apps/debuganalyzer/ThreadsPage.h b/src/apps/debuganalyzer/ThreadsPage.h new file mode 100644 index 0000000000..c8abc8e9d7 --- /dev/null +++ b/src/apps/debuganalyzer/ThreadsPage.h @@ -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 + + +class BColumnListView; + + +class ThreadsPage : public BGroupView { +public: + ThreadsPage(); + virtual ~ThreadsPage(); + +private: + BColumnListView* fThreadsListView; +}; + + + +#endif // THREADS_PAGE_H