source: pacpusframework/trunk/src/PacpusTools/src/PosixShMem.cpp@ 3

Last change on this file since 3 was 3, checked in by sgosseli, 12 years ago
  • Add the existing Pacpus files from pacpusdev and pacpuscore.
  • Provide a clean build system based on multiple CMake files.
File size: 5.1 KB
Line 
1#include <cassert>
2#include <cstdlib> // exit
3#include <iomanip>
4
5#include "PacpusTools/PosixShMem.h"
6#include "kernel/Log.h"
7
8DECLARE_STATIC_LOGGER("pacpus.core.PosixShMem");
9
10using std::hex;
11
12//////////////////////////////////////////////////////////////////////////
13/// Constructor
14PosixShMem::PosixShMem(const char * name, int size)
15{
16 LOG_TRACE("constructor(" << name << ", " << size << ")");
17 LOG_INFO("creating shared memory" << "\t"
18 << "name=" << name << "\t"
19 << "size=" << size
20 );
21
22 {
23 QString memoryName = QString(name);
24 memory_ = new QSharedMemory(memoryName);
25 }
26 if (!memory_) {
27 LOG_FATAL("out of memory: cannot create shared memory object");
28 exit(-1);
29 }
30
31 bool result = false;
32 LOG_DEBUG("trying to create a memory segment");
33 if (!memory_->create(size)) {
34 if (QSharedMemory::AlreadyExists == memory_->error()) {
35 LOG_DEBUG("trying to attach to an existing memory segment");
36 if (!memory_->attach()) {
37 LOG_ERROR("cannot attach to an existing shared memory segment '" << name << "'"
38 << ". error code: " << memory_->error()
39 << ". error message:" << memory_->errorString().toStdString()
40 );
41 } else {
42 LOG_INFO("attached shared memory segment '" << name << "'");
43 int attachedMemorySize = memory_->size();
44 LOG_INFO("attached memory size = " << attachedMemorySize);
45 if (attachedMemorySize < size) {
46 LOG_ERROR("attached memory is smaller than requested, unexpected behaviour possible");
47 LOG_INFO("use system tools like 'ipcs' and 'ipcrm' to remove shared memory and re-run");
48 }
49 result = true;
50 }
51 } else {
52 LOG_ERROR("cannot create shared memory segment '" << name << "'"
53 << ". error code: " << memory_->error()
54 << ". error message:" << memory_->errorString().toStdString()
55 );
56 }
57 } else {
58 LOG_INFO("created shared memory segment '" << name << "'");
59 result = true;
60 }
61
62 /////////////////////////////////////////
63 if (result) {
64 // create the equivalent Windows event (autoreset mode?)
65 QString eventName = "EvtShMem_" + QString(name);
66 LOG_DEBUG("creating event '" << eventName << "'...");
67 event_ = new QSystemSemaphore(eventName, 0, QSystemSemaphore::Create);
68 if (event_) {
69 LOG_DEBUG("created event '" << eventName << "'");
70 } else {
71 LOG_ERROR("cannot create event '" << eventName << "'"
72 );
73 }
74
75 // get a pointer to the shared memory segment
76 shMem_ = memory_->data();
77 } else {
78 LOG_FATAL("cannot create shared memory segment '" << name << "'");
79 //throw MemoryCreationError();
80 exit(memory_->error());
81 }
82}
83
84//////////////////////////////////////////////////////////////////////////
85/// Destructor
86PosixShMem::~PosixShMem()
87{
88 LOG_TRACE("destructor");
89
90 // detach this process from the shared memory
91 memory_->detach();
92 // free shared memory
93 delete memory_;
94 // free event
95 delete event_;
96}
97
98//////////////////////////////////////////////////////////////////////////
99/// Use this method to get the data of the shared memory
100void * PosixShMem::read()
101{
102 return shMem_;
103}
104
105//////////////////////////////////////////////////////////////////////////
106/// Use this method to write data in shared memory. Offset is given in bytes
107void PosixShMem::write(void * data, int size, unsigned long offset)
108{
109 LOG_TRACE("writing " << size << " bytes to shared memory");
110
111 lockMemory();
112 uint32_t * dest = (uint32_t *) shMem_ + offset;
113
114 LOG_TRACE("adresses:"
115 << " shm = " << hex << shMem_
116 << " dst = " << hex << dest
117 << " src = " << hex << data
118 );
119
120 memcpy(dest, data, size);
121 unlockMemory();
122 event_->release();
123}
124
125//////////////////////////////////////////////////////////////////////////
126/// Function that locks access to the shared memory
127void PosixShMem::lockMemory()
128{
129 assert(memory_);
130 if (!memory_->lock()) {
131 LOG_ERROR("cannot lock memory '" << memory_->key().toStdString() << "'");
132 }
133}
134
135//////////////////////////////////////////////////////////////////////////
136/// Function that unlocks access to the shared memory
137void PosixShMem::unlockMemory()
138{
139 assert(memory_);
140 if (!memory_->unlock()) {
141 LOG_ERROR("cannot unlock memory '" << memory_->key().toStdString() << "'");
142 }
143}
144
145//////////////////////////////////////////////////////////////////////////
146/// Use this method to wait the incoming of new data
147/// you can specify a timeout in ms to avoid infinite blocking or 0 (infinite)
148/// return true if new data available before the timeout or else false
149bool PosixShMem::wait(unsigned long /*timeout*/)
150{
151 bool result = event_->acquire();
152 LOG_TRACE("event acquired: note that timeout doesn't work yet on linux platform");
153 return result;
154}
Note: See TracBrowser for help on using the repository browser.