// // Created by Cigerxwin Chaker on 05.11.19. // #include #include #include #include #include #include #include #include #include #include #include "SharedMemoryAccess.h" /* header is important for the shmID. name could be different. maybe not needed cause: (shmget(memory_access_key, NULL, 0)) */ #include "internal.h" 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; int initSemaphore() { /* 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; } int semaphoreOperation(int op) { semaphore.sem_op = static_cast(op); semaphore.sem_flg = SEM_UNDO; if (semop(semId, &semaphore, 1) == -1) { perror(" semop "); return -1; } return 1; } void writeSharedMemory(char *data, int size, int offset) { int shmId = shmget(impl.sharedMemoryKey, 0, 0); // dont init just get the ID if already existing. if (shmId >= 0) { std::cout << "writing" << std::endl; auto *shm_pointer = reinterpret_cast(shmat(shmId, nullptr, 0)); semaphoreOperation(LOCK); memcpy(shm_pointer + offset, data, size); shmdt(shm_pointer); //close shm_pointer semaphoreOperation(UNLOCK); std::cout << "writing successed" << std::endl; } } void getSharedMemory(char *address, int size, int offset) { int shmId = shmget(impl.sharedMemoryKey, 0, 0); if (shmId >= 0) { auto *shm_pointer = reinterpret_cast(shmat(shmId, nullptr, 0)); semaphoreOperation(LOCK); memcpy(address, shm_pointer + offset, size); shmdt(shm_pointer); //close shm_pointer semaphoreOperation(UNLOCK); } } char *getSharedMemory() { /* int shmId = shmget(impl.sharedMemoryKey, NULL, 0); if(shmId < 0) { return nullptr; // we could return -1, not sure if it will be useful to continue after there is no shm allocated for any reason } else { return (char *) shmat(shmId, NULL, 0); } */ //using a local buffer for shared memory testing if (localSharedMemory.empty()) { initSemaphore(); localSharedMemory.resize(impl.sharedMemorySize * 1024); } return &localSharedMemory[0]; } int getSharedMemorySize() { return impl.sharedMemorySize; } void lockSharedMemory() { semaphoreOperation(LOCK); } void unlockSharedMemory() { semaphoreOperation(UNLOCK); }