diff options
6 files changed, 41 insertions, 30 deletions
diff --git a/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.cpp b/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.cpp index 85b2a7a4b99..c56db96ee8d 100644 --- a/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.cpp +++ b/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.cpp @@ -14,10 +14,11 @@ ResourceUsageMetrics::ResourceUsageMetrics(metrics::MetricSet *parent) transient_disk("transient_disk", {}, "The relative amount of transient disk needed for running disk index fusion. Max value among all disk indexes (value in the range [0, 1])", this), memoryMappings("memory_mappings", {}, "The number of mapped memory areas", this), openFileDescriptors("open_file_descriptors", {}, "The number of open files", this), - feedingBlocked("feeding_blocked", {}, "Whether feeding is blocked due to resource limits being reached (value is either 0 or 1)", this) + feedingBlocked("feeding_blocked", {}, "Whether feeding is blocked due to resource limits being reached (value is either 0 or 1)", this), + mallocArena("malloc_arena", {}, "Size of malloc arena", this) { } -ResourceUsageMetrics::~ResourceUsageMetrics() {} +ResourceUsageMetrics::~ResourceUsageMetrics() = default; } // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.h b/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.h index 038d9149b3b..acadeba8372 100644 --- a/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.h +++ b/searchcore/src/vespa/searchcore/proton/metrics/resource_usage_metrics.h @@ -21,6 +21,7 @@ struct ResourceUsageMetrics : metrics::MetricSet metrics::LongValueMetric memoryMappings; metrics::LongValueMetric openFileDescriptors; metrics::LongValueMetric feedingBlocked; + metrics::LongValueMetric mallocArena; ResourceUsageMetrics(metrics::MetricSet *parent); ~ResourceUsageMetrics(); diff --git a/searchcore/src/vespa/searchcore/proton/server/proton.cpp b/searchcore/src/vespa/searchcore/proton/server/proton.cpp index 26e1bc8b951..139df7f8799 100644 --- a/searchcore/src/vespa/searchcore/proton/server/proton.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/proton.cpp @@ -40,6 +40,7 @@ #include <vespa/vespalib/util/mmap_file_allocator_factory.h> #include <vespa/vespalib/util/random.h> #include <vespa/vespalib/util/size_literals.h> +#include <malloc.h> #include <vespa/searchlib/aggregation/forcelink.hpp> #include <vespa/searchlib/expression/forcelink.hpp> @@ -763,6 +764,10 @@ Proton::updateMetrics(const metrics::MetricLockGuard &) metrics.resourceUsage.memoryMappings.set(usageFilter.getMemoryStats().getMappingsCount()); metrics.resourceUsage.openFileDescriptors.set(FastOS_File::count_open_files()); metrics.resourceUsage.feedingBlocked.set((usageFilter.acceptWriteOperation() ? 0.0 : 1.0)); + struct mallinfo mallocInfo = mallinfo(); + // Vespamalloc reports arena in 1M blocks as an 'int' is too small. + // If we use something else than vespamalloc this must be changed. + metrics.resourceUsage.mallocArena.set(uint64_t(mallocInfo.arena) << 20); } { ContentProtonMetrics::ProtonExecutorMetrics &metrics = _metricsEngine->root().executor; diff --git a/vespamalloc/src/tests/stacktrace/stacktrace.cpp b/vespamalloc/src/tests/stacktrace/stacktrace.cpp index e7c53fa5c3f..957f05d9b66 100644 --- a/vespamalloc/src/tests/stacktrace/stacktrace.cpp +++ b/vespamalloc/src/tests/stacktrace/stacktrace.cpp @@ -4,6 +4,7 @@ #include <pthread.h> #include <dlfcn.h> #include <cassert> +#include <malloc.h> void * run(void * arg) { @@ -16,7 +17,18 @@ void * run(void * arg) } void verify_that_vespamalloc_datasegment_size_exists() { - assert(dlsym(RTLD_NEXT, "vespamalloc_datasegment_size") != nullptr); + struct mallinfo info = mallinfo(); + printf("Malloc used %dm of memory\n",info.arena); + assert(info.arena == 24); + assert(info.fordblks == 0); + assert(info.fsmblks == 0); + assert(info.hblkhd == 0); + assert(info.hblks == 0); + assert(info.keepcost == 0); + assert(info.ordblks == 0); + assert(info.smblks == 0); + assert(info.uordblks == 0); + assert(info.usmblks == 0); } int main(int argc, char *argv[]) diff --git a/vespamalloc/src/vespamalloc/malloc/overload.h b/vespamalloc/src/vespamalloc/malloc/overload.h index f9c51582fb9..ca3a76b705b 100644 --- a/vespamalloc/src/vespamalloc/malloc/overload.h +++ b/vespamalloc/src/vespamalloc/malloc/overload.h @@ -5,6 +5,7 @@ #include <errno.h> #include <new> #include <stdlib.h> +#include <malloc.h> class CreateAllocator { @@ -105,9 +106,20 @@ void operator delete[](void* ptr, std::size_t sz, std::align_val_t alignment) no extern "C" { -unsigned long vespamalloc_datasegment_size() __attribute__((visibility ("default"))); -unsigned long vespamalloc_datasegment_size() { - return vespamalloc::_GmemP->dataSegment().dataSize(); +struct mallinfo mallinfo() __THROW __attribute__((visibility ("default"))); +struct mallinfo mallinfo() __THROW { + struct mallinfo info; + info.arena = (vespamalloc::_GmemP->dataSegment().dataSize() >> 20); // Note reporting in 1M blocks + info.ordblks = 0; + info.smblks = 0; + info.hblks = 0; + info.hblkhd = 0; + info.usmblks = 0; + info.fsmblks = 0; + info.uordblks = 0; + info.fordblks = 0; + info.keepcost = 0; + return info; } void * malloc(size_t sz) { @@ -124,8 +136,8 @@ void * realloc(void * ptr, size_t sz) return vespamalloc::createAllocator()->realloc(ptr, sz); } -void* memalign(size_t align, size_t sz) __attribute__((visibility ("default"))); -void* memalign(size_t align, size_t sz) +void* memalign(size_t align, size_t sz) __THROW __attribute__((visibility ("default"))); +void* memalign(size_t align, size_t sz) __THROW { void *ptr(nullptr); size_t align_1(align - 1); @@ -137,7 +149,6 @@ void* memalign(size_t align, size_t sz) } int posix_memalign(void** ptr, size_t align, size_t sz) __THROW __nonnull((1)) __attribute__((visibility ("default"))); - int posix_memalign(void** ptr, size_t align, size_t sz) __THROW { int retval(0); @@ -186,7 +197,8 @@ void cfree(void *) __THROW __attribute__((leaf void __libc_free(void* ptr) __THROW __attribute__((leaf)) ALIAS("free"); void __libc_cfree(void* ptr) __THROW __attribute__((leaf)) ALIAS("cfree"); #endif -void* __libc_memalign(size_t align, size_t s) ALIAS("memalign"); +struct mallinfo __libc_mallinfo() __THROW ALIAS("mallinfo"); +void* __libc_memalign(size_t align, size_t s) __THROW __attribute__((leaf, malloc, alloc_size(2))) ALIAS("memalign"); int __posix_memalign(void** r, size_t a, size_t s) __THROW __nonnull((1)) ALIAS("posix_memalign"); #undef ALIAS diff --git a/vespamalloc/src/vespamalloc/malloc/vespamalloc.h b/vespamalloc/src/vespamalloc/malloc/vespamalloc.h deleted file mode 100644 index 4dbadf8a26e..00000000000 --- a/vespamalloc/src/vespamalloc/malloc/vespamalloc.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -/** - * Contains the interfaces that vespamalloc offers in addition to the standard - * allocation interfaces like malloc, calloc, free, new, delete, etc. - * Use dlsym(RTLD_NEXT, "function_name") to ensure the existence of the interface. - **/ - -extern "C" { - -/** - * Reports the amount of memory vespamalloc uses. It is actually the size of the datasegment. - * This is the peak memory usage during process lifetime, and does not differentiate between malloced or freed memory. - * This is cheap to call - **/ -unsigned long vespamalloc_datasegment_size(); - -} |