aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorDavid Goldblatt <davidgoldblatt@fb.com>2017-04-26 18:37:44 -0700
committerDavid Goldblatt <davidtgoldblatt@gmail.com>2017-05-01 10:49:56 -0700
commit209f2926b8e734317942231332f24b4bfd94587e (patch)
tree6be83c3604e7874d99714736a6ff76aa018d4413 /test
parentc86c8f4ffbf8c118203f7327610a2ad80cf9622c (diff)
downloadplatform_external_jemalloc_new-209f2926b8e734317942231332f24b4bfd94587e.tar.gz
platform_external_jemalloc_new-209f2926b8e734317942231332f24b4bfd94587e.tar.bz2
platform_external_jemalloc_new-209f2926b8e734317942231332f24b4bfd94587e.zip
Header refactoring: tsd - cleanup and dependency breaking.
This removes the tsd macros (which are used only for tsd_t in real builds). We break up the circular dependencies involving tsd. We also move all tsd access through getters and setters. This allows us to assert that we only touch data when tsd is in a valid state. We simplify the usages of the x macro trick, removing all the customizability (get/set, init, cleanup), moving the lifetime logic to tsd_init and tsd_cleanup. This lets us make initialization order independent of order within tsd_t.
Diffstat (limited to 'test')
-rw-r--r--test/unit/tsd.c77
1 files changed, 33 insertions, 44 deletions
diff --git a/test/unit/tsd.c b/test/unit/tsd.c
index 38114674..c9a7d809 100644
--- a/test/unit/tsd.c
+++ b/test/unit/tsd.c
@@ -1,41 +1,29 @@
#include "test/jemalloc_test.h"
-#define THREAD_DATA 0x72b65c10
-
-typedef unsigned int data_t;
-
-static bool data_cleanup_executed;
-static bool data_test_started;
-
-malloc_tsd_types(data_, data_t)
-malloc_tsd_protos(, data_, data_t)
+static int data_cleanup_count;
void
-data_cleanup(void *arg) {
- data_t *data = (data_t *)arg;
-
- if (!data_test_started) {
- return;
- }
- if (!data_cleanup_executed) {
- assert_x_eq(*data, THREAD_DATA,
+data_cleanup(int *data) {
+ if (data_cleanup_count == 0) {
+ assert_x_eq(*data, MALLOC_TSD_TEST_DATA_INIT,
"Argument passed into cleanup function should match tsd "
"value");
}
- data_cleanup_executed = true;
+ ++data_cleanup_count;
/*
* Allocate during cleanup for two rounds, in order to assure that
* jemalloc's internal tsd reinitialization happens.
*/
+ bool reincarnate = false;
switch (*data) {
- case THREAD_DATA:
+ case MALLOC_TSD_TEST_DATA_INIT:
*data = 1;
- data_tsd_set(data);
+ reincarnate = true;
break;
case 1:
*data = 2;
- data_tsd_set(data);
+ reincarnate = true;
break;
case 2:
return;
@@ -43,37 +31,35 @@ data_cleanup(void *arg) {
not_reached();
}
- {
+ if (reincarnate) {
void *p = mallocx(1, 0);
assert_ptr_not_null(p, "Unexpeced mallocx() failure");
dallocx(p, 0);
}
}
-malloc_tsd_externs(data_, data_t)
-#define DATA_INIT 0x12345678
-malloc_tsd_data(, data_, data_t, DATA_INIT)
-malloc_tsd_funcs(, data_, data_t, DATA_INIT, data_cleanup)
-
static void *
thd_start(void *arg) {
- data_t d = (data_t)(uintptr_t)arg;
+ int d = (int)(uintptr_t)arg;
void *p;
- assert_x_eq(*data_tsd_get(true), DATA_INIT,
+ tsd_t *tsd = tsd_fetch();
+ assert_x_eq(tsd_test_data_get(tsd), MALLOC_TSD_TEST_DATA_INIT,
"Initial tsd get should return initialization value");
p = malloc(1);
assert_ptr_not_null(p, "Unexpected malloc() failure");
- data_tsd_set(&d);
- assert_x_eq(*data_tsd_get(true), d,
+ tsd_test_data_set(tsd, d);
+ assert_x_eq(tsd_test_data_get(tsd), d,
"After tsd set, tsd get should return value that was set");
d = 0;
- assert_x_eq(*data_tsd_get(true), (data_t)(uintptr_t)arg,
+ assert_x_eq(tsd_test_data_get(tsd), (int)(uintptr_t)arg,
"Resetting local data should have no effect on tsd");
+ tsd_test_callback_set(tsd, &data_cleanup);
+
free(p);
return NULL;
}
@@ -86,11 +72,15 @@ TEST_END
TEST_BEGIN(test_tsd_sub_thread) {
thd_t thd;
- data_cleanup_executed = false;
- thd_create(&thd, thd_start, (void *)THREAD_DATA);
+ data_cleanup_count = 0;
+ thd_create(&thd, thd_start, (void *)MALLOC_TSD_TEST_DATA_INIT);
thd_join(thd, NULL);
- assert_true(data_cleanup_executed,
- "Cleanup function should have executed");
+ /*
+ * We reincarnate twice in the data cleanup, so it should execute at
+ * least 3 times.
+ */
+ assert_x_ge(data_cleanup_count, 3,
+ "Cleanup function should have executed multiple times.");
}
TEST_END
@@ -103,9 +93,11 @@ thd_start_reincarnated(void *arg) {
assert_ptr_not_null(p, "Unexpected malloc() failure");
/* Manually trigger reincarnation. */
- assert_ptr_not_null(tsd->arena, "Should have tsd arena set.");
+ assert_ptr_not_null(tsd_arena_get(tsd),
+ "Should have tsd arena set.");
tsd_cleanup((void *)tsd);
- assert_ptr_null(tsd->arena, "TSD arena should have been cleared.");
+ assert_ptr_null(*tsd_arenap_get_unsafe(tsd),
+ "TSD arena should have been cleared.");
assert_u_eq(tsd->state, tsd_state_purgatory,
"TSD state should be purgatory\n");
@@ -114,12 +106,12 @@ thd_start_reincarnated(void *arg) {
"TSD state should be reincarnated\n");
p = mallocx(1, MALLOCX_TCACHE_NONE);
assert_ptr_not_null(p, "Unexpected malloc() failure");
- assert_ptr_not_null(tsd->arena,
+ assert_ptr_not_null(*tsd_arenap_get_unsafe(tsd),
"Should have tsd arena set after reincarnation.");
free(p);
tsd_cleanup((void *)tsd);
- assert_ptr_null(tsd->arena,
+ assert_ptr_null(*tsd_arenap_get_unsafe(tsd),
"TSD arena should have been cleared after 2nd cleanup.");
return NULL;
@@ -134,14 +126,11 @@ TEST_END
int
main(void) {
- /* Core tsd bootstrapping must happen prior to data_tsd_boot(). */
+ /* Ensure tsd bootstrapped. */
if (nallocx(1, 0) == 0) {
malloc_printf("Initialization error");
return test_status_fail;
}
- data_test_started = false;
- data_tsd_boot();
- data_test_started = true;
return test_no_reentrancy(
test_tsd_main_thread,