* 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"
|
#include "slab_private.h"
|
||||||
|
|
||||||
|
|
||||||
static const size_t kCacheColorPeriod = 8;
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
object_cache_return_object_wrapper(object_depot* depot, void* cookie,
|
object_cache_return_object_wrapper(object_depot* depot, void* cookie,
|
||||||
void* object, uint32 flags)
|
void* object, uint32 flags)
|
||||||
@@ -52,6 +49,9 @@ ObjectCache::Init(const char* name, size_t objectSize, size_t alignment,
|
|||||||
if (objectSize < sizeof(object_link))
|
if (objectSize < sizeof(object_link))
|
||||||
objectSize = sizeof(object_link);
|
objectSize = sizeof(object_link);
|
||||||
|
|
||||||
|
if (alignment < kMinObjectAlignment)
|
||||||
|
alignment = kMinObjectAlignment;
|
||||||
|
|
||||||
if (alignment > 0 && (objectSize & (alignment - 1)))
|
if (alignment > 0 && (objectSize & (alignment - 1)))
|
||||||
object_size = objectSize + alignment - (objectSize & (alignment - 1));
|
object_size = objectSize + alignment - (objectSize & (alignment - 1));
|
||||||
else
|
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,
|
TRACE_CACHE(this, "init %lu, %lu -> %lu", objectSize, alignment,
|
||||||
object_size);
|
object_size);
|
||||||
|
|
||||||
|
this->alignment = alignment;
|
||||||
cache_color_cycle = 0;
|
cache_color_cycle = 0;
|
||||||
total_objects = 0;
|
total_objects = 0;
|
||||||
used_count = 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);
|
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 += alignment;
|
||||||
cache_color_cycle = slab->offset = 0;
|
if (cache_color_cycle > spareBytes)
|
||||||
else
|
cache_color_cycle = 0;
|
||||||
cache_color_cycle += kCacheColorPeriod;
|
|
||||||
} else
|
|
||||||
slab->offset = 0;
|
|
||||||
|
|
||||||
TRACE_CACHE(this, " %lu objects, %lu spare bytes, offset %lu",
|
TRACE_CACHE(this, " %lu objects, %lu spare bytes, offset %lu",
|
||||||
slab->size, spareBytes, slab->offset);
|
slab->size, spareBytes, slab->offset);
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ struct ObjectCache : DoublyLinkedListLinkImpl<ObjectCache> {
|
|||||||
char name[32];
|
char name[32];
|
||||||
mutex lock;
|
mutex lock;
|
||||||
size_t object_size;
|
size_t object_size;
|
||||||
|
size_t alignment;
|
||||||
size_t cache_color_cycle;
|
size_t cache_color_cycle;
|
||||||
SlabList empty;
|
SlabList empty;
|
||||||
SlabList partial;
|
SlabList partial;
|
||||||
|
|||||||
@@ -208,17 +208,18 @@ dump_slab(::slab* slab)
|
|||||||
static int
|
static int
|
||||||
dump_slabs(int argc, char* argv[])
|
dump_slabs(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
kprintf("%10s %22s %8s %8s %6s %8s %8s %8s\n", "address", "name",
|
kprintf("%10s %22s %8s %8s %8s %6s %8s %8s %8s\n", "address", "name",
|
||||||
"objsize", "usage", "empty", "usedobj", "total", "flags");
|
"objsize", "align", "usage", "empty", "usedobj", "total", "flags");
|
||||||
|
|
||||||
ObjectCacheList::Iterator it = sObjectCaches.GetIterator();
|
ObjectCacheList::Iterator it = sObjectCaches.GetIterator();
|
||||||
|
|
||||||
while (it.HasNext()) {
|
while (it.HasNext()) {
|
||||||
ObjectCache* cache = it.Next();
|
ObjectCache* cache = it.Next();
|
||||||
|
|
||||||
kprintf("%p %22s %8lu %8lu %6lu %8lu %8lu %8lx\n", cache, cache->name,
|
kprintf("%p %22s %8lu %8" B_PRIuSIZE " %8lu %6lu %8lu %8lu %8lx\n",
|
||||||
cache->object_size, cache->usage, cache->empty_count,
|
cache, cache->name, cache->object_size, cache->alignment,
|
||||||
cache->used_count, cache->total_objects, cache->flags);
|
cache->usage, cache->empty_count, cache->used_count,
|
||||||
|
cache->total_objects, cache->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -238,6 +239,7 @@ dump_cache_info(int argc, char* argv[])
|
|||||||
kprintf("name: %s\n", cache->name);
|
kprintf("name: %s\n", cache->name);
|
||||||
kprintf("lock: %p\n", &cache->lock);
|
kprintf("lock: %p\n", &cache->lock);
|
||||||
kprintf("object_size: %lu\n", cache->object_size);
|
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("cache_color_cycle: %lu\n", cache->cache_color_cycle);
|
||||||
kprintf("total_objects: %lu\n", cache->total_objects);
|
kprintf("total_objects: %lu\n", cache->total_objects);
|
||||||
kprintf("used_count: %lu\n", cache->used_count);
|
kprintf("used_count: %lu\n", cache->used_count);
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ size_to_index(size_t size)
|
|||||||
void*
|
void*
|
||||||
block_alloc(size_t size, size_t alignment, uint32 flags)
|
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
|
// 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
|
// 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
|
// 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];
|
size_t size = kBlockSizes[index];
|
||||||
|
|
||||||
// align the power of two objects to their size
|
// align the power of two objects to their size
|
||||||
if ((size & (size - 1)) == 0)
|
size_t alignment = (size & (size - 1)) == 0 ? size : 0;
|
||||||
flags |= CACHE_ALIGN_ON_SIZE;
|
|
||||||
|
|
||||||
// For the larger allocation sizes disable the object depot, so we don't
|
// For the larger allocation sizes disable the object depot, so we don't
|
||||||
// keep lot's of unused objects around.
|
// keep lot's of unused objects around.
|
||||||
if (size > 2048)
|
if (size > 2048)
|
||||||
flags |= CACHE_NO_DEPOT;
|
flags |= CACHE_NO_DEPOT;
|
||||||
|
|
||||||
sBlockCaches[index] = create_object_cache_etc(name, size, 0, 0, 0, 0,
|
sBlockCaches[index] = create_object_cache_etc(name, size, alignment, 0,
|
||||||
flags, NULL, NULL, NULL, NULL);
|
0, 0, flags, NULL, NULL, NULL, NULL);
|
||||||
if (sBlockCaches[index] == NULL)
|
if (sBlockCaches[index] == NULL)
|
||||||
panic("allocator: failed to init block cache");
|
panic("allocator: failed to init block cache");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,11 @@
|
|||||||
#define COMPONENT_PARANOIA_LEVEL OBJECT_CACHE_PARANOIA
|
#define COMPONENT_PARANOIA_LEVEL OBJECT_CACHE_PARANOIA
|
||||||
#include <debug_paranoia.h>
|
#include <debug_paranoia.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const size_t kMinObjectAlignment = 8;
|
||||||
|
|
||||||
|
|
||||||
struct ObjectCache;
|
struct ObjectCache;
|
||||||
struct object_depot;
|
struct object_depot;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user