[CP] support alloc_align/free_align for ObIAllocator
This commit is contained in:
53
deps/oblib/src/lib/allocator/ob_allocator.h
vendored
53
deps/oblib/src/lib/allocator/ob_allocator.h
vendored
@ -21,6 +21,45 @@ namespace oceanbase
|
||||
namespace common
|
||||
{
|
||||
using lib::ObMemAttr;
|
||||
class ObAllocAlign
|
||||
{
|
||||
public:
|
||||
struct Header
|
||||
{
|
||||
static const uint32_t MAGIC_CODE = 0XAA22CCE1;
|
||||
bool check_magic_code() const { return MAGIC_CODE == magic_code_; }
|
||||
void mark_unused() { magic_code_ &= ~0x1; }
|
||||
uint32_t magic_code_;
|
||||
uint32_t offset_;
|
||||
};
|
||||
template<typename alloc_func, typename... Args>
|
||||
static void *alloc_align(const int64_t size, const int64_t align, alloc_func &&alloc, const Args&... args)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
int64_t real_align = lib::align_up2(align, 16);
|
||||
int64_t real_size = real_align + size + sizeof(Header);
|
||||
char *tmp_ptr = (char*)alloc(real_size, args...);
|
||||
if (NULL != tmp_ptr) {
|
||||
ptr = (void*)lib::align_up2((int64_t)tmp_ptr + sizeof(Header), real_align);
|
||||
Header *header = (Header*)ptr - 1;
|
||||
header->magic_code_ = Header::MAGIC_CODE;
|
||||
header->offset_ = (char*)header - tmp_ptr;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template<typename free_func>
|
||||
static void free_align(void *ptr, free_func &&free)
|
||||
{
|
||||
if (NULL != ptr) {
|
||||
Header *header = (Header*)ptr - 1;
|
||||
abort_unless(header->check_magic_code());
|
||||
header->mark_unused();
|
||||
char *orig_ptr = (char*)header - header->offset_;
|
||||
free(orig_ptr);
|
||||
}
|
||||
}
|
||||
};
|
||||
class ObIAllocator
|
||||
{
|
||||
public:
|
||||
@ -46,6 +85,20 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
virtual void free(void *ptr) = 0;
|
||||
virtual void *alloc_align(const int64_t size, const int64_t align) final
|
||||
{
|
||||
return ObAllocAlign::alloc_align(size, align,
|
||||
[this](const int64_t size) { return this->alloc(size); });
|
||||
}
|
||||
virtual void *alloc_align(const int64_t size, const int64_t align, const ObMemAttr &attr) final
|
||||
{
|
||||
return ObAllocAlign::alloc_align(size, align,
|
||||
[this](const int64_t size, const ObMemAttr &attr) { return this->alloc(size, attr); }, attr);
|
||||
}
|
||||
virtual void free_align(void *ptr) final
|
||||
{
|
||||
ObAllocAlign::free_align(ptr, [this](void *ptr){ this->free(ptr); });
|
||||
}
|
||||
virtual int64_t total() const
|
||||
{
|
||||
return 0;
|
||||
|
||||
@ -60,15 +60,6 @@ public:
|
||||
{
|
||||
return alloc(size);
|
||||
}
|
||||
void *alloc_align(const int64_t size, const int64_t align)
|
||||
{
|
||||
UNUSED(align);
|
||||
return alloc(size);
|
||||
}
|
||||
virtual void *alloc_align(const int64_t size, const int64_t align, const ObMemAttr &)
|
||||
{
|
||||
return alloc_align(size, align);
|
||||
}
|
||||
virtual void free(void *ptr) override;
|
||||
|
||||
void set_label(const lib::ObLabel &label) { UNUSED(label); }
|
||||
|
||||
@ -276,16 +276,16 @@ bool ObFIFOAllocator::check_magic(void *p, int64_t &size)
|
||||
|
||||
void *ObFIFOAllocator::alloc(const int64_t size)
|
||||
{
|
||||
return alloc_align(size, 16);
|
||||
return inner_alloc_align(size, 16);
|
||||
}
|
||||
|
||||
void *ObFIFOAllocator::alloc(const int64_t size, const ObMemAttr &attr)
|
||||
{
|
||||
UNUSED(attr);
|
||||
return alloc_align(size, 16);
|
||||
return inner_alloc_align(size, 16);
|
||||
}
|
||||
|
||||
void *ObFIFOAllocator::alloc_align(const int64_t size, const int64_t align)
|
||||
void *ObFIFOAllocator::inner_alloc_align(const int64_t size, const int64_t align)
|
||||
{
|
||||
ObLockGuard<ObSpinLock> guard(lock_);
|
||||
void *ptr = nullptr;
|
||||
|
||||
@ -97,7 +97,6 @@ public:
|
||||
void reset();
|
||||
void *alloc(const int64_t size);
|
||||
void *alloc(const int64_t size, const ObMemAttr &attr);
|
||||
virtual void *alloc_align(const int64_t size, const int64_t align);
|
||||
void free(void *p);
|
||||
void set_label(const lib::ObLabel &label) { attr_.label_ = label; }
|
||||
void set_attr(const ObMemAttr &attr) { attr_ = attr; }
|
||||
@ -129,6 +128,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void *inner_alloc_align(const int64_t size, const int64_t align);
|
||||
BasePageHeader *get_page_header(void *p);
|
||||
bool check_param(const int64_t size, const int64_t align);
|
||||
bool check_magic(void *p, int64_t &size);
|
||||
|
||||
48
deps/oblib/src/lib/allocator/ob_malloc.cpp
vendored
48
deps/oblib/src/lib/allocator/ob_malloc.cpp
vendored
@ -61,55 +61,13 @@ void *oceanbase::common::ob_malloc_align(const int64_t alignment, const int64_t
|
||||
void *oceanbase::common::ob_malloc_align(const int64_t align, const int64_t nbyte,
|
||||
const ObMemAttr &attr)
|
||||
{
|
||||
const int min_align = 16;
|
||||
const int64_t alignment =
|
||||
align <= min_align ? min_align : lib::align_up2(align, 16);
|
||||
char *ptr = static_cast<char *>(oceanbase::common::ob_malloc(nbyte + alignment, attr));
|
||||
char *align_ptr = NULL;
|
||||
if (NULL != ptr) {
|
||||
align_ptr = reinterpret_cast<char *>(oceanbase::common::upper_align(reinterpret_cast<int64_t>(ptr),
|
||||
alignment));
|
||||
if (align_ptr == ptr) {
|
||||
align_ptr = ptr + alignment;
|
||||
}
|
||||
int64_t padding = align_ptr - ptr;
|
||||
if (!(padding <= alignment && padding > 0)) {
|
||||
_OB_LOG_RET(ERROR, OB_INVALID_ARGUMENT, "invalid padding(padding=%ld, alignment=%ld", padding, alignment);
|
||||
}
|
||||
uint8_t *sign_ptr = reinterpret_cast<uint8_t *>(align_ptr - 1);
|
||||
int64_t *header_ptr = reinterpret_cast<int64_t *>(align_ptr - 1 - sizeof(int64_t));
|
||||
if (padding < (int64_t)sizeof(int64_t) + 1) {
|
||||
*sign_ptr = static_cast<uint8_t>(padding) & 0x7f;
|
||||
} else {
|
||||
*sign_ptr = 0x80;
|
||||
*header_ptr = padding;
|
||||
}
|
||||
} else {
|
||||
_OB_LOG_RET(WARN, OB_ALLOCATE_MEMORY_FAILED, "ob_tc_malloc allocate memory failed, alignment[%ld], nbyte[%ld], tenant_id[%lu], label[%s].",
|
||||
alignment, nbyte, attr.tenant_id_, (const char*)attr.label_);
|
||||
}
|
||||
return align_ptr;
|
||||
return ObAllocAlign::alloc_align(nbyte, align,
|
||||
[](const int64_t size, const ObMemAttr &attr){ return ob_malloc(size, attr); }, attr);
|
||||
}
|
||||
|
||||
void oceanbase::common::ob_free_align(void *ptr)
|
||||
{
|
||||
if (NULL == ptr) {
|
||||
_OB_LOG_RET(WARN, OB_INVALID_ARGUMENT, "cannot free NULL pointer.");
|
||||
} else if (oceanbase::lib::ObMallocAllocator::is_inited_) {
|
||||
uint8_t *sign_ptr = reinterpret_cast<uint8_t *>(static_cast<char *>(ptr) - 1);
|
||||
int64_t *header_ptr = reinterpret_cast<int64_t *>(static_cast<char *>(ptr) - 1 - sizeof(int64_t));
|
||||
char *origin_ptr = NULL;
|
||||
if (NULL != sign_ptr) {
|
||||
if ((*sign_ptr & 0x80) != 0) {
|
||||
origin_ptr = reinterpret_cast<char *>(ptr) - (*header_ptr);
|
||||
} else {
|
||||
origin_ptr = reinterpret_cast<char *>(ptr) - (*sign_ptr & 0x7f);
|
||||
}
|
||||
if (NULL != origin_ptr) {
|
||||
oceanbase::common::ob_free(origin_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
ObAllocAlign::free_align(ptr, [](void *ptr){ ob_free(ptr); });
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -91,6 +91,15 @@ TEST_F(TestAllocator, basic)
|
||||
sz = ((sz | reinterpret_cast<size_t>(p[0])) & ((1<<13) - 1));
|
||||
}
|
||||
|
||||
// test alloc_align/free_align
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
int64_t align = 8<<i;
|
||||
void *ptr = a.alloc_align(100, align);
|
||||
ASSERT_EQ(0, (int64_t)ptr & (align - 1));
|
||||
ASSERT_GT(a.used(), 0);
|
||||
a.free_align(ptr);
|
||||
ASSERT_EQ(a.used(), 0);
|
||||
}
|
||||
cout << "done" << endl;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user