diff --git a/Sources/Plasma/CoreLib/HeadSpin.h b/Sources/Plasma/CoreLib/HeadSpin.h index 5fd53a70..4b5648c5 100644 --- a/Sources/Plasma/CoreLib/HeadSpin.h +++ b/Sources/Plasma/CoreLib/HeadSpin.h @@ -489,19 +489,4 @@ void DebugMsg(const char* fmt, ...); #define DEFAULT_FATAL(var) default: FATAL("No valid case for switch variable '" #var "'"); break; #endif -/***************************************************************************** -* -* Atomic Operations -* FIXME: Replace with std::atomic when VS2012 supports WinXP -* -***/ - -#ifdef _MSC_VER -# define AtomicAdd(value, increment) InterlockedExchangeAdd(value, increment) -# define AtomicSet(value, set) InterlockedExchange(value, set) -#elif __GNUC__ -# define AtomicAdd(value, increment) __sync_fetch_and_add(value, increment) -# define AtomicSet(value, set) __sync_lock_test_and_set(value, set) -#endif - #endif diff --git a/Sources/Plasma/FeatureLib/pfGameMgr/pfGameMgr.cpp b/Sources/Plasma/FeatureLib/pfGameMgr/pfGameMgr.cpp index 61b88b88..39f4043f 100644 --- a/Sources/Plasma/FeatureLib/pfGameMgr/pfGameMgr.cpp +++ b/Sources/Plasma/FeatureLib/pfGameMgr/pfGameMgr.cpp @@ -133,8 +133,8 @@ static HASHTABLEDECL(TransState, THashKeyVal, link) s_trans; static HASHTABLEDECL(IGameCli, THashKeyVal, link) s_games; static std::map s_factories; -static long s_transId; -static ARRAYOBJ(plKey) s_receivers; +static std::atomic s_transId; +static ARRAYOBJ(plKey) s_receivers; /***************************************************************************** @@ -163,11 +163,7 @@ AUTO_INIT_FUNC (SetGameMgrMsgHandler) { //============================================================================ static inline unsigned INextTransId () { - - unsigned transId = AtomicAdd(&s_transId, 1); - while (!transId) - transId = AtomicAdd(&s_transId, 1); - return transId; + return ++s_transId; } diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNt.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNt.cpp index 1475ede2..277a5eea 100644 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNt.cpp +++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNt.cpp @@ -80,7 +80,6 @@ static unsigned s_pageSizeMask; //=========================================================================== CNtWaitHandle::CNtWaitHandle () { - m_refCount = 1; m_event = CreateEvent( (LPSECURITY_ATTRIBUTES) nil, true, // manual reset @@ -94,17 +93,6 @@ CNtWaitHandle::~CNtWaitHandle () { CloseHandle(m_event); } -//=========================================================================== -void CNtWaitHandle::IncRef () { - InterlockedIncrement(&m_refCount); -} - -//=========================================================================== -void CNtWaitHandle::DecRef () { - if (!InterlockedDecrement(&m_refCount)) - delete this; -} - //=========================================================================== bool CNtWaitHandle::WaitForObject (unsigned timeMs) const { return WAIT_TIMEOUT != WaitForSingleObject(m_event, timeMs); @@ -189,7 +177,7 @@ static void INtOpDispatch ( // set event *after* operation is complete if (signalComplete) { signalComplete->SignalObject(); - signalComplete->DecRef(); + signalComplete->UnRef(); } // if we just deleted the last operation then stop dispatching @@ -203,7 +191,7 @@ static void INtOpDispatch ( if (op->pending) break; - InterlockedDecrement(&ntObj->ioCount); + --ntObj->ioCount; } ntObj->critsect.Leave(); @@ -300,7 +288,7 @@ bool INtConnInitialize (NtObject * ntObj) { //=========================================================================== void INtConnCompleteOperation (NtObject * ntObj) { // are we completing the last operation for this object? - if (InterlockedDecrement(&ntObj->ioCount)) + if (--ntObj->ioCount) return; DWORD err = GetLastError(); diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtInt.h b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtInt.h index f142836e..24effcaa 100644 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtInt.h +++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtInt.h @@ -50,6 +50,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #endif #define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNASYNCCOREEXE_PRIVATE_NT_PNACENTINT_H +#include "hsRefCnt.h" namespace Nt { @@ -87,15 +88,12 @@ public: BOOL TryEnter () { return TryEnterCriticalSection(&m_handle); } }; -class CNtWaitHandle { - long m_refCount; +class CNtWaitHandle : public hsAtomicRefCnt { HANDLE m_event; public: CNtWaitHandle (); ~CNtWaitHandle (); - void IncRef (); - void DecRef (); bool WaitForObject (unsigned timeMs) const; void SignalObject () const; }; @@ -131,7 +129,7 @@ struct NtObject { LISTDECL(Operation, link) opList; long nextCompleteSequence; long nextStartSequence; - long ioCount; + std::atomic ioCount; bool closed; NtObject() diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtSocket.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtSocket.cpp index 0437681f..ab4cd404 100644 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtSocket.cpp +++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtSocket.cpp @@ -49,6 +49,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #pragma hdrstop #include "pnAceNtInt.h" +#include namespace Nt { @@ -222,7 +223,7 @@ static void SocketStartAsyncRead (NtSock * sock) { bool readResult; sock->critsect.Enter(); if (sock->handle != INVALID_HANDLE_VALUE) { - InterlockedIncrement(&sock->ioCount); + ++sock->ioCount; readResult = ReadFile( sock->handle, sock->buffer + sock->bytesLeft, @@ -238,7 +239,7 @@ static void SocketStartAsyncRead (NtSock * sock) { DWORD err = GetLastError(); if (!readResult && (err != ERROR_IO_PENDING)) - InterlockedDecrement(&sock->ioCount); + --sock->ioCount; } //=========================================================================== @@ -378,7 +379,7 @@ static NtOpSocketWrite * SocketQueueAsyncWrite ( op->write.bytesProcessed = bytes; memcpy(op->write.buffer, data, bytes); - InterlockedIncrement(&sock->ioCount); + ++sock->ioCount; PerfAddCounter(kAsyncPerfSocketBytesWaitQueued, bytes); return op; @@ -1022,8 +1023,8 @@ void INtSocketOpCompleteSocketRead ( || ((sock->opRead.read.bytesProcessed + sock->bytesLeft) > sizeof(sock->buffer)) ) { #ifdef HS_DEBUGGING - static long s_once; - if (!AtomicAdd(&s_once, 1)) { + static std::once_flag s_once; + std::call_once(s_once, [sock]() { DumpInvalidData( "NtSockErr.log", sizeof(sock->buffer), @@ -1034,7 +1035,7 @@ void INtSocketOpCompleteSocketRead ( sock->opRead.read.bytes, sock->opRead.read.bytesProcessed ); - } + }); #endif // ifdef HS_DEBUGGING LogMsg( @@ -1419,7 +1420,7 @@ bool NtSocketWrite ( op->write.bytesProcessed = bytes; PerfAddCounter(kAsyncPerfSocketBytesWaitQueued, bytes); - InterlockedIncrement(&sock->ioCount); + ++sock->ioCount; if (op == sock->opList.Head()) result = INtSocketOpCompleteQueuedSocketWrite((NtSock *) sock, op); diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceCore.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceCore.cpp index 8d109840..98322fe4 100644 --- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceCore.cpp +++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceCore.cpp @@ -48,6 +48,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "Pch.h" #pragma hdrstop +#include /***************************************************************************** * @@ -55,7 +56,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com * ***/ -static long s_perf[kNumAsyncPerfCounters]; +static std::atomic s_perf[kNumAsyncPerfCounters]; /**************************************************************************** @@ -124,19 +125,19 @@ static void IAsyncInitForServer () { //============================================================================ long PerfAddCounter (unsigned id, unsigned n) { ASSERT(id < kNumAsyncPerfCounters); - return AtomicAdd(&s_perf[id], n); + return s_perf[id].fetch_add(n); } //============================================================================ long PerfSubCounter (unsigned id, unsigned n) { ASSERT(id < kNumAsyncPerfCounters); - return AtomicAdd(&s_perf[id], -(signed)n); + return s_perf[id].fetch_sub(n); } //============================================================================ long PerfSetCounter (unsigned id, unsigned n) { ASSERT(id < kNumAsyncPerfCounters); - return AtomicSet(&s_perf[id], n); + return s_perf[id].exchange(n); } diff --git a/Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp b/Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp index f89e2e98..4ee6e878 100644 --- a/Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp +++ b/Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp @@ -815,10 +815,10 @@ void NetCommActivatePostInitErrorHandler () { //============================================================================ void NetCommUpdate () { // plClient likes to recursively call us on occasion; debounce that crap. - static long s_updating; - if (0 == AtomicSet(&s_updating, 1)) { + static std::atomic_flag s_updating = ATOMIC_FLAG_INIT; + if (!s_updating.test_and_set()) { NetClientUpdate(); - AtomicSet(&s_updating, 0); + s_updating.clear(); } } diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h b/Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h index 363347a3..8aff7722 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h @@ -273,7 +273,7 @@ static const char * s_transTypes[] = { }; static_assert(arrsize(s_transTypes) == kNumTransTypes, "Ngl Trans array and enum differ in size"); -static long s_perfTransCount[kNumTransTypes]; +static std::atomic s_perfTransCount[kNumTransTypes]; namespace Auth { struct CliAuConn; } diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp index ec7a0f80..b93b55d5 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp @@ -1208,7 +1208,7 @@ static ShaDigest s_accountNamePassHash; static wchar_t s_authToken[kMaxPublisherAuthKeyLength]; static wchar_t s_os[kMaxGTOSIdLength]; -static long s_perf[kNumPerf]; +static std::atomic s_perf[kNumPerf]; static uint32_t s_encryptionKey[4]; @@ -1596,14 +1596,14 @@ CliAuConn::CliAuConn () { memset(name, 0, sizeof(name)); - AtomicAdd(&s_perf[kPerfConnCount], 1); + ++s_perf[kPerfConnCount]; } //============================================================================ CliAuConn::~CliAuConn () { if (cli) NetCliDelete(cli, true); - AtomicAdd(&s_perf[kPerfConnCount], -1); + --s_perf[kPerfConnCount]; } //=========================================================================== diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglCore.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglCore.cpp index 8890b699..843aaacd 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglCore.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglCore.cpp @@ -77,7 +77,7 @@ struct ReportNetErrorTrans : NetNotifyTrans { ***/ static FNetClientErrorProc s_errorProc; -static long s_initCount; +static std::atomic s_initCount; /***************************************************************************** @@ -143,7 +143,7 @@ void ReportNetError (ENetProtocol protocol, ENetError error) { //============================================================================ void NetClientInitialize () { - if (0 == AtomicAdd(&s_initCount, 1)) { + if (0 == s_initCount.fetch_add(1)) { NetTransInitialize(); AuthInitialize(); GameInitialize(); @@ -160,7 +160,7 @@ void NetClientCancelAllTrans () { //============================================================================ void NetClientDestroy (bool wait) { - if (1 == AtomicAdd(&s_initCount, -1)) { + if (1 == s_initCount.fetch_sub(1)) { s_errorProc = nil; GateKeeperDestroy(false); diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp index 19c142a8..a808f4ac 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp @@ -225,7 +225,7 @@ static bool s_running; static CCritSect s_critsect; static LISTDECL(CliFileConn, link) s_conns; static CliFileConn * s_active; -static long s_perf[kNumPerf]; +static std::atomic s_perf[kNumPerf]; static unsigned s_connectBuildId; static unsigned s_serverType; @@ -588,7 +588,7 @@ CliFileConn::CliFileConn () , pingTimer(nil), pingSendTimeMs(0), lastHeardTimeMs(0) { memset(name, 0, sizeof(name)); - AtomicAdd(&s_perf[kPerfConnCount], 1); + ++s_perf[kPerfConnCount]; } //============================================================================ @@ -596,7 +596,7 @@ CliFileConn::~CliFileConn () { ASSERT(!cancelId); ASSERT(!reconnectTimer); Destroy(); - AtomicAdd(&s_perf[kPerfConnCount], -1); + --s_perf[kPerfConnCount]; } //=========================================================================== diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp index 1ac3fb15..49e5d79a 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp @@ -156,7 +156,7 @@ static LISTDECL(CliGmConn, link) s_conns; static CliGmConn * s_active; static FNetCliGameRecvBufferHandler s_bufHandler; static FNetCliGameRecvGameMgrMsgHandler s_gameMgrMsgHandler; -static long s_perf[kNumPerf]; +static std::atomic s_perf[kNumPerf]; /***************************************************************************** @@ -419,14 +419,14 @@ CliGmConn::CliGmConn () , seq(0), abandoned(false) , pingTimer(nil), pingSendTimeMs(0), lastHeardTimeMs(0) { - AtomicAdd(&s_perf[kPerfConnCount], 1); + ++s_perf[kPerfConnCount]; } //============================================================================ CliGmConn::~CliGmConn () { if (cli) NetCliDelete(cli, true); - AtomicAdd(&s_perf[kPerfConnCount], -1); + --s_perf[kPerfConnCount]; } //============================================================================ diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp index 70b260e5..91fc7a0c 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp @@ -188,7 +188,7 @@ static CCritSect s_critsect; static LISTDECL(CliGkConn, link) s_conns; static CliGkConn * s_active; -static long s_perf[kNumPerf]; +static std::atomic s_perf[kNumPerf]; @@ -532,14 +532,14 @@ CliGkConn::CliGkConn () { memset(name, 0, sizeof(name)); - AtomicAdd(&s_perf[kPerfConnCount], 1); + ++s_perf[kPerfConnCount]; } //============================================================================ CliGkConn::~CliGkConn () { if (cli) NetCliDelete(cli, true); - AtomicAdd(&s_perf[kPerfConnCount], -1); + --s_perf[kPerfConnCount]; } //=========================================================================== diff --git a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp index b6a164a4..aa611a1d 100644 --- a/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp +++ b/Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp @@ -66,7 +66,7 @@ static const unsigned kDefaultTimeoutMs = 5 * 60 * 1000; static bool s_running; static CCritSect s_critsect; static LISTDECL(NetTrans, m_link) s_transactions; -static long s_perf[kNumPerf]; +static std::atomic s_perf[kNumPerf]; static unsigned s_timeoutMs = kDefaultTimeoutMs; @@ -127,16 +127,16 @@ NetTrans::NetTrans (ENetProtocol protocol, ETransType transType) , m_timeoutAtMs(0) , m_transType(transType) { - AtomicAdd(&s_perf[kPerfCurrTransactions], 1); - AtomicAdd(&s_perfTransCount[m_transType], 1); + ++s_perf[kPerfCurrTransactions]; + ++s_perfTransCount[m_transType]; // DebugMsg("%s@%p created", s_transTypes[m_transType], this); } //============================================================================ NetTrans::~NetTrans () { ASSERT(!m_link.IsLinked()); - AtomicAdd(&s_perfTransCount[m_transType], -1); - AtomicAdd(&s_perf[kPerfCurrTransactions], -1); + --s_perfTransCount[m_transType]; + --s_perf[kPerfCurrTransactions]; // DebugMsg("%s@%p destroyed", s_transTypes[m_transType], this); } diff --git a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp index 3a16e831..8b671160 100644 --- a/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp +++ b/Sources/Plasma/PubUtilLib/plVault/plVaultClientApi.cpp @@ -250,7 +250,7 @@ struct AddChildNodeFetchTrans { FVaultAddChildNodeCallback callback; void * cbParam; ENetError result; - long opCount; + std::atomic opCount; AddChildNodeFetchTrans() : callback(nil), cbParam(nil), result(kNetSuccess), opCount(0) { } @@ -1019,12 +1019,11 @@ void AddChildNodeFetchTrans::VaultNodeRefsFetched ( param, &incFetchCount ); - AtomicAdd(&trans->opCount, incFetchCount); + trans->opCount += incFetchCount; } // Make the callback now if there are no nodes to fetch, or if error - AtomicAdd(&trans->opCount, -1); - if (!trans->opCount) { + if (!(--trans->opCount)) { if (trans->callback) trans->callback( trans->result, @@ -1046,9 +1045,8 @@ void AddChildNodeFetchTrans::VaultNodeFetched ( if (IS_NET_ERROR(result)) trans->result = result; - - AtomicAdd(&trans->opCount, -1); - if (!trans->opCount) { + + if (!(--trans->opCount)) { if (trans->callback) trans->callback( trans->result, @@ -1793,13 +1791,13 @@ void VaultAddChildNode ( // One or more nodes need to be fetched before the callback is made AddChildNodeFetchTrans * trans = new AddChildNodeFetchTrans(callback, param); if (!childLink->node->GetNodeType()) { - AtomicAdd(&trans->opCount, 1); + ++trans->opCount; NetCliAuthVaultNodeFetch( childId, AddChildNodeFetchTrans::VaultNodeFetched, trans ); - AtomicAdd(&trans->opCount, 1); + ++trans->opCount; NetCliAuthVaultFetchNodeRefs( childId, AddChildNodeFetchTrans::VaultNodeRefsFetched, @@ -1807,13 +1805,13 @@ void VaultAddChildNode ( ); } if (!parentLink->node->GetNodeType()) { - AtomicAdd(&trans->opCount, 1); + ++trans->opCount; NetCliAuthVaultNodeFetch( parentId, AddChildNodeFetchTrans::VaultNodeFetched, trans ); - AtomicAdd(&trans->opCount, 1); + ++trans->opCount; NetCliAuthVaultFetchNodeRefs( parentId, AddChildNodeFetchTrans::VaultNodeRefsFetched, @@ -2218,8 +2216,7 @@ namespace _VaultFetchNodesAndWait { ) { ::VaultNodeFetched(result, nil, node); - long * nodeCount = (long *)param; - AtomicAdd(nodeCount, -1); + --(*reinterpret_cast*>(param)); } } // namespace _VaultFetchNodesAndWait @@ -2231,20 +2228,21 @@ void VaultFetchNodesAndWait ( ) { using namespace _VaultFetchNodesAndWait; - long nodeCount = (long)count; + std::atomic nodeCount(count); for (unsigned i = 0; i < count; ++i) { if (!force) { // See if we already have this node if (RelVaultNodeLink * link = s_nodes.Find(nodeIds[i])) { - AtomicAdd(&nodeCount, -1); + --nodeCount; continue; } } - // Start fetching the node - NetCliAuthVaultNodeFetch(nodeIds[i], _VaultNodeFetched, (void *)&nodeCount); + // Start fetching the node + NetCliAuthVaultNodeFetch(nodeIds[i], _VaultNodeFetched, + reinterpret_cast(&nodeCount)); } while (nodeCount) {