[haiku-commits] haiku: hrev53238 - in src: add-ons/kernel/file_systems/packagefs/util add-ons/kernel/file_systems/packagefs/package system/kernel/slab

  • From: waddlesplash <waddlesplash@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 10 Jul 2019 00:34:16 -0400 (EDT)

hrev53238 adds 4 changesets to branch 'master'
old head: ed9a502a9aba6ff9d5d8f6df6b0c2d128d67b87a
new head: d387d8c5f47bf53be29d1fa8602dc0d267c4bf32
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=d387d8c5f47b+%5Eed9a502a9aba

----------------------------------------------------------------------------

71e255cd3115: packagefs: Remove PackageDataV1 from PackageData.
  
  Now that we never access V1 packages in here, we don't need this.
  This saves *24* bytes off the size of the class, which is
  extremely significant as not only every PackageFile instance
  has an instance of this class, but every PackageNode does too;
  so the savings from this change is probably in the MB.

d230b5fdd372: packagefs: Use object caches for the most used node classes.
  
  Slab statistics from KDL show that on a stock nightly image
  (i.e. no additional packages besides the standards installed)
  there are 43848 *objects* (not bytes) in the PackageNodeAttribute
  cache, and 25090 in the PackageFile cache, so this seems more than
  worth it.
  
  The last commit seems to reduce memory usage at boot by about 1%,
  this commit seems to not affect it at all; but it is a significant
  performance optimization and on systems with more packages installed
  the effect may be very noticeable.
  
  Change-Id: I676a642ed6003f82b14396e1f02684575d899362

86e43bdf5833: kernel: Add missing error checks to 
MemoryManager::_AllocateChunks.

d387d8c5f47b: packagefs: Use an object_cache in the TwoKeyAVLTree also.
  
  TwoKeyAVLTree in packagefs is used for indexing. On a stock nightly,
  just after boot there are 3 TwoKeyAVLTrees with just over 28000 items
  each. So, this is another significant load off the generic allocator.

                              [ Augustin Cavalier <waddlesplash@xxxxxxxxx> ]

----------------------------------------------------------------------------

11 files changed, 108 insertions(+), 49 deletions(-)
.../file_systems/packagefs/package/Package.cpp   |  6 +--
.../file_systems/packagefs/package/PackageData.h | 41 +-------------------
.../packagefs/package/PackageDirectory.cpp       |  5 +++
.../packagefs/package/PackageDirectory.h         |  3 ++
.../packagefs/package/PackageFile.cpp            |  7 ++++
.../file_systems/packagefs/package/PackageFile.h |  3 ++
.../packagefs/package/PackageNodeAttribute.cpp   |  5 +++
.../packagefs/package/PackageNodeAttribute.h     |  3 ++
.../file_systems/packagefs/util/ClassCache.h     | 35 +++++++++++++++++
.../file_systems/packagefs/util/TwoKeyAVLTree.h  | 41 +++++++++++++++++++-
src/system/kernel/slab/MemoryManager.cpp         |  8 ++--

############################################################################

Commit:      71e255cd3115918af581cf98c73b86f34a585272
URL:         https://git.haiku-os.org/haiku/commit/?id=71e255cd3115
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Tue Jul  9 03:29:40 2019 UTC

packagefs: Remove PackageDataV1 from PackageData.

Now that we never access V1 packages in here, we don't need this.
This saves *24* bytes off the size of the class, which is
extremely significant as not only every PackageFile instance
has an instance of this class, but every PackageNode does too;
so the savings from this change is probably in the MB.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageData.h 
b/src/add-ons/kernel/file_systems/packagefs/package/PackageData.h
index 7968c3ed3b..6b82f717ba 100644
--- a/src/add-ons/kernel/file_systems/packagefs/package/PackageData.h
+++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageData.h
@@ -7,35 +7,27 @@
 
 
 #include <package/hpkg/PackageData.h>
-#include <package/hpkg/v1/PackageData.h>
 
 #include <string.h>
 
 
 typedef BPackageKit::BHPKG::BPackageData PackageDataV2;
-typedef BPackageKit::BHPKG::V1::BPackageData PackageDataV1;
 
 
 class PackageData {
 public:
-       explicit                                        PackageData(const 
PackageDataV1& data);
        explicit                                        PackageData(const 
PackageDataV2& data);
 
                        uint8                           Version() const { 
return fVersion; }
-                       const PackageDataV1& DataV1() const;
                        const PackageDataV2& DataV2() const;
 
-                       uint64                          CompressedSize() const;
                        uint64                          UncompressedSize() 
const;
 
                        bool                            IsEncodedInline() const;
                        const uint8*            InlineData() const;
 
 private:
-       static  const size_t            kDataSize = sizeof(PackageDataV1)
-                                                                               

sizeof(PackageDataV2)
-                                                                       ? 
sizeof(PackageDataV1)
-                                                                       : 
sizeof(PackageDataV2);
+       static  const size_t            kDataSize = sizeof(PackageDataV2);
 
 private:
                        union {
@@ -46,15 +38,6 @@ private:
 };
 
 
-inline
-PackageData::PackageData(const PackageDataV1& data)
-       :
-       fVersion(1)
-{
-       memcpy(&fData, &data, sizeof(data));
-}
-
-
 inline
 PackageData::PackageData(const PackageDataV2& data)
        :
@@ -64,13 +47,6 @@ PackageData::PackageData(const PackageDataV2& data)
 }
 
 
-inline const PackageDataV1&
-PackageData::DataV1() const
-{
-       return *(PackageDataV1*)&fData;
-}
-
-
 inline const PackageDataV2&
 PackageData::DataV2() const
 {
@@ -78,20 +54,9 @@ PackageData::DataV2() const
 }
 
 
-inline uint64
-PackageData::CompressedSize() const
-{
-       if (fVersion == 1)
-               return DataV1().CompressedSize();
-       return DataV2().Size();
-}
-
-
 inline uint64
 PackageData::UncompressedSize() const
 {
-       if (fVersion == 1)
-               return DataV1().UncompressedSize();
        return DataV2().Size();
 }
 
@@ -99,8 +64,6 @@ PackageData::UncompressedSize() const
 inline bool
 PackageData::IsEncodedInline() const
 {
-       if (fVersion == 1)
-               return DataV1().IsEncodedInline();
        return DataV2().IsEncodedInline();
 }
 
@@ -108,8 +71,6 @@ PackageData::IsEncodedInline() const
 inline const uint8*
 PackageData::InlineData() const
 {
-       if (fVersion == 1)
-               return DataV1().InlineData();
        return DataV2().InlineData();
 }
 

############################################################################

Commit:      d230b5fdd3722564c2ddd7186d60749932324006
URL:         https://git.haiku-os.org/haiku/commit/?id=d230b5fdd372
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Tue Jul  9 04:54:53 2019 UTC

packagefs: Use object caches for the most used node classes.

Slab statistics from KDL show that on a stock nightly image
(i.e. no additional packages besides the standards installed)
there are 43848 *objects* (not bytes) in the PackageNodeAttribute
cache, and 25090 in the PackageFile cache, so this seems more than
worth it.

The last commit seems to reduce memory usage at boot by about 1%,
this commit seems to not affect it at all; but it is a significant
performance optimization and on systems with more packages installed
the effect may be very noticeable.

Change-Id: I676a642ed6003f82b14396e1f02684575d899362

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp 
b/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp
index a5ffa4783b..bcb34e18a6 100644
--- a/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp
+++ b/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp
@@ -140,7 +140,7 @@ struct Package::LoaderContentHandler : 
BPackageContentHandler {
                PackageNode* node;
                if (S_ISREG(mode)) {
                        // file
-                       node = new(std::nothrow) PackageFile(fPackage, mode,
+                       node = new PackageFile(fPackage, mode,
                                PackageData(entry->Data()));
                } else if (S_ISLNK(mode)) {
                        // symlink
@@ -157,7 +157,7 @@ struct Package::LoaderContentHandler : 
BPackageContentHandler {
                        node = symlink;
                } else if (S_ISDIR(mode)) {
                        // directory
-                       node = new(std::nothrow) PackageDirectory(fPackage, 
mode);
+                       node = new PackageDirectory(fPackage, mode);
                } else
                        RETURN_ERROR(B_BAD_DATA);
 
@@ -201,7 +201,7 @@ struct Package::LoaderContentHandler : 
BPackageContentHandler {
                if (!name.SetTo(attribute->Name()))
                        RETURN_ERROR(B_NO_MEMORY);
 
-               PackageNodeAttribute* nodeAttribute = new(std::nothrow)
+               PackageNodeAttribute* nodeAttribute = new
                        PackageNodeAttribute(attribute->Type(),
                        PackageData(attribute->Data()));
                if (nodeAttribute == NULL)
diff --git 
a/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.cpp 
b/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.cpp
index 916c42decd..9a51d9f7f3 100644
--- a/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.cpp
+++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.cpp
@@ -7,6 +7,11 @@
 #include "PackageDirectory.h"
 #include "Package.h"
 
+#include "ClassCache.h"
+
+
+CLASS_CACHE(PackageDirectory);
+
 
 PackageDirectory::PackageDirectory(Package* package, mode_t mode)
        :
diff --git 
a/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.h 
b/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.h
index d851ae3ded..70f2d49f24 100644
--- a/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.h
+++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageDirectory.h
@@ -14,6 +14,9 @@
 class PackageDirectory : public PackageNode,
        public DoublyLinkedListLinkImpl<PackageDirectory> {
 public:
+       static  void*                           operator new(size_t size);
+       static  void                            operator delete(void* block);
+
                                                                
PackageDirectory(Package* package, mode_t mode);
        virtual                                         ~PackageDirectory();
 
diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.cpp 
b/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.cpp
index dce9c7613c..477c955445 100644
--- a/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.cpp
+++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.cpp
@@ -19,12 +19,19 @@
 #include <util/AutoLock.h>
 
 #include "DebugSupport.h"
+#include "ClassCache.h"
 #include "Package.h"
 
 
 using namespace BPackageKit::BHPKG;
 
 
+// #pragma mark - class cache
+
+
+CLASS_CACHE(PackageFile);
+
+
 // #pragma mark - DataAccessor
 
 
diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.h 
b/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.h
index a59fc2d396..aea4a0b7a6 100644
--- a/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.h
+++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageFile.h
@@ -12,6 +12,9 @@
 
 class PackageFile : public PackageLeafNode {
 public:
+       static  void*                           operator new(size_t size);
+       static  void                            operator delete(void* block);
+
                                                                
PackageFile(Package* package, mode_t mode,
                                                                        const 
PackageData& data);
        virtual                                         ~PackageFile();
diff --git 
a/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.cpp 
b/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.cpp
index 713d85a6c1..d7caa92ed4 100644
--- a/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.cpp
+++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.cpp
@@ -9,6 +9,11 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "ClassCache.h"
+
+
+CLASS_CACHE(PackageNodeAttribute);
+
 
 PackageNodeAttribute::PackageNodeAttribute(uint32 type,
        const PackageData& data)
diff --git 
a/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.h 
b/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.h
index af01f85652..6404eb53c7 100644
--- a/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.h
+++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.h
@@ -19,6 +19,9 @@ class PackageNode;
 class PackageNodeAttribute
        : public DoublyLinkedListLinkImpl<PackageNodeAttribute> {
 public:
+       static  void*                           operator new(size_t size);
+       static  void                            operator delete(void* block);
+
                                                                
PackageNodeAttribute(uint32 type,
                                                                        const 
PackageData& data);
                                                                
~PackageNodeAttribute();
diff --git a/src/add-ons/kernel/file_systems/packagefs/util/ClassCache.h 
b/src/add-ons/kernel/file_systems/packagefs/util/ClassCache.h
new file mode 100644
index 0000000000..e8cad806b5
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/packagefs/util/ClassCache.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2019, Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef CLASSCACHE_H
+#define CLASSCACHE_H
+
+
+#include <slab/Slab.h>
+
+
+#define CLASS_CACHE(CLASS) \
+       static object_cache* s##CLASS##Cache = NULL; \
+       \
+       void* \
+       CLASS::operator new(size_t size) \
+       { \
+               if (size != sizeof(CLASS)) \
+                       panic("unexpected size passed to operator new!"); \
+               if (s##CLASS##Cache == NULL) { \
+                       s##CLASS##Cache = create_object_cache("packagefs " 
#CLASS "s", \
+                               sizeof(CLASS), 8, NULL, NULL, NULL); \
+               } \
+       \
+               return object_cache_alloc(s##CLASS##Cache, 0); \
+       } \
+       \
+       void \
+       CLASS::operator delete(void* block) \
+       { \
+               object_cache_free(s##CLASS##Cache, block, 0); \
+       }
+
+
+#endif // CLASSCACHE_H

############################################################################

Commit:      86e43bdf5833c57f60ef0a6bc18427bc1a0eaaac
URL:         https://git.haiku-os.org/haiku/commit/?id=86e43bdf5833
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Wed Jul 10 02:43:25 2019 UTC

kernel: Add missing error checks to MemoryManager::_AllocateChunks.

----------------------------------------------------------------------------

diff --git a/src/system/kernel/slab/MemoryManager.cpp 
b/src/system/kernel/slab/MemoryManager.cpp
index 1dab8fb807..2e633937cd 100644
--- a/src/system/kernel/slab/MemoryManager.cpp
+++ b/src/system/kernel/slab/MemoryManager.cpp
@@ -956,8 +956,8 @@ MemoryManager::_AllocateChunks(size_t chunkSize, uint32 
chunkCount,
                _AddArea(_PopFreeArea());
                _RequestMaintenance();
 
-               _GetChunks(metaChunkList, chunkSize, chunkCount, _metaChunk, 
_chunk);
-               return B_OK;
+               return _GetChunks(metaChunkList, chunkSize, chunkCount, 
_metaChunk,
+                       _chunk) ? B_OK : B_NO_MEMORY;
        }
 
        if ((flags & CACHE_DONT_LOCK_KERNEL_SPACE) != 0) {
@@ -1018,8 +1018,8 @@ MemoryManager::_AllocateChunks(size_t chunkSize, uint32 
chunkCount,
        }
 
        _AddArea(area);
-       _GetChunks(metaChunkList, chunkSize, chunkCount, _metaChunk, _chunk);
-       return B_OK;
+       return _GetChunks(metaChunkList, chunkSize, chunkCount, _metaChunk,
+               _chunk) ? B_OK : B_NO_MEMORY;
 }
 
 

############################################################################

Revision:    hrev53238
Commit:      d387d8c5f47bf53be29d1fa8602dc0d267c4bf32
URL:         https://git.haiku-os.org/haiku/commit/?id=d387d8c5f47b
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Wed Jul 10 04:33:55 2019 UTC

packagefs: Use an object_cache in the TwoKeyAVLTree also.

TwoKeyAVLTree in packagefs is used for indexing. On a stock nightly,
just after boot there are 3 TwoKeyAVLTrees with just over 28000 items
each. So, this is another significant load off the generic allocator.

----------------------------------------------------------------------------

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 4579fdc014..a2671178b6 100644
--- a/src/add-ons/kernel/file_systems/packagefs/util/TwoKeyAVLTree.h
+++ b/src/add-ons/kernel/file_systems/packagefs/util/TwoKeyAVLTree.h
@@ -6,6 +6,7 @@
 #define TWO_KEY_AVL_TREE_H
 
 
+#include <slab/Slab.h>
 #include <util/AVLTreeMap.h>
 
 
@@ -155,9 +156,37 @@ 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(),
@@ -170,12 +199,17 @@ public:
 
        inline Node* Allocate(const Key& key, const Value& value) const
        {
-               return new(nothrow) Node(value);
+               return new(fObjectCache) Node(value);
        }
 
        inline void Free(Node* node) const
        {
-               delete node;
+               if (node == NULL)
+                       return;
+
+               // There is no way to overload operator delete with extra 
parameters.
+               node->~Node();
+               object_cache_free(fObjectCache, node, 0);
        }
 
        // internal use (not part of the strategy)
@@ -228,6 +262,9 @@ private:
        SecondaryKeyCompare     fSecondaryKeyCompare;
        GetPrimaryKey           fGetPrimaryKey;
        GetSecondaryKey         fGetSecondaryKey;
+
+       object_cache*           fObjectCache;
+       int32*                          fObjectCacheRefs;
 };
 
 


Other related posts:

  • » [haiku-commits] haiku: hrev53238 - in src: add-ons/kernel/file_systems/packagefs/util add-ons/kernel/file_systems/packagefs/package system/kernel/slab - waddlesplash