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
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"
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
);
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;
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
));
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
);
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