* HashedObjectCache: Instead of entering the individual objects in the hash

table, we only enter the slab. This also saves us the link object per object.
* Removed the now useless {Prepare,Unprepare}Object() methods.
* SmallObjectCache: Unlock the cache while calling into the MemoryManager. We
  need to do that to avoid an indirect violation of the CACHE_DONT_* policy.
* Simplified lower_boundary().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35285 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2010-01-25 15:33:25 +00:00
parent 5993482bf5
commit f1bdb8b92c
5 changed files with 55 additions and 131 deletions
+20 -65
View File
@@ -25,15 +25,15 @@ __fls0(size_t value)
}
static slab*
static HashedSlab*
allocate_slab(uint32 flags)
{
return (slab*)slab_internal_alloc(sizeof(slab), flags);
return (HashedSlab*)slab_internal_alloc(sizeof(HashedSlab), flags);
}
static void
free_slab(slab* slab, uint32 flags)
free_slab(HashedSlab* slab, uint32 flags)
{
slab_internal_free(slab, flags);
}
@@ -83,7 +83,7 @@ HashedObjectCache::Create(const char* name, size_t object_size,
cache->slab_size = 8 * object_size;
cache->slab_size = MemoryManager::AcceptableChunkSize(cache->slab_size);
cache->lower_boundary = __fls0(cache->object_size);
cache->lower_boundary = __fls0(cache->slab_size);
return cache;
}
@@ -105,13 +105,16 @@ HashedObjectCache::CreateSlab(uint32 flags)
Unlock();
slab* slab = allocate_slab(flags);
HashedSlab* slab = allocate_slab(flags);
if (slab != NULL) {
void* pages;
if (MemoryManager::Allocate(this, flags, pages) == B_OK) {
Lock();
if (InitSlab(slab, pages, slab_size, flags))
if (InitSlab(slab, pages, slab_size, flags)) {
hash_table.InsertUnchecked(slab);
_ResizeHashTableIfNeeded(flags);
return slab;
}
Unlock();
MemoryManager::Free(pages, flags);
}
@@ -125,9 +128,15 @@ HashedObjectCache::CreateSlab(uint32 flags)
void
HashedObjectCache::ReturnSlab(slab* slab, uint32 flags)
HashedObjectCache::ReturnSlab(slab* _slab, uint32 flags)
{
HashedSlab* slab = static_cast<HashedSlab*>(_slab);
hash_table.RemoveUnchecked(slab);
_ResizeHashTableIfNeeded(flags);
UninitSlab(slab);
Unlock();
MemoryManager::Free(slab->pages, flags);
free_slab(slab, flags);
@@ -138,51 +147,12 @@ HashedObjectCache::ReturnSlab(slab* slab, uint32 flags)
slab*
HashedObjectCache::ObjectSlab(void* object) const
{
Link* link = hash_table.Lookup(object);
if (link == NULL) {
panic("object cache: requested object %p missing from hash table",
object);
HashedSlab* slab = hash_table.Lookup(::lower_boundary(object, slab_size));
if (slab == NULL) {
panic("hash object cache %p: unknown object %p", this, object);
return NULL;
}
return link->parent;
}
status_t
HashedObjectCache::PrepareObject(slab* source, void* object, uint32 flags)
{
Link* link = _AllocateLink(flags);
if (link == NULL)
return B_NO_MEMORY;
link->buffer = object;
link->parent = source;
hash_table.InsertUnchecked(link);
_ResizeHashTableIfNeeded(flags);
return B_OK;
}
void
HashedObjectCache::UnprepareObject(slab* source, void* object, uint32 flags)
{
Link* link = hash_table.Lookup(object);
if (link == NULL) {
panic("object cache: requested object missing from hash table");
return;
}
if (link->parent != source) {
panic("object cache: slab mismatch");
return;
}
hash_table.RemoveUnchecked(link);
_ResizeHashTableIfNeeded(flags);
_FreeLink(link, flags);
return slab;
}
@@ -208,18 +178,3 @@ HashedObjectCache::_ResizeHashTableIfNeeded(uint32 flags)
}
}
}
/*static*/ inline HashedObjectCache::Link*
HashedObjectCache::_AllocateLink(uint32 flags)
{
return (HashedObjectCache::Link*)
slab_internal_alloc(sizeof(HashedObjectCache::Link), flags);
}
/*static*/ inline void
HashedObjectCache::_FreeLink(HashedObjectCache::Link* link, uint32 flags)
{
slab_internal_free(link, flags);
}
+13 -23
View File
@@ -14,6 +14,11 @@
#include "slab_private.h"
struct HashedSlab : slab {
HashedSlab* hash_next;
};
struct HashedObjectCache : ObjectCache {
HashedObjectCache();
@@ -29,22 +34,11 @@ struct HashedObjectCache : ObjectCache {
virtual void ReturnSlab(slab* slab, uint32 flags);
virtual slab* ObjectSlab(void* object) const;
virtual status_t PrepareObject(slab* source, void* object,
uint32 flags);
virtual void UnprepareObject(slab* source, void* object,
uint32 flags);
private:
struct Link {
const void* buffer;
slab* parent;
Link* next;
};
struct Definition {
typedef HashedObjectCache ParentType;
typedef const void* KeyType;
typedef Link ValueType;
typedef HashedSlab ValueType;
Definition(HashedObjectCache* parent)
:
@@ -60,23 +54,23 @@ private:
size_t HashKey(const void* key) const
{
return (((const uint8*)key) - ((const uint8*)0))
return (addr_t)::lower_boundary(key, parent->slab_size)
>> parent->lower_boundary;
}
size_t Hash(Link* value) const
size_t Hash(HashedSlab* value) const
{
return HashKey(value->buffer);
return HashKey(value->pages);
}
bool Compare(const void* key, Link* value) const
bool Compare(const void* key, HashedSlab* value) const
{
return value->buffer == key;
return value->pages == key;
}
Link*& GetLink(Link* value) const
HashedSlab*& GetLink(HashedSlab* value) const
{
return value->next;
return value->hash_next;
}
HashedObjectCache* parent;
@@ -102,10 +96,6 @@ private:
private:
void _ResizeHashTableIfNeeded(uint32 flags);
static Link* _AllocateLink(uint32 flags);
static void _FreeLink(HashedObjectCache::Link* link,
uint32 flags);
private:
HashTable hash_table;
size_t lower_boundary;
+3 -25
View File
@@ -133,23 +133,15 @@ ObjectCache::InitSlab(slab* slab, void* pages, size_t byteCount, uint32 flags)
CREATE_PARANOIA_CHECK_SET(slab, "slab");
for (size_t i = 0; i < slab->size; i++) {
bool failedOnFirst = false;
status_t status = PrepareObject(slab, data, flags);
if (status < B_OK)
failedOnFirst = true;
else if (constructor)
status_t status = B_OK;
if (constructor)
status = constructor(cookie, data);
if (status < B_OK) {
if (!failedOnFirst)
UnprepareObject(slab, data, flags);
if (status != B_OK) {
data = ((uint8*)pages) + slab->offset;
for (size_t j = 0; j < i; j++) {
if (destructor)
destructor(cookie, data);
UnprepareObject(slab, data, flags);
data += object_size;
}
@@ -191,25 +183,11 @@ ObjectCache::UninitSlab(slab* slab)
for (size_t i = 0; i < slab->size; i++) {
if (destructor)
destructor(cookie, data);
UnprepareObject(slab, data, flags);
data += object_size;
}
}
status_t
ObjectCache::PrepareObject(slab* source, void* object, uint32 flags)
{
return B_OK;
}
void
ObjectCache::UnprepareObject(slab* source, void* object, uint32 flags)
{
}
void
ObjectCache::ReturnObjectToSlab(slab* source, void* object, uint32 flags)
{
+4 -17
View File
@@ -94,11 +94,6 @@ public:
size_t byteCount, uint32 flags);
void UninitSlab(slab* slab);
virtual status_t PrepareObject(slab* source, void* object,
uint32 flags);
virtual void UnprepareObject(slab* source, void* object,
uint32 flags);
void ReturnObjectToSlab(slab* source, void* object,
uint32 flags);
@@ -127,23 +122,15 @@ object_to_link(void* object, size_t objectSize)
}
static inline slab *
slab_in_pages(const void *pages, size_t slab_size)
static inline void*
lower_boundary(const void* object, size_t byteCount)
{
return (slab *)(((uint8 *)pages) + slab_size - sizeof(slab));
}
static inline const void *
lower_boundary(void *object, size_t byteCount)
{
const uint8 *null = (uint8 *)NULL;
return null + ((((uint8 *)object) - null) & ~(byteCount - 1));
return (void*)((addr_t)object & ~(byteCount - 1));
}
static inline bool
check_cache_quota(ObjectCache *cache)
check_cache_quota(ObjectCache* cache)
{
if (cache->maximum == 0)
return true;
+15 -1
View File
@@ -12,6 +12,13 @@
#include "slab_private.h"
static inline slab *
slab_in_pages(const void *pages, size_t slab_size)
{
return (slab *)(((uint8 *)pages) + slab_size - sizeof(slab));
}
/*static*/ SmallObjectCache*
SmallObjectCache::Create(const char* name, size_t object_size,
size_t alignment, size_t maximum, uint32 flags, void* cookie,
@@ -57,7 +64,11 @@ SmallObjectCache::CreateSlab(uint32 flags)
void* pages;
if (MemoryManager::Allocate(this, flags, pages) != B_OK)
Unlock();
status_t error = MemoryManager::Allocate(this, flags, pages);
Lock();
if (error != B_OK)
return NULL;
return InitSlab(slab_in_pages(pages, slab_size), pages,
@@ -69,7 +80,10 @@ void
SmallObjectCache::ReturnSlab(slab* slab, uint32 flags)
{
UninitSlab(slab);
Unlock();
MemoryManager::Free(slab->pages, flags);
Lock();
}