#include #include #include #include #include #include #include #include "SharedMemoryAccess.hpp" #include "internal.hpp" #include "log.hpp" namespace vkvm { constexpr int PERMISSION = 0666; constexpr int LOCK = -1; constexpr int UNLOCK = 1; constexpr int SEM_KEY = 123458L; 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 | PERMISSION); 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 "); log(LogLevel::CRITICAL, "could not operate on semaphore, exiting"); 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 * { if(impl.sharedMemory != nullptr){ return impl.sharedMemory; } 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(reinterpret_cast(ptr) == static_cast(-1)){ log(LogLevel::WARNING, strerror(errno)); }else{ impl.sharedMemory = ptr; return ptr; } return getLocalMemory(); } 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); } }