2019-11-06 11:05:11 +01:00
//
// Created by Cigerxwin Chaker on 05.11.19.
//
# include <iostream>
2019-11-06 11:54:26 +01:00
# include <sys/types.h>
2019-11-06 11:05:11 +01:00
# include <sys/ipc.h>
# include <sys/shm.h>
# include <stdio.h>
# include <stdlib.h>
# include <sys/stat.h>
# include <sys/sem.h>
# include <unistd.h>
2019-11-06 11:54:26 +01:00
# include <cstring>
2019-11-07 12:05:06 +01:00
# include "internal.h"
2019-11-06 11:54:26 +01:00
# include "SharedMemoryAccess.h" /* header is important for the shmID. name could be different. maybe not needed cause: (shmget(memory_access_key, NULL, 0)) */
2019-11-06 11:05:11 +01:00
2019-11-07 12:05:06 +01:00
# define PERM 0666 /* Zugriffsrechte */
# define LOCK -1
# define UNLOCK 1
# define 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 ;
2019-11-07 16:34:15 +01:00
std : : vector < char > localSharedMemory ;
int initSemaphore ( ) {
2019-11-06 11:05:11 +01:00
/* Testen, ob das Semaphor bereits existiert */
2019-11-06 11:54:26 +01:00
semId = semget ( SEM_KEY , 0 , IPC_PRIVATE ) ;
2019-11-06 11:05:11 +01:00
if ( semId < 0 ) {
/* ... existiert noch nicht, also anlegen */
/* Alle Zugriffsrechte der Dateikreierungsmaske */
/* erlauben */
umask ( 0 ) ;
2019-11-06 11:54:26 +01:00
semId = semget ( SEM_KEY , 1 , IPC_CREAT | IPC_EXCL | PERM ) ;
2019-11-06 11:05:11 +01:00
if ( semId < 0 ) {
return - 1 ;
}
/* Semaphor mit 1 initialisieren */
if ( semctl ( semId , 0 , SETVAL , ( int ) 1 ) = = - 1 )
return - 1 ;
}
return 1 ;
}
int semaphoreOperation ( int op ) {
2019-11-07 16:34:15 +01:00
semaphore . sem_op = ( short ) op ;
2019-11-06 11:05:11 +01:00
semaphore . sem_flg = SEM_UNDO ;
if ( semop ( semId , & semaphore , 1 ) = = - 1 ) {
perror ( " semop " ) ;
2019-11-07 16:34:15 +01:00
return - 1 ;
2019-11-06 11:05:11 +01:00
}
return 1 ;
}
2019-11-07 12:05:06 +01:00
void writeSharedMemory ( char * data , int size , int offset ) {
int shmId = shmget ( impl . sharedMemoryKey , NULL , 0 ) ; // dont init just get the ID if already existing.
2019-11-06 11:05:11 +01:00
if ( shmId < 0 ) {
2019-11-07 16:34:15 +01:00
return ;
2019-11-06 11:05:11 +01:00
/* we could return -1, not sure if it will be useful to continue after there is no shm allocated for any reason*/
} else {
2019-11-08 18:30:27 +01:00
std : : cout < < " writing " < < std : : endl ;
2019-11-06 11:05:11 +01:00
char * shm_pointer = ( char * ) shmat ( shmId , NULL , 0 ) ;
2019-11-06 11:54:26 +01:00
semaphoreOperation ( LOCK ) ;
2019-11-07 12:05:06 +01:00
memcpy ( shm_pointer + offset , data , size ) ;
2019-11-08 18:30:27 +01:00
shmdt ( shm_pointer ) ; //close shm_pointer
2019-11-06 11:54:26 +01:00
semaphoreOperation ( UNLOCK ) ;
2019-11-08 18:30:27 +01:00
std : : cout < < " writing successed " < < std : : endl ;
}
}
void getSharedMemory ( char * address , int size , int offset ) {
int shmId = shmget ( impl . sharedMemoryKey , NULL , 0 ) ;
if ( shmId < 0 ) {
return ;
} else {
char * shm_pointer = ( char * ) shmat ( shmId , NULL , 0 ) ;
semaphoreOperation ( LOCK ) ;
memcpy ( address , shm_pointer + offset , size ) ;
shmdt ( shm_pointer ) ; //close shm_pointer
semaphoreOperation ( UNLOCK ) ;
return ;
2019-11-06 11:05:11 +01:00
}
}
2019-11-07 16:34:15 +01:00
char * getSharedMemory ( ) {
/*
2019-11-07 12:05:06 +01:00
int shmId = shmget ( impl . sharedMemoryKey , NULL , 0 ) ;
2019-11-06 11:05:11 +01:00
if ( shmId < 0 ) {
2019-11-07 16:34:15 +01:00
return nullptr ;
// we could return -1, not sure if it will be useful to continue after there is no shm allocated for any reason
2019-11-06 11:05:11 +01:00
} else {
return ( char * ) shmat ( shmId , NULL , 0 ) ;
}
2019-11-07 16:34:15 +01:00
*/
//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 ) ;
}