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

Last change on this file since 214 was 213, checked in by Sanahuja Guillaume, 6 years ago

thread stack size rework
add Matrix class

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