예제 #1
0
파일: huge.c 프로젝트: BombShen/kbengine
TEST_END

TEST_BEGIN(huge_mallocx) {
	unsigned arena1, arena2;
	size_t sz = sizeof(unsigned);

	assert_d_eq(mallctl("arenas.create", &arena1, &sz, NULL, 0), 0,
	    "Failed to create arena");
	void *huge = mallocx(HUGE_SZ, MALLOCX_ARENA(arena1));
	assert_ptr_not_null(huge, "Fail to allocate huge size");
	assert_d_eq(mallctl("arenas.lookup", &arena2, &sz, &huge,
	    sizeof(huge)), 0, "Unexpected mallctl() failure");
	assert_u_eq(arena1, arena2, "Wrong arena used for mallocx");
	dallocx(huge, MALLOCX_ARENA(arena1));

	void *huge2 = mallocx(HUGE_SZ, 0);
	assert_ptr_not_null(huge, "Fail to allocate huge size");
	assert_d_eq(mallctl("arenas.lookup", &arena2, &sz, &huge2,
	    sizeof(huge2)), 0, "Unexpected mallctl() failure");
	assert_u_ne(arena1, arena2,
	    "Huge allocation should not come from the manual arena.");
	assert_u_ne(arena2, 0,
	    "Huge allocation should not come from the arena 0.");
	dallocx(huge2, 0);
}
예제 #2
0
void *memkind_arena_calloc(struct memkind *kind, size_t num, size_t size)
{
    void *result = NULL;
    int err = 0;
    unsigned int arena;

    err = kind->ops->get_arena(kind, &arena, size);
    if (!err) {
        result = jemk_mallocx_check(num * size, MALLOCX_ARENA(arena) | MALLOCX_ZERO);
    }
    return result;
}
예제 #3
0
void *memkind_arena_realloc(struct memkind *kind, void *ptr, size_t size)
{
    int err = 0;
    unsigned int arena;

    if (size == 0 && ptr != NULL) {
        memkind_free(kind, ptr);
        ptr = NULL;
    }
    else {
        err = kind->ops->get_arena(kind, &arena, size);
        if (!err) {
            if (ptr == NULL) {
                ptr = jemk_mallocx_check(size, MALLOCX_ARENA(arena));
            }
            else {
                ptr = jemk_rallocx_check(ptr, size, MALLOCX_ARENA(arena));
            }
        }
    }
    return ptr;
}
예제 #4
0
파일: mallctl.c 프로젝트: memkind/memkind
TEST_END

