From 7133196d6b90f71926af0ba69190dc5fb26fb328 Mon Sep 17 00:00:00 2001 From: Mathias Stearn Date: Tue, 1 Dec 2009 19:28:27 -0500 Subject: [PATCH 1/3] Make OID and MSGID increments atomic --- db/jsobj.cpp | 7 +++---- util/goodies.h | 20 ++++++++++++++++---- util/message.cpp | 3 +-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/db/jsobj.cpp b/db/jsobj.cpp index e1cbb55fbe4..17cdf4db533 100644 --- a/db/jsobj.cpp +++ b/db/jsobj.cpp @@ -1430,7 +1430,7 @@ namespace mongo { } void OID::init() { - static unsigned inc = (unsigned) security.getNonce(); + static WrappingInt inc = (unsigned) security.getNonce(); unsigned t = (unsigned) time(0); char *T = (char *) &t; data[0] = T[3]; @@ -1440,9 +1440,8 @@ namespace mongo { (unsigned&) data[4] = _machine; - // TODO: use compiler intrinsic atomic increment instead of inc++ - int old_inc = inc++; - T = (char *) &old_inc; + int new_inc = inc.atomicIncrement(); + T = (char *) &new_inc; char * raw = (char*)&b; raw[0] = T[3]; raw[1] = T[2]; diff --git a/util/goodies.h b/util/goodies.h index 23a214b2a60..eb0631061a6 100644 --- a/util/goodies.h +++ b/util/goodies.h @@ -19,6 +19,10 @@ #pragma once +#if defined(__MSCV__) +# include +#endif + namespace mongo { #if !defined(_WIN32) && !defined(NOEXECINFO) @@ -112,14 +116,22 @@ namespace mongo { x = 0; } WrappingInt(unsigned z) : x(z) { } - unsigned x; + volatile unsigned x; operator unsigned() const { return x; } - WrappingInt& operator++() { - x++; - return *this; + + WrappingInt atomicIncrement(){ +#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + return __sync_add_and_fetch(&x, 1); +#elif defined(__MSCV__) + return InterlockedIncrement((long*)&x); //long is 32bits in Win64 +#else +# warning "OID and MSGID generation will not be thread safe" + return ++inc; +#endif } + static int diff(unsigned a, unsigned b) { return a-b; } diff --git a/util/message.cpp b/util/message.cpp index a483df42569..cfb03a53168 100644 --- a/util/message.cpp +++ b/util/message.cpp @@ -429,8 +429,7 @@ again: } msgstart; MSGID nextMessageId(){ - MSGID msgid = NextMsgId; - ++NextMsgId; + MSGID msgid = NextMsgId.atomicIncrement(); if ( usingClientIds ){ msgid = msgid & 0xFFFF; From 31723f3d28d9c8b2d08a3ffcce23751f70a8b153 Mon Sep 17 00:00:00 2001 From: Mathias Stearn Date: Tue, 1 Dec 2009 20:06:50 -0500 Subject: [PATCH 2/3] working atomic increment --- stdafx.h | 1 + util/goodies.h | 13 +------------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/stdafx.h b/stdafx.h index 5352c5e4d58..f0558378ff9 100644 --- a/stdafx.h +++ b/stdafx.h @@ -99,6 +99,7 @@ namespace mongo { #include #include #include +#include #define BOOST_SPIRIT_THREADSAFE #include diff --git a/util/goodies.h b/util/goodies.h index eb0631061a6..30013de867b 100644 --- a/util/goodies.h +++ b/util/goodies.h @@ -19,10 +19,6 @@ #pragma once -#if defined(__MSCV__) -# include -#endif - namespace mongo { #if !defined(_WIN32) && !defined(NOEXECINFO) @@ -122,14 +118,7 @@ namespace mongo { } WrappingInt atomicIncrement(){ -#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) - return __sync_add_and_fetch(&x, 1); -#elif defined(__MSCV__) - return InterlockedIncrement((long*)&x); //long is 32bits in Win64 -#else -# warning "OID and MSGID generation will not be thread safe" - return ++inc; -#endif + return boost::interprocess::detail::atomic_inc32(&x); } static int diff(unsigned a, unsigned b) { From c0e79bf1d4b6a2813a0aa93bc63fdb6c89c281c0 Mon Sep 17 00:00:00 2001 From: Mathias Stearn Date: Tue, 1 Dec 2009 20:25:48 -0500 Subject: [PATCH 3/3] removing atomic increment for now --- stdafx.h | 1 - util/goodies.h | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stdafx.h b/stdafx.h index f0558378ff9..5352c5e4d58 100644 --- a/stdafx.h +++ b/stdafx.h @@ -99,7 +99,6 @@ namespace mongo { #include #include #include -#include #define BOOST_SPIRIT_THREADSAFE #include diff --git a/util/goodies.h b/util/goodies.h index 30013de867b..3d34715a430 100644 --- a/util/goodies.h +++ b/util/goodies.h @@ -117,8 +117,9 @@ namespace mongo { return x; } + // TODO: make atomic WrappingInt atomicIncrement(){ - return boost::interprocess::detail::atomic_inc32(&x); + return x++; } static int diff(unsigned a, unsigned b) {