aboutsummaryrefslogtreecommitdiffstats
path: root/trace-view-store.c
diff options
context:
space:
mode:
Diffstat (limited to 'trace-view-store.c')
-rw-r--r--trace-view-store.c221
1 files changed, 217 insertions, 4 deletions
diff --git a/trace-view-store.c b/trace-view-store.c
index be86662..9ad2073 100644
--- a/trace-view-store.c
+++ b/trace-view-store.c
@@ -1,5 +1,6 @@
1#include "trace-view-store.h" 1#include "trace-view-store.h"
2#include <stdlib.h> 2#include <stdlib.h>
3#include <string.h>
3 4
4#include "cpu.h" 5#include "cpu.h"
5 6
@@ -207,6 +208,8 @@ trace_view_store_finalize (GObject *object)
207 g_free(store->rows); 208 g_free(store->rows);
208 g_free(store->cpu_items); 209 g_free(store->cpu_items);
209 210
211 filter_task_hash_free(store->task_filter);
212
210 if (store->spin) { 213 if (store->spin) {
211 gtk_widget_destroy(store->spin); 214 gtk_widget_destroy(store->spin);
212 store->spin = NULL; 215 store->spin = NULL;
@@ -490,6 +493,183 @@ trace_view_store_get_value (GtkTreeModel *tree_model,
490 } 493 }
491} 494}
492 495
496int str_cmp(const void *a, const void *b)
497{
498 char * const * sa = a;
499 char * const * sb = b;
500
501 return strcmp(*sa, *sb);
502}
503
504int id_cmp(const void *a, const void *b)
505{
506 const gint *ia = a;
507 const gint *ib = b;
508
509 if (*ia > *ib)
510 return 1;
511 if (*ia < *ib)
512 return -1;
513 return 0;
514}
515
516gboolean trace_view_store_system_enabled(TraceViewStore *store, const gchar *system)
517{
518 const gchar **sys = &system;
519
520 g_return_val_if_fail (TRACE_VIEW_IS_LIST (store), FALSE);
521
522 if (store->all_events)
523 return TRUE;
524
525 if (!store->systems)
526 return FALSE;
527
528 sys = bsearch(sys, store->systems, store->systems_size,
529 sizeof(system), str_cmp);
530
531 return sys != NULL;
532}
533
534gboolean trace_view_store_event_enabled(TraceViewStore *store, gint event_id)
535{
536 gint key = event_id;
537 gint *ret;
538
539 g_return_val_if_fail (TRACE_VIEW_IS_LIST (store), FALSE);
540
541 if (store->all_events)
542 return TRUE;
543
544 /* TODO: search for the system of the event? */
545
546 if (!store->event_types)
547 return FALSE;
548
549 ret = bsearch(&key, store->event_types, store->event_types_size,
550 sizeof(gint), id_cmp);
551
552 return ret != NULL;
553}
554
555void trace_view_store_set_all_events_enabled(TraceViewStore *store)
556{
557 gint i;
558
559 g_return_if_fail (TRACE_VIEW_IS_LIST (store));
560
561 if (store->all_events)
562 return;
563
564 if (store->systems_size) {
565 for (i = 0; i < store->systems_size; i++)
566 g_free(store->systems[i]);
567
568 g_free(store->systems);
569 store->systems = NULL;
570 store->systems_size = 0;
571 }
572
573 g_free(store->event_types);
574 store->event_types = NULL;
575 store->event_types_size = 0;
576
577 store->all_events = 1;
578}
579
580static void remove_system(TraceViewStore *store, const gchar *system)
581{
582 const gchar **sys = &system;
583
584 if (!store->systems)
585 return;
586
587 sys = bsearch(sys, store->systems, store->systems_size,
588 sizeof(system), str_cmp);
589
590 if (!sys)
591 return;
592
593 g_free(*((gchar **)sys));
594
595 g_memmove(sys, sys+1, sizeof(*sys) * (store->systems_size -
596 ((gchar **)sys - store->systems)));
597 store->systems_size--;
598 store->systems[store->systems_size] = NULL;
599}
600
601void trace_view_store_set_system_enabled(TraceViewStore *store, const gchar *system)
602{
603 g_return_if_fail (TRACE_VIEW_IS_LIST (store));
604
605 if (store->all_events)
606 /*
607 * We are adding a new filter, so this is the
608 * only system enabled.
609 */
610 store->all_events = 0;
611
612 if (trace_view_store_system_enabled(store, system))
613 return;
614
615 if (!store->systems) {
616 store->systems = g_new0(gchar *, 2);
617 store->systems[0] = g_strdup(system);
618 store->systems_size++;
619 return;
620 }
621
622 store->systems_size++;
623 store->systems = g_realloc(store->systems,
624 sizeof(*store->systems) * (store->systems_size+1));
625 store->systems[store->systems_size - 1] = g_strdup(system);
626 store->systems[store->systems_size] = NULL;
627
628 qsort(store->systems, store->systems_size, sizeof(gchar *), str_cmp);
629}
630
631
632void trace_view_store_set_event_enabled(TraceViewStore *store, gint event_id)
633{
634 struct pevent *pevent;
635 struct event_format *event;
636
637 g_return_if_fail (TRACE_VIEW_IS_LIST (store));
638
639 pevent = tracecmd_get_pevent(store->handle);
640 event = pevent_find_event(pevent, event_id);
641 if (!event)
642 return;
643
644 if (store->all_events)
645 /*
646 * We are adding a new filter, so this is the
647 * only system enabled.
648 */
649 store->all_events = 0;
650
651 remove_system(store, event->system);
652
653 if (trace_view_store_event_enabled(store, event_id))
654 return;
655
656 if (!store->event_types) {
657 store->event_types = g_new0(gint, 2);
658 store->event_types[0] = event_id;
659 store->event_types[1] = -1;
660 store->event_types_size++;
661 return;
662 }
663
664 store->event_types_size++;
665 store->event_types = g_realloc(store->event_types,
666 sizeof(*store->event_types) * (store->event_types_size+1));
667 store->event_types[store->event_types_size - 1] = event_id;
668 store->event_types[store->event_types_size] = -1;
669
670 qsort(store->event_types, store->event_types_size, sizeof(gint), id_cmp);
671}
672
493 673
494/***************************************************************************** 674/*****************************************************************************
495 * 675 *
@@ -1059,7 +1239,7 @@ gint get_next_pid(TraceViewStore *store, struct pevent *pevent, struct record *r
1059 unsigned long long val; 1239 unsigned long long val;
1060 int ret; 1240 int ret;
1061 1241
1062 ret = pevent_read_number_field(store->sched_switch_next_field, record, &val); 1242 ret = pevent_read_number_field(store->sched_switch_next_field, record->data, &val);
1063 1243
1064 return val; 1244 return val;
1065} 1245}
@@ -1067,14 +1247,23 @@ gint get_next_pid(TraceViewStore *store, struct pevent *pevent, struct record *r
1067void trace_view_store_filter_tasks(TraceViewStore *store, struct filter_task *filter) 1247void trace_view_store_filter_tasks(TraceViewStore *store, struct filter_task *filter)
1068{ 1248{
1069 struct tracecmd_input *handle; 1249 struct tracecmd_input *handle;
1250 struct event_format *event;
1070 struct pevent *pevent; 1251 struct pevent *pevent;
1071 struct record *record; 1252 struct record *record;
1253 gint last_event_id = -1;
1254 gint event_id;
1072 gint pid; 1255 gint pid;
1073 gint cpu; 1256 gint cpu;
1074 gint i; 1257 gint i;
1075 1258
1076 g_return_if_fail (TRACE_VIEW_IS_LIST (store)); 1259 g_return_if_fail (TRACE_VIEW_IS_LIST (store));
1077 1260
1261 /* We may pass in the store->task_filter. Don't free it if we do */
1262 if (store->task_filter && store->task_filter != filter)
1263 filter_task_hash_free(store->task_filter);
1264
1265 store->task_filter = filter_task_hash_copy(filter);
1266
1078 handle = store->handle; 1267 handle = store->handle;
1079 pevent = tracecmd_get_pevent(store->handle); 1268 pevent = tracecmd_get_pevent(store->handle);
1080 1269
@@ -1094,7 +1283,22 @@ void trace_view_store_filter_tasks(TraceViewStore *store, struct filter_task *fi
1094 1283
1095 g_assert(record->offset == store->cpu_list[cpu][i].offset); 1284 g_assert(record->offset == store->cpu_list[cpu][i].offset);
1096 1285
1097 /* TODO: put event filter check here */ 1286 /* The record may be filtered by the events */
1287 if (!store->all_events) {
1288 event_id = pevent_data_type(pevent, record);
1289 if (last_event_id != event_id) {
1290 /* optimize: only search event when new */
1291 event = pevent_find_event(pevent, event_id);
1292 g_assert(event);
1293 }
1294 last_event_id = event_id;
1295 if (!trace_view_store_system_enabled(store, event->system) &&
1296 !trace_view_store_event_enabled(store, event_id)) {
1297 store->cpu_list[cpu][i].visible = 0;
1298 goto skip;
1299 }
1300 }
1301
1098 pid = pevent_data_pid(pevent, record); 1302 pid = pevent_data_pid(pevent, record);
1099 if (!filter || filter_task_find_pid(filter, pid)) 1303 if (!filter || filter_task_find_pid(filter, pid))
1100 store->cpu_list[cpu][i].visible = 1; 1304 store->cpu_list[cpu][i].visible = 1;
@@ -1108,10 +1312,11 @@ void trace_view_store_filter_tasks(TraceViewStore *store, struct filter_task *fi
1108 store->cpu_list[cpu][i].visible = 1; 1312 store->cpu_list[cpu][i].visible = 1;
1109 else 1313 else
1110 store->cpu_list[cpu][i].visible = 0; 1314 store->cpu_list[cpu][i].visible = 0;
1111 } 1315 } else
1112 store->cpu_list[cpu][i].visible = 0; 1316 store->cpu_list[cpu][i].visible = 0;
1113 } 1317 }
1114 1318
1319 skip:
1115 free_record(record); 1320 free_record(record);
1116 record = tracecmd_read_data(handle, cpu); 1321 record = tracecmd_read_data(handle, cpu);
1117 } 1322 }
@@ -1121,6 +1326,14 @@ void trace_view_store_filter_tasks(TraceViewStore *store, struct filter_task *fi
1121 merge_sort_rows_ts(store); 1326 merge_sort_rows_ts(store);
1122} 1327}
1123 1328
1329void trace_view_store_update_filter(TraceViewStore *store)
1330{
1331 g_return_if_fail (TRACE_VIEW_IS_LIST (store));
1332
1333 trace_view_store_filter_tasks(store, store->task_filter);
1334}
1335
1336
1124/***************************************************************************** 1337/*****************************************************************************
1125 * 1338 *
1126 * trace_view_store_append_record: Empty lists are boring. This function can 1339 * trace_view_store_append_record: Empty lists are boring. This function can