summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Bostic <keith@wiredtiger.com>2015-01-22 17:08:00 -0500
committerKeith Bostic <keith@wiredtiger.com>2015-01-22 17:08:00 -0500
commit23eac61d89dae1f875287f888ceb833b88b89b5f (patch)
tree241b18a168c9ff32b4b58d25b405310f5fc34507 /src
parent7835fd35b597cd445e80a0b11df24a109abb217d (diff)
downloadmongo-23eac61d89dae1f875287f888ceb833b88b89b5f.tar.gz
Try and avoid underflow, it just makes a bad situation worse.
Diffstat (limited to 'src')
-rw-r--r--src/include/btree.i37
-rw-r--r--src/include/misc.h1
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.