diff --git a/src/common/classes/alloc.cpp b/src/common/classes/alloc.cpp index 9d6e953e63..6521182f1f 100644 --- a/src/common/classes/alloc.cpp +++ b/src/common/classes/alloc.cpp @@ -213,29 +213,41 @@ static void print_block(FILE *file, MemoryBlock *blk, bool used_only, inline void MemoryPool::increment_usage(size_t size) { - size_t temp = stats->mst_usage += size; - if (temp > stats->mst_max_usage) - stats->mst_max_usage = temp; + for (MemoryStats* statistics = stats; statistics; statistics = statistics->mst_parent) + { + size_t temp = statistics->mst_usage += size; + if (temp > statistics->mst_max_usage) + statistics->mst_max_usage = temp; + } used_memory += size; } inline void MemoryPool::decrement_usage(size_t size) { - stats->mst_usage -= size; + for (MemoryStats* statistics = stats; statistics; statistics = statistics->mst_parent) + { + statistics->mst_usage -= size; + } used_memory -= size; } inline void MemoryPool::increment_mapping(size_t size) { - size_t temp = stats->mst_mapped += size; - if (temp > stats->mst_max_mapped) - stats->mst_max_mapped = temp; + for (MemoryStats* statistics = stats; statistics; statistics = statistics->mst_parent) + { + size_t temp = statistics->mst_mapped += size; + if (temp > statistics->mst_max_mapped) + statistics->mst_max_mapped = temp; + } mapped_memory += size; } inline void MemoryPool::decrement_mapping(size_t size) { - stats->mst_mapped -= size; + for (MemoryStats* statistics = stats; statistics; statistics = statistics->mst_parent) + { + statistics->mst_mapped -= size; + } mapped_memory -= size; } diff --git a/src/common/classes/alloc.h b/src/common/classes/alloc.h index 8a4b90dd85..e7068433b6 100644 --- a/src/common/classes/alloc.h +++ b/src/common/classes/alloc.h @@ -170,15 +170,24 @@ struct PendingFreeBlock class MemoryStats { public: - MemoryStats() : mst_usage(0), mst_mapped(0), mst_max_usage(0), mst_max_mapped(0) {} - ~MemoryStats() {} - size_t get_current_usage() const { return mst_usage.value(); } - size_t get_maximum_usage() const { return mst_max_usage; } - size_t get_current_mapping() const { return mst_mapped.value(); } - size_t get_maximum_mapping() const { return mst_max_mapped; } + explicit MemoryStats(MemoryStats* parent = NULL) + : mst_parent(parent), mst_usage(0), mst_mapped(0), mst_max_usage(0), mst_max_mapped(0) + {} + + ~MemoryStats() + {} + + size_t getCurrentUsage() const { return mst_usage.value(); } + size_t getMaximumUsage() const { return mst_max_usage; } + size_t getCurrentMapping() const { return mst_mapped.value(); } + size_t getMaximumMapping() const { return mst_max_mapped; } + private: - // Forbid copy constructor - MemoryStats(const MemoryStats& object) {} + // Forbid copying/assignment + MemoryStats(const MemoryStats&); + MemoryStats& operator=(const MemoryStats&); + + MemoryStats* mst_parent; // Currently allocated memory (without allocator overhead) // Useful for monitoring engine memory leaks @@ -186,12 +195,12 @@ private: // Amount of memory mapped (including all overheads) // Useful for monitoring OS memory consumption AtomicCounter mst_mapped; - + // We don't particularily care about extreme precision of these max values, // this is why we don't synchronize them on Windows size_t mst_max_usage; size_t mst_max_mapped; - + friend class MemoryPool; };