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

[t:2949] Revert memory status to old design to avoid issues in portability...

[t:2949] Revert memory status to old design to avoid issues in portability layer, make translation to new system in ydb.c.  Refs #2949.

git-svn-id: file:///svn/toku/tokudb@39389 c7de825b-a66e-492c-adef-691d508d4ae1
parent 599cedfb
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
#ident "Copyright (c) 2007-2011 Tokutek Inc. All rights reserved." #ident "Copyright (c) 2007-2011 Tokutek Inc. All rights reserved."
#include <toku_portability.h> #include <toku_portability.h>
#include "db.h" // get Toku-specific version of db.h
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -18,51 +16,7 @@ static free_fun_t t_free = 0; ...@@ -18,51 +16,7 @@ static free_fun_t t_free = 0;
static realloc_fun_t t_realloc = 0; static realloc_fun_t t_realloc = 0;
static realloc_fun_t t_xrealloc = 0; static realloc_fun_t t_xrealloc = 0;
/////////////////////////////////////////////////////////////////////////////////// static LOCAL_MEMORY_STATUS_S status;
// Engine status
//
// Status is intended for display to humans to help understand system behavior.
// It does not need to be perfectly thread-safe.
static MEMORY_STATUS_S memory_status;
static volatile uint64_t max_in_use; // maximum memory footprint (used - freed), approximate (not worth threadsafety overhead for exact, but worth keeping as volatile)
#define STATUS_INIT(k,t,l) { \
memory_status.status[k].keyname = #k; \
memory_status.status[k].type = t; \
memory_status.status[k].legend = "memory: " l; \
}
static void
status_init(void) {
// Note, this function initializes the keyname, type, and legend fields.
// Value fields are initialized to zero by compiler.
STATUS_INIT(MEMORY_MALLOC_COUNT, UINT64, "number of malloc operations");
STATUS_INIT(MEMORY_FREE_COUNT, UINT64, "number of free operations");
STATUS_INIT(MEMORY_REALLOC_COUNT, UINT64, "number of realloc operations");
STATUS_INIT(MEMORY_MALLOC_FAIL, UINT64, "number of malloc operations that failed");
STATUS_INIT(MEMORY_REALLOC_FAIL, UINT64, "number of realloc operations that failed" );
STATUS_INIT(MEMORY_REQUESTED, UINT64, "number of bytes requested");
STATUS_INIT(MEMORY_USED, UINT64, "number of bytes used (requested + overhead)");
STATUS_INIT(MEMORY_FREED, UINT64, "number of bytes freed");
STATUS_INIT(MEMORY_MAX_IN_USE, UINT64, "estimated maximum memory footprint");
STATUS_INIT(MEMORY_MALLOCATOR_VERSION, CHARSTR, "mallocator version");
STATUS_INIT(MEMORY_MMAP_THRESHOLD, UINT64, "mmap threshold");
memory_status.initialized = 1; // TODO 2949 Make this a bool, set to true
}
#undef STATUS_INIT
#define STATUS_VALUE(x) memory_status.status[x].value.num
void
toku_memory_get_status(MEMORY_STATUS statp) {
if (!memory_status.initialized)
status_init();
STATUS_VALUE(MEMORY_MAX_IN_USE) = max_in_use;
*statp = memory_status;
}
#define STATUS_VERSION_STRING memory_status.status[MEMORY_MALLOCATOR_VERSION].value.str
int int
toku_memory_startup(void) { toku_memory_startup(void) {
...@@ -72,8 +26,8 @@ toku_memory_startup(void) { ...@@ -72,8 +26,8 @@ toku_memory_startup(void) {
size_t mmap_threshold = 64 * 1024; // 64K and larger should be malloced with mmap(). size_t mmap_threshold = 64 * 1024; // 64K and larger should be malloced with mmap().
int success = mallopt(M_MMAP_THRESHOLD, mmap_threshold); int success = mallopt(M_MMAP_THRESHOLD, mmap_threshold);
if (success) { if (success) {
STATUS_VERSION_STRING = "libc"; status.mallocator_version = "libc";
STATUS_VALUE(MEMORY_MMAP_THRESHOLD) = mmap_threshold; status.mmap_threshold = mmap_threshold;
} else } else
result = EINVAL; result = EINVAL;
...@@ -84,14 +38,14 @@ toku_memory_startup(void) { ...@@ -84,14 +38,14 @@ toku_memory_startup(void) {
mallctl_fun_t mallctl_f; mallctl_fun_t mallctl_f;
mallctl_f = (mallctl_fun_t) dlsym(RTLD_DEFAULT, "mallctl"); mallctl_f = (mallctl_fun_t) dlsym(RTLD_DEFAULT, "mallctl");
if (mallctl_f) { // jemalloc is loaded if (mallctl_f) { // jemalloc is loaded
size_t version_length = sizeof STATUS_VERSION_STRING; size_t version_length = sizeof status.mallocator_version;
result = mallctl_f("version", &STATUS_VERSION_STRING, &version_length, NULL, 0); result = mallctl_f("version", &status.mallocator_version, &version_length, NULL, 0);
if (result == 0) { if (result == 0) {
size_t lg_chunk; // log2 of the mmap threshold size_t lg_chunk; // log2 of the mmap threshold
size_t lg_chunk_length = sizeof lg_chunk; size_t lg_chunk_length = sizeof lg_chunk;
result = mallctl_f("opt.lg_chunk", &lg_chunk, &lg_chunk_length, NULL, 0); result = mallctl_f("opt.lg_chunk", &lg_chunk, &lg_chunk_length, NULL, 0);
if (result == 0) if (result == 0)
STATUS_VALUE(MEMORY_MMAP_THRESHOLD) = 1 << lg_chunk; status.mmap_threshold = 1 << lg_chunk;
} }
} }
...@@ -102,6 +56,11 @@ void ...@@ -102,6 +56,11 @@ void
toku_memory_shutdown(void) { toku_memory_shutdown(void) {
} }
void
toku_memory_get_status(LOCAL_MEMORY_STATUS s) {
*s = status;
}
// jemalloc's malloc_usable_size does not work with a NULL pointer, so we implement a version that works // jemalloc's malloc_usable_size does not work with a NULL pointer, so we implement a version that works
static size_t static size_t
my_malloc_usable_size(void *p) { my_malloc_usable_size(void *p) {
...@@ -112,16 +71,16 @@ my_malloc_usable_size(void *p) { ...@@ -112,16 +71,16 @@ my_malloc_usable_size(void *p) {
// It is not worth the overhead to make it completely accurate, but // It is not worth the overhead to make it completely accurate, but
// this logic is intended to guarantee that it increases monotonically. // this logic is intended to guarantee that it increases monotonically.
// Note that status.sum_used and status.sum_freed increase monotonically // Note that status.sum_used and status.sum_freed increase monotonically
// and that max_in_use is declared volatile. // and that status.max_in_use is declared volatile.
static inline void static inline void
set_max(uint64_t sum_used, uint64_t sum_freed) { set_max(uint64_t sum_used, uint64_t sum_freed) {
if (sum_used >= sum_freed) { if (sum_used >= sum_freed) {
uint64_t in_use = sum_used - sum_freed; uint64_t in_use = sum_used - sum_freed;
uint64_t old_max; uint64_t old_max;
do { do {
old_max = max_in_use; old_max = status.max_in_use;
} while (old_max < in_use && } while (old_max < in_use &&
!__sync_bool_compare_and_swap(&max_in_use, old_max, in_use)); !__sync_bool_compare_and_swap(&status.max_in_use, old_max, in_use));
} }
} }
...@@ -133,7 +92,7 @@ toku_memory_footprint(void * p, size_t touched) { ...@@ -133,7 +92,7 @@ toku_memory_footprint(void * p, size_t touched) {
pagesize = sysconf(_SC_PAGESIZE); pagesize = sysconf(_SC_PAGESIZE);
if (p) { if (p) {
size_t usable = my_malloc_usable_size(p); size_t usable = my_malloc_usable_size(p);
if (usable >= STATUS_VALUE(MEMORY_MMAP_THRESHOLD)) { if (usable >= status.mmap_threshold) {
int num_pages = (touched + pagesize) / pagesize; int num_pages = (touched + pagesize) / pagesize;
rval = num_pages * pagesize; rval = num_pages * pagesize;
} }
...@@ -149,12 +108,12 @@ toku_malloc(size_t size) { ...@@ -149,12 +108,12 @@ 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);
if (p) { if (p) {
size_t used = my_malloc_usable_size(p); size_t used = my_malloc_usable_size(p);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_MALLOC_COUNT), 1); __sync_add_and_fetch(&status.malloc_count, 1);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_REQUESTED), size); __sync_add_and_fetch(&status.requested,size);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_USED), used); __sync_add_and_fetch(&status.used, used);
set_max(STATUS_VALUE(MEMORY_USED), STATUS_VALUE(MEMORY_FREED)); set_max(status.used, status.freed);
} else { } else {
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_MALLOC_FAIL), 1); __sync_add_and_fetch(&status.malloc_fail, 1);
} }
return p; return p;
} }
...@@ -173,13 +132,13 @@ toku_realloc(void *p, size_t size) { ...@@ -173,13 +132,13 @@ toku_realloc(void *p, size_t size) {
void *q = t_realloc ? t_realloc(p, size) : os_realloc(p, size); void *q = t_realloc ? t_realloc(p, size) : os_realloc(p, size);
if (q) { if (q) {
size_t used = my_malloc_usable_size(q); size_t used = my_malloc_usable_size(q);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_REALLOC_COUNT), 1); __sync_add_and_fetch(&status.realloc_count, 1);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_REQUESTED), size); __sync_add_and_fetch(&status.requested, size);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_USED), used); __sync_add_and_fetch(&status.used, used);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_FREED), used_orig); __sync_add_and_fetch(&status.freed, used_orig);
set_max(STATUS_VALUE(MEMORY_USED), STATUS_VALUE(MEMORY_FREED)); set_max(status.used, status.freed);
} else { } else {
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_REALLOC_FAIL), 1); __sync_add_and_fetch(&status.realloc_fail, 1);
} }
return q; return q;
} }
...@@ -200,8 +159,8 @@ void ...@@ -200,8 +159,8 @@ void
toku_free(void *p) { toku_free(void *p) {
if (p) { if (p) {
size_t used = my_malloc_usable_size(p); size_t used = my_malloc_usable_size(p);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_FREE_COUNT), 1); __sync_add_and_fetch(&status.free_count, 1);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_FREED), used); __sync_add_and_fetch(&status.freed, used);
if (t_free) if (t_free)
t_free(p); t_free(p);
else else
...@@ -220,10 +179,10 @@ toku_xmalloc(size_t size) { ...@@ -220,10 +179,10 @@ toku_xmalloc(size_t size) {
if (p == NULL) // avoid function call in common case if (p == NULL) // avoid function call in common case
resource_assert(p); resource_assert(p);
size_t used = my_malloc_usable_size(p); size_t used = my_malloc_usable_size(p);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_MALLOC_COUNT), 1); __sync_add_and_fetch(&status.malloc_count, 1);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_REQUESTED), size); __sync_add_and_fetch(&status.requested, size);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_USED), used); __sync_add_and_fetch(&status.used, used);
set_max(STATUS_VALUE(MEMORY_USED), STATUS_VALUE(MEMORY_FREED)); set_max(status.used, status.freed);
return p; return p;
} }
...@@ -242,11 +201,11 @@ toku_xrealloc(void *v, size_t size) { ...@@ -242,11 +201,11 @@ toku_xrealloc(void *v, size_t size) {
if (p == 0) // avoid function call in common case if (p == 0) // avoid function call in common case
resource_assert(p); resource_assert(p);
size_t used = my_malloc_usable_size(p); size_t used = my_malloc_usable_size(p);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_REALLOC_COUNT), 1); __sync_add_and_fetch(&status.realloc_count, 1);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_REQUESTED), size); __sync_add_and_fetch(&status.requested, size);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_USED), used); __sync_add_and_fetch(&status.used, used);
__sync_add_and_fetch(&STATUS_VALUE(MEMORY_FREED), used_orig); __sync_add_and_fetch(&status.freed, used_orig);
set_max(STATUS_VALUE(MEMORY_USED), STATUS_VALUE(MEMORY_FREED)); set_max(status.used, status.freed);
return p; return p;
} }
...@@ -309,5 +268,5 @@ toku_set_func_free(free_fun_t f) { ...@@ -309,5 +268,5 @@ toku_set_func_free(free_fun_t f) {
void __attribute__((constructor)) toku_memory_drd_ignore(void); void __attribute__((constructor)) toku_memory_drd_ignore(void);
void void
toku_memory_drd_ignore(void) { toku_memory_drd_ignore(void) {
DRD_IGNORE_VAR(memory_status); DRD_IGNORE_VAR(status);
} }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
int main(void) { int main(void) {
toku_memory_startup(); toku_memory_startup();
MEMORY_STATUS_S s; LOCAL_MEMORY_STATUS_S s;
toku_memory_get_status(&s); toku_memory_get_status(&s);
printf("mallocator: %s\n", s.mallocator_version); printf("mallocator: %s\n", s.mallocator_version);
printf("mmap threshold: %" PRIu64 "\n", s.mmap_threshold); printf("mmap threshold: %" PRIu64 "\n", s.mmap_threshold);
......
...@@ -130,6 +130,7 @@ print_engine_status(DB_ENV * UU(env)) { ...@@ -130,6 +130,7 @@ print_engine_status(DB_ENV * UU(env)) {
static __attribute__((__unused__)) uint64_t static __attribute__((__unused__)) uint64_t
get_engine_status_val(DB_ENV * UU(env), char * keyname) { get_engine_status_val(DB_ENV * UU(env), char * keyname) {
uint64_t rval = 0;
#ifdef USE_TDB #ifdef USE_TDB
uint64_t nrows; uint64_t nrows;
env->get_engine_status_num_rows(env, &nrows); env->get_engine_status_num_rows(env, &nrows);
...@@ -141,7 +142,6 @@ get_engine_status_val(DB_ENV * UU(env), char * keyname) { ...@@ -141,7 +142,6 @@ get_engine_status_val(DB_ENV * UU(env), char * keyname) {
int r = env->get_engine_status (env, mystat, nrows, &redzone_state, &panic, panic_string, panic_string_len); int r = env->get_engine_status (env, mystat, nrows, &redzone_state, &panic, panic_string, panic_string_len);
CKERR(r); CKERR(r);
int found = 0; int found = 0;
uint64_t rval = 0;
for (uint64_t i = 0; i < nrows && !found; i++) { for (uint64_t i = 0; i < nrows && !found; i++) {
if (strcmp(keyname, mystat[i].keyname) == 0) { if (strcmp(keyname, mystat[i].keyname) == 0) {
found++; found++;
...@@ -149,8 +149,8 @@ get_engine_status_val(DB_ENV * UU(env), char * keyname) { ...@@ -149,8 +149,8 @@ get_engine_status_val(DB_ENV * UU(env), char * keyname) {
} }
} }
CKERR2(found, 1); CKERR2(found, 1);
return rval;
#endif #endif
return rval;
} }
......
...@@ -128,7 +128,7 @@ static YDB_LAYER_STATUS_S ydb_layer_status; ...@@ -128,7 +128,7 @@ static YDB_LAYER_STATUS_S ydb_layer_status;
ydb_layer_status.status[k].legend = l; \ ydb_layer_status.status[k].legend = l; \
} }
static void static void
status_init (void) { ydb_layer_status_init (void) {
// Note, this function initializes the keyname, type, and legend fields. // Note, this function initializes the keyname, type, and legend fields.
// Value fields are initialized to zero by compiler. // Value fields are initialized to zero by compiler.
...@@ -964,7 +964,7 @@ toku_env_open(DB_ENV * env, const char *home, u_int32_t flags, int mode) { ...@@ -964,7 +964,7 @@ toku_env_open(DB_ENV * env, const char *home, u_int32_t flags, int mode) {
need_rollback_cachefile = TRUE; need_rollback_cachefile = TRUE;
} }
status_init(); // do this before possibly upgrading, so upgrade work is counted in status counters ydb_layer_status_init(); // do this before possibly upgrading, so upgrade work is counted in status counters
LSN last_lsn_of_clean_shutdown_read_from_log = ZERO_LSN; LSN last_lsn_of_clean_shutdown_read_from_log = ZERO_LSN;
BOOL upgrade_in_progress = FALSE; BOOL upgrade_in_progress = FALSE;
...@@ -1977,7 +1977,11 @@ format_time(const time_t *timer, char *buf) { ...@@ -1977,7 +1977,11 @@ format_time(const time_t *timer, char *buf) {
} }
} }
// local status struct, used to concentrate file system information collected from various places ////////////////////////////////////////////////////////////////////////////////////////////////
// Local definition of status information from portability layer, which should not include db.h.
// Local status structs are used to concentrate file system information collected from various places
// and memory information collected from memory.c.
//
typedef enum { typedef enum {
FS_ENOSPC_REDZONE_STATE = 0, // possible values are enumerated by fs_redzone_state FS_ENOSPC_REDZONE_STATE = 0, // possible values are enumerated by fs_redzone_state
FS_ENOSPC_THREADS_BLOCKED, // how many threads currently blocked on ENOSPC FS_ENOSPC_THREADS_BLOCKED, // how many threads currently blocked on ENOSPC
...@@ -2042,6 +2046,76 @@ fs_get_status(DB_ENV * env, fs_redzone_state * redzone_state) { ...@@ -2042,6 +2046,76 @@ fs_get_status(DB_ENV * env, fs_redzone_state * redzone_state) {
} }
#undef FS_STATUS_VALUE #undef FS_STATUS_VALUE
// Local status struct used to get information from memory.c
typedef enum {
MEMORY_MALLOC_COUNT = 0,
MEMORY_FREE_COUNT,
MEMORY_REALLOC_COUNT,
MEMORY_MALLOC_FAIL,
MEMORY_REALLOC_FAIL,
MEMORY_REQUESTED,
MEMORY_USED,
MEMORY_FREED,
MEMORY_MAX_IN_USE,
MEMORY_MALLOCATOR_VERSION,
MEMORY_MMAP_THRESHOLD,
MEMORY_STATUS_NUM_ROWS
} memory_status_entry;
typedef struct {
BOOL initialized;
TOKU_ENGINE_STATUS_ROW_S status[MEMORY_STATUS_NUM_ROWS];
} MEMORY_STATUS_S, *MEMORY_STATUS;
static MEMORY_STATUS_S memory_status;
#define STATUS_INIT(k,t,l) { \
memory_status.status[k].keyname = #k; \
memory_status.status[k].type = t; \
memory_status.status[k].legend = "memory: " l; \
}
static void
memory_status_init(void) {
// Note, this function initializes the keyname, type, and legend fields.
// Value fields are initialized to zero by compiler.
STATUS_INIT(MEMORY_MALLOC_COUNT, UINT64, "number of malloc operations");
STATUS_INIT(MEMORY_FREE_COUNT, UINT64, "number of free operations");
STATUS_INIT(MEMORY_REALLOC_COUNT, UINT64, "number of realloc operations");
STATUS_INIT(MEMORY_MALLOC_FAIL, UINT64, "number of malloc operations that failed");
STATUS_INIT(MEMORY_REALLOC_FAIL, UINT64, "number of realloc operations that failed" );
STATUS_INIT(MEMORY_REQUESTED, UINT64, "number of bytes requested");
STATUS_INIT(MEMORY_USED, UINT64, "number of bytes used (requested + overhead)");
STATUS_INIT(MEMORY_FREED, UINT64, "number of bytes freed");
STATUS_INIT(MEMORY_MAX_IN_USE, UINT64, "estimated maximum memory footprint");
STATUS_INIT(MEMORY_MALLOCATOR_VERSION, CHARSTR, "mallocator version");
STATUS_INIT(MEMORY_MMAP_THRESHOLD, UINT64, "mmap threshold");
memory_status.initialized = true;
}
#undef STATUS_INIT
#define MEMORY_STATUS_VALUE(x) memory_status.status[x].value.num
static void
memory_get_status(void) {
if (!memory_status.initialized)
memory_status_init();
LOCAL_MEMORY_STATUS_S local_memstat;
MEMORY_STATUS_VALUE(MEMORY_MALLOC_COUNT) = local_memstat.malloc_count;
MEMORY_STATUS_VALUE(MEMORY_FREE_COUNT) = local_memstat.free_count;
MEMORY_STATUS_VALUE(MEMORY_REALLOC_COUNT) = local_memstat.realloc_count;
MEMORY_STATUS_VALUE(MEMORY_MALLOC_FAIL) = local_memstat.malloc_fail;
MEMORY_STATUS_VALUE(MEMORY_REALLOC_FAIL) = local_memstat.realloc_fail;
MEMORY_STATUS_VALUE(MEMORY_REQUESTED) = local_memstat.requested;
MEMORY_STATUS_VALUE(MEMORY_USED) = local_memstat.used;
MEMORY_STATUS_VALUE(MEMORY_FREED) = local_memstat.freed;
MEMORY_STATUS_VALUE(MEMORY_MAX_IN_USE) = local_memstat.max_in_use;
MEMORY_STATUS_VALUE(MEMORY_MMAP_THRESHOLD) = local_memstat.mmap_threshold;
memory_status.status[MEMORY_MALLOCATOR_VERSION].value.str = local_memstat.mallocator_version;
}
#undef MEMORY_STATUS_VALUE
// how many rows are in engine status? // how many rows are in engine status?
static int static int
env_get_engine_status_num_rows (DB_ENV * UU(env), uint64_t * num_rowsp) { env_get_engine_status_num_rows (DB_ENV * UU(env), uint64_t * num_rowsp) {
...@@ -2193,10 +2267,10 @@ env_get_engine_status (DB_ENV * env, TOKU_ENGINE_STATUS_ROW engstat, uint64_t ma ...@@ -2193,10 +2267,10 @@ env_get_engine_status (DB_ENV * env, TOKU_ENGINE_STATUS_ROW engstat, uint64_t ma
} }
{ {
MEMORY_STATUS_S memorystat; // memory_status is local to this file
toku_memory_get_status(&memorystat); memory_get_status();
for (int i = 0; i < MEMORY_STATUS_NUM_ROWS && row < maxrows; i++) { for (int i = 0; i < MEMORY_STATUS_NUM_ROWS && row < maxrows; i++) {
engstat[row++] = memorystat.status[i]; engstat[row++] = memory_status.status[i];
} }
} }
{ {
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <toku_portability.h> #include <toku_portability.h>
#include <db.h>
#if defined(__cplusplus) || defined(__cilkplusplus) #if defined(__cplusplus) || defined(__cilkplusplus)
extern "C" { extern "C" {
...@@ -98,28 +97,21 @@ void toku_set_func_xrealloc_only(realloc_fun_t f); ...@@ -98,28 +97,21 @@ void toku_set_func_xrealloc_only(realloc_fun_t f);
void toku_set_func_realloc_only(realloc_fun_t f); void toku_set_func_realloc_only(realloc_fun_t f);
void toku_set_func_free(free_fun_t f); void toku_set_func_free(free_fun_t f);
typedef enum { typedef struct memory_status {
MEMORY_MALLOC_COUNT = 0, uint64_t malloc_count; // number of malloc operations
MEMORY_FREE_COUNT, uint64_t free_count; // number of free operations
MEMORY_REALLOC_COUNT, uint64_t realloc_count; // number of realloc operations
MEMORY_MALLOC_FAIL, uint64_t malloc_fail; // number of malloc operations that failed
MEMORY_REALLOC_FAIL, uint64_t realloc_fail; // number of realloc operations that failed
MEMORY_REQUESTED, uint64_t requested; // number of bytes requested
MEMORY_USED, uint64_t used; // number of bytes used (requested + overhead), obtained from malloc_usable_size()
MEMORY_FREED, uint64_t freed; // number of bytes freed;
MEMORY_MAX_IN_USE, volatile uint64_t max_in_use; // maximum memory footprint (used - freed), approximate (not worth threadsafety overhead for exact)
MEMORY_MALLOCATOR_VERSION, char *mallocator_version;
MEMORY_MMAP_THRESHOLD, uint64_t mmap_threshold;
MEMORY_STATUS_NUM_ROWS } LOCAL_MEMORY_STATUS_S, *LOCAL_MEMORY_STATUS;
} memory_status_entry;
void toku_memory_get_status(LOCAL_MEMORY_STATUS s);
typedef struct {
int initialized; // TODO 2949 make this a bool
TOKU_ENGINE_STATUS_ROW_S status[MEMORY_STATUS_NUM_ROWS];
} MEMORY_STATUS_S, *MEMORY_STATUS;
void toku_memory_get_status(MEMORY_STATUS s);
size_t toku_memory_footprint(void * p, size_t touched); size_t toku_memory_footprint(void * p, size_t touched);
......
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