/*
- * $Id$
+ * Copyright (C) 1996-2015 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_POOL_H
#define SQUID_IPC_MEM_PAGE_POOL_H
+#include "ipc/mem/Page.h"
#include "ipc/mem/PageStack.h"
-#include "ipc/mem/Segment.h"
+#include "ipc/mem/Pointer.h"
-namespace Ipc {
+namespace Ipc
+{
-namespace Mem {
-
-class PageId;
+namespace Mem
+{
/// Atomic container of shared memory pages. Implemented using a collection of
/// Segments, each with a PageStack index of free pages. All pools must be
/// created by a single process.
-class PagePool {
+class PagePool
+{
public:
- /// creates a new shared page pool that can hold up to capacity pages of pageSize size
- PagePool(const String &id, const unsigned int capacity, const size_t pageSize);
- /// attaches to the identified shared page pool
- PagePool(const String &id);
+ typedef Ipc::Mem::Owner<PageStack> Owner;
+
+ static Owner *Init(const char *const id, const unsigned int capacity, const size_t pageSize);
+
+ PagePool(const char *const id);
- unsigned int capacity() const { return shared->theCapacity; }
+ unsigned int capacity() const { return pageIndex->capacity(); }
+ size_t pageSize() const { return pageIndex->pageSize(); }
/// lower bound for the number of free pages
- unsigned int size() const { return pageIndex.size(); }
- size_t pageSize() const { return shared->thePageSize; }
+ unsigned int size() const { return pageIndex->size(); }
+ /// approximate number of shared memory pages used now
+ size_t level() const { return capacity() - size(); }
+ /// approximate number of shared memory pages used now for given purpose
+ size_t level(const int purpose) const;
/// sets page ID and returns true unless no free pages are found
- bool get(PageId &page);
+ bool get(const PageId::Purpose purpose, PageId &page);
/// makes identified page available as a free page to future get() callers
void put(PageId &page);
/// converts page handler into a temporary writeable shared memory pointer
- void *pagePointer(const PageId &page);
+ char *pagePointer(const PageId &page);
private:
- inline bool pageIdIsValid(const PageId &page) const;
-
- struct Shared {
- Shared(const unsigned int aCapacity, const size_t aPageSize);
-
- /// total shared memory size required to share
- static off_t MemSize(const unsigned int capacity, const size_t pageSize);
-
- const unsigned int theId; ///< pool id
- const unsigned int theCapacity; ///< number of pages in the pool
- const size_t thePageSize; ///< page size
-
- // TODO: add padding to make pages system page-aligned?
- char theBuf[]; ///< pages storage
- };
-
- PageStack pageIndex; ///< free pages index
- Segment shm; ///< shared memory segment to store metadata (and pages)
- Shared *shared; ///< our metadata and page storage, shared among all pool users
+ Ipc::Mem::Pointer<PageStack> pageIndex; ///< free pages index
+ /// number of shared memory pages used now for each purpose
+ Atomic::Word *const theLevels;
+ char *const theBuf; ///< pages storage
};
} // namespace Mem
} // namespace Ipc
#endif // SQUID_IPC_MEM_PAGE_POOL_H
+