From b60fa5fa051cae7e3a723cf92ddd4cb2bbffa017 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Sat, 31 Aug 2024 13:15:17 -0400 Subject: [PATCH] packagefs: Use only one object_cache for all TwoKeyAVLTreeNodes. Previously there were 6, all with the exact same object size. --- .../packagefs/kernel_interface.cpp | 7 ++ .../packagefs/util/TwoKeyAVLTree.h | 76 ++++++++----------- 2 files changed, 39 insertions(+), 44 deletions(-) diff --git a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp index 8d709a51f1..861a34a5de 100644 --- a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp @@ -19,6 +19,7 @@ #include #include +#include "util/TwoKeyAVLTree.h" #include "AttributeCookie.h" #include "AttributeDirectoryCookie.h" @@ -32,6 +33,8 @@ #include "Volume.h" +template<> object_cache* TwoKeyAVLTreeNode::sNodeCache = NULL; + static const uint32 kOptimalIOSize = 64 * 1024; @@ -1085,6 +1088,9 @@ packagefs_std_ops(int32 op, ...) PackageFileHeapAccessorBase::kChunkSize, sizeof(void*), 0, /* magazine capacity, count */ 2, 1, 0, NULL, NULL, NULL, NULL); + TwoKeyAVLTreeNode::sNodeCache = + create_object_cache("pkgfs TKAVLTreeNodes", + sizeof(TwoKeyAVLTreeNode), 8, NULL, NULL, NULL); error = PackageFSRoot::GlobalInit(); if (error != B_OK) { @@ -1102,6 +1108,7 @@ packagefs_std_ops(int32 op, ...) { PRINT("package_std_ops(): B_MODULE_UNINIT\n"); PackageFSRoot::GlobalUninit(); + delete_object_cache(TwoKeyAVLTreeNode::sNodeCache); delete_object_cache((object_cache*) PackageFileHeapAccessorBase::sChunkCache); StringConstants::Cleanup(); diff --git a/src/add-ons/kernel/file_systems/packagefs/util/TwoKeyAVLTree.h b/src/add-ons/kernel/file_systems/packagefs/util/TwoKeyAVLTree.h index 2c607a8290..42c66e92bd 100644 --- a/src/add-ons/kernel/file_systems/packagefs/util/TwoKeyAVLTree.h +++ b/src/add-ons/kernel/file_systems/packagefs/util/TwoKeyAVLTree.h @@ -138,12 +138,42 @@ public: // #pragma mark - TwoKeyAVLTreeNodeStrategy +template +struct TwoKeyAVLTreeNode : AVLTreeNode { + static object_cache* sNodeCache; + + static void* operator new(size_t size) + { + object_cache* cache = TwoKeyAVLTreeNode::sNodeCache; + const size_t nodeSize = sizeof(TwoKeyAVLTreeNode); + if (size != nodeSize || cache == NULL) + panic("unexpected size passed to operator new!"); + return object_cache_alloc(cache, 0); + } + static void operator delete(void* object) + { + object_cache_free(TwoKeyAVLTreeNode::sNodeCache, object, 0); + } + +public: + TwoKeyAVLTreeNode(const Value& value) + : + AVLTreeNode(), + value(value) + { + } + + Value value; +}; + + template class TwoKeyAVLTreeNodeStrategy { public: typedef TwoKeyAVLTreeKey Key; + typedef TwoKeyAVLTreeNode Node; TwoKeyAVLTreeNodeStrategy( const PrimaryKeyCompare& primaryKeyCompare = PrimaryKeyCompare(), @@ -156,58 +186,19 @@ public: fGetPrimaryKey(getPrimaryKey), fGetSecondaryKey(getSecondaryKey) { - fObjectCache = create_object_cache("packagefs TwoKeyAVLTreeNodes", sizeof(Node), 8, - NULL, NULL, NULL); - fObjectCacheRefs = new int32(1); - } - TwoKeyAVLTreeNodeStrategy(const TwoKeyAVLTreeNodeStrategy& other) - : - fPrimaryKeyCompare(other.fPrimaryKeyCompare), - fSecondaryKeyCompare(other.fSecondaryKeyCompare), - fGetPrimaryKey(other.fGetPrimaryKey), - fGetSecondaryKey(other.fGetSecondaryKey), - fObjectCache(other.fObjectCache), - fObjectCacheRefs(other.fObjectCacheRefs) - { - atomic_add(fObjectCacheRefs, 1); } ~TwoKeyAVLTreeNodeStrategy() { - atomic_add(fObjectCacheRefs, -1); - if (atomic_get(fObjectCacheRefs) == 0) { - delete_object_cache(fObjectCache); - delete fObjectCacheRefs; - } } - struct Node : AVLTreeNode { - static void* operator new(size_t size, object_cache* cache) { - if (size != sizeof(Node) || !cache) - panic("unexpected size passed to operator new!"); - return object_cache_alloc(cache, 0); - } - - Node(const Value& value) - : - AVLTreeNode(), - value(value) - { - } - - Value value; - }; - inline Node* Allocate(const Key& key, const Value& value) const { - return new(fObjectCache) Node(value); + return new Node(value); } inline void Free(Node* node) const { - if (node == NULL) - return; - - object_cache_delete(fObjectCache, node, 0); + delete node; } // internal use (not part of the strategy) @@ -260,9 +251,6 @@ private: SecondaryKeyCompare fSecondaryKeyCompare; GetPrimaryKey fGetPrimaryKey; GetSecondaryKey fGetSecondaryKey; - - object_cache* fObjectCache; - int32* fObjectCacheRefs; };