10 #include <boost/filesystem.hpp>
11 #include <boost/function.hpp>
12 #include <boost/interprocess/allocators/allocator.hpp>
13 #include <boost/interprocess/containers/vector.hpp>
14 #include <boost/interprocess/managed_shared_memory.hpp>
15 #include <boost/interprocess/sync/interprocess_semaphore.hpp>
16 #include <boost/interprocess/sync/named_mutex.hpp>
17 #include <boost/move/unique_ptr.hpp>
18 #include <boost/unordered_set.hpp>
29 boost::interprocess::allocator<int32_t, boost::interprocess::managed_shared_memory::segment_manager>;
31 using PidSet = boost::interprocess::vector<int32_t, ShmemAllocator>;
57 void read(uint64_t bar, uint64_t address, int32_t* data,
size_t sizeInBytes)
override;
58 void write(uint64_t bar, uint64_t address, int32_t
const* data,
size_t sizeInBytes)
override;
63 std::string address, std::map<std::string, std::string> parameters);
73 std::map<uint64_t, SharedMemoryVector*> _barContents;
76 std::map<uint64_t, size_t> _barSizesInBytes;
79 const char* SHARED_MEMORY_BAR_PREFIX =
"BAR_";
81 class InterruptDispatcherInterface;
85 class SharedMemoryManager {
90 ~SharedMemoryManager();
102 std::pair<size_t, size_t> getInfoOnMemory();
108 static const size_t SHARED_MEMORY_CONST_OVERHEAD = 1000;
109 static const size_t SHARED_MEMORY_OVERHEAD_PER_VECTOR = 160;
111 const char* SHARED_MEMORY_PID_SET_NAME =
"PidSet";
112 const char* SHARED_MEMORY_REQUIRED_VERSION_NAME =
"RequiredVersion";
117 std::string userHash;
118 std::string mapFileHash;
119 std::string instanceIdHash;
125 boost::interprocess::managed_shared_memory segment;
135 unsigned* requiredVersion{
nullptr};
137 size_t getRequiredMemoryWithOverhead();
145 bool checkPidSetConsistency();
148 std::vector<std::string> listNamedElements();
152 boost::interprocess::named_mutex interprocessMutex;
154 boost::movelib::unique_ptr<InterruptDispatcherInterface> intDispatcherIf;
158 SharedMemoryManager sharedMemoryManager;
161 void setupBarContents();
164 size_t getTotalRegisterSizeInBytes()
const;
166 static void checkSizeIsMultipleOfWordSize(
size_t sizeInBytes);
168 static std::string convertPathRelativeToDmapToAbs(std::string
const& mapfileName);
179 using SemId = std::uint32_t;
183 SemEntry() =
default;
184 boost::interprocess::interprocess_semaphore s{0};
192 struct InterruptEntry {
193 int _controllerId{0};
195 std::uint32_t _counter = 0;
200 static const int maxInterruptEntries = 1000;
214 using Sem = boost::interprocess::interprocess_semaphore;
216 ShmForSems() =
default;
217 ShmForSems(
const ShmForSems&) =
delete;
220 Sem* addSem(SemId semId);
221 bool removeSem(SemId semId);
223 void cleanup(
PidSet* pidSet);
227 void addInterrupt(uint32_t interruptNumber);
232 std::list<Sem*> findSems(uint32_t interruptNumber = {},
bool update =
false);
238 InterruptEntry interruptEntries[maxInterruptEntries];
241 struct InterruptDispatcherThread;
243 class InterruptDispatcherInterface {
249 InterruptDispatcherInterface(
SharedDummyBackend& backend, boost::interprocess::managed_shared_memory& shm,
250 boost::interprocess::named_mutex& shmMutex);
253 ~InterruptDispatcherInterface();
257 static void cleanupShm(boost::interprocess::managed_shared_memory& shm);
258 static void cleanupShm(boost::interprocess::managed_shared_memory& shm,
PidSet* pidSet);
262 boost::interprocess::named_mutex& _shmMutex;
265 boost::movelib::unique_ptr<InterruptDispatcherThread> _dispatcherThread;
269 struct InterruptDispatcherThread {
271 explicit InterruptDispatcherThread(InterruptDispatcherInterface* dispatcherInterf);
272 InterruptDispatcherThread(
const InterruptDispatcherThread&) =
delete;
274 ~InterruptDispatcherThread();
277 void stop() noexcept;
279 void handleInterrupt(uint32_t interruptNumber);
283 InterruptDispatcherInterface* _dispatcherInterf;
286 ShmForSems::Sem* _sem =
nullptr;
288 std::atomic_bool _started{
false};
289 std::atomic_bool _stop{
false};