Added some temporary means to ease debugging block caches - at least the list

of all caches should be removed at a later point.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21461 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-06-18 23:58:15 +00:00
parent 5680c33e48
commit 5de78b2cdb
2 changed files with 108 additions and 1 deletions
+107
View File
@@ -39,6 +39,8 @@
# define TRACE(x) ;
#endif
#define DEBUG_BLOCK_CACHE
// This macro is used for fatal situations that are acceptable in a running
// system, like out of memory situations - should only panic for debugging.
#define FATAL(x) panic x
@@ -62,6 +64,12 @@ static status_t write_cached_block(block_cache *cache, cached_block *block,
bool deleteTransaction = true);
#ifdef DEBUG_BLOCK_CACHE
static DoublyLinkedList<block_cache> sCaches;
static mutex sCachesLock;
#endif
// #pragma mark - private transaction
@@ -161,6 +169,12 @@ block_cache::block_cache(int _fd, off_t numBlocks, size_t blockSize,
ranges_hash(NULL),
read_only(readOnly)
{
#ifdef DEBUG_BLOCK_CACHE
mutex_lock(&sCachesLock);
sCaches.Add(this);
mutex_unlock(&sCachesLock);
#endif
hash = hash_init(32, 0, &cached_block::Compare, &cached_block::Hash);
if (hash == NULL)
return;
@@ -188,6 +202,12 @@ block_cache::block_cache(int _fd, off_t numBlocks, size_t blockSize,
block_cache::~block_cache()
{
#ifdef DEBUG_BLOCK_CACHE
mutex_lock(&sCachesLock);
sCaches.Remove(this);
mutex_unlock(&sCachesLock);
#endif
unregister_low_memory_handler(&block_cache::LowMemoryHandler, this);
benaphore_destroy(&lock);
@@ -431,6 +451,8 @@ put_cached_block(block_cache *cache, cached_block *block)
&& block->previous_transaction == NULL) {
// put this block in the list of unused blocks
block->unused = true;
if (block->original_data != NULL || block->parent_data != NULL)
panic("put_cached_block(): %p (%Ld): %p, %p\n", block, block->block_number, block->original_data, block->parent_data);
cache->unused_blocks.Add(block);
// block->current_data = cache->allocator->Release(block->current_data);
}
@@ -697,9 +719,94 @@ write_cached_block(block_cache *cache, cached_block *block,
}
#ifdef DEBUG_BLOCK_CACHE
static int
dump_cache(int argc, char **argv)
{
if (argc < 2) {
kprintf("usage: %s [-b] <address>\n", argv[0]);
return 0;
}
bool showBlocks = false;
int32 i = 1;
if (!strcmp(argv[1], "-b")) {
showBlocks = true;
i++;
}
block_cache *cache = (struct block_cache *)strtoul(argv[i], NULL, 0);
if (cache == NULL) {
kprintf("invalid cache address\n");
return 0;
}
kprintf("BLOCK CACHE: %p\n", cache);
kprintf(" fd: %d\n", cache->fd);
kprintf(" max_blocks: %Ld\n", cache->max_blocks);
kprintf(" block_size: %lu\n", cache->block_size);
kprintf(" next_transaction_id: %ld\n", cache->next_transaction_id);
kprintf(" chunks_per_range: %lu\n", cache->chunks_per_range);
kprintf(" chunks_size: %lu\n", cache->chunk_size);
kprintf(" range_mask: %lu\n", cache->range_mask);
kprintf(" chunks_mask: %lu\n", cache->chunk_mask);
if (showBlocks) {
kprintf(" blocks:\n");
kprintf("address block no. current original parent refs access flags transact prev. trans\n");
}
uint32 count = 0;
hash_iterator iterator;
hash_open(cache->hash, &iterator);
cached_block *block;
while ((block = (cached_block *)hash_next(cache->hash, &iterator)) != NULL) {
if (showBlocks) {
kprintf("%08lx %9Ld %08lx %08lx %08lx %5ld %6ld %c%c%c%c%c %08lx %08lx\n",
(addr_t)block, block->block_number, (addr_t)block->current_data,
(addr_t)block->original_data, (addr_t)block->parent_data,
block->ref_count, block->accessed, block->busy ? 'B' : '-',
block->is_writing ? 'W' : '-', block->is_dirty ? 'B' : '-',
block->unused ? 'U' : '-', block->unmapped ? 'M' : '-',
(addr_t)block->transaction, (addr_t)block->previous_transaction);
}
count++;
}
kprintf(" %ld blocks.\n", count);
hash_close(cache->hash, &iterator, false);
return 0;
}
static int
dump_caches(int argc, char **argv)
{
kprintf("Block caches:\n");
DoublyLinkedList<block_cache>::Iterator i = sCaches.GetIterator();
while (i.HasNext()) {
kprintf(" %p\n", i.Next());
}
return 0;
}
#endif // DEBUG_BLOCK_CACHE
extern "C" status_t
block_cache_init(void)
{
#ifdef DEBUG_BLOCK_CACHE
mutex_init(&sCachesLock, "block caches");
new (&sCaches) DoublyLinkedList<block_cache>;
// manually call constructor
add_debugger_command("block_caches", &dump_caches, "dumps all block caches");
add_debugger_command("block_cache", &dump_cache, "dumps a specific block cache");
#endif
return init_block_allocator();
}
+1 -1
View File
@@ -97,7 +97,7 @@ typedef DoublyLinkedList<block_range,
DoublyLinkedListMemberGetLink<block_range,
&block_range::link> > range_list;
struct block_cache {
struct block_cache : DoublyLinkedListLinkImpl<block_cache> {
hash_table *hash;
benaphore lock;
int fd;