source: flair-src/trunk/lib/FlairCore/src/SharedMem_impl.cpp@ 187

Last change on this file since 187 was 152, checked in by Bayard Gildas, 7 years ago

clean

File size: 6.6 KB
RevLine 
[2]1// %flair:license{
[15]2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
[2]4// %flair:license}
5// created: 2014/02/10
6// filename: SharedMem_impl.cpp
7//
8// author: Guillaume Sanahuja
9// Copyright Heudiasyc UMR UTC/CNRS 7253
10//
11// version: $Id: $
12//
13// purpose: Class defining a shared memory
14//
15//
16/*********************************************************************/
17
18#include "SharedMem_impl.h"
19#include "SharedMem.h"
20#include <fcntl.h>
21#include <unistd.h>
22#include <sys/mman.h>
23#include <string.h>
24
25using std::string;
26using namespace flair::core;
27
[15]28SharedMem_impl::SharedMem_impl(const SharedMem *self, string name,
[149]29 size_t size, SharedMem::Type &type):type(type) {
[15]30 this->size = size;
31 this->self = self;
[133]32 char errorMsg[256];
[2]33
34#ifdef __XENO__
[15]35 heap_binded = false;
36 int status = rt_heap_create(&heap, name.c_str(), size,
37 H_SHARED | H_FIFO | H_NONCACHED);
38 if (status == -EEXIST) {
39 heap_binded = true;
40 status = rt_heap_bind(&heap, name.c_str(), TM_INFINITE);
41 }
42 if (status != 0) {
[133]43 self->Err("rt_heap_create error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
[15]44 return;
45 }
[2]46
[15]47 void *ptr;
48 status = rt_heap_alloc(&heap, 0, TM_NONBLOCK, &ptr);
49 if (status != 0) {
[133]50 self->Err("rt_heap_alloc error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
[15]51 }
52 mem_segment = (char *)ptr;
[2]53
[15]54 mutex_binded = false;
55 string mutex_name = "mutex_" + name;
56 status = rt_mutex_create(&mutex, mutex_name.c_str());
57 if (status == -EEXIST) {
58 mutex_binded = true;
59 status = rt_mutex_bind(&mutex, mutex_name.c_str(), TM_INFINITE);
60 }
61 if (status != 0) {
[133]62 self->Err("rt_mutex_create error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
[15]63 return;
64 }
[2]65
66#else
[15]67 shm_name = "/" + name;
68 fd = shm_open(shm_name.c_str(), O_RDWR | O_CREAT, 0666);
69 if (fd == -1) {
70 self->Err("Error creating shared memory\n");
71 }
72 ftruncate(fd, size);
[2]73
[149]74 if (type==SharedMem::Type::mutex) {
75 sem_name="/" + name + "_mutex";
76 sem=sem_open(sem_name.c_str(), O_CREAT, 0666, 1);
77 if (sem==SEM_FAILED) {
78 self->Err("Error creating mutex semaphore\n");
79 }
80 } else if (type==SharedMem::Type::producerConsumer) {
81 sem_name_producer="/" + name + "_producer";
82 sem_producer=sem_open(sem_name_producer.c_str(), O_CREAT, 0666, 0);
83 if (sem==SEM_FAILED) {
84 self->Err("Error creating producer semaphore\n");
85 }
86 sem_name_consumer="/" + name + "_consumer";
87 sem_consumer=sem_open(sem_name_consumer.c_str(), O_CREAT, 0666, 0);
88 if (sem==SEM_FAILED) {
89 self->Err("Error creating consumer semaphore\n");
90 }
[15]91 }
[2]92
[15]93 mem_segment =
94 (char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
95 if (mem_segment == MAP_FAILED) {
96 self->Err("Failed to map memory\n");
97 }
[2]98#endif
99}
100
[15]101SharedMem_impl::~SharedMem_impl() {
102 int status;
[133]103 char errorMsg[256];
104
[2]105#ifdef __XENO__
[15]106 /* unnecessary because heap is opened in H_SINGLE mode
107 status=rt_heap_free(&heap,mem_segment);
108 if(status!=0)
109 {
[133]110 self->Err("rt_heap_free error (%s)\n",strerror_r(-status, errorMsg, sizeof(errorMsg)));
[15]111 }
112 */
[2]113
[15]114 if (heap_binded == false) {
115 status = rt_heap_delete(&heap);
116 if (status != 0) {
[133]117 self->Err("rt_heap_delete error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
[2]118 }
[15]119 }
[2]120
[15]121 if (mutex_binded == false) {
122 status = rt_mutex_delete(&mutex);
123 if (status != 0) {
[133]124 self->Err("error destroying mutex (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
[2]125 }
[15]126 }
[2]127#else
[15]128 status = munmap(mem_segment, size);
129 if (status != 0) {
[133]130 self->Err("Failed to unmap memory (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
[15]131 }
[2]132
[15]133 status = close(fd);
134 if (status != 0) {
[133]135 self->Err("Failed to close file (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
[15]136 }
[2]137
[149]138 // do not check errors as it can be done by another process
[15]139 status = shm_unlink(shm_name.c_str()); /*
140 if(status!=0)
141 {
[133]142 self->Err("Failed to unlink memory (%s)\n",strerror_r(-status, errorMsg, sizeof(errorMsg)));
[15]143 }
[2]144*/
[149]145 // do not check errors as it can be done by another process
146 if (type==SharedMem::Type::mutex) {
147 status = sem_unlink(sem_name.c_str());
148 status = sem_close(sem);
149 if (status != 0) {
150 self->Err("Failed to close mutex semaphore (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
151 }
152 } else if (type==SharedMem::Type::producerConsumer) {
153 status = sem_unlink(sem_name_producer.c_str());
154 status = sem_close(sem_producer);
155 if (status != 0) {
156 self->Err("Failed to close producer semaphore (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
157 }
158 status = sem_unlink(sem_name_consumer.c_str());
159 status = sem_close(sem_consumer);
160 if (status != 0) {
161 self->Err("Failed to close consumer semaphore (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
162 }
[15]163 }
[2]164#endif
165}
166
[149]167void SharedMem_impl::ReaderReady() {
168#ifdef __XENO__
169//TODO
170#else
171 sem_post(sem_consumer);
172#endif
173}
174
[15]175void SharedMem_impl::Write(const char *buf, size_t size) {
[2]176#ifdef __XENO__
[15]177 int status = rt_mutex_acquire(&mutex, TM_INFINITE);
[133]178 if (status != 0) {
179 char errorMsg[256];
180 self->Err("error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
181 }
[15]182 memcpy(mem_segment, buf, size);
183 status = rt_mutex_release(&mutex);
[133]184 if (status != 0) {
185 char errorMsg[256];
186 self->Err("error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
187 }
[2]188#else
[149]189 if (type==SharedMem::Type::mutex) {
190 sem_wait(sem);
191 memcpy(mem_segment, buf, size);
192 sem_post(sem);
193 } else if (type==SharedMem::Type::producerConsumer) {
194 //wait until consumer took the data away before writting a new one
195 //but should not block if nobody's there to read
196 if (sem_trywait(sem_consumer)==0) {
197 memcpy(mem_segment, buf, size);
198 sem_post(sem_producer);
199 }
200 }
[2]201#endif
202}
203
[15]204void SharedMem_impl::Read(char *buf, size_t size) {
[2]205#ifdef __XENO__
[15]206 int status = rt_mutex_acquire(&mutex, TM_INFINITE);
[133]207 if (status != 0) {
208 char errorMsg[256];
209 self->Err("error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
210 }
[15]211 memcpy(buf, mem_segment, size);
212 status = rt_mutex_release(&mutex);
[133]213 if (status != 0) {
214 char errorMsg[256];
215 self->Err("error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
216 }
[2]217#else
[149]218 if (type==SharedMem::Type::mutex) {
219 sem_wait(sem);
220 memcpy(buf, mem_segment, size);
221 sem_post(sem);
222 } else if (type==SharedMem::Type::producerConsumer) {
223 sem_wait(sem_producer); //wait until some data is available
224 memcpy(buf, mem_segment, size);
225 sem_post(sem_consumer);
226 }
[2]227#endif
228}
Note: See TracBrowser for help on using the repository browser.