1 #include "test/jemalloc_test.h" 2 3 #define THREAD_DATA 0x72b65c10 4 5 typedef unsigned int data_t; 6 7 static bool data_cleanup_executed; 8 9 malloc_tsd_types(data_, data_t) 10 malloc_tsd_protos(, data_, data_t) 11 12 void 13 data_cleanup(void *arg) 14 { 15 data_t *data = (data_t *)arg; 16 17 if (!data_cleanup_executed) { 18 assert_x_eq(*data, THREAD_DATA, 19 "Argument passed into cleanup function should match tsd " 20 "value"); 21 } 22 data_cleanup_executed = true; 23 24 /* 25 * Allocate during cleanup for two rounds, in order to assure that 26 * jemalloc's internal tsd reinitialization happens. 27 */ 28 switch (*data) { 29 case THREAD_DATA: 30 *data = 1; 31 data_tsd_set(data); 32 break; 33 case 1: 34 *data = 2; 35 data_tsd_set(data); 36 break; 37 case 2: 38 return; 39 default: 40 not_reached(); 41 } 42 43 { 44 void *p = mallocx(1, 0); 45 assert_ptr_not_null(p, "Unexpeced mallocx() failure"); 46 dallocx(p, 0); 47 } 48 } 49 50 malloc_tsd_externs(data_, data_t) 51 #define DATA_INIT 0x12345678 52 malloc_tsd_data(, data_, data_t, DATA_INIT) 53 malloc_tsd_funcs(, data_, data_t, DATA_INIT, data_cleanup) 54 55 static void * 56 thd_start(void *arg) 57 { 58 data_t d = (data_t)(uintptr_t)arg; 59 void *p; 60 61 assert_x_eq(*data_tsd_get(true), DATA_INIT, 62 "Initial tsd get should return initialization value"); 63 64 p = malloc(1); 65 assert_ptr_not_null(p, "Unexpected malloc() failure"); 66 67 data_tsd_set(&d); 68 assert_x_eq(*data_tsd_get(true), d, 69 "After tsd set, tsd get should return value that was set"); 70 71 d = 0; 72 assert_x_eq(*data_tsd_get(true), (data_t)(uintptr_t)arg, 73 "Resetting local data should have no effect on tsd"); 74 75 free(p); 76 return (NULL); 77 } 78 79 TEST_BEGIN(test_tsd_main_thread) 80 { 81 82 thd_start((void *)(uintptr_t)0xa5f3e329); 83 } 84 TEST_END 85 86 TEST_BEGIN(test_tsd_sub_thread) 87 { 88 thd_t thd; 89 90 data_cleanup_executed = false; 91 thd_create(&thd, thd_start, (void *)THREAD_DATA); 92 thd_join(thd, NULL); 93 assert_true(data_cleanup_executed, 94 "Cleanup function should have executed"); 95 } 96 TEST_END 97 98 int 99 main(void) 100 { 101 102 /* Core tsd bootstrapping must happen prior to data_tsd_boot(). */ 103 if (nallocx(1, 0) == 0) { 104 malloc_printf("Initialization error"); 105 return (test_status_fail); 106 } 107 data_tsd_boot(); 108 109 return (test( 110 test_tsd_main_thread, 111 test_tsd_sub_thread)); 112 } 113