Skip to content
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
8 changes: 7 additions & 1 deletion include/msgpack/zone.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,13 @@ static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size)
{
void* ptr = msgpack_zone_malloc_expand(zone, size + (MSGPACK_ZONE_ALIGN - 1));
if (ptr) {
return (char*)((uintptr_t)(ptr) & ~(uintptr_t)(MSGPACK_ZONE_ALIGN - 1));
/* round up into the padding reserved above; rounding down
* would hand out the new chunk's header */
return (char*)(
(uintptr_t)(
(char*)ptr + (MSGPACK_ZONE_ALIGN - 1)
) & ~(uintptr_t)(MSGPACK_ZONE_ALIGN - 1)
);
}
}
return NULL;
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ SET (check_PROGRAMS
msgpack_c.cpp
pack_unpack_c.cpp
streaming_c.cpp
zone_align_c.cpp
zone_c.cpp
)

Expand Down
29 changes: 29 additions & 0 deletions test/zone_align_c.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* msgpack_zone_malloc() is inline, so its alignment is fixed per translation
* unit. Use one stricter than the zone chunk header, as CMakeLists.txt does
* on sparc (MSGPACK_ZONE_ALIGN=8 with a 4-byte header), so that an object
* served from a newly expanded chunk needs padding. */
#undef MSGPACK_ZONE_ALIGN
#define MSGPACK_ZONE_ALIGN (2 * sizeof(void*))

#include <msgpack/zone.h>

#include <gtest/gtest.h>

#include <string.h>

TEST(zone, zone_c_malloc_expand_align)
{
msgpack_zone z;
const size_t size = 4096;
EXPECT_TRUE(msgpack_zone_init(&z, 2048));
/* larger than the chunk size: served by msgpack_zone_malloc_expand() */
char* p = (char*)msgpack_zone_malloc(&z, size);
ASSERT_TRUE(p != NULL);
EXPECT_TRUE((uintptr_t)p % MSGPACK_ZONE_ALIGN == 0);
/* the object has to stay inside the size + MSGPACK_ZONE_ALIGN - 1 bytes
* reserved by the expansion, not overlap the new chunk's header */
ASSERT_TRUE(p >= z.chunk_list.ptr - (size + MSGPACK_ZONE_ALIGN - 1));
ASSERT_TRUE(p + size <= z.chunk_list.ptr);
memset(p, 0xff, size);
msgpack_zone_destroy(&z);
}
Loading