From 46e2eba914f51018df7efafd38ce3d14f45b2ea0 Mon Sep 17 00:00:00 2001 From: Barry Perlman Date: Wed, 17 Apr 2013 00:00:01 -0400 Subject: [PATCH] [t:4181] #4181 Make memory accounting a little cleaner. git-svn-id: file:///svn/toku/tokudb@38050 c7de825b-a66e-492c-adef-691d508d4ae1 --- linux/memory.c | 18 ++++++++++++------ toku_include/memory.h | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/linux/memory.c b/linux/memory.c index ab459d3fac7..21a8670c26b 100644 --- a/linux/memory.c +++ b/linux/memory.c @@ -67,14 +67,20 @@ my_malloc_usable_size(void *p) { return p == NULL ? 0 : malloc_usable_size(p); } -// max_in_use may be slightly off because use of max_in_use is not thread-safe. -// It is not worth the overhead to make it completely accurate. +// Note that max_in_use may be slightly off because use of max_in_use is not thread-safe. +// It is not worth the overhead to make it completely accurate, but +// this logic is intended to guarantee that it increases monotonically. +// Note that status.sum_used and status.sum_freed increase monotonically +// and that status.max_in_use is declared volatile. static inline void set_max(uint64_t sum_used, uint64_t sum_freed) { - uint64_t in_use = (sum_used - sum_freed); - if ((!(in_use & 0x8000000000000000)) // if wrap due to another thread, ignore bogus "negative" value - && (in_use > status.max_in_use)) { - status.max_in_use = in_use; + if (sum_used >= sum_freed) { + uint64_t in_use = sum_used - sum_freed; + uint64_t old_max; + do { + old_max = status.max_in_use; + } while (old_max < in_use && + !__sync_bool_compare_and_swap(&status.max_in_use, old_max, in_use)); } } diff --git a/toku_include/memory.h b/toku_include/memory.h index 430bb2c2fd3..bd66896198a 100644 --- a/toku_include/memory.h +++ b/toku_include/memory.h @@ -106,7 +106,7 @@ typedef struct memory_status { uint64_t requested; // number of bytes requested uint64_t used; // number of bytes used (requested + overhead), obtained from malloc_usable_size() uint64_t freed; // number of bytes freed; - uint64_t max_in_use; // maximum memory footprint (used - freed), approximate (not worth threadsafety overhead for exact) + volatile uint64_t max_in_use; // maximum memory footprint (used - freed), approximate (not worth threadsafety overhead for exact) const char *mallocator_version; uint64_t mmap_threshold; } MEMORY_STATUS_S, *MEMORY_STATUS;