/* Copyright 2006 The Android Open Source Project */

/* A wrapper file for dlmalloc.c that compiles in the
 * mspace_*() functions, which provide an interface for
 * creating multiple heaps.
 */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/ioctl.h>

#include <cutils/ashmem.h>

/* It's a pain getting the mallinfo stuff to work
 * with Linux, OSX, and klibc, so just turn it off
 * for now.
 * TODO: make mallinfo work
 */
#define NO_MALLINFO 1

/* Allow setting the maximum heap footprint.
 */
#define USE_MAX_ALLOWED_FOOTPRINT 1

/* Don't try to trim memory.
 * TODO: support this.
 */
#define MORECORE_CANNOT_TRIM 1

/* Use mmap()d anonymous memory to guarantee
 * that an mspace is contiguous.
 *
 * create_mspace() won't work right if this is
 * defined, so hide the definition of it and
 * break any users at build time.
 */
#define USE_CONTIGUOUS_MSPACES 1
#if USE_CONTIGUOUS_MSPACES
/* This combination of settings forces sys_alloc()
 * to always use MORECORE().  It won't expect the
 * results to be contiguous, but we'll guarantee
 * that they are.
 */
#define HAVE_MMAP 0
#define HAVE_MORECORE 1
#define MORECORE_CONTIGUOUS 0
/* m is always the appropriate local when MORECORE() is called. */
#define MORECORE(S) contiguous_mspace_morecore(m, S)
#define create_mspace   HIDDEN_create_mspace_HIDDEN
#define destroy_mspace   HIDDEN_destroy_mspace_HIDDEN
typedef struct malloc_state *mstate0;
static void *contiguous_mspace_morecore(mstate0 m, ssize_t nb);
#endif /* USE_CONTIGUOUS_MSPACES */

#define MSPACES 1
#define ONLY_MSPACES 1
#include "dlmalloc.c"

#ifndef PAGESIZE
#define PAGESIZE  mparams.page_size
#endif

#define ALIGN_UP(p, alignment) \
    (((uintptr_t)(p) + (alignment)-1) & ~((alignment)-1))

/* A direct copy of dlmalloc_usable_size(),
 * which isn't compiled in when ONLY_MSPACES is set.
 * The mspace parameter isn't actually necessary,
 * but we include it to be consistent with the
 * rest of the mspace_*() functions.
 */
size_t mspace_usable_size(mspace _unused, const void* mem) {
  if (mem != 0) {
    const mchunkptr p = mem2chunk(mem);
    if (cinuse(p))
      return chunksize(p) - overhead_for(p);
  }
  return 0;
}

#if USE_CONTIGUOUS_MSPACES
#include <sys/mman.h>
#include <limits.h>

#define CONTIG_STATE_MAGIC  0xf00dd00d
struct mspace_contig_state {
  unsigned int magic;
  char *brk;
  char *top;
  mspace m;
};

static void *contiguous_mspace_morecore(mstate m, ssize_t nb) {
  struct mspace_contig_state *cs;
  char *oldbrk;
  const unsigned int pagesize = PAGESIZE;

  cs = (struct mspace_contig_state *)((uintptr_t)m & ~(pagesize-1));
  assert(cs->magic == CONTIG_STATE_MAGIC);
  assert(cs->m == m);
assert(nb >= 0);  //xxx deal with the trim case

  oldbrk = cs->brk;
  if (nb > 0) {
    /* Break to the first page boundary that satisfies the request.
     */
    char *newbrk = (char *)ALIGN_UP(oldbrk + nb, pagesize);
    if (newbrk > cs->top)
      return CMFAIL;

    /* Update the protection on the underlying memory.
     * Pages we've given to dlmalloc are read/write, and
     * pages we haven't are not accessable (read or write
     * will cause a seg fault).
     */
    if (mprotect(cs, newbrk - (char *)cs, PROT_READ | PROT_WRITE) < 0)
      return CMFAIL;
    if (newbrk != cs->top) {
      if (mprotect(newbrk, cs->top - newbrk, PROT_NONE) < 0)
        return CMFAIL;
    }

    cs->brk = newbrk;

    /* Make sure that dlmalloc will merge this block with the
     * initial block that was passed to create_mspace_with_base().
     * We don't care about extern vs. non-extern, so just clear it.
     */
    m->seg.sflags &= ~EXTERN_BIT;
  }

  return oldbrk;
}

