How to implement dynamic change of shared memory?

Currently, I use shm_open to get the file descriptor, and then use ftruncate and mmap whenever I want to add a new buffer to shared memory. Each buffer is used individually for its own purposes.

Now I need to make an arbitrary buffer size. As well as munmap buffers and use free space again later.

The only solution I can solve for the first problem is: ftuncate (file_size + old_buffer_size + extra_size), mmap, copy the data to a new buffer and then munmap the original data. It looks very expensive to me, and probably the best way. It also entails deleting the original buffer every time.

For the second problem, I don’t even have a bad solution, I obviously can not move the memory every time the buffer is deleted. And if I follow the free memory and use it whenever possible, this will slow down the distribution process, and also leave me with bits and pieces between them that are not used.

Hope this is not too confusing. Thanks

+3
source share
2 answers

I wrote an open source library just for this purpose: rszshm is a resizable shared memory with a pointer

To quote on the description page:

To accommodate resizing, rszshm first displays a large, closed, null map. This serves to request a range of addresses. Shared file mapping then overlaps the beginning of the range. Later calls to expand the display cover more spans. Attempting to go beyond the span returns an error.

I expand the display by calling mmap with MAP_FIXED at the source address and with a new size.

+3
source

As far as I understand, you need to increase (or reduce) the existing memory mapping. Under Linux memory, implemented as a file, it is located in the / dev / shm file system. All operations in this file are the same as in regular files (and file descriptors).

if you want to expand the existing map, first expand the file size using ftruncate (as you wrote), then use mremap to expand the map with the requested size.

If you store pointers in this region, you may need to update them, but first try calling with flag 0. In this case, the system tries to increase the existing mapping to the requested size (if there is no collision with another stored memory area), and the pointers remain valid .

If the previous option is not available, use the flag MREMAP_MAYMOVE. In this case, the system is reassigned to other locations, but basically it is done efficiently (without the copy used by the system). Then update the pointers.

Abbreviation is the same as in the reverse order.

+2
source

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


All Articles