Files
cKit/Memory/c_BuddyAllocator.h
T
2026-08-30 01:48:03 +08:00

97 lines
3.1 KiB
C

#ifndef INCLUDED_C_BUDDYALLOCATOR_H
#define INCLUDED_C_BUDDYALLOCATOR_H
#ifndef INCLUDED_C_BUDDY_H
#include <c_Buddy.h>
#endif /*INCLUDED_C_BUDDY_H*/
#ifndef INCLUDED_C_ALLOCATOR_H
#include <c_Allocator.h>
#endif /*INCLUDED_C_ALLOCATOR_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef struct {
c_Buddy_t* buddy;
}c_BuddyAllocator_t;
C_STATIC_FORCE_INLINE
void c_BuddyAllocator_Init(c_BuddyAllocator_t* allocator, c_Buddy_t* buddy) {
allocator->buddy = buddy;
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
C_STATIC_FORCE_INLINE
C_ALLOCATOR_ALLOC_FN(c_BuddyAllocator_Alloc) {
c_BuddyAllocator_t* self = (c_BuddyAllocator_t*)ud;
if (!self || !self->buddy) return NULL;
return c_Buddy_Alloc(self->buddy, (int)nBytes);
}
C_STATIC_FORCE_INLINE
C_ALLOCATOR_FREE_FN(c_BuddyAllocator_Free) {
c_BuddyAllocator_t* self = (c_BuddyAllocator_t*)ud;
if (!self || !self->buddy) return;
c_Buddy_Free(self->buddy, ptr);
}
C_STATIC_FORCE_INLINE
C_ALLOCATOR_REALLOC_FN(c_BuddyAllocator_Realloc) {
c_BuddyAllocator_t* self = (c_BuddyAllocator_t*)ud;
if (!self || !self->buddy) return NULL;
// 情况 1: 指针为空,直接分配新内存
if (!ptr) {
return c_Buddy_Alloc(self->buddy, (int)nNewSize);
}
// 情况 2: 新大小为 0,直接释放内存
if (nNewSize==0) {
c_Buddy_Free(self->buddy, ptr);
return NULL;
}
// 核心优化:利用 Header 逆向获取该块在底层伙伴系统中的真实物理大小
const c_BuddyBlock_t *block = (c_BuddyBlock_t *) ((uint8_t *) ptr - self->buddy->alignment);
const int actual_block_size = block->size;
// 【就地复用判定】:如果新申请的大小没有超过当前伙伴块的物理承载上限,并且新大小不至于小到需要缩容割裂
// 直接返回原指针,零拷贝,零内存搬迁!
if ((int)nNewSize <= actual_block_size && (int)nNewSize > (actual_block_size / 2)) {
return ptr;
}
// 情况 3: 伙伴块大小不匹配(需要升级或降级阶数),申请新块
void* new_ptr = c_Buddy_Alloc(self->buddy, (int)nNewSize);
if (!new_ptr) return NULL;
// 计算安全的拷贝长度
const c_size_t copy_size = ((c_size_t)actual_block_size < nNewSize) ? (c_size_t)actual_block_size : nNewSize;
// 数据迁移
memcpy(new_ptr, ptr, copy_size);
// 释放旧伙伴块
c_Buddy_Free(self->buddy, ptr);
return new_ptr;
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
C_STATIC_FORCE_INLINE
c_Allocator_t c_BuddyAllocator_Build(c_BuddyAllocator_t* self, c_Buddy_t* buddy) {
c_BuddyAllocator_Init(self, buddy);
c_Allocator_t allocator={0};
allocator.ud = self;
allocator.alloc = c_BuddyAllocator_Alloc;
allocator.free = c_BuddyAllocator_Free;
allocator.realloc = c_BuddyAllocator_Realloc;
return allocator;
}
#endif /*INCLUDED_C_BUDDYALLOCATOR_H*/