Optimize memory_map::resize using upgrade lock.
evoskuil opened this issue · 1 comments
evoskuil commented
The remap allocator starts with a unique lock and downgrades to shared lock. In the vast majority of cases there is no need for a unique lock. It is only require when size
exceeds file_size_
. Otherwise writes with sufficient file space are needlessly blocking reads.
memory_ptr memory_map::reserve(size_t size, size_t expansion)
{
// Internally preventing resize during close is not possible because of
// cross-file integrity. So we must coalesce all threads before closing.
// Critical Section (internal)
///////////////////////////////////////////////////////////////////////////
const auto memory = REMAP_ALLOCATOR(mutex_);
// The store should only have been closed after all threads terminated.
if (closed_)
throw std::runtime_error("Resize failure, store already closed.");
if (size > file_size_)
{
// TODO: manage overflow (requires ceiling_multiply).
// Expansion is an integral number that represents a real number factor.
const size_t target = size * ((expansion + 100.0) / 100.0);
if (!truncate_mapped(target))
{
handle_error("resize", filename_);
throw std::runtime_error("Resize failure, disk space may be low.");
}
}
logical_size_ = size;
REMAP_DOWNGRADE(memory, data_);
return memory;
///////////////////////////////////////////////////////////////////////////
}
evoskuil commented
Resolved.