Files
snmalloc/src/test/func/thread_alloc_external/thread_alloc_external.cc
Matthew Parkinson 7f3642e05c Change external thread_alloc example. (#424)
On Open Enclave having the `local_alloc` directly in thread-local
storage was causing a crash.  This changes the `local_alloc` to be
indirected, and thus puts less pressure on the thread-local storage.

The test also has deals with how to allocate before a thread-local
storage has been established.
2021-12-02 10:39:44 +00:00

90 lines
1.8 KiB
C++

#ifdef SNMALLOC_USE_PTHREAD_DESTRUCTORS
# undef SNMALLOC_USE_PTHREAD_DESTRUCTORS
#endif
#include <snmalloc_core.h>
#include <test/setup.h>
// Specify using own
#define SNMALLOC_EXTERNAL_THREAD_ALLOC
#include "backend/globalconfig.h"
namespace snmalloc
{
using Alloc = snmalloc::LocalAllocator<snmalloc::Globals>;
}
using namespace snmalloc;
class ThreadAllocExternal
{
public:
static Alloc*& get_inner()
{
static thread_local Alloc* alloc;
return alloc;
}
static Alloc& get()
{
return *get_inner();
}
};
#include <snmalloc_front.h>
void allocator_thread_init(void)
{
void* aptr;
{
// Create bootstrap allocator
auto a = snmalloc::ScopedAllocator();
// Create storage for the thread-local allocator
aptr = a->alloc(sizeof(snmalloc::Alloc));
}
// Initialize the thread-local allocator
ThreadAllocExternal::get_inner() = new (aptr) snmalloc::Alloc();
ThreadAllocExternal::get().init();
}
void allocator_thread_cleanup(void)
{
// Teardown the thread-local allocator
ThreadAllocExternal::get().teardown();
// Need a bootstrap allocator to deallocate the thread-local allocator
auto a = snmalloc::ScopedAllocator();
// Deallocate the storage for the thread local allocator
a->dealloc(ThreadAllocExternal::get_inner());
}
int main()
{
setup();
allocator_thread_init();
auto& a = ThreadAlloc::get();
for (size_t i = 0; i < 1000; i++)
{
auto r1 = a.alloc(i);
a.dealloc(r1);
}
ThreadAlloc::get().teardown();
// This checks that the scoped allocator does not call
// register clean up, as this configuration will fault
// if that occurs.
auto a2 = ScopedAllocator();
for (size_t i = 0; i < 1000; i++)
{
auto r1 = a2->alloc(i);
a2->dealloc(r1);
}
allocator_thread_cleanup();
}