// 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
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
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<Ipc::Mem::PageStack::Value>);
const size_t pagesDataSize = capacity * pageSize;
return StackSize(capacity) + pagesDataSize + levelsSize;
}
#ifndef SQUID_IPC_MEM_PAGE_STACK_H
#define SQUID_IPC_MEM_PAGE_STACK_H
-#include "ipc/AtomicWord.h"
#include "ipc/mem/FlexibleArray.h"
+#include <atomic>
+
namespace Ipc
{
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);
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<Offset> theSize;
+ std::atomic<Offset> theSize;
/// last readable item index; just a hint, not a guarantee
- Atomic::WordT<Offset> theLastReadable;
+ std::atomic<Offset> theLastReadable;
/// first writable item index; just a hint, not a guarantee
- Atomic::WordT<Offset> theFirstWritable;
+ std::atomic<Offset> theFirstWritable;
- typedef Atomic::WordT<Value> Item;
+ typedef std::atomic<Value> Item;
Ipc::Mem::FlexibleArray<Item> theItems; ///< page number storage
};