From 39af44596634e640b76b9cef47acb1f93e6bf514 Mon Sep 17 00:00:00 2001 From: Hugo Santos Date: Sun, 29 Apr 2007 21:45:23 +0000 Subject: [PATCH] added object_cache_reserve to allow cache users to pre-allocate slabs. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20912 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/slab/Base.h | 3 +++ src/system/kernel/slab/Slab.cpp | 42 ++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/headers/private/kernel/slab/Base.h b/headers/private/kernel/slab/Base.h index 06e5d037ef..69edca16e8 100644 --- a/headers/private/kernel/slab/Base.h +++ b/headers/private/kernel/slab/Base.h @@ -46,6 +46,9 @@ void delete_object_cache(object_cache *cache); void *object_cache_alloc(object_cache *cache, uint32 flags); void object_cache_free(object_cache *cache, void *object); +status_t object_cache_reserve(object_cache *cache, size_t object_count, + uint32 flags); + #ifdef __cplusplus } #endif diff --git a/src/system/kernel/slab/Slab.cpp b/src/system/kernel/slab/Slab.cpp index 8e171c2638..674a3eb77b 100644 --- a/src/system/kernel/slab/Slab.cpp +++ b/src/system/kernel/slab/Slab.cpp @@ -158,6 +158,8 @@ static benaphore sObjectCacheListLock; static uint8 *sInitialBegin, *sInitialLimit, *sInitialPointer; +static status_t object_cache_reserve_internal(object_cache *cache, + size_t object_count, uint32 flags); static status_t object_depot_init_locks(object_depot *depot); static depot_magazine *alloc_magazine(); static void free_magazine(depot_magazine *magazine); @@ -558,16 +560,14 @@ object_cache_alloc(object_cache *cache, uint32 flags) if (cache->partial.IsEmpty()) { if (cache->empty.IsEmpty()) { - source = cache->CreateSlab(flags); - if (source == NULL) + if (object_cache_reserve_internal(cache, 1, flags) < B_OK) return NULL; cache->pressure++; - } else { - source = cache->empty.RemoveHead(); - cache->empty_count--; } + source = cache->empty.RemoveHead(); + cache->empty_count--; cache->partial.Add(source); } else { source = cache->partial.Head(); @@ -635,6 +635,38 @@ object_cache_free(object_cache *cache, void *object) } +static status_t +object_cache_reserve_internal(object_cache *cache, size_t object_count, + uint32 flags) +{ + size_t numBytes = object_count * cache->object_size; + size_t slabCount = ((numBytes - 1) / cache->slab_size) + 1; + + while (slabCount > 0) { + slab *newSlab = cache->CreateSlab(flags); + if (newSlab == NULL) + return B_NO_MEMORY; + + cache->empty.Add(newSlab); + cache->empty_count++; + slabCount--; + } + + return B_OK; +} + + +status_t +object_cache_reserve(object_cache *cache, size_t object_count, uint32 flags) +{ + if (object_count == 0) + return B_OK; + + BenaphoreLocker _(cache->lock); + return object_cache_reserve_internal(cache, object_count, flags); +} + + slab * object_cache::InitSlab(slab *slab, void *pages, size_t byteCount) {