mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-04-24 09:08:44 +02:00
Revert "Arenoros zone/optimization size/delayed malloc"
This commit is contained in:
parent
2987022c10
commit
d372a71786
@ -29,101 +29,121 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
|||||||
|
|
||||||
class zone {
|
class zone {
|
||||||
struct finalizer {
|
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 operator()() { m_func(m_data); }
|
||||||
void (*m_func)(void*);
|
void (*m_func)(void*);
|
||||||
void* m_data;
|
void* m_data;
|
||||||
finalizer* m_next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct finalizer_array {
|
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() {
|
~finalizer_array() {
|
||||||
clear();
|
call();
|
||||||
|
::free(m_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
finalizer* fin = m_head;
|
call();
|
||||||
finalizer* tmp = MSGPACK_NULLPTR;
|
m_tail = m_array;
|
||||||
while(fin) {
|
|
||||||
(*fin)();
|
|
||||||
tmp = fin;
|
|
||||||
fin = fin->m_next;
|
|
||||||
delete tmp;
|
|
||||||
}
|
}
|
||||||
m_head = MSGPACK_NULLPTR;
|
void push(void (*func)(void* data), void* data)
|
||||||
|
{
|
||||||
|
finalizer* fin = m_tail;
|
||||||
|
|
||||||
|
if(fin == m_end) {
|
||||||
|
push_expand(func, data);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(void (*func)(void* data), void* data) {
|
fin->m_func = func;
|
||||||
m_head = new finalizer(func, data, m_head);
|
fin->m_data = data;
|
||||||
}
|
|
||||||
|
|
||||||
void pop() {
|
++m_tail;
|
||||||
finalizer* n = m_head->m_next;
|
|
||||||
delete m_head;
|
|
||||||
m_head = n;
|
|
||||||
}
|
}
|
||||||
|
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;
|
++m_tail;
|
||||||
private:
|
}
|
||||||
finalizer_array(const finalizer_array&);
|
finalizer* m_tail;
|
||||||
finalizer_array& operator=(const finalizer_array&);
|
finalizer* m_end;
|
||||||
|
finalizer* m_array;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chunk {
|
struct chunk {
|
||||||
chunk* m_next;
|
chunk* m_next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chunk_list {
|
struct chunk_list {
|
||||||
chunk_list(size_t chunk_size, char* ptr): m_free(chunk_size), m_ptr(ptr), m_head(MSGPACK_NULLPTR) {}
|
chunk_list(size_t chunk_size)
|
||||||
~chunk_list() {
|
{
|
||||||
chunk* c = m_head;
|
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
|
||||||
while(c) {
|
if(!c) {
|
||||||
chunk* n = c->m_next;
|
throw std::bad_alloc();
|
||||||
::free(c);
|
|
||||||
c = n;
|
|
||||||
}
|
|
||||||
m_head = MSGPACK_NULLPTR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear(size_t chunk_size, char* ptr) {
|
m_head = c;
|
||||||
chunk* c = m_head;
|
|
||||||
while(c) {
|
|
||||||
chunk* n = c->m_next;
|
|
||||||
::free(c);
|
|
||||||
c = n;
|
|
||||||
}
|
|
||||||
m_head = MSGPACK_NULLPTR;
|
|
||||||
m_free = chunk_size;
|
m_free = chunk_size;
|
||||||
m_ptr = ptr;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void clear(size_t chunk_size)
|
||||||
|
{
|
||||||
|
chunk* c = m_head;
|
||||||
|
while(true) {
|
||||||
|
chunk* n = c->m_next;
|
||||||
|
if(n) {
|
||||||
|
::free(c);
|
||||||
|
c = n;
|
||||||
|
} else {
|
||||||
|
m_head = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_head->m_next = MSGPACK_NULLPTR;
|
||||||
|
m_free = chunk_size;
|
||||||
|
m_ptr = reinterpret_cast<char*>(m_head) + sizeof(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t m_free;
|
size_t m_free;
|
||||||
char* m_ptr;
|
char* m_ptr;
|
||||||
chunk* m_head;
|
chunk* m_head;
|
||||||
|
|
||||||
private:
|
|
||||||
chunk_list(const chunk_list&);
|
|
||||||
chunk_list& operator=(const chunk_list&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t m_chunk_size;
|
size_t m_chunk_size;
|
||||||
chunk_list* m_chunk_list;
|
chunk_list m_chunk_list;
|
||||||
finalizer_array m_finalizer_array;
|
finalizer_array m_finalizer_array;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE);
|
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_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN);
|
||||||
|
|
||||||
void* allocate_no_align(size_t size);
|
void* allocate_no_align(size_t size);
|
||||||
|
|
||||||
bool allocated() {
|
|
||||||
return m_chunk_list != MSGPACK_NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_finalizer(void (*func)(void*), void* data);
|
void push_finalizer(void (*func)(void*), void* data);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -132,23 +152,24 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void swap(zone& o);
|
void swap(zone& o);
|
||||||
|
static void* operator new(std::size_t size)
|
||||||
static void* operator new(std::size_t size) {
|
{
|
||||||
void* p = ::malloc(size);
|
void* p = ::malloc(size);
|
||||||
if (!p) throw std::bad_alloc();
|
if (!p) throw std::bad_alloc();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
static void operator delete(void *p) /* throw() */
|
||||||
static void operator delete(void *p) /* throw() */ {
|
{
|
||||||
::free(p);
|
::free(p);
|
||||||
}
|
}
|
||||||
|
static void* operator new(std::size_t size, void* place) /* throw() */
|
||||||
static void* operator new(std::size_t /*size*/, void* mem) /* throw() */ {
|
{
|
||||||
return mem;
|
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
|
/// @cond
|
||||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
@ -167,26 +188,18 @@ private:
|
|||||||
|
|
||||||
static char* get_aligned(char* ptr, size_t align);
|
static char* get_aligned(char* ptr, size_t align);
|
||||||
|
|
||||||
chunk_list& get_chank_lst();
|
|
||||||
|
|
||||||
char* allocate_expand(size_t size);
|
char* allocate_expand(size_t size);
|
||||||
private:
|
private:
|
||||||
zone(const zone&);
|
zone(const zone&);
|
||||||
zone& operator=(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(size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
|
||||||
|
{
|
||||||
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 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)
|
MSGPACK_ASSERT(align != 0 && (align & (align - 1)) == 0); // align must be 2^n (n >= 0)
|
||||||
return
|
return
|
||||||
reinterpret_cast<char*>(
|
reinterpret_cast<char*>(
|
||||||
@ -194,45 +207,37 @@ inline char* zone::get_aligned(char* ptr, size_t align) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline zone::chunk_list& zone::get_chank_lst() {
|
inline void* zone::allocate_align(size_t size, size_t align)
|
||||||
if (!m_chunk_list) {
|
{
|
||||||
void* ptr = ::malloc(sizeof(chunk_list) + m_chunk_size);
|
char* aligned = get_aligned(m_chunk_list.m_ptr, align);
|
||||||
if (!ptr)
|
size_t adjusted_size = size + static_cast<size_t>(aligned - m_chunk_list.m_ptr);
|
||||||
throw std::bad_alloc();
|
if (m_chunk_list.m_free < adjusted_size) {
|
||||||
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) {
|
|
||||||
size_t enough_size = size + align - 1;
|
size_t enough_size = size + align - 1;
|
||||||
char* ptr = allocate_expand(enough_size);
|
char* ptr = allocate_expand(enough_size);
|
||||||
aligned = get_aligned(ptr, align);
|
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;
|
m_chunk_list.m_free -= adjusted_size;
|
||||||
chank_lst.m_ptr += adjusted_size;
|
m_chunk_list.m_ptr += adjusted_size;
|
||||||
return aligned;
|
return aligned;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void* zone::allocate_no_align(size_t size) {
|
inline void* zone::allocate_no_align(size_t size)
|
||||||
chunk_list& chank_lst = get_chank_lst();
|
{
|
||||||
char* ptr = chank_lst.m_ptr;
|
char* ptr = m_chunk_list.m_ptr;
|
||||||
if(chank_lst.m_free < size) {
|
if(m_chunk_list.m_free < size) {
|
||||||
ptr = allocate_expand(size);
|
ptr = allocate_expand(size);
|
||||||
}
|
}
|
||||||
chank_lst.m_free -= size;
|
m_chunk_list.m_free -= size;
|
||||||
chank_lst.m_ptr += size;
|
m_chunk_list.m_ptr += size;
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline char* zone::allocate_expand(size_t size) {
|
inline char* zone::allocate_expand(size_t size)
|
||||||
chunk_list& cl = get_chank_lst();
|
{
|
||||||
|
chunk_list* const cl = &m_chunk_list;
|
||||||
|
|
||||||
size_t sz = m_chunk_size;
|
size_t sz = m_chunk_size;
|
||||||
|
|
||||||
while(sz < size) {
|
while(sz < size) {
|
||||||
@ -249,54 +254,60 @@ inline char* zone::allocate_expand(size_t size) {
|
|||||||
|
|
||||||
char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
|
char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
|
||||||
|
|
||||||
c->m_next = cl.m_head;
|
c->m_next = cl->m_head;
|
||||||
cl.m_head = c;
|
cl->m_head = c;
|
||||||
cl.m_free = sz;
|
cl->m_free = sz;
|
||||||
cl.m_ptr = ptr;
|
cl->m_ptr = ptr;
|
||||||
|
|
||||||
return 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);
|
m_finalizer_array.push(func, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
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());
|
m_finalizer_array.push(&zone::object_delete<T>, obj.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void zone::clear() {
|
inline void zone::clear()
|
||||||
|
{
|
||||||
m_finalizer_array.clear();
|
m_finalizer_array.clear();
|
||||||
if (m_chunk_list) {
|
m_chunk_list.clear(m_chunk_size);
|
||||||
m_chunk_list->clear(m_chunk_size, reinterpret_cast<char*>(m_chunk_list) + sizeof(chunk_list));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void zone::swap(zone& o) {
|
inline void zone::swap(zone& o)
|
||||||
|
{
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(m_chunk_size, o.m_chunk_size);
|
swap(m_chunk_size, o.m_chunk_size);
|
||||||
swap(m_chunk_list, o.m_chunk_list);
|
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>
|
template <typename T>
|
||||||
void zone::object_delete(void* obj) {
|
void zone::object_destruct(void* obj)
|
||||||
delete static_cast<T*>(obj);
|
{
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void zone::object_destruct(void* obj) {
|
|
||||||
static_cast<T*>(obj)->~T();
|
static_cast<T*>(obj)->~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void zone::undo_allocate(size_t size) {
|
template <typename T>
|
||||||
chunk_list& cl = get_chank_lst();
|
void zone::object_delete(void* obj)
|
||||||
cl.m_ptr -= size;
|
{
|
||||||
cl.m_free += size;
|
delete static_cast<T*>(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::size_t aligned_size(std::size_t size, std::size_t align) {
|
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) {
|
||||||
return (size + align - 1) / align * align;
|
return (size + align - 1) / align * align;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +326,7 @@ T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>)
|
|||||||
try {
|
try {
|
||||||
return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>);
|
return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FIND_PACKAGE (Boost REQUIRED)
|
FIND_PACKAGE (Boost REQUIRED COMPONENTS system)
|
||||||
FIND_PACKAGE (Threads REQUIRED)
|
FIND_PACKAGE (Threads REQUIRED)
|
||||||
FIND_PACKAGE (ZLIB REQUIRED)
|
FIND_PACKAGE (ZLIB REQUIRED)
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ FOREACH (source_file ${exec_PROGRAMS})
|
|||||||
)
|
)
|
||||||
TARGET_LINK_LIBRARIES (${source_file_we} PRIVATE
|
TARGET_LINK_LIBRARIES (${source_file_we} PRIVATE
|
||||||
msgpack-cxx
|
msgpack-cxx
|
||||||
|
Boost::system
|
||||||
Threads::Threads
|
Threads::Threads
|
||||||
)
|
)
|
||||||
IF (ZLIB_FOUND)
|
IF (ZLIB_FOUND)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
IF (MSGPACK_USE_X3_PARSE AND MSGPACK_DEFAULT_API_VERSION VERSION_GREATER 1)
|
IF (MSGPACK_USE_X3_PARSE AND MSGPACK_DEFAULT_API_VERSION VERSION_GREATER 1)
|
||||||
FIND_PACKAGE (Boost REQUIRED COMPONENTS context)
|
FIND_PACKAGE (Boost REQUIRED COMPONENTS context system)
|
||||||
FIND_PACKAGE (Threads REQUIRED)
|
FIND_PACKAGE (Threads REQUIRED)
|
||||||
|
|
||||||
LIST (APPEND exec_PROGRAMS
|
LIST (APPEND exec_PROGRAMS
|
||||||
@ -42,6 +42,7 @@ IF (MSGPACK_USE_X3_PARSE AND MSGPACK_DEFAULT_API_VERSION VERSION_GREATER 1)
|
|||||||
TARGET_LINK_LIBRARIES (${source_file_we} PRIVATE
|
TARGET_LINK_LIBRARIES (${source_file_we} PRIVATE
|
||||||
msgpack-cxx
|
msgpack-cxx
|
||||||
Boost::context
|
Boost::context
|
||||||
|
Boost::system
|
||||||
Threads::Threads
|
Threads::Threads
|
||||||
)
|
)
|
||||||
IF ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
IF ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
FIND_PACKAGE (Threads REQUIRED)
|
FIND_PACKAGE (Threads REQUIRED)
|
||||||
FIND_PACKAGE (Boost REQUIRED COMPONENTS filesystem unit_test_framework)
|
FIND_PACKAGE (Boost REQUIRED COMPONENTS system filesystem unit_test_framework)
|
||||||
|
|
||||||
LIST (APPEND check_PROGRAMS
|
LIST (APPEND check_PROGRAMS
|
||||||
regression_runner.cpp
|
regression_runner.cpp
|
||||||
@ -19,6 +19,7 @@ FOREACH (source_file ${check_PROGRAMS})
|
|||||||
msgpack-cxx
|
msgpack-cxx
|
||||||
Threads::Threads
|
Threads::Threads
|
||||||
Boost::filesystem
|
Boost::filesystem
|
||||||
|
Boost::system
|
||||||
Boost::unit_test_framework
|
Boost::unit_test_framework
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,101 +29,121 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
|||||||
|
|
||||||
class zone {
|
class zone {
|
||||||
struct finalizer {
|
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 operator()() { m_func(m_data); }
|
||||||
void (*m_func)(void*);
|
void (*m_func)(void*);
|
||||||
void* m_data;
|
void* m_data;
|
||||||
finalizer* m_next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct finalizer_array {
|
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() {
|
~finalizer_array() {
|
||||||
clear();
|
call();
|
||||||
|
::free(m_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
finalizer* fin = m_head;
|
call();
|
||||||
finalizer* tmp = MSGPACK_NULLPTR;
|
m_tail = m_array;
|
||||||
while(fin) {
|
|
||||||
(*fin)();
|
|
||||||
tmp = fin;
|
|
||||||
fin = fin->m_next;
|
|
||||||
delete tmp;
|
|
||||||
}
|
}
|
||||||
m_head = MSGPACK_NULLPTR;
|
void push(void (*func)(void* data), void* data)
|
||||||
|
{
|
||||||
|
finalizer* fin = m_tail;
|
||||||
|
|
||||||
|
if(fin == m_end) {
|
||||||
|
push_expand(func, data);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(void (*func)(void* data), void* data) {
|
fin->m_func = func;
|
||||||
m_head = new finalizer(func, data, m_head);
|
fin->m_data = data;
|
||||||
}
|
|
||||||
|
|
||||||
void pop() {
|
++m_tail;
|
||||||
finalizer* n = m_head->m_next;
|
|
||||||
delete m_head;
|
|
||||||
m_head = n;
|
|
||||||
}
|
}
|
||||||
|
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;
|
++m_tail;
|
||||||
private:
|
}
|
||||||
finalizer_array(const finalizer_array&);
|
finalizer* m_tail;
|
||||||
finalizer_array& operator=(const finalizer_array&);
|
finalizer* m_end;
|
||||||
|
finalizer* m_array;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chunk {
|
struct chunk {
|
||||||
chunk* m_next;
|
chunk* m_next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chunk_list {
|
struct chunk_list {
|
||||||
chunk_list(size_t chunk_size, char* ptr): m_free(chunk_size), m_ptr(ptr), m_head(MSGPACK_NULLPTR) {}
|
chunk_list(size_t chunk_size)
|
||||||
~chunk_list() {
|
{
|
||||||
chunk* c = m_head;
|
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
|
||||||
while(c) {
|
if(!c) {
|
||||||
chunk* n = c->m_next;
|
throw std::bad_alloc();
|
||||||
::free(c);
|
|
||||||
c = n;
|
|
||||||
}
|
|
||||||
m_head = MSGPACK_NULLPTR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear(size_t chunk_size, char* ptr) {
|
m_head = c;
|
||||||
chunk* c = m_head;
|
|
||||||
while(c) {
|
|
||||||
chunk* n = c->m_next;
|
|
||||||
::free(c);
|
|
||||||
c = n;
|
|
||||||
}
|
|
||||||
m_head = MSGPACK_NULLPTR;
|
|
||||||
m_free = chunk_size;
|
m_free = chunk_size;
|
||||||
m_ptr = ptr;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void clear(size_t chunk_size)
|
||||||
|
{
|
||||||
|
chunk* c = m_head;
|
||||||
|
while(true) {
|
||||||
|
chunk* n = c->m_next;
|
||||||
|
if(n) {
|
||||||
|
::free(c);
|
||||||
|
c = n;
|
||||||
|
} else {
|
||||||
|
m_head = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_head->m_next = MSGPACK_NULLPTR;
|
||||||
|
m_free = chunk_size;
|
||||||
|
m_ptr = reinterpret_cast<char*>(m_head) + sizeof(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t m_free;
|
size_t m_free;
|
||||||
char* m_ptr;
|
char* m_ptr;
|
||||||
chunk* m_head;
|
chunk* m_head;
|
||||||
|
|
||||||
private:
|
|
||||||
chunk_list(const chunk_list&);
|
|
||||||
chunk_list& operator=(const chunk_list&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t m_chunk_size;
|
size_t m_chunk_size;
|
||||||
chunk_list* m_chunk_list;
|
chunk_list m_chunk_list;
|
||||||
finalizer_array m_finalizer_array;
|
finalizer_array m_finalizer_array;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE);
|
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_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN);
|
||||||
|
|
||||||
void* allocate_no_align(size_t size);
|
void* allocate_no_align(size_t size);
|
||||||
|
|
||||||
bool allocated() {
|
|
||||||
return m_chunk_list != MSGPACK_NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_finalizer(void (*func)(void*), void* data);
|
void push_finalizer(void (*func)(void*), void* data);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -132,23 +152,24 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void swap(zone& o);
|
void swap(zone& o);
|
||||||
|
static void* operator new(std::size_t size)
|
||||||
static void* operator new(std::size_t size) {
|
{
|
||||||
void* p = ::malloc(size);
|
void* p = ::malloc(size);
|
||||||
if (!p) throw std::bad_alloc();
|
if (!p) throw std::bad_alloc();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
static void operator delete(void *p) /* throw() */
|
||||||
static void operator delete(void *p) /* throw() */ {
|
{
|
||||||
::free(p);
|
::free(p);
|
||||||
}
|
}
|
||||||
|
static void* operator new(std::size_t size, void* place) /* throw() */
|
||||||
static void* operator new(std::size_t /*size*/, void* mem) /* throw() */ {
|
{
|
||||||
return mem;
|
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
|
/// @cond
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -212,26 +233,18 @@ private:
|
|||||||
|
|
||||||
static char* get_aligned(char* ptr, size_t align);
|
static char* get_aligned(char* ptr, size_t align);
|
||||||
|
|
||||||
chunk_list& get_chank_lst();
|
|
||||||
|
|
||||||
char* allocate_expand(size_t size);
|
char* allocate_expand(size_t size);
|
||||||
private:
|
private:
|
||||||
zone(const zone&);
|
zone(const zone&);
|
||||||
zone& operator=(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(size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
|
||||||
|
{
|
||||||
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 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)
|
MSGPACK_ASSERT(align != 0 && (align & (align - 1)) == 0); // align must be 2^n (n >= 0)
|
||||||
return
|
return
|
||||||
reinterpret_cast<char*>(
|
reinterpret_cast<char*>(
|
||||||
@ -239,45 +252,37 @@ inline char* zone::get_aligned(char* ptr, size_t align) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline zone::chunk_list& zone::get_chank_lst() {
|
inline void* zone::allocate_align(size_t size, size_t align)
|
||||||
if (!m_chunk_list) {
|
{
|
||||||
void* ptr = ::malloc(sizeof(chunk_list) + m_chunk_size);
|
char* aligned = get_aligned(m_chunk_list.m_ptr, align);
|
||||||
if (!ptr)
|
size_t adjusted_size = size + static_cast<size_t>(aligned - m_chunk_list.m_ptr);
|
||||||
throw std::bad_alloc();
|
if (m_chunk_list.m_free < adjusted_size) {
|
||||||
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) {
|
|
||||||
size_t enough_size = size + align - 1;
|
size_t enough_size = size + align - 1;
|
||||||
char* ptr = allocate_expand(enough_size);
|
char* ptr = allocate_expand(enough_size);
|
||||||
aligned = get_aligned(ptr, align);
|
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;
|
m_chunk_list.m_free -= adjusted_size;
|
||||||
chank_lst.m_ptr += adjusted_size;
|
m_chunk_list.m_ptr += adjusted_size;
|
||||||
return aligned;
|
return aligned;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void* zone::allocate_no_align(size_t size) {
|
inline void* zone::allocate_no_align(size_t size)
|
||||||
chunk_list& chank_lst = get_chank_lst();
|
{
|
||||||
char* ptr = chank_lst.m_ptr;
|
char* ptr = m_chunk_list.m_ptr;
|
||||||
if(chank_lst.m_free < size) {
|
if(m_chunk_list.m_free < size) {
|
||||||
ptr = allocate_expand(size);
|
ptr = allocate_expand(size);
|
||||||
}
|
}
|
||||||
chank_lst.m_free -= size;
|
m_chunk_list.m_free -= size;
|
||||||
chank_lst.m_ptr += size;
|
m_chunk_list.m_ptr += size;
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline char* zone::allocate_expand(size_t size) {
|
inline char* zone::allocate_expand(size_t size)
|
||||||
chunk_list& cl = get_chank_lst();
|
{
|
||||||
|
chunk_list* const cl = &m_chunk_list;
|
||||||
|
|
||||||
size_t sz = m_chunk_size;
|
size_t sz = m_chunk_size;
|
||||||
|
|
||||||
while(sz < size) {
|
while(sz < size) {
|
||||||
@ -294,54 +299,60 @@ inline char* zone::allocate_expand(size_t size) {
|
|||||||
|
|
||||||
char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
|
char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
|
||||||
|
|
||||||
c->m_next = cl.m_head;
|
c->m_next = cl->m_head;
|
||||||
cl.m_head = c;
|
cl->m_head = c;
|
||||||
cl.m_free = sz;
|
cl->m_free = sz;
|
||||||
cl.m_ptr = ptr;
|
cl->m_ptr = ptr;
|
||||||
|
|
||||||
return 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);
|
m_finalizer_array.push(func, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
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());
|
m_finalizer_array.push(&zone::object_delete<T>, obj.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void zone::clear() {
|
inline void zone::clear()
|
||||||
|
{
|
||||||
m_finalizer_array.clear();
|
m_finalizer_array.clear();
|
||||||
if (m_chunk_list) {
|
m_chunk_list.clear(m_chunk_size);
|
||||||
m_chunk_list->clear(m_chunk_size, reinterpret_cast<char*>(m_chunk_list) + sizeof(chunk_list));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void zone::swap(zone& o) {
|
inline void zone::swap(zone& o)
|
||||||
|
{
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(m_chunk_size, o.m_chunk_size);
|
swap(m_chunk_size, o.m_chunk_size);
|
||||||
swap(m_chunk_list, o.m_chunk_list);
|
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>
|
template <typename T>
|
||||||
void zone::object_delete(void* obj) {
|
void zone::object_destruct(void* obj)
|
||||||
delete static_cast<T*>(obj);
|
{
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void zone::object_destruct(void* obj) {
|
|
||||||
static_cast<T*>(obj)->~T();
|
static_cast<T*>(obj)->~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void zone::undo_allocate(size_t size) {
|
template <typename T>
|
||||||
chunk_list& cl = get_chank_lst();
|
void zone::object_delete(void* obj)
|
||||||
cl.m_ptr -= size;
|
{
|
||||||
cl.m_free += size;
|
delete static_cast<T*>(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::size_t aligned_size(std::size_t size, std::size_t align) {
|
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) {
|
||||||
return (size + align - 1) / align * align;
|
return (size + align - 1) / align * align;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,7 +371,7 @@ T* zone::allocate()
|
|||||||
try {
|
try {
|
||||||
return new (x) T();
|
return new (x) T();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -379,7 +390,7 @@ T* zone::allocate(A1 a1)
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1);
|
return new (x) T(a1);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -398,7 +409,7 @@ T* zone::allocate(A1 a1, A2 a2)
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2);
|
return new (x) T(a1, a2);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -417,7 +428,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3)
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2, a3);
|
return new (x) T(a1, a2, a3);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -436,7 +447,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4)
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2, a3, a4);
|
return new (x) T(a1, a2, a3, a4);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -455,7 +466,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2, a3, a4, a5);
|
return new (x) T(a1, a2, a3, a4, a5);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -474,7 +485,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2, a3, a4, a5, a6);
|
return new (x) T(a1, a2, a3, a4, a5, a6);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -493,7 +504,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2, a3, a4, a5, a6, a7);
|
return new (x) T(a1, a2, a3, a4, a5, a6, a7);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -512,7 +523,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8);
|
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -531,7 +542,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -550,7 +561,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
|
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -569,7 +580,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -588,7 +599,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -607,7 +618,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13);
|
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -626,7 +637,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14);
|
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
@ -645,7 +656,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
|
|||||||
try {
|
try {
|
||||||
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15);
|
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
@ -29,113 +29,154 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
|||||||
class zone {
|
class zone {
|
||||||
private:
|
private:
|
||||||
struct finalizer {
|
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 operator()() { m_func(m_data); }
|
||||||
void (*m_func)(void*);
|
void (*m_func)(void*);
|
||||||
void* m_data;
|
void* m_data;
|
||||||
finalizer* m_next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct finalizer_array {
|
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() {
|
~finalizer_array() {
|
||||||
clear();
|
call();
|
||||||
|
::free(m_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
finalizer* fin = m_head;
|
call();
|
||||||
finalizer* tmp = MSGPACK_NULLPTR;
|
m_tail = m_array;
|
||||||
while(fin) {
|
|
||||||
(*fin)();
|
|
||||||
tmp = fin;
|
|
||||||
fin = fin->m_next;
|
|
||||||
delete tmp;
|
|
||||||
}
|
}
|
||||||
m_head = MSGPACK_NULLPTR;
|
void push(void (*func)(void* data), void* data)
|
||||||
|
{
|
||||||
|
finalizer* fin = m_tail;
|
||||||
|
|
||||||
|
if(fin == m_end) {
|
||||||
|
push_expand(func, data);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(void (*func)(void* data), void* data) {
|
fin->m_func = func;
|
||||||
m_head = new finalizer(func, data, m_head);
|
fin->m_data = data;
|
||||||
}
|
|
||||||
|
|
||||||
void pop() {
|
++m_tail;
|
||||||
auto n = m_head->m_next;
|
|
||||||
delete m_head;
|
|
||||||
m_head = n;
|
|
||||||
}
|
}
|
||||||
|
void push_expand(void (*func)(void*), void* data) {
|
||||||
finalizer_array(finalizer_array&& other) noexcept: m_head(other.m_head) {
|
const size_t nused = static_cast<size_t>(m_end - m_array);
|
||||||
other.m_head = MSGPACK_NULLPTR;
|
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_array& operator=(finalizer_array&& other) noexcept {
|
++m_tail;
|
||||||
m_head = other.m_head;
|
}
|
||||||
other.m_head = MSGPACK_NULLPTR;
|
finalizer_array(finalizer_array&& other) noexcept
|
||||||
|
:m_tail(other.m_tail), m_end(other.m_end), m_array(other.m_array)
|
||||||
|
{
|
||||||
|
other.m_tail = MSGPACK_NULLPTR;
|
||||||
|
other.m_end = MSGPACK_NULLPTR;
|
||||||
|
other.m_array = MSGPACK_NULLPTR;
|
||||||
|
}
|
||||||
|
finalizer_array& operator=(finalizer_array&& other) noexcept
|
||||||
|
{
|
||||||
|
this->~finalizer_array();
|
||||||
|
new (this) finalizer_array(std::move(other));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finalizer* m_tail;
|
||||||
|
finalizer* m_end;
|
||||||
|
finalizer* m_array;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
finalizer* m_head;
|
|
||||||
finalizer_array(const finalizer_array&);
|
finalizer_array(const finalizer_array&);
|
||||||
finalizer_array& operator=(const finalizer_array&);
|
finalizer_array& operator=(const finalizer_array&);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chunk {
|
struct chunk {
|
||||||
chunk* m_next;
|
chunk* m_next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chunk_list {
|
struct chunk_list {
|
||||||
chunk_list(size_t chunk_size, char* ptr): m_free(chunk_size), m_ptr(ptr), m_head(MSGPACK_NULLPTR) {}
|
chunk_list(size_t chunk_size)
|
||||||
~chunk_list() {
|
{
|
||||||
chunk* c = m_head;
|
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
|
||||||
while(c) {
|
if(!c) {
|
||||||
chunk* n = c->m_next;
|
throw std::bad_alloc();
|
||||||
::free(c);
|
|
||||||
c = n;
|
|
||||||
}
|
|
||||||
m_head = MSGPACK_NULLPTR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear(size_t chunk_size, char* ptr) {
|
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;
|
chunk* c = m_head;
|
||||||
while(c) {
|
while(c) {
|
||||||
chunk* n = c->m_next;
|
chunk* n = c->m_next;
|
||||||
::free(c);
|
::free(c);
|
||||||
c = n;
|
c = n;
|
||||||
}
|
}
|
||||||
m_head = MSGPACK_NULLPTR;
|
}
|
||||||
|
void clear(size_t chunk_size)
|
||||||
|
{
|
||||||
|
chunk* c = m_head;
|
||||||
|
while(true) {
|
||||||
|
chunk* n = c->m_next;
|
||||||
|
if(n) {
|
||||||
|
::free(c);
|
||||||
|
c = n;
|
||||||
|
} else {
|
||||||
|
m_head = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_head->m_next = MSGPACK_NULLPTR;
|
||||||
m_free = chunk_size;
|
m_free = chunk_size;
|
||||||
m_ptr = ptr;
|
m_ptr = reinterpret_cast<char*>(m_head) + sizeof(chunk);
|
||||||
|
}
|
||||||
|
chunk_list(chunk_list&& other) noexcept
|
||||||
|
:m_free(other.m_free), m_ptr(other.m_ptr), m_head(other.m_head)
|
||||||
|
{
|
||||||
|
other.m_head = MSGPACK_NULLPTR;
|
||||||
|
}
|
||||||
|
chunk_list& operator=(chunk_list&& other) noexcept
|
||||||
|
{
|
||||||
|
this->~chunk_list();
|
||||||
|
new (this) chunk_list(std::move(other));
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t m_free;
|
size_t m_free;
|
||||||
char* m_ptr;
|
char* m_ptr;
|
||||||
chunk* m_head;
|
chunk* m_head;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
chunk_list(chunk_list&& other) noexcept = delete;
|
|
||||||
chunk_list& operator=(chunk_list&& other) noexcept = delete;
|
|
||||||
chunk_list(const chunk_list&);
|
chunk_list(const chunk_list&);
|
||||||
chunk_list& operator=(const chunk_list&);
|
chunk_list& operator=(const chunk_list&);
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t m_chunk_size;
|
size_t m_chunk_size;
|
||||||
chunk_list* m_chunk_list{};
|
chunk_list m_chunk_list;
|
||||||
finalizer_array m_finalizer_array;
|
finalizer_array m_finalizer_array;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE);
|
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_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN);
|
||||||
|
|
||||||
void* allocate_no_align(size_t size);
|
void* allocate_no_align(size_t size);
|
||||||
|
|
||||||
bool allocated() {
|
|
||||||
return m_chunk_list != MSGPACK_NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_finalizer(void (*func)(void*), void* data);
|
void push_finalizer(void (*func)(void*), void* data);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -145,21 +186,23 @@ public:
|
|||||||
|
|
||||||
void swap(zone& o);
|
void swap(zone& o);
|
||||||
|
|
||||||
static void* operator new(std::size_t size) {
|
static void* operator new(std::size_t size)
|
||||||
|
{
|
||||||
void* p = ::malloc(size);
|
void* p = ::malloc(size);
|
||||||
if (!p) throw std::bad_alloc();
|
if (!p) throw std::bad_alloc();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
static void operator delete(void *p) noexcept
|
||||||
static void operator delete(void *p) noexcept {
|
{
|
||||||
::free(p);
|
::free(p);
|
||||||
}
|
}
|
||||||
|
static void* operator new(std::size_t /*size*/, void* mem) noexcept
|
||||||
static void* operator new(std::size_t /*size*/, void* mem) noexcept {
|
{
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
static void operator delete(void * /*p*/, void* /*mem*/) noexcept
|
||||||
static void operator delete(void * /*p*/, void* /*mem*/) noexcept {}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
T* allocate(Args... args);
|
T* allocate(Args... args);
|
||||||
@ -180,23 +223,15 @@ private:
|
|||||||
|
|
||||||
static char* get_aligned(char* ptr, size_t align);
|
static char* get_aligned(char* ptr, size_t align);
|
||||||
|
|
||||||
chunk_list& get_chank_lst();
|
|
||||||
|
|
||||||
char* allocate_expand(size_t size);
|
char* allocate_expand(size_t size);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline zone::zone(size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(MSGPACK_NULLPTR) {}
|
inline zone::zone(size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
|
||||||
|
{
|
||||||
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 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)
|
MSGPACK_ASSERT(align != 0 && (align & (align - 1)) == 0); // align must be 2^n (n >= 0)
|
||||||
return
|
return
|
||||||
reinterpret_cast<char*>(
|
reinterpret_cast<char*>(
|
||||||
@ -204,45 +239,37 @@ inline char* zone::get_aligned(char* ptr, size_t align) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline zone::chunk_list& zone::get_chank_lst() {
|
inline void* zone::allocate_align(size_t size, size_t align)
|
||||||
if (!m_chunk_list) {
|
{
|
||||||
auto ptr = ::malloc(sizeof(chunk_list) + m_chunk_size);
|
char* aligned = get_aligned(m_chunk_list.m_ptr, align);
|
||||||
if (!ptr)
|
size_t adjusted_size = size + static_cast<size_t>(aligned - m_chunk_list.m_ptr);
|
||||||
throw std::bad_alloc();
|
if (m_chunk_list.m_free < adjusted_size) {
|
||||||
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) {
|
|
||||||
size_t enough_size = size + align - 1;
|
size_t enough_size = size + align - 1;
|
||||||
char* ptr = allocate_expand(enough_size);
|
char* ptr = allocate_expand(enough_size);
|
||||||
aligned = get_aligned(ptr, align);
|
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;
|
m_chunk_list.m_free -= adjusted_size;
|
||||||
chank_lst.m_ptr += adjusted_size;
|
m_chunk_list.m_ptr += adjusted_size;
|
||||||
return aligned;
|
return aligned;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void* zone::allocate_no_align(size_t size) {
|
inline void* zone::allocate_no_align(size_t size)
|
||||||
chunk_list& chank_lst = get_chank_lst();
|
{
|
||||||
char* ptr = chank_lst.m_ptr;
|
char* ptr = m_chunk_list.m_ptr;
|
||||||
if(chank_lst.m_free < size) {
|
if(m_chunk_list.m_free < size) {
|
||||||
ptr = allocate_expand(size);
|
ptr = allocate_expand(size);
|
||||||
}
|
}
|
||||||
chank_lst.m_free -= size;
|
m_chunk_list.m_free -= size;
|
||||||
chank_lst.m_ptr += size;
|
m_chunk_list.m_ptr += size;
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline char* zone::allocate_expand(size_t size) {
|
inline char* zone::allocate_expand(size_t size)
|
||||||
chunk_list& cl = get_chank_lst();
|
{
|
||||||
|
chunk_list* const cl = &m_chunk_list;
|
||||||
|
|
||||||
size_t sz = m_chunk_size;
|
size_t sz = m_chunk_size;
|
||||||
|
|
||||||
while(sz < size) {
|
while(sz < size) {
|
||||||
@ -259,56 +286,58 @@ inline char* zone::allocate_expand(size_t size) {
|
|||||||
|
|
||||||
char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
|
char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
|
||||||
|
|
||||||
c->m_next = cl.m_head;
|
c->m_next = cl->m_head;
|
||||||
cl.m_head = c;
|
cl->m_head = c;
|
||||||
cl.m_free = sz;
|
cl->m_free = sz;
|
||||||
cl.m_ptr = ptr;
|
cl->m_ptr = ptr;
|
||||||
|
|
||||||
return 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);
|
m_finalizer_array.push(func, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
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());
|
m_finalizer_array.push(&zone::object_delete<T>, obj.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void zone::clear() {
|
inline void zone::clear()
|
||||||
|
{
|
||||||
m_finalizer_array.clear();
|
m_finalizer_array.clear();
|
||||||
if (m_chunk_list) {
|
m_chunk_list.clear(m_chunk_size);
|
||||||
m_chunk_list->clear(m_chunk_size, reinterpret_cast<char*>(m_chunk_list) + sizeof(chunk_list));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void zone::swap(zone& o) {
|
inline void zone::swap(zone& o)
|
||||||
|
{
|
||||||
std::swap(*this, o);
|
std::swap(*this, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void zone::object_delete(void* obj) {
|
void zone::object_delete(void* obj)
|
||||||
|
{
|
||||||
delete static_cast<T*>(obj);
|
delete static_cast<T*>(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void zone::object_destruct(void* obj) {
|
void zone::object_destruct(void* obj)
|
||||||
|
{
|
||||||
static_cast<T*>(obj)->~T();
|
static_cast<T*>(obj)->~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void zone::undo_allocate(size_t size) {
|
inline void zone::undo_allocate(size_t size)
|
||||||
chunk_list& cl = get_chank_lst();
|
{
|
||||||
cl.m_ptr -= size;
|
m_chunk_list.m_ptr -= size;
|
||||||
cl.m_free += size;
|
m_chunk_list.m_free += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::size_t aligned_size(std::size_t size, std::size_t align) {
|
|
||||||
return (size + align - 1) / align * align;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
T* zone::allocate(Args... args) {
|
T* zone::allocate(Args... args)
|
||||||
|
{
|
||||||
void* x = allocate_align(sizeof(T), MSGPACK_ZONE_ALIGNOF(T));
|
void* x = allocate_align(sizeof(T), MSGPACK_ZONE_ALIGNOF(T));
|
||||||
try {
|
try {
|
||||||
m_finalizer_array.push(&zone::object_destruct<T>, x);
|
m_finalizer_array.push(&zone::object_destruct<T>, x);
|
||||||
@ -319,12 +348,18 @@ T* zone::allocate(Args... args) {
|
|||||||
try {
|
try {
|
||||||
return new (x) T(args...);
|
return new (x) T(args...);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_finalizer_array.pop();
|
--m_finalizer_array.m_tail;
|
||||||
undo_allocate(sizeof(T));
|
undo_allocate(sizeof(T));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::size_t aligned_size(
|
||||||
|
std::size_t size,
|
||||||
|
std::size_t align) {
|
||||||
|
return (size + align - 1) / align * align;
|
||||||
|
}
|
||||||
|
|
||||||
/// @cond
|
/// @cond
|
||||||
} // MSGPACK_API_VERSION_NAMESPACE(v1)
|
} // MSGPACK_API_VERSION_NAMESPACE(v1)
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
require 'erb'
|
|
||||||
|
|
||||||
files = {
|
|
||||||
"erb/v1/cpp03_msgpack_tuple_decl.hpp" => "include/msgpack/v1/adaptor/detail/cpp03_msgpack_tuple_decl.hpp",
|
|
||||||
"erb/v1/cpp03_msgpack_tuple.hpp" => "include/msgpack/v1/adaptor/detail/cpp03_msgpack_tuple.hpp",
|
|
||||||
"erb/v1/cpp03_define_array_decl.hpp" => "include/msgpack/v1/adaptor/detail/cpp03_define_array_decl.hpp",
|
|
||||||
"erb/v1/cpp03_define_array.hpp" => "include/msgpack/v1/adaptor/detail/cpp03_define_array.hpp",
|
|
||||||
"erb/v1/cpp03_define_map_decl.hpp" => "include/msgpack/v1/adaptor/detail/cpp03_define_map_decl.hpp",
|
|
||||||
"erb/v1/cpp03_define_map.hpp" => "include/msgpack/v1/adaptor/detail/cpp03_define_map.hpp",
|
|
||||||
"erb/v1/cpp03_zone_decl.hpp" => "include/msgpack/v1/detail/cpp03_zone_decl.hpp",
|
|
||||||
"erb/v1/cpp03_zone.hpp" => "include/msgpack/v1/detail/cpp03_zone.hpp"
|
|
||||||
}
|
|
||||||
|
|
||||||
files.map { |erb, hpp|
|
|
||||||
res = ERB.new(File.open(erb+".erb").read).result
|
|
||||||
File.write(hpp, res)
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
FIND_PACKAGE (Threads REQUIRED)
|
FIND_PACKAGE (Threads REQUIRED)
|
||||||
FIND_PACKAGE (ZLIB)
|
FIND_PACKAGE (ZLIB)
|
||||||
FIND_PACKAGE (Boost REQUIRED COMPONENTS unit_test_framework)
|
FIND_PACKAGE (Boost REQUIRED COMPONENTS unit_test_framework system)
|
||||||
|
|
||||||
LIST (APPEND check_PROGRAMS
|
LIST (APPEND check_PROGRAMS
|
||||||
array_ref.cpp
|
array_ref.cpp
|
||||||
@ -79,6 +79,7 @@ FOREACH (source_file ${check_PROGRAMS})
|
|||||||
|
|
||||||
TARGET_LINK_LIBRARIES (${source_file_we}
|
TARGET_LINK_LIBRARIES (${source_file_we}
|
||||||
msgpack-cxx
|
msgpack-cxx
|
||||||
|
Boost::system
|
||||||
Boost::unit_test_framework
|
Boost::unit_test_framework
|
||||||
Threads::Threads
|
Threads::Threads
|
||||||
ZLIB::ZLIB
|
ZLIB::ZLIB
|
||||||
|
Loading…
x
Reference in New Issue
Block a user