10 #include <sys/types.h>
17 using namespace std::chrono_literals;
19 #define PERMISSION (0600)
22 assert(name.length() > 4);
23 if(name.at(0) !=
'/') {
27 m_semaphoreName = name;
37 if(m_shmAddress != -1) {
38 std::clog <<
"[SharedMemory::allocate] Already allocated.\n";
42 m_shmAddress = shm_open(m_shmName.c_str(), O_RDWR | O_CREAT | O_TRUNC,
PERMISSION);
43 if (m_shmAddress == -1) {
44 std::cerr <<
"[SharedMemory::allocate] Failed to allocate shared memory.\n";
48 std::clog <<
"[SharedMemory::allocate] Successfully allocated memory\n";
51 int status = ftruncate(m_shmAddress, sizeBytes);
53 std::cerr <<
"[SharedMemory::allocate] Failed to truncate shared memory. (Not enough space?)\n";
58 m_shmSize = sizeBytes;
63 m_sharedArea = mmap(NULL, m_shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, m_shmAddress, 0);
64 if(m_sharedArea == MAP_FAILED) {
65 std::cerr <<
"[SharedMemory::allocate] Failed to create semaphore. (Maybe already existing)\n";
72 m_semaphore = sem_open(m_semaphoreName.c_str(), O_CREAT | O_EXCL,
PERMISSION, 1);
73 if(m_semaphore == SEM_FAILED) {
74 std::cerr <<
"[SharedMemory::allocate] Failed to create semaphore. (Maybe already existing)\n";
84 this->write_mutexed(data);
91 if(m_sharedArea != MAP_FAILED && m_sharedArea !=
nullptr) {
92 if (munmap(m_sharedArea, m_shmSize) == -1) {
93 std::cerr <<
"[SharedMemory::deallocate] Failed to unmap shared area\n";
97 std::clog <<
"[SharedMemory::deallocate] Unmapped shared area successfully\n";
100 if(m_semaphore != SEM_FAILED && m_semaphore !=
nullptr) {
101 if(sem_unlink(m_semaphoreName.c_str()) != 0) {
102 std::cerr <<
"[SharedMemory::deallocate] FAILED to unlink semaphore\n";
106 std::clog <<
"[SharedMemory::deallocate] Semaphore unlinked successfully\n";
110 if(m_shmAddress != -1 && m_shmSize != -1 && shm_unlink(m_shmName.c_str()) != 0) {
111 std::cerr <<
"[SharedMemory::deallocate] FAILED to deallocate shared memory\n";
115 std::clog <<
"[SharedMemory::deallocate] Deallocated shared memory successfully\n";
127 if(m_sharedArea ==
nullptr || m_sharedArea == MAP_FAILED) {
128 std::cerr <<
"[SharedMemory::write_mutexed] Shared memory not initialized/allocated! \n";
133 if(size > m_shmSize) {
134 std::cerr <<
"[SharedMemory::write_mutexed] Data too large to write into mutex. (Data is shrinked!)\n";
137 else if(size != m_shmSize - 8 && size != 0) {
138 std::clog <<
"[SharedMemory::write_mutexed] INFO: Data not as large as shared memory.\n";
141 if(acquire_semaphore(
true) ==
false) {
142 std::cerr <<
"[SharedMemory::write_mutexed] Could NOT acquire_semaphore. Skip writing to shared mem.\n";
147 std::memcpy(m_sharedArea, &data.
tv_sec,
sizeof(data.
tv_sec));
149 std::memcpy(m_sharedArea +
sizeof(data.
tv_sec) +
sizeof(data.
tv_nsec), data.
data, size);
151 if(release_semaphore() ==
false) {
152 std::cerr <<
"[SharedMemory::write_mutexed] Semaphore NOT released.\n";
160 if(m_sharedArea ==
nullptr || m_sharedArea == MAP_FAILED) {
161 std::cerr <<
"[SharedMemory::is_new_data_available] Shared memory not initialized/allocated! \n";
165 if(acquire_semaphore(
true) ==
false) {
173 std::memcpy(&sec, m_sharedArea,
sizeof(sec));
174 std::memcpy(&nsec, m_sharedArea +
sizeof(sec),
sizeof(nsec));
176 if(release_semaphore() ==
false) {
177 std::cerr <<
"[SharedMemory::is_new_data_available] Semaphore NOT released.\n";
180 return (sec != m_lastDataSec || nsec != m_lastDataNSec);
184 if(m_sharedArea ==
nullptr || m_sharedArea == MAP_FAILED) {
185 std::cerr <<
"[SharedMemory::read_mutexed] Shared memory not initialized/allocated! \n";
189 if(acquire_semaphore(
false) ==
false) {
194 if(sizeToRead > m_shmSize - 2 *
sizeof(data.
tv_sec)) {
195 std::clog <<
"[SharedMemory::read_mutexed] Shared Memory not as large as desired size to read.\n";
196 sizeToRead = m_shmSize - 2 *
sizeof(data.
tv_sec);
200 std::memcpy(&data.
tv_sec, m_sharedArea,
sizeof(data.
tv_sec));
202 std::memcpy(data.
data, m_sharedArea +
sizeof(data.
tv_sec) +
sizeof(data.
tv_nsec), sizeToRead);
204 if(release_semaphore() ==
false) {
205 std::cerr <<
"[SharedMemory::read_mutexed] Semaphore NOT released.\n";
208 m_lastDataSec = data.
tv_sec;
216 if (timedWait && clock_gettime(CLOCK_REALTIME,&tms) == 0) {
217 tms.tv_nsec += 10000000;
218 if(sem_timedwait(m_semaphore, &tms) != 0) {
219 std::cerr <<
"[SharedMemory::acquire_semaphore] FAILED to get semaphore (timed).\n";
224 if(timedWait) std::clog <<
"[SharedMemory::acquire_semaphore] get clock not worked\n";
225 if(sem_wait(m_semaphore) != 0) {
226 std::cerr <<
"[SharedMemory::acquire_semaphore] FAILED to get semaphore.\n";
236 while(maxTries > 0 && sem_post(m_semaphore) != 0) {
237 std::cerr <<
"[SharedMemory::release_semaphore] FAILED to post semaphore! Retrying\n";
238 std::this_thread::sleep_for(10ms);
241 return (maxTries > 0);