// %flair:license{ // This file is part of the Flair framework distributed under the // CECILL-C License, Version 1.0. // %flair:license} // created: 2014/02/10 // filename: SharedMem_impl.cpp // // author: Guillaume Sanahuja // Copyright Heudiasyc UMR UTC/CNRS 7253 // // version: $Id: $ // // purpose: Class defining a shared memory // // /*********************************************************************/ #include "SharedMem_impl.h" #include "SharedMem.h" #include #include #include #include using std::string; using namespace flair::core; SharedMem_impl::SharedMem_impl(const SharedMem* self,string name,size_t size) { this->size=size; this->self=self; #ifdef __XENO__ heap_binded=false; int status=rt_heap_create(&heap,name.c_str(),size,H_SHARED|H_FIFO|H_NONCACHED); if(status==-EEXIST) { heap_binded=true; status=rt_heap_bind(&heap,name.c_str(),TM_INFINITE); } if(status!=0) { self->Err("rt_heap_create error (%s)\n",strerror(-status)); return; } void *ptr; status=rt_heap_alloc(&heap,0,TM_NONBLOCK ,&ptr); if(status!=0) { self->Err("rt_heap_alloc error (%s)\n",strerror(-status)); } mem_segment =(char*)ptr; mutex_binded=false; string mutex_name="mutex_"+ name; status=rt_mutex_create(&mutex,mutex_name.c_str()); if(status==-EEXIST) { mutex_binded=true; status=rt_mutex_bind(&mutex,mutex_name.c_str(),TM_INFINITE); } if(status!=0) { self->Err("rt_mutex_create error (%s)\n",strerror(-status)); return; } #else shm_name="/" + name; fd = shm_open(shm_name.c_str(), O_RDWR | O_CREAT, 0666); if (fd == -1) { self->Err("Error creating shared memory\n"); } ftruncate(fd, size); sem_name="/" +name; sem = sem_open(sem_name.c_str(), O_CREAT, 0666, 1); if (sem == SEM_FAILED) { self->Err("Error creating semaphore\n"); } mem_segment =(char*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mem_segment == MAP_FAILED) { self->Err("Failed to map memory\n"); } #endif } SharedMem_impl::~SharedMem_impl() { int status; #ifdef __XENO__ /* unnecessary because heap is opened in H_SINGLE mode status=rt_heap_free(&heap,mem_segment); if(status!=0) { self->Err("rt_heap_free error (%s)\n",strerror(-status)); } */ if(heap_binded==false) { status=rt_heap_delete(&heap); if(status!=0) { self->Err("rt_heap_delete error (%s)\n",strerror(-status)); } } if(mutex_binded==false) { status=rt_mutex_delete(&mutex); if(status!=0) { self->Err("error destroying mutex (%s)\n",strerror(-status)); } } #else status = munmap(mem_segment, size); if(status!=0) { self->Err("Failed to unmap memory (%s)\n",strerror(-status)); } status = close(fd); if(status!=0) { self->Err("Failed to close file (%s)\n",strerror(-status)); } //do not check erros as it can be done by another process status = shm_unlink(shm_name.c_str());/* if(status!=0) { self->Err("Failed to unlink memory (%s)\n",strerror(-status)); } */ //do not check erros as it can be done by another process status = sem_unlink(sem_name.c_str());/* if(status!=0) { self->Err("Failed to unlink semaphore (%s)\n",strerror(-status)); }*/ status = sem_close(sem); if(status!=0) { self->Err("Failed to close semaphore (%s)\n",strerror(-status)); } #endif } void SharedMem_impl::Write(const char* buf,size_t size) { #ifdef __XENO__ int status=rt_mutex_acquire(&mutex,TM_INFINITE); if(status!=0) self->Err("error (%s)\n",strerror(-status)); memcpy(mem_segment,buf,size); status=rt_mutex_release(&mutex); if(status!=0) self->Err("error (%s)\n",strerror(-status)); #else sem_wait(sem); memcpy(mem_segment,buf,size); sem_post(sem); #endif } void SharedMem_impl::Read(char* buf,size_t size) { #ifdef __XENO__ int status=rt_mutex_acquire(&mutex,TM_INFINITE); if(status!=0) self->Err("error (%s)\n",strerror(-status)); memcpy(buf,mem_segment,size); status=rt_mutex_release(&mutex); if(status!=0) self->Err("error (%s)\n",strerror(-status)); #else sem_wait(sem); memcpy(buf,mem_segment,size); sem_post(sem); #endif }