summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2016-11-09 08:30:05 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2017-01-03 11:01:56 +0100
commitad711a467185a694ef5059add8f560e1da9d6461 (patch)
treebbbbbb1ba39545f865ba30b32f65c8ca888296d4
parent2bb90b30dd247e324cfbea639907d4724fcca4ac (diff)
extend in place if possible.
-rw-r--r--vespalib/src/vespa/vespalib/util/alloc.cpp51
-rw-r--r--vespalib/src/vespa/vespalib/util/alloc.h4
2 files changed, 48 insertions, 7 deletions
diff --git a/vespalib/src/vespa/vespalib/util/alloc.cpp b/vespalib/src/vespa/vespalib/util/alloc.cpp
index 8d899eae551..1f58d3ec3d2 100644
--- a/vespalib/src/vespa/vespalib/util/alloc.cpp
+++ b/vespalib/src/vespa/vespalib/util/alloc.cpp
@@ -118,6 +118,7 @@ class HeapAllocator : public MemoryAllocator {
public:
PtrAndSize alloc(size_t sz) const override;
void free(PtrAndSize alloc) const override;
+ size_t extend_inplace(PtrAndSize, size_t) const override { return 0; }
static PtrAndSize salloc(size_t sz);
static void sfree(PtrAndSize alloc);
static MemoryAllocator & getDefault();
@@ -138,7 +139,9 @@ class MMapAllocator : public MemoryAllocator {
public:
PtrAndSize alloc(size_t sz) const override;
void free(PtrAndSize alloc) const override;
- static PtrAndSize salloc(size_t sz);
+ size_t extend_inplace(PtrAndSize current, size_t newSize) const override;
+ static size_t sextend_inplace(PtrAndSize current, size_t newSize);
+ static PtrAndSize salloc(size_t sz, void * wantedAddress);
static void sfree(PtrAndSize alloc);
static MemoryAllocator & getDefault();
};
@@ -148,6 +151,7 @@ public:
AutoAllocator(size_t mmapLimit, size_t alignment) : _mmapLimit(mmapLimit), _alignment(alignment) { }
PtrAndSize alloc(size_t sz) const override;
void free(PtrAndSize alloc) const override;
+ size_t extend_inplace(PtrAndSize current, size_t newSize) const override;
static MemoryAllocator & getDefault();
static MemoryAllocator & getAllocator(size_t mmapLimit, size_t alignment);
private:
@@ -256,13 +260,18 @@ AlignedHeapAllocator::alloc(size_t sz) const {
return PtrAndSize(ptr, sz);
}
+size_t
+MMapAllocator::extend_inplace(PtrAndSize current, size_t newSize) const {
+ return sextend_inplace(current, newSize);
+}
+
MemoryAllocator::PtrAndSize
MMapAllocator::alloc(size_t sz) const {
- return salloc(sz);
+ return salloc(sz, nullptr);
}
MemoryAllocator::PtrAndSize
-MMapAllocator::salloc(size_t sz)
+MMapAllocator::salloc(size_t sz, void * wantedAddress)
{
void * buf(nullptr);
if (sz > 0) {
@@ -274,7 +283,7 @@ MMapAllocator::salloc(size_t sz)
stackTrace = getStackTrace(1);
LOG(info, "mmap %ld of size %ld from %s", mmapId, sz, stackTrace.c_str());
}
- buf = mmap(nullptr, sz, prot, flags | _G_HugeFlags, -1, 0);
+ buf = mmap(wantedAddress, sz, prot, flags | _G_HugeFlags, -1, 0);
if (buf == MAP_FAILED) {
if ( ! _G_hasHugePageFailureJustHappened ) {
_G_hasHugePageFailureJustHappened = true;
@@ -282,7 +291,7 @@ MMapAllocator::salloc(size_t sz)
" Will resort to ordinary mmap until it works again.",
sz, FastOS_FileInterface::getLastErrorString().c_str());
}
- buf = mmap(nullptr, sz, prot, flags, -1, 0);
+ buf = mmap(wantedAddress, sz, prot, flags, -1, 0);
if (buf == MAP_FAILED) {
stackTrace = getStackTrace(1);
string msg = make_string("Failed mmaping anonymous of size %ld errno(%d) from %s", sz, errno, stackTrace.c_str());
@@ -313,6 +322,15 @@ MMapAllocator::salloc(size_t sz)
return PtrAndSize(buf, sz);
}
+size_t
+MMapAllocator::sextend_inplace(PtrAndSize current, size_t newSize) {
+ PtrAndSize got = MMapAllocator::salloc(newSize, current.first);
+ if (current.first == got.first) {
+ return got.second;
+ }
+ return 0;
+}
+
void MMapAllocator::free(PtrAndSize alloc) const {
sfree(alloc);
}
@@ -333,11 +351,21 @@ void MMapAllocator::sfree(PtrAndSize alloc)
}
}
+size_t
+AutoAllocator::extend_inplace(PtrAndSize current, size_t newSize) const {
+ if (useMMap(current.second) && useMMap(newSize)) {
+ newSize = roundUpToHugePages(newSize);
+ return MMapAllocator::sextend_inplace(current, newSize);
+ } else {
+ return 0;
+ }
+}
+
MMapAllocator::PtrAndSize
AutoAllocator::alloc(size_t sz) const {
if (useMMap(sz)) {
sz = roundUpToHugePages(sz);
- return MMapAllocator::salloc(sz);
+ return MMapAllocator::salloc(sz, nullptr);
} else {
if (_alignment == 0) {
return HeapAllocator::salloc(sz);
@@ -362,6 +390,17 @@ Alloc::allocHeap(size_t sz)
return Alloc(&HeapAllocator::getDefault(), sz);
}
+bool
+Alloc::extend_inplace(size_t newSize)
+{
+ size_t extendedSize = _allocator->extend_inplace(_alloc, newSize);
+ if (extendedSize > newSize) {
+ _alloc.second = extendedSize;
+ return true;
+ }
+ return false;
+}
+
Alloc
Alloc::allocAlignedHeap(size_t sz, size_t alignment)
{
diff --git a/vespalib/src/vespa/vespalib/util/alloc.h b/vespalib/src/vespa/vespalib/util/alloc.h
index 9f0937424a9..28ea4a436d6 100644
--- a/vespalib/src/vespa/vespalib/util/alloc.h
+++ b/vespalib/src/vespa/vespalib/util/alloc.h
@@ -21,6 +21,7 @@ public:
virtual ~MemoryAllocator() { }
virtual PtrAndSize alloc(size_t sz) const = 0;
virtual void free(PtrAndSize alloc) const = 0;
+ virtual size_t extend_inplace(PtrAndSize current, size_t newSize) const = 0;
static size_t roundUpToHugePages(size_t sz) {
return (sz+(HUGEPAGE_SIZE-1)) & ~(HUGEPAGE_SIZE-1);
}
@@ -35,13 +36,14 @@ public:
class Alloc
{
private:
- using PtrAndSize = MemoryAllocator::PtrAndSize;;
+ using PtrAndSize = MemoryAllocator::PtrAndSize;
public:
size_t size() const { return _alloc.second; }
void * get() { return _alloc.first; }
const void * get() const { return _alloc.first; }
void * operator -> () { return _alloc.first; }
const void * operator -> () const { return _alloc.first; }
+ bool extend_inplace(size_t newSize);
Alloc(const Alloc &) = delete;
Alloc & operator = (const Alloc &) = delete;
Alloc(Alloc && rhs) :