diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2016-11-09 08:30:05 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2017-01-03 11:01:56 +0100 |
commit | ad711a467185a694ef5059add8f560e1da9d6461 (patch) | |
tree | bbbbbb1ba39545f865ba30b32f65c8ca888296d4 | |
parent | 2bb90b30dd247e324cfbea639907d4724fcca4ac (diff) |
extend in place if possible.
-rw-r--r-- | vespalib/src/vespa/vespalib/util/alloc.cpp | 51 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/alloc.h | 4 |
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) : |