diff --git a/src/system/kernel/slab/ObjectCache.cpp b/src/system/kernel/slab/ObjectCache.cpp index f42531f330..7a3bb3b258 100644 --- a/src/system/kernel/slab/ObjectCache.cpp +++ b/src/system/kernel/slab/ObjectCache.cpp @@ -17,9 +17,6 @@ #include "slab_private.h" -static const size_t kCacheColorPeriod = 8; - - static void object_cache_return_object_wrapper(object_depot* depot, void* cookie, void* object, uint32 flags) @@ -52,6 +49,9 @@ ObjectCache::Init(const char* name, size_t objectSize, size_t alignment, if (objectSize < sizeof(object_link)) objectSize = sizeof(object_link); + if (alignment < kMinObjectAlignment) + alignment = kMinObjectAlignment; + if (alignment > 0 && (objectSize & (alignment - 1))) object_size = objectSize + alignment - (objectSize & (alignment - 1)); else @@ -60,6 +60,7 @@ ObjectCache::Init(const char* name, size_t objectSize, size_t alignment, TRACE_CACHE(this, "init %lu, %lu -> %lu", objectSize, alignment, object_size); + this->alignment = alignment; cache_color_cycle = 0; total_objects = 0; used_count = 0; @@ -123,15 +124,11 @@ ObjectCache::InitSlab(slab* slab, void* pages, size_t byteCount, uint32 flags) size_t spareBytes = byteCount - (slab->size * object_size); - if ((this->flags & CACHE_ALIGN_ON_SIZE) != 0) { - slab->offset = cache_color_cycle; + slab->offset = cache_color_cycle; - if (slab->offset > spareBytes) - cache_color_cycle = slab->offset = 0; - else - cache_color_cycle += kCacheColorPeriod; - } else - slab->offset = 0; + cache_color_cycle += alignment; + if (cache_color_cycle > spareBytes) + cache_color_cycle = 0; TRACE_CACHE(this, " %lu objects, %lu spare bytes, offset %lu", slab->size, spareBytes, slab->offset); diff --git a/src/system/kernel/slab/ObjectCache.h b/src/system/kernel/slab/ObjectCache.h index 3ee13cbe26..f2d36b5caf 100644 --- a/src/system/kernel/slab/ObjectCache.h +++ b/src/system/kernel/slab/ObjectCache.h @@ -41,6 +41,7 @@ struct ObjectCache : DoublyLinkedListLinkImpl { char name[32]; mutex lock; size_t object_size; + size_t alignment; size_t cache_color_cycle; SlabList empty; SlabList partial; diff --git a/src/system/kernel/slab/Slab.cpp b/src/system/kernel/slab/Slab.cpp index f8b190bd20..6cb1a40ea4 100644 --- a/src/system/kernel/slab/Slab.cpp +++ b/src/system/kernel/slab/Slab.cpp @@ -208,17 +208,18 @@ dump_slab(::slab* slab) static int dump_slabs(int argc, char* argv[]) { - kprintf("%10s %22s %8s %8s %6s %8s %8s %8s\n", "address", "name", - "objsize", "usage", "empty", "usedobj", "total", "flags"); + kprintf("%10s %22s %8s %8s %8s %6s %8s %8s %8s\n", "address", "name", + "objsize", "align", "usage", "empty", "usedobj", "total", "flags"); ObjectCacheList::Iterator it = sObjectCaches.GetIterator(); while (it.HasNext()) { ObjectCache* cache = it.Next(); - kprintf("%p %22s %8lu %8lu %6lu %8lu %8lu %8lx\n", cache, cache->name, - cache->object_size, cache->usage, cache->empty_count, - cache->used_count, cache->total_objects, cache->flags); + kprintf("%p %22s %8lu %8" B_PRIuSIZE " %8lu %6lu %8lu %8lu %8lx\n", + cache, cache->name, cache->object_size, cache->alignment, + cache->usage, cache->empty_count, cache->used_count, + cache->total_objects, cache->flags); } return 0; @@ -238,6 +239,7 @@ dump_cache_info(int argc, char* argv[]) kprintf("name: %s\n", cache->name); kprintf("lock: %p\n", &cache->lock); kprintf("object_size: %lu\n", cache->object_size); + kprintf("alignment: %" B_PRIuSIZE "\n", cache->alignment); kprintf("cache_color_cycle: %lu\n", cache->cache_color_cycle); kprintf("total_objects: %lu\n", cache->total_objects); kprintf("used_count: %lu\n", cache->used_count); diff --git a/src/system/kernel/slab/allocator.cpp b/src/system/kernel/slab/allocator.cpp index d12787ac22..0ae346d805 100644 --- a/src/system/kernel/slab/allocator.cpp +++ b/src/system/kernel/slab/allocator.cpp @@ -74,7 +74,7 @@ size_to_index(size_t size) void* block_alloc(size_t size, size_t alignment, uint32 flags) { - if (alignment > 8) { + if (alignment > kMinObjectAlignment) { // Make size >= alignment and a power of two. This is sufficient, since // all of our object caches with power of two sizes are aligned. We may // waste quite a bit of memory, but memalign() is very rarely used @@ -173,16 +173,15 @@ block_allocator_init_boot() size_t size = kBlockSizes[index]; // align the power of two objects to their size - if ((size & (size - 1)) == 0) - flags |= CACHE_ALIGN_ON_SIZE; + size_t alignment = (size & (size - 1)) == 0 ? size : 0; // For the larger allocation sizes disable the object depot, so we don't // keep lot's of unused objects around. if (size > 2048) flags |= CACHE_NO_DEPOT; - sBlockCaches[index] = create_object_cache_etc(name, size, 0, 0, 0, 0, - flags, NULL, NULL, NULL, NULL); + sBlockCaches[index] = create_object_cache_etc(name, size, alignment, 0, + 0, 0, flags, NULL, NULL, NULL, NULL); if (sBlockCaches[index] == NULL) panic("allocator: failed to init block cache"); } diff --git a/src/system/kernel/slab/slab_private.h b/src/system/kernel/slab/slab_private.h index a43af608cc..6eba3fcf69 100644 --- a/src/system/kernel/slab/slab_private.h +++ b/src/system/kernel/slab/slab_private.h @@ -26,6 +26,11 @@ #define COMPONENT_PARANOIA_LEVEL OBJECT_CACHE_PARANOIA #include + + +static const size_t kMinObjectAlignment = 8; + + struct ObjectCache; struct object_depot;