Synchronizer.cpp
2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
* Synchronizer.cpp
*
* Created on: 15 gru 2018
* Author: mariuszo
*/
#include <sys/mman.h>
#include "Synchronizer.h"
#include "MemoryManager.h"
std::map<std::string, SynchronizerBase*> SynchronizerBase::synchronizersMap;
std::mutex SynchronizerBase::synchronizersMapLock;
SynchronizerBase::SynchronizerBase(const std::string& name) : m_name(name), m_slotsRingBufferSize(0), m_syncSlotsRingBuffer(NULL), m_synchronizerData(NULL) {
}
SynchronizerBase::~SynchronizerBase() {
}
void SynchronizerBase::create(){
synchronizersMapLock.lock();
try {
if (synchronizersMap.find(m_name)!=synchronizersMap.end()){
synchronizersMapLock.unlock();
throw std::logic_error("Process data memory\""+m_name+"\" already exists");
}
MemoryManager<access_type::access_slave> memoryManagerData(m_name);
memoryManagerData.attach();
m_slotsRingBufferSize = memoryManagerData.dataSlotsRingBufferSize();
m_synchronizerData=new synchronizerData;
m_synchronizerData->writeSlotID=0;
sem_init(&(m_synchronizerData->lock),0,0);
m_synchronizerData->consumersLock=PTHREAD_RWLOCK_INITIALIZER;
mlock(m_synchronizerData,sizeof(*m_synchronizerData));
m_syncSlotsRingBuffer=new syncSlot[m_slotsRingBufferSize];
mlock(m_syncSlotsRingBuffer,sizeof(m_slotsRingBufferSize*sizeof(*m_syncSlotsRingBuffer)));
for (size_t i = 0; i < m_slotsRingBufferSize; ++i) {
if (wrflock_init(&(m_syncSlotsRingBuffer[i].lock), WRFLOCK_FWAITYIELD, 0)!=0)
throw std::logic_error("WRF lock init error");
m_syncSlotsRingBuffer[i].dataSlotID=static_cast<off_t>(specialid_type::specialid_empty);
}
synchronizersMap[m_name]=this;
}
catch (...) {
synchronizersMapLock.unlock();
throw;
}
synchronizersMapLock.unlock();
}
void SynchronizerBase::attach(){
synchronizersMapLock.lock();
try {
if (synchronizersMap.find(m_name)==synchronizersMap.end()){
synchronizersMapLock.unlock();
throw std::logic_error("Synchronizer data \""+m_name+"\" does not exists");
}
MemoryManager<access_type::access_slave> ringbufferData(m_name);
ringbufferData.attach();
m_slotsRingBufferSize = ringbufferData.dataSlotsRingBufferSize();
m_synchronizerData=synchronizersMap[m_name]->m_synchronizerData;
m_syncSlotsRingBuffer=synchronizersMap[m_name]->m_syncSlotsRingBuffer;
}
catch (...) {
synchronizersMapLock.unlock();
throw;
}
synchronizersMapLock.unlock();
}
void SynchronizerBase::destroy(){
synchronizersMapLock.lock();
if (m_syncSlotsRingBuffer){
for (size_t i=0;i<m_slotsRingBufferSize;i++){
wrflock_destroy(&(m_syncSlotsRingBuffer[i].lock));
}
munlock(m_syncSlotsRingBuffer,m_slotsRingBufferSize*sizeof(*m_syncSlotsRingBuffer));
delete [] m_syncSlotsRingBuffer;
}
if (m_synchronizerData){
sem_destroy(&(m_synchronizerData->lock));
munlock(m_synchronizerData,sizeof(*m_synchronizerData));
delete m_synchronizerData;
}
assert (synchronizersMap.find(m_name)!=synchronizersMap.end());
synchronizersMap.erase(m_name);
synchronizersMapLock.unlock();
}