aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/traceevent/event-parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/traceevent/event-parse.c')
-rw-r--r--tools/lib/traceevent/event-parse.c156
1 files changed, 123 insertions, 33 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index c3bd294a63d1..190cc886ab91 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -1951,6 +1951,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1951 strcmp(token, "*") == 0 || 1951 strcmp(token, "*") == 0 ||
1952 strcmp(token, "^") == 0 || 1952 strcmp(token, "^") == 0 ||
1953 strcmp(token, "/") == 0 || 1953 strcmp(token, "/") == 0 ||
1954 strcmp(token, "%") == 0 ||
1954 strcmp(token, "<") == 0 || 1955 strcmp(token, "<") == 0 ||
1955 strcmp(token, ">") == 0 || 1956 strcmp(token, ">") == 0 ||
1956 strcmp(token, "<=") == 0 || 1957 strcmp(token, "<=") == 0 ||
@@ -2397,6 +2398,12 @@ static int arg_num_eval(struct print_arg *arg, long long *val)
2397 break; 2398 break;
2398 *val = left + right; 2399 *val = left + right;
2399 break; 2400 break;
2401 case '~':
2402 ret = arg_num_eval(arg->op.right, &right);
2403 if (!ret)
2404 break;
2405 *val = ~right;
2406 break;
2400 default: 2407 default:
2401 do_warning("unknown op '%s'", arg->op.op); 2408 do_warning("unknown op '%s'", arg->op.op);
2402 ret = 0; 2409 ret = 0;
@@ -2634,6 +2641,7 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok)
2634 2641
2635free_field: 2642free_field:
2636 free_arg(arg->hex.field); 2643 free_arg(arg->hex.field);
2644 arg->hex.field = NULL;
2637out: 2645out:
2638 *tok = NULL; 2646 *tok = NULL;
2639 return EVENT_ERROR; 2647 return EVENT_ERROR;
@@ -2658,8 +2666,10 @@ process_int_array(struct event_format *event, struct print_arg *arg, char **tok)
2658 2666
2659free_size: 2667free_size:
2660 free_arg(arg->int_array.count); 2668 free_arg(arg->int_array.count);
2669 arg->int_array.count = NULL;
2661free_field: 2670free_field:
2662 free_arg(arg->int_array.field); 2671 free_arg(arg->int_array.field);
2672 arg->int_array.field = NULL;
2663out: 2673out:
2664 *tok = NULL; 2674 *tok = NULL;
2665 return EVENT_ERROR; 2675 return EVENT_ERROR;
@@ -3689,6 +3699,9 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
3689 case '/': 3699 case '/':
3690 val = left / right; 3700 val = left / right;
3691 break; 3701 break;
3702 case '%':
3703 val = left % right;
3704 break;
3692 case '*': 3705 case '*':
3693 val = left * right; 3706 val = left * right;
3694 break; 3707 break;
@@ -4971,7 +4984,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
4971 break; 4984 break;
4972 } 4985 }
4973 } 4986 }
4974 if (pevent->long_size == 8 && ls && 4987 if (pevent->long_size == 8 && ls == 1 &&
4975 sizeof(long) != 8) { 4988 sizeof(long) != 8) {
4976 char *p; 4989 char *p;
4977 4990
@@ -5335,41 +5348,45 @@ static bool is_timestamp_in_us(char *trace_clock, bool use_trace_clock)
5335 return false; 5348 return false;
5336} 5349}
5337 5350
5338void pevent_print_event(struct pevent *pevent, struct trace_seq *s, 5351/**
5339 struct pevent_record *record, bool use_trace_clock) 5352 * pevent_find_event_by_record - return the event from a given record
5353 * @pevent: a handle to the pevent
5354 * @record: The record to get the event from
5355 *
5356 * Returns the associated event for a given record, or NULL if non is
5357 * is found.
5358 */
5359struct event_format *
5360pevent_find_event_by_record(struct pevent *pevent, struct pevent_record *record)
5340{ 5361{
5341 static const char *spaces = " "; /* 20 spaces */
5342 struct event_format *event;
5343 unsigned long secs;
5344 unsigned long usecs;
5345 unsigned long nsecs;
5346 const char *comm;
5347 void *data = record->data;
5348 int type; 5362 int type;
5349 int pid;
5350 int len;
5351 int p;
5352 bool use_usec_format;
5353
5354 use_usec_format = is_timestamp_in_us(pevent->trace_clock,
5355 use_trace_clock);
5356 if (use_usec_format) {
5357 secs = record->ts / NSECS_PER_SEC;
5358 nsecs = record->ts - secs * NSECS_PER_SEC;
5359 }
5360 5363
5361 if (record->size < 0) { 5364 if (record->size < 0) {
5362 do_warning("ug! negative record size %d", record->size); 5365 do_warning("ug! negative record size %d", record->size);
5363 return; 5366 return NULL;
5364 } 5367 }
5365 5368
5366 type = trace_parse_common_type(pevent, data); 5369 type = trace_parse_common_type(pevent, record->data);
5367 5370
5368 event = pevent_find_event(pevent, type); 5371 return pevent_find_event(pevent, type);
5369 if (!event) { 5372}
5370 do_warning("ug! no event found for type %d", type); 5373
5371 return; 5374/**
5372 } 5375 * pevent_print_event_task - Write the event task comm, pid and CPU
5376 * @pevent: a handle to the pevent
5377 * @s: the trace_seq to write to
5378 * @event: the handle to the record's event
5379 * @record: The record to get the event from
5380 *
5381 * Writes the tasks comm, pid and CPU to @s.
5382 */
5383void pevent_print_event_task(struct pevent *pevent, struct trace_seq *s,
5384 struct event_format *event,
5385 struct pevent_record *record)
5386{
5387 void *data = record->data;
5388 const char *comm;
5389 int pid;
5373 5390
5374 pid = parse_common_pid(pevent, data); 5391 pid = parse_common_pid(pevent, data);
5375 comm = find_cmdline(pevent, pid); 5392 comm = find_cmdline(pevent, pid);
@@ -5377,9 +5394,43 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
5377 if (pevent->latency_format) { 5394 if (pevent->latency_format) {
5378 trace_seq_printf(s, "%8.8s-%-5d %3d", 5395 trace_seq_printf(s, "%8.8s-%-5d %3d",
5379 comm, pid, record->cpu); 5396 comm, pid, record->cpu);
5380 pevent_data_lat_fmt(pevent, s, record);
5381 } else 5397 } else
5382 trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu); 5398 trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);
5399}
5400
5401/**
5402 * pevent_print_event_time - Write the event timestamp
5403 * @pevent: a handle to the pevent
5404 * @s: the trace_seq to write to
5405 * @event: the handle to the record's event
5406 * @record: The record to get the event from
5407 * @use_trace_clock: Set to parse according to the @pevent->trace_clock
5408 *
5409 * Writes the timestamp of the record into @s.
5410 */
5411void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s,
5412 struct event_format *event,
5413 struct pevent_record *record,
5414 bool use_trace_clock)
5415{
5416 unsigned long secs;
5417 unsigned long usecs;
5418 unsigned long nsecs;
5419 int p;
5420 bool use_usec_format;
5421
5422 use_usec_format = is_timestamp_in_us(pevent->trace_clock,
5423 use_trace_clock);
5424 if (use_usec_format) {
5425 secs = record->ts / NSECS_PER_SEC;
5426 nsecs = record->ts - secs * NSECS_PER_SEC;
5427 }
5428
5429 if (pevent->latency_format) {
5430 trace_seq_printf(s, " %3d", record->cpu);
5431 pevent_data_lat_fmt(pevent, s, record);
5432 } else
5433 trace_seq_printf(s, " [%03d]", record->cpu);
5383 5434
5384 if (use_usec_format) { 5435 if (use_usec_format) {
5385 if (pevent->flags & PEVENT_NSEC_OUTPUT) { 5436 if (pevent->flags & PEVENT_NSEC_OUTPUT) {
@@ -5387,14 +5438,36 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
5387 p = 9; 5438 p = 9;
5388 } else { 5439 } else {
5389 usecs = (nsecs + 500) / NSECS_PER_USEC; 5440 usecs = (nsecs + 500) / NSECS_PER_USEC;
5441 /* To avoid usecs larger than 1 sec */
5442 if (usecs >= 1000000) {
5443 usecs -= 1000000;
5444 secs++;
5445 }
5390 p = 6; 5446 p = 6;
5391 } 5447 }
5392 5448
5393 trace_seq_printf(s, " %5lu.%0*lu: %s: ", 5449 trace_seq_printf(s, " %5lu.%0*lu:", secs, p, usecs);
5394 secs, p, usecs, event->name);
5395 } else 5450 } else
5396 trace_seq_printf(s, " %12llu: %s: ", 5451 trace_seq_printf(s, " %12llu:", record->ts);
5397 record->ts, event->name); 5452}
5453
5454/**
5455 * pevent_print_event_data - Write the event data section
5456 * @pevent: a handle to the pevent
5457 * @s: the trace_seq to write to
5458 * @event: the handle to the record's event
5459 * @record: The record to get the event from
5460 *
5461 * Writes the parsing of the record's data to @s.
5462 */
5463void pevent_print_event_data(struct pevent *pevent, struct trace_seq *s,
5464 struct event_format *event,
5465 struct pevent_record *record)
5466{
5467 static const char *spaces = " "; /* 20 spaces */
5468 int len;
5469
5470 trace_seq_printf(s, " %s: ", event->name);
5398 5471
5399 /* Space out the event names evenly. */ 5472 /* Space out the event names evenly. */
5400 len = strlen(event->name); 5473 len = strlen(event->name);
@@ -5404,6 +5477,23 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
5404 pevent_event_info(s, event, record); 5477 pevent_event_info(s, event, record);
5405} 5478}
5406 5479
5480void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
5481 struct pevent_record *record, bool use_trace_clock)
5482{
5483 struct event_format *event;
5484
5485 event = pevent_find_event_by_record(pevent, record);
5486 if (!event) {
5487 do_warning("ug! no event found for type %d",
5488 trace_parse_common_type(pevent, record->data));
5489 return;
5490 }
5491
5492 pevent_print_event_task(pevent, s, event, record);
5493 pevent_print_event_time(pevent, s, event, record, use_trace_clock);
5494 pevent_print_event_data(pevent, s, event, record);
5495}
5496
5407static int events_id_cmp(const void *a, const void *b) 5497static int events_id_cmp(const void *a, const void *b)
5408{ 5498{
5409 struct event_format * const * ea = a; 5499 struct event_format * const * ea = a;