static mspace createMspace(void *base, size_t startSize, size_t maximumSize) { /* Create an unlocked dlmalloc mspace to use as * a heap source. * * We start off reserving startSize / 2 bytes but * letting the heap grow to startSize. This saves * memory in the case where a process uses even less * than the starting size. */ LOGV_HEAP("Creating VM heap of size %zu", startSize); errno = 0; mspace msp = create_contiguous_mspace_with_base(startSize/2, maximumSize, /*locked=*/false, base); if (msp != NULL) { /* Don't let the heap grow past the starting size without * our intervention. */ mspace_set_max_allowed_footprint(msp, startSize); } else { /* There's no guarantee that errno has meaning when the call * fails, but it often does. */ LOGE_HEAP("Can't create VM heap of size (%zu,%zu): %s", startSize/2, maximumSize, strerror(errno)); } return msp; }
mspace create_contiguous_mspace_with_name(size_t starting_capacity, size_t max_capacity, int locked, char const *name) { int fd, ret; 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); 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); 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; }