/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
/* @UNSAFE: whole file */
#include "lib.h"
#include "mmap-util.h"
#include <fcntl.h>
#ifndef MAP_ANONYMOUS
# ifdef MAP_ANON
# else
# define MAP_ANONYMOUS 0
# endif
#endif
#ifndef HAVE_LINUX_MREMAP
struct anon_header {
unsigned int signature;
};
static int page_size = 0;
static int header_size = 0;
static void movable_mmap_init(void)
{
#if MAP_ANONYMOUS == 0
if (zero_fd == -1)
#endif
page_size = getpagesize();
}
{
void *base;
if (header_size == 0)
/* we need extra page to store the pieces which construct
the full mmap. also allocate only page-aligned mmap sizes. */
if (base == MAP_FAILED)
return MAP_FAILED;
/* initialize the header */
return (char *) hdr + header_size;
}
{
void *new_base;
char *p;
if (new_base == MAP_FAILED)
return MAP_FAILED;
/* If we're moving large memory areas, it takes less memory to
copy the memory pages in smaller blocks. */
do {
if (block_size > old_size)
p -= block_size;
old_size -= block_size;
if (munmap((void *) p, block_size) < 0)
i_panic("munmap() failed: %m");
} while (old_size != 0);
i_panic("munmap() failed: %m");
return new_base;
}
{
return MAP_FAILED;
}
i_panic("movable_mremap(): Invalid old_address");
/* grow */
if ((flags & MREMAP_MAYMOVE) == 0) {
return MAP_FAILED;
}
}
/* shrink */
i_panic("munmap() failed: %m");
}
return old_address;
}
{
return -1;
}
i_panic("movable_munmap(): Invalid address");
i_panic("munmap() failed: %m");
return 0;
}
#else
{
}
unsigned long flags)
{
}
{
}
#endif