Linux provides the mremap() system call for expanding or shrinking the size of a given mapping. This function is Linux-specific: #define _GNU_SOURCE #include <unistd.h void * mremap (void *addr, size_t old_size, A call to mremap() expands or shrinks mapping in the region [addr,addr+old_size) to the new size new_size. The kernel can potentially move the mapping at the same time, depending on the availability of space in the process’ address space and the value of flags.
Theflags parameter can be either0orMREMAP_MAYMOVE, which specifies that the kernel is free to move the mapping, if required, in order to perform the requested resizing. A large resizing is more likely to succeed if the kernel can move the mapping. On success, mremap() returns a pointer to the newly resized memory mapping. On failure, it returns MAP_FAILED, and sets errnoto one of the following:
EAGAIN EFAULT EINVAL ENOMEM Libraries such as glibc often usemremap()to implement an efficientrealloc(), which is an interface for resizing a block of memory originally obtained viamalloc(). For example: void * realloc (void *addr, size_t len) p = mremap (addr, old_size, len, MREMAP_MAYMOVE); This would only work if allmalloc()allocations were unique anonymous mappings; nonetheless, it stands as a useful example of the performance gains to be had. The example assumes the programmer has written alook_up_mapping_size()function. The GNU C library does usemmap()and family for performing some memory allocations. We will look that topic in depth in Chapter 8.
blog comments powered by Disqus |