aboutsummaryrefslogtreecommitdiff
path: root/src/tcache.c
diff options
context:
space:
mode:
authorBen Maurer <bmaurer@fb.com>2014-04-15 13:28:37 -0700
committerBen Maurer <bmaurer@fb.com>2014-04-16 13:36:56 -0700
commita7619b7fa56f98d1ca99a23b458696dd37c12b77 (patch)
treed428b52a46cf1aaf944f32d1fff9fa066811f025 /src/tcache.c
parent9b0cbf0850b130a9b0a8c58bd10b2926b2083510 (diff)
downloadjemalloc-a7619b7fa56f98d1ca99a23b458696dd37c12b77.tar.gz
outline rare tcache_get codepaths
Diffstat (limited to 'src/tcache.c')
-rw-r--r--src/tcache.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/tcache.c b/src/tcache.c
index 6de9296..868f2d7 100644
--- a/src/tcache.c
+++ b/src/tcache.c
@@ -266,6 +266,46 @@ tcache_arena_dissociate(tcache_t *tcache)
}
tcache_t *
+tcache_get_hard(tcache_t *tcache, bool create)
+{
+
+ if (tcache == NULL) {
+ if (create == false) {
+ /*
+ * Creating a tcache here would cause
+ * allocation as a side effect of free().
+ * Ordinarily that would be okay since
+ * tcache_create() failure is a soft failure
+ * that doesn't propagate. However, if TLS
+ * data are freed via free() as in glibc,
+ * subtle corruption could result from setting
+ * a TLS variable after its backing memory is
+ * freed.
+ */
+ return (NULL);
+ }
+ if (tcache_enabled_get() == false) {
+ tcache_enabled_set(false); /* Memoize. */
+ return (NULL);
+ }
+ return (tcache_create(choose_arena(NULL)));
+ }
+ if (tcache == TCACHE_STATE_PURGATORY) {
+ /*
+ * Make a note that an allocator function was called
+ * after tcache_thread_cleanup() was called.
+ */
+ tcache = TCACHE_STATE_REINCARNATED;
+ tcache_tsd_set(&tcache);
+ return (NULL);
+ }
+ if (tcache == TCACHE_STATE_REINCARNATED)
+ return (NULL);
+ not_reached();
+ return (NULL);
+}
+
+tcache_t *
tcache_create(arena_t *arena)
{
tcache_t *tcache;