]>
Commit | Line | Data |
---|---|---|
be17aa82 | 1 | /* |
5b74111a | 2 | * Copyright (C) 1996-2018 The Squid Software Foundation and contributors |
bbc27441 AJ |
3 | * |
4 | * Squid software is distributed under GPLv2+ license and includes | |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
be17aa82 AR |
7 | */ |
8 | ||
9 | #ifndef SQUID_IPC_MEM_PAGE_STACK_H | |
10 | #define SQUID_IPC_MEM_PAGE_STACK_H | |
11 | ||
3a8c5551 | 12 | #include "ipc/mem/FlexibleArray.h" |
be17aa82 | 13 | |
2253ee0b AJ |
14 | #include <atomic> |
15 | ||
9199139f AR |
16 | namespace Ipc |
17 | { | |
be17aa82 | 18 | |
9199139f AR |
19 | namespace Mem |
20 | { | |
be17aa82 | 21 | |
68353d5a DK |
22 | class PageId; |
23 | ||
be17aa82 AR |
24 | /// Atomic container of "free" page numbers inside a single SharedMemory space. |
25 | /// Assumptions: all page numbers are unique, positive, have an known maximum, | |
26 | /// and can be temporary unavailable as long as they are never trully lost. | |
9199139f AR |
27 | class PageStack |
28 | { | |
be17aa82 AR |
29 | public: |
30 | typedef uint32_t Value; ///< stack item type (a free page number) | |
31 | ||
68353d5a | 32 | PageStack(const uint32_t aPoolId, const unsigned int aCapacity, const size_t aPageSize); |
be17aa82 | 33 | |
68353d5a DK |
34 | unsigned int capacity() const { return theCapacity; } |
35 | size_t pageSize() const { return thePageSize; } | |
b940ff87 | 36 | /// lower bound for the number of free pages |
2253ee0b | 37 | unsigned int size() const { return max(0, theSize.load()); } |
b940ff87 | 38 | |
be17aa82 | 39 | /// sets value and returns true unless no free page numbers are found |
68353d5a | 40 | bool pop(PageId &page); |
be17aa82 | 41 | /// makes value available as a free page number to future pop() callers |
68353d5a DK |
42 | void push(PageId &page); |
43 | ||
44 | bool pageIdIsValid(const PageId &page) const; | |
45 | ||
46 | /// total shared memory size required to share | |
47 | static size_t SharedMemorySize(const uint32_t aPoolId, const unsigned int capacity, const size_t pageSize); | |
48 | size_t sharedMemorySize() const; | |
be17aa82 | 49 | |
551f8a18 DK |
50 | /// shared memory size required only by PageStack, excluding |
51 | /// shared counters and page data | |
52 | static size_t StackSize(const unsigned int capacity); | |
53 | size_t stackSize() const; | |
54 | ||
be17aa82 | 55 | private: |
e963b5b5 AR |
56 | /// stack index and size type (may temporary go negative) |
57 | typedef int Offset; | |
be17aa82 | 58 | |
68353d5a DK |
59 | // these help iterate the stack in search of a free spot or a page |
60 | Offset next(const Offset idx) const { return (idx + 1) % theCapacity; } | |
61 | Offset prev(const Offset idx) const { return (theCapacity + idx - 1) % theCapacity; } | |
be17aa82 | 62 | |
68353d5a DK |
63 | const uint32_t thePoolId; ///< pool ID |
64 | const Offset theCapacity; ///< stack capacity, i.e. theItems size | |
65 | const size_t thePageSize; ///< page size, used to calculate shared memory size | |
66 | /// lower bound for the number of free pages (may get negative!) | |
2253ee0b | 67 | std::atomic<Offset> theSize; |
be17aa82 | 68 | |
68353d5a | 69 | /// last readable item index; just a hint, not a guarantee |
2253ee0b | 70 | std::atomic<Offset> theLastReadable; |
68353d5a | 71 | /// first writable item index; just a hint, not a guarantee |
2253ee0b | 72 | std::atomic<Offset> theFirstWritable; |
be17aa82 | 73 | |
2253ee0b | 74 | typedef std::atomic<Value> Item; |
3a8c5551 | 75 | Ipc::Mem::FlexibleArray<Item> theItems; ///< page number storage |
be17aa82 AR |
76 | }; |
77 | ||
78 | } // namespace Mem | |
79 | ||
80 | } // namespace Ipc | |
81 | ||
82 | #endif // SQUID_IPC_MEM_PAGE_STACK_H | |
f53969cc | 83 |