diff options
author | Keith Bostic <keith@wiredtiger.com> | 2015-01-22 17:08:00 -0500 |
---|---|---|
committer | Keith Bostic <keith@wiredtiger.com> | 2015-01-22 17:08:00 -0500 |
commit | 23eac61d89dae1f875287f888ceb833b88b89b5f (patch) | |
tree | 241b18a168c9ff32b4b58d25b405310f5fc34507 /src | |
parent | 7835fd35b597cd445e80a0b11df24a109abb217d (diff) | |
download | mongo-23eac61d89dae1f875287f888ceb833b88b89b5f.tar.gz |
Try and avoid underflow, it just makes a bad situation worse.
Diffstat (limited to 'src')
-rw-r--r-- | src/include/btree.i | 37 | ||||
-rw-r--r-- | src/include/misc.h | 1 |
2 files changed, 34 insertions, 4 deletions
diff --git a/src/include/btree.i b/src/include/btree.i index b6c425bed0e..f64e80e7d12 100644 --- a/src/include/btree.i +++ b/src/include/btree.i @@ -44,6 +44,34 @@ __wt_cache_page_inmem_incr(WT_SESSION_IMPL *session, WT_PAGE *page, size_t size) } } +/* + * WT_CACHE_DECR -- + * Macro to decrement a field by a size. + * + * Be defensive and don't underflow: a band-aid on a gaping wound, but underflow + * won't make things better no matter the problem (specifically, underflow makes + * eviction crazy trying to evict non-existent memory). + */ +#ifdef HAVE_DIAGNOSTIC +#define WT_CACHE_DECR(session, f, sz) do { \ + static int __first = 1; \ + if (WT_ATOMIC_SUB8(f, sz) > WT_EXABYTE) { \ + (void)WT_ATOMIC_ADD8(f, sz); \ + if (__first) { \ + __wt_errx(session, \ + "%s underflow: decrementing %" WT_SIZET_FMT,\ + #f, sz); \ + __first = 0; \ + } \ + } \ +} while (0) +#else +#define WT_CACHE_DECR(s, f, sz) do { \ + if (WT_ATOMIC_SUB8(f, sz) > WT_EXABYTE) \ + (void)WT_ATOMIC_ADD8(f, sz); \ +} while (0) +#endif + /* * __wt_cache_page_inmem_decr -- * Decrement a page's memory footprint in the cache. @@ -54,11 +82,12 @@ __wt_cache_page_inmem_decr(WT_SESSION_IMPL *session, WT_PAGE *page, size_t size) WT_CACHE *cache; cache = S2C(session)->cache; - (void)WT_ATOMIC_SUB8(cache->bytes_inmem, size); - (void)WT_ATOMIC_SUB8(page->memory_footprint, size); + + WT_CACHE_DECR(session, cache->bytes_inmem, size); + WT_CACHE_DECR(session, page->memory_footprint, size); if (__wt_page_is_modified(page)) { - (void)WT_ATOMIC_SUB8(cache->bytes_dirty, size); - (void)WT_ATOMIC_SUB8(page->modify->bytes_dirty, size); + WT_CACHE_DECR(session, cache->bytes_dirty, size); + WT_CACHE_DECR(session, page->modify->bytes_dirty, size); } } diff --git a/src/include/misc.h b/src/include/misc.h index 97fc2a47f20..71d6e802fa8 100644 --- a/src/include/misc.h +++ b/src/include/misc.h @@ -21,6 +21,7 @@ #define WT_GIGABYTE (1073741824) #define WT_TERABYTE ((uint64_t)1099511627776) #define WT_PETABYTE ((uint64_t)1125899906842624) +#define WT_EXABYTE ((uint64_t)1152921504606846976) /* * Number of directory entries can grow dynamically. |