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

Last change on this file since 76 was 76, checked in by Marek Kurdej, 11 years ago

Added: automated license updating lines:
%pacpus:license{
%pacpus:license}

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