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: