VTrain/tools/rtsp_server/net/MemoryManager.cpp

127 lines
2.3 KiB
C++

#include "MemoryManager.h"
using namespace xop;
void* xop::Alloc(uint32_t size)
{
return MemoryManager::Instance().Alloc(size);
}
void xop::Free(void *ptr)
{
return MemoryManager::Instance().Free(ptr);
}
MemoryPool::MemoryPool()
{
}
MemoryPool::~MemoryPool()
{
if (memory_) {
free(memory_);
}
}
void MemoryPool::Init(uint32_t size, uint32_t n)
{
if (memory_) {
return;
}
block_size_ = size;
num_blocks_ = n;
memory_ = (char*)malloc(num_blocks_ * (block_size_ + sizeof(MemoryBlock)));
head_ = (MemoryBlock*)memory_;
head_->block_id = 1;
head_->pool = this;
head_->next = nullptr;
MemoryBlock* current = head_;
for (uint32_t n = 1; n < num_blocks_; n++) {
MemoryBlock* next = (MemoryBlock*)(memory_ + (n * (block_size_ + sizeof(MemoryBlock))));
next->block_id = n + 1;
next->pool = this;
next->next = nullptr;
current->next = next;
current = next;
}
}
void* MemoryPool::Alloc(uint32_t size)
{
std::lock_guard<std::mutex> locker(mutex_);
if (head_ != nullptr) {
MemoryBlock* block = head_;
head_ = head_->next;
return ((char*)block + sizeof(MemoryBlock));
}
return nullptr;
}
void MemoryPool::Free(void* ptr)
{
MemoryBlock *block = (MemoryBlock*)((char*)ptr - sizeof(MemoryBlock));
if (block->block_id != 0) {
std::lock_guard<std::mutex> locker(mutex_);
block->next = head_;
head_ = block;
}
}
MemoryManager::MemoryManager()
{
memory_pools_[0].Init(4096, 50);
memory_pools_[1].Init(40960, 10);
memory_pools_[2].Init(102400, 5);
//memory_pools_[3].Init(204800, 2);
}
MemoryManager::~MemoryManager()
{
}
MemoryManager& MemoryManager::Instance()
{
static MemoryManager s_mgr;
return s_mgr;
}
void* MemoryManager::Alloc(uint32_t size)
{
for (int n = 0; n < kMaxMemoryPool; n++) {
if (size <= memory_pools_[n].BolckSize()) {
void* ptr = memory_pools_[n].Alloc(size);
if (ptr != nullptr) {
return ptr;
}
else {
break;
}
}
}
MemoryBlock *block = (MemoryBlock*)malloc(size + sizeof(MemoryBlock));
block->block_id = 0;
block->pool = nullptr;
block->next = nullptr;
return ((char*)block + sizeof(MemoryBlock));
}
void MemoryManager::Free(void* ptr)
{
MemoryBlock *block = (MemoryBlock*)((char*)ptr - sizeof(MemoryBlock));
MemoryPool *pool = block->pool;
if (pool != nullptr && block->block_id > 0) {
pool->Free(ptr);
}
else {
::free(block);
}
}