diff --git a/src/system/kernel/slab/HashedObjectCache.cpp b/src/system/kernel/slab/HashedObjectCache.cpp index eb50df4f3d..cab4472972 100644 --- a/src/system/kernel/slab/HashedObjectCache.cpp +++ b/src/system/kernel/slab/HashedObjectCache.cpp @@ -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(_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); -} diff --git a/src/system/kernel/slab/HashedObjectCache.h b/src/system/kernel/slab/HashedObjectCache.h index cba0630e00..00c0acbdc6 100644 --- a/src/system/kernel/slab/HashedObjectCache.h +++ b/src/system/kernel/slab/HashedObjectCache.h @@ -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; diff --git a/src/system/kernel/slab/ObjectCache.cpp b/src/system/kernel/slab/ObjectCache.cpp index 668f30fdcd..88ce1f51e4 100644 --- a/src/system/kernel/slab/ObjectCache.cpp +++ b/src/system/kernel/slab/ObjectCache.cpp @@ -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) { diff --git a/src/system/kernel/slab/ObjectCache.h b/src/system/kernel/slab/ObjectCache.h index 9baa64c192..febc36b865 100644 --- a/src/system/kernel/slab/ObjectCache.h +++ b/src/system/kernel/slab/ObjectCache.h @@ -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; diff --git a/src/system/kernel/slab/SmallObjectCache.cpp b/src/system/kernel/slab/SmallObjectCache.cpp index c69112eb5b..62c0dbc661 100644 --- a/src/system/kernel/slab/SmallObjectCache.cpp +++ b/src/system/kernel/slab/SmallObjectCache.cpp @@ -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(); }