summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYinan Zhang <zyn8950@gmail.com>2019-04-09 18:01:26 (GMT)
committerQi Wang <interwq@gmail.com>2019-04-10 20:03:20 (GMT)
commit7ee3897740aabdccb2381b7b6ab68fff0aac3ec4 (patch)
treee8674cc98f46b62c4027a1c47ff897f290c53434
parentd3d7a8ef09b6fa79109e8930aaba7a677f8b24ac (diff)
downloadjemalloc-7ee3897740aabdccb2381b7b6ab68fff0aac3ec4.zip
jemalloc-7ee3897740aabdccb2381b7b6ab68fff0aac3ec4.tar.gz
jemalloc-7ee3897740aabdccb2381b7b6ab68fff0aac3ec4.tar.bz2
Separate tests for extent utilization API
As title.
-rw-r--r--Makefile.in1
-rw-r--r--src/ctl.c4
-rw-r--r--test/unit/extent_util.c190
-rw-r--r--test/unit/mallctl.c196
4 files changed, 194 insertions, 197 deletions
diff --git a/Makefile.in b/Makefile.in
index 0777f6a..3a09442 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -178,6 +178,7 @@ TESTS_UNIT := \
$(srcroot)test/unit/div.c \
$(srcroot)test/unit/emitter.c \
$(srcroot)test/unit/extent_quantize.c \
+ $(srcroot)test/unit/extent_util.c \
$(srcroot)test/unit/fork.c \
$(srcroot)test/unit/hash.c \
$(srcroot)test/unit/hook.c \
diff --git a/src/ctl.c b/src/ctl.c
index dd7e467..193d2b0 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -3131,7 +3131,7 @@ label_return:
* #define BIN_NREGS_READ(out) COUNTS(out)[4]
*
* and then write e.g. NFREE_READ(oldp) to fetch the output. See the unit test
- * test_utilization_query in test/unit/mallctl.c for an example.
+ * test_query in test/unit/extent_util.c for an example.
*
* For a typical defragmentation workflow making use of this API for
* understanding the fragmentation level, please refer to the comment for
@@ -3223,7 +3223,7 @@ label_return:
* #define SIZE_READ(out, i) out[(i) * 3 + 2]
*
* and then write e.g. NFREE_READ(oldp, i) to fetch the output. See the unit
- * test test_utilization_batch in test/unit/mallctl.c for a concrete example.
+ * test test_batch in test/unit/extent_util.c for a concrete example.
*
* A typical workflow would be composed of the following steps:
*
diff --git a/test/unit/extent_util.c b/test/unit/extent_util.c
new file mode 100644
index 0000000..6995325
--- /dev/null
+++ b/test/unit/extent_util.c
@@ -0,0 +1,190 @@
+#include "test/jemalloc_test.h"
+
+#define TEST_UTIL_EINVAL(node, a, b, c, d, why_inval) do { \
+ assert_d_eq(mallctl("experimental.utilization." node, \
+ a, b, c, d), EINVAL, "Should fail when " why_inval); \
+ assert_zu_eq(out_sz, out_sz_ref, \
+ "Output size touched when given invalid arguments"); \
+ assert_d_eq(memcmp(out, out_ref, out_sz_ref), 0, \
+ "Output content touched when given invalid arguments"); \
+} while (0)
+
+#define TEST_UTIL_QUERY_EINVAL(a, b, c, d, why_inval) \
+ TEST_UTIL_EINVAL("query", a, b, c, d, why_inval)
+#define TEST_UTIL_BATCH_EINVAL(a, b, c, d, why_inval) \
+ TEST_UTIL_EINVAL("batch_query", a, b, c, d, why_inval)
+
+#define TEST_UTIL_VALID(node) do { \
+ assert_d_eq(mallctl("experimental.utilization." node, \
+ out, &out_sz, in, in_sz), 0, \
+ "Should return 0 on correct arguments"); \
+ assert_zu_eq(out_sz, out_sz_ref, "incorrect output size"); \
+ assert_d_ne(memcmp(out, out_ref, out_sz_ref), 0, \
+ "Output content should be changed"); \
+} while (0)
+
+#define TEST_UTIL_BATCH_VALID TEST_UTIL_VALID("batch_query")
+
+TEST_BEGIN(test_query) {
+ void *p = mallocx(1, 0);
+ void **in = &p;
+ size_t in_sz = sizeof(const void *);
+ size_t out_sz = sizeof(void *) + sizeof(size_t) * 5;
+ void *out = mallocx(out_sz, 0);
+ void *out_ref = mallocx(out_sz, 0);
+ size_t out_sz_ref = out_sz;
+
+ assert_ptr_not_null(p, "test pointer allocation failed");
+ assert_ptr_not_null(out, "test output allocation failed");
+ assert_ptr_not_null(out_ref, "test reference output allocation failed");
+
+#define SLABCUR_READ(out) (*(void **)out)
+#define COUNTS(out) ((size_t *)((void **)out + 1))
+#define NFREE_READ(out) COUNTS(out)[0]
+#define NREGS_READ(out) COUNTS(out)[1]
+#define SIZE_READ(out) COUNTS(out)[2]
+#define BIN_NFREE_READ(out) COUNTS(out)[3]
+#define BIN_NREGS_READ(out) COUNTS(out)[4]
+
+ SLABCUR_READ(out) = NULL;
+ NFREE_READ(out) = NREGS_READ(out) = SIZE_READ(out) = -1;
+ BIN_NFREE_READ(out) = BIN_NREGS_READ(out) = -1;
+ memcpy(out_ref, out, out_sz);
+
+ /* Test invalid argument(s) errors */
+ TEST_UTIL_QUERY_EINVAL(NULL, &out_sz, in, in_sz, "old is NULL");
+ TEST_UTIL_QUERY_EINVAL(out, NULL, in, in_sz, "oldlenp is NULL");
+ TEST_UTIL_QUERY_EINVAL(out, &out_sz, NULL, in_sz, "newp is NULL");
+ TEST_UTIL_QUERY_EINVAL(out, &out_sz, in, 0, "newlen is zero");
+ in_sz -= 1;
+ TEST_UTIL_QUERY_EINVAL(out, &out_sz, in, in_sz, "invalid newlen");
+ in_sz += 1;
+ out_sz_ref = out_sz -= 2 * sizeof(size_t);
+ TEST_UTIL_QUERY_EINVAL(out, &out_sz, in, in_sz, "invalid *oldlenp");
+ out_sz_ref = out_sz += 2 * sizeof(size_t);
+
+ /* Examine output for valid call */
+ TEST_UTIL_VALID("query");
+ assert_zu_le(NFREE_READ(out), NREGS_READ(out),
+ "Extent free count exceeded region count");
+ assert_zu_le(NREGS_READ(out), SIZE_READ(out),
+ "Extent region count exceeded size");
+ assert_zu_ne(NREGS_READ(out), 0,
+ "Extent region count must be positive");
+ assert_zu_ne(SIZE_READ(out), 0, "Extent size must be positive");
+ if (config_stats) {
+ assert_zu_le(BIN_NFREE_READ(out), BIN_NREGS_READ(out),
+ "Bin free count exceeded region count");
+ assert_zu_ne(BIN_NREGS_READ(out), 0,
+ "Bin region count must be positive");
+ assert_zu_le(NFREE_READ(out), BIN_NFREE_READ(out),
+ "Extent free count exceeded bin free count");
+ assert_zu_le(NREGS_READ(out), BIN_NREGS_READ(out),
+ "Extent region count exceeded bin region count");
+ assert_zu_eq(BIN_NREGS_READ(out) % NREGS_READ(out), 0,
+ "Bin region count isn't a multiple of extent region count");
+ assert_zu_le(NREGS_READ(out) - NFREE_READ(out),
+ BIN_NREGS_READ(out) - BIN_NFREE_READ(out),
+ "Extent utilized count exceeded bin utilized count");
+ } else {
+ assert_zu_eq(BIN_NFREE_READ(out), 0,
+ "Bin free count should be zero when stats are disabled");
+ assert_zu_eq(BIN_NREGS_READ(out), 0,
+ "Bin region count should be zero when stats are disabled");
+ }
+ assert_ptr_not_null(SLABCUR_READ(out), "Current slab is null");
+ assert_true(NFREE_READ(out) == 0 || SLABCUR_READ(out) <= p,
+ "Allocation should follow first fit principle");
+
+#undef BIN_NREGS_READ
+#undef BIN_NFREE_READ
+#undef SIZE_READ
+#undef NREGS_READ
+#undef NFREE_READ
+#undef COUNTS
+#undef SLABCUR_READ
+
+ free(out_ref);
+ free(out);
+ free(p);
+}
+TEST_END
+
+TEST_BEGIN(test_batch) {
+ void *p = mallocx(1, 0);
+ void *q = mallocx(1, 0);
+ void *in[] = {p, q};
+ size_t in_sz = sizeof(const void *) * 2;
+ size_t out[] = {-1, -1, -1, -1, -1, -1};
+ size_t out_sz = sizeof(size_t) * 6;
+ size_t out_ref[] = {-1, -1, -1, -1, -1, -1};
+ size_t out_sz_ref = out_sz;
+
+ assert_ptr_not_null(p, "test pointer allocation failed");
+ assert_ptr_not_null(q, "test pointer allocation failed");
+
+ /* Test invalid argument(s) errors */
+ TEST_UTIL_BATCH_EINVAL(NULL, &out_sz, in, in_sz, "old is NULL");
+ TEST_UTIL_BATCH_EINVAL(out, NULL, in, in_sz, "oldlenp is NULL");
+ TEST_UTIL_BATCH_EINVAL(out, &out_sz, NULL, in_sz, "newp is NULL");
+ TEST_UTIL_BATCH_EINVAL(out, &out_sz, in, 0, "newlen is zero");
+ in_sz -= 1;
+ TEST_UTIL_BATCH_EINVAL(out, &out_sz, in, in_sz,
+ "newlen is not an exact multiple");
+ in_sz += 1;
+ out_sz_ref = out_sz -= 2 * sizeof(size_t);
+ TEST_UTIL_BATCH_EINVAL(out, &out_sz, in, in_sz,
+ "*oldlenp is not an exact multiple");
+ out_sz_ref = out_sz += 2 * sizeof(size_t);
+ in_sz -= sizeof(const void *);
+ TEST_UTIL_BATCH_EINVAL(out, &out_sz, in, in_sz,
+ "*oldlenp and newlen do not match");
+ in_sz += sizeof(const void *);
+
+ /* Examine output for valid calls */
+#define TEST_EQUAL_REF(i, message) \
+ assert_d_eq(memcmp(out + (i) * 3, out_ref + (i) * 3, 3), 0, message)
+
+#define NFREE_READ(out, i) out[(i) * 3]
+#define NREGS_READ(out, i) out[(i) * 3 + 1]
+#define SIZE_READ(out, i) out[(i) * 3 + 2]
+
+ out_sz_ref = out_sz /= 2;
+ in_sz /= 2;
+ TEST_UTIL_BATCH_VALID;
+ assert_zu_le(NFREE_READ(out, 0), NREGS_READ(out, 0),
+ "Extent free count exceeded region count");
+ assert_zu_le(NREGS_READ(out, 0), SIZE_READ(out, 0),
+ "Extent region count exceeded size");
+ assert_zu_ne(NREGS_READ(out, 0), 0,
+ "Extent region count must be positive");
+ assert_zu_ne(SIZE_READ(out, 0), 0, "Extent size must be positive");
+ TEST_EQUAL_REF(1, "Should not overwrite content beyond what's needed");
+ in_sz *= 2;
+ out_sz_ref = out_sz *= 2;
+
+ memcpy(out_ref, out, 3 * sizeof(size_t));
+ TEST_UTIL_BATCH_VALID;
+ TEST_EQUAL_REF(0, "Statistics should be stable across calls");
+ assert_zu_le(NFREE_READ(out, 1), NREGS_READ(out, 1),
+ "Extent free count exceeded region count");
+ assert_zu_eq(NREGS_READ(out, 0), NREGS_READ(out, 1),
+ "Extent region count should be same for same region size");
+ assert_zu_eq(SIZE_READ(out, 0), SIZE_READ(out, 1),
+ "Extent size should be same for same region size");
+
+#undef SIZE_READ
+#undef NREGS_READ
+#undef NFREE_READ
+
+#undef TEST_EQUAL_REF
+
+ free(q);
+ free(p);
+}
+TEST_END
+
+int
+main(void) {
+ return test(test_query, test_batch);
+}
diff --git a/test/unit/mallctl.c b/test/unit/mallctl.c
index ef00a3d..498f9e0 100644
--- a/test/unit/mallctl.c
+++ b/test/unit/mallctl.c
@@ -853,198 +853,6 @@ TEST_BEGIN(test_hooks_exhaustion) {
}
TEST_END
-#define TEST_UTIL_EINVAL(node, a, b, c, d, why_inval) do { \
- assert_d_eq(mallctl("experimental.utilization." node, \
- a, b, c, d), EINVAL, "Should fail when " why_inval); \
- assert_zu_eq(out_sz, out_sz_ref, \
- "Output size touched when given invalid arguments"); \
- assert_d_eq(memcmp(out, out_ref, out_sz_ref), 0, \
- "Output content touched when given invalid arguments"); \
-} while (0)
-
-#define TEST_UTIL_VALID(node) do { \
- assert_d_eq(mallctl("experimental.utilization." node, \
- out, &out_sz, in, in_sz), 0, \
- "Should return 0 on correct arguments"); \
- assert_zu_eq(out_sz, out_sz_ref, "incorrect output size"); \
- assert_d_ne(memcmp(out, out_ref, out_sz_ref), 0, \
- "Output content should be changed"); \
-} while (0)
-
-TEST_BEGIN(test_utilization_query) {
- void *p = mallocx(1, 0);
- void **in = &p;
- size_t in_sz = sizeof(const void *);
- size_t out_sz = sizeof(void *) + sizeof(size_t) * 5;
- void *out = mallocx(out_sz, 0);
- void *out_ref = mallocx(out_sz, 0);
- size_t out_sz_ref = out_sz;
-
- assert_ptr_not_null(p, "test pointer allocation failed");
- assert_ptr_not_null(out, "test output allocation failed");
- assert_ptr_not_null(out_ref, "test reference output allocation failed");
-
-#define SLABCUR_READ(out) (*(void **)out)
-#define COUNTS(out) ((size_t *)((void **)out + 1))
-#define NFREE_READ(out) COUNTS(out)[0]
-#define NREGS_READ(out) COUNTS(out)[1]
-#define SIZE_READ(out) COUNTS(out)[2]
-#define BIN_NFREE_READ(out) COUNTS(out)[3]
-#define BIN_NREGS_READ(out) COUNTS(out)[4]
-
- SLABCUR_READ(out) = NULL;
- NFREE_READ(out) = NREGS_READ(out) = SIZE_READ(out) = -1;
- BIN_NFREE_READ(out) = BIN_NREGS_READ(out) = -1;
- memcpy(out_ref, out, out_sz);
-
- /* Test invalid argument(s) errors */
-#define TEST_UTIL_QUERY_EINVAL(a, b, c, d, why_inval) \
- TEST_UTIL_EINVAL("query", a, b, c, d, why_inval)
-
- TEST_UTIL_QUERY_EINVAL(NULL, &out_sz, in, in_sz, "old is NULL");
- TEST_UTIL_QUERY_EINVAL(out, NULL, in, in_sz, "oldlenp is NULL");
- TEST_UTIL_QUERY_EINVAL(out, &out_sz, NULL, in_sz, "newp is NULL");
- TEST_UTIL_QUERY_EINVAL(out, &out_sz, in, 0, "newlen is zero");
- in_sz -= 1;
- TEST_UTIL_QUERY_EINVAL(out, &out_sz, in, in_sz, "invalid newlen");
- in_sz += 1;
- out_sz_ref = out_sz -= 2 * sizeof(size_t);
- TEST_UTIL_QUERY_EINVAL(out, &out_sz, in, in_sz, "invalid *oldlenp");
- out_sz_ref = out_sz += 2 * sizeof(size_t);
-
-#undef TEST_UTIL_QUERY_EINVAL
-
- /* Examine output for valid call */
- TEST_UTIL_VALID("query");
- assert_zu_le(NFREE_READ(out), NREGS_READ(out),
- "Extent free count exceeded region count");
- assert_zu_le(NREGS_READ(out), SIZE_READ(out),
- "Extent region count exceeded size");
- assert_zu_ne(NREGS_READ(out), 0,
- "Extent region count must be positive");
- assert_zu_ne(SIZE_READ(out), 0, "Extent size must be positive");
- if (config_stats) {
- assert_zu_le(BIN_NFREE_READ(out), BIN_NREGS_READ(out),
- "Bin free count exceeded region count");
- assert_zu_ne(BIN_NREGS_READ(out), 0,
- "Bin region count must be positive");
- assert_zu_le(NFREE_READ(out), BIN_NFREE_READ(out),
- "Extent free count exceeded bin free count");
- assert_zu_le(NREGS_READ(out), BIN_NREGS_READ(out),
- "Extent region count exceeded bin region count");
- assert_zu_eq(BIN_NREGS_READ(out) % NREGS_READ(out), 0,
- "Bin region count isn't a multiple of extent region count");
- assert_zu_le(NREGS_READ(out) - NFREE_READ(out),
- BIN_NREGS_READ(out) - BIN_NFREE_READ(out),
- "Extent utilized count exceeded bin utilized count");
- } else {
- assert_zu_eq(BIN_NFREE_READ(out), 0,
- "Bin free count should be zero when stats are disabled");
- assert_zu_eq(BIN_NREGS_READ(out), 0,
- "Bin region count should be zero when stats are disabled");
- }
- assert_ptr_not_null(SLABCUR_READ(out), "Current slab is null");
- assert_true(NFREE_READ(out) == 0 || SLABCUR_READ(out) <= p,
- "Allocation should follow first fit principle");
-
-#undef BIN_NREGS_READ
-#undef BIN_NFREE_READ
-#undef SIZE_READ
-#undef NREGS_READ
-#undef NFREE_READ
-#undef COUNTS
-#undef SLABCUR_READ
-
- free(out_ref);
- free(out);
- free(p);
-}
-TEST_END
-
-TEST_BEGIN(test_utilization_batch_query) {
- void *p = mallocx(1, 0);
- void *q = mallocx(1, 0);
- void *in[] = {p, q};
- size_t in_sz = sizeof(const void *) * 2;
- size_t out[] = {-1, -1, -1, -1, -1, -1};
- size_t out_sz = sizeof(size_t) * 6;
- size_t out_ref[] = {-1, -1, -1, -1, -1, -1};
- size_t out_sz_ref = out_sz;
-
- assert_ptr_not_null(p, "test pointer allocation failed");
- assert_ptr_not_null(q, "test pointer allocation failed");
-
- /* Test invalid argument(s) errors */
-#define TEST_UTIL_BATCH_EINVAL(a, b, c, d, why_inval) \
- TEST_UTIL_EINVAL("batch_query", a, b, c, d, why_inval)
-
- TEST_UTIL_BATCH_EINVAL(NULL, &out_sz, in, in_sz, "old is NULL");
- TEST_UTIL_BATCH_EINVAL(out, NULL, in, in_sz, "oldlenp is NULL");
- TEST_UTIL_BATCH_EINVAL(out, &out_sz, NULL, in_sz, "newp is NULL");
- TEST_UTIL_BATCH_EINVAL(out, &out_sz, in, 0, "newlen is zero");
- in_sz -= 1;
- TEST_UTIL_BATCH_EINVAL(out, &out_sz, in, in_sz,
- "newlen is not an exact multiple");
- in_sz += 1;
- out_sz_ref = out_sz -= 2 * sizeof(size_t);
- TEST_UTIL_BATCH_EINVAL(out, &out_sz, in, in_sz,
- "*oldlenp is not an exact multiple");
- out_sz_ref = out_sz += 2 * sizeof(size_t);
- in_sz -= sizeof(const void *);
- TEST_UTIL_BATCH_EINVAL(out, &out_sz, in, in_sz,
- "*oldlenp and newlen do not match");
- in_sz += sizeof(const void *);
-
-#undef TEST_UTIL_BATCH_EINVAL
-
- /* Examine output for valid calls */
-#define TEST_UTIL_BATCH_VALID TEST_UTIL_VALID("batch_query")
-#define TEST_EQUAL_REF(i, message) \
- assert_d_eq(memcmp(out + (i) * 3, out_ref + (i) * 3, 3), 0, message)
-
-#define NFREE_READ(out, i) out[(i) * 3]
-#define NREGS_READ(out, i) out[(i) * 3 + 1]
-#define SIZE_READ(out, i) out[(i) * 3 + 2]
-
- out_sz_ref = out_sz /= 2;
- in_sz /= 2;
- TEST_UTIL_BATCH_VALID;
- assert_zu_le(NFREE_READ(out, 0), NREGS_READ(out, 0),
- "Extent free count exceeded region count");
- assert_zu_le(NREGS_READ(out, 0), SIZE_READ(out, 0),
- "Extent region count exceeded size");
- assert_zu_ne(NREGS_READ(out, 0), 0,
- "Extent region count must be positive");
- assert_zu_ne(SIZE_READ(out, 0), 0, "Extent size must be positive");
- TEST_EQUAL_REF(1, "Should not overwrite content beyond what's needed");
- in_sz *= 2;
- out_sz_ref = out_sz *= 2;
-
- memcpy(out_ref, out, 3 * sizeof(size_t));
- TEST_UTIL_BATCH_VALID;
- TEST_EQUAL_REF(0, "Statistics should be stable across calls");
- assert_zu_le(NFREE_READ(out, 1), NREGS_READ(out, 1),
- "Extent free count exceeded region count");
- assert_zu_eq(NREGS_READ(out, 0), NREGS_READ(out, 1),
- "Extent region count should be same for same region size");
- assert_zu_eq(SIZE_READ(out, 0), SIZE_READ(out, 1),
- "Extent size should be same for same region size");
-
-#undef SIZE_READ
-#undef NREGS_READ
-#undef NFREE_READ
-
-#undef TEST_EQUAL_REF
-#undef TEST_UTIL_BATCH_VALID
-
- free(q);
- free(p);
-}
-TEST_END
-
-#undef TEST_UTIL_VALID
-#undef TEST_UTIL_EINVAL
-
int
main(void) {
return test(
@@ -1075,7 +883,5 @@ main(void) {
test_arenas_lookup,
test_stats_arenas,
test_hooks,
- test_hooks_exhaustion,
- test_utilization_query,
- test_utilization_batch_query);
+ test_hooks_exhaustion);
}