1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
24 #include <ltt/event.h>
26 #include <ltt/trace.h>
28 #include <lttv/lttv.h>
29 #include <lttv/module.h>
30 #include <lttv/tracecontext.h>
31 #include <lttv/hook.h>
32 #include <lttv/state.h>
33 #include <lttv/stats.h>
35 #include <lttvwindow/lttvwindow.h>
36 #include <lttvwindow/lttvwindowtraces.h>
38 #include "hGuiStatisticInsert.xpm"
40 #define PATH_LENGTH 256 /* CHECK */
41 #define MAX_NUMBER_EVENT "max_number_event"
44 //static GPtrArray * statistic_traceset;
46 /** Array containing instanced objects. Used when module is unloaded */
47 static GSList
*g_statistic_viewer_data_list
= NULL
;
49 typedef struct _StatisticViewerData StatisticViewerData
;
51 static void request_background_data(StatisticViewerData
*svd
);
52 GtkWidget
*guistatistic_get_widget(StatisticViewerData
*svd
);
54 //! Statistic Viewer's constructor hook
55 GtkWidget
*h_gui_statistic(Tab
*tab
, LttvTracesetSelector
* s
, char * key
);
56 //! Statistic Viewer's constructor
57 StatisticViewerData
*gui_statistic(Tab
*tab
);
58 //! Statistic Viewer's destructor
59 void gui_statistic_destructor(StatisticViewerData
*statistic_viewer_data
);
61 void grab_focus(GtkWidget
*widget
, gpointer data
);
62 static void tree_selection_changed_cb (GtkTreeSelection
*selection
, gpointer data
);
64 void statistic_destroy_hash_key(gpointer key
);
65 void statistic_destroy_hash_data(gpointer data
);
67 void show_traceset_stats(StatisticViewerData
* statistic_viewer_data
);
68 void show_tree(StatisticViewerData
* statistic_viewer_data
,
69 LttvAttribute
* stats
, GtkTreeIter
* parent
);
70 void show_statistic(StatisticViewerData
* statistic_viewer_data
,
71 LttvAttribute
* stats
, GtkTextBuffer
* buf
);
74 gboolean
statistic_traceset_changed(void * hook_data
, void * call_data
);
75 //void statistic_add_context_hooks(StatisticViewerData * statistic_viewer_data,
76 // LttvTracesetContext * tsc);
77 //void statistic_remove_context_hooks(StatisticViewerData *statistic_viewer_data,
78 // LttvTracesetContext * tsc);
80 //gboolean statistic_insert_traceset_stats(void * stats);
88 struct _StatisticViewerData
{
90 //LttvTracesetStats * stats;
93 //gboolean shown; //indicate if the statistic is shown or not
97 GtkTreeStore
* store_m
;
100 //scroll window containing Tree View
101 GtkWidget
* scroll_win_tree
;
104 //scroll window containing Text View
105 GtkWidget
* scroll_win_text
;
108 GtkTreeSelection
*select_c
;
111 GHashTable
*statistic_hash
;
117 /* Action to do when background computation completed.
119 * Eventually, will have to check that every requested traces are finished
120 * before doing the redraw. It will save unnecessary processor usage.
123 static gint
background_ready(void *hook_data
, void *call_data
)
125 StatisticViewerData
*svd
= (StatisticViewerData
*)hook_data
;
127 LttvTrace
*trace
= (LttvTrace
*)call_data
;
129 g_debug("statistics viewer : background computation data ready.");
131 gtk_tree_store_clear (svd
->store_m
);
133 lttv_stats_sum_traceset(lttvwindow_get_traceset_stats(tab
));
134 show_traceset_stats(svd
);
139 /* Request background computation. Verify if it is in progress or ready first.
141 * Right now, for all loaded traces.
143 * Later : must be only for each trace in the tab's traceset.
145 static void request_background_data(StatisticViewerData
*svd
)
147 gint num_traces
= lttvwindowtraces_get_number();
151 LttvHooks
*background_ready_hook
=
153 lttv_hooks_add(background_ready_hook
, background_ready
, svd
,
156 for(i
=0;i
<num_traces
;i
++) {
157 trace
= lttvwindowtraces_get_trace(i
);
159 if(lttvwindowtraces_get_ready(g_quark_from_string("stats"),trace
)==FALSE
) {
161 if(lttvwindowtraces_get_in_progress(g_quark_from_string("stats"),
163 /* We first remove requests that could have been done for the same
164 * information. Happens when two viewers ask for it before servicing
167 lttvwindowtraces_background_request_remove(trace
, "stats");
168 lttvwindowtraces_background_request_queue(trace
,
170 lttvwindowtraces_background_notify_queue(svd
,
174 background_ready_hook
);
175 } else { /* in progress */
177 lttvwindowtraces_background_notify_current(svd
,
181 background_ready_hook
);
186 lttv_hooks_destroy(background_ready_hook
);
190 GtkWidget
*guistatistic_get_widget(StatisticViewerData
*svd
)
192 return svd
->hpaned_v
;
197 gui_statistic_destructor(StatisticViewerData
*statistic_viewer_data
)
199 Tab
*tab
= statistic_viewer_data
->tab
;
201 /* May already been done by GTK window closing */
202 if(GTK_IS_WIDGET(guistatistic_get_widget(statistic_viewer_data
))){
203 g_info("widget still exists");
206 lttvwindow_unregister_traceset_notify(statistic_viewer_data
->tab
,
207 statistic_traceset_changed
,
208 statistic_viewer_data
);
210 lttvwindowtraces_background_notify_remove(statistic_viewer_data
);
212 g_hash_table_destroy(statistic_viewer_data
->statistic_hash
);
213 g_statistic_viewer_data_list
=
214 g_slist_remove(g_statistic_viewer_data_list
, statistic_viewer_data
);
215 g_free(statistic_viewer_data
);
220 * Statistic Viewer's constructor hook
222 * This constructor is given as a parameter to the menuitem and toolbar button
223 * registration. It creates the list.
224 * @param parent_window A pointer to the parent window.
225 * @return The widget created.
228 h_gui_statistic(Tab
*tab
, LttvTracesetSelector
* s
, char * key
)
230 StatisticViewerData
* statistic_viewer_data
= gui_statistic(tab
) ;
232 if(statistic_viewer_data
)
233 return guistatistic_get_widget(statistic_viewer_data
);
239 gboolean
statistic_insert_traceset_stats(void * stats
)
244 len
= statistic_traceset
->len
;
246 s
= g_ptr_array_index(statistic_traceset
, i
);
247 if(s
== stats
) break;
250 g_ptr_array_add(statistic_traceset
, stats
);
258 * Statistic Viewer's constructor
260 * This constructor is used to create StatisticViewerData data structure.
261 * @return The Statistic viewer data created.
263 StatisticViewerData
*
264 gui_statistic(Tab
*tab
)
266 GtkCellRenderer
*renderer
;
267 GtkTreeViewColumn
*column
;
269 StatisticViewerData
* statistic_viewer_data
= g_new(StatisticViewerData
,1);
271 statistic_viewer_data
->tab
= tab
;
272 // statistic_viewer_data->stats =
273 // lttvwindow_get_traceset_stats(statistic_viewer_data->tab);
274 // statistic_viewer_data->calculate_stats =
275 // statistic_insert_traceset_stats((void *)statistic_viewer_data->stats);
277 lttvwindow_register_traceset_notify(statistic_viewer_data
->tab
,
278 statistic_traceset_changed
,
279 statistic_viewer_data
);
280 request_background_data(statistic_viewer_data
);
282 statistic_viewer_data
->statistic_hash
= g_hash_table_new_full(g_str_hash
,
284 statistic_destroy_hash_key
,
285 statistic_destroy_hash_data
);
287 statistic_viewer_data
->hpaned_v
= gtk_hpaned_new();
288 statistic_viewer_data
->store_m
= gtk_tree_store_new (N_COLUMNS
, G_TYPE_STRING
);
289 statistic_viewer_data
->tree_v
=
290 gtk_tree_view_new_with_model (
291 GTK_TREE_MODEL (statistic_viewer_data
->store_m
));
292 g_object_unref (G_OBJECT (statistic_viewer_data
->store_m
));
294 g_signal_connect (G_OBJECT (statistic_viewer_data
->tree_v
), "grab-focus",
295 G_CALLBACK (grab_focus
),
296 statistic_viewer_data
);
298 // Setup the selection handler
299 statistic_viewer_data
->select_c
= gtk_tree_view_get_selection (GTK_TREE_VIEW (statistic_viewer_data
->tree_v
));
300 gtk_tree_selection_set_mode (statistic_viewer_data
->select_c
, GTK_SELECTION_SINGLE
);
301 g_signal_connect (G_OBJECT (statistic_viewer_data
->select_c
), "changed",
302 G_CALLBACK (tree_selection_changed_cb
),
303 statistic_viewer_data
);
305 renderer
= gtk_cell_renderer_text_new ();
306 column
= gtk_tree_view_column_new_with_attributes ("Statistic Name",
310 gtk_tree_view_column_set_alignment (column
, 0.0);
311 // gtk_tree_view_column_set_fixed_width (column, 45);
312 gtk_tree_view_append_column (GTK_TREE_VIEW (statistic_viewer_data
->tree_v
), column
);
315 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (statistic_viewer_data
->tree_v
), FALSE
);
317 statistic_viewer_data
->scroll_win_tree
= gtk_scrolled_window_new (NULL
, NULL
);
318 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(statistic_viewer_data
->scroll_win_tree
),
319 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
321 gtk_container_add (GTK_CONTAINER (statistic_viewer_data
->scroll_win_tree
), statistic_viewer_data
->tree_v
);
322 gtk_paned_pack1(GTK_PANED(statistic_viewer_data
->hpaned_v
),statistic_viewer_data
->scroll_win_tree
, TRUE
, FALSE
);
323 gtk_paned_set_position(GTK_PANED(statistic_viewer_data
->hpaned_v
), 160);
325 statistic_viewer_data
->scroll_win_text
= gtk_scrolled_window_new (NULL
, NULL
);
326 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(statistic_viewer_data
->scroll_win_text
),
327 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
329 statistic_viewer_data
->text_v
= gtk_text_view_new ();
330 g_signal_connect (G_OBJECT (statistic_viewer_data
->text_v
), "grab-focus",
331 G_CALLBACK (grab_focus
),
332 statistic_viewer_data
);
334 gtk_text_view_set_editable(GTK_TEXT_VIEW(statistic_viewer_data
->text_v
),FALSE
);
335 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(statistic_viewer_data
->text_v
),FALSE
);
336 gtk_container_add (GTK_CONTAINER (statistic_viewer_data
->scroll_win_text
), statistic_viewer_data
->text_v
);
337 gtk_paned_pack2(GTK_PANED(statistic_viewer_data
->hpaned_v
), statistic_viewer_data
->scroll_win_text
, TRUE
, FALSE
);
339 gtk_widget_show(statistic_viewer_data
->scroll_win_tree
);
340 gtk_widget_show(statistic_viewer_data
->scroll_win_text
);
341 gtk_widget_show(statistic_viewer_data
->tree_v
);
342 gtk_widget_show(statistic_viewer_data
->text_v
);
343 gtk_widget_show(statistic_viewer_data
->hpaned_v
);
345 g_object_set_data_full(
346 G_OBJECT(guistatistic_get_widget(statistic_viewer_data
)),
347 "statistic_viewer_data",
348 statistic_viewer_data
,
349 (GDestroyNotify
)gui_statistic_destructor
);
351 /* Add the object's information to the module's array */
352 g_statistic_viewer_data_list
= g_slist_append(
353 g_statistic_viewer_data_list
,
354 statistic_viewer_data
);
356 return statistic_viewer_data
;
359 void grab_focus(GtkWidget
*widget
, gpointer data
)
361 StatisticViewerData
*statistic_viewer_data
= (StatisticViewerData
*)data
;
362 Tab
* tab
= statistic_viewer_data
->tab
;
363 lttvwindow_report_focus(tab
, guistatistic_get_widget(statistic_viewer_data
));
367 tree_selection_changed_cb (GtkTreeSelection
*selection
, gpointer data
)
369 StatisticViewerData
*statistic_viewer_data
= (StatisticViewerData
*)data
;
371 GtkTreeModel
*model
= GTK_TREE_MODEL(statistic_viewer_data
->store_m
);
376 GtkTextIter text_iter
;
377 LttvAttribute
* stats
;
379 if (gtk_tree_selection_get_selected (selection
, &model
, &iter
))
381 gtk_tree_model_get (model
, &iter
, NAME_COLUMN
, &event
, -1);
383 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(model
),&iter
);
384 str
= gtk_tree_path_to_string (path
);
385 stats
= (LttvAttribute
*)g_hash_table_lookup (statistic_viewer_data
->statistic_hash
,str
);
388 buf
= gtk_text_view_get_buffer((GtkTextView
*)statistic_viewer_data
->text_v
);
389 gtk_text_buffer_set_text(buf
,"Statistic for '", -1);
390 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
391 gtk_text_buffer_insert(buf
, &text_iter
, event
, strlen(event
));
392 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
393 gtk_text_buffer_insert(buf
, &text_iter
, "' :\n\n",5);
395 show_statistic(statistic_viewer_data
, stats
, buf
);
401 void statistic_destroy_hash_key(gpointer key
)
406 void statistic_destroy_hash_data(gpointer data
)
416 void show_traceset_stats(StatisticViewerData
* statistic_viewer_data
)
418 Tab
*tab
= statistic_viewer_data
->tab
;
422 LttSystemDescription
*desc
;
423 LttvTracesetStats
* tscs
= lttvwindow_get_traceset_stats(tab
);
424 gchar
* str
, trace_str
[PATH_LENGTH
];
427 GtkTreeStore
* store
= statistic_viewer_data
->store_m
;
429 if(tscs
->stats
== NULL
) return;
431 lttv_attribute_write_xml(tscs
->stats
, stdout
, 1, 4);
434 ts
= tscs
->parent
.parent
.ts
;
435 nb
= lttv_traceset_number(ts
);
438 gtk_tree_store_append (store
, &iter
, NULL
);
439 gtk_tree_store_set (store
, &iter
,
440 NAME_COLUMN
, "Traceset statistics",
442 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
443 str
= gtk_tree_path_to_string (path
);
444 g_hash_table_insert(statistic_viewer_data
->statistic_hash
,
445 (gpointer
)str
, tscs
->stats
);
446 show_tree(statistic_viewer_data
, tscs
->stats
, &iter
);
448 //show stats for all traces
449 for(i
= 0 ; i
< nb
; i
++) {
450 tcs
= (LttvTraceStats
*)(LTTV_TRACESET_CONTEXT(tscs
)->traces
[i
]);
451 desc
= ltt_trace_system_description(tcs
->parent
.parent
.t
);
452 sprintf(trace_str
, "Trace on system %s at time %d secs",
453 ltt_trace_system_description_node_name(desc
),
454 (ltt_trace_system_description_trace_start_time(desc
)).tv_sec
);
456 gtk_tree_store_append (store
, &iter
, NULL
);
457 gtk_tree_store_set (store
, &iter
,NAME_COLUMN
,trace_str
,-1);
458 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
459 str
= gtk_tree_path_to_string (path
);
460 g_hash_table_insert(statistic_viewer_data
->statistic_hash
,
461 (gpointer
)str
,tcs
->stats
);
462 show_tree(statistic_viewer_data
, tcs
->stats
, &iter
);
464 lttv_attribute_write_xml(tcs
->stats
, stdout
, 3, 4);
469 void show_tree(StatisticViewerData
* statistic_viewer_data
,
470 LttvAttribute
* stats
, GtkTreeIter
* parent
)
473 LttvAttribute
*subtree
;
474 LttvAttributeName name
;
475 LttvAttributeValue value
;
476 LttvAttributeType type
;
477 gchar
* str
, dir_str
[PATH_LENGTH
];
480 GtkTreeStore
* store
= statistic_viewer_data
->store_m
;
482 nb
= lttv_attribute_get_number(stats
);
483 for(i
= 0 ; i
< nb
; i
++) {
484 type
= lttv_attribute_get(stats
, i
, &name
, &value
);
487 if(LTTV_IS_ATTRIBUTE(*(value
.v_gobject
))) {
488 sprintf(dir_str
, "%s", g_quark_to_string(name
));
489 subtree
= (LttvAttribute
*)*(value
.v_gobject
);
490 gtk_tree_store_append (store
, &iter
, parent
);
491 gtk_tree_store_set (store
, &iter
,NAME_COLUMN
,dir_str
,-1);
492 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
493 str
= gtk_tree_path_to_string (path
);
494 g_hash_table_insert(statistic_viewer_data
->statistic_hash
,
495 (gpointer
)str
, subtree
);
496 show_tree(statistic_viewer_data
, subtree
, &iter
);
505 void show_statistic(StatisticViewerData
* statistic_viewer_data
,
506 LttvAttribute
* stats
, GtkTextBuffer
* buf
)
509 LttvAttribute
*subtree
;
510 LttvAttributeName name
;
511 LttvAttributeValue value
;
512 LttvAttributeType type
;
513 gchar type_name
[PATH_LENGTH
], type_value
[PATH_LENGTH
];
514 GtkTextIter text_iter
;
517 nb
= lttv_attribute_get_number(stats
);
518 for(i
= 0 ; i
< nb
; i
++) {
519 type
= lttv_attribute_get(stats
, i
, &name
, &value
);
520 sprintf(type_name
,"%s", g_quark_to_string(name
));
521 type_value
[0] = '\0';
524 sprintf(type_value
, " : %d\n", *value
.v_int
);
527 sprintf(type_value
, " : %u\n", *value
.v_uint
);
530 sprintf(type_value
, " : %ld\n", *value
.v_long
);
533 sprintf(type_value
, " : %lu\n", *value
.v_ulong
);
536 sprintf(type_value
, " : %f\n", (double)*value
.v_float
);
539 sprintf(type_value
, " : %f\n", *value
.v_double
);
542 sprintf(type_value
, " : %10u.%09u\n", value
.v_time
->tv_sec
,
543 value
.v_time
->tv_nsec
);
546 sprintf(type_value
, " : POINTER\n");
549 sprintf(type_value
, " : %s\n", *value
.v_string
);
554 if(strlen(type_value
)){
556 strcat(type_name
,type_value
);
557 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
558 gtk_text_buffer_insert(buf
, &text_iter
, type_name
, strlen(type_name
));
563 sprintf(type_value
, "No statistic information in this directory.\nCheck in subdirectories please.\n");
564 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
565 gtk_text_buffer_insert(buf
, &text_iter
, type_value
, strlen(type_value
));
570 gboolean
statistic_traceset_changed(void * hook_data
, void * call_data
)
572 StatisticViewerData
*statistic_viewer_data
= (StatisticViewerData
*) hook_data
;
574 request_background_data(statistic_viewer_data
);
580 void statistic_add_context_hooks(StatisticViewerData
* statistic_viewer_data
,
581 LttvTracesetContext
* tsc
)
583 gint i
, j
, nbi
, nb_tracefile
;
585 LttvTraceContext
*tc
;
586 LttvTracefileContext
*tfc
;
587 LttvTracesetSelector
* ts_s
;
588 LttvTraceSelector
* t_s
;
589 LttvTracefileSelector
* tf_s
;
592 ts_s
= (LttvTracesetSelector
*)g_object_get_data(G_OBJECT(statistic_viewer_data
->hpaned_v
),
593 statistic_viewer_data
->filter_key
);
595 //if there are hooks for traceset, add them here
597 nbi
= lttv_traceset_number(tsc
->ts
);
598 for(i
= 0 ; i
< nbi
; i
++) {
599 t_s
= lttv_traceset_selector_trace_get(ts_s
,i
);
600 selected
= lttv_trace_selector_get_selected(t_s
);
601 if(!selected
) continue;
604 //if there are hooks for trace, add them here
606 nb_tracefile
= ltt_trace_control_tracefile_number(trace
) +
607 ltt_trace_per_cpu_tracefile_number(trace
);
609 for(j
= 0 ; j
< nb_tracefile
; j
++) {
610 tf_s
= lttv_trace_selector_tracefile_get(t_s
,j
);
611 selected
= lttv_tracefile_selector_get_selected(tf_s
);
612 if(!selected
) continue;
613 tfc
= tc
->tracefiles
[j
];
615 //if there are hooks for tracefile, add them here
616 // lttv_tracefile_context_add_hooks(tfc, NULL,NULL,NULL,NULL,
617 // statistic_viewer_data->before_event_hooks,NULL);
621 lttv_stats_add_event_hooks(LTTV_TRACESET_STATS(tsc
));
625 void statistic_remove_context_hooks(StatisticViewerData
* statistic_viewer_data
,
626 LttvTracesetContext
* tsc
)
628 gint i
, j
, nbi
, nb_tracefile
;
630 LttvTraceContext
*tc
;
631 LttvTracefileContext
*tfc
;
632 LttvTracesetSelector
* ts_s
;
633 LttvTraceSelector
* t_s
;
634 LttvTracefileSelector
* tf_s
;
637 ts_s
= (LttvTracesetSelector
*)g_object_get_data(G_OBJECT(statistic_viewer_data
->hpaned_v
),
638 statistic_viewer_data
->filter_key
);
640 //if there are hooks for traceset, remove them here
642 nbi
= lttv_traceset_number(tsc
->ts
);
643 for(i
= 0 ; i
< nbi
; i
++) {
644 t_s
= lttv_traceset_selector_trace_get(ts_s
,i
);
645 selected
= lttv_trace_selector_get_selected(t_s
);
646 if(!selected
) continue;
649 //if there are hooks for trace, remove them here
651 nb_tracefile
= ltt_trace_control_tracefile_number(trace
) +
652 ltt_trace_per_cpu_tracefile_number(trace
);
654 for(j
= 0 ; j
< nb_tracefile
; j
++) {
655 tf_s
= lttv_trace_selector_tracefile_get(t_s
,j
);
656 selected
= lttv_tracefile_selector_get_selected(tf_s
);
657 if(!selected
) continue;
658 tfc
= tc
->tracefiles
[j
];
660 //if there are hooks for tracefile, remove them here
661 // lttv_tracefile_context_remove_hooks(tfc, NULL,NULL,NULL,NULL,
662 // statistic_viewer_data->before_event_hooks,NULL);
666 lttv_stats_remove_event_hooks(LTTV_TRACESET_STATS(tsc
));
671 * plugin's init function
673 * This function initializes the Statistic Viewer functionnality through the
678 lttvwindow_register_constructor("/",
679 "Insert Statistic Viewer",
680 hGuiStatisticInsert_xpm
,
681 "Insert Statistic Viewer",
685 void statistic_destroy_walk(gpointer data
, gpointer user_data
)
687 StatisticViewerData
*svd
= (StatisticViewerData
*)data
;
689 g_debug("CFV.c : statistic_destroy_walk, %p", svd
);
690 /* May already have been done by GTK window closing */
691 if(GTK_IS_WIDGET(guistatistic_get_widget(svd
)))
692 gtk_widget_destroy(guistatistic_get_widget(svd
));
696 * plugin's destroy function
698 * This function releases the memory reserved by the module and unregisters
699 * everything that has been registered in the gtkTraceSet API.
701 static void destroy() {
704 g_slist_foreach(g_statistic_viewer_data_list
, statistic_destroy_walk
, NULL
);
705 g_slist_free(g_statistic_viewer_data_list
);
707 lttvwindow_unregister_constructor(h_gui_statistic
);
712 LTTV_MODULE("guistatistics", "Statistics viewer", \
713 "Graphical module to view statistics about processes, CPUs and systems", \
714 init
, destroy
, "lttvwindow")