Successfully implemented a cpuTime marshaller.
[aesalon.git] / monitor / src / program / ZoneReader.cpp
blob0bc9e7f54ca28fe16efdf85c8251083fc5f59c0a
1 /**
2 Aesalon, a tool to visualize a program's behaviour at run-time.
3 Copyright (C) 2010, Aesalon Development Team.
5 Aesalon is distributed under the terms of the GNU GPLv3. For more
6 licensing information, see the file LICENSE included with the distribution.
8 @file monitor/src/program/ZoneReader.cpp
12 #include <stdlib.h>
13 #include <string.h>
15 #include "program/ZoneReader.h"
16 #include "Coordinator.h"
17 #include "common/Config.h"
18 #include "common/StringTo.h"
19 #include "common/SHMPacket.h"
21 namespace Monitor {
22 namespace Program {
24 ZoneReader::ZoneReader(SharedMemory *sharedMemory, Module::List *moduleList, VCommunication::DataSink *dataSink)
25 : m_sharedMemory(sharedMemory), m_moduleList(moduleList), m_dataSink(dataSink) {
28 ZoneReader::~ZoneReader() {
32 void ZoneReader::start() {
33 pthread_create(&m_threadID, NULL, run, this);
36 void ZoneReader::startInThread() {
37 m_threadID = pthread_self();
38 run(this);
41 void ZoneReader::join() {
42 pthread_join(m_threadID, NULL);
45 void *ZoneReader::run(void *voidInstance) {
46 uint32_t zoneSize = Common::StringTo<uint32_t>(Coordinator::instance()->vault()->get("zoneSize"))*AesalonPageSize;
47 uint8_t *packetBuffer = NULL;
48 uint32_t packetBufferSize = 0;
50 ZoneReader *instance = static_cast<ZoneReader *>(voidInstance);
51 while(true) {
52 instance->m_sharedMemory->waitForPacket();
54 uint8_t *zoneData = instance->m_sharedMemory->zoneWithPacket();
55 if(zoneData == NULL) continue;
57 ZoneHeader_t *zoneHeader = reinterpret_cast<ZoneHeader_t *>(zoneData);
58 SHMPacketHeader_t *packetHeader = NULL;
60 uint32_t dataStart = 0;
62 if(zoneHeader->head + sizeof(packetHeader) < zoneSize) {
63 packetHeader = reinterpret_cast<SHMPacketHeader_t *>(zoneData + zoneHeader->head);
64 dataStart = zoneHeader->head + sizeof(packetHeader);
66 else {
67 packetHeader = reinterpret_cast<SHMPacketHeader_t *>(zoneData + ZoneDataOffset);
68 dataStart = ZoneDataOffset + sizeof(packetHeader);
71 uint32_t packetSize = packetHeader->packetSize;
72 uint8_t *packetData = NULL;
73 if(dataStart + packetHeader->packetSize < zoneSize) {
74 /* This is straightforwards, all the data is nice and contiguous. */
75 packetData = zoneData + dataStart + sizeof(SHMPacketHeader_t);
77 zoneHeader->head = dataStart + packetSize;
79 else {
80 /* This is a bit more complex; the data is in two parts,
81 thus it needs to be copied into a temporary buffer. */
83 uint32_t underSize = zoneSize - dataStart - zoneHeader->gapSize;
84 uint32_t overSize = packetSize - underSize;
86 if(packetBufferSize < packetSize) {
87 /* Replace this w/doubling behaviour? */
88 packetBuffer = static_cast<uint8_t *>(realloc(packetBuffer, packetSize));
89 packetBufferSize = packetSize;
91 memcpy(packetBuffer, zoneData + dataStart, underSize);
92 memcpy(packetBuffer + underSize, zoneData + ZoneDataOffset, overSize);
94 packetData = packetBuffer;
96 zoneHeader->head = ZoneDataOffset + overSize;
99 std::cout << "Received packet:" << std::endl;
100 std::cout << "\tsize: " << packetSize << std::endl;
101 std::cout << "\tmoduleID: " << packetHeader->moduleID << std::endl;
102 std::cout << "\tPID: " << zoneHeader->processID << std::endl;
103 std::cout << "\tTID: " << zoneHeader->threadID << std::endl;
105 Module::Module *module = instance->m_moduleList->module(packetHeader->moduleID);
106 if(module == NULL) {
107 std::cout << "Unknown packet received from module ID#" << packetHeader->moduleID << std::endl;
108 continue;
110 Common::MarshallerInterface *interface = module->marshallerInterface();
111 if(interface != NULL) {
112 Common::VPacket packet(
113 zoneHeader->processID,
114 zoneHeader->threadID,
115 packetHeader->moduleID,
116 packetData,
117 packetSize);
119 interface->marhsall(instance->m_dataSink, &packet);
122 free(packetBuffer);
123 return NULL;
126 } // namespace Program
127 } // namespace Monitor