* Added ObjectCache::alignment, the object alignment and used the alignment for
incrementing the cache color cycle. Using the fixed value (8) would potentially misalign the object again. * Don't use CACHE_ALIGN_ON_SIZE for object caches any longer -- we have the alignment parameter anyway (the flag is still used for the MemoryManager, though). * ObjectCache::InitSlab(): Slab coloring *was* done when CACHE_ALIGN_ON_SIZE was given, i.e. exactly the wrong way around. Also the cache_color_cycle computation was weird -- color 0 was used twice in a row. * The "slabs" and "slab_cache" KDL commands also print the alignment, now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37534 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -41,6 +41,7 @@ struct ObjectCache : DoublyLinkedListLinkImpl<ObjectCache> {
|
||||
char name[32];
|
||||
mutex lock;
|
||||
size_t object_size;
|
||||
size_t alignment;
|
||||
size_t cache_color_cycle;
|
||||
SlabList empty;
|
||||
SlabList partial;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
#define COMPONENT_PARANOIA_LEVEL OBJECT_CACHE_PARANOIA
|
||||
#include <debug_paranoia.h>
|
||||
|
||||
|
||||
|
||||
static const size_t kMinObjectAlignment = 8;
|
||||
|
||||
|
||||
struct ObjectCache;
|
||||
struct object_depot;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user