1#include "test/jemalloc_test.h" 2 3#define THREAD_DATA 0x72b65c10 4 5typedef unsigned int data_t; 6 7static bool data_cleanup_executed; 8 9malloc_tsd_types(data_, data_t) 10malloc_tsd_protos(, data_, data_t) 11 12void 13data_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 50malloc_tsd_externs(data_, data_t) 51#define DATA_INIT 0x12345678 52malloc_tsd_data(, data_, data_t, DATA_INIT) 53malloc_tsd_funcs(, data_, data_t, DATA_INIT, data_cleanup) 54 55static void * 56thd_start(void *arg) 57{ 58 data_t d = (data_t)(uintptr_t)arg; 59 void *p; 60 61 assert_x_eq(*data_tsd_get(), 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(), d, 69 "After tsd set, tsd get should return value that was set"); 70 71 d = 0; 72 assert_x_eq(*data_tsd_get(), (data_t)(uintptr_t)arg, 73 "Resetting local data should have no effect on tsd"); 74 75 free(p); 76 return (NULL); 77} 78 79TEST_BEGIN(test_tsd_main_thread) 80{ 81 82 thd_start((void *) 0xa5f3e329); 83} 84TEST_END 85 86TEST_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} 96TEST_END 97 98int 99main(void) 100{ 101 102 data_tsd_boot(); 103 104 return (test( 105 test_tsd_main_thread, 106 test_tsd_sub_thread)); 107} 108