diff --git a/Shared Memory/CMakeLists.txt b/Shared Memory/CMakeLists.txt new file mode 100644 index 0000000..815844a --- /dev/null +++ b/Shared Memory/CMakeLists.txt @@ -0,0 +1,21 @@ +# CMakeList.txt : CMake project for Shared Memory, include source and define +# project specific logic here. +# +cmake_minimum_required (VERSION 3.8) + +# Enable Hot Reload for MSVC compilers if supported. +if (POLICY CMP0141) + cmake_policy(SET CMP0141 NEW) + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$,$>,$<$:EditAndContinue>,$<$:ProgramDatabase>>") +endif() + +project("Shared Memory" VERSION 1.0.0 LANGUAGES C CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +add_executable(reader "reader.c" "shm_demo.c") +add_executable(writer "writer.c" "shm_demo.c") + +# TODO: Add tests and install targets if needed. diff --git a/Shared Memory/reader.c b/Shared Memory/reader.c new file mode 100644 index 0000000..379cb2e --- /dev/null +++ b/Shared Memory/reader.c @@ -0,0 +1,26 @@ +#include +#include + +extern int +read_from_shared_memory(char* mmap_key, + char* buffer, + unsigned int buff_size, + unsigned int bytes_to_read); + +int +main(int argc, char* argv[]) { + + char* key = "/introduction"; + char read_buffer[128]; + memset(read_buffer, 0, 128); + + int rc = read_from_shared_memory(key, read_buffer, 128, 128); + if (rc < 0) { + printf("Error reading from shared memory\n"); + return -1; + } + + printf("Data read = %s\n", (char*)read_buffer); + + return 0; +} \ No newline at end of file diff --git a/Shared Memory/shm_demo.c b/Shared Memory/shm_demo.c new file mode 100644 index 0000000..6ab4bb2 --- /dev/null +++ b/Shared Memory/shm_demo.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int +create_and_write_shared_memory(char* mmap_key, char* value, unsigned int size) { + + int shm_fd; + + /* + Create a shared memory object in kernel space. If shared memory + already exists it will truncate it to zero bytes again. + */ + + shm_fd = shm_open(mmap_key, O_CREAT | O_RDWR | O_TRUNC, 0660); + + if (shm_fd < 0) { + printf("Failure on shm_open on shm_fd, errcode = %d\n", errno); + return -1; + } + + if (ftruncate(shm_fd, size) == -1) { + printf("Error on ftruncate to allocate size of shared memory region\n"); + return -1; + } + + /*Now map the shared memory in kernel space into process's Virtual address space.*/ + void* shm_reg = mmap(NULL, // let the kernel chose to return the base address of shm memory + size, // size of the shared memory to map to virtual address of + PROT_READ | PROT_WRITE,// shared memory is Read and Writable + MAP_SHARED, // shared memory is accessible by different processes + shm_fd, // file descriptor of the shared memory + 0); // offset from the base address of the physical/shared memory to be mapped + + + /* + shm_reg is the address in process's Virtual address space, just like any other address. + The Linux paging mechanism maps this address to starting address of the shared memory region + in kernel space. Any operation performed by process on shm_reg address is actually the operation + performed in shared memory which resides in kernel. + */ + + memset(shm_reg, 0, size); + memcpy(shm_reg, value, size); + munmap(shm_reg, size); + + /* + Reader Process will not able to read shm if writer unlink + the name below. + */ + + //shm_unlink(mmap_key); + close(shm_fd); + return size; + +} + +int +read_from_shared_memory(char* mmap_key, + char* buffer, + unsigned int buff_size, + unsigned int bytes_to_read) { + + int shm_fd = 0, rc = 0; + + shm_fd = shm_open(mmap_key, O_CREAT | O_RDONLY, 0660); + + if (shm_fd < 0) { + + printf("Failure on shm_open on shm_fd, error code = %d\n", errno); + return -1; + + } + + void* shm_reg = mmap(NULL, bytes_to_read, PROT_READ, MAP_SHARED, shm_fd, 0); + + if (shm_reg == MAP_FAILED) { + printf("Error on mapping\n"); + return -1; + } + + memcpy(buffer, shm_reg, bytes_to_read); + rc = munmap(shm_reg, bytes_to_read); + + if (rc < 0) { + printf("munmap failed\n"); + return -1; + } + + close(shm_fd); + return bytes_to_read; /* Return the number of bytes read */ +} \ No newline at end of file diff --git a/Shared Memory/writer.c b/Shared Memory/writer.c new file mode 100644 index 0000000..5e26c81 --- /dev/null +++ b/Shared Memory/writer.c @@ -0,0 +1,16 @@ +#include +#include + +extern int +create_and_write_shared_memory(char* mmap_key, + char* value, + unsigned int size); + +int +main(int argc, char* argv[]) { + + char* key = "/introduction"; + char* intro = "Hello, I'm Hizenberg."; + create_and_write_shared_memory(key, intro, strlen(intro)); + return 0; +} \ No newline at end of file