Merge pull request #9 from Microsoft/two_alloc_types

Add example for including the allocator with different settings in two compilation units.
This commit is contained in:
Matthew Parkinson 2019-01-24 11:38:20 +00:00 коммит произвёл GitHub
Родитель e0a2f10412 67fbcba653
Коммит 5b81caac87
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 127 добавлений и 53 удалений

Просмотреть файл

@ -140,7 +140,7 @@ extern "C"
for (; sc < NUM_SIZECLASSES; sc++)
{
size = sizeclass_to_size(sc);
if ((size & -size) >= alignment)
if ((size & (~size - 1)) >= alignment)
{
return SNMALLOC_NAME_MANGLE(aligned_alloc)(alignment, size);
}
@ -201,7 +201,7 @@ extern "C"
return ENOENT;
}
#ifndef __PIC__
#if !defined(__PIC__) && !defined(NO_BOOTSTRAP_ALLOCATOR)
// The following functions are required to work before TLS is set up, in
// statically-linked programs. These temporarily grab an allocator from the
// pool and return it.
@ -210,6 +210,7 @@ extern "C"
{
return get_slow_allocator()->alloc(size);
}
void* __je_bootstrap_calloc(size_t nmemb, size_t size)
{
bool overflow = false;
@ -223,6 +224,7 @@ extern "C"
sz = ((sz - 1) >> (bits::BITS - 1)) + sz;
return get_slow_allocator()->alloc<ZeroMem::YesZero>(sz);
}
void __je_bootstrap_free(void* ptr)
{
get_slow_allocator()->dealloc(ptr);

Просмотреть файл

@ -0,0 +1,10 @@
#undef IS_ADDRESS_SPACE_CONSTRAINED
#define OPEN_ENCLAVE
#define OPEN_ENCLAVE_SIMULATION
#define USE_RESERVE_MULTIPLE 1
#define NO_BOOTSTRAP_ALLOCATOR
#define IS_ADDRESS_SPACE_CONSTRAINED
#define SNMALLOC_NAME_MANGLE(a) enclave_##a
// Redefine the namespace, so we can have two versions.
#define snmalloc snmalloc_enclave
#include "../../../override/malloc.cc"

Просмотреть файл

@ -0,0 +1,6 @@
#undef IS_ADDRESS_SPACE_CONSTRAINED
#define SNMALLOC_NAME_MANGLE(a) host_##a
#define NO_BOOTSTRAP_ALLOCATOR
// Redefine the namespace, so we can have two versions.
#define snmalloc snmalloc_host
#include "../../../override/malloc.cc"

Просмотреть файл

@ -0,0 +1,53 @@
#include "../../../snmalloc.h"
#include <iostream>
#include <stdlib.h>
#include <string.h>
void* oe_base;
void* oe_end;
extern "C" const void* __oe_get_heap_base()
{
return oe_base;
}
extern "C" const void* __oe_get_heap_end()
{
return oe_end;
}
extern "C" void* oe_memset(void* p, int c, size_t size)
{
return memset(p, c, size);
}
extern "C" void oe_abort()
{
abort();
}
extern "C" void* host_malloc(size_t);
extern "C" void host_free(void*);
extern "C" void* enclave_malloc(size_t);
extern "C" void enclave_free(void*);
using namespace snmalloc;
int main()
{
DefaultPal pal;
size_t size = 1ULL << 28;
oe_base = pal.reserve<true>(&size, 0);
oe_end = (uint8_t*)oe_base + size;
std::cout << "Allocated region " << oe_base << " - " << oe_end << std::endl;
auto a = host_malloc(128);
auto b = enclave_malloc(128);
std::cout << "Host alloc " << a << std::endl;
std::cout << "Enclave alloc " << b << std::endl;
host_free(a);
enclave_free(b);
}

Просмотреть файл

@ -5,62 +5,65 @@
using namespace snmalloc;
constexpr size_t count_log = 20;
constexpr size_t count = 1 << count_log;
// Pre allocate all the objects
size_t* objects[count];
NOINLINE void setup(xoroshiro::p128r64& r, Alloc* alloc)
namespace test
{
for (size_t i = 0; i < count; i++)
static constexpr size_t count_log = 20;
static constexpr size_t count = 1 << count_log;
// Pre allocate all the objects
size_t* objects[count];
NOINLINE void setup(xoroshiro::p128r64& r, Alloc* alloc)
{
size_t rand = (size_t)r.next();
size_t offset = bits::clz(rand);
if (offset > 30)
offset = 30;
size_t size = (rand & 15) << offset;
if (size < 16)
size = 16;
// store object
objects[i] = (size_t*)alloc->alloc(size);
// Store allocators size for this object
*objects[i] = Alloc::alloc_size(objects[i]);
}
}
NOINLINE void teardown(Alloc* alloc)
{
// Deallocate everything
for (size_t i = 0; i < count; i++)
{
alloc->dealloc(objects[i]);
}
current_alloc_pool()->debug_check_empty();
}
void test_external_pointer(xoroshiro::p128r64& r)
{
auto* alloc = ThreadAlloc::get();
setup(r, alloc);
DO_TIME("External pointer queries ", {
for (size_t i = 0; i < 10000000; i++)
for (size_t i = 0; i < count; i++)
{
size_t rand = (size_t)r.next();
size_t oid = rand & (((size_t)1 << count_log) - 1);
size_t* external_ptr = objects[oid];
size_t size = *external_ptr;
size_t offset = (size >> 4) * (rand & 15);
size_t interior_ptr = ((size_t)external_ptr) + offset;
void* calced_external = Alloc::external_pointer((void*)interior_ptr);
if (calced_external != external_ptr)
abort();
size_t offset = bits::clz(rand);
if (offset > 30)
offset = 30;
size_t size = (rand & 15) << offset;
if (size < 16)
size = 16;
// store object
objects[i] = (size_t*)alloc->alloc(size);
// Store allocators size for this object
*objects[i] = Alloc::alloc_size(objects[i]);
}
});
}
teardown(alloc);
NOINLINE void teardown(Alloc* alloc)
{
// Deallocate everything
for (size_t i = 0; i < count; i++)
{
alloc->dealloc(objects[i]);
}
current_alloc_pool()->debug_check_empty();
}
void test_external_pointer(xoroshiro::p128r64& r)
{
auto* alloc = ThreadAlloc::get();
setup(r, alloc);
DO_TIME("External pointer queries ", {
for (size_t i = 0; i < 10000000; i++)
{
size_t rand = (size_t)r.next();
size_t oid = rand & (((size_t)1 << count_log) - 1);
size_t* external_ptr = objects[oid];
size_t size = *external_ptr;
size_t offset = (size >> 4) * (rand & 15);
size_t interior_ptr = ((size_t)external_ptr) + offset;
void* calced_external = Alloc::external_pointer((void*)interior_ptr);
if (calced_external != external_ptr)
abort();
}
});
teardown(alloc);
}
}
int main(int, char**)
@ -73,6 +76,6 @@ int main(int, char**)
#endif
for (size_t n = 0; n < nn; n++)
test_external_pointer(r);
test::test_external_pointer(r);
return 0;
}