1234370Sjasone#define	JEMALLOC_TSD_C_
2234370Sjasone#include "jemalloc/internal/jemalloc_internal.h"
3234370Sjasone
4234370Sjasone/******************************************************************************/
5234370Sjasone/* Data. */
6234370Sjasone
7234370Sjasonestatic unsigned ncleanups;
8234370Sjasonestatic malloc_tsd_cleanup_t cleanups[MALLOC_TSD_CLEANUPS_MAX];
9234370Sjasone
10234370Sjasone/******************************************************************************/
11234370Sjasone
12234370Sjasonevoid *
13234370Sjasonemalloc_tsd_malloc(size_t size)
14234370Sjasone{
15234370Sjasone
16234370Sjasone	/* Avoid choose_arena() in order to dodge bootstrapping issues. */
17235238Sjasone	return (arena_malloc(arenas[0], size, false, false));
18234370Sjasone}
19234370Sjasone
20234370Sjasonevoid
21234370Sjasonemalloc_tsd_dalloc(void *wrapper)
22234370Sjasone{
23234370Sjasone
24234370Sjasone	idalloc(wrapper);
25234370Sjasone}
26234370Sjasone
27234370Sjasonevoid
28234370Sjasonemalloc_tsd_no_cleanup(void *arg)
29234370Sjasone{
30234370Sjasone
31234370Sjasone	not_reached();
32234370Sjasone}
33234370Sjasone
34235238Sjasone#if defined(JEMALLOC_MALLOC_THREAD_CLEANUP) || defined(_WIN32)
35235238Sjasone#ifndef _WIN32
36235238SjasoneJEMALLOC_EXPORT
37235238Sjasone#endif
38234370Sjasonevoid
39234370Sjasone_malloc_thread_cleanup(void)
40234370Sjasone{
41235238Sjasone	bool pending[MALLOC_TSD_CLEANUPS_MAX], again;
42234370Sjasone	unsigned i;
43234370Sjasone
44234370Sjasone	for (i = 0; i < ncleanups; i++)
45234370Sjasone		pending[i] = true;
46234370Sjasone
47234370Sjasone	do {
48234370Sjasone		again = false;
49234370Sjasone		for (i = 0; i < ncleanups; i++) {
50234370Sjasone			if (pending[i]) {
51234543Sjasone				pending[i] = cleanups[i]();
52234370Sjasone				if (pending[i])
53234370Sjasone					again = true;
54234370Sjasone			}
55234370Sjasone		}
56234370Sjasone	} while (again);
57234370Sjasone}
58234370Sjasone#endif
59234370Sjasone
60234370Sjasonevoid
61234543Sjasonemalloc_tsd_cleanup_register(bool (*f)(void))
62234370Sjasone{
63234370Sjasone
64234370Sjasone	assert(ncleanups < MALLOC_TSD_CLEANUPS_MAX);
65234543Sjasone	cleanups[ncleanups] = f;
66234370Sjasone	ncleanups++;
67234370Sjasone}
68234370Sjasone
69234370Sjasonevoid
70234370Sjasonemalloc_tsd_boot(void)
71234370Sjasone{
72234370Sjasone
73234370Sjasone	ncleanups = 0;
74234370Sjasone}
75235238Sjasone
76235238Sjasone#ifdef _WIN32
77235238Sjasonestatic BOOL WINAPI
78235238Sjasone_tls_callback(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
79235238Sjasone{
80235238Sjasone
81235238Sjasone	switch (fdwReason) {
82235238Sjasone#ifdef JEMALLOC_LAZY_LOCK
83235238Sjasone	case DLL_THREAD_ATTACH:
84235238Sjasone		isthreaded = true;
85235238Sjasone		break;
86235238Sjasone#endif
87235238Sjasone	case DLL_THREAD_DETACH:
88235238Sjasone		_malloc_thread_cleanup();
89235238Sjasone		break;
90235238Sjasone	default:
91235238Sjasone		break;
92235238Sjasone	}
93235238Sjasone	return (true);
94235238Sjasone}
95235238Sjasone
96235238Sjasone#ifdef _MSC_VER
97235238Sjasone#  ifdef _M_IX86
98235238Sjasone#    pragma comment(linker, "/INCLUDE:__tls_used")
99235238Sjasone#  else
100235238Sjasone#    pragma comment(linker, "/INCLUDE:_tls_used")
101235238Sjasone#  endif
102235238Sjasone#  pragma section(".CRT$XLY",long,read)
103235238Sjasone#endif
104235238SjasoneJEMALLOC_SECTION(".CRT$XLY") JEMALLOC_ATTR(used)
105235238Sjasonestatic const BOOL	(WINAPI *tls_callback)(HINSTANCE hinstDLL,
106235238Sjasone    DWORD fdwReason, LPVOID lpvReserved) = _tls_callback;
107235238Sjasone#endif
108