Resize POSIX shared memory. Working example

I have a shared dynamic array in a POSIX model between two different applications. I would like to be able to resize without copying. Unfortunately, I could not find the right solution to increase and decrease the total POSIX memory in C. I found many documents on the Internet with poor explanations and poor examples. I managed to find interesting topics, but all of them do not suit me:

I developed an example as I understand the documentation. Unfortunately, it does not work correctly. Please give me advice where I am wrong. And please be kind to give me a working example.

In the documentation, I found that I needed to use ftruncate () before mremap (), but I could not find the correct syntax to use them. In addition, mremap () works with offset pages of memory. How to increase the total memory in this case?

/* main.c */ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <sys/shm.h> #include <sys/stat.h> #include <sys/mman.h> #include <sys/types.h> #include <errno.h> int main(void) { size_t size_of_mem = 1024; int fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRWXO | S_IRUSR | S_IWUSR); if (fd == -1) { perror("Error in shm_open"); return EXIT_FAILURE; } if (ftruncate(fd, size_of_mem) == -1) { perror("Error in ftruncate"); return EXIT_FAILURE; } void *shm_address = mmap(0, size_of_mem, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, 0); if (shm_address == MAP_FAILED) { perror("Error mmapping the file"); return EXIT_FAILURE; } /* Increase shard memory */ for (size_t i=0; i<1024; ++i){ /* Does 8 align memory page? */ size_t new_size_of_mem = 1024+(8*i); if (ftruncate(fd, new_size_of_mem) == -1) { perror("Error in ftruncate"); return EXIT_FAILURE; } /* mremap() works with aligned memory pages. How to properly increase shared memory in this case? */ void *temp = mremap(shm_address, size_of_mem, new_size_of_mem, MREMAP_MAYMOVE); if(temp == (void*)-1) { perror("Error on mremap()"); return EXIT_FAILURE; } size_of_mem = new_size_of_mem; } return 0; } 

Addition:

 $ gcc -g -O0 -ggdb -pipe -Wall -Wextra -Wpedantic -Wshadow -march=native -std=c11 -o ./main ./main.c -lrt 

Run:

 $ ./main Error on mremap(): Bad address 
+5
source share
1 answer

You are losing the address of the new allocated / reassigned memory assigned to temp .

This means that after the second cycle of the for loop, you move the already moved memory.

After checking the return value of mremap, you can rewrite the new address with the shm_address pointer.

 void *temp = mremap(shm_address, size_of_mem, new_size_of_mem, MREMAP_MAYMOVE); if(temp == (void*)-1) { perror("Error on mremap()"); return EXIT_FAILURE; } shm_address = temp; 
+2
source

Source: https://habr.com/ru/post/1259202/


All Articles