Began implementing the VCommunication namespace.
[aesalon.git] / monitor / src / program / ZoneReader.cpp
blobce0aa3f8b1ce5f746d2bb105715635c43107a55a
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"
20 namespace Monitor {
21 namespace Program {
23 ZoneReader::ZoneReader(SharedMemory *sharedMemory, Module::List *moduleList) :
24 m_sharedMemory(sharedMemory), m_moduleList(moduleList) {
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;
104 /* TODO: process packet. Data is in packetData, size of packet is packetSize, and header is packetHeader. */
105 /* Other associated information such as the PID and TID of the source are in zoneHeader. */
107 free(packetBuffer);
108 return NULL;
111 } // namespace Program
112 } // namespace Monitor