* 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:
Ingo Weinhold
2010-07-16 01:27:27 +00:00
parent a8d618d4d2
commit 3aea1d4f53
5 changed files with 25 additions and 21 deletions
+8 -11
View File
@@ -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);
+1
View File
@@ -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;
+7 -5
View File
@@ -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);
+4 -5
View File
@@ -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");
}
+5
View File
@@ -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;