mspace create_contiguous_mspace_with_base(size_t starting_capacity,
    size_t max_capacity, int locked, void *base) {
  struct mspace_contig_state *cs;
  unsigned int pagesize;
  mstate m;

  init_mparams();
  pagesize = PAGESIZE;
  assert(starting_capacity <= max_capacity);
  assert(((uintptr_t)base & (pagesize-1)) == 0);
  assert(((uintptr_t)max_capacity & (pagesize-1)) == 0);
  starting_capacity = (size_t)ALIGN_UP(starting_capacity, pagesize);

  /* Make the first page read/write. dlmalloc needs to use that page.
   */
  if (mprotect(base, starting_capacity, PROT_READ | PROT_WRITE) < 0) {
    goto error;
  }

  /* Create the mspace, pointing to the memory given.
   */
  m = create_mspace_with_base((char *)base + sizeof(*cs), starting_capacity,
                              locked);
  if (m == (mspace)0) {
    goto error;
  }
  /* Make sure that m is in the same page as base.
   */
  assert(((uintptr_t)m & (uintptr_t)~(pagesize-1)) == (uintptr_t)base);
  /* Use some space for the information that our MORECORE needs.
   */
  cs = (struct mspace_contig_state *)base;

  /* Find out exactly how much of the memory the mspace
   * is using.
   */
  cs->brk = m->seg.base + m->seg.size;
  cs->top = (char *)base + max_capacity;

  assert((char *)base <= cs->brk);
  assert(cs->brk <= cs->top);
  /* Prevent access to the memory we haven't handed out yet.
   */
  if (cs->brk != cs->top) {
    /* mprotect() requires page-aligned arguments, but it's possible
     * for cs->brk not to be page-aligned at this point.
     */
    char *prot_brk = (char *)ALIGN_UP(cs->brk, pagesize);
    if ((mprotect(base, prot_brk - (char *)base, PROT_READ | PROT_WRITE) < 0) ||
        (mprotect(prot_brk, cs->top - prot_brk, PROT_NONE) < 0)) {
      goto error;
    }
  }

  cs->m = m;
  cs->magic = CONTIG_STATE_MAGIC;

  return (mspace)m;

error:
  return (mspace)0;
}

mspace create_contiguous_mspace_with_name(size_t starting_capacity,
    size_t max_capacity, int locked, char const *name) {
  int fd;
  char buf[ASHMEM_NAME_LEN] = "mspace";
  void *base;
  unsigned int pagesize;
  mstate m;

  if (starting_capacity > max_capacity)
    return (mspace)0;

  init_mparams();
  pagesize = PAGESIZE;

  /* Create the anonymous memory that will back the mspace.
   * This reserves all of the virtual address space we could
   * ever need.  Physical pages will be mapped as the memory
   * is touched.
   *
   * Align max_capacity to a whole page.
   */
  max_capacity = (size_t)ALIGN_UP(max_capacity, pagesize);

  if (name)
    snprintf(buf, sizeof(buf), "mspace/%s", name);
#ifdef USE_ASHMEM
  fd = ashmem_create_region(buf, max_capacity);
  if (fd < 0)
    return (mspace)0;
  base = mmap(NULL, max_capacity, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
  close(fd);
#else
  fd = -1;
  base = mmap(NULL, max_capacity, PROT_READ | PROT_WRITE,
              MAP_PRIVATE | MAP_ANONYMOUS, fd, 0);
#endif /* USE_ASHMEM */

  if (base == MAP_FAILED)
    return (mspace)0;

  /* Make sure that base is at the beginning of a page.
   */
  assert(((uintptr_t)base & (pagesize-1)) == 0);

  m = create_contiguous_mspace_with_base(starting_capacity, max_capacity,
                                         locked, base);
  if (m == 0) {
    munmap(base, max_capacity);
  }
  return m;
}

mspace create_contiguous_mspace(size_t starting_capacity,
    size_t max_capacity, int locked) {
  return create_contiguous_mspace_with_name(starting_capacity,
      max_capacity, locked, NULL);
}

size_t destroy_contiguous_mspace(mspace msp) {
  mstate ms = (mstate)msp;

  if (ok_magic(ms)) {
    struct mspace_contig_state *cs;
    size_t length;
    const unsigned int pagesize = PAGESIZE;

    cs = (struct mspace_contig_state *)((uintptr_t)ms & ~(pagesize-1));
    assert(cs->magic == CONTIG_STATE_MAGIC);
    assert(cs->m == ms);

    length = cs->top - (char *)cs;
    if (munmap((char *)cs, length) != 0)
      return length;
  }
  else {
    USAGE_ERROR_ACTION(ms, ms);
  }
  return 0;
}

void *contiguous_mspace_sbrk0(mspace msp) {
    struct mspace_contig_state *cs;
    mstate ms;
    const unsigned int pagesize = PAGESIZE;

    ms = (mstate)msp;
    cs = (struct mspace_contig_state *)((uintptr_t)ms & ~(pagesize-1));
    assert(cs->magic == CONTIG_STATE_MAGIC);
    assert(cs->m == ms);
    return cs->brk;
}
#endif /* USE_CONTIGUOUS_MSPACES */
