]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Polished shared memory initialization sequence, using RunnersRegistry API.
authorAlex Rousskov <rousskov@measurement-factory.com>
Thu, 14 Apr 2011 04:25:35 +0000 (22:25 -0600)
committerAlex Rousskov <rousskov@measurement-factory.com>
Thu, 14 Apr 2011 04:25:35 +0000 (22:25 -0600)
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.

src/MemStore.cc
src/MemStore.h
src/ipc/mem/Pages.cc

index e6bec8bf4cddf24ae035f39f47aa9a40736b8888..d90364f7fdd5de53978fef67c4a7748767cfd861 100644 (file)
@@ -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();
+}
index 547f07c83c8c4b9e2a49a9e3022170f408630f08..7709b7019d200d623342a2205b39e48ceb8bbfdf 100644 (file)
@@ -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
 };
index 34889043afd9d5cfea23297873f17748cc277670..dad5f8ca03a99350777db8dd48ed273cf1473d9c 100644 (file)
@@ -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();
+}