From: Alex Rousskov Date: Thu, 14 Apr 2011 04:25:35 +0000 (-0600) Subject: Polished shared memory initialization sequence, using RunnersRegistry API. X-Git-Tag: take06~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a4555399ac03b5fefe9bb248dd20819a55817539;p=thirdparty%2Fsquid.git Polished shared memory initialization sequence, using RunnersRegistry API. The master process is now responsible for initializing all shared memory segments before starting kids. The kids do not create new segments and attach to the already initialized segments instead. This approach may not scale for ever, but it avoids more complex initialization synchronization via Coordinator. Do not use Strings for globals because current string memory pools do not support early initialization. --- diff --git a/src/MemStore.cc b/src/MemStore.cc index e6bec8bf4c..d90364f7fd 100644 --- a/src/MemStore.cc +++ b/src/MemStore.cc @@ -6,15 +6,28 @@ */ #include "config.h" +#include "base/RunnersRegistry.h" #include "ipc/mem/Page.h" #include "ipc/mem/Pages.h" #include "MemObject.h" #include "MemStore.h" #include "HttpReply.h" +/// shared memory segment path to use for MemStore maps +static const char *ShmLabel = "cache_mem"; // XXX: support storage using more than one page per entry +void +MemStore::Init() +{ + const int64_t entryLimit = EntryLimit(); + if (entryLimit <= 0) + return; // no memory cache configured or a misconfiguration + + MemStoreMap *map = new MemStoreMap(ShmLabel, entryLimit); + delete map; // we just wanted to initialize shared memory segments +} MemStore::MemStore(): map(NULL) { @@ -26,18 +39,13 @@ MemStore::~MemStore() } void -MemStore::init() -{ - if (!map && Config.memMaxSize && (!UsingSmp() || IamWorkerProcess())) { - // TODO: warn if we cannot support the configured maximum entry size - const int64_t entrySize = Ipc::Mem::PageSize(); // for now - const int64_t entryCount = Config.memMaxSize / entrySize; - // TODO: warn if we cannot cache at least one item (misconfiguration) - if (entryCount > 0) { - map = new MemStoreMap("cache_mem", entryCount); - map->cleaner = this; - } - } +MemStore::init() { + const int64_t entryLimit = EntryLimit(); + if (entryLimit <= 0) + return; // no memory cache configured or a misconfiguration + + map = new MemStoreMap(ShmLabel); + map->cleaner = this; } void @@ -304,3 +312,37 @@ MemStore::cleanReadable(const sfileno fileno) Ipc::Mem::PutPage(map->extras(fileno).page); } +/// calculates maximum number of entries we need to store and map +int64_t +MemStore::EntryLimit() +{ + if (!Config.memMaxSize) + return 0; // no memory cache configured + + // TODO: warn if we cannot support the configured maximum entry size + const int64_t entrySize = Ipc::Mem::PageSize(); // for now + const int64_t entryLimit = Config.memMaxSize / entrySize; + // TODO: warn if we cannot cache at least one item (misconfiguration) + return entryLimit; +} + + +/// initializes shared memory segments used by MemStore +class MemStoreRr: public RegisteredRunner +{ +public: + /* RegisteredRunner API */ + virtual void run(const RunnerRegistry &); + // TODO: cleanup in destructor +}; + +RunnerRegistrationEntry(rrAfterConfig, MemStoreRr); + + +void MemStoreRr::run(const RunnerRegistry &) +{ + // XXX: restore if (!UsingSmp()) return; + + if (IamMasterProcess()) + MemStore::Init(); +} diff --git a/src/MemStore.h b/src/MemStore.h index 547f07c83c..7709b7019d 100644 --- a/src/MemStore.h +++ b/src/MemStore.h @@ -32,6 +32,9 @@ public: virtual void maintain(); virtual void updateSize(int64_t size, int sign); + /// initializes shared memory segments before they are used by workers + static void Init(); + protected: bool willFit(int64_t needed); void keep(StoreEntry &e); @@ -42,6 +45,8 @@ protected: // Ipc::StoreMapCleaner API virtual void cleanReadable(const sfileno fileno); + static int64_t EntryLimit(); + private: MemStoreMap *map; ///< index of mem-cached entries }; diff --git a/src/ipc/mem/Pages.cc b/src/ipc/mem/Pages.cc index 34889043af..dad5f8ca03 100644 --- a/src/ipc/mem/Pages.cc +++ b/src/ipc/mem/Pages.cc @@ -7,6 +7,7 @@ #include "config.h" #include "base/TextException.h" +#include "base/RunnersRegistry.h" #include "ipc/mem/PagePool.h" #include "ipc/mem/Pages.h" #include "structs.h" @@ -16,7 +17,7 @@ // 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; // TODO: make configurable to avoid waste when mem-cached objects are small/big @@ -72,3 +73,26 @@ Ipc::Mem::Limit() } // TODO: Implement size_t Ipc::Mem::Level() + + +/// initializes shared memory pages +class SharedMemPagesRr: public RegisteredRunner +{ +public: + /* RegisteredRunner API */ + virtual void run(const RunnerRegistry &); + // TODO: cleanup in destructor +}; + +RunnerRegistrationEntry(rrAfterConfig, SharedMemPagesRr); + + +void SharedMemPagesRr::run(const RunnerRegistry &) +{ + // XXX: restore if (!UsingSmp()) return; + + if (IamMasterProcess()) + Ipc::Mem::Init(); + else + Ipc::Mem::Attach(); +}