From c0e0dbc2b9f2865832f937650a617477a350cb55 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 31 Jan 2006 09:21:04 +0100 Subject: [PATCH] [PATCH] blkparse: cut down on excessive number of fcntl() calls Cache the blocking state locally and only issue it if changed. --- blkparse.c | 35 ++++++++++++++++++++++------------- blktrace.h | 1 + 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/blkparse.c b/blkparse.c index 5af31a7..8a90362 100644 --- a/blkparse.c +++ b/blkparse.c @@ -1701,17 +1701,22 @@ static void show_entries_rb(int force) } } -static int read_data(int fd, void *buffer, int bytes, int block) +static int read_data(int fd, void *buffer, int bytes, int block, int *fdblock) { int ret, bytes_left, fl; void *p; - fl = fcntl(fd, F_GETFL); + if (block != *fdblock) { + fl = fcntl(fd, F_GETFL); - if (!block) - fcntl(fd, F_SETFL, fl | O_NONBLOCK); - else - fcntl(fd, F_SETFL, fl & ~O_NONBLOCK); + if (!block) { + *fdblock = 0; + fcntl(fd, F_SETFL, fl | O_NONBLOCK); + } else { + *fdblock = 1; + fcntl(fd, F_SETFL, fl & ~O_NONBLOCK); + } + } bytes_left = bytes; p = buffer; @@ -1742,7 +1747,7 @@ static int read_data(int fd, void *buffer, int bytes, int block) return 0; } -static int read_events(int fd, int always_block) +static int read_events(int fd, int always_block, int *fdblock) { struct per_dev_info *pdi = NULL; unsigned int events = 0; @@ -1750,12 +1755,14 @@ static int read_events(int fd, int always_block) while (!is_done() && events < rb_batch) { struct blk_io_trace *bit; struct trace *t; - int pdu_len; + int pdu_len, should_block; __u32 magic; bit = bit_alloc(); - if (read_data(fd, bit, sizeof(*bit), !events || always_block)) { + should_block = !events || always_block; + + if (read_data(fd, bit, sizeof(*bit), should_block, fdblock)) { bit_free(bit); break; } @@ -1770,7 +1777,7 @@ static int read_events(int fd, int always_block) if (pdu_len) { void *ptr = realloc(bit, sizeof(*bit) + pdu_len); - if (read_data(fd, ptr + sizeof(*bit), pdu_len, 1)) { + if (read_data(fd, ptr + sizeof(*bit), pdu_len, 1, fdblock)) { bit_free(ptr); break; } @@ -1826,6 +1833,7 @@ static int do_file(void) pci = get_cpu_info(pdi, j); pci->cpu = j; pci->fd = -1; + pci->fdblock = -1; p = strdup(pdi->name); dname = dirname(p); @@ -1877,7 +1885,7 @@ static int do_file(void) if (pci->fd == -1) continue; - events = read_events(pci->fd, 1); + events = read_events(pci->fd, 1, &pci->fdblock); if (!events) { cpu_mark_offline(pdi, pci->cpu); close(pci->fd); @@ -1911,7 +1919,7 @@ static int do_file(void) static int do_stdin(void) { unsigned long long youngest; - int fd, events; + int fd, events, fdblock; last_allowed_time = -1ULL; fd = dup(STDIN_FILENO); @@ -1920,7 +1928,8 @@ static int do_stdin(void) return -1; } - while ((events = read_events(fd, 0)) != 0) { + fdblock = -1; + while ((events = read_events(fd, 0, &fdblock)) != 0) { smallest_seq_read = -1U; diff --git a/blktrace.h b/blktrace.h index 046a1aa..7462edc 100644 --- a/blktrace.h +++ b/blktrace.h @@ -37,6 +37,7 @@ struct per_cpu_info { unsigned int nelems; int fd; + int fdblock; char fname[128]; struct io_stats io_stats; -- 2.25.1