TEST_BEGIN(test_arenas_lookup) {
	unsigned arena, arena1;
	void *ptr;
	size_t sz = sizeof(unsigned);
	assert_d_eq(mallctl("arenas.create", (void *)&arena, &sz, NULL, 0), 0,
	    "Unexpected mallctl() failure");
	ptr = mallocx(42, MALLOCX_ARENA(arena) | MALLOCX_TCACHE_NONE);
	assert_ptr_not_null(ptr, "Unexpected mallocx() failure");
	assert_d_eq(mallctl("arenas.lookup", &arena1, &sz, &ptr, sizeof(ptr)),
	    0, "Unexpected mallctl() failure");
	assert_u_eq(arena, arena1, "Unexpected arena index");
	dallocx(ptr, 0);
}
예제 #5
0
static void
test_zero(size_t szmin, size_t szmax)
{
	int flags = MALLOCX_ARENA(arena_ind()) | MALLOCX_ZERO;
	size_t sz, nsz;
	void *p;
#define	FILL_BYTE 0x7aU

	sz = szmax;
	p = mallocx(sz, flags);
	assert_ptr_not_null(p, "Unexpected mallocx() error");
	assert_false(validate_fill(p, 0x00, 0, sz), "Memory not filled: sz=%zu",
	    sz);

	/*
	 * Fill with non-zero so that non-debug builds are more likely to detect
	 * errors.
	 */
	memset(p, FILL_BYTE, sz);
	assert_false(validate_fill(p, FILL_BYTE, 0, sz),
	    "Memory not filled: sz=%zu", sz);

	/* Shrink in place so that we can expect growing in place to succeed. */
	sz = szmin;
	assert_zu_eq(xallocx(p, sz, 0, flags), sz,
	    "Unexpected xallocx() error");
	assert_false(validate_fill(p, FILL_BYTE, 0, sz),
	    "Memory not filled: sz=%zu", sz);

	for (sz = szmin; sz < szmax; sz = nsz) {
		nsz = nallocx(sz+1, flags);
		assert_zu_eq(xallocx(p, sz+1, 0, flags), nsz,
		    "Unexpected xallocx() failure");
		assert_false(validate_fill(p, FILL_BYTE, 0, sz),
		    "Memory not filled: sz=%zu", sz);
		assert_false(validate_fill(p, 0x00, sz, nsz-sz),
		    "Memory not filled: sz=%zu, nsz-sz=%zu", sz, nsz-sz);
		memset((void *)((uintptr_t)p + sz), FILL_BYTE, nsz-sz);
		assert_false(validate_fill(p, FILL_BYTE, 0, nsz),
		    "Memory not filled: nsz=%zu", nsz);
	}

	dallocx(p, flags);
}
bool JemallocNodumpAllocator::extend_and_setup_arena() {
#ifdef FOLLY_JEMALLOC_NODUMP_ALLOCATOR_SUPPORTED
    if (mallctl == nullptr) {
        // Not linked with jemalloc.
        return false;
    }

    size_t len = sizeof(arena_index_);
    if (auto ret = mallctl("arenas.extend", &arena_index_, &len, nullptr, 0)) {
        LOG(FATAL) << "Unable to extend arena: " << errnoStr(ret);
    }
    flags_ = MALLOCX_ARENA(arena_index_) | MALLOCX_TCACHE_NONE;

    // Set the custom alloc hook
    const auto key =
        folly::to<std::string>("arena.", arena_index_, ".chunk_hooks");
    chunk_hooks_t hooks;
    len = sizeof(hooks);
    // Read the existing hooks
    if (auto ret = mallctl(key.c_str(), &hooks, &len, nullptr, 0)) {
        LOG(FATAL) << "Unable to get the hooks: " << errnoStr(ret);
    }
    if (original_chunk_alloc_ == nullptr) {
        original_chunk_alloc_ = hooks.alloc;
    } else {
        DCHECK_EQ(original_chunk_alloc_, hooks.alloc);
    }

    // Set the custom hook
    hooks.alloc = &JemallocNodumpAllocator::chunk_alloc;
    if (auto ret =
                mallctl(key.c_str(), nullptr, nullptr, &hooks, sizeof(hooks))) {
        LOG(FATAL) << "Unable to set the hooks: " << errnoStr(ret);
    }

    return true;
#else // FOLLY_JEMALLOC_NODUMP_ALLOCATOR_SUPPORTED
    return false;
#endif // FOLLY_JEMALLOC_NODUMP_ALLOCATOR_SUPPORTED
}
예제 #7
0
int memkind_arena_posix_memalign(struct memkind *kind, void **memptr, size_t alignment,
                                 size_t size)
{
    int err = 0;
    unsigned int arena;
    int errno_before;

    *memptr = NULL;
    err = kind->ops->get_arena(kind, &arena, size);
    if (!err) {
        err = memkind_posix_check_alignment(kind, alignment);
    }
    if (!err) {
        /* posix_memalign should not change errno.
           Set it to its previous value after calling jemalloc */
        errno_before = errno;
        *memptr = jemk_mallocx_check(size, MALLOCX_ALIGN(alignment) | MALLOCX_ARENA(arena));
        errno = errno_before;
        err = *memptr ? 0 : ENOMEM;
    }
    return err;
}
예제 #8
0
void as_join(int id) {
  if (as_flags[id] != 0) {
    log_gas("address space %d already joined\n", id);
    return;
  }

  const chunk_hooks_t *hooks = _hooks[id];

  // If there aren't any custom hooks set for this space, then the basic local
  // allocator is fine, which means that we don't need any special flags for
  // this address space.
  if (!hooks) {
    log_gas("no custom allocator for %d, using local\n", id);
    return;
  }

  // Create an arena that uses the right hooks.
  unsigned arena;
  size_t sz = sizeof(arena);
  dbg_check( je_mallctl("arenas.extend", &arena, &sz, NULL, 0) );

  char path[128];
  snprintf(path, 128, "arena.%u.chunk_hooks", arena);
  dbg_check( je_mallctl(path, NULL, NULL, (void*)hooks, sizeof(*hooks)) );

  // // Disable dirty page purging for this arena
  // snprintf(path, 124, "arena.%u.lg_dirty_mult", arena);
  // ssize_t i = -1;
  // dbg_check( je_mallctl(path, NULL, NULL, (void*)&i, sizeof(i)) );

  // Create a cache.
  unsigned cache;
  sz = sizeof(cache);
  dbg_check( je_mallctl("tcache.create", &cache, &sz, NULL, 0) );

  // And set the flags.
  as_flags[id] = MALLOCX_ARENA(arena) | MALLOCX_TCACHE(cache);
}
예제 #9
0
TEST_END

