Successfully implemented a cpuTime marshaller.
[aesalon.git] / monitor / src / program / SharedMemory.cpp
bloba27638fdec3bd7f88c417aee85650932410106c6
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/SharedMemory.cpp
12 #include <iostream>
14 #include <sys/mman.h>
15 #include <fcntl.h>
16 #include <string.h>
17 #include <errno.h>
19 #include "program/SharedMemory.h"
20 #include "common/AssertionException.h"
21 #include "common/Config.h"
22 #include "common/StreamAsString.h"
23 #include "common/StringTo.h"
24 #include "config/Vault.h"
25 #include "Coordinator.h"
27 namespace Monitor {
28 namespace Program {
30 SharedMemory::SharedMemory() {
31 m_shmName = Common::StreamAsString() << "/Aesalon-" << getpid();
33 m_fd = shm_open(m_shmName.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
35 setupHeader();
36 setupConfiguration();
37 setupZones();
40 SharedMemory::~SharedMemory() {
41 shm_unlink(m_shmName.c_str());
44 uint32_t SharedMemory::zoneCount() const {
45 return m_header->zoneCount;
48 uint8_t *SharedMemory::zoneWithPacket() {
49 for(uint32_t i = 0; i < m_header->zonesAllocated; i ++) {
50 if(m_zoneUseData[i] & (0x01 << (i % 8))) {
51 uint8_t *zoneData = zone(i);
52 ZoneHeader_t *zoneHeader = reinterpret_cast<ZoneHeader_t *>(zoneData);
54 if(sem_trywait(&zoneHeader->packetSemaphore) == -1 && errno == EAGAIN) continue;
56 return zoneData;
59 return NULL;
62 void SharedMemory::waitForPacket() {
63 sem_wait(&m_header->packetSemaphore);
66 void SharedMemory::setupHeader() {
67 ftruncate(m_fd, AesalonPageSize);
68 m_header = static_cast<SharedMemoryHeader_t *>(
69 mmap(NULL, AesalonPageSize, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0));
71 sem_init(&m_header->packetSemaphore, 1, 0);
72 sem_init(&m_header->resizeSemaphore, 1, 1);
75 uint8_t *SharedMemory::zone(uint32_t id) {
76 uint8_t *data = m_zoneMap[id];
77 if(data != NULL) return data;
79 data = static_cast<uint8_t *>(mmap(NULL, AesalonPageSize*m_header->zoneSize,
80 PROT_READ | PROT_WRITE, MAP_SHARED, m_fd,
81 (m_header->zonePageOffset + id*m_header->zoneSize)*AesalonPageSize));
83 m_zoneMap[id] = data;
84 return data;
87 void SharedMemory::setupConfiguration() {
88 char *configurationData = static_cast<char *>(
89 mmap(NULL, AesalonPageSize, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, AesalonPageSize));
90 m_header->configDataSize = 1;
91 ftruncate(m_fd, 2*AesalonPageSize);
93 std::vector<Config::Vault::KeyPair> configItems;
94 Coordinator::instance()->vault()->match("*", configItems);
96 uint32_t offset = 0;
98 for(std::vector<Config::Vault::KeyPair>::iterator i = configItems.begin(); i != configItems.end(); ++i) {
99 /* Ignore all internal items. */
100 if(i->first.find("::") == 0) continue;
102 while((offset + i->first.length() + i->second.length() + 2) > m_header->configDataSize*AesalonPageSize) {
103 munmap(configurationData, m_header->configDataSize*AesalonPageSize);
104 m_header->configDataSize ++;
105 /* NOTE: the +1 is for the header. */
106 ftruncate(m_fd, (m_header->configDataSize+1)*AesalonPageSize);
107 configurationData = static_cast<char *>(
108 mmap(NULL, m_header->configDataSize*AesalonPageSize, PROT_READ | PROT_WRITE, MAP_SHARED,
109 m_fd, AesalonPageSize));
111 memcpy(&configurationData[offset], i->first.c_str(), i->first.length()+1);
112 offset += i->first.length()+1;
113 memcpy(&configurationData[offset], i->second.c_str(), i->second.length()+1);
114 offset += i->second.length()+1;
118 void SharedMemory::setupZones() {
119 m_header->zoneCount = 0;
121 m_header->zoneSize = Common::StringTo<uint32_t>(Coordinator::instance()->vault()->get("zoneSize"));
122 m_header->zoneUsagePages = Common::StringTo<uint32_t>(Coordinator::instance()->vault()->get("zoneUsePages"));
123 m_header->zonesAllocated = Common::StringTo<uint32_t>(Coordinator::instance()->vault()->get("defaultZones"));
125 m_header->shmSize = (1 + m_header->configDataSize + m_header->zoneUsagePages +
126 (m_header->zonesAllocated*m_header->zoneSize));
128 ftruncate(m_fd, m_header->shmSize*AesalonPageSize);
131 } // namespace Program
132 } // namespace Monitor