hpdata: Add a test.

We're about to make the functionality here more complicated; testing hpdata
directly (rather than relying on user's tests) will make debugging easier.
This commit is contained in:
David Goldblatt 2020-12-02 07:04:01 -08:00 committed by David Goldblatt
parent 3ed0b4e8a3
commit d9f7e6c668
3 changed files with 69 additions and 2 deletions

View File

@ -219,6 +219,7 @@ TESTS_UNIT := \
$(srcroot)test/unit/hook.c \ $(srcroot)test/unit/hook.c \
$(srcroot)test/unit/hpa.c \ $(srcroot)test/unit/hpa.c \
$(srcroot)test/unit/hpa_central.c \ $(srcroot)test/unit/hpa_central.c \
$(srcroot)test/unit/hpdata.c \
$(srcroot)test/unit/huge.c \ $(srcroot)test/unit/huge.c \
$(srcroot)test/unit/inspect.c \ $(srcroot)test/unit/inspect.c \
$(srcroot)test/unit/junk.c \ $(srcroot)test/unit/junk.c \

View File

@ -112,10 +112,15 @@ hpdata_assert_empty(hpdata_t *hpdata) {
assert(hpdata_nfree_get(hpdata) == HUGEPAGE_PAGES); assert(hpdata_nfree_get(hpdata) == HUGEPAGE_PAGES);
} }
static inline bool
hpdata_consistent(hpdata_t *hpdata) {
return fb_urange_longest(hpdata->active_pages, HUGEPAGE_PAGES)
== hpdata_longest_free_range_get(hpdata);
}
static inline void static inline void
hpdata_assert_consistent(hpdata_t *hpdata) { hpdata_assert_consistent(hpdata_t *hpdata) {
assert(fb_urange_longest(hpdata->active_pages, HUGEPAGE_PAGES) assert(hpdata_consistent(hpdata));
== hpdata_longest_free_range_get(hpdata));
} }
TYPED_LIST(hpdata_list, hpdata_t, ql_link) TYPED_LIST(hpdata_list, hpdata_t, ql_link)

61
test/unit/hpdata.c Normal file
View File

@ -0,0 +1,61 @@
#include "test/jemalloc_test.h"
#define HPDATA_ADDR ((void *)(10 * HUGEPAGE))
#define HPDATA_AGE 123
TEST_BEGIN(test_reserve_alloc) {
hpdata_t hpdata;
hpdata_init(&hpdata, HPDATA_ADDR, HPDATA_AGE);
/* Allocating a page at a time, we should do first fit. */
for (size_t i = 0; i < HUGEPAGE_PAGES; i++) {
expect_true(hpdata_consistent(&hpdata), "");
expect_zu_eq(HUGEPAGE_PAGES - i,
hpdata_longest_free_range_get(&hpdata), "");
void *alloc = hpdata_reserve_alloc(&hpdata, PAGE);
expect_ptr_eq((char *)HPDATA_ADDR + i * PAGE, alloc, "");
expect_true(hpdata_consistent(&hpdata), "");
}
expect_true(hpdata_consistent(&hpdata), "");
expect_zu_eq(0, hpdata_longest_free_range_get(&hpdata), "");
/*
* Build up a bigger free-range, 2 pages at a time, until we've got 6
* adjacent free pages total. Pages 8-13 should be unreserved after
* this.
*/
hpdata_unreserve(&hpdata, (char *)HPDATA_ADDR + 10 * PAGE, 2 * PAGE);
expect_true(hpdata_consistent(&hpdata), "");
expect_zu_eq(2, hpdata_longest_free_range_get(&hpdata), "");
hpdata_unreserve(&hpdata, (char *)HPDATA_ADDR + 12 * PAGE, 2 * PAGE);
expect_true(hpdata_consistent(&hpdata), "");
expect_zu_eq(4, hpdata_longest_free_range_get(&hpdata), "");
hpdata_unreserve(&hpdata, (char *)HPDATA_ADDR + 8 * PAGE, 2 * PAGE);
expect_true(hpdata_consistent(&hpdata), "");
expect_zu_eq(6, hpdata_longest_free_range_get(&hpdata), "");
/*
* Leave page 14 reserved, but free page 15 (this test the case where
* unreserving combines two ranges).
*/
hpdata_unreserve(&hpdata, (char *)HPDATA_ADDR + 15 * PAGE, PAGE);
/*
* Longest free range shouldn't change; we've got a free range of size
* 6, then a reserved page, then another free range.
*/
expect_true(hpdata_consistent(&hpdata), "");
expect_zu_eq(6, hpdata_longest_free_range_get(&hpdata), "");
/* After freeing page 14, the two ranges get combined. */
hpdata_unreserve(&hpdata, (char *)HPDATA_ADDR + 14 * PAGE, PAGE);
expect_true(hpdata_consistent(&hpdata), "");
expect_zu_eq(8, hpdata_longest_free_range_get(&hpdata), "");
}
TEST_END
int main(void) {
return test_no_reentrancy(
test_reserve_alloc);
}