|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <boost/foreach.hpp> |
|
|
#include "MemPool.h" |
|
|
#include "util/scoped.hh" |
|
|
#include "legacy/Util2.h" |
|
|
|
|
|
using namespace std; |
|
|
|
|
|
namespace Moses2 |
|
|
{ |
|
|
|
|
|
MemPool::Page::Page(std::size_t vSize) : |
|
|
size(vSize) |
|
|
{ |
|
|
mem = (uint8_t*) util::MallocOrThrow(size); |
|
|
end = mem + size; |
|
|
} |
|
|
|
|
|
MemPool::Page::~Page() |
|
|
{ |
|
|
free(mem); |
|
|
} |
|
|
|
|
|
MemPool::MemPool(size_t initSize) : |
|
|
m_currSize(initSize), m_currPage(0) |
|
|
{ |
|
|
Page *page = new Page(m_currSize); |
|
|
m_pages.push_back(page); |
|
|
|
|
|
current_ = page->mem; |
|
|
|
|
|
} |
|
|
|
|
|
MemPool::~MemPool() |
|
|
{ |
|
|
|
|
|
RemoveAllInColl(m_pages); |
|
|
} |
|
|
|
|
|
uint8_t* MemPool::Allocate(std::size_t size) { |
|
|
if (size == 0) { |
|
|
return nullptr; |
|
|
} |
|
|
|
|
|
|
|
|
size = (size + 15) & 0xfffffff0; |
|
|
|
|
|
|
|
|
uint8_t* ret = current_; |
|
|
current_ += size; |
|
|
|
|
|
assert(m_currPage < m_pages.size()); |
|
|
Page& page = *m_pages[m_currPage]; |
|
|
if (current_ <= page.end) { |
|
|
|
|
|
} |
|
|
else { |
|
|
ret = More(size); |
|
|
} |
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
uint8_t *MemPool::More(std::size_t size) |
|
|
{ |
|
|
++m_currPage; |
|
|
if (m_currPage >= m_pages.size()) { |
|
|
|
|
|
m_currSize <<= 1; |
|
|
std::size_t amount = std::max(m_currSize, size); |
|
|
|
|
|
Page *page = new Page(amount); |
|
|
|
|
|
m_pages.push_back(page); |
|
|
|
|
|
uint8_t *ret = page->mem; |
|
|
current_ = ret + size; |
|
|
return ret; |
|
|
} else { |
|
|
|
|
|
Page &page = *m_pages[m_currPage]; |
|
|
if (size <= page.size) { |
|
|
uint8_t *ret = page.mem; |
|
|
current_ = ret + size; |
|
|
return ret; |
|
|
} else { |
|
|
|
|
|
return More(size); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
void MemPool::Reset() |
|
|
{ |
|
|
if (m_pages.size() > 1) { |
|
|
size_t total = 0; |
|
|
for (size_t i = 0; i < m_pages.size(); ++i) { |
|
|
total += m_pages[i]->size; |
|
|
} |
|
|
RemoveAllInColl(m_pages); |
|
|
Page* page = new Page(total); |
|
|
m_pages.push_back(page); |
|
|
} |
|
|
|
|
|
m_currPage = 0; |
|
|
current_ = m_pages[0]->mem; |
|
|
} |
|
|
|
|
|
size_t MemPool::Size() |
|
|
{ |
|
|
size_t ret = 0; |
|
|
for (const Page *page: m_pages) { |
|
|
ret += page->size; |
|
|
} |
|
|
return ret; |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|