#include #include #include #include #include #include #include #include #include #include #include "SharedMemoryAccess.hpp" /* header is important for the shmID. name could be different. maybe not needed cause: (shmget(memory_access_key, NULL, 0)) */ #include "internal.hpp" #include "log.hpp" namespace vkvm { constexpr int PERM = 0666; /* access rights */ constexpr int LOCK = -1; constexpr int UNLOCK = 1; constexpr int SEM_KEY = 123458L; //int memoryAccessKey; /* var type is int. but could be another type. */ //TODO: look after type in sharedmemory group int semId; struct sembuf semaphore; std::vector localSharedMemory; auto initSemaphore() -> int { /* Testen, ob das Semaphor bereits existiert */ semId = semget(SEM_KEY, 0, IPC_PRIVATE); if (semId < 0) { /* ... existiert noch nicht, also anlegen */ /* Alle Zugriffsrechte der Dateikreierungsmaske */ /* erlauben */ umask(0); semId = semget(SEM_KEY, 1, IPC_CREAT | IPC_EXCL | PERM); if (semId < 0) { return -1; } /* Semaphor mit 1 initialisieren */ if (semctl(semId, 0, SETVAL, 1) == -1) { return -1; } } return 1; } auto semaphoreOperation(int op) -> int { semaphore.sem_op = static_cast(op); semaphore.sem_flg = SEM_UNDO; if (semop(semId, &semaphore, 1) == -1) { perror(" semop "); return -1; } return 1; } auto writeSharedMemory(char *data, int size, int offset) -> void { lockSharedMemory(); memcpy(getSharedMemory() + offset, data, size); unlockSharedMemory(); } char *getLocalMemory(){ static bool givenWarning {false}; if(!givenWarning && impl.localMemoryWarn){ givenWarning = true; log(LogLevel::WARNING, "no shared memory found, using local memory instead!"); } if (localSharedMemory.empty()) { constexpr int kilo = 1024; localSharedMemory.resize(impl.sharedMemorySize * kilo); } return &localSharedMemory[0]; } auto getSharedMemory() -> char * { int shmId = shmget(impl.sharedMemoryKey, 0, 0); if (shmId < 0) { //using a local buffer for shared memory testing return getLocalMemory(); } char *ptr = static_cast(shmat(shmId, nullptr, 0)); if((size_t)ptr == (size_t)-1){ return getLocalMemory(); }else{ return ptr; } } auto getSharedMemory(char *address, int size, int offset) -> void { lockSharedMemory(); memcpy(address, getSharedMemory() + offset, size); unlockSharedMemory(); } auto getSharedMemorySize() -> int { return impl.sharedMemorySize; } auto lockSharedMemory() -> void { semaphoreOperation(LOCK); } auto unlockSharedMemory() -> void { semaphoreOperation(UNLOCK); } }