From 4171bc72bce5ea14a907bfbd0c880b080c2ba7e3 Mon Sep 17 00:00:00 2001 From: Hugo Santos Date: Wed, 25 Apr 2007 19:54:18 +0000 Subject: [PATCH] test_slab: moved the Backend independent HashCacheStrategy operations to BaseHashCacheStrategy so we don't end up with multiple instantiations of the same code. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20826 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/system/kernel/slab/Slab.h | 120 ++++++++++++++++++---------- 1 file changed, 77 insertions(+), 43 deletions(-) diff --git a/src/tests/system/kernel/slab/Slab.h b/src/tests/system/kernel/slab/Slab.h index d67e23fcf0..1b14d54cb2 100644 --- a/src/tests/system/kernel/slab/Slab.h +++ b/src/tests/system/kernel/slab/Slab.h @@ -312,24 +312,21 @@ Fls(size_t value) } -template -struct HashCacheStrategy : BaseCacheStrategy { - typedef typename BaseCacheStrategy::Slab Slab; - typedef HashCacheStrategy Strategy; +struct BaseHashCacheStrategy { typedef BaseCache::ObjectLink ObjectLink; typedef BaseCache::ObjectInfo ObjectInfo; struct Link : ObjectLink, HashTableLink { - Slab *slab; + BaseCache::Slab *slab; void *buffer; }; struct HashTableDefinition { - typedef Strategy ParentType; - typedef void * KeyType; - typedef Link ValueType; + typedef BaseHashCacheStrategy ParentType; + typedef void * KeyType; + typedef Link ValueType; - HashTableDefinition(Strategy *_parent) : parent(_parent) {} + HashTableDefinition(BaseHashCacheStrategy *_parent) : parent(_parent) {} size_t HashKey(void *key) const { @@ -345,7 +342,7 @@ struct HashCacheStrategy : BaseCacheStrategy { HashTableLink *GetLink(Link *value) const { return value; } - Strategy *parent; + BaseHashCacheStrategy *parent; }; // for g++ 2.95 @@ -353,15 +350,8 @@ struct HashCacheStrategy : BaseCacheStrategy { typedef OpenHashTable HashTable; - HashCacheStrategy(BaseCache *parent) - : BaseCacheStrategy(parent), fHashTable(this), - fSlabCache("slab cache", 0), fLinkCache("link cache", 0), - fLowerBoundary(Fls(parent->ObjectSize()) - 1) {} - - static size_t RequiredSpace(size_t objectSize) - { - return objectSize; - } + BaseHashCacheStrategy(BaseCache *parent) + : fHashTable(this), fLowerBoundary(Fls(parent->ObjectSize()) - 1) {} void *Object(ObjectLink *link) const { @@ -374,6 +364,36 @@ struct HashCacheStrategy : BaseCacheStrategy { return ObjectInfo(link->slab, link); } +protected: + Link *_Linkage(void *object) const + { + return fHashTable.Lookup(object); + } + + static ObjectLink *_Linkage(void *_this, void *object) + { + return ((BaseHashCacheStrategy *)_this)->_Linkage(object); + } + + HashTable fHashTable; + const size_t fLowerBoundary; +}; + + +template +struct HashCacheStrategy : BaseCacheStrategy, BaseHashCacheStrategy { + typedef typename BaseCacheStrategy::Slab Slab; + typedef HashCacheStrategy Strategy; + + HashCacheStrategy(BaseCache *parent) + : BaseCacheStrategy(parent), BaseHashCacheStrategy(parent), + fSlabCache("slab cache", 0), fLinkCache("link cache", 0) {} + + static size_t RequiredSpace(size_t objectSize) + { + return objectSize; + } + BaseCache::Slab *NewSlab(uint32_t flags) { size_t byteCount = _SlabSize(); @@ -389,31 +409,21 @@ struct HashCacheStrategy : BaseCacheStrategy { return NULL; } - uint8_t *data = (uint8_t *)pages; - for (uint8_t *it = data; - it < (data + byteCount); it += fParent->ObjectSize()) { - Link *link = fLinkCache.Alloc(flags); - link->slab = slab; - link->buffer = it; - fHashTable.Insert(link); + if (_PrepareSlab(fParent, slab, pages, byteCount, flags) < B_OK) { + Backend::FreePages(fParent, slab->id); + fSlabCache.Free(slab); + return NULL; } + // it's very important that we cast this to BaseHashCacheStrategy + // so we get the proper instance offset through void * return BaseCacheStrategy::_ConstructSlab(slab, pages, 0, - _Linkage, this); + _Linkage, (BaseHashCacheStrategy *)this); } void ReturnSlab(BaseCache::Slab *slab) { - uint8_t *data = (uint8_t *)slab->pages; - size_t byteCount = _SlabSize(); - - for (uint8_t *it = data; - it < (data + byteCount); it += fParent->ObjectSize()) { - Link *link = fHashTable.Lookup(it); - fHashTable.Remove(link); - fLinkCache.Free(link); - } - + _ClearSlab(fParent, slab->pages, _SlabSize()); BaseCacheStrategy::_DestructSlab(slab); fSlabCache.Free((Slab *)slab); } @@ -424,20 +434,44 @@ private: return BaseCacheStrategy::SlabSize(0); } - Link *_Linkage(void *object) const + status_t _PrepareSlab(BaseCache *parent, Slab *slab, void *pages, + size_t byteCount, uint32_t flags) { - return fHashTable.Lookup(object); + uint8_t *data = (uint8_t *)pages; + for (uint8_t *it = data; + it < (data + byteCount); it += parent->ObjectSize()) { + Link *link = fLinkCache.Alloc(flags); + + if (link == NULL) { + _ClearSlabRange(parent, data, it); + return B_NO_MEMORY; + } + + link->slab = slab; + link->buffer = it; + fHashTable.Insert(link); + } + + return B_OK; } - static ObjectLink *_Linkage(void *_this, void *object) + void _ClearSlab(BaseCache *parent, void *pages, size_t byteCount) { - return ((Strategy *)_this)->_Linkage(object); + _ClearSlabRange(parent, (uint8_t *)pages, + ((uint8_t *)pages) + byteCount); + } + + void _ClearSlabRange(BaseCache *parent, uint8_t *data, uint8_t *end) + { + for (uint8_t *it = data; it < end; it += parent->ObjectSize()) { + Link *link = fHashTable.Lookup(it); + fHashTable.Remove(link); + fLinkCache.Free(link); + } } - HashTable fHashTable; TypedCache fSlabCache; TypedCache fLinkCache; - const size_t fLowerBoundary; };