2019-11-12 14:07:02 +01:00
# include <cstdio>
# include <cstdlib>
# include <cstring>
2019-11-06 11:05:11 +01:00
# include <iostream>
# include <sys/ipc.h>
2019-11-12 14:07:02 +01:00
# include <sys/sem.h>
2019-11-06 11:05:11 +01:00
# include <sys/shm.h>
# include <sys/stat.h>
2019-11-12 14:07:02 +01:00
# include <sys/types.h>
2019-11-06 11:05:11 +01:00
# include <unistd.h>
2019-11-06 11:54:26 +01:00
2019-11-13 13:37:49 +01:00
# 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"
2019-11-06 11:05:11 +01:00
2019-11-13 13:37:49 +01:00
namespace vkvm {
constexpr int PERM = 0666 ; /* access rights */
constexpr int LOCK = - 1 ;
constexpr int UNLOCK = 1 ;
constexpr int SEM_KEY = 123458L ;
2019-11-07 12:05:06 +01:00
//int memoryAccessKey; /* var type is int. but could be another type. */ //TODO: look after type in sharedmemory group
2019-11-13 13:37:49 +01:00
int semId ;
struct sembuf semaphore ;
2019-11-07 12:05:06 +01:00
2019-11-13 13:37:49 +01:00
std : : vector < char > localSharedMemory ;
2019-11-07 16:34:15 +01:00
2019-11-13 13:37:49 +01:00
auto initSemaphore ( ) - > int {
/* Testen, ob das Semaphor bereits existiert */
semId = semget ( SEM_KEY , 0 , IPC_PRIVATE ) ;
2019-11-06 11:05:11 +01:00
if ( semId < 0 ) {
2019-11-13 13:37:49 +01:00
/* ... 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 */
2019-11-13 15:42:04 +01:00
if ( semctl ( semId , 0 , SETVAL , 1 ) = = - 1 ) {
2019-11-13 13:37:49 +01:00
return - 1 ;
}
2019-11-06 11:05:11 +01:00
}
2019-11-13 13:37:49 +01:00
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 " ) ;
2019-11-06 11:05:11 +01:00
return - 1 ;
2019-11-12 14:07:02 +01:00
}
2019-11-13 13:37:49 +01:00
return 1 ;
2019-11-06 11:05:11 +01:00
}
2019-11-13 13:37:49 +01:00
auto writeSharedMemory ( char * data , int size , int offset ) - > void {
lockSharedMemory ( ) ;
memcpy ( getSharedMemory ( ) + offset , data , size ) ;
unlockSharedMemory ( ) ;
2019-11-06 11:05:11 +01:00
}
2019-11-21 13:03:53 +01:00
char * getLocalMemory ( ) {
if ( localSharedMemory . empty ( ) ) {
constexpr int kilo = 1024 ;
localSharedMemory . resize ( impl . sharedMemorySize ) ;
}
return & localSharedMemory [ 0 ] ;
}
2019-11-13 13:37:49 +01:00
auto getSharedMemory ( ) - > char * {
2019-11-13 15:42:04 +01:00
int shmId = shmget ( impl . sharedMemoryKey , 0 , 0 ) ;
if ( shmId < 0 ) {
2019-11-13 13:37:49 +01:00
//using a local buffer for shared memory testing
2019-11-21 13:03:53 +01:00
return getLocalMemory ( ) ;
}
char * ptr = static_cast < char * > ( shmat ( shmId , nullptr , 0 ) ) ;
if ( ( size_t ) ptr = = ( size_t ) - 1 ) {
return getLocalMemory ( ) ;
} else {
return ptr ;
2019-11-12 19:05:33 +01:00
}
}
2019-11-13 13:37:49 +01:00
auto getSharedMemory ( char * address , int size , int offset ) - > void {
lockSharedMemory ( ) ;
memcpy ( address , getSharedMemory ( ) + offset , size ) ;
unlockSharedMemory ( ) ;
2019-11-07 16:34:15 +01:00
}
2019-11-13 13:37:49 +01:00
auto getSharedMemorySize ( ) - > int {
return impl . sharedMemorySize ;
}
2019-11-07 16:34:15 +01:00
2019-11-13 13:37:49 +01:00
auto lockSharedMemory ( ) - > void {
semaphoreOperation ( LOCK ) ;
}
2019-11-07 16:34:15 +01:00
2019-11-13 13:37:49 +01:00
auto unlockSharedMemory ( ) - > void {
semaphoreOperation ( UNLOCK ) ;
}
2019-11-07 16:34:15 +01:00
2019-11-13 13:37:49 +01:00
}