From 1ff34e14da6507063b6b7936374201459d07e756 Mon Sep 17 00:00:00 2001 From: Ethereal Date: Sun, 27 Feb 2011 17:48:25 -0700 Subject: [PATCH] Began proof-of-concept memory module. This time around, it should actually be possible to perform the initialization without having to know the address libc is loaded into and the offset of calloc. Simply allocating a small static buffer and using that while the initialization occurs should work out quite nicely. --- build/config | 2 +- include/artisan/gviewport/RectObject.h | 29 +++++++++++++ include/artisan/gviewport/RenderedImage.h | 2 + include/informer/Informer.h | 1 - modules/memory/SConscript | 1 + modules/memory/module.conf | 6 +++ modules/memory/src/SConscript | 13 ++++++ modules/memory/src/artisan/DataStore.cpp | 25 +++++++++++ modules/memory/src/artisan/DataStore.h | 26 ++++++++++++ modules/memory/src/artisan/Interface.cpp | 20 +++++++++ modules/memory/src/artisan/Interface.h | 18 ++++++++ modules/memory/src/artisan/Viewport.cpp | 40 ++++++++++++++++++ modules/memory/src/artisan/Viewport.h | 17 ++++++++ modules/memory/src/collector/cpuTime.c | 69 +++++++++++++++++++++++++++++++ modules/memory/src/marshal/Marshal.cpp | 19 +++++++++ modules/memory/src/marshal/Marshal.h | 14 +++++++ src/artisan/gviewport/LineObject.cpp | 4 -- src/artisan/gviewport/RectObject.cpp | 32 ++++++++++++++ src/artisan/gviewport/RenderedImage.cpp | 6 ++- src/artisan/gviewport/Renderer.cpp | 2 + 20 files changed, 339 insertions(+), 7 deletions(-) create mode 100644 include/artisan/gviewport/RectObject.h create mode 100644 modules/memory/SConscript create mode 100644 modules/memory/module.conf create mode 100644 modules/memory/src/SConscript create mode 100644 modules/memory/src/artisan/DataStore.cpp create mode 100644 modules/memory/src/artisan/DataStore.h create mode 100644 modules/memory/src/artisan/Interface.cpp create mode 100644 modules/memory/src/artisan/Interface.h create mode 100644 modules/memory/src/artisan/Viewport.cpp create mode 100644 modules/memory/src/artisan/Viewport.h create mode 100644 modules/memory/src/collector/cpuTime.c create mode 100644 modules/memory/src/marshal/Marshal.cpp create mode 100644 modules/memory/src/marshal/Marshal.h create mode 100644 src/artisan/gviewport/RectObject.cpp diff --git a/build/config b/build/config index 18552fb..f76678c 100644 --- a/build/config +++ b/build/config @@ -2,7 +2,7 @@ { # The version of Aesalon. - "version": "0.4.0", + "version": "0.5.0", # The name of the module configuration file in the module root. "moduleConfigFileName": "module.conf", diff --git a/include/artisan/gviewport/RectObject.h b/include/artisan/gviewport/RectObject.h new file mode 100644 index 0000000..a542eda --- /dev/null +++ b/include/artisan/gviewport/RectObject.h @@ -0,0 +1,29 @@ +/** Aesalon, a tool to visualize program behaviour in real time. + Copyright (C) 2009-2011, Aesalon development team. + + Aesalon is distributed under the terms of the GNU GPLv3. See + the included file LICENSE for more information. + + @file include/artisan/gviewport/RectObject.h +*/ + +#ifndef AesalonArtisan_GViewport_RectObject_H +#define AesalonArtisan_GViewport_RectObject_H + +#include "Object.h" + +namespace Artisan { +namespace GViewport { + +class RectObject : public Object { +public: + RectObject(const Rect &rect); + virtual ~RectObject(); + + virtual void renderOnto(RenderedImage &image); +}; + +} // namespace GViewport +} // namespace Artisan + +#endif diff --git a/include/artisan/gviewport/RenderedImage.h b/include/artisan/gviewport/RenderedImage.h index a8b51ae..3531574 100644 --- a/include/artisan/gviewport/RenderedImage.h +++ b/include/artisan/gviewport/RenderedImage.h @@ -12,6 +12,7 @@ #include #include +#include #include "Rect.h" @@ -24,6 +25,7 @@ private: Rect m_pixelSize; QImage m_image; QPainter *m_painter; + QMutex m_paintLock; public: RenderedImage(const Rect &dataRange = Rect(), const Rect &pixelSize = Rect()); ~RenderedImage(); diff --git a/include/informer/Informer.h b/include/informer/Informer.h index ee1766e..30afc76 100644 --- a/include/informer/Informer.h +++ b/include/informer/Informer.h @@ -59,5 +59,4 @@ void AC_EXPORT AI_ContinueCollection(pthread_t threadID); /** Returns 1 if data should be collected, 0 otherwise. */ short AC_EXPORT AI_CollectionStatus(); - #endif diff --git a/modules/memory/SConscript b/modules/memory/SConscript new file mode 100644 index 0000000..ad755cf --- /dev/null +++ b/modules/memory/SConscript @@ -0,0 +1 @@ +SConscript("src/SConscript", variant_dir="build", duplicate=0) diff --git a/modules/memory/module.conf b/modules/memory/module.conf new file mode 100644 index 0000000..4e419a9 --- /dev/null +++ b/modules/memory/module.conf @@ -0,0 +1,6 @@ +module memory { + collectorPath = "build/libcollector.so"; + marshalPath = "build/libmarshal.so"; + artisanPath = "build/libartisan.so"; +} + diff --git a/modules/memory/src/SConscript b/modules/memory/src/SConscript new file mode 100644 index 0000000..0b86e71 --- /dev/null +++ b/modules/memory/src/SConscript @@ -0,0 +1,13 @@ +Import("env") +Import("qtEnv") + +collectorEnv = env.Clone() +marshalEnv = env.Clone() +artisanEnv = qtEnv.Clone() + +collectorEnv.Append(LIBS = ["rt", "dl"]) +artisanEnv.EnableQt4Modules(["QtCore", "QtGui"]) + +collectorEnv.SharedLibrary(target="collector", source=Glob("collector/*.c")) +marshalEnv.SharedLibrary(target="marshal", source=Glob("marshal/*.cpp")) +artisanEnv.SharedLibrary(target="artisan", source=Glob("artisan/*.cpp")) diff --git a/modules/memory/src/artisan/DataStore.cpp b/modules/memory/src/artisan/DataStore.cpp new file mode 100644 index 0000000..f084501 --- /dev/null +++ b/modules/memory/src/artisan/DataStore.cpp @@ -0,0 +1,25 @@ +#include "DataStore.h" + +DataStore::DataStore() { + m_firstTime = 0.0; +} + +DataStore::~DataStore() { + +} + +void DataStore::process(Comm::Packet *packet) { + uint64_t timestamp = reinterpret_cast(packet->data())[0]; + uint64_t cpuTime = reinterpret_cast(packet->data())[1]; + + if(m_firstTime == 0.0) { + m_firstTime = timestamp; + } + else { + double value = double(cpuTime-m_lastCpuTime) / (timestamp - m_lastTime); + m_dataList.push_back(QPair(timestamp - m_firstTime, value)); + } + + m_lastTime = timestamp; + m_lastCpuTime = cpuTime; +} diff --git a/modules/memory/src/artisan/DataStore.h b/modules/memory/src/artisan/DataStore.h new file mode 100644 index 0000000..55bced0 --- /dev/null +++ b/modules/memory/src/artisan/DataStore.h @@ -0,0 +1,26 @@ +#ifndef AesalonArtisan_cpuTime_DataStore_H +#define AesalonArtisan_cpuTime_DataStore_H + +#include +#include +#include + +#include "artisan/DataStore.h" +#include "artisan/gviewport/Data.h" + +class DataStore : public Artisan::DataStore, public Artisan::GViewport::Data { +private: + QList > m_dataList; + double m_firstTime; + double m_lastCpuTime; + double m_lastTime; +public: + DataStore(); + virtual ~DataStore(); + + virtual void process(Comm::Packet *packet); + + QListIterator > iterator() { return QListIterator >(m_dataList); } +}; + +#endif diff --git a/modules/memory/src/artisan/Interface.cpp b/modules/memory/src/artisan/Interface.cpp new file mode 100644 index 0000000..f1855f6 --- /dev/null +++ b/modules/memory/src/artisan/Interface.cpp @@ -0,0 +1,20 @@ +#include "Interface.h" +#include "Viewport.h" + +InstantiateArtisan(Interface) + +Interface::Interface() { + m_storage = new DataStore(); +} + +Interface::~Interface() { + +} + +Artisan::DataStore *Interface::dataStore() { + return m_storage; +} + +Artisan::Viewport *Interface::createViewport() { + return new Viewport(m_storage); +} diff --git a/modules/memory/src/artisan/Interface.h b/modules/memory/src/artisan/Interface.h new file mode 100644 index 0000000..b7d9386 --- /dev/null +++ b/modules/memory/src/artisan/Interface.h @@ -0,0 +1,18 @@ +#ifndef AesalonArtisan_cpuTime_Interface_H +#define AesalonArtisan_cpuTime_Interface_H + +#include "artisan/Interface.h" +#include "DataStore.h" + +class Interface : public Artisan::Interface { +private: + DataStore *m_storage; +public: + Interface(); + virtual ~Interface(); + + virtual Artisan::DataStore *dataStore(); + virtual Artisan::Viewport *createViewport(); +}; + +#endif diff --git a/modules/memory/src/artisan/Viewport.cpp b/modules/memory/src/artisan/Viewport.cpp new file mode 100644 index 0000000..4bd7e3a --- /dev/null +++ b/modules/memory/src/artisan/Viewport.cpp @@ -0,0 +1,40 @@ +#include + +#include "Viewport.h" +#include "util/MessageSystem.h" + +#include "artisan/gviewport/LineObject.h" + +Viewport::Viewport(DataStore *dataStore) : Artisan::GViewport::BasicViewport(dataStore), m_dataStore(dataStore) { + Message(Debug, "Creating cpuTime Viewport instance . . ."); + setViewport(Artisan::GViewport::Rect(1.0, 1.0)); + + Artisan::GViewport::Object *object = NULL; + + double lastTime = 0.0; + double lastData = 0.0; + + QListIterator > i = m_dataStore->iterator(); + while(i.hasNext()) { + QPair pair = i.next(); + + if(lastTime != 0.0 || lastData != 0.0) { + object = new Artisan::GViewport::LineObject( + Artisan::GViewport::Point(lastTime, lastData), + Artisan::GViewport::Point(pair.first, pair.second)); + + data()->addObject(object); + } + lastTime = pair.first; + lastData = pair.second; + } + + Artisan::GViewport::TreeType::Bound maxBound = data()->tree().bounds(); + + setViewport(Artisan::GViewport::Rect(maxBound.range(0).start(), maxBound.range(0).end(), maxBound.range(1).start(), + maxBound.range(1).end())); +} + +Viewport::~Viewport() { + +} diff --git a/modules/memory/src/artisan/Viewport.h b/modules/memory/src/artisan/Viewport.h new file mode 100644 index 0000000..2f97412 --- /dev/null +++ b/modules/memory/src/artisan/Viewport.h @@ -0,0 +1,17 @@ +#ifndef AesalonArtisan_cpuTime_Viewport_H +#define AesalonArtisan_cpuTime_Viewport_H + +#include "artisan/Viewport.h" +#include "artisan/gviewport/BasicViewport.h" +#include "DataStore.h" + +class Viewport : public Artisan::GViewport::BasicViewport { +private: + DataStore *m_dataStore; + double m_prevX, m_prevY; +public: + Viewport(DataStore *dataStore); + virtual ~Viewport(); +}; + +#endif diff --git a/modules/memory/src/collector/cpuTime.c b/modules/memory/src/collector/cpuTime.c new file mode 100644 index 0000000..fd2810b --- /dev/null +++ b/modules/memory/src/collector/cpuTime.c @@ -0,0 +1,69 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include + +#include "informer/Informer.h" + +void AC_EXPORT *calloc(size_t nmemb, size_t size); +void AC_EXPORT *malloc(size_t size); +void AC_EXPORT free(void *ptr); +void AC_EXPORT *realloc(void *ptr, size_t size); + +ModuleID AC_moduleID; +void *(*AC_callocFP)(size_t nmemb, size_t size); +void *(*AC_mallocFP)(size_t size); +void (*AC_freeFP)(void *ptr); + +void AC_EXPORT *calloc(size_t nmemb, size_t size) { + static int resolving = 0; + static char resolvingData[1024]; + static size_t usedData = 0; + printf("Intercepted calloc call, nmemb %li with size %li.\n", nmemb, size); + if(resolving == 1) { + printf("\tIn \"resolving\" mode, using local static buffer . . .\n"); + size_t original = usedData; + usedData += nmemb * size; + return resolvingData + original; + } + if(AC_callocFP == NULL) { + resolving = 1; + *(void **)&AC_callocFP = dlsym(RTLD_NEXT, "calloc"); + resolving = 0; + } + return AC_callocFP(nmemb, size); +} + +void AC_EXPORT *malloc(size_t size) { + printf("Intercepted malloc call for size %li.\n", size); + if(AC_mallocFP == NULL) { + *(void **)&AC_mallocFP = dlsym(RTLD_NEXT, "malloc"); + } + return AC_mallocFP(size); +} + +void AC_EXPORT free(void *ptr) { + printf("Intercepted free call.\n"); + if(AC_freeFP == NULL) { + *(void **)&AC_freeFP = dlsym(RTLD_NEXT, "free"); + } + AC_freeFP(ptr); +} + +void __attribute__((constructor)) AC_EXPORT AM_Construct() { + printf("Constructing memory module . . .\n"); + AI_Construct(); + + + + + AC_moduleID = AI_ConfigurationLong("memory:moduleID"); + + AI_ModuleLoaded("memory", AC_moduleID); +} + +void __attribute__((destructor)) AC_EXPORT AM_Destruct() { + +} diff --git a/modules/memory/src/marshal/Marshal.cpp b/modules/memory/src/marshal/Marshal.cpp new file mode 100644 index 0000000..e785b8b --- /dev/null +++ b/modules/memory/src/marshal/Marshal.cpp @@ -0,0 +1,19 @@ +#include "Marshal.h" +#include "util/MessageSystem.h" +#include "storage/Mempool.h" + +InstantiateMarshal(CpuTimeMarshal) + +CpuTimeMarshal::CpuTimeMarshal() { + +} + +CpuTimeMarshal::~CpuTimeMarshal() { + +} + +Comm::Packet *CpuTimeMarshal::marshal(Comm::Packet *packet) { + Message(Debug, "CpuTimeMarshal: marshalling packet . . ."); + + return packet; +} diff --git a/modules/memory/src/marshal/Marshal.h b/modules/memory/src/marshal/Marshal.h new file mode 100644 index 0000000..d431428 --- /dev/null +++ b/modules/memory/src/marshal/Marshal.h @@ -0,0 +1,14 @@ +#ifndef AesalonModule_cpuTime_Marshal_H +#define AesalonModule_cpuTime_Marshal_H + +#include "marshal/Interface.h" + +class CpuTimeMarshal : public Marshal::Interface { +public: + CpuTimeMarshal(); + virtual ~CpuTimeMarshal(); + + virtual Comm::Packet *marshal(Comm::Packet *packet); +}; + +#endif diff --git a/src/artisan/gviewport/LineObject.cpp b/src/artisan/gviewport/LineObject.cpp index b04e229..fcf9317 100644 --- a/src/artisan/gviewport/LineObject.cpp +++ b/src/artisan/gviewport/LineObject.cpp @@ -24,16 +24,12 @@ LineObject::~LineObject() { } void LineObject::renderOnto(RenderedImage &image) { - image.startPainting(); - CoordinateMapper mapper(image); image.painter().drawLine( mapper.dataToPixel(m_from).toQPoint(), mapper.dataToPixel(m_to).toQPoint() ); - - image.stopPainting(); } } // namespace GViewport diff --git a/src/artisan/gviewport/RectObject.cpp b/src/artisan/gviewport/RectObject.cpp new file mode 100644 index 0000000..48a738f --- /dev/null +++ b/src/artisan/gviewport/RectObject.cpp @@ -0,0 +1,32 @@ +/** Aesalon, a tool to visualize program behaviour in real time. + Copyright (C) 2009-2011, Aesalon development team. + + Aesalon is distributed under the terms of the GNU GPLv3. See + the included file LICENSE for more information. + + @file src/artisan/gviewport/RectObject.cpp +*/ + +#include "artisan/gviewport/RectObject.h" +#include "artisan/gviewport/CoordinateMapper.h" + + +namespace Artisan { +namespace GViewport { + +RectObject::RectObject(const Rect &rect) : Object(rect) { + +} + +RectObject::~RectObject() { + +} + +void RectObject::renderOnto(RenderedImage &image) { + CoordinateMapper mapper(image); + + image.painter().drawRect(mapper.dataToPixel(bound()).toQRect()); +} + +} // namespace GViewport +} // namespace Artisan \ No newline at end of file diff --git a/src/artisan/gviewport/RenderedImage.cpp b/src/artisan/gviewport/RenderedImage.cpp index 98f3219..fabb878 100644 --- a/src/artisan/gviewport/RenderedImage.cpp +++ b/src/artisan/gviewport/RenderedImage.cpp @@ -9,6 +9,7 @@ #include #include +#include #include "artisan/gviewport/RenderedImage.h" #include "artisan/gviewport/CoordinateMapper.h" @@ -23,7 +24,8 @@ RenderedImage::RenderedImage(const Rect &dataRange, const Rect &pixelSize) m_image = QImage(m_pixelSize.width(), m_pixelSize.height(), QImage::Format_ARGB32); - m_image.fill(qRgb(qrand()%256, qrand()%256, qrand()%256)); + //m_image.fill(qRgb(qrand()%256, qrand()%256, qrand()%256)); + m_image.fill(qRgb(255, 255, 255)); m_painter = new QPainter(); } @@ -43,11 +45,13 @@ void RenderedImage::merge(RenderedImage &other) { } void RenderedImage::startPainting() { + m_paintLock.lock(); m_painter->begin(&m_image); } void RenderedImage::stopPainting() { m_painter->end(); + m_paintLock.unlock(); } void RenderedImage::paintOnto(QPaintDevice *device) { diff --git a/src/artisan/gviewport/Renderer.cpp b/src/artisan/gviewport/Renderer.cpp index 543851a..a45d332 100644 --- a/src/artisan/gviewport/Renderer.cpp +++ b/src/artisan/gviewport/Renderer.cpp @@ -32,9 +32,11 @@ void Renderer::enqueue() { void Renderer::run() { m_data->startReading(); + m_image->startPainting(); m_data->tree().search(m_image->dataRange().toTreeBound(), this); + m_image->stopPainting(); m_data->stopReading(); emit finishedRendering(m_image); -- 2.11.4.GIT