summaryrefslogtreecommitdiff
path: root/src/mongo/db/stats
diff options
context:
space:
mode:
authorBilly Donahue <billy.donahue@mongodb.com>2018-11-06 16:20:39 -0500
committerBilly Donahue <billy.donahue@mongodb.com>2018-11-16 11:03:18 -0500
commit63e43f1bb47f7bddf3dc37ad03a2bbee6d2a9423 (patch)
tree80d0f30295208dd648b0edf3027fb508be291047 /src/mongo/db/stats
parent1da5a8ac8ea43e1f704384238765fa5ca5b11af6 (diff)
downloadmongo-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.cpp54
-rw-r--r--src/mongo/db/stats/counters.h34
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;