Skip to content

Commit

Permalink
add realloc
Browse files Browse the repository at this point in the history
  • Loading branch information
gwq5210 committed Sep 1, 2022
1 parent b0e3435 commit c7a4aff
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 9 deletions.
47 changes: 38 additions & 9 deletions src/gtl/memory/simple_allocator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ namespace gtl {
std::atomic_int SimpleMemoryAllocator::block_id_(0);

void* SimpleMemoryAllocator::Malloc(size_t size) {
BlockHeader* block = FindFreeBlock(size);
if (block != nullptr) {
RemoveFromFreeList(block);
SplitBlock(block, size);
GTL_INFO("find free block: {}, size: {}", fmt::ptr(block), block->size);
return BlockHeader::ToData(block);
BlockHeader* block = nullptr;
{
LockGuard lock_guard(mutex_);
block = FindFreeBlock(size);
if (block != nullptr) {
RemoveFromFreeList(block);
SplitBlock(block, size);
GTL_INFO("find free block: {}, size: {}", fmt::ptr(block), block->size);
return BlockHeader::ToData(block);
}
}

block = static_cast<BlockHeader*>(NewBlock(size));
Expand All @@ -31,6 +35,7 @@ void SimpleMemoryAllocator::Free(void* ptr) {
return;
}

LockGuard lock_guard(mutex_);
BlockHeader* block = BlockHeader::ToBlockHeader(ptr);
AddToFreeList(block);
GTL_INFO("free block: {}", GetBlockInfo(block));
Expand Down Expand Up @@ -112,7 +117,31 @@ void* SimpleMemoryAllocator::Realloc(void* ptr, size_t size) {
return ptr;
}

return nullptr;
{
// 相同region的block是空闲的且合起来之后有足够的空间
LockGuard lock_guard(mutex_);
BlockHeader* next_block = nullptr;
if (block->block_list.next != &block_head_) {
next_block = ListEntry(block->block_list.next, BlockHeader, block_list);
if (next_block->region != block->region || next_block->used ||
block->size + next_block->size + kBlockHeaderSize < size) {
next_block = nullptr;
}
}
if (next_block) {
MergeTwoBlock(block, next_block);
SplitBlock(block, size);
return ptr;
}
}

void* new_ptr = Malloc(size);
if (new_ptr == nullptr) {
return nullptr;
}
memcpy(new_ptr, ptr, block->size);
Free(ptr);
return new_ptr;
}

void* SimpleMemoryAllocator::AllocMemory(size_t size) {
Expand Down Expand Up @@ -196,13 +225,13 @@ SimpleMemoryAllocator::BlockHeader* SimpleMemoryAllocator::MergeRightBlock(Block
}

SimpleMemoryAllocator::BlockHeader* SimpleMemoryAllocator::MergeTwoBlock(BlockHeader* lblock, BlockHeader* rblock) {
GTL_CHECK(lblock != nullptr && rblock != nullptr && !lblock->used && !rblock->used);
GTL_CHECK(lblock != nullptr && rblock != nullptr && !rblock->used);

GTL_INFO("merge two block begin");
GTL_INFO("lblock: {}", GetBlockInfo(lblock));
GTL_INFO("rblock: {}", GetBlockInfo(rblock));

doubly_list::Remove(&rblock->block_list);
RemoveFromBlockList(rblock);
RemoveFromFreeList(rblock);
lblock->size = lblock->size + rblock->size + kBlockHeaderSize;

Expand Down
2 changes: 2 additions & 0 deletions src/gtl/memory/simple_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "gtl/container/list_base.h"
#include "gtl/logging.h"
#include "gtl/memory/allocator.h"
#include "gtl/thread/mutex.h"

#include "fmt/format.h"

Expand Down Expand Up @@ -137,6 +138,7 @@ class SimpleMemoryAllocator : public MemoryAllocator {
doubly_list::ListNode block_head_;
size_t free_block_count_ = 0;
doubly_list::ListNode free_head_;
Mutex mutex_;
};

} // namespace gtl
18 changes: 18 additions & 0 deletions src/gtl/memory/test/allocator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,22 @@ TEST(AllocatorTest, AllocatorTest) {
allocator.Free(ptr4);
GTL_INFO("free all\n{}", allocator.MemoryInfo());
}

{
size_t size = 129;
GTL_INFO("new 129 begin\n{}", allocator.MemoryInfo());
char* ptr = static_cast<char*>(allocator.Malloc(size));
ASSERT_NE(ptr, nullptr);
memset(ptr, 0, size);
GTL_INFO("new 129 end\n{}", allocator.MemoryInfo());

size_t new_size = 256;
char* realloc_ptr = static_cast<char*>(allocator.Realloc(ptr, new_size));
ASSERT_NE(realloc_ptr, nullptr);
EXPECT_EQ(realloc_ptr, ptr);
GTL_INFO("realloc 256 end\n{}", allocator.MemoryInfo());

allocator.Free(realloc_ptr);
GTL_INFO("free 256 end\n{}", allocator.MemoryInfo());
}
}
11 changes: 11 additions & 0 deletions src/gtl/thread/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,15 @@ class RWMutex {
Handle rwlock_;
};

class LockGuard {
public:
LockGuard(Mutex& mutex) : mutex_(mutex) { mutex_.Lock(); }
~LockGuard() { mutex_.Unlock(); }
LockGuard(const LockGuard& other) = delete;
LockGuard& operator=(const LockGuard& other) = delete;

private:
Mutex& mutex_;
};

} // namespace gtl

0 comments on commit c7a4aff

Please sign in to comment.