*
*/
-#include "config.h"
+#include "squid.h"
#include "base/TextException.h"
#include "base/RunnersRegistry.h"
#include "ipc/mem/PagePool.h"
// TODO: make pool id more unique so it does not conflict with other Squids?
static const char *PagePoolId = "squid-page-pool";
static Ipc::Mem::PagePool *ThePagePool = 0;
+static int TheLimits[Ipc::Mem::PageId::maxPurpose];
// TODO: make configurable to avoid waste when mem-cached objects are small/big
size_t
-Ipc::Mem::PageSize() {
+Ipc::Mem::PageSize()
+{
return 32*1024;
}
bool
-Ipc::Mem::GetPage(PageId &page)
+Ipc::Mem::GetPage(const PageId::Purpose purpose, PageId &page)
{
- return ThePagePool ? ThePagePool->get(page) : false;
+ return ThePagePool && PagesAvailable(purpose) > 0 ?
+ ThePagePool->get(purpose, page) : false;
}
void
size_t
Ipc::Mem::PageLimit()
{
- return ThePagePool ? ThePagePool->capacity() : 0;
+ size_t limit = 0;
+ for (int i = 0; i < PageId::maxPurpose; ++i)
+ limit += PageLimit(i);
+ return limit;
}
size_t
-Ipc::Mem::CachePageLimit()
+Ipc::Mem::PageLimit(const int purpose)
{
- // TODO: adjust cache_mem description to say that in SMP mode,
- // in-transit objects are not allocated using cache_mem. Eventually,
- // they should not use cache_mem even if shared memory is not used:
- // in-transit objects have nothing to do with caching.
- return Config.memMaxSize > 0 ? Config.memMaxSize / PageSize() : 0;
+ Must(0 <= purpose && purpose <= PageId::maxPurpose);
+ return TheLimits[purpose];
}
-size_t
-Ipc::Mem::IoPageLimit()
+// note: adjust this if we start recording needs during reconfigure
+void
+Ipc::Mem::NotePageNeed(const int purpose, const int count)
{
- // XXX: this should be independent from memory cache pages
- return CachePageLimit();
+ Must(0 <= purpose && purpose <= PageId::maxPurpose);
+ Must(count >= 0);
+ TheLimits[purpose] += count;
}
size_t
Ipc::Mem::PageLevel()
{
- return ThePagePool ? ThePagePool->capacity() - ThePagePool->size() : 0;
+ return ThePagePool ? ThePagePool->level() : 0;
}
size_t
-Ipc::Mem::CachePageLevel()
+Ipc::Mem::PageLevel(const int purpose)
{
- // TODO: make a separate counter for shared memory pages for memory cache
- return PageLevel();
-}
-
-size_t
-Ipc::Mem::IoPageLevel()
-{
- // TODO: make a separate counter for shared memory pages for IPC I/O
- return PageLevel();
+ return ThePagePool ? ThePagePool->level(purpose) : 0;
}
/// initializes shared memory pages
-class SharedMemPagesRr: public RegisteredRunner
+class SharedMemPagesRr: public Ipc::Mem::RegisteredRunner
{
public:
/* RegisteredRunner API */
SharedMemPagesRr(): owner(NULL) {}
virtual void run(const RunnerRegistry &);
+ virtual void create(const RunnerRegistry &);
+ virtual void open(const RunnerRegistry &);
virtual ~SharedMemPagesRr();
private:
RunnerRegistrationEntry(rrAfterConfig, SharedMemPagesRr);
-void SharedMemPagesRr::run(const RunnerRegistry &)
+void
+SharedMemPagesRr::run(const RunnerRegistry &r)
{
- if (!UsingSmp())
+ if (Ipc::Mem::PageLimit() <= 0)
return;
- // When cache_dirs start using shared memory pages, they would
- // need to communicate their needs to us somehow.
- if (Config.memMaxSize <= 0)
- return;
-
- if (Ipc::Mem::CachePageLimit() <= 0) {
- if (IamMasterProcess()) {
- debugs(54, DBG_IMPORTANT, "WARNING: mem-cache size is too small ("
- << (Config.memMaxSize / 1024.0) << " KB), should be >= " <<
- (Ipc::Mem::PageSize() / 1024.0) << " KB");
- }
- return;
- }
+ Ipc::Mem::RegisteredRunner::run(r);
+}
- if (IamMasterProcess()) {
- Must(!owner);
- // reserve 10% for IPC I/O
- const size_t capacity = Ipc::Mem::CachePageLimit() * 1.1;
- owner = Ipc::Mem::PagePool::Init(PagePoolId, capacity, Ipc::Mem::PageSize());
- }
+void
+SharedMemPagesRr::create(const RunnerRegistry &)
+{
+ Must(!owner);
+ owner = Ipc::Mem::PagePool::Init(PagePoolId, Ipc::Mem::PageLimit(),
+ Ipc::Mem::PageSize());
+}
+void
+SharedMemPagesRr::open(const RunnerRegistry &)
+{
Must(!ThePagePool);
ThePagePool = new Ipc::Mem::PagePool(PagePoolId);
}