Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Arenoros zone/optimization size/delayed malloc" #1101

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
255 changes: 133 additions & 122 deletions erb/v1/cpp03_zone.hpp.erb
Original file line number Diff line number Diff line change
Expand Up @@ -29,101 +29,121 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {

class zone {
struct finalizer {
finalizer(void (*func)(void*), void* data, finalizer* next): m_func(func), m_data(data), m_next(next) {}
finalizer(void (*func)(void*), void* data):m_func(func), m_data(data) {}
void operator()() { m_func(m_data); }
void (*m_func)(void*);
void* m_data;
finalizer* m_next;
};

struct finalizer_array {
finalizer_array(): m_head(MSGPACK_NULLPTR) {}

finalizer_array():m_tail(MSGPACK_NULLPTR), m_end(MSGPACK_NULLPTR), m_array(MSGPACK_NULLPTR) {}
void call() {
finalizer* fin = m_tail;
for(; fin != m_array; --fin) (*(fin-1))();
}
~finalizer_array() {
clear();
call();
::free(m_array);
}

void clear() {
finalizer* fin = m_head;
finalizer* tmp = MSGPACK_NULLPTR;
while(fin) {
(*fin)();
tmp = fin;
fin = fin->m_next;
delete tmp;
}
m_head = MSGPACK_NULLPTR;
call();
m_tail = m_array;
}
void push(void (*func)(void* data), void* data)
{
finalizer* fin = m_tail;

void push(void (*func)(void* data), void* data) {
m_head = new finalizer(func, data, m_head);
}
if(fin == m_end) {
push_expand(func, data);
return;
}

fin->m_func = func;
fin->m_data = data;

void pop() {
finalizer* n = m_head->m_next;
delete m_head;
m_head = n;
++m_tail;
}
void push_expand(void (*func)(void*), void* data) {
const size_t nused = static_cast<size_t>(m_end - m_array);
size_t nnext;
if(nused == 0) {
nnext = (sizeof(finalizer) < 72/2) ?
72 / sizeof(finalizer) : 8;
} else {
nnext = nused * 2;
}
finalizer* tmp =
static_cast<finalizer*>(::realloc(m_array, sizeof(finalizer) * nnext));
if(!tmp) {
throw std::bad_alloc();
}
m_array = tmp;
m_end = tmp + nnext;
m_tail = tmp + nused;
new (m_tail) finalizer(func, data);

finalizer* m_head;
private:
finalizer_array(const finalizer_array&);
finalizer_array& operator=(const finalizer_array&);
++m_tail;
}
finalizer* m_tail;
finalizer* m_end;
finalizer* m_array;
};

struct chunk {
chunk* m_next;
};

struct chunk_list {
chunk_list(size_t chunk_size, char* ptr): m_free(chunk_size), m_ptr(ptr), m_head(MSGPACK_NULLPTR) {}
~chunk_list() {
chunk_list(size_t chunk_size)
{
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
if(!c) {
throw std::bad_alloc();
}

m_head = c;
m_free = chunk_size;
m_ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
c->m_next = MSGPACK_NULLPTR;
}
~chunk_list()
{
chunk* c = m_head;
while(c) {
chunk* n = c->m_next;
::free(c);
c = n;
}
m_head = MSGPACK_NULLPTR;
}

void clear(size_t chunk_size, char* ptr) {
void clear(size_t chunk_size)
{
chunk* c = m_head;
while(c) {
while(true) {
chunk* n = c->m_next;
::free(c);
c = n;
if(n) {
::free(c);
c = n;
} else {
m_head = c;
break;
}
}
m_head = MSGPACK_NULLPTR;
m_head->m_next = MSGPACK_NULLPTR;
m_free = chunk_size;
m_ptr = ptr;
m_ptr = reinterpret_cast<char*>(m_head) + sizeof(chunk);
}

size_t m_free;
char* m_ptr;
chunk* m_head;

private:
chunk_list(const chunk_list&);
chunk_list& operator=(const chunk_list&);
};

size_t m_chunk_size;
chunk_list* m_chunk_list;
chunk_list m_chunk_list;
finalizer_array m_finalizer_array;

public:
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE);
~zone();

public:
void* allocate_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN);

void* allocate_no_align(size_t size);

bool allocated() {
return m_chunk_list != MSGPACK_NULLPTR;
}

void push_finalizer(void (*func)(void*), void* data);

template <typename T>
Expand All @@ -132,23 +152,24 @@ public:
void clear();

void swap(zone& o);

static void* operator new(std::size_t size) {
static void* operator new(std::size_t size)
{
void* p = ::malloc(size);
if (!p) throw std::bad_alloc();
return p;
}

static void operator delete(void *p) /* throw() */ {
static void operator delete(void *p) /* throw() */
{
::free(p);
}

static void* operator new(std::size_t /*size*/, void* mem) /* throw() */ {
return mem;
static void* operator new(std::size_t size, void* place) /* throw() */
{
return ::operator new(size, place);
}
static void operator delete(void* p, void* place) /* throw() */
{
::operator delete(p, place);
}

static void operator delete(void * /*p*/, void* /*mem*/) /* throw() */ {}

/// @cond
<%0.upto(GENERATION_LIMIT) {|i|%>
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
Expand All @@ -167,72 +188,56 @@ private:

static char* get_aligned(char* ptr, size_t align);

chunk_list& get_chank_lst();

char* allocate_expand(size_t size);
private:
zone(const zone&);
zone& operator=(const zone&);
};

inline zone::zone(size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(MSGPACK_NULLPTR) {}

inline zone::~zone() {
m_finalizer_array.~finalizer_array();
if(m_chunk_list) {
m_chunk_list->~chunk_list();
::free(m_chunk_list);
m_chunk_list = MSGPACK_NULLPTR;
}
inline zone::zone(size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
{
}

inline char* zone::get_aligned(char* ptr, size_t align) {
inline char* zone::get_aligned(char* ptr, size_t align)
{
MSGPACK_ASSERT(align != 0 && (align & (align - 1)) == 0); // align must be 2^n (n >= 0)
return
reinterpret_cast<char*>(
reinterpret_cast<uintptr_t>(ptr + (align - 1)) & ~static_cast<uintptr_t>(align - 1)
);
}

inline zone::chunk_list& zone::get_chank_lst() {
if (!m_chunk_list) {
void* ptr = ::malloc(sizeof(chunk_list) + m_chunk_size);
if (!ptr)
throw std::bad_alloc();
m_chunk_list = new (ptr) chunk_list(m_chunk_size, reinterpret_cast<char*>(ptr) + sizeof(chunk_list));
}
return *m_chunk_list;
}

inline void* zone::allocate_align(size_t size, size_t align) {
chunk_list& chank_lst = get_chank_lst();
char* aligned = get_aligned(chank_lst.m_ptr, align);
size_t adjusted_size = size + static_cast<size_t>(aligned - chank_lst.m_ptr);
if (chank_lst.m_free < adjusted_size) {
inline void* zone::allocate_align(size_t size, size_t align)
{
char* aligned = get_aligned(m_chunk_list.m_ptr, align);
size_t adjusted_size = size + static_cast<size_t>(aligned - m_chunk_list.m_ptr);
if (m_chunk_list.m_free < adjusted_size) {
size_t enough_size = size + align - 1;
char* ptr = allocate_expand(enough_size);
aligned = get_aligned(ptr, align);
adjusted_size = size + static_cast<size_t>(aligned - chank_lst.m_ptr);
adjusted_size = size + static_cast<size_t>(aligned - m_chunk_list.m_ptr);
}
chank_lst.m_free -= adjusted_size;
chank_lst.m_ptr += adjusted_size;
m_chunk_list.m_free -= adjusted_size;
m_chunk_list.m_ptr += adjusted_size;
return aligned;
}

inline void* zone::allocate_no_align(size_t size) {
chunk_list& chank_lst = get_chank_lst();
char* ptr = chank_lst.m_ptr;
if(chank_lst.m_free < size) {
inline void* zone::allocate_no_align(size_t size)
{
char* ptr = m_chunk_list.m_ptr;
if(m_chunk_list.m_free < size) {
ptr = allocate_expand(size);
}
chank_lst.m_free -= size;
chank_lst.m_ptr += size;
m_chunk_list.m_free -= size;
m_chunk_list.m_ptr += size;

return ptr;
}

inline char* zone::allocate_expand(size_t size) {
chunk_list& cl = get_chank_lst();
inline char* zone::allocate_expand(size_t size)
{
chunk_list* const cl = &m_chunk_list;

size_t sz = m_chunk_size;

while(sz < size) {
Expand All @@ -249,54 +254,60 @@ inline char* zone::allocate_expand(size_t size) {

char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);

c->m_next = cl.m_head;
cl.m_head = c;
cl.m_free = sz;
cl.m_ptr = ptr;
c->m_next = cl->m_head;
cl->m_head = c;
cl->m_free = sz;
cl->m_ptr = ptr;

return ptr;
}

inline void zone::push_finalizer(void (*func)(void*), void* data) {
inline void zone::push_finalizer(void (*func)(void*), void* data)
{
m_finalizer_array.push(func, data);
}

template <typename T>
inline void zone::push_finalizer(msgpack::unique_ptr<T> obj) {
inline void zone::push_finalizer(msgpack::unique_ptr<T> obj)
{
m_finalizer_array.push(&zone::object_delete<T>, obj.release());
}

inline void zone::clear() {
inline void zone::clear()
{
m_finalizer_array.clear();
if (m_chunk_list) {
m_chunk_list->clear(m_chunk_size, reinterpret_cast<char*>(m_chunk_list) + sizeof(chunk_list));
}
m_chunk_list.clear(m_chunk_size);
}

inline void zone::swap(zone& o) {
inline void zone::swap(zone& o)
{
using std::swap;
swap(m_chunk_size, o.m_chunk_size);
swap(m_chunk_list, o.m_chunk_list);
swap(m_finalizer_array.m_head, o.m_finalizer_array.m_head);
swap(m_finalizer_array, o.m_finalizer_array);
}

template <typename T>
void zone::object_delete(void* obj) {
delete static_cast<T*>(obj);
void zone::object_destruct(void* obj)
{
static_cast<T*>(obj)->~T();
}

template <typename T>
void zone::object_destruct(void* obj) {
static_cast<T*>(obj)->~T();
void zone::object_delete(void* obj)
{
delete static_cast<T*>(obj);
}

inline void zone::undo_allocate(size_t size) {
chunk_list& cl = get_chank_lst();
cl.m_ptr -= size;
cl.m_free += size;
inline void zone::undo_allocate(size_t size)
{
m_chunk_list.m_ptr -= size;
m_chunk_list.m_free += size;
}

inline std::size_t aligned_size(std::size_t size, std::size_t align) {
inline std::size_t aligned_size(
std::size_t size,
std::size_t align) {
return (size + align - 1) / align * align;
}

Expand All @@ -315,7 +326,7 @@ T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>)
try {
return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>);
} catch (...) {
m_finalizer_array.pop();
--m_finalizer_array.m_tail;
undo_allocate(sizeof(T));
throw;
}
Expand Down
Loading
Loading