/* * Copyright (C) 1996-2023 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. */ /* DEBUG: section 54 Interprocess Communication */ #include "squid.h" #include "base/TextException.h" #include "ipc/mem/Page.h" #include "ipc/mem/PagePool.h" // Ipc::Mem::PagePool Ipc::Mem::PagePool::Owner * Ipc::Mem::PagePool::Init(const char *const shmId, const Ipc::Mem::PoolId stackId, const unsigned int capacity, const size_t pageSize) { PageStack::Config config; config.poolId = stackId; config.pageSize = pageSize; // the pages are stored in Ipc::Mem::Pages config.capacity = capacity; config.createFull = true; // all pages are initially available return shm_new(PageStack)(shmId, config); } Ipc::Mem::PagePool::PagePool(const char *const id): pageIndex(shm_old(PageStack)(id)), theLevels(reinterpret_cast( reinterpret_cast(pageIndex.getRaw()) + pageIndex->stackSize() + pageIndex->levelsPaddingSize())), theBuf(reinterpret_cast(theLevels + PageId::maxPurpose)) { } size_t Ipc::Mem::PagePool::level(const int purpose) const { Must(0 <= purpose && purpose < PageId::maxPurpose); return theLevels[purpose]; } bool Ipc::Mem::PagePool::get(const PageId::Purpose purpose, PageId &page) { Must(0 <= purpose && purpose < PageId::maxPurpose); if (pageIndex->pop(page)) { page.purpose = purpose; ++theLevels[purpose]; return true; } return false; } void Ipc::Mem::PagePool::put(PageId &page) { if (!page) return; Must(0 <= page.purpose && page.purpose < PageId::maxPurpose); --theLevels[page.purpose]; page.purpose = PageId::maxPurpose; return pageIndex->push(page); } char * Ipc::Mem::PagePool::pagePointer(const PageId &page) { Must(pageIndex->pageIdIsValid(page)); return theBuf + pageSize() * (page.number - 1); }