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	assert_x_eq(*data_tsd_get(), DATA_INIT,
60	    "Initial tsd get should return initialization value");
61
62	data_tsd_set(&d);
63	assert_x_eq(*data_tsd_get(), d,
64	    "After tsd set, tsd get should return value that was set");
65
66	d = 0;
67	assert_x_eq(*data_tsd_get(), (data_t)(uintptr_t)arg,
68	    "Resetting local data should have no effect on tsd");
69
70	return (NULL);
71}
72
73TEST_BEGIN(test_tsd_main_thread)
74{
75
76	thd_start((void *) 0xa5f3e329);
77}
78TEST_END
79
80TEST_BEGIN(test_tsd_sub_thread)
81{
82	thd_t thd;
83
84	data_cleanup_executed = false;
85	thd_create(&thd, thd_start, (void *)THREAD_DATA);
86	thd_join(thd, NULL);
87	assert_true(data_cleanup_executed,
88	    "Cleanup function should have executed");
89}
90TEST_END
91
92int
93main(void)
94{
95
96	data_tsd_boot();
97
98	return (test(
99	    test_tsd_main_thread,
100	    test_tsd_sub_thread));
101}
102