* Added debugger command "transaction" and added a new "-t" option to
"block_cache" to dump info about transactions. * Improved tracing. * Now uses the new add_debugger_command_etc(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23644 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5d8d6d9a0a
commit
5f7a62cfdd
157
src/system/kernel/cache/block_cache.cpp
vendored
157
src/system/kernel/cache/block_cache.cpp
vendored
@ -76,9 +76,9 @@ struct cache_transaction {
|
||||
#ifdef TRANSACTION_TRACING
|
||||
namespace TransactionTracing {
|
||||
|
||||
class StartEnd : public AbstractTraceEntry {
|
||||
class Action : public AbstractTraceEntry {
|
||||
public:
|
||||
StartEnd(const char *label, block_cache *cache,
|
||||
Action(const char *label, block_cache *cache,
|
||||
cache_transaction *transaction)
|
||||
:
|
||||
fCache(cache),
|
||||
@ -849,21 +849,48 @@ write_cached_block(block_cache *cache, cached_block *block,
|
||||
|
||||
|
||||
#ifdef DEBUG_BLOCK_CACHE
|
||||
static void
|
||||
dump_block(cached_block *block)
|
||||
{
|
||||
kprintf("%08lx %9Ld %08lx %08lx %08lx %5ld %6ld %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' : '-',
|
||||
(addr_t)block->transaction,
|
||||
(addr_t)block->previous_transaction);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dump_cache(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2 || !strcmp(argv[1], "--help")) {
|
||||
kprintf("usage: %s [-b] <address> [block-number]\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool showTransactions = false;
|
||||
bool showBlocks = false;
|
||||
int32 i = 1;
|
||||
if (!strcmp(argv[1], "-b")) {
|
||||
showBlocks = true;
|
||||
while (argv[i] != NULL && argv[i][0] == '-') {
|
||||
for (char *arg = &argv[i][1]; arg[0]; arg++) {
|
||||
switch (arg[0]) {
|
||||
case 'b':
|
||||
showBlocks = true;
|
||||
break;
|
||||
case 't':
|
||||
showTransactions = true;
|
||||
break;
|
||||
default:
|
||||
print_debugger_command_usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i >= argc) {
|
||||
print_debugger_command_usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
block_cache *cache = (struct block_cache *)parse_expression(argv[i]);
|
||||
if (cache == NULL) {
|
||||
kprintf("invalid cache address\n");
|
||||
@ -915,6 +942,23 @@ dump_cache(int argc, char **argv)
|
||||
kprintf(" block_size: %lu\n", cache->block_size);
|
||||
kprintf(" next_transaction_id: %ld\n", cache->next_transaction_id);
|
||||
|
||||
if (showTransactions) {
|
||||
kprintf(" transactions:\n");
|
||||
kprintf("address id state blocks main sub\n");
|
||||
|
||||
hash_iterator iterator;
|
||||
hash_open(cache->transaction_hash, &iterator);
|
||||
|
||||
cache_transaction *transaction;
|
||||
while ((transaction = (cache_transaction *)hash_next(
|
||||
cache->transaction_hash, &iterator)) != NULL) {
|
||||
kprintf("%p %5ld %-7s %5ld %5ld %5ld\n", transaction,
|
||||
transaction->id, transaction->open ? "open" : "closed",
|
||||
transaction->num_blocks, transaction->main_num_blocks,
|
||||
transaction->sub_num_blocks);
|
||||
}
|
||||
}
|
||||
|
||||
if (showBlocks) {
|
||||
kprintf(" blocks:\n");
|
||||
kprintf("address block no. current original parent refs access "
|
||||
@ -928,16 +972,8 @@ dump_cache(int argc, char **argv)
|
||||
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 %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' : '-',
|
||||
(addr_t)block->transaction,
|
||||
(addr_t)block->previous_transaction);
|
||||
}
|
||||
if (showBlocks)
|
||||
dump_block(block);
|
||||
|
||||
if (block->is_dirty)
|
||||
dirty++;
|
||||
@ -954,6 +990,69 @@ dump_cache(int argc, char **argv)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dump_transaction(int argc, char **argv)
|
||||
{
|
||||
bool showBlocks = false;
|
||||
int i = 1;
|
||||
if (argc > 1 && !strcmp(argv[1], "-b")) {
|
||||
showBlocks = true;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (argc - i < 1 || argc - i > 2) {
|
||||
print_debugger_command_usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cache_transaction *transaction = NULL;
|
||||
|
||||
if (argc - i == 1) {
|
||||
transaction = (cache_transaction *)parse_expression(argv[i]);
|
||||
} else {
|
||||
block_cache *cache = (block_cache *)parse_expression(argv[i]);
|
||||
int32 id = parse_expression(argv[i + 1]);
|
||||
transaction = lookup_transaction(cache, id);
|
||||
if (transaction == NULL) {
|
||||
kprintf("No transaction with ID %ld found.\n", id);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
kprintf("TRANSACTION %p\n", transaction);
|
||||
|
||||
kprintf(" id: %ld\n", transaction->id);
|
||||
kprintf(" num block: %ld\n", transaction->num_blocks);
|
||||
kprintf(" main num block: %ld\n", transaction->main_num_blocks);
|
||||
kprintf(" sub num block: %ld\n", transaction->sub_num_blocks);
|
||||
kprintf(" has sub: %d\n", transaction->has_sub_transaction);
|
||||
kprintf(" state: %s\n", transaction->open ? "open" : "closed");
|
||||
|
||||
if (!showBlocks)
|
||||
return 0;
|
||||
|
||||
kprintf(" blocks:\n");
|
||||
kprintf("address block no. current original parent refs access "
|
||||
"flags transact prev. trans\n");
|
||||
|
||||
cached_block *block = transaction->first_block;
|
||||
while (block != NULL) {
|
||||
dump_block(block);
|
||||
block = block->transaction_next;
|
||||
}
|
||||
|
||||
kprintf("--\n");
|
||||
|
||||
block_list::Iterator iterator = transaction->blocks.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
block = iterator.Next();
|
||||
dump_block(block);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dump_caches(int argc, char **argv)
|
||||
{
|
||||
@ -981,8 +1080,17 @@ block_cache_init(void)
|
||||
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");
|
||||
add_debugger_command_etc("block_caches", &dump_caches,
|
||||
"dumps all block caches", "\n", 0);
|
||||
add_debugger_command_etc("block_cache", &dump_cache,
|
||||
"dumps a specific block cache",
|
||||
"[-bt] <cache-address> [block-number]\n"
|
||||
" -t lists the transactions\n"
|
||||
" -b lists all blocks\n", 0);
|
||||
add_debugger_command_etc("transaction", &dump_transaction,
|
||||
"dumps a specific transaction", "[-b] ((<cache> <id>) | <transaction>)\n"
|
||||
"Either use a block cache pointer and an ID or a pointer to the transaction.\n"
|
||||
" -b lists all blocks that are part of this transaction\n", 0);
|
||||
#endif
|
||||
|
||||
return B_OK;
|
||||
@ -1011,7 +1119,7 @@ cache_start_transaction(void *_cache)
|
||||
cache->last_transaction = transaction;
|
||||
|
||||
TRACE(("cache_start_transaction(): id %ld started\n", transaction->id));
|
||||
T(StartEnd("start", cache, transaction));
|
||||
T(Action("start", cache, transaction));
|
||||
|
||||
hash_insert(cache->transaction_hash, transaction);
|
||||
|
||||
@ -1038,6 +1146,7 @@ cache_sync_transaction(void *_cache, int32 id)
|
||||
|
||||
if (transaction->id <= id && !transaction->open) {
|
||||
// write back all of their remaining dirty blocks
|
||||
T(Action("sync", cache, transaction));
|
||||
while (transaction->num_blocks > 0) {
|
||||
status = write_cached_block(cache, transaction->blocks.Head(),
|
||||
false);
|
||||
@ -1070,7 +1179,7 @@ cache_end_transaction(void *_cache, int32 id,
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
T(StartEnd("end", cache, transaction));
|
||||
T(Action("end", cache, transaction));
|
||||
|
||||
transaction->notification_hook = hook;
|
||||
transaction->notification_data = data;
|
||||
@ -1338,7 +1447,7 @@ cache_start_sub_transaction(void *_cache, int32 id)
|
||||
transaction->has_sub_transaction = true;
|
||||
transaction->main_num_blocks = transaction->num_blocks;
|
||||
transaction->sub_num_blocks = 0;
|
||||
T(StartEnd("start-sub", cache, transaction));
|
||||
T(Action("start-sub", cache, transaction));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user