source: flair-src/branches/sanscv/lib/FlairCore/src/SharedMem_impl.cpp @ 326

Last change on this file since 326 was 324, checked in by Sanahuja Guillaume, 2 years ago

removing opencv dependency

File size: 4.4 KB
Line 
1// %flair:license{
2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
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
28SharedMem_impl::SharedMem_impl(const SharedMem *self, string name, size_t size, SharedMem::Type &type):self(self),type(type),size(size) {
29#ifdef __XENO__
30  heap_binded = false;
31  int status = rt_heap_create(&heap, name.c_str(), size,
32                              H_SHARED | H_FIFO | H_NONCACHED);
33  if (status == -EEXIST) {
34    heap_binded = true;
35    status = rt_heap_bind(&heap, name.c_str(), TM_INFINITE);
36  }
37  if (status != 0) {
38    char errorMsg[256];
39    self->Err("rt_heap_create error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
40    return;
41  }
42
43  void *ptr;
44  status = rt_heap_alloc(&heap, 0, TM_NONBLOCK, &ptr);
45  if (status != 0) {
46    char errorMsg[256];
47    self->Err("rt_heap_alloc error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
48  }
49  mem_segment = (char *)ptr;
50
51#else
52  if (type==SharedMem::Type::mutex) {
53      sem = new Semaphore(self,1,"/" + name + "_mutex",Semaphore::Type::named);
54  } else { //producerConsumer
55      sem_producer=new Semaphore(self,0,"/" + name + "_producer", Semaphore::Type::named);
56      sem_consumer=new Semaphore(self,0,"/" + name + "_consumer", Semaphore::Type::named);
57  }
58  shm_name = "/" + name;
59  fd = shm_open(shm_name.c_str(), O_RDWR | O_CREAT, 0666);
60  if (fd == -1) {
61    self->Err("Error creating shared memory\n");
62  }
63  ftruncate(fd, size);
64
65  mem_segment = (char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
66  if (mem_segment == MAP_FAILED) {
67    self->Err("Failed to map memory\n");
68  }
69#endif
70}
71
72SharedMem_impl::~SharedMem_impl() {
73  int status;
74       
75#ifdef __XENO__
76
77  if (heap_binded == false) {
78    status = rt_heap_delete(&heap);
79    if (status != 0) {
80      char errorMsg[256];
81      self->Err("rt_heap_delete error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
82    }
83  }
84
85#else
86  status = munmap(mem_segment, size);
87  if (status != 0) {
88    char errorMsg[256];
89    self->Err("Failed to unmap memory (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
90  }
91
92  status = close(fd);
93  if (status != 0) {
94    char errorMsg[256];
95    self->Err("Failed to close file (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
96  }
97
98  // do not check errors as it can be done by another process
99  status = shm_unlink(shm_name.c_str()); /*
100   if(status!=0)
101   {
102      char errorMsg[256];
103       self->Err("Failed to unlink memory (%s)\n",strerror_r(-status, errorMsg, sizeof(errorMsg)));
104   }
105*/
106    if (type==SharedMem::Type::mutex) {
107      delete sem;
108    } else {
109      delete sem_producer;
110      delete sem_consumer;
111    }
112#endif
113}
114
115void SharedMem_impl::ReaderReady() {
116  if (type==SharedMem::Type::producerConsumer) {
117    sem_consumer->ReleaseSemaphore();
118  } else {
119    self->Warn("Called on a non producerConsumer type of shared memory! (this is seriously wrong)");
120  }
121}
122
123void SharedMem_impl::Write(const char *buf, size_t size) {
124  if (type==SharedMem::Type::mutex) {
125    sem->GetSemaphore();
126    memcpy(mem_segment, buf, size);
127    sem->ReleaseSemaphore();
128  } else if (type==SharedMem::Type::producerConsumer) {
129    //wait until consumer took the data away before writing a new one
130    //but should not block if nobody's there to read
131    if (sem_consumer->TryGetSemaphore()) {
132      memcpy(mem_segment, buf, size);
133      sem_producer->ReleaseSemaphore();
134    }
135  }
136}
137
138bool SharedMem_impl::Read(char *buf, size_t size, Time nsTimeout) {
139  if (type==SharedMem::Type::mutex) {
140    if (sem->GetSemaphore()) { //may block for ever
141      memcpy(buf, mem_segment, size);
142      sem->ReleaseSemaphore();
143      return true;
144    }
145  } else if (type==SharedMem::Type::producerConsumer) {
146    if (sem_producer->GetSemaphore(nsTimeout)) { //if nobody ever writes we need to exit this after a while
147      memcpy(buf, mem_segment, size);
148      sem_consumer->ReleaseSemaphore();
149      return true;
150    };
151  }
152  return false;
153}
Note: See TracBrowser for help on using the repository browser.