source: pacpusframework/tags/0.1.1/src/PacpusTools/src/PosixShMem.cpp@ 218

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

Update: merged changes from trunk.

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