From 240b02174defb84a7383ab24af5afa280e274111 Mon Sep 17 00:00:00 2001 From: Takatoshi Kondo Date: Fri, 5 Dec 2014 20:46:56 +0900 Subject: [PATCH] Fixed zone allocate alignment problem. --- erb/cpp03_zone.hpp.erb | 19 +++++++++++++++---- include/msgpack/detail/cpp03_zone.hpp | 19 +++++++++++++++---- include/msgpack/detail/cpp11_zone.hpp | 19 +++++++++++++++---- include/msgpack/zone.h | 22 +++++++++++++++++++--- 4 files changed, 64 insertions(+), 15 deletions(-) diff --git a/erb/cpp03_zone.hpp.erb b/erb/cpp03_zone.hpp.erb index c64273ad..f8f96cf1 100644 --- a/erb/cpp03_zone.hpp.erb +++ b/erb/cpp03_zone.hpp.erb @@ -150,7 +150,7 @@ public: zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE) /* throw() */; public: - void* allocate_align(size_t size); + void* allocate_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN); void* allocate_no_align(size_t size); void push_finalizer(void (*func)(void*), void* data); @@ -203,10 +203,21 @@ inline zone::zone(size_t chunk_size) /* throw() */ :m_chunk_size(chunk_size), m_ { } -inline void* zone::allocate_align(size_t size) +inline void* zone::allocate_align(size_t size, size_t align) { - return allocate_no_align( - ((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1)); + char* aligned = + reinterpret_cast( + reinterpret_cast( + (m_chunk_list.m_ptr + (align - 1))) / align * align); + size_t adjusted_size = size + (aligned - m_chunk_list.m_ptr); + if(m_chunk_list.m_free >= adjusted_size) { + m_chunk_list.m_free -= adjusted_size; + m_chunk_list.m_ptr += adjusted_size; + return aligned; + } + return reinterpret_cast( + reinterpret_cast( + allocate_expand(size + (align - 1))) / align * align); } inline void* zone::allocate_no_align(size_t size) diff --git a/include/msgpack/detail/cpp03_zone.hpp b/include/msgpack/detail/cpp03_zone.hpp index adc8e78e..880544c1 100644 --- a/include/msgpack/detail/cpp03_zone.hpp +++ b/include/msgpack/detail/cpp03_zone.hpp @@ -150,7 +150,7 @@ public: zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE) /* throw() */; public: - void* allocate_align(size_t size); + void* allocate_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN); void* allocate_no_align(size_t size); void push_finalizer(void (*func)(void*), void* data); @@ -248,10 +248,21 @@ inline zone::zone(size_t chunk_size) /* throw() */ :m_chunk_size(chunk_size), m_ { } -inline void* zone::allocate_align(size_t size) +inline void* zone::allocate_align(size_t size, size_t align) { - return allocate_no_align( - ((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1)); + char* aligned = + reinterpret_cast( + reinterpret_cast( + (m_chunk_list.m_ptr + (align - 1))) / align * align); + size_t adjusted_size = size + (aligned - m_chunk_list.m_ptr); + if(m_chunk_list.m_free >= adjusted_size) { + m_chunk_list.m_free -= adjusted_size; + m_chunk_list.m_ptr += adjusted_size; + return aligned; + } + return reinterpret_cast( + reinterpret_cast( + allocate_expand(size + (align - 1))) / align * align); } inline void* zone::allocate_no_align(size_t size) diff --git a/include/msgpack/detail/cpp11_zone.hpp b/include/msgpack/detail/cpp11_zone.hpp index 2ce7aae3..0c0e2efd 100644 --- a/include/msgpack/detail/cpp11_zone.hpp +++ b/include/msgpack/detail/cpp11_zone.hpp @@ -188,7 +188,7 @@ public: zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE) noexcept; public: - void* allocate_align(size_t size); + void* allocate_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN); void* allocate_no_align(size_t size); void push_finalizer(void (*func)(void*), void* data); @@ -243,10 +243,21 @@ inline zone::zone(size_t chunk_size) noexcept:m_chunk_size(chunk_size), m_chunk_ { } -inline void* zone::allocate_align(size_t size) +inline void* zone::allocate_align(size_t size, size_t align) { - return allocate_no_align( - ((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1)); + char* aligned = + reinterpret_cast( + reinterpret_cast( + (m_chunk_list.m_ptr + (align - 1))) / align * align); + size_t adjusted_size = size + (aligned - m_chunk_list.m_ptr); + if(m_chunk_list.m_free >= adjusted_size) { + m_chunk_list.m_free -= adjusted_size; + m_chunk_list.m_ptr += adjusted_size; + return aligned; + } + return reinterpret_cast( + reinterpret_cast( + allocate_expand(size + (align - 1))) / align * align); } inline void* zone::allocate_no_align(size_t size) diff --git a/include/msgpack/zone.h b/include/msgpack/zone.h index 05e6bc8d..572185ce 100644 --- a/include/msgpack/zone.h +++ b/include/msgpack/zone.h @@ -113,8 +113,25 @@ void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size) static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size) { - return msgpack_zone_malloc_no_align(zone, - ((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1)); + char* aligned = + (char*)( + (size_t)( + zone->chunk_list.ptr + (MSGPACK_ZONE_ALIGN - 1) + ) / MSGPACK_ZONE_ALIGN * MSGPACK_ZONE_ALIGN + ); + size_t adjusted_size = size + (aligned - zone->chunk_list.ptr); + if(zone->chunk_list.free >= adjusted_size) { + zone->chunk_list.free -= adjusted_size; + zone->chunk_list.ptr += adjusted_size; + return aligned; + } + { + void* ptr = msgpack_zone_malloc_expand(zone, size + (MSGPACK_ZONE_ALIGN - 1)); + if (ptr) { + return (char*)((size_t)(ptr) / MSGPACK_ZONE_ALIGN * MSGPACK_ZONE_ALIGN); + } + } + return NULL; } @@ -152,4 +169,3 @@ static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b) #endif #endif /* msgpack/zone.h */ -