aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-02-10 13:10:48 -0500
committerSteven Rostedt <rostedt@goodmis.org>2010-02-10 13:10:48 -0500
commitffc9da087d4168a00640ef04376e2e4f42e7fa42 (patch)
tree8527f3df050f05c450cc57cb25b8e75850a8ef6f
parent37fe347963f8f43d95ca0ccd978a769fd6cc96f3 (diff)
trace-cmd: Add tracecmd_read_prev()
Add the tracecmd_read_prev(handle, record) that returns the record before the given record. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--trace-cmd.h3
-rw-r--r--trace-input.c99
2 files changed, 102 insertions, 0 deletions
diff --git a/trace-cmd.h b/trace-cmd.h
index b7cd5cc..7228a6d 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -64,6 +64,9 @@ struct record *
64tracecmd_read_data(struct tracecmd_input *handle, int cpu); 64tracecmd_read_data(struct tracecmd_input *handle, int cpu);
65 65
66struct record * 66struct record *
67tracecmd_read_prev(struct tracecmd_input *handle, struct record *record);
68
69struct record *
67tracecmd_read_next_data(struct tracecmd_input *handle, int *rec_cpu); 70tracecmd_read_next_data(struct tracecmd_input *handle, int *rec_cpu);
68 71
69struct record * 72struct record *
diff --git a/trace-input.c b/trace-input.c
index ce7bd09..279382a 100644
--- a/trace-input.c
+++ b/trace-input.c
@@ -1500,6 +1500,105 @@ tracecmd_read_next_data(struct tracecmd_input *handle, int *rec_cpu)
1500 return NULL; 1500 return NULL;
1501} 1501}
1502 1502
1503/**
1504 * tracecmd_read_prev - read the record before the given record
1505 * @handle: input handle to the trace.dat file
1506 * @record: the record to use to find the previous record.
1507 *
1508 * This returns the record before the @record on its CPU. If
1509 * @record is the first record, NULL is returned. The cursor is set
1510 * as if the previous record was read by tracecmd_read_data().
1511 *
1512 * @record can not be NULL, otherwise NULL is returned.
1513 *
1514 * Note, this is not that fast of an algorithm, since it needs
1515 * to build the timestamp for the record.
1516 *
1517 * Note 2: This may free any record allocoted with tracecmd_peek_data().
1518 *
1519 * The record returned must be freed with free_record().
1520 */
1521struct record *
1522tracecmd_read_prev(struct tracecmd_input *handle, struct record *record)
1523{
1524 unsigned long long offset, page_offset;;
1525 struct cpu_data *cpu_data;
1526 int index;
1527 int cpu;
1528
1529 if (!record)
1530 return NULL;
1531
1532 cpu = record->cpu;
1533 offset = record->offset;
1534 cpu_data = &handle->cpu_data[cpu];
1535
1536 page_offset = calc_page_offset(handle, offset);
1537 index = offset - page_offset;
1538
1539 /* Note, the record passed in could have been a peek */
1540 if (cpu_data->next) {
1541 free_record(cpu_data->next);
1542 cpu_data->next = NULL;
1543 }
1544
1545 /* Reset the cursor */
1546 /* Should not happen */
1547 if (get_page(handle, cpu, page_offset) < 0)
1548 return NULL;
1549
1550 update_page_info(handle, cpu);
1551
1552 /* Find the record before this record */
1553 index = 0;
1554 for (;;) {
1555 record = tracecmd_read_data(handle, cpu);
1556 /* Should not happen! */
1557 if (!record)
1558 return NULL;
1559 if (record->offset == offset)
1560 break;
1561 index = record->offset - page_offset;
1562 free_record(record);
1563 }
1564 free_record(record);
1565
1566 if (index)
1567 /* we found our record */
1568 return tracecmd_read_at(handle, page_offset + index, NULL);
1569
1570 /* The previous record is on the previous page */
1571 for (;;) {
1572 /* check if this is the first page */
1573 if (page_offset == cpu_data->file_offset)
1574 return NULL;
1575 page_offset -= handle->page_size;
1576
1577 /* Updating page to a new page will reset index to 0 */
1578 get_page(handle, cpu, page_offset);
1579
1580 record = NULL;
1581 index = 0;
1582 do {
1583 if (record) {
1584 index = record->offset - page_offset;
1585 free_record(record);
1586 }
1587 record = tracecmd_read_data(handle, cpu);
1588 /* Should not happen */
1589 if (!record)
1590 return NULL;
1591 } while (record->offset != offset);
1592 free_record(record);
1593
1594 if (index)
1595 /* we found our record */
1596 return tracecmd_read_at(handle, page_offset + index, NULL);
1597 }
1598
1599 /* Not reached */
1600}
1601
1503static int init_cpu(struct tracecmd_input *handle, int cpu) 1602static int init_cpu(struct tracecmd_input *handle, int cpu)
1504{ 1603{
1505 struct cpu_data *cpu_data = &handle->cpu_data[cpu]; 1604 struct cpu_data *cpu_data = &handle->cpu_data[cpu];