[dovecot-cvs] dovecot/src/lib mmap-anon.c,1.14,1.15
cras at procontrol.fi
cras at procontrol.fi
Mon Oct 20 00:15:18 EEST 2003
Update of /home/cvs/dovecot/src/lib
In directory danu:/tmp/cvs-serv17143
Modified Files:
mmap-anon.c
Log Message:
MAP_FIXED didn't actually work the way I thought (should have looked the man
page more carefully..). Dropped that and now we'll always just memcpy() the
data when we want to grow a mmaping.
Index: mmap-anon.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/mmap-anon.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- mmap-anon.c 26 Aug 2003 21:18:16 -0000 1.14
+++ mmap-anon.c 19 Oct 2003 20:15:15 -0000 1.15
@@ -22,88 +22,38 @@
#include <stdlib.h>
#include <sys/mman.h>
-/* MMAP_BASE_MOVE may be set to negative as well */
-#if SSIZE_T_MAX > 2147483647L
- /* 64bit or more */
-# define MMAP_BASE_MOVE (1024ULL*1024ULL*1024ULL*128ULL) /* 128GB */
-#else
- /* 32bit most likely */
-# define MMAP_BASE_MOVE (1024UL*1024UL*128UL) /* 128M */
-#endif
-
#define MMAP_SIGNATURE 0xdeadbeef
#define PAGE_ALIGN(size) \
(((size) + (size_t)page_size-1) & ~(size_t)(page_size-1))
-struct movable_header {
+struct anon_header {
unsigned int signature;
size_t size;
};
static int page_size = 0;
static int header_size = 0;
-static void *movable_mmap_base = NULL;
-static void *mmap_top_limit, *mmap_heap_bottom, *mmap_heap_top;
static int zero_fd = -1;
static void movable_mmap_init(void)
{
- ssize_t abs_base_move;
- char x;
-
#if MAP_ANONYMOUS == 0
/* mmap()ing /dev/zero should be the same with some platforms */
zero_fd = open("/dev/zero", O_RDWR);
if (zero_fd == -1)
- i_fatal("Can't open /dev/zero for creating anonymous mmap");
+ i_fatal("Can't open /dev/zero for creating anonymous mmap: %m");
fd_close_on_exec(zero_fd, TRUE);
#endif
- abs_base_move = MMAP_BASE_MOVE;
- if (abs_base_move < 0)
- abs_base_move = -abs_base_move;
-
page_size = getpagesize();
header_size = page_size;
-
- /* keep our allocations far below stack. assumes the stack is
- growing down. */
- mmap_top_limit = &x - abs_base_move*2;
-
- /* keep our allocations far from heap */
- mmap_heap_bottom = malloc(1);
- mmap_heap_top = (char *) mmap_heap_bottom + abs_base_move*2;
- free(mmap_heap_bottom);
-}
-
-static int anon_mmap_fixed(void *address, size_t length)
-{
- void *base;
-
- i_assert(address != NULL);
-
- base = mmap(address, length, PROT_READ | PROT_WRITE,
- MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, zero_fd, 0);
-
- if (base != MAP_FAILED && base != address) {
- /* shouldn't happen with MAP_FIXED, but who knows.. */
- if (munmap(base, length) < 0)
- i_panic("munmap() failed: %m");
- base = MAP_FAILED;
- errno = EINVAL;
- }
-
- return base == MAP_FAILED ? -1 : 0;
}
void *mmap_anon(size_t length)
{
- struct movable_header *hdr;
- void *next_mmap_base, *base;
- ssize_t offset;
- unsigned int count;
- int ret;
+ struct anon_header *hdr;
+ void *base;
if (header_size == 0)
movable_mmap_init();
@@ -112,101 +62,20 @@
the full mmap. also allocate only page-aligned mmap sizes. */
length = PAGE_ALIGN(length + header_size);
- if (movable_mmap_base == NULL) {
- /* this is fully guessing */
- movable_mmap_base = (char *) NULL +
- PAGE_ALIGN((size_t)((char *)mmap_anon - (char *)NULL));
- }
-
- offset = MMAP_BASE_MOVE; count = 0;
- for (;;) {
- next_mmap_base = (char *) movable_mmap_base + offset;
- if ((char *) next_mmap_base < (char *) movable_mmap_base) {
- /* we're wrapping, fix the offset a bit so we won't
- just loop with same addresses.. */
- offset /= 2;
- if (offset/10 < page_size) {
- /* enough tries */
- errno = ENOMEM;
- return MAP_FAILED;
- }
- }
-
- movable_mmap_base = next_mmap_base;
-
- if ((char *) movable_mmap_base >
- (char *) movable_mmap_base + length) {
- /* too high, would wrap */
- continue;
- }
-
- if ((char *) movable_mmap_base + length >=
- (char *) mmap_top_limit) {
- /* too high, stack could grow over it */
- continue;
- }
-
- if ((char *) movable_mmap_base >= (char *) mmap_heap_bottom &&
- (char *) movable_mmap_base < (char *) mmap_heap_top) {
- /* too near heap */
- continue;
- }
-
- if (movable_mmap_base == NULL)
- continue;
-
- ret = anon_mmap_fixed(movable_mmap_base, length);
- if (ret == 0)
- break;
-
- if (errno != EINVAL && errno != ENOMEM)
- return MAP_FAILED;
-
- if (++count == 100) {
- /* enough tries, try non-fixed mmap() */
- base = mmap(NULL, length, PROT_READ | PROT_WRITE,
- MAP_ANONYMOUS | MAP_PRIVATE, zero_fd, 0);
- if (base == MAP_FAILED)
- return MAP_FAILED;
-
- movable_mmap_base = base;
- break;
- }
- }
+ base = mmap(NULL, length, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, zero_fd, 0);
+ if (base == MAP_FAILED)
+ return MAP_FAILED;
/* initialize the header */
- hdr = movable_mmap_base;
+ hdr = base;
hdr->signature = MMAP_SIGNATURE;
hdr->size = length - header_size;
return (char *) hdr + header_size;
}
-static int mremap_try_grow(struct movable_header *hdr, size_t new_size)
-{
- void *grow_base;
-
- grow_base = (char *) hdr + header_size + hdr->size;
- if ((char *) grow_base <= (char *) hdr + header_size ||
- (char *) grow_base >= (char *) mmap_top_limit) {
- /* overflows valid address range */
- return 0;
- }
-
- if (anon_mmap_fixed(grow_base, new_size - hdr->size) < 0) {
- if (errno == EINVAL || errno == ENOMEM) {
- /* can't grow, wanted address space is already in use */
- return 0;
- }
-
- return -1;
- }
-
- hdr->size = new_size;
- return 1;
-}
-
-static void *mremap_move(struct movable_header *hdr, size_t new_size)
+static void *mremap_move(struct anon_header *hdr, size_t new_size)
{
void *new_base;
char *p;
@@ -242,15 +111,14 @@
void *mremap_anon(void *old_address, size_t old_size __attr_unused__,
size_t new_size, unsigned long flags)
{
- struct movable_header *hdr;
- int ret;
+ struct anon_header *hdr;
if (old_address == NULL || old_address == MAP_FAILED) {
errno = EINVAL;
return MAP_FAILED;
}
- hdr = (struct movable_header *) ((char *) old_address - header_size);
+ hdr = (struct anon_header *) ((char *) old_address - header_size);
if (hdr->signature != MMAP_SIGNATURE)
i_panic("movable_mremap(): Invalid old_address");
@@ -258,12 +126,6 @@
if (new_size > hdr->size) {
/* grow */
- ret = mremap_try_grow(hdr, new_size);
- if (ret > 0)
- return old_address;
- if (ret < 0)
- return MAP_FAILED;
-
if ((flags & MREMAP_MAYMOVE) == 0) {
errno = ENOMEM;
return MAP_FAILED;
@@ -285,14 +147,14 @@
int munmap_anon(void *start, size_t length __attr_unused__)
{
- struct movable_header *hdr;
+ struct anon_header *hdr;
if (start == NULL || start == MAP_FAILED) {
errno = EINVAL;
return -1;
}
- hdr = (struct movable_header *) ((char *) start - header_size);
+ hdr = (struct anon_header *) ((char *) start - header_size);
if (hdr->signature != MMAP_SIGNATURE)
i_panic("movable_munmap(): Invalid address");
More information about the dovecot-cvs
mailing list