Commit c436cfd2 authored by Barry Perlman's avatar Barry Perlman Committed by Yoni Fogel

[t:3825] #3825 Add max_mem_in_use to memory statistics.

git-svn-id: file:///svn/toku/tokudb@35067 c7de825b-a66e-492c-adef-691d508d4ae1
parent af0bfe6d
...@@ -210,6 +210,7 @@ typedef struct __toku_engine_status { ...@@ -210,6 +210,7 @@ typedef struct __toku_engine_status {
uint64_t mem_requested; /* number of bytes requested via malloc/realloc */ uint64_t mem_requested; /* number of bytes requested via malloc/realloc */
uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */ uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */
uint64_t mem_freed; /* number of bytes freed */ uint64_t mem_freed; /* number of bytes freed */
uint64_t max_mem_in_use; /* estimatd max value of (used - freed) */
} ENGINE_STATUS; } ENGINE_STATUS;
typedef enum { typedef enum {
DB_BTREE=1, DB_BTREE=1,
......
...@@ -210,6 +210,7 @@ typedef struct __toku_engine_status { ...@@ -210,6 +210,7 @@ typedef struct __toku_engine_status {
uint64_t mem_requested; /* number of bytes requested via malloc/realloc */ uint64_t mem_requested; /* number of bytes requested via malloc/realloc */
uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */ uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */
uint64_t mem_freed; /* number of bytes freed */ uint64_t mem_freed; /* number of bytes freed */
uint64_t max_mem_in_use; /* estimatd max value of (used - freed) */
} ENGINE_STATUS; } ENGINE_STATUS;
typedef enum { typedef enum {
DB_BTREE=1, DB_BTREE=1,
......
...@@ -210,6 +210,7 @@ typedef struct __toku_engine_status { ...@@ -210,6 +210,7 @@ typedef struct __toku_engine_status {
uint64_t mem_requested; /* number of bytes requested via malloc/realloc */ uint64_t mem_requested; /* number of bytes requested via malloc/realloc */
uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */ uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */
uint64_t mem_freed; /* number of bytes freed */ uint64_t mem_freed; /* number of bytes freed */
uint64_t max_mem_in_use; /* estimatd max value of (used - freed) */
} ENGINE_STATUS; } ENGINE_STATUS;
typedef enum { typedef enum {
DB_BTREE=1, DB_BTREE=1,
......
...@@ -210,6 +210,7 @@ typedef struct __toku_engine_status { ...@@ -210,6 +210,7 @@ typedef struct __toku_engine_status {
uint64_t mem_requested; /* number of bytes requested via malloc/realloc */ uint64_t mem_requested; /* number of bytes requested via malloc/realloc */
uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */ uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */
uint64_t mem_freed; /* number of bytes freed */ uint64_t mem_freed; /* number of bytes freed */
uint64_t max_mem_in_use; /* estimatd max value of (used - freed) */
} ENGINE_STATUS; } ENGINE_STATUS;
typedef enum { typedef enum {
DB_BTREE=1, DB_BTREE=1,
......
This diff is collapsed.
...@@ -603,6 +603,7 @@ int main (int argc __attribute__((__unused__)), char *const argv[] __attribute__ ...@@ -603,6 +603,7 @@ int main (int argc __attribute__((__unused__)), char *const argv[] __attribute__
printf(" uint64_t mem_requested; /* number of bytes requested via malloc/realloc */ \n"); printf(" uint64_t mem_requested; /* number of bytes requested via malloc/realloc */ \n");
printf(" uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */ \n"); printf(" uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */ \n");
printf(" uint64_t mem_freed; /* number of bytes freed */ \n"); printf(" uint64_t mem_freed; /* number of bytes freed */ \n");
printf(" uint64_t max_mem_in_use; /* estimated max value of (used - freed) */ \n");
printf("} ENGINE_STATUS;\n"); printf("} ENGINE_STATUS;\n");
print_dbtype(); print_dbtype();
......
...@@ -210,6 +210,7 @@ typedef struct __toku_engine_status { ...@@ -210,6 +210,7 @@ typedef struct __toku_engine_status {
uint64_t mem_requested; /* number of bytes requested via malloc/realloc */ uint64_t mem_requested; /* number of bytes requested via malloc/realloc */
uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */ uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */
uint64_t mem_freed; /* number of bytes freed */ uint64_t mem_freed; /* number of bytes freed */
uint64_t max_mem_in_use; /* estimatd max value of (used - freed) */
} ENGINE_STATUS; } ENGINE_STATUS;
typedef enum { typedef enum {
DB_BTREE=1, DB_BTREE=1,
......
...@@ -210,6 +210,7 @@ typedef struct __toku_engine_status { ...@@ -210,6 +210,7 @@ typedef struct __toku_engine_status {
uint64_t mem_requested; /* number of bytes requested via malloc/realloc */ uint64_t mem_requested; /* number of bytes requested via malloc/realloc */
uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */ uint64_t mem_used; /* number of bytes used (obtained from malloc_usable_size()) */
uint64_t mem_freed; /* number of bytes freed */ uint64_t mem_freed; /* number of bytes freed */
uint64_t max_mem_in_use; /* estimatd max value of (used - freed) */
} ENGINE_STATUS; } ENGINE_STATUS;
typedef enum { typedef enum {
DB_BTREE=1, DB_BTREE=1,
......
...@@ -2032,6 +2032,7 @@ env_get_engine_status(DB_ENV * env, ENGINE_STATUS * engstat, char * env_panic_st ...@@ -2032,6 +2032,7 @@ env_get_engine_status(DB_ENV * env, ENGINE_STATUS * engstat, char * env_panic_st
engstat->mem_requested = memory_status.requested; engstat->mem_requested = memory_status.requested;
engstat->mem_used = memory_status.used; engstat->mem_used = memory_status.used;
engstat->mem_freed = memory_status.freed; engstat->mem_freed = memory_status.freed;
engstat->max_mem_in_use = memory_status.max_in_use;
} }
} }
return r; return r;
...@@ -2213,6 +2214,7 @@ env_get_engine_status_text(DB_ENV * env, char * buff, int bufsiz) { ...@@ -2213,6 +2214,7 @@ env_get_engine_status_text(DB_ENV * env, char * buff, int bufsiz) {
n += snprintf(buff + n, bufsiz - n, "mem_requested %"PRIu64"\n", engstat.mem_requested); n += snprintf(buff + n, bufsiz - n, "mem_requested %"PRIu64"\n", engstat.mem_requested);
n += snprintf(buff + n, bufsiz - n, "mem_used %"PRIu64"\n", engstat.mem_used); n += snprintf(buff + n, bufsiz - n, "mem_used %"PRIu64"\n", engstat.mem_used);
n += snprintf(buff + n, bufsiz - n, "mem_freed %"PRIu64"\n", engstat.mem_freed); n += snprintf(buff + n, bufsiz - n, "mem_freed %"PRIu64"\n", engstat.mem_freed);
n += snprintf(buff + n, bufsiz - n, "max_mem_in_use %"PRIu64"\n", engstat.max_mem_in_use);
} }
if (n > bufsiz) { if (n > bufsiz) {
char * errmsg = "BUFFER TOO SMALL\n"; char * errmsg = "BUFFER TOO SMALL\n";
......
...@@ -116,6 +116,7 @@ typedef struct memory_status { ...@@ -116,6 +116,7 @@ typedef struct memory_status {
uint64_t requested; // number of bytes requested uint64_t requested; // number of bytes requested
uint64_t used; // number of bytes used (requested + overhead), obtained from malloc_usable_size() uint64_t used; // number of bytes used (requested + overhead), obtained from malloc_usable_size()
uint64_t freed; // number of bytes freed; uint64_t freed; // number of bytes freed;
uint64_t max_in_use; // maximum memory footprint (used - freed), approximate (not worth threadsafety overhead for exact)
} MEMORY_STATUS_S, *MEMORY_STATUS; } MEMORY_STATUS_S, *MEMORY_STATUS;
void toku_memory_get_status(MEMORY_STATUS s); void toku_memory_get_status(MEMORY_STATUS s);
......
...@@ -25,6 +25,17 @@ toku_memory_get_status(MEMORY_STATUS s) { ...@@ -25,6 +25,17 @@ toku_memory_get_status(MEMORY_STATUS s) {
} }
// 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.
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;
}
}
void *toku_malloc(size_t size) { void *toku_malloc(size_t size) {
void *p = t_malloc ? t_malloc(size) : os_malloc(size); void *p = t_malloc ? t_malloc(size) : os_malloc(size);
...@@ -32,7 +43,8 @@ void *toku_malloc(size_t size) { ...@@ -32,7 +43,8 @@ void *toku_malloc(size_t size) {
size_t used = malloc_usable_size(p); size_t used = malloc_usable_size(p);
__sync_add_and_fetch(&status.malloc_count, 1L); __sync_add_and_fetch(&status.malloc_count, 1L);
__sync_add_and_fetch(&status.requested, size); __sync_add_and_fetch(&status.requested, size);
__sync_add_and_fetch(&status.used, used); uint64_t sum_used = __sync_add_and_fetch(&status.used, used);
set_max(sum_used, status.freed);
} }
else else
__sync_add_and_fetch(&status.malloc_fail, 1L); __sync_add_and_fetch(&status.malloc_fail, 1L);
...@@ -55,8 +67,9 @@ toku_realloc(void *p, size_t size) { ...@@ -55,8 +67,9 @@ toku_realloc(void *p, size_t size) {
size_t used = malloc_usable_size(q); size_t used = malloc_usable_size(q);
__sync_add_and_fetch(&status.realloc_count, 1L); __sync_add_and_fetch(&status.realloc_count, 1L);
__sync_add_and_fetch(&status.requested, size); __sync_add_and_fetch(&status.requested, size);
__sync_add_and_fetch(&status.used, used); uint64_t sum_used = __sync_add_and_fetch(&status.used, used);
__sync_add_and_fetch(&status.freed, used_orig); uint64_t sum_freed = __sync_add_and_fetch(&status.freed, used_orig);
set_max(sum_used, sum_freed);
} }
else else
__sync_add_and_fetch(&status.realloc_fail, 1L); __sync_add_and_fetch(&status.realloc_fail, 1L);
...@@ -101,7 +114,8 @@ toku_xmalloc(size_t size) { ...@@ -101,7 +114,8 @@ toku_xmalloc(size_t size) {
size_t used = malloc_usable_size(p); size_t used = malloc_usable_size(p);
__sync_add_and_fetch(&status.malloc_count, 1L); __sync_add_and_fetch(&status.malloc_count, 1L);
__sync_add_and_fetch(&status.requested, size); __sync_add_and_fetch(&status.requested, size);
__sync_add_and_fetch(&status.used, used); uint64_t sum_used = __sync_add_and_fetch(&status.used, used);
set_max(sum_used, status.freed);
return p; return p;
} }
...@@ -122,8 +136,9 @@ toku_xrealloc(void *v, size_t size) { ...@@ -122,8 +136,9 @@ toku_xrealloc(void *v, size_t size) {
size_t used = malloc_usable_size(p); size_t used = malloc_usable_size(p);
__sync_add_and_fetch(&status.realloc_count, 1L); __sync_add_and_fetch(&status.realloc_count, 1L);
__sync_add_and_fetch(&status.requested, size); __sync_add_and_fetch(&status.requested, size);
__sync_add_and_fetch(&status.used, used); uint64_t sum_used = __sync_add_and_fetch(&status.used, used);
__sync_add_and_fetch(&status.freed, used_orig); uint64_t sum_freed = __sync_add_and_fetch(&status.freed, used_orig);
set_max(sum_used, sum_freed);
return p; return p;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment