in src/mem/localalloc.h [116:163]
SNMALLOC_SLOW_PATH decltype(auto) lazy_init(Action action, Args... args)
{
SNMALLOC_ASSERT(core_alloc == nullptr);
if constexpr (!SharedStateHandle::Options.LocalAllocSupportsLazyInit)
{
SNMALLOC_CHECK(
false &&
"lazy_init called on an allocator that doesn't support lazy "
"initialisation");
// Unreachable, but needed to keep the type checker happy in deducing
// the return type of this function.
return static_cast<decltype(action(core_alloc, args...))>(nullptr);
}
else
{
// Initialise the thread local allocator
if constexpr (SharedStateHandle::Options.CoreAllocOwnsLocalState)
{
init();
}
// register_clean_up must be called after init. register clean up may
// be implemented with allocation, so need to ensure we have a valid
// allocator at this point.
if (!post_teardown)
// Must be called at least once per thread.
// A pthread implementation only calls the thread destruction handle
// if the key has been set.
SharedStateHandle::register_clean_up();
// Perform underlying operation
auto r = action(core_alloc, args...);
// After performing underlying operation, in the case of teardown
// already having begun, we must flush any state we just acquired.
if (post_teardown)
{
#ifdef SNMALLOC_TRACING
std::cout << "post_teardown flush()" << std::endl;
#endif
// We didn't have an allocator because the thread is being torndown.
// We need to return any local state, so we don't leak it.
flush();
}
return r;
}
}