TEST_BEGIN(test_extra_huge)
{
	int flags = MALLOCX_ARENA(arena_ind());
	size_t largemax, huge1, huge2, huge3, hugemax;
	void *p;

	/* Get size classes. */
	largemax = get_large_size(get_nlarge()-1);
	huge1 = get_huge_size(1);
	huge2 = get_huge_size(2);
	huge3 = get_huge_size(3);
	hugemax = get_huge_size(get_nhuge()-1);

	p = mallocx(huge3, flags);
	assert_ptr_not_null(p, "Unexpected mallocx() error");

	assert_zu_eq(xallocx(p, huge3, 0, flags), huge3,
	    "Unexpected xallocx() behavior");
	/* Test size decrease with zero extra. */
	assert_zu_ge(xallocx(p, huge1, 0, flags), huge1,
	    "Unexpected xallocx() behavior");
	assert_zu_ge(xallocx(p, largemax, 0, flags), huge1,
	    "Unexpected xallocx() behavior");

	assert_zu_eq(xallocx(p, huge3, 0, flags), huge3,
	    "Unexpected xallocx() behavior");
	/* Test size decrease with non-zero extra. */
	assert_zu_eq(xallocx(p, huge1, huge3 - huge1, flags), huge3,
	    "Unexpected xallocx() behavior");
	assert_zu_eq(xallocx(p, huge2, huge3 - huge2, flags), huge3,
	    "Unexpected xallocx() behavior");
	assert_zu_eq(xallocx(p, huge1, huge2 - huge1, flags), huge2,
	    "Unexpected xallocx() behavior");
	assert_zu_ge(xallocx(p, largemax, huge1 - largemax, flags), huge1,
	    "Unexpected xallocx() behavior");

	assert_zu_ge(xallocx(p, huge1, 0, flags), huge1,
	    "Unexpected xallocx() behavior");
	/* Test size increase with zero extra. */
	assert_zu_le(xallocx(p, huge3, 0, flags), huge3,
	    "Unexpected xallocx() behavior");
	assert_zu_le(xallocx(p, hugemax+1, 0, flags), huge3,
	    "Unexpected xallocx() behavior");

	assert_zu_ge(xallocx(p, huge1, 0, flags), huge1,
	    "Unexpected xallocx() behavior");
	/* Test size increase with non-zero extra. */
	assert_zu_le(xallocx(p, huge1, SIZE_T_MAX - huge1, flags), hugemax,
	    "Unexpected xallocx() behavior");

	assert_zu_ge(xallocx(p, huge1, 0, flags), huge1,
	    "Unexpected xallocx() behavior");
	/* Test size increase with non-zero extra. */
	assert_zu_le(xallocx(p, huge1, huge3 - huge1, flags), huge3,
	    "Unexpected xallocx() behavior");

	assert_zu_eq(xallocx(p, huge3, 0, flags), huge3,
	    "Unexpected xallocx() behavior");
	/* Test size+extra overflow. */
	assert_zu_le(xallocx(p, huge3, hugemax - huge3 + 1, flags), hugemax,
	    "Unexpected xallocx() behavior");

	dallocx(p, flags);
}
예제 #10
0
TEST_END

