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
15 #include "program/ZoneReader.h"
16 #include "Coordinator.h"
17 #include "common/Config.h"
18 #include "common/StringTo.h"
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();
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
);
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
);
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
;
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. */
111 } // namespace Program
112 } // namespace Monitor