103 lines
3.0 KiB
C++
103 lines
3.0 KiB
C++
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <sys/ipc.h>
|
|
#include <sys/sem.h>
|
|
#include <sys/shm.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
#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"
|
|
|
|
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<char> 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<int16_t>(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(){
|
|
if (localSharedMemory.empty()) {
|
|
constexpr int kilo = 1024;
|
|
localSharedMemory.resize(impl.sharedMemorySize);
|
|
}
|
|
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<char *>(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);
|
|
}
|
|
|
|
} |