]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/ipc/mem/PageStack.h
Docs: Copyright updates for 2018 (#114)
[thirdparty/squid.git] / src / ipc / mem / PageStack.h
index 3048ba20a35f405d816f370d8ec31391c199cb2a..3df60a19e8a572444a283d5fd0a23df38a843a95 100644 (file)
@@ -1,61 +1,78 @@
 /*
- * $Id$
+ * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
  *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #ifndef SQUID_IPC_MEM_PAGE_STACK_H
 #define SQUID_IPC_MEM_PAGE_STACK_H
 
-#include "ipc/AtomicWord.h"
-#include "ipc/mem/Segment.h"
+#include "ipc/mem/FlexibleArray.h"
 
-namespace Ipc {
+#include <atomic>
 
-namespace Mem {
+namespace Ipc
+{
+
+namespace Mem
+{
+
+class PageId;
 
 /// Atomic container of "free" page numbers inside a single SharedMemory space.
 /// Assumptions: all page numbers are unique, positive, have an known maximum,
 /// and can be temporary unavailable as long as they are never trully lost.
-class PageStack {
+class PageStack
+{
 public:
     typedef uint32_t Value; ///< stack item type (a free page number)
 
-    /// creates a new shared stack that can hold up to capacity items
-    PageStack(const String &id, const unsigned int capacity);
-    /// attaches to the identified shared stack
-    PageStack(const String &id);
+    PageStack(const uint32_t aPoolId, const unsigned int aCapacity, const size_t aPageSize);
+
+    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.load()); }
 
     /// sets value and returns true unless no free page numbers are found
-    bool pop(Value &value);
+    bool pop(PageId &page);
     /// makes value available as a free page number to future pop() callers
-    void push(const Value value);
+    void push(PageId &page);
+
+    bool pageIdIsValid(const PageId &page) const;
+
+    /// total shared memory size required to share
+    static size_t SharedMemorySize(const uint32_t aPoolId, const unsigned int capacity, const size_t pageSize);
+    size_t sharedMemorySize() const;
+
+    /// shared memory size required only by PageStack, excluding
+    /// shared counters and page data
+    static size_t StackSize(const unsigned int capacity);
+    size_t stackSize() const;
 
 private:
     /// stack index and size type (may temporary go negative)
     typedef int Offset;
 
-    struct Shared {
-        Shared(const unsigned int aCapacity);
-
-        // these help iterate the stack in search of a free spot or a page
-        Offset next(const Offset idx) const { return (idx + 1) % theCapacity; }
-        Offset prev(const Offset idx) const { return (theCapacity + idx - 1) % theCapacity; }
+    // these help iterate the stack in search of a free spot or a page
+    Offset next(const Offset idx) const { return (idx + 1) % theCapacity; }
+    Offset prev(const Offset idx) const { return (theCapacity + idx - 1) % theCapacity; }
 
-        const Offset theCapacity; ///< stack capacity, i.e. theItems size
-        /// lower bound for the number of free pages (may get negative!)
-        AtomicWordT<Offset> theSize;
+    const uint32_t thePoolId; ///< pool ID
+    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!)
+    std::atomic<Offset> theSize;
 
-        /// last readable item index; just a hint, not a guarantee
-        AtomicWordT<Offset> theLastReadable;
-        /// first writable item index; just a hint, not a guarantee
-        AtomicWordT<Offset> theFirstWritable;
+    /// last readable item index; just a hint, not a guarantee
+    std::atomic<Offset> theLastReadable;
+    /// first writable item index; just a hint, not a guarantee
+    std::atomic<Offset> theFirstWritable;
 
-        typedef AtomicWordT<Value> Item;
-        Item theItems[]; ///< page number storage
-    };
-
-    Segment shm; ///< shared memory segment to store metadata (and pages)
-    Shared *shared; ///< our metadata, shared among all stack users
+    typedef std::atomic<Value> Item;
+    Ipc::Mem::FlexibleArray<Item> theItems; ///< page number storage
 };
 
 } // namespace Mem
@@ -63,3 +80,4 @@ private:
 } // namespace Ipc
 
 #endif // SQUID_IPC_MEM_PAGE_STACK_H
+