TEST_BEGIN(test_extra_large)
{
	int flags = MALLOCX_ARENA(arena_ind());
	size_t smallmax, large0, large1, large2, huge0, hugemax;
	void *p;

	/* Get size classes. */
	smallmax = get_small_size(get_nsmall()-1);
	large0 = get_large_size(0);
	large1 = get_large_size(1);
	large2 = get_large_size(2);
	huge0 = get_huge_size(0);
	hugemax = get_huge_size(get_nhuge()-1);

	p = mallocx(large2, flags);
	assert_ptr_not_null(p, "Unexpected mallocx() error");

	assert_zu_eq(xallocx(p, large2, 0, flags), large2,
	    "Unexpected xallocx() behavior");
	/* Test size decrease with zero extra. */
	assert_zu_eq(xallocx(p, large0, 0, flags), large0,
	    "Unexpected xallocx() behavior");
	assert_zu_eq(xallocx(p, smallmax, 0, flags), large0,
	    "Unexpected xallocx() behavior");

	assert_zu_eq(xallocx(p, large2, 0, flags), large2,
	    "Unexpected xallocx() behavior");
	/* Test size decrease with non-zero extra. */
	assert_zu_eq(xallocx(p, large0, large2 - large0, flags), large2,
	    "Unexpected xallocx() behavior");
	assert_zu_eq(xallocx(p, large1, large2 - large1, flags), large2,
	    "Unexpected xallocx() behavior");
	assert_zu_eq(xallocx(p, large0, large1 - large0, flags), large1,
	    "Unexpected xallocx() behavior");
	assert_zu_eq(xallocx(p, smallmax, large0 - smallmax, flags), large0,
	    "Unexpected xallocx() behavior");

	assert_zu_eq(xallocx(p, large0, 0, flags), large0,
	    "Unexpected xallocx() behavior");
	/* Test size increase with zero extra. */
	assert_zu_eq(xallocx(p, large2, 0, flags), large2,
	    "Unexpected xallocx() behavior");
	assert_zu_eq(xallocx(p, huge0, 0, flags), large2,
	    "Unexpected xallocx() behavior");

	assert_zu_eq(xallocx(p, large0, 0, flags), large0,
	    "Unexpected xallocx() behavior");
	/* Test size increase with non-zero extra. */
	assert_zu_lt(xallocx(p, large0, huge0 - large0, flags), huge0,
	    "Unexpected xallocx() behavior");

	assert_zu_eq(xallocx(p, large0, 0, flags), large0,
	    "Unexpected xallocx() behavior");
	/* Test size increase with non-zero extra. */
	assert_zu_eq(xallocx(p, large0, large2 - large0, flags), large2,
	    "Unexpected xallocx() behavior");

	assert_zu_eq(xallocx(p, large2, 0, flags), large2,
	    "Unexpected xallocx() behavior");
	/* Test size+extra overflow. */
	assert_zu_lt(xallocx(p, large2, hugemax - large2 + 1, flags), huge0,
	    "Unexpected xallocx() behavior");

	dallocx(p, flags);
}