Fix for FreeBSD and possibly OSX, added reference counting

This commit is contained in:
Marcin Junczys-Dowmunt 2012-08-09 17:12:58 +02:00
parent 654ed29209
commit 533b0852f8

View File

@ -43,6 +43,7 @@ namespace Moses
char* m_data_ptr;
size_t m_data_offset;
bool m_fixed;
size_t* m_count;
public:
typedef T value_type;
@ -56,42 +57,45 @@ namespace Moses
MmapAllocator() throw()
: m_file_ptr(std::tmpfile()), m_file_desc(fileno(m_file_ptr)),
m_page_size(sysconf(_SC_PAGE_SIZE)), m_map_size(0), m_data_ptr(0),
m_data_offset(0), m_fixed(false)
m_data_offset(0), m_fixed(false), m_count(new size_t(0))
{ }
MmapAllocator(std::FILE* f_ptr) throw()
: m_file_ptr(f_ptr), m_file_desc(fileno(m_file_ptr)),
m_page_size(sysconf(_SC_PAGE_SIZE)), m_map_size(0), m_data_ptr(0),
m_data_offset(0), m_fixed(false)
m_data_offset(0), m_fixed(false), m_count(new size_t(0))
{ }
MmapAllocator(std::FILE* f_ptr, size_t data_offset = 0) throw()
: m_file_ptr(f_ptr), m_file_desc(fileno(m_file_ptr)),
m_page_size(sysconf(_SC_PAGE_SIZE)), m_map_size(0), m_data_ptr(0),
m_data_offset(data_offset), m_fixed(true)
m_data_offset(data_offset), m_fixed(true), m_count(new size_t(0))
{ }
MmapAllocator(std::string fileName) throw()
: m_file_ptr(std::fopen(fileName.c_str(), "wb+")), m_file_desc(fileno(m_file_ptr)),
m_page_size(sysconf(_SC_PAGE_SIZE)), m_map_size(0), m_data_ptr(0),
m_data_offset(0), m_fixed(false)
m_data_offset(0), m_fixed(false), m_count(new size_t(0))
{ }
MmapAllocator(const MmapAllocator& c) throw()
: m_file_ptr(c.m_file_ptr), m_file_desc(c.m_file_desc),
m_page_size(c.m_page_size), m_map_size(c.m_map_size),
m_data_ptr(c.m_data_ptr), m_data_offset(c.m_data_offset),
m_fixed(c.m_fixed)
{ }
m_fixed(c.m_fixed), m_count(c.m_count)
{
(*m_count)++;
}
~MmapAllocator() throw()
{
if(m_data_ptr)
if(m_data_ptr && *m_count == 1)
{
munmap(m_data_ptr, m_map_size);
if(!m_fixed && std::ftell(m_file_ptr) != -1)
std::fclose(m_file_ptr);
}
(*m_count)--;
}
template <class U>
@ -124,6 +128,8 @@ namespace Moses
read += ftruncate(m_file_desc, m_map_size);
m_data_ptr = (char*)mmap(0, m_map_size, PROT_READ|PROT_WRITE, MAP_SHARED,
m_file_desc, 0);
if(m_data_ptr == MAP_FAILED)
std::cerr << "Error: mmapping" << std::endl;
return (pointer)m_data_ptr;
}
else
@ -142,8 +148,9 @@ namespace Moses
void deallocate (pointer p, size_type num)
{
if(!m_fixed)
if(!m_fixed) {
munmap(p, num * sizeof(T));
}
else {
size_t map_offset = (m_data_offset / m_page_size) * m_page_size;
size_t relative_offset = m_data_offset - map_offset;