diff options
author | Billy Donahue <billy.donahue@mongodb.com> | 2018-11-06 16:20:39 -0500 |
---|---|---|
committer | Billy Donahue <billy.donahue@mongodb.com> | 2018-11-16 11:03:18 -0500 |
commit | 63e43f1bb47f7bddf3dc37ad03a2bbee6d2a9423 (patch) | |
tree | 80d0f30295208dd648b0edf3027fb508be291047 /src/mongo/db/stats | |
parent | 1da5a8ac8ea43e1f704384238765fa5ca5b11af6 (diff) | |
download | mongo-63e43f1bb47f7bddf3dc37ad03a2bbee6d2a9423.tar.gz |
SERVER-5739 Fix races in RARELY/OCCASIONALLY.
Switch to using C++ instead of macros.
Fix SERVER-37247: these should fire on first hit.
Diffstat (limited to 'src/mongo/db/stats')
-rw-r--r-- | src/mongo/db/stats/counters.cpp | 54 | ||||
-rw-r--r-- | src/mongo/db/stats/counters.h | 34 |
2 files changed, 30 insertions, 58 deletions
diff --git a/src/mongo/db/stats/counters.cpp b/src/mongo/db/stats/counters.cpp index 81a77016a8b..0355fa8787b 100644 --- a/src/mongo/db/stats/counters.cpp +++ b/src/mongo/db/stats/counters.cpp @@ -36,50 +36,10 @@ #include "mongo/db/stats/counters.h" #include "mongo/db/jsobj.h" -#include "mongo/util/debug_util.h" #include "mongo/util/log.h" namespace mongo { -using std::endl; - -OpCounters::OpCounters() {} - -void OpCounters::gotInserts(int n) { - RARELY _checkWrap(); - _insert.fetchAndAdd(n); -} - -void OpCounters::gotInsert() { - RARELY _checkWrap(); - _insert.fetchAndAdd(1); -} - -void OpCounters::gotQuery() { - RARELY _checkWrap(); - _query.fetchAndAdd(1); -} - -void OpCounters::gotUpdate() { - RARELY _checkWrap(); - _update.fetchAndAdd(1); -} - -void OpCounters::gotDelete() { - RARELY _checkWrap(); - _delete.fetchAndAdd(1); -} - -void OpCounters::gotGetMore() { - RARELY _checkWrap(); - _getmore.fetchAndAdd(1); -} - -void OpCounters::gotCommand() { - RARELY _checkWrap(); - _command.fetchAndAdd(1); -} - void OpCounters::gotOp(int op, bool isCommand) { switch (op) { case dbInsert: /*gotInsert();*/ @@ -104,18 +64,14 @@ void OpCounters::gotOp(int op, bool isCommand) { case opReply: break; default: - log() << "OpCounters::gotOp unknown op: " << op << endl; + log() << "OpCounters::gotOp unknown op: " << op << std::endl; } } -void OpCounters::_checkWrap() { - const int64_t MAX = 1ULL << 60; - - bool wrap = _insert.loadRelaxed() > MAX || _query.loadRelaxed() > MAX || - _update.loadRelaxed() > MAX || _delete.loadRelaxed() > MAX || - _getmore.loadRelaxed() > MAX || _command.loadRelaxed() > MAX; - - if (wrap) { +void OpCounters::_checkWrap(CacheAligned<AtomicInt64> OpCounters::*counter, int n) { + static constexpr auto maxCount = AtomicInt64::WordType{1} << 60; + auto oldValue = (this->*counter).fetchAndAddRelaxed(n); + if (oldValue > maxCount) { _insert.store(0); _query.store(0); _update.store(0); diff --git a/src/mongo/db/stats/counters.h b/src/mongo/db/stats/counters.h index 07e38b251a9..4d6a057e427 100644 --- a/src/mongo/db/stats/counters.h +++ b/src/mongo/db/stats/counters.h @@ -47,14 +47,29 @@ namespace mongo { */ class OpCounters { public: - OpCounters(); - void gotInserts(int n); - void gotInsert(); - void gotQuery(); - void gotUpdate(); - void gotDelete(); - void gotGetMore(); - void gotCommand(); + OpCounters() = default; + + void gotInserts(int n) { + _checkWrap(&OpCounters::_insert, n); + } + void gotInsert() { + _checkWrap(&OpCounters::_insert, 1); + } + void gotQuery() { + _checkWrap(&OpCounters::_query, 1); + } + void gotUpdate() { + _checkWrap(&OpCounters::_update, 1); + } + void gotDelete() { + _checkWrap(&OpCounters::_delete, 1); + } + void gotGetMore() { + _checkWrap(&OpCounters::_getmore, 1); + } + void gotCommand() { + _checkWrap(&OpCounters::_command, 1); + } void gotOp(int op, bool isCommand); @@ -81,7 +96,8 @@ public: } private: - void _checkWrap(); + // Increment member `counter` by `n`, resetting all counters if it was > 2^60. + void _checkWrap(CacheAligned<AtomicInt64> OpCounters::*counter, int n); CacheAligned<AtomicInt64> _insert; CacheAligned<AtomicInt64> _query; |