diff options
29 files changed, 121 insertions, 293 deletions
diff --git a/src/mongo/bson/util/atomic_int.h b/src/mongo/bson/util/atomic_int.h deleted file mode 100644 index 2d4515df7f6..00000000000 --- a/src/mongo/bson/util/atomic_int.h +++ /dev/null @@ -1,143 +0,0 @@ -// atomic_int.h -// atomic wrapper for unsigned - -/* Copyright 2009 10gen Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects - * for all of the code used other than as permitted herein. If you modify - * file(s) with this exception, you may extend this exception to your - * version of the file(s), but you are not obligated to do so. If you do not - * wish to do so, delete this exception statement from your version. If you - * delete this exception statement from all source files in the program, - * then also delete it in the license file. - */ - -#pragma once - -#if defined(_WIN32) -#include "mongo/platform/windows_basic.h" -#endif - -#include "mongo/platform/compiler.h" - -namespace mongo { - - /** - * An unsigned integer supporting atomic read-modify-write operations. - * - * Many operations on these types depend on natural alignment (4 byte alignment for 4-byte - * words, i.e.). - */ - struct MONGO_COMPILER_ALIGN_TYPE( 4 ) AtomicUInt { - AtomicUInt() : x(0) {} - AtomicUInt(unsigned z) : x(z) { } - - operator unsigned() const { return x; } - unsigned get() const { return x; } - inline void set(unsigned newX); - - inline AtomicUInt operator++(); // ++prefix - inline AtomicUInt operator++(int);// postfix++ - inline AtomicUInt operator--(); // --prefix - inline AtomicUInt operator--(int); // postfix-- - inline void signedAdd(int by); - inline void zero() { set(0); } - volatile unsigned x; - }; - -#if defined(_WIN32) - void AtomicUInt::set(unsigned newX) { - InterlockedExchange((volatile long *)&x, newX); - } - - AtomicUInt AtomicUInt::operator++() { - return InterlockedIncrement((volatile long*)&x); - } - AtomicUInt AtomicUInt::operator++(int) { - return InterlockedIncrement((volatile long*)&x)-1; - } - AtomicUInt AtomicUInt::operator--() { - return InterlockedDecrement((volatile long*)&x); - } - AtomicUInt AtomicUInt::operator--(int) { - return InterlockedDecrement((volatile long*)&x)+1; - } -# if defined(_WIN64) - // don't see an InterlockedAdd for _WIN32...hmmm - void AtomicUInt::signedAdd(int by) { - InterlockedAdd((volatile long *)&x,by); - } -# endif -#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) - // this is in GCC >= 4.1 - inline void AtomicUInt::set(unsigned newX) { __sync_synchronize(); x = newX; } - AtomicUInt AtomicUInt::operator++() { - return __sync_add_and_fetch(&x, 1); - } - AtomicUInt AtomicUInt::operator++(int) { - return __sync_fetch_and_add(&x, 1); - } - AtomicUInt AtomicUInt::operator--() { - return __sync_add_and_fetch(&x, -1); - } - AtomicUInt AtomicUInt::operator--(int) { - return __sync_fetch_and_add(&x, -1); - } - void AtomicUInt::signedAdd(int by) { - __sync_fetch_and_add(&x, by); - } -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - inline void AtomicUInt::set(unsigned newX) { - asm volatile("mfence" ::: "memory"); - x = newX; - } - - // from boost 1.39 interprocess/detail/atomic.hpp - inline unsigned atomic_int_helper(volatile unsigned *x, int val) { - int r; - asm volatile - ( - "lock\n\t" - "xadd %1, %0": - "+m"( *x ), "=r"( r ): // outputs (%0, %1) - "1"( val ): // inputs (%2 == %1) - "memory", "cc" // clobbers - ); - return r; - } - AtomicUInt AtomicUInt::operator++() { - return atomic_int_helper(&x, 1)+1; - } - AtomicUInt AtomicUInt::operator++(int) { - return atomic_int_helper(&x, 1); - } - AtomicUInt AtomicUInt::operator--() { - return atomic_int_helper(&x, -1)-1; - } - AtomicUInt AtomicUInt::operator--(int) { - return atomic_int_helper(&x, -1); - } - void AtomicUInt::signedAdd(int by) { - atomic_int_helper(&x, by); - } -#else -# error "unsupported compiler or platform" -#endif - -} // namespace mongo diff --git a/src/mongo/client/examples/mongoperf.cpp b/src/mongo/client/examples/mongoperf.cpp index 9b96879b5cb..40def7265f1 100644 --- a/src/mongo/client/examples/mongoperf.cpp +++ b/src/mongo/client/examples/mongoperf.cpp @@ -44,9 +44,9 @@ #include <boost/filesystem/operations.hpp> #include <boost/thread/thread.hpp> -#include "mongo/bson/util/atomic_int.h" #include "mongo/db/jsobj.h" #include "mongo/db/json.h" +#include "mongo/platform/atomic_word.h" #include "mongo/util/logfile.h" #include "mongo/util/mmap.h" #include "mongo/util/mongoutils/str.h" @@ -68,7 +68,7 @@ const unsigned PG = 4096; unsigned nThreadsRunning = 0; // as this is incremented A LOT, at some point this becomes a bottleneck if very high ops/second (in cache) things are happening. -AtomicUInt iops; +AtomicUInt32 iops; SimpleMutex m("mperf"); @@ -116,7 +116,7 @@ void workerThread() { dummy += mmf[rofs]; rofs += PG; } - iops++; + iops.fetchAndAdd(1); } if( w ) { for( unsigned p = P; p <= recSizeKB; p += P ) { @@ -124,17 +124,17 @@ void workerThread() { mmf[wofs] = 3; wofs += PG; } - iops++; + iops.fetchAndAdd(1); } } else { if( r ) { lf->readAt(rofs, a.addr(), recSizeKB * 1024); - iops++; + iops.fetchAndAdd(1); } if( w ) { lf->writeAt(wofs, a.addr(), recSizeKB * 1024); - iops++; + iops.fetchAndAdd(1); } } long long micros = su / nThreadsRunning; @@ -225,8 +225,8 @@ void go() { } } sleepsecs(1); - unsigned long long w = iops.get(); - iops.zero(); + unsigned long long w = iops.loadRelaxed(); + iops.store(0); w /= 1; // 1 secs cout << w << " ops/sec "; if( mmf == 0 ) diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp index 6f697087659..dd9feb4a351 100644 --- a/src/mongo/db/commands/mr.cpp +++ b/src/mongo/db/commands/mr.cpp @@ -64,7 +64,7 @@ namespace mongo { namespace mr { - AtomicUInt Config::JOB_NUMBER; + AtomicUInt32 Config::JOB_NUMBER; JSFunction::JSFunction( const std::string& type , const BSONElement& e ) { _type = type; @@ -276,7 +276,7 @@ namespace mongo { << ".tmp.mr." << cmdObj.firstElement().String() << "_" - << JOB_NUMBER++; + << JOB_NUMBER.fetchAndAdd(1); incLong = tempNamespace + "_inc"; } diff --git a/src/mongo/db/commands/mr.h b/src/mongo/db/commands/mr.h index 06e1bcb66f4..500e677428c 100644 --- a/src/mongo/db/commands/mr.h +++ b/src/mongo/db/commands/mr.h @@ -38,6 +38,7 @@ #include "mongo/db/curop.h" #include "mongo/db/instance.h" #include "mongo/db/jsobj.h" +#include "mongo/platform/atomic_word.h" #include "mongo/scripting/engine.h" namespace mongo { @@ -227,7 +228,7 @@ namespace mongo { // true when called from mongos to do phase-1 of M/R bool shardedFirstPass; - static AtomicUInt JOB_NUMBER; + static AtomicUInt32 JOB_NUMBER; }; // end MRsetup /** diff --git a/src/mongo/db/concurrency/lock_mgr.h b/src/mongo/db/concurrency/lock_mgr.h index 9a94bd33799..a38b4f3aec7 100644 --- a/src/mongo/db/concurrency/lock_mgr.h +++ b/src/mongo/db/concurrency/lock_mgr.h @@ -36,10 +36,11 @@ #include <string> #include <vector> +#include "mongo/platform/atomic_word.h" #include "mongo/platform/compiler.h" #include "mongo/platform/cstdint.h" #include "mongo/util/timer.h" -#include "mongo/bson/util/atomic_int.h" + /* * LockManager controls access to resources through two functions: acquire and release @@ -620,14 +621,18 @@ namespace mongo { // support functions for changing policy to/from read/write only void _incStatsForMode(const LockMode& mode) { - kShared==mode ? _numCurrentActiveReadRequests++ : _numCurrentActiveWriteRequests++; + kShared==mode ? + _numCurrentActiveReadRequests.fetchAndAdd(1) : + _numCurrentActiveWriteRequests.fetchAndAdd(1); } void _decStatsForMode(const LockMode& mode) { - kShared==mode ? _numCurrentActiveReadRequests-- : _numCurrentActiveWriteRequests--; + kShared==mode ? + _numCurrentActiveReadRequests.fetchAndSubtract(1) : + _numCurrentActiveWriteRequests.fetchAndSubtract(1); } - unsigned _numActiveReads() const { return _numCurrentActiveReadRequests; } - unsigned _numActiveWrites() const { return _numCurrentActiveWriteRequests; } + unsigned _numActiveReads() const { return _numCurrentActiveReadRequests.loadRelaxed(); } + unsigned _numActiveWrites() const { return _numCurrentActiveWriteRequests.loadRelaxed(); } private: @@ -685,8 +690,8 @@ namespace mongo { LockStats _stats[kNumResourcePartitions]; // used when changing policy to/from Readers/Writers Only - AtomicUInt _numCurrentActiveReadRequests; - AtomicUInt _numCurrentActiveWriteRequests; + AtomicUInt32 _numCurrentActiveReadRequests; + AtomicUInt32 _numCurrentActiveWriteRequests; }; /** diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp index d4855becf24..48e644b1f1c 100644 --- a/src/mongo/db/curop.cpp +++ b/src/mongo/db/curop.cpp @@ -62,7 +62,7 @@ namespace mongo { _active = false; _reset(); _op = 0; - _opNum = _nextOpNum++; + _opNum = _nextOpNum.fetchAndAdd(1); _command = NULL; } @@ -84,7 +84,7 @@ namespace mongo { void CurOp::reset() { _reset(); _start = 0; - _opNum = _nextOpNum++; + _opNum = _nextOpNum.fetchAndAdd(1); _debug.reset(); _query.reset(); _active = true; // this should be last for ui clarity @@ -258,7 +258,7 @@ namespace mongo { return _maxTimeTracker.getRemainingMicros(); } - AtomicUInt CurOp::_nextOpNum; + AtomicUInt32 CurOp::_nextOpNum; static Counter64 returnedCounter; static Counter64 insertedCounter; diff --git a/src/mongo/db/curop.h b/src/mongo/db/curop.h index e895799abba..ed8b9057ae8 100644 --- a/src/mongo/db/curop.h +++ b/src/mongo/db/curop.h @@ -31,8 +31,8 @@ #pragma once -#include "mongo/bson/util/atomic_int.h" #include "mongo/db/client.h" +#include "mongo/platform/atomic_word.h" #include "mongo/util/concurrency/spin_lock.h" #include "mongo/util/net/hostandport.h" #include "mongo/util/progress_meter.h" @@ -212,7 +212,7 @@ namespace mongo { return _dbprofile >= 2 || ms >= serverGlobalParams.slowMS; } - AtomicUInt opNum() const { return _opNum; } + unsigned int opNum() const { return _opNum; } /** if this op is running */ bool active() const { return _active; } @@ -325,7 +325,7 @@ namespace mongo { friend class Client; void _reset(); - static AtomicUInt _nextOpNum; + static AtomicUInt32 _nextOpNum; Client * _client; CurOp * _wrapped; Command * _command; @@ -336,7 +336,7 @@ namespace mongo { int _op; bool _isCommand; int _dbprofile; // 0=off, 1=slow, 2=all - AtomicUInt _opNum; // todo: simple being "unsigned" may make more sense here + unsigned int _opNum; ThreadSafeString _ns; HostAndPort _remote; // CAREFUL here with thread safety CachedBSONObj<512> _query; // CachedBSONObj is thread safe diff --git a/src/mongo/db/global_environment_d.cpp b/src/mongo/db/global_environment_d.cpp index f7eeb67aa3b..27155f89c3d 100644 --- a/src/mongo/db/global_environment_d.cpp +++ b/src/mongo/db/global_environment_d.cpp @@ -30,7 +30,6 @@ #include <set> -#include "mongo/bson/util/atomic_int.h" #include "mongo/db/client.h" #include "mongo/db/curop.h" #include "mongo/db/operation_context_impl.h" @@ -56,7 +55,7 @@ namespace mongo { } namespace { - void interruptJs(AtomicUInt* op) { + void interruptJs(unsigned int op) { if (!globalScriptEngine) { return; } @@ -65,7 +64,7 @@ namespace mongo { globalScriptEngine->interruptAll(); } else { - globalScriptEngine->interrupt(*op); + globalScriptEngine->interrupt(op); } } } // namespace @@ -79,7 +78,7 @@ namespace mongo { return _globalKill; } - bool GlobalEnvironmentMongoD::killOperation(AtomicUInt opId) { + bool GlobalEnvironmentMongoD::killOperation(unsigned int opId) { scoped_lock clientLock(Client::clientsMutex); bool found = false; @@ -103,7 +102,7 @@ namespace mongo { } } if ( found ) { - interruptJs( &opId ); + interruptJs( opId ); } return found; } diff --git a/src/mongo/db/global_environment_d.h b/src/mongo/db/global_environment_d.h index a5ee76438fc..2f4d0e88cd5 100644 --- a/src/mongo/db/global_environment_d.h +++ b/src/mongo/db/global_environment_d.h @@ -50,7 +50,7 @@ namespace mongo { bool getKillAllOperations(); - bool killOperation(AtomicUInt opId); + bool killOperation(unsigned int opId); void registerOperationContext(OperationContext* txn); diff --git a/src/mongo/db/global_environment_experiment.h b/src/mongo/db/global_environment_experiment.h index d9f4c2dbaf6..30ba29e6d72 100644 --- a/src/mongo/db/global_environment_experiment.h +++ b/src/mongo/db/global_environment_experiment.h @@ -29,7 +29,6 @@ #pragma once #include "mongo/base/disallow_copying.h" -#include "mongo/bson/util/atomic_int.h" namespace mongo { @@ -71,7 +70,7 @@ namespace mongo { * @param i opid of operation to kill * @return if operation was found **/ - virtual bool killOperation(AtomicUInt opId) = 0; + virtual bool killOperation(unsigned int opId) = 0; /** * Registers the specified operation context on the global environment, so it is diff --git a/src/mongo/db/global_environment_noop.cpp b/src/mongo/db/global_environment_noop.cpp index ea8f3c49ca9..4d791a6568c 100644 --- a/src/mongo/db/global_environment_noop.cpp +++ b/src/mongo/db/global_environment_noop.cpp @@ -44,7 +44,7 @@ namespace mongo { return false; } - bool GlobalEnvironmentNoop::killOperation(AtomicUInt opId) { + bool GlobalEnvironmentNoop::killOperation(unsigned int opId) { return false; } diff --git a/src/mongo/db/global_environment_noop.h b/src/mongo/db/global_environment_noop.h index bebe2c6047d..6d2f14b377b 100644 --- a/src/mongo/db/global_environment_noop.h +++ b/src/mongo/db/global_environment_noop.h @@ -34,7 +34,7 @@ namespace mongo { public: StorageEngine* getGlobalStorageEngine(); - bool killOperation(AtomicUInt opId); + bool killOperation(unsigned int opId); void setKillAllOperations(); diff --git a/src/mongo/db/index_builder.cpp b/src/mongo/db/index_builder.cpp index c6112291149..78af3691d3c 100644 --- a/src/mongo/db/index_builder.cpp +++ b/src/mongo/db/index_builder.cpp @@ -44,11 +44,11 @@ namespace mongo { MONGO_LOG_DEFAULT_COMPONENT_FILE(::mongo::logger::LogComponent::kIndexing); - AtomicUInt IndexBuilder::_indexBuildCount = 0; + AtomicUInt32 IndexBuilder::_indexBuildCount; IndexBuilder::IndexBuilder(const BSONObj& index) : BackgroundJob(true /* self-delete */), _index(index.getOwned()), - _name(str::stream() << "repl index builder " << (_indexBuildCount++).get()) { + _name(str::stream() << "repl index builder " << _indexBuildCount.addAndFetch(1)) { } IndexBuilder::~IndexBuilder() {} diff --git a/src/mongo/db/index_builder.h b/src/mongo/db/index_builder.h index e825794a4c3..1d3699e6671 100644 --- a/src/mongo/db/index_builder.h +++ b/src/mongo/db/index_builder.h @@ -33,6 +33,7 @@ #include "mongo/db/catalog/index_catalog.h" #include "mongo/db/client.h" #include "mongo/db/jsobj.h" +#include "mongo/platform/atomic_word.h" #include "mongo/util/background.h" /** @@ -76,7 +77,7 @@ namespace mongo { private: const BSONObj _index; std::string _name; // name of this builder, not related to the index - static AtomicUInt _indexBuildCount; + static AtomicUInt32 _indexBuildCount; }; } diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp index bf63472c6ba..e9b2fe966fb 100644 --- a/src/mongo/db/instance.cpp +++ b/src/mongo/db/instance.cpp @@ -34,7 +34,6 @@ #include <fstream> #include "mongo/base/status.h" -#include "mongo/bson/util/atomic_int.h" #include "mongo/db/audit.h" #include "mongo/db/auth/action_type.h" #include "mongo/db/auth/authorization_manager.h" @@ -70,6 +69,7 @@ #include "mongo/db/repl/repl_coordinator_global.h" #include "mongo/db/stats/counters.h" #include "mongo/db/storage_options.h" +#include "mongo/platform/atomic_word.h" #include "mongo/platform/process_id.h" #include "mongo/s/d_logic.h" #include "mongo/s/stale_exception.h" // for SendStaleConfigException diff --git a/src/mongo/db/operation_context_impl.cpp b/src/mongo/db/operation_context_impl.cpp index 924c46a1181..ea82457cc9b 100644 --- a/src/mongo/db/operation_context_impl.cpp +++ b/src/mongo/db/operation_context_impl.cpp @@ -146,7 +146,7 @@ namespace mongo { MONGO_FAIL_POINT_BLOCK(checkForInterruptFail, scopedFailPoint) { if (opShouldFail(c, scopedFailPoint.getData())) { log() << "set pending kill on " << (c.curop()->parent() ? "nested" : "top-level") - << " op " << c.curop()->opNum().get() << ", for checkForInterruptFail"; + << " op " << c.curop()->opNum() << ", for checkForInterruptFail"; c.curop()->kill(); } } @@ -171,7 +171,7 @@ namespace mongo { MONGO_FAIL_POINT_BLOCK(checkForInterruptFail, scopedFailPoint) { if (opShouldFail(c, scopedFailPoint.getData())) { log() << "set pending kill on " << (c.curop()->parent() ? "nested" : "top-level") - << " op " << c.curop()->opNum().get() << ", for checkForInterruptFail"; + << " op " << c.curop()->opNum() << ", for checkForInterruptFail"; c.curop()->kill(); } } diff --git a/src/mongo/db/repl/rs_config.cpp b/src/mongo/db/repl/rs_config.cpp index 65b70dd9c01..0544ff05d1b 100644 --- a/src/mongo/db/repl/rs_config.cpp +++ b/src/mongo/db/repl/rs_config.cpp @@ -55,7 +55,7 @@ namespace repl { const int ReplSetConfig::DEFAULT_HB_TIMEOUT = 10; namespace { - AtomicUInt _warnedAboutVotes = 0; + AtomicUInt32 _warnedAboutVotes; void assertOnlyHas(BSONObj o, const set<string>& fields) { BSONObj::iterator i(o); @@ -534,7 +534,7 @@ namespace { m.priority = mobj["priority"].Number(); if( mobj.hasElement("votes") ) m.votes = (unsigned) mobj["votes"].Number(); - if (m.votes > 1 && !_warnedAboutVotes) { + if (m.votes > 1 && (_warnedAboutVotes.load() == 0)) { log() << "\t\tWARNING: Having more than 1 vote on a single replicaset member is" << startupWarningsLog; log() << "\t\tdeprecated, as it causes issues with majority write concern. For" @@ -542,7 +542,7 @@ namespace { log() << "\t\tmore information, see " << "http://dochub.mongodb.org/core/replica-set-votes-deprecated" << startupWarningsLog; - _warnedAboutVotes.set(1); + _warnedAboutVotes.store(1); } if( mobj.hasElement("tags") ) { const BSONObj &t = mobj["tags"].Obj(); diff --git a/src/mongo/db/sorter/sorter.cpp b/src/mongo/db/sorter/sorter.cpp index c2a39a1e0b2..113813d22f3 100644 --- a/src/mongo/db/sorter/sorter.cpp +++ b/src/mongo/db/sorter/sorter.cpp @@ -51,9 +51,9 @@ #include <snappy.h> #include "mongo/base/string_data.h" -#include "mongo/bson/util/atomic_int.h" #include "mongo/db/jsobj.h" #include "mongo/db/storage_options.h" +#include "mongo/platform/atomic_word.h" #include "mongo/util/assert_util.h" #include "mongo/util/bufreader.h" #include "mongo/util/goodies.h" @@ -765,8 +765,8 @@ namespace mongo { inline unsigned nextFileNumber() { // This is unified across all Sorter types and instances. - static AtomicUInt fileCounter; - return fileCounter++; + static AtomicUInt32 fileCounter; + return fileCounter.fetchAndAdd(1); } } // namespace sorter diff --git a/src/mongo/db/stats/counters.cpp b/src/mongo/db/stats/counters.cpp index a50aca7eeba..eba6ae93b0b 100644 --- a/src/mongo/db/stats/counters.cpp +++ b/src/mongo/db/stats/counters.cpp @@ -39,37 +39,37 @@ namespace mongo { void OpCounters::incInsertInWriteLock(int n) { RARELY _checkWrap(); - _insert.x += n; + _insert.fetchAndAdd(n); } void OpCounters::gotInsert() { RARELY _checkWrap(); - _insert++; + _insert.fetchAndAdd(1); } void OpCounters::gotQuery() { RARELY _checkWrap(); - _query++; + _query.fetchAndAdd(1); } void OpCounters::gotUpdate() { RARELY _checkWrap(); - _update++; + _update.fetchAndAdd(1); } void OpCounters::gotDelete() { RARELY _checkWrap(); - _delete++; + _delete.fetchAndAdd(1); } void OpCounters::gotGetMore() { RARELY _checkWrap(); - _getmore++; + _getmore.fetchAndAdd(1); } void OpCounters::gotCommand() { RARELY _checkWrap(); - _command++; + _command.fetchAndAdd(1); } void OpCounters::gotOp( int op , bool isCommand ) { @@ -97,31 +97,31 @@ namespace mongo { const unsigned MAX = 1 << 30; bool wrap = - _insert.get() > MAX || - _query.get() > MAX || - _update.get() > MAX || - _delete.get() > MAX || - _getmore.get() > MAX || - _command.get() > MAX; + _insert.loadRelaxed() > MAX || + _query.loadRelaxed() > MAX || + _update.loadRelaxed() > MAX || + _delete.loadRelaxed() > MAX || + _getmore.loadRelaxed() > MAX || + _command.loadRelaxed() > MAX; if ( wrap ) { - _insert.zero(); - _query.zero(); - _update.zero(); - _delete.zero(); - _getmore.zero(); - _command.zero(); + _insert.store(0); + _query.store(0); + _update.store(0); + _delete.store(0); + _getmore.store(0); + _command.store(0); } } BSONObj OpCounters::getObj() const { BSONObjBuilder b; - b.append( "insert" , _insert.get() ); - b.append( "query" , _query.get() ); - b.append( "update" , _update.get() ); - b.append( "delete" , _delete.get() ); - b.append( "getmore" , _getmore.get() ); - b.append( "command" , _command.get() ); + b.append( "insert" , _insert.loadRelaxed() ); + b.append( "query" , _query.loadRelaxed() ); + b.append( "update" , _update.loadRelaxed() ); + b.append( "delete" , _delete.loadRelaxed() ); + b.append( "getmore" , _getmore.loadRelaxed() ); + b.append( "command" , _command.loadRelaxed() ); return b.obj(); } diff --git a/src/mongo/db/stats/counters.h b/src/mongo/db/stats/counters.h index b0aad7a7ce6..d9c54242cb4 100644 --- a/src/mongo/db/stats/counters.h +++ b/src/mongo/db/stats/counters.h @@ -30,8 +30,8 @@ #pragma once #include "mongo/pch.h" -#include "mongo/bson/util/atomic_int.h" #include "mongo/db/jsobj.h" +#include "mongo/platform/atomic_word.h" #include "mongo/util/net/message.h" #include "mongo/util/processinfo.h" #include "mongo/util/concurrency/spin_lock.h" @@ -59,25 +59,24 @@ namespace mongo { BSONObj getObj() const; // thse are used by snmp, and other things, do not remove - const AtomicUInt * getInsert() const { return &_insert; } - const AtomicUInt * getQuery() const { return &_query; } - const AtomicUInt * getUpdate() const { return &_update; } - const AtomicUInt * getDelete() const { return &_delete; } - const AtomicUInt * getGetMore() const { return &_getmore; } - const AtomicUInt * getCommand() const { return &_command; } - + const AtomicUInt32 * getInsert() const { return &_insert; } + const AtomicUInt32 * getQuery() const { return &_query; } + const AtomicUInt32 * getUpdate() const { return &_update; } + const AtomicUInt32 * getDelete() const { return &_delete; } + const AtomicUInt32 * getGetMore() const { return &_getmore; } + const AtomicUInt32 * getCommand() const { return &_command; } private: void _checkWrap(); // todo: there will be a lot of cache line contention on these. need to do something // else eventually. - AtomicUInt _insert; - AtomicUInt _query; - AtomicUInt _update; - AtomicUInt _delete; - AtomicUInt _getmore; - AtomicUInt _command; + AtomicUInt32 _insert; + AtomicUInt32 _query; + AtomicUInt32 _update; + AtomicUInt32 _delete; + AtomicUInt32 _getmore; + AtomicUInt32 _command; }; extern OpCounters globalOpCounters; diff --git a/src/mongo/dbtests/threadedtests.cpp b/src/mongo/dbtests/threadedtests.cpp index 2d8d3ebf96b..c2cde0818ad 100644 --- a/src/mongo/dbtests/threadedtests.cpp +++ b/src/mongo/dbtests/threadedtests.cpp @@ -33,7 +33,6 @@ #include <boost/thread.hpp> -#include "mongo/bson/util/atomic_int.h" #include "mongo/db/d_concurrency.h" #include "mongo/db/operation_context_impl.h" #include "mongo/dbtests/dbtests.h" @@ -303,36 +302,6 @@ namespace ThreadedTests { } }; - // Tested with up to 30k threads - class IsAtomicUIntAtomic : public ThreadedTest<> { - static const int iterations = 1000000; - AtomicUInt target; - - void subthread(int) { - for(int i=0; i < iterations; i++) { - //target.x++; // verified to fail with this version - target++; - } - } - void validate() { - ASSERT_EQUALS(target.x , unsigned(nthreads * iterations)); - - AtomicUInt u; - ASSERT_EQUALS(0u, u); - ASSERT_EQUALS(0u, u++); - ASSERT_EQUALS(2u, ++u); - ASSERT_EQUALS(2u, u--); - ASSERT_EQUALS(0u, --u); - ASSERT_EQUALS(0u, u); - - u++; - ASSERT( u > 0 ); - - u--; - ASSERT( ! ( u > 0 ) ); - } - }; - template <typename _AtomicUInt> class IsAtomicWordAtomic : public ThreadedTest<> { static const int iterations = 1000000; @@ -1034,7 +1003,6 @@ namespace ThreadedTests { add< List1Test >(); add< List1Test2 >(); - add< IsAtomicUIntAtomic >(); add< IsAtomicWordAtomic<AtomicUInt32> >(); add< IsAtomicWordAtomic<AtomicUInt64> >(); add< MVarTest >(); diff --git a/src/mongo/s/chunk.cpp b/src/mongo/s/chunk.cpp index d6611f4fdd7..97adbc1e307 100644 --- a/src/mongo/s/chunk.cpp +++ b/src/mongo/s/chunk.cpp @@ -668,7 +668,7 @@ namespace mongo { // ------- ChunkManager -------- - AtomicUInt ChunkManager::NextSequenceNumber = 1; + AtomicUInt32 ChunkManager::NextSequenceNumber(1U); ChunkManager::ChunkManager( const string& ns, const ShardKeyPattern& pattern , bool unique ) : _ns( ns ), @@ -676,7 +676,7 @@ namespace mongo { _unique( unique ), _chunkRanges(), _mutex("ChunkManager"), - _sequenceNumber(++NextSequenceNumber) + _sequenceNumber(NextSequenceNumber.addAndFetch(1)) { // // Sets up a chunk manager from new data @@ -698,7 +698,7 @@ namespace mongo { // The shard versioning mechanism hinges on keeping track of the number of times we reloaded ChunkManager's. // Increasing this number here will prompt checkShardVersion() to refresh the connection-level versions to // the most up to date value. - _sequenceNumber(++NextSequenceNumber) + _sequenceNumber(NextSequenceNumber.addAndFetch(1)) { // @@ -717,7 +717,7 @@ namespace mongo { _unique( oldManager->isUnique() ), _chunkRanges(), _mutex("ChunkManager"), - _sequenceNumber(++NextSequenceNumber) + _sequenceNumber(NextSequenceNumber.addAndFetch(1)) { // // Sets up a chunk manager based on an older manager diff --git a/src/mongo/s/chunk.h b/src/mongo/s/chunk.h index 5c60137e718..4cda8a0451e 100644 --- a/src/mongo/s/chunk.h +++ b/src/mongo/s/chunk.h @@ -31,7 +31,7 @@ #pragma once #include "mongo/base/string_data.h" -#include "mongo/bson/util/atomic_int.h" +#include "mongo/platform/atomic_word.h" #include "mongo/s/chunk_version.h" #include "mongo/s/distlock.h" #include "mongo/s/shard.h" @@ -574,7 +574,7 @@ namespace mongo { friend class Chunk; friend class ChunkRangeManager; // only needed for CRM::assertValid() - static AtomicUInt NextSequenceNumber; + static AtomicUInt32 NextSequenceNumber; /** Just for testing */ friend class TestableChunkManager; diff --git a/src/mongo/s/commands_public.cpp b/src/mongo/s/commands_public.cpp index 581fad685cf..2e66a9a8c91 100644 --- a/src/mongo/s/commands_public.cpp +++ b/src/mongo/s/commands_public.cpp @@ -50,6 +50,7 @@ #include "mongo/db/pipeline/document_source.h" #include "mongo/db/pipeline/expression_context.h" #include "mongo/db/query/lite_parsed_query.h" +#include "mongo/platform/atomic_word.h" #include "mongo/s/client_info.h" #include "mongo/s/chunk.h" #include "mongo/s/config.h" @@ -1630,7 +1631,7 @@ namespace mongo { */ class MRCmd : public PublicGridCommand { public: - AtomicUInt JOB_NUMBER; + AtomicUInt32 JOB_NUMBER; MRCmd() : PublicGridCommand( "mapReduce", "mapreduce" ) {} @@ -1642,7 +1643,7 @@ namespace mongo { string getTmpName( const string& coll ) { stringstream ss; - ss << "tmp.mrs." << coll << "_" << time(0) << "_" << JOB_NUMBER++; + ss << "tmp.mrs." << coll << "_" << time(0) << "_" << JOB_NUMBER.fetchAndAdd(1); return ss.str(); } diff --git a/src/mongo/s/distlock_test.cpp b/src/mongo/s/distlock_test.cpp index 8d2e7f014fd..a194c62a213 100644 --- a/src/mongo/s/distlock_test.cpp +++ b/src/mongo/s/distlock_test.cpp @@ -36,11 +36,11 @@ #include <vector> #include "mongo/base/init.h" -#include "mongo/bson/util/atomic_int.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/commands.h" +#include "mongo/platform/atomic_word.h" #include "mongo/util/bson_util.h" #include "mongo/util/concurrency/thread_name.h" #include "mongo/util/log.h" @@ -100,10 +100,9 @@ namespace mongo { while (keepGoing) { try { if (current->lock_try( "test" )) { - count++; - int before = count; + int before = count.addAndFetch(1); sleepmillis(3); - int after = count; + int after = count.loadRelaxed(); if (after != before) { error() << " before: " << before << " after: " << after @@ -125,7 +124,7 @@ namespace mongo { DistributedLock lk(ConnectionString(cmdObj["host"].String(), ConnectionString::SYNC), "testdistlockwithsync", 0, 0); current = &lk; - count = 0; + count.store(0); gotit = 0; errors = 0; keepGoing = true; @@ -147,7 +146,7 @@ namespace mongo { current = 0; - result.append("count", count); + result.append("count", count.loadRelaxed()); result.append("gotit", gotit); result.append("errors", errors); result.append("timeMS", t.millis()); @@ -159,7 +158,7 @@ namespace mongo { static DistributedLock * current; static int gotit; static int errors; - static AtomicUInt count; + static AtomicUInt32 count; static bool keepGoing; @@ -173,7 +172,7 @@ namespace mongo { } DistributedLock * TestDistLockWithSync::current; - AtomicUInt TestDistLockWithSync::count; + AtomicUInt32 TestDistLockWithSync::count; int TestDistLockWithSync::gotit; int TestDistLockWithSync::errors; bool TestDistLockWithSync::keepGoing; @@ -274,23 +273,22 @@ namespace mongo { log() << "**** Locked for thread " << threadId << " with ts " << lockObj["ts"] << endl; - if( count % 2 == 1 && ! myLock->lock_try( "Testing lock re-entry.", true ) ) { + if( count.loadRelaxed() % 2 == 1 && ! myLock->lock_try( "Testing lock re-entry.", true ) ) { errors = true; log() << "**** !Could not re-enter lock already held" << endl; break; } - if( count % 3 == 1 && myLock->lock_try( "Testing lock non-re-entry.", false ) ) { + if( count.loadRelaxed() % 3 == 1 && myLock->lock_try( "Testing lock non-re-entry.", false ) ) { errors = true; log() << "**** !Invalid lock re-entry" << endl; break; } - count++; - int before = count; + int before = count.addAndFetch(1); int sleep = randomWait(); sleepmillis(sleep); - int after = count; + int after = count.loadRelaxed(); if(after != before) { errors = true; @@ -363,7 +361,7 @@ namespace mongo { return false; } - count = 0; + count.store(0); keepGoing = true; vector<shared_ptr<boost::thread> > threads; @@ -385,7 +383,7 @@ namespace mongo { errors = errors || results[i].get()->obj()["errors"].Bool(); } - result.append("count", count); + result.append("count", count.loadRelaxed()); result.append("errors", errors); result.append("timeMS", t.millis()); @@ -440,7 +438,7 @@ namespace mongo { // variables for test thread_specific_ptr<DistributedLock> lock; - AtomicUInt count; + AtomicUInt32 count; bool keepGoing; }; diff --git a/src/mongo/shell/bench.cpp b/src/mongo/shell/bench.cpp index 3c95600d943..de5c04f2605 100644 --- a/src/mongo/shell/bench.cpp +++ b/src/mongo/shell/bench.cpp @@ -250,7 +250,7 @@ namespace mongo { } void BenchRunState::tellWorkersToFinish() { - _isShuttingDown.set( 1 ); + _isShuttingDown.store( 1 ); } void BenchRunState::assertFinished() { @@ -259,7 +259,7 @@ namespace mongo { } bool BenchRunState::shouldWorkerFinish() { - return bool(_isShuttingDown.get()); + return (_isShuttingDown.loadRelaxed() == 1); } void BenchRunState::onWorkerStarted() { diff --git a/src/mongo/shell/bench.h b/src/mongo/shell/bench.h index 18784b4457d..ee9a232fa0c 100644 --- a/src/mongo/shell/bench.h +++ b/src/mongo/shell/bench.h @@ -34,9 +34,9 @@ #include <boost/thread/condition.hpp> #include <boost/thread/mutex.hpp> -#include "mongo/bson/util/atomic_int.h" #include "mongo/client/dbclientinterface.h" #include "mongo/db/jsobj.h" +#include "mongo/platform/atomic_word.h" #include "mongo/util/timer.h" namespace pcrecpp { @@ -305,7 +305,7 @@ namespace mongo { boost::condition _stateChangeCondition; unsigned _numUnstartedWorkers; unsigned _numActiveWorkers; - AtomicUInt _isShuttingDown; + AtomicUInt32 _isShuttingDown; }; /** diff --git a/src/mongo/util/concurrency/rwlockimpl.cpp b/src/mongo/util/concurrency/rwlockimpl.cpp index 0abef186217..0ebb3e49da2 100644 --- a/src/mongo/util/concurrency/rwlockimpl.cpp +++ b/src/mongo/util/concurrency/rwlockimpl.cpp @@ -79,13 +79,13 @@ namespace mongo { dassert( state == 0 ); state++; AcquireSRWLockShared(&_lock); - shares++; + shares.fetchAndAdd(1); } void SimpleRWLock::unlock_shared() { int& state = s.getRef(); dassert( state == 1 ); state--; - shares--; + shares.fetchAndSubtract(1); ReleaseSRWLockShared(&_lock); } # else diff --git a/src/mongo/util/concurrency/simplerwlock.h b/src/mongo/util/concurrency/simplerwlock.h index 289c422606d..b267b03e7c2 100644 --- a/src/mongo/util/concurrency/simplerwlock.h +++ b/src/mongo/util/concurrency/simplerwlock.h @@ -29,7 +29,7 @@ #pragma once #include "mongo/base/string_data.h" -#include "mongo/bson/util/atomic_int.h" +#include "mongo/platform/atomic_word.h" namespace mongo { @@ -43,7 +43,7 @@ namespace mongo { RWLockBase m; #endif #if defined(_WIN32) && defined(_DEBUG) - AtomicUInt shares; + AtomicUInt32 shares; ThreadLocalValue<int> s; unsigned tid; #endif |