Commit 45ebb26e authored by Barry Perlman's avatar Barry Perlman Committed by Yoni Fogel

[t:4181] #4181 Merge from tokudb.4181 to main. Improve memory accounting to...

[t:4181] #4181 Merge from tokudb.4181 to main.  Improve memory accounting to prevent resident set size (RSS) from exceeding allocation.

git-svn-id: file:///svn/toku/tokudb@37499 c7de825b-a66e-492c-adef-691d508d4ae1
parent 0b71e81c
......@@ -18,6 +18,10 @@ static realloc_fun_t t_xrealloc = 0;
static MEMORY_STATUS_S status;
//TODO 4222 Replace this hard-coded constant with supplied by mallocator.
// Perhaps make this work with libc as well.
static const size_t mmap_limit = 4 * 1024 * 1024;
void
toku_memory_get_status(MEMORY_STATUS s) {
if (status.mallocator_version == NULL) {
......@@ -52,6 +56,27 @@ set_max(uint64_t sum_used, uint64_t sum_freed) {
}
}
size_t toku_memory_footprint(void * p, size_t touched) {
static size_t pagesize = 0;
size_t rval = 0;
if (!pagesize)
pagesize = sysconf(_SC_PAGESIZE);
if (p) {
size_t usable = malloc_usable_size(p);
if (usable >= mmap_limit) {
int num_pages = (touched + pagesize) / pagesize;
rval = num_pages * pagesize;
}
else {
rval = usable;
}
}
return rval;
}
void *toku_malloc(size_t size) {
void *p = t_malloc ? t_malloc(size) : os_malloc(size);
if (p) {
......
......@@ -120,6 +120,7 @@ struct brtnode_nonleaf_childinfo {
unsigned int toku_bnc_nbytesinbuf(NONLEAF_CHILDINFO bnc);
int toku_bnc_n_entries(NONLEAF_CHILDINFO bnc);
long toku_bnc_memory_size(NONLEAF_CHILDINFO bnc);
long toku_bnc_memory_used(NONLEAF_CHILDINFO bnc);
int toku_bnc_insert_msg(NONLEAF_CHILDINFO bnc, const void *key, ITEMLEN keylen, const void *data, ITEMLEN datalen, int type, MSN msn, XIDS xids, bool is_fresh, DESCRIPTOR desc, brt_compare_func cmp);
void toku_bnc_empty(NONLEAF_CHILDINFO bnc);
int toku_bnc_flush_to_child(
......
......@@ -490,8 +490,21 @@ fetch_from_buf (OMT omt, u_int32_t idx) {
return (LEAFENTRY)v;
}
long
// how much memory does this child buffer consume?
long
toku_bnc_memory_size(NONLEAF_CHILDINFO bnc)
{
return (sizeof(*bnc) +
toku_fifo_memory_footprint(bnc->buffer) +
toku_omt_memory_size(bnc->fresh_message_tree) +
toku_omt_memory_size(bnc->stale_message_tree) +
toku_omt_memory_size(bnc->broadcast_list));
}
// how much memory in this child buffer holds useful data?
// originally created solely for use by test program(s).
long
toku_bnc_memory_used(NONLEAF_CHILDINFO bnc)
{
return (sizeof(*bnc) +
toku_fifo_memory_size_in_use(bnc->buffer) +
......@@ -573,7 +586,7 @@ brtnode_memory_size (BRTNODE node)
{
// include fragmentation overhead but do not include space in the
// mempool that has not yet been allocated for leaf entries
size_t poolsize = toku_mempool_get_allocated_space(&bn->buffer_mempool);
size_t poolsize = toku_mempool_footprint(&bn->buffer_mempool);
invariant (poolsize >= BLB_NBYTESINBUF(node,i));
retval += poolsize;
}
......
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "$Id$"
#ident "Copyright (c) 2007-2010 Tokutek Inc. All rights reserved."
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
......@@ -208,6 +209,12 @@ unsigned long toku_fifo_memory_size_in_use(FIFO fifo) {
return sizeof(*fifo)+fifo->memory_start+fifo->memory_used;
}
unsigned long toku_fifo_memory_footprint(FIFO fifo) {
size_t size_used = toku_memory_footprint(fifo->memory, fifo->memory_start+fifo->memory_used);
long rval = sizeof(*fifo) + size_used;
return rval;
}
unsigned long toku_fifo_memory_size(FIFO fifo) {
return sizeof(*fifo)+fifo->memory_size;
}
......
......@@ -56,7 +56,9 @@ int toku_fifo_deq(FIFO); // we cannot deq items anymore, since their offsets ar
// THIS ONLY REMAINS FOR TESTING, DO NOT USE IT IN CODE
int toku_fifo_empty(FIFO); // don't deallocate the memory for the fifo
unsigned long toku_fifo_memory_size_in_use(FIFO fifo); // return how much memory the fifo uses.
unsigned long toku_fifo_memory_size_in_use(FIFO fifo); // return how much memory in the fifo holds useful data
unsigned long toku_fifo_memory_footprint(FIFO fifo); // return how much memory the fifo occupies
unsigned long toku_fifo_memory_size(FIFO); // return how much memory fifo has allocated
......
......@@ -130,3 +130,10 @@ void toku_mempool_mfree(struct mempool *mp, void *vp, size_t size) {
}
/* get memory footprint */
size_t toku_mempool_footprint(struct mempool *mp) {
void * base = mp->base;
size_t touched = mp->free_offset;
size_t rval = toku_memory_footprint(base, touched);
return rval;
}
......@@ -80,6 +80,9 @@ static inline int toku_mempool_inrange(struct mempool *mp, void *vp, size_t size
return (mp->base <= vp) && ((char *)vp + size <= (char *)mp->base + mp->size);
}
/* get memory footprint */
size_t toku_mempool_footprint(struct mempool *mp);
#if defined(__cplusplus) || defined(__cilkplusplus)
};
#endif
......
......@@ -232,13 +232,13 @@ flush_to_internal(BRT t) {
NONLEAF_CHILDINFO child_bnc = toku_create_empty_nl();
int i;
for (i = 0; toku_bnc_memory_size(child_bnc) < 4*M; ++i) {
for (i = 0; toku_bnc_memory_used(child_bnc) < 4*M; ++i) {
insert_random_message(child_bnc, &child_messages[i], &child_messages_is_fresh[i], xids_123, 0);
}
int num_child_messages = i;
NONLEAF_CHILDINFO parent_bnc = toku_create_empty_nl();
for (i = 0; toku_bnc_memory_size(parent_bnc) < 4*M; ++i) {
for (i = 0; toku_bnc_memory_used(parent_bnc) < 4*M; ++i) {
insert_random_message(parent_bnc, &parent_messages[i], &parent_messages_is_fresh[i], xids_234, 0);
}
int num_parent_messages = i;
......@@ -355,9 +355,9 @@ flush_to_internal_multiple(BRT t) {
}
int total_size = 0;
for (i = 0; total_size < 4*M; ++i) {
total_size -= toku_bnc_memory_size(child_bncs[i%8]);
total_size -= toku_bnc_memory_used(child_bncs[i%8]);
insert_random_message(child_bncs[i%8], &child_messages[i], &child_messages_is_fresh[i], xids_123, i%8);
total_size += toku_bnc_memory_size(child_bncs[i%8]);
total_size += toku_bnc_memory_used(child_bncs[i%8]);
if (i % 8 < 7) {
if (childkeys[i%8] == NULL || dummy_cmp(NULL, child_messages[i]->u.id.key, childkeys[i%8]->u.id.key) > 0) {
childkeys[i%8] = child_messages[i];
......@@ -367,7 +367,7 @@ flush_to_internal_multiple(BRT t) {
int num_child_messages = i;
NONLEAF_CHILDINFO parent_bnc = toku_create_empty_nl();
for (i = 0; toku_bnc_memory_size(parent_bnc) < 4*M; ++i) {
for (i = 0; toku_bnc_memory_used(parent_bnc) < 4*M; ++i) {
insert_random_message(parent_bnc, &parent_messages[i], &parent_messages_is_fresh[i], xids_234, 0);
}
int num_parent_messages = i;
......@@ -535,7 +535,7 @@ flush_to_leaf(BRT t, bool make_leaf_up_to_date, bool use_flush) {
}
NONLEAF_CHILDINFO parent_bnc = toku_create_empty_nl();
MSN max_parent_msn = MIN_MSN;
for (i = 0; toku_bnc_memory_size(parent_bnc) < 4*M; ++i) {
for (i = 0; toku_bnc_memory_used(parent_bnc) < 4*M; ++i) {
insert_random_update_message(parent_bnc, &parent_messages[i], parent_messages_is_fresh[i], xids_234, i%8, &parent_messages_applied[i], &max_parent_msn);
}
int num_parent_messages = i;
......@@ -752,7 +752,7 @@ flush_to_leaf_with_keyrange(BRT t, bool make_leaf_up_to_date) {
}
NONLEAF_CHILDINFO parent_bnc = toku_create_empty_nl();
MSN max_parent_msn = MIN_MSN;
for (i = 0; toku_bnc_memory_size(parent_bnc) < 4*M; ++i) {
for (i = 0; toku_bnc_memory_used(parent_bnc) < 4*M; ++i) {
insert_random_update_message(parent_bnc, &parent_messages[i], parent_messages_is_fresh[i], xids_234, i%8, &parent_messages_applied[i], &max_parent_msn);
}
int num_parent_messages = i;
......@@ -932,7 +932,7 @@ compare_apply_and_flush(BRT t, bool make_leaf_up_to_date) {
}
NONLEAF_CHILDINFO parent_bnc = toku_create_empty_nl();
MSN max_parent_msn = MIN_MSN;
for (i = 0; toku_bnc_memory_size(parent_bnc) < 4*M; ++i) {
for (i = 0; toku_bnc_memory_used(parent_bnc) < 4*M; ++i) {
insert_random_update_message(parent_bnc, &parent_messages[i], parent_messages_is_fresh[i], xids_234, i%8, &parent_messages_applied[i], &max_parent_msn);
}
int num_parent_messages = i;
......
......@@ -109,6 +109,8 @@ typedef struct memory_status {
void toku_memory_get_status(MEMORY_STATUS s);
size_t toku_memory_footprint(void * p, size_t touched);
#if defined(__cplusplus) || defined(__cilkplusplus)
}
#endif
......
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