summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2022-02-09 14:13:52 +0100
committerTor Egge <Tor.Egge@online.no>2022-02-09 14:13:52 +0100
commit8cd068dfd76da175b96e50fa4a98f48d84c48021 (patch)
tree82014e4750a29e9d5fcb6172222e209b08432548
parent234adeffe4f1e4f1275a834f42293722a2ce6829 (diff)
Block in-place resize from nonzero to zero size.
-rw-r--r--vespalib/src/tests/alloc/alloc_test.cpp55
-rw-r--r--vespalib/src/vespa/vespalib/util/alloc.cpp6
2 files changed, 42 insertions, 19 deletions
diff --git a/vespalib/src/tests/alloc/alloc_test.cpp b/vespalib/src/tests/alloc/alloc_test.cpp
index 2b6d3ee4613..da41d75b479 100644
--- a/vespalib/src/tests/alloc/alloc_test.cpp
+++ b/vespalib/src/tests/alloc/alloc_test.cpp
@@ -139,22 +139,28 @@ TEST("rounding of large mmaped buffer") {
EXPECT_EQUAL(MemoryAllocator::HUGEPAGE_SIZE*12ul, buf.size());
}
+void verifyExtension(Alloc& buf, size_t currSZ, size_t newSZ) {
+ bool expectSuccess = (currSZ != newSZ);
+ void* oldPtr = buf.get();
+ EXPECT_EQUAL(currSZ, buf.size());
+ EXPECT_EQUAL(expectSuccess, buf.resize_inplace(currSZ + 1));
+ EXPECT_EQUAL(oldPtr, buf.get());
+ EXPECT_EQUAL(newSZ, buf.size());
+}
+
TEST("heap alloc can not be extended") {
Alloc buf = Alloc::allocHeap(100);
- void * oldPtr = buf.get();
- EXPECT_EQUAL(100ul, buf.size());
- EXPECT_FALSE(buf.resize_inplace(101));
- EXPECT_EQUAL(oldPtr, buf.get());
- EXPECT_EQUAL(100ul, buf.size());
+ verifyExtension(buf, 100, 100);
+}
+
+TEST("mmap alloc cannot be extended from zero") {
+ Alloc buf = Alloc::allocMMap(0);
+ verifyExtension(buf, 0, 0);
}
TEST("auto alloced heap alloc can not be extended") {
Alloc buf = Alloc::alloc(100);
- void * oldPtr = buf.get();
- EXPECT_EQUAL(100ul, buf.size());
- EXPECT_FALSE(buf.resize_inplace(101));
- EXPECT_EQUAL(oldPtr, buf.get());
- EXPECT_EQUAL(100ul, buf.size());
+ verifyExtension(buf, 100, 100);
}
TEST("auto alloced heap alloc can not be extended, even if resize will be mmapped") {
@@ -166,15 +172,6 @@ TEST("auto alloced heap alloc can not be extended, even if resize will be mmappe
EXPECT_EQUAL(100ul, buf.size());
}
-void verifyExtension(Alloc & buf, size_t currSZ, size_t newSZ) {
- bool expectSuccess = (currSZ != newSZ);
- void * oldPtr = buf.get();
- EXPECT_EQUAL(currSZ, buf.size());
- EXPECT_EQUAL(expectSuccess, buf.resize_inplace(currSZ+1));
- EXPECT_EQUAL(oldPtr, buf.get());
- EXPECT_EQUAL(newSZ, buf.size());
-}
-
void ensureRoomForExtension(const Alloc & buf, Alloc & reserved) {
// Normally mmapping starts at the top and grows down in address space.
// Then there is no room to extend the last mapping.
@@ -253,6 +250,11 @@ TEST("heap alloc can not be shrinked") {
EXPECT_EQUAL(101ul, buf.size());
}
+TEST("heap alloc cannot be shrunk to zero") {
+ Alloc buf = Alloc::allocHeap(101);
+ EXPECT_FALSE(buf.resize_inplace(0));
+}
+
TEST("mmap alloc can be shrinked") {
Alloc buf = Alloc::allocMMap(4097);
void * oldPtr = buf.get();
@@ -262,6 +264,11 @@ TEST("mmap alloc can be shrinked") {
EXPECT_EQUAL(4_Ki, buf.size());
}
+TEST("mmap alloc cannot be shrunk to zero") {
+ Alloc buf = Alloc::allocMMap(4097);
+ EXPECT_FALSE(buf.resize_inplace(0));
+}
+
TEST("auto alloced heap alloc can not be shrinked") {
Alloc buf = Alloc::alloc(101);
void * oldPtr = buf.get();
@@ -271,6 +278,11 @@ TEST("auto alloced heap alloc can not be shrinked") {
EXPECT_EQUAL(101ul, buf.size());
}
+TEST("auto alloced heap alloc cannot be shrunk to zero") {
+ Alloc buf = Alloc::alloc(101);
+ EXPECT_FALSE(buf.resize_inplace(0));
+}
+
TEST("auto alloced mmap alloc can be shrinked") {
static constexpr size_t SZ = MemoryAllocator::HUGEPAGE_SIZE;
Alloc buf = Alloc::alloc(SZ + 1);
@@ -281,6 +293,11 @@ TEST("auto alloced mmap alloc can be shrinked") {
EXPECT_EQUAL(SZ, buf.size());
}
+TEST("auto alloced mmap alloc cannot be shrunk to zero") {
+ Alloc buf = Alloc::alloc(MemoryAllocator::HUGEPAGE_SIZE + 1);
+ EXPECT_FALSE(buf.resize_inplace(0));
+}
+
TEST("auto alloced mmap alloc can not be shrinked below HUGEPAGE_SIZE/2 + 1 ") {
static constexpr size_t SZ = MemoryAllocator::HUGEPAGE_SIZE;
Alloc buf = Alloc::alloc(SZ + 1);
diff --git a/vespalib/src/vespa/vespalib/util/alloc.cpp b/vespalib/src/vespa/vespalib/util/alloc.cpp
index 69f2eedcecb..bf5f0200600 100644
--- a/vespalib/src/vespa/vespalib/util/alloc.cpp
+++ b/vespalib/src/vespa/vespalib/util/alloc.cpp
@@ -381,6 +381,9 @@ MMapAllocator::sresize_inplace(PtrAndSize current, size_t newSize) {
size_t
MMapAllocator::extend_inplace(PtrAndSize current, size_t newSize) {
+ if (current.second == 0u) {
+ return 0u;
+ }
PtrAndSize got = MMapAllocator::salloc(newSize - current.second, static_cast<char *>(current.first)+current.second);
if ((static_cast<const char *>(current.first) + current.second) == static_cast<const char *>(got.first)) {
return current.second + got.second;
@@ -477,6 +480,9 @@ Alloc::allocHeap(size_t sz)
bool
Alloc::resize_inplace(size_t newSize)
{
+ if (newSize == 0u) {
+ return size() == 0u;
+ }
size_t extendedSize = _allocator->resize_inplace(_alloc, newSize);
if (extendedSize >= newSize) {
_alloc.second = extendedSize;