2017-01-11 10:06:31 +08:00
|
|
|
#ifndef JEMALLOC_INTERNAL_TSD_INLINES_H
|
|
|
|
#define JEMALLOC_INTERNAL_TSD_INLINES_H
|
|
|
|
|
|
|
|
#ifndef JEMALLOC_ENABLE_INLINE
|
|
|
|
malloc_tsd_protos(JEMALLOC_ATTR(unused), , tsd_t)
|
|
|
|
|
|
|
|
tsd_t *tsd_fetch_impl(bool init);
|
|
|
|
tsd_t *tsd_fetch(void);
|
|
|
|
tsdn_t *tsd_tsdn(tsd_t *tsd);
|
|
|
|
bool tsd_nominal(tsd_t *tsd);
|
2017-01-20 13:41:41 +08:00
|
|
|
#define O(n, t, c) \
|
2017-01-11 10:06:31 +08:00
|
|
|
t *tsd_##n##p_get(tsd_t *tsd); \
|
|
|
|
t tsd_##n##_get(tsd_t *tsd); \
|
|
|
|
void tsd_##n##_set(tsd_t *tsd, t n);
|
|
|
|
MALLOC_TSD
|
|
|
|
#undef O
|
|
|
|
tsdn_t *tsdn_fetch(void);
|
|
|
|
bool tsdn_null(const tsdn_t *tsdn);
|
|
|
|
tsd_t *tsdn_tsd(tsdn_t *tsdn);
|
|
|
|
rtree_ctx_t *tsdn_rtree_ctx(tsdn_t *tsdn, rtree_ctx_t *fallback);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_TSD_C_))
|
|
|
|
malloc_tsd_externs(, tsd_t)
|
|
|
|
malloc_tsd_funcs(JEMALLOC_ALWAYS_INLINE, , tsd_t, tsd_initializer, tsd_cleanup)
|
|
|
|
|
|
|
|
JEMALLOC_ALWAYS_INLINE tsd_t *
|
2017-01-16 08:56:30 +08:00
|
|
|
tsd_fetch_impl(bool init) {
|
2017-01-11 10:06:31 +08:00
|
|
|
tsd_t *tsd = tsd_get(init);
|
|
|
|
|
2017-01-16 08:56:30 +08:00
|
|
|
if (!init && tsd_get_allocates() && tsd == NULL) {
|
2017-01-20 10:15:45 +08:00
|
|
|
return NULL;
|
2017-01-16 08:56:30 +08:00
|
|
|
}
|
2017-01-11 10:06:31 +08:00
|
|
|
assert(tsd != NULL);
|
|
|
|
|
|
|
|
if (unlikely(tsd->state != tsd_state_nominal)) {
|
|
|
|
if (tsd->state == tsd_state_uninitialized) {
|
|
|
|
tsd->state = tsd_state_nominal;
|
|
|
|
/* Trigger cleanup handler registration. */
|
|
|
|
tsd_set(tsd);
|
|
|
|
} else if (tsd->state == tsd_state_purgatory) {
|
|
|
|
tsd->state = tsd_state_reincarnated;
|
|
|
|
tsd_set(tsd);
|
2017-01-16 08:56:30 +08:00
|
|
|
} else {
|
2017-01-11 10:06:31 +08:00
|
|
|
assert(tsd->state == tsd_state_reincarnated);
|
2017-01-16 08:56:30 +08:00
|
|
|
}
|
2017-01-11 10:06:31 +08:00
|
|
|
}
|
|
|
|
|
2017-01-20 10:15:45 +08:00
|
|
|
return tsd;
|
2017-01-11 10:06:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
JEMALLOC_ALWAYS_INLINE tsd_t *
|
2017-01-16 08:56:30 +08:00
|
|
|
tsd_fetch(void) {
|
2017-01-20 10:15:45 +08:00
|
|
|
return tsd_fetch_impl(true);
|
2017-01-11 10:06:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
JEMALLOC_ALWAYS_INLINE tsdn_t *
|
2017-01-16 08:56:30 +08:00
|
|
|
tsd_tsdn(tsd_t *tsd) {
|
2017-01-20 10:15:45 +08:00
|
|
|
return (tsdn_t *)tsd;
|
2017-01-11 10:06:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
JEMALLOC_INLINE bool
|
2017-01-16 08:56:30 +08:00
|
|
|
tsd_nominal(tsd_t *tsd) {
|
2017-01-11 10:06:31 +08:00
|
|
|
return (tsd->state == tsd_state_nominal);
|
|
|
|
}
|
|
|
|
|
2017-01-20 13:41:41 +08:00
|
|
|
#define O(n, t, c) \
|
2017-01-11 10:06:31 +08:00
|
|
|
JEMALLOC_ALWAYS_INLINE t * \
|
2017-01-16 08:56:30 +08:00
|
|
|
tsd_##n##p_get(tsd_t *tsd) { \
|
2017-01-20 10:15:45 +08:00
|
|
|
return &tsd->n; \
|
2017-01-11 10:06:31 +08:00
|
|
|
} \
|
|
|
|
\
|
|
|
|
JEMALLOC_ALWAYS_INLINE t \
|
2017-01-16 08:56:30 +08:00
|
|
|
tsd_##n##_get(tsd_t *tsd) { \
|
2017-01-20 10:15:45 +08:00
|
|
|
return *tsd_##n##p_get(tsd); \
|
2017-01-11 10:06:31 +08:00
|
|
|
} \
|
|
|
|
\
|
|
|
|
JEMALLOC_ALWAYS_INLINE void \
|
2017-01-16 08:56:30 +08:00
|
|
|
tsd_##n##_set(tsd_t *tsd, t n) { \
|
2017-01-11 10:06:31 +08:00
|
|
|
assert(tsd->state == tsd_state_nominal); \
|
|
|
|
tsd->n = n; \
|
|
|
|
}
|
|
|
|
MALLOC_TSD
|
|
|
|
#undef O
|
|
|
|
|
|
|
|
JEMALLOC_ALWAYS_INLINE tsdn_t *
|
2017-01-16 08:56:30 +08:00
|
|
|
tsdn_fetch(void) {
|
|
|
|
if (!tsd_booted_get()) {
|
2017-01-20 10:15:45 +08:00
|
|
|
return NULL;
|
2017-01-16 08:56:30 +08:00
|
|
|
}
|
2017-01-11 10:06:31 +08:00
|
|
|
|
2017-01-20 10:15:45 +08:00
|
|
|
return tsd_tsdn(tsd_fetch_impl(false));
|
2017-01-11 10:06:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
JEMALLOC_ALWAYS_INLINE bool
|
2017-01-16 08:56:30 +08:00
|
|
|
tsdn_null(const tsdn_t *tsdn) {
|
2017-01-20 10:15:45 +08:00
|
|
|
return tsdn == NULL;
|
2017-01-11 10:06:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
JEMALLOC_ALWAYS_INLINE tsd_t *
|
2017-01-16 08:56:30 +08:00
|
|
|
tsdn_tsd(tsdn_t *tsdn) {
|
2017-01-11 10:06:31 +08:00
|
|
|
assert(!tsdn_null(tsdn));
|
|
|
|
|
2017-01-20 10:15:45 +08:00
|
|
|
return &tsdn->tsd;
|
2017-01-11 10:06:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
JEMALLOC_ALWAYS_INLINE rtree_ctx_t *
|
2017-01-16 08:56:30 +08:00
|
|
|
tsdn_rtree_ctx(tsdn_t *tsdn, rtree_ctx_t *fallback) {
|
2017-01-11 10:06:31 +08:00
|
|
|
/*
|
|
|
|
* If tsd cannot be accessed, initialize the fallback rtree_ctx and
|
|
|
|
* return a pointer to it.
|
|
|
|
*/
|
|
|
|
if (unlikely(tsdn_null(tsdn))) {
|
|
|
|
static const rtree_ctx_t rtree_ctx = RTREE_CTX_INITIALIZER;
|
|
|
|
memcpy(fallback, &rtree_ctx, sizeof(rtree_ctx_t));
|
2017-01-20 10:15:45 +08:00
|
|
|
return fallback;
|
2017-01-11 10:06:31 +08:00
|
|
|
}
|
2017-01-20 10:15:45 +08:00
|
|
|
return tsd_rtree_ctxp_get(tsdn_tsd(tsdn));
|
2017-01-11 10:06:31 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* JEMALLOC_INTERNAL_TSD_INLINES_H */
|