diff --git a/dbcon/joblist/resourcemanager.cpp b/dbcon/joblist/resourcemanager.cpp index db5cd15b3..91831f366 100644 --- a/dbcon/joblist/resourcemanager.cpp +++ b/dbcon/joblist/resourcemanager.cpp @@ -347,23 +347,23 @@ bool ResourceManager::userPriorityEnabled() const // If both have space, return true. bool ResourceManager::getMemory(int64_t amount, boost::shared_ptr& sessionLimit, bool patience) { - bool ret1 = (totalUmMemLimit.fetch_sub(amount, std::memory_order_relaxed) >= 0); + bool ret1 = (atomicops::atomicSubRef(totalUmMemLimit, amount) >= 0); bool ret2 = sessionLimit ? (atomicops::atomicSub(sessionLimit.get(), amount) >= 0) : ret1; uint32_t retryCounter = 0, maxRetries = 20; // 10s delay while (patience && !(ret1 && ret2) && retryCounter++ < maxRetries) { - totalUmMemLimit.fetch_add(amount, std::memory_order_relaxed); + atomicops::atomicAddRef(totalUmMemLimit, amount); sessionLimit ? atomicops::atomicAdd(sessionLimit.get(), amount) : 0; usleep(500000); - ret1 = (totalUmMemLimit.fetch_sub(amount, std::memory_order_relaxed) >= 0); + ret1 = (atomicops::atomicSubRef(totalUmMemLimit, amount) >= 0); ret2 = sessionLimit ? (atomicops::atomicSub(sessionLimit.get(), amount) >= 0) : ret1; } if (!(ret1 && ret2)) { // If we didn't get any memory, restore the counters. - totalUmMemLimit.fetch_add(amount, std::memory_order_relaxed); + atomicops::atomicAddRef(totalUmMemLimit, amount); sessionLimit ? atomicops::atomicAdd(sessionLimit.get(), amount) : 0; } return (ret1 && ret2); @@ -372,20 +372,20 @@ bool ResourceManager::getMemory(int64_t amount, boost::shared_ptr& sess // The amount type is unsafe if amount close to max that is unrealistic in 2024. bool ResourceManager::getMemory(int64_t amount, bool patience) { - bool ret1 = (totalUmMemLimit.fetch_sub(amount, std::memory_order_relaxed) >= 0); + bool ret1 = (atomicops::atomicSubRef(totalUmMemLimit, amount) >= 0); uint32_t retryCounter = 0, maxRetries = 20; // 10s delay while (patience && !ret1 && retryCounter++ < maxRetries) { - totalUmMemLimit.fetch_add(amount, std::memory_order_relaxed); + atomicops::atomicAddRef(totalUmMemLimit, amount); usleep(500000); - ret1 = (totalUmMemLimit.fetch_sub(amount, std::memory_order_relaxed) >= 0); + ret1 = (atomicops::atomicSubRef(totalUmMemLimit, amount) >= 0); } if (!ret1) { // If we didn't get any memory, restore the counters. - totalUmMemLimit.fetch_add(amount, std::memory_order_relaxed); + atomicops::atomicAddRef(totalUmMemLimit, amount); } return ret1; } diff --git a/dbcon/joblist/resourcemanager.h b/dbcon/joblist/resourcemanager.h index e6c296c96..eacbceb3c 100644 --- a/dbcon/joblist/resourcemanager.h +++ b/dbcon/joblist/resourcemanager.h @@ -327,11 +327,11 @@ class ResourceManager bool getMemory(int64_t amount, bool patience = true); inline void returnMemory(int64_t amount) { - totalUmMemLimit.fetch_add(amount, std::memory_order_relaxed); + atomicops::atomicAddRef(totalUmMemLimit, amount); } inline void returnMemory(int64_t amount, boost::shared_ptr& sessionLimit) { - totalUmMemLimit.fetch_add(amount, std::memory_order_relaxed); + atomicops::atomicAddRef(totalUmMemLimit, amount); sessionLimit ? atomicops::atomicAdd(sessionLimit.get(), amount) : 0; } inline int64_t availableMemory() const diff --git a/utils/common/atomicops.h b/utils/common/atomicops.h index 94e3e3201..9aec08da9 100644 --- a/utils/common/atomicops.h +++ b/utils/common/atomicops.h @@ -22,6 +22,7 @@ #include #include #include +#include /* This is an attempt to wrap the differneces between Windows and Linux around atomic ops. @@ -30,6 +31,16 @@ Boost has something in interprocess::ipcdetail, but it doesn't have 64-bit API's namespace atomicops { +// Atomic operations for atomic references +inline int64_t atomicAddRef(std::atomic& ref, int64_t val) +{ + return ref.fetch_add(val, std::memory_order_relaxed); +} + +inline int64_t atomicSubRef(std::atomic& ref, int64_t val) +{ + return ref.fetch_sub(val, std::memory_order_relaxed); +} // Returns the resulting, incremented value template inline T atomicInc(volatile T* mem) diff --git a/utils/common/countingallocator.h b/utils/common/countingallocator.h index f49f3132c..b0d554aad 100644 --- a/utils/common/countingallocator.h +++ b/utils/common/countingallocator.h @@ -22,6 +22,7 @@ #include #include #include +#include "atomicops.h" namespace allocators { @@ -74,10 +75,10 @@ class CountingAllocator assert(lastMemoryLimitCheckpointDiff > 0); auto currentGlobalMemoryLimit = - memoryLimit_->fetch_sub(lastMemoryLimitCheckpointDiff, std::memory_order_relaxed); + atomicops::atomicSubRef(*memoryLimit_, lastMemoryLimitCheckpointDiff); if (currentGlobalMemoryLimit < memoryLimitLowerBound_) { - memoryLimit_->fetch_add(lastMemoryLimitCheckpointDiff, std::memory_order_relaxed); + atomicops::atomicAddRef(*memoryLimit_, lastMemoryLimitCheckpointDiff); throw std::bad_alloc(); } lastMemoryLimitCheckpoint_ += lastMemoryLimitCheckpointDiff; @@ -147,7 +148,7 @@ class CountingAllocator : diffSinceLastCheckPoint + sizeToDeallocate; assert(lastMemoryLimitCheckpointDiff > 0); - memoryLimit_->fetch_add(lastMemoryLimitCheckpointDiff, std::memory_order_relaxed); + atomicops::atomicAddRef(*memoryLimit_, lastMemoryLimitCheckpointDiff); lastMemoryLimitCheckpoint_ -= (lastMemoryLimitCheckpoint_ == 0) ? 0 : lastMemoryLimitCheckpointDiff; }