summaryrefslogtreecommitdiff
path: root/blkparse.c
diff options
context:
space:
mode:
authorOlaf Kirch <okir@lst.de>2006-12-01 10:34:11 +0100
committerJens Axboe <jens.axboe@oracle.com>2006-12-01 10:34:11 +0100
commit7bd4fd0a4fca645bb50a641afac1e460a4e32dfd (patch)
tree3b07ba4c6f2b5245dd6a70e0657cf90b6638338b /blkparse.c
parentb22050b50f412c4c6567eebbcd2f3364e74908d9 (diff)
downloadblktrace-7bd4fd0a4fca645bb50a641afac1e460a4e32dfd.tar.gz
blktrace-7bd4fd0a4fca645bb50a641afac1e460a4e32dfd.tar.bz2
[PATCH] Add timestamp support
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'blkparse.c')
-rw-r--r--blkparse.c60
1 files changed, 58 insertions, 2 deletions
diff --git a/blkparse.c b/blkparse.c
index f029341..8e16c7a 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -288,6 +288,9 @@ static int text_output = 1;
#define is_done() (*(volatile int *)(&done))
static volatile int done;
+struct timespec abs_start_time;
+static unsigned long long start_timestamp;
+
#define JHASH_RANDOM (0x3af5f2ee)
#define CPUS_PER_LONG (8 * sizeof(unsigned long))
@@ -556,6 +559,40 @@ static void add_ppm_hash(pid_t pid, const char *name)
}
}
+static void handle_notify(struct blk_io_trace *bit)
+{
+ void *payload = (caddr_t) bit + sizeof(*bit);
+ __u32 two32[2];
+
+ switch (bit->action) {
+ case BLK_TN_PROCESS:
+ add_ppm_hash(bit->pid, payload);
+ break;
+
+ case BLK_TN_TIMESTAMP:
+ if (bit->pdu_len != sizeof(two32))
+ return;
+ memcpy(two32, payload, sizeof(two32));
+ if (!data_is_native) {
+ two32[0] = be32_to_cpu(two32[0]);
+ two32[1] = be32_to_cpu(two32[1]);
+ }
+ start_timestamp = bit->time;
+ abs_start_time.tv_sec = two32[0];
+ abs_start_time.tv_nsec = two32[1];
+ if (abs_start_time.tv_nsec < 0) {
+ abs_start_time.tv_sec--;
+ abs_start_time.tv_nsec += 1000000000;
+ }
+
+ break;
+
+ default:
+ /* Ignore unknown notify events */
+ ;
+ }
+}
+
char *find_process_name(pid_t pid)
{
struct process_pid_map *ppm = find_ppm(pid);
@@ -1654,6 +1691,25 @@ static void find_genesis(void)
t = t->next;
}
+
+ /* The time stamp record will usually be the first
+ * record in the trace, but not always.
+ */
+ if (start_timestamp
+ && start_timestamp != genesis_time) {
+ long delta = genesis_time - start_timestamp;
+
+ abs_start_time.tv_sec += SECONDS(delta);
+ abs_start_time.tv_nsec += NANO_SECONDS(delta);
+ if (abs_start_time.tv_nsec < 0) {
+ abs_start_time.tv_nsec += 1000000000;
+ abs_start_time.tv_sec -= 1;
+ } else
+ if (abs_start_time.tv_nsec > 1000000000) {
+ abs_start_time.tv_nsec -= 1000000000;
+ abs_start_time.tv_sec += 1;
+ }
+ }
}
static inline int check_stopwatch(struct blk_io_trace *bit)
@@ -1975,7 +2031,7 @@ static int read_events(int fd, int always_block, int *fdblock)
* not a real trace, so grab and handle it here
*/
if (bit->action & BLK_TC_ACT(BLK_TC_NOTIFY)) {
- add_ppm_hash(bit->pid, (char *) bit + sizeof(*bit));
+ handle_notify(bit);
output_binary(bit, sizeof(*bit) + bit->pdu_len);
continue;
}
@@ -2117,7 +2173,7 @@ static int ms_prime(struct ms_stream *msp)
goto err;
if (bit->action & BLK_TC_ACT(BLK_TC_NOTIFY)) {
- add_ppm_hash(bit->pid, (char *) bit + sizeof(*bit));
+ handle_notify(bit);
output_binary(bit, sizeof(*bit) + bit->pdu_len);
bit_free(bit);