configmgr/source/components.cxx             |    6 +++++
 configmgr/source/node.cxx                   |   13 +++++++++++-
 configmgr/source/node.hxx                   |    4 +++
 include/salhelper/simplereferenceobject.hxx |   29 ++++++++++++++++++++++------
 4 files changed, 45 insertions(+), 7 deletions(-)

New commits:
commit f05302c3dffe79dc4a799ed341e0096f34b66808
Author:     Michael Meeks <michael.me...@collabora.com>
AuthorDate: Sat Oct 19 16:57:44 2024 +0100
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Fri Feb 28 15:43:40 2025 +0100

    lok: encourage more sharing of config Node pages.
    
    Profiles show lots of probe:do_wp_page events from things like
    configmgr::Access::getUnmodifiedChild - as when we read we touch
    lots of Node reference counts - un-necessarily.
    
    So - reduce un-necessary reference counting thrash here in the
    lok case through the environment variable. Quite possibly this
    would also be safe and beneficial for the desktop app - needs
    measurement.
    
    measuring with coolmap and an empty hello-world.odt before & after:
    before:
            unshared  3634 (14536kB)
            unshared  3631 (14524kB)
            unshared  3605 (14420kB)
    
    after:
            unshared  3578 (14312kB)
            unshared  3613 (14452kB)
            unshared  3599 (14396kB)
    
    Not hugely encouraging, perhaps there is another page touch
    underneath we'll find when this is addressed.
    
    Change-Id: I8ac74c5fcd17f8699139e914a7076a7848456e2a
    Signed-off-by: Michael Meeks <michael.me...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175197
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182349
    Tested-by: Jenkins

diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx
index 5716da7d4616..85e66a1f27f6 100644
--- a/configmgr/source/components.cxx
+++ b/configmgr/source/components.cxx
@@ -492,6 +492,10 @@ Components::Components(
 {
     assert(context.is());
     lock_ = lock();
+
+    bool staticize = !!getenv("SAL_CONFIG_STATICIZE");
+    Node::setStaticizedFlag(staticize);
+
     OUString conf(expand(u"${CONFIGURATION_LAYERS}"_ustr));
     int layer = 0;
     for (sal_Int32 i = 0;;) {
@@ -629,6 +633,8 @@ Components::Components(
         }
         i = n;
     }
+
+    Node::setStaticizedFlag(false);
 }
 
 Components::~Components()
diff --git a/configmgr/source/node.cxx b/configmgr/source/node.cxx
index fdb166f146b8..3c8387cfaf43 100644
--- a/configmgr/source/node.cxx
+++ b/configmgr/source/node.cxx
@@ -65,7 +65,18 @@ rtl::Reference< Node > Node::getMember(OUString const & 
name) {
     return i == members.end() ? rtl::Reference< Node >() : i->second;
 }
 
-Node::Node(int layer): layer_(layer), finalized_(Data::NO_LAYER) {}
+bool Node::CreateStaticizedNodes = false;
+
+void Node::setStaticizedFlag(bool staticized)
+{
+    CreateStaticizedNodes = staticized;
+}
+
+Node::Node(int layer): layer_(layer), finalized_(Data::NO_LAYER)
+{
+    if (CreateStaticizedNodes)
+        staticize();
+}
 
 Node::Node(const Node & other):
     SimpleReferenceObject(), layer_(other.layer_), finalized_(other.finalized_)
diff --git a/configmgr/source/node.hxx b/configmgr/source/node.hxx
index df5a127cdbb5..304307677176 100644
--- a/configmgr/source/node.hxx
+++ b/configmgr/source/node.hxx
@@ -50,6 +50,9 @@ public:
     void setLayer(int layer);
     int getLayer() const { return layer_;}
 
+    /// when @staticized is set all new nodes will not ref-count
+    static void setStaticizedFlag(bool staticized);
+
     void setFinalized(int layer);
     int getFinalized() const { return finalized_;}
 
@@ -67,6 +70,7 @@ private:
     int layer_;
     int finalized_;
     OUString description_;
+    static bool CreateStaticizedNodes;
 };
 
 }
commit b30c061989ede0c19b62a10f6206cecc77e2bf69
Author:     Michael Meeks <michael.me...@collabora.com>
AuthorDate: Thu Oct 17 07:24:10 2024 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Fri Feb 28 15:43:32 2025 +0100

    SimpleReferenceObject: add ability to staticize the ref-count.
    
    Useful for when we allocate data at startup and want to share it
    across multiple threads. Also potentiall useful for turning
    extreme cases of ref-count wrap-around into a more benign leak.
    
    Change-Id: I04e6a62dbd366d294d86ab72036c3498402357f0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175196
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182348
    Reviewed-by: Michael Meeks <michael.me...@collabora.com>
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/include/salhelper/simplereferenceobject.hxx 
b/include/salhelper/simplereferenceobject.hxx
index ac721ad3da98..59a2baf83bc6 100644
--- a/include/salhelper/simplereferenceobject.hxx
+++ b/include/salhelper/simplereferenceobject.hxx
@@ -60,20 +60,28 @@ namespace salhelper {
  */
 class SALHELPER_DLLPUBLIC SimpleReferenceObject
 {
+    static const size_t nStaticFlag = 0x80000000;
+
 public:
     SimpleReferenceObject(): m_nCount(0) {}
 
     /** @attention
-        The results are undefined if, for any individual instance of
-        SimpleReferenceObject, the total number of calls to acquire() exceeds
-        the total number of calls to release() by a platform dependent amount
-        (which, hopefully, is quite large).
+        If, for any individual instance of SimpleReferenceObject, the total
+        number of calls to acquire() exceeds the total number of calls to
+        release() by 2^31 - the object will never subsequently be released.
      */
     void acquire()
-    { osl_atomic_increment(&m_nCount); }
+    {
+        if (!(m_nCount & nStaticFlag))
+            osl_atomic_increment(&m_nCount);
+    }
 
     void release()
-    { if (osl_atomic_decrement(&m_nCount) == 0) delete this; }
+    {
+        if (!(m_nCount & nStaticFlag) &&
+            osl_atomic_decrement(&m_nCount) == 0)
+            delete this;
+    }
 
     /** see general class documentation
      */
@@ -95,6 +103,15 @@ public:
 protected:
     virtual ~SimpleReferenceObject() COVERITY_NOEXCEPT_FALSE;
 
+    /** mark reference count as not to be touched, and the
+     * related object as having an indefinite lifespan.
+     * NB. do not use if you have a non-empty destructor.
+     */
+    void staticize()
+    {
+        m_nCount |= nStaticFlag;
+    }
+
     oslInterlockedCount m_nCount;
 
 private:

Reply via email to