Home | History | Annotate | Download | only in unit
      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