From 2253ee0b564157dbae316dde135c7269404983fe Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Tue, 2 Jun 2015 01:21:08 -0700 Subject: [PATCH] Refactor Ipc::Mem::PageStack using std::atomic --- src/ipc/mem/PagePool.h | 1 + src/ipc/mem/PageStack.cc | 15 ++++++++------- src/ipc/mem/PageStack.h | 13 +++++++------ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/ipc/mem/PagePool.h b/src/ipc/mem/PagePool.h index 09a0116974..9622574fd0 100644 --- a/src/ipc/mem/PagePool.h +++ b/src/ipc/mem/PagePool.h @@ -9,6 +9,7 @@ #ifndef SQUID_IPC_MEM_PAGE_POOL_H #define SQUID_IPC_MEM_PAGE_POOL_H +#include "ipc/AtomicWord.h" #include "ipc/mem/Page.h" #include "ipc/mem/PageStack.h" #include "ipc/mem/Pointer.h" diff --git a/src/ipc/mem/PageStack.cc b/src/ipc/mem/PageStack.cc index 05ec03f423..6be806cfe5 100644 --- a/src/ipc/mem/PageStack.cc +++ b/src/ipc/mem/PageStack.cc @@ -46,16 +46,16 @@ Ipc::Mem::PageStack::pop(PageId &page) // find a Readable slot, starting with theLastReadable and going left while (theSize >= 0) { - const Offset idx = theLastReadable; + Offset idx = theLastReadable; // mark the slot at ids Writable while extracting its current value - const Value value = theItems[idx].fetchAndAnd(0); // works if Writable is 0 + const Value value = theItems[idx].fetch_and(0); // works if Writable is 0 const bool popped = value != Writable; // theItems[idx] is probably not Readable [any more] // Whether we popped a Readable value or not, we should try going left // to maintain the index (and make progress). // We may fail if others already updated the index, but that is OK. - theLastReadable.swap_if(idx, prev(idx)); // may fail or lie + theLastReadable.compare_exchange_weak(idx, prev(idx)); // may fail or lie if (popped) { // the slot we emptied may already be filled, but that is OK @@ -83,14 +83,15 @@ Ipc::Mem::PageStack::push(PageId &page) Must(pageIdIsValid(page)); // find a Writable slot, starting with theFirstWritable and going right while (theSize < theCapacity) { - const Offset idx = theFirstWritable; - const bool pushed = theItems[idx].swap_if(Writable, page.number); + Offset idx = theFirstWritable; + auto isWritable = Writable; + const bool pushed = theItems[idx].compare_exchange_strong(isWritable, page.number); // theItems[idx] is probably not Writable [any more]; // Whether we pushed the page number or not, we should try going right // to maintain the index (and make progress). // We may fail if others already updated the index, but that is OK. - theFirstWritable.swap_if(idx, next(idx)); // may fail or lie + theFirstWritable.compare_exchange_weak(idx, next(idx)); // may fail or lie if (pushed) { // the enqueued value may already by gone, but that is OK @@ -121,7 +122,7 @@ Ipc::Mem::PageStack::sharedMemorySize() const size_t Ipc::Mem::PageStack::SharedMemorySize(const uint32_t, const unsigned int capacity, const size_t pageSize) { - const size_t levelsSize = PageId::maxPurpose * sizeof(Atomic::Word); + const size_t levelsSize = PageId::maxPurpose * sizeof(std::atomic); const size_t pagesDataSize = capacity * pageSize; return StackSize(capacity) + pagesDataSize + levelsSize; } diff --git a/src/ipc/mem/PageStack.h b/src/ipc/mem/PageStack.h index 6e22ade010..2895f85fa6 100644 --- a/src/ipc/mem/PageStack.h +++ b/src/ipc/mem/PageStack.h @@ -9,9 +9,10 @@ #ifndef SQUID_IPC_MEM_PAGE_STACK_H #define SQUID_IPC_MEM_PAGE_STACK_H -#include "ipc/AtomicWord.h" #include "ipc/mem/FlexibleArray.h" +#include + namespace Ipc { @@ -33,7 +34,7 @@ public: unsigned int capacity() const { return theCapacity; } size_t pageSize() const { return thePageSize; } /// lower bound for the number of free pages - unsigned int size() const { return max(0, theSize.get()); } + unsigned int size() const { return max(0, theSize.load()); } /// sets value and returns true unless no free page numbers are found bool pop(PageId &page); @@ -63,14 +64,14 @@ private: const Offset theCapacity; ///< stack capacity, i.e. theItems size const size_t thePageSize; ///< page size, used to calculate shared memory size /// lower bound for the number of free pages (may get negative!) - Atomic::WordT theSize; + std::atomic theSize; /// last readable item index; just a hint, not a guarantee - Atomic::WordT theLastReadable; + std::atomic theLastReadable; /// first writable item index; just a hint, not a guarantee - Atomic::WordT theFirstWritable; + std::atomic theFirstWritable; - typedef Atomic::WordT Item; + typedef std::atomic Item; Ipc::Mem::FlexibleArray theItems; ///< page number storage }; -- 2.39.5