Lazily initialise TLS on slow paths.
Copying an idea from mimalloc, initialise the TLS variable to a global allocator that doesn't own any memory and then lazily check when we hit a slow path (which we always do when using the global allocator, because it doesn't own any memory) if we are the global allocator and replace it. There is a slight complication compared to mimalloc's version of this idea. Snmalloc collects outgoing messages and it's possible for the first operation in a thread to be a free of memory allocated by a different thread. We address this by initialising the queues with a size value indicating that they are full and then do the lazy check when about to insert a message that would make a queue full. This will then trigger lazy creation of an allocator. Global initialisation doesn't work for the fake allocator, so skip most of its constructor.
This commit is contained in:
@@ -6,11 +6,25 @@
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
inline void* lazy_replacement(void*);
|
||||
using Alloc =
|
||||
Allocator<GlobalVirtual, SNMALLOC_DEFAULT_PAGEMAP, true, lazy_replacement>;
|
||||
|
||||
template<class MemoryProvider>
|
||||
class AllocPool : Pool<Allocator<MemoryProvider>, MemoryProvider>
|
||||
class AllocPool : Pool<
|
||||
Allocator<
|
||||
MemoryProvider,
|
||||
SNMALLOC_DEFAULT_PAGEMAP,
|
||||
true,
|
||||
lazy_replacement>,
|
||||
MemoryProvider>
|
||||
{
|
||||
using Alloc = Allocator<MemoryProvider>;
|
||||
using Parent = Pool<Allocator<MemoryProvider>, MemoryProvider>;
|
||||
using Alloc = Allocator<
|
||||
MemoryProvider,
|
||||
SNMALLOC_DEFAULT_PAGEMAP,
|
||||
true,
|
||||
lazy_replacement>;
|
||||
using Parent = Pool<Alloc, MemoryProvider>;
|
||||
|
||||
public:
|
||||
static AllocPool* make(MemoryProvider& mp)
|
||||
@@ -175,5 +189,4 @@ namespace snmalloc
|
||||
return AllocPool<MemoryProvider>::make(mp);
|
||||
}
|
||||
|
||||
using Alloc = Allocator<GlobalVirtual>;
|
||||
} // namespace snmalloc
|
||||
|
||||
Reference in New Issue
Block a user