Skip to content
Permalink
Browse files

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
  • Loading branch information...
waddlesplash committed Jul 9, 2019
1 parent 71e255c commit d230b5fdd3722564c2ddd7186d60749932324006
@@ -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)
@@ -7,6 +7,11 @@
#include "PackageDirectory.h"
#include "Package.h"

#include "ClassCache.h"


CLASS_CACHE(PackageDirectory);


PackageDirectory::PackageDirectory(Package* package, mode_t mode)
:
@@ -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();

@@ -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


@@ -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();
@@ -9,6 +9,11 @@
#include <stdlib.h>
#include <string.h>

#include "ClassCache.h"


CLASS_CACHE(PackageNodeAttribute);


PackageNodeAttribute::PackageNodeAttribute(uint32 type,
const PackageData& data)
@@ -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();
@@ -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

0 comments on commit d230b5f

Please sign in to comment.
You can’t perform that action at this time.