*
*/
-#include "config.h"
+#include "squid.h"
#include "base/TextException.h"
+#include "base/RunnersRegistry.h"
#include "ipc/mem/PagePool.h"
#include "ipc/mem/Pages.h"
#include "structs.h"
// Eventually, we may have pools dedicated to memory caching, disk I/O, etc.
// TODO: make pool id more unique so it does not conflict with other Squids?
-static const String PagePoolId = "squid-page-pool";
+static const char *PagePoolId = "squid-page-pool";
static Ipc::Mem::PagePool *ThePagePool = 0;
+static int TheLimits[Ipc::Mem::PageId::maxPurpose];
-// XXX: make configurable
+// TODO: make configurable to avoid waste when mem-cached objects are small/big
size_t
-Ipc::Mem::PageSize() {
- return 16*1024;
-}
-
-void
-Ipc::Mem::Init()
-{
- Must(!ThePagePool);
- // XXX: pool capacity and page size should be configurable/meaningful
- ThePagePool = new PagePool(PagePoolId, 1024, PageSize());
-}
-
-void
-Ipc::Mem::Attach()
+Ipc::Mem::PageSize()
{
- Must(!ThePagePool);
- // TODO: make pool id more unique so it does not conflict with other Squid instances?
- ThePagePool = new PagePool(PagePoolId);
+ return 32*1024;
}
bool
-Ipc::Mem::GetPage(PageId &page)
+Ipc::Mem::GetPage(const PageId::Purpose purpose, PageId &page)
{
- Must(ThePagePool);
- return ThePagePool->get(page);
+ return ThePagePool && PagesAvailable(purpose) > 0 ?
+ ThePagePool->get(purpose, page) : false;
}
void
ThePagePool->put(page);
}
-void *
+char *
Ipc::Mem::PagePointer(const PageId &page)
{
Must(ThePagePool);
return ThePagePool->pagePointer(page);
}
+
+size_t
+Ipc::Mem::PageLimit()
+{
+ size_t limit = 0;
+ for (int i = 0; i < PageId::maxPurpose; ++i)
+ limit += PageLimit(i);
+ return limit;
+}
+
+size_t
+Ipc::Mem::PageLimit(const int purpose)
+{
+ Must(0 <= purpose && purpose <= PageId::maxPurpose);
+ return TheLimits[purpose];
+}
+
+// note: adjust this if we start recording needs during reconfigure
+void
+Ipc::Mem::NotePageNeed(const int purpose, const int count)
+{
+ Must(0 <= purpose && purpose <= PageId::maxPurpose);
+ Must(count >= 0);
+ TheLimits[purpose] += count;
+}
+
+size_t
+Ipc::Mem::PageLevel()
+{
+ return ThePagePool ? ThePagePool->level() : 0;
+}
+
+size_t
+Ipc::Mem::PageLevel(const int purpose)
+{
+ return ThePagePool ? ThePagePool->level(purpose) : 0;
+}
+
+/// initializes shared memory pages
+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:
+ Ipc::Mem::PagePool::Owner *owner;
+};
+
+RunnerRegistrationEntry(rrAfterConfig, SharedMemPagesRr);
+
+
+void
+SharedMemPagesRr::run(const RunnerRegistry &r)
+{
+ if (Ipc::Mem::PageLimit() <= 0)
+ return;
+
+ Ipc::Mem::RegisteredRunner::run(r);
+}
+
+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);
+}
+
+SharedMemPagesRr::~SharedMemPagesRr()
+{
+ if (!UsingSmp())
+ return;
+
+ delete ThePagePool;
+ ThePagePool = NULL;
+ delete owner;
+}