Author: bonefish Date: 2010-01-25 16:33:25 +0100 (Mon, 25 Jan 2010) New Revision: 35285 Changeset: http://dev.haiku-os.org/changeset/35285/haiku Modified: haiku/trunk/src/system/kernel/slab/HashedObjectCache.cpp haiku/trunk/src/system/kernel/slab/HashedObjectCache.h haiku/trunk/src/system/kernel/slab/ObjectCache.cpp haiku/trunk/src/system/kernel/slab/ObjectCache.h haiku/trunk/src/system/kernel/slab/SmallObjectCache.cpp Log: * 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(). Modified: haiku/trunk/src/system/kernel/slab/HashedObjectCache.cpp =================================================================== --- haiku/trunk/src/system/kernel/slab/HashedObjectCache.cpp 2010-01-25 13:53:26 UTC (rev 35284) +++ haiku/trunk/src/system/kernel/slab/HashedObjectCache.cpp 2010-01-25 15:33:25 UTC (rev 35285) @@ -25,15 +25,15 @@ } -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 @@ 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 @@ 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 @@ 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,55 +147,16 @@ 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; + return slab; } -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); -} - - -void HashedObjectCache::_ResizeHashTableIfNeeded(uint32 flags) { size_t hashSize = hash_table.ResizeNeeded(); @@ -208,18 +178,3 @@ } } } - - -/*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); -} Modified: haiku/trunk/src/system/kernel/slab/HashedObjectCache.h =================================================================== --- haiku/trunk/src/system/kernel/slab/HashedObjectCache.h 2010-01-25 13:53:26 UTC (rev 35284) +++ haiku/trunk/src/system/kernel/slab/HashedObjectCache.h 2010-01-25 15:33:25 UTC (rev 35285) @@ -14,6 +14,11 @@ #include "slab_private.h" +struct HashedSlab : slab { + HashedSlab* hash_next; +}; + + struct HashedObjectCache : ObjectCache { HashedObjectCache(); @@ -29,22 +34,11 @@ 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 @@ 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: 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; Modified: haiku/trunk/src/system/kernel/slab/ObjectCache.cpp =================================================================== --- haiku/trunk/src/system/kernel/slab/ObjectCache.cpp 2010-01-25 13:53:26 UTC (rev 35284) +++ haiku/trunk/src/system/kernel/slab/ObjectCache.cpp 2010-01-25 15:33:25 UTC (rev 35285) @@ -133,23 +133,15 @@ 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,26 +183,12 @@ 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) { if (source == NULL) { Modified: haiku/trunk/src/system/kernel/slab/ObjectCache.h =================================================================== --- haiku/trunk/src/system/kernel/slab/ObjectCache.h 2010-01-25 13:53:26 UTC (rev 35284) +++ haiku/trunk/src/system/kernel/slab/ObjectCache.h 2010-01-25 15:33:25 UTC (rev 35285) @@ -94,11 +94,6 @@ 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 @@ } -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)); + return (void*)((addr_t)object & ~(byteCount - 1)); } -static inline const void * -lower_boundary(void *object, size_t byteCount) -{ - const uint8 *null = (uint8 *)NULL; - return null + ((((uint8 *)object) - null) & ~(byteCount - 1)); -} - - static inline bool -check_cache_quota(ObjectCache *cache) +check_cache_quota(ObjectCache* cache) { if (cache->maximum == 0) return true; Modified: haiku/trunk/src/system/kernel/slab/SmallObjectCache.cpp =================================================================== --- haiku/trunk/src/system/kernel/slab/SmallObjectCache.cpp 2010-01-25 13:53:26 UTC (rev 35284) +++ haiku/trunk/src/system/kernel/slab/SmallObjectCache.cpp 2010-01-25 15:33:25 UTC (rev 35285) @@ -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 @@ 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 @@ SmallObjectCache::ReturnSlab(slab* slab, uint32 flags) { UninitSlab(slab); + + Unlock(); MemoryManager::Free(slab->pages, flags); + Lock(); }