used event_by_id
[lttv.git] / ltt / branches / poly / lttv / modules / gui / diskperformance / diskperformance.c
CommitLineData
a4f37ccd 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2005 Peter Ho
3 *
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;
7 *
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.
12 *
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,
16 * MA 02111-1307, USA.
17 */
18
19
20#include <math.h>
21
22#include <glib.h>
23#include <gtk/gtk.h>
24#include <gdk/gdk.h>
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include <ltt/ltt.h>
31#include <ltt/event.h>
32#include <ltt/type.h>
33#include <ltt/trace.h>
34#include <ltt/facility.h>
35#include <lttv/module.h>
36#include <lttv/hook.h>
37#include <lttv/tracecontext.h>
38#include <lttv/state.h>
39#include <lttv/filter.h>
40#include <lttvwindow/lttvwindow.h>
41#include <ltt/time.h>
42
43#include "hDiskPerformanceInsert.xpm"
44
45
46#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
47#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
48#define NO_ITEMS 0
49
50enum{
51 DISKNAME_COLUMN,
52 BYTES_RD_COLUMN,
53 BYTES_RD_SEC_COLUMN,
54 NUM_RD_COLUMN,
55 BYTES_WR_COLUMN,
56 BYTES_WR_SEC_COLUMN,
57 NUM_WR_COLUMN,
58 N_COLUMNS
59};
60enum operation_t {
61 LTTV_READ_OPERATION = 1,
62 LTTV_WRITE_OPERATION
63};
64
65typedef struct _DiskPerformanceData {
66
67 Tab * tab;
68 LttvHooks * event_hooks;
69 LttvHooks * hooks_trace_after;
70 LttvHooks * hooks_trace_before;
71 TimeWindow time_window; // time window
72
73 GtkWidget * scroll_win;
74 /* Model containing list data */
75 GtkListStore *store_m;
76 GtkWidget *hbox_v;
77 /* Widget to display the data in a columned list */
78 GtkWidget *tree_v;
79 /* Selection handler */
80 GtkTreeSelection *select_c;
81
82 GArray *disk_array;
83
84} DiskPerformanceData;
85
86
87typedef struct _lttv_block {
88 guint major_number;
89 guint minor_number;
90 guint size;
91} lttv_block;
92
93typedef struct _lttv_total_block {
94 char diskname[10];
95 guint64 total_bytes_read;
96 guint num_read_operations;
97 guint64 total_bytes_written;
98 guint num_write_operations;
99
100} lttv_total_block;
101
102GSList *g_disk_data_list = NULL ;
103
104DiskPerformanceData *disk_performance_data(Tab *tab);
105static void disk_destroy_walk(gpointer data, gpointer user_data);
106static gboolean parse_event(void *hook_data, void *call_data);
107static gboolean disk_show(void *hook_data, void *call_data);
108static gboolean trace_header(void *hook_data, void *call_data);
109static gboolean disk_update_time_window(void * hook_data, void * call_data);
110static void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data);
111static void tree_v_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data);
112static void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data);
113static void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1, gint arg2, gpointer data);
114static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data);
115static void request_event( DiskPerformanceData *disk_performance);
116void gui_disperformance_free(DiskPerformanceData *event_viewer_data);
117static void get_event_detail(LttEvent *e, LttField *f, GString * s, lttv_block* disk_data);
118static char * major_minor_to_diskname( lttv_block* disk_data);
119static void sum_data(char* diskname, guint size, enum operation_t opt, GArray *disk_array);
120
121GtkWidget *disk_performance(Tab * tab){
122
123 DiskPerformanceData* disk_data = disk_performance_data(tab);
124 if(disk_data)
125 return disk_data->hbox_v;
126 else
127 return NULL;
128
129}
130
131DiskPerformanceData *disk_performance_data(Tab *tab){
132
133 LttTime end;
134 GtkTreeViewColumn *column;
135 GtkCellRenderer *renderer;
136 DiskPerformanceData* disk_data = g_new(DiskPerformanceData,1) ;
137
138 g_info("enter disk_performance_data \n");
139
140 disk_data->tab = tab;
141 disk_data->time_window = lttvwindow_get_time_window(tab);
142
143 disk_data->disk_array = g_array_new(FALSE, FALSE, sizeof(lttv_total_block ));
144
145 lttvwindow_register_time_window_notify(tab,
146 disk_update_time_window,
147 disk_data);
148
149 disk_data->scroll_win = gtk_scrolled_window_new (NULL, NULL);
150 gtk_widget_show (disk_data->scroll_win);
151 gtk_scrolled_window_set_policy(
152 GTK_SCROLLED_WINDOW(disk_data->scroll_win),
153 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC/*GTK_POLICY_NEVER*/);
154
155
156 /* Create a model for storing the data list */
157 disk_data->store_m = gtk_list_store_new (
158 N_COLUMNS, /* Total number of columns */
159 G_TYPE_STRING, /* Diskname */ // to change from INT to string later
160 G_TYPE_INT64, /* Bytes read */
161 G_TYPE_INT64, /* Bytes read/sec */
162 G_TYPE_INT,
163 G_TYPE_INT64, /* bytes written */
164 G_TYPE_INT64, /* bytes written/sec */
165 G_TYPE_INT
166 );
167
168 disk_data->tree_v = gtk_tree_view_new_with_model (GTK_TREE_MODEL (disk_data->store_m));
169
170 g_signal_connect (G_OBJECT (disk_data->tree_v), "size-allocate",
171 G_CALLBACK (tree_v_size_allocate_cb),
172 disk_data);
173 g_signal_connect (G_OBJECT (disk_data->tree_v), "size-request",
174 G_CALLBACK (tree_v_size_request_cb),
175 disk_data);
176 g_signal_connect (G_OBJECT (disk_data->tree_v), "cursor-changed",
177 G_CALLBACK (tree_v_cursor_changed_cb),
178 disk_data);
179 g_signal_connect (G_OBJECT (disk_data->tree_v), "move-cursor",
180 G_CALLBACK (tree_v_move_cursor_cb),
181 disk_data);
182
183 g_object_unref (G_OBJECT (disk_data->store_m));
184
185 renderer = gtk_cell_renderer_text_new ();
186 column = gtk_tree_view_column_new_with_attributes ("DiskName",
187 renderer,
188 "text", DISKNAME_COLUMN,
189 NULL);
190 gtk_tree_view_column_set_alignment (column, 0.0);
191 gtk_tree_view_column_set_fixed_width (column, 45);
192 gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
193
194 renderer = gtk_cell_renderer_text_new ();
195 column = gtk_tree_view_column_new_with_attributes ("BytesRead",
196 renderer,
197 "text", BYTES_RD_COLUMN,
198 NULL);
199 gtk_tree_view_column_set_alignment (column, 0.0);
200 gtk_tree_view_column_set_fixed_width (column, 220);
201 gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
202
203 renderer = gtk_cell_renderer_text_new ();
204 column = gtk_tree_view_column_new_with_attributes ("BytesRead/sec",
205 renderer,
206 "text", BYTES_RD_SEC_COLUMN,
207 NULL);
208 gtk_tree_view_column_set_alignment (column, 1.0);
209 gtk_tree_view_column_set_fixed_width (column, 220);
210 gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
211
212 renderer = gtk_cell_renderer_text_new ();
213 column = gtk_tree_view_column_new_with_attributes ("NumReadOperations",
214 renderer,
215 "text",NUM_RD_COLUMN,
216 NULL);
217 gtk_tree_view_column_set_alignment (column, 1.0);
218 gtk_tree_view_column_set_fixed_width (column, 220);
219 gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
220
221 renderer = gtk_cell_renderer_text_new ();
222 column = gtk_tree_view_column_new_with_attributes ("BytesWritten",
223 renderer,
224 "text", BYTES_WR_COLUMN,
225 NULL);
226 gtk_tree_view_column_set_alignment (column, 0.0);
227 gtk_tree_view_column_set_fixed_width (column, 145);
228 gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
229
230 renderer = gtk_cell_renderer_text_new ();
231 column = gtk_tree_view_column_new_with_attributes ("BytesWritten/sec",
232 renderer,
233 "text", BYTES_WR_SEC_COLUMN,
234 NULL);
235 gtk_tree_view_column_set_alignment (column, 1.0);
236 gtk_tree_view_column_set_fixed_width (column, 220);
237 gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
238
239 renderer = gtk_cell_renderer_text_new ();
240 column = gtk_tree_view_column_new_with_attributes ("NumWriteOperations",
241 renderer,
242 "text",NUM_WR_COLUMN,
243 NULL);
244 gtk_tree_view_column_set_alignment (column, 0.0);
245 gtk_tree_view_column_set_fixed_width (column, 145);
246 gtk_tree_view_append_column (GTK_TREE_VIEW (disk_data->tree_v), column);
247
248 disk_data->select_c = gtk_tree_view_get_selection (GTK_TREE_VIEW (disk_data->tree_v));
249 gtk_tree_selection_set_mode (disk_data->select_c, GTK_SELECTION_SINGLE);
250 g_signal_connect (G_OBJECT (disk_data->select_c), "changed",
251 G_CALLBACK (tree_selection_changed_cb),
252 disk_data);
253
254 gtk_container_add (GTK_CONTAINER (disk_data->scroll_win), disk_data->tree_v);
255
256 disk_data->hbox_v = gtk_hbox_new(0, 0);
257 gtk_box_pack_start(GTK_BOX(disk_data->hbox_v), disk_data->scroll_win, TRUE, TRUE, 0);
258
259 gtk_widget_show(disk_data->hbox_v);
260 gtk_widget_show(disk_data->tree_v);
261
262
263 g_disk_data_list = g_slist_append(g_disk_data_list, disk_data);
264 g_object_set_data_full(G_OBJECT(disk_data->hbox_v),
265 "disk_data",
266 disk_data,
267 (GDestroyNotify)gui_disperformance_free);
268
269 request_event(disk_data);
270 return disk_data;
271}
272
273
274static gboolean disk_show(void *hook_data, void *call_data){
275
276 guint i;
277 lttv_total_block element;
278 GtkTreeIter iter;
279 LttTime time_interval;
280 guint64 time_interval_64;
281 guint64 temp_variable;
282 guint64 bytes_read_per_sec, bytes_written_per_sec;
283 g_info(" diskperformance: disk_show() \n");
284 DiskPerformanceData *disk_performance = (DiskPerformanceData *)hook_data;
285 GArray *disk_array = disk_performance->disk_array;
286 time_interval = ltt_time_sub(disk_performance->time_window.end_time, disk_performance->time_window.start_time);
287
288 time_interval_64 = time_interval.tv_sec;
289 time_interval_64 *= NANOSECONDS_PER_SECOND;
290 time_interval_64 += time_interval.tv_nsec;
291 gtk_list_store_clear(disk_performance->store_m);
292 for(i = 0; i < disk_array->len; i++){
293
294 element = g_array_index(disk_array,lttv_total_block,i);
295 temp_variable = element.total_bytes_read * NANOSECONDS_PER_SECOND;
296 bytes_read_per_sec = (guint64) temp_variable / time_interval_64;
297
298 temp_variable = element.total_bytes_written * NANOSECONDS_PER_SECOND;
299 bytes_written_per_sec = (guint64) temp_variable / time_interval_64;
300
301 gtk_list_store_append (disk_performance->store_m, &iter);
302 gtk_list_store_set (disk_performance->store_m, &iter,
303 DISKNAME_COLUMN, element.diskname,
304 BYTES_RD_COLUMN, element.total_bytes_read,
305 BYTES_RD_SEC_COLUMN,bytes_read_per_sec,
306 NUM_RD_COLUMN, element.num_read_operations,
307 BYTES_WR_COLUMN, element.total_bytes_written,
308 BYTES_WR_SEC_COLUMN, bytes_written_per_sec,
309 NUM_WR_COLUMN, element.num_write_operations,
310 -1);
311
312 }
313 if(disk_performance->disk_array->len)
314 g_array_remove_range (disk_performance->disk_array,0,disk_performance->disk_array->len);
315 return FALSE;
316}
317
318static gboolean trace_header(void *hook_data, void *call_data){
319 return FALSE;
320}
321
322void request_event(DiskPerformanceData *disk_performance){
323
324 disk_performance->event_hooks = lttv_hooks_new();
325 lttv_hooks_add(disk_performance->event_hooks, parse_event, disk_performance, LTTV_PRIO_DEFAULT);
326
327 disk_performance->hooks_trace_after = lttv_hooks_new();
328 lttv_hooks_add(disk_performance->hooks_trace_after, disk_show, disk_performance, LTTV_PRIO_DEFAULT);
329
330 disk_performance->hooks_trace_before = lttv_hooks_new();
331 lttv_hooks_add(disk_performance->hooks_trace_before, trace_header, disk_performance, LTTV_PRIO_DEFAULT);
332
333 EventsRequest *events_request = g_new(EventsRequest, 1);
334 events_request->owner = disk_performance;
335 events_request->viewer_data = disk_performance;
336 events_request->servicing = FALSE;
337 events_request->start_time = disk_performance->time_window.start_time;
338 events_request->start_position = NULL;
339 events_request->stop_flag = FALSE;
340 events_request->end_time = disk_performance->time_window.end_time;
341 events_request->num_events = G_MAXUINT;
342 events_request->end_position = NULL;
343 events_request->trace = 0;
344 events_request->hooks = NULL;
345 events_request->before_chunk_traceset = NULL;
346 events_request->before_chunk_trace = disk_performance->hooks_trace_before;
347 events_request->before_chunk_tracefile= NULL;
348 events_request->event = disk_performance->event_hooks;
349 events_request->event_by_id = NULL;
350 events_request->after_chunk_tracefile = NULL;
351 events_request->after_chunk_trace = NULL;
352 events_request->after_chunk_traceset = NULL;
353 events_request->before_request = NULL;
354 events_request->after_request = disk_performance->hooks_trace_after;
355
356 lttvwindow_events_request(disk_performance->tab, events_request);
357
358}
359
360static gboolean disk_update_time_window(void * hook_data, void * call_data){
361
362 DiskPerformanceData *disk_performance = (DiskPerformanceData *) hook_data;
363 const TimeWindowNotifyData *time_window_nofify_data = ((const TimeWindowNotifyData *)call_data);
364 disk_performance->time_window = *time_window_nofify_data->new_time_window;
365 /*
366 printf("end_time: %ld.%ld\n", disk_performance->time_window.end_time.tv_sec,disk_performance->time_window.end_time.tv_nsec);
367 */
368 Tab *tab = disk_performance->tab;
369 lttvwindow_events_request_remove_all(tab, disk_performance);
370 request_event( disk_performance);
371
372
373 return FALSE;
374}
375
376void tree_v_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer data){
377 g_info("enter tree_v_size_allocate_cb\n");
378}
379
380void tree_v_size_request_cb (GtkWidget *widget, GtkRequisition *requisition, gpointer data){
381
382}
383
384static void tree_v_cursor_changed_cb (GtkWidget *widget, gpointer data){
385
386}
387
388static void tree_v_move_cursor_cb (GtkWidget *widget, GtkMovementStep arg1, gint arg2, gpointer data){
389}
390static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data){
391
392}
393void gui_disperformance_free(DiskPerformanceData *eventdata){
394 Tab *tab = eventdata->tab;
395 g_info("disperformance.c : gui_disperformance_free, %p", eventdata);
396 g_info("%p, %p", eventdata, tab);
397 if(tab != NULL)
398 {
399 g_array_free (eventdata->disk_array, TRUE);
400
401 lttvwindow_unregister_time_window_notify(tab,
402 disk_update_time_window,
403 eventdata);
404
405 lttvwindow_events_request_remove_all(eventdata->tab,
406 eventdata);
407 g_disk_data_list = g_slist_remove(g_disk_data_list, eventdata);
408 }
409 g_free(eventdata);
410 g_info("disperformance.c : gui_disperformance_free end, %p", eventdata);
411}
412
413
414static char * major_minor_to_diskname( lttv_block* disk_data){
415 if (disk_data->major_number == 3 && disk_data->minor_number == 0)
416 return "hda";
417 if (disk_data->major_number == 4 && disk_data->minor_number == 0)
418 return "hdb";
419}
420
421
422static void sum_data(char* diskname, guint size, enum operation_t operation, GArray *disk_array){
423
424 lttv_total_block data;
425 lttv_total_block *element;
426 guint i;
427 gboolean notFound = FALSE;
428
429 memset ((void*)&data, 0,sizeof(lttv_total_block));
430
431 if(disk_array->len == NO_ITEMS){
432 strcpy(data.diskname, diskname);
433 if(operation == LTTV_READ_OPERATION){
434 data.total_bytes_read = size;
435 data.num_read_operations++;
436 }
437 else{
438 data.total_bytes_written = size;
439 data.num_write_operations ++;
440 }
441 g_array_append_val (disk_array, data);
442 }
443 else{
444 for(i = 0; i < disk_array->len; i++){
445 element = &g_array_index(disk_array,lttv_total_block,i);
446 if(strcmp(element->diskname,diskname) == 0){
447 if(operation == LTTV_READ_OPERATION){
448 element->num_read_operations++;
449 element->total_bytes_read += size;
450 }
451 else{
452 element->num_write_operations ++;
453 element->total_bytes_written += size;
454 }
455 notFound = TRUE;
456 }
457 }
458 if(!notFound){
459 strcpy(data.diskname, diskname);
460 if(operation == LTTV_READ_OPERATION){
461 data.total_bytes_read = size;
462 data.num_read_operations ++;
463 }
464 else{
465 data.total_bytes_written = size;
466 data.num_write_operations ++;
467 }
468 g_array_append_val (disk_array, data);
469 }
470 }
471}
472
473static void get_event_detail(LttEvent *e, LttField *f, GString * s, lttv_block* disk_data){
474 LttType *type;
475 LttField *element;
476 //char *name;
477 GQuark name;
478 int nb, i;
479 static int count;
480 type = ltt_field_type(f);
481 switch(ltt_type_class(type)) {
482 case LTT_INT:
483 g_string_append_printf(s, " %ld", ltt_event_get_long_int(e,f));
484 break;
485
486 case LTT_UINT:
487 g_string_append_printf(s, " %lu", ltt_event_get_long_unsigned(e,f));
488 break;
489
490 case LTT_FLOAT:
491 g_string_append_printf(s, " %g", ltt_event_get_double(e,f));
492 break;
493
494 case LTT_STRING:
495 g_string_append_printf(s, " \"%s\"", ltt_event_get_string(e,f));
496 break;
497
498 case LTT_ENUM:
499 g_string_append_printf(s, " %s", ltt_enum_string_get(type,
500 ltt_event_get_unsigned(e,f)-1));
501 break;
502
503 case LTT_ARRAY:
504 case LTT_SEQUENCE:
505 g_string_append_printf(s, " {");
506 nb = ltt_event_field_element_number(e,f);
507 element = ltt_field_element(f);
508 for(i = 0 ; i < nb ; i++) {
509 ltt_event_field_element_select(e,f,i);
510 get_event_detail(e, element, s, disk_data);
511 }
512 g_string_append_printf(s, " }");
513 break;
514
515 case LTT_STRUCT:
516 g_string_append_printf(s, " {");
517 nb = ltt_type_member_number(type);
518 for(i = 0 ; i < nb ; i++) {
519 element = ltt_field_member(f,i);
520 ltt_type_member_type(type, i, &name);
521 g_string_append_printf(s, " %s = ", name);
522 if(i== 0)
523 disk_data->major_number = ltt_event_get_long_unsigned(e, element);
524 if(i== 1)
525 disk_data->minor_number = ltt_event_get_long_unsigned(e, element);
526 if(i==2)
527 disk_data->size = ltt_event_get_long_unsigned(e, element);
528 }
529 g_string_append_printf(s, " }");
530 break;
531
532 case LTT_UNION:
533 g_string_append_printf(s, " {");
534 nb = ltt_type_member_number(type);
535 for(i = 0 ; i < nb ; i++) {
536 element = ltt_field_member(f,i);
537 ltt_type_member_type(type, i, &name);
538 g_string_append_printf(s, " %s = ", name);
539 get_event_detail(e, element, s, disk_data);
540 }
541 g_string_append_printf(s, " }");
542 break;
543
544 }
545
546}
547
548
549gboolean parse_event(void *hook_data, void *call_data){
550
551 static LttTime time_entry, previous_time, event_time;
552 LttEvent *e;
553 LttField *field;
554 LttEventType *event_type;
555 gint i;
556 unsigned cpu_id;
557 lttv_block block_read, block_write;
558 char *diskname;
559
560 gboolean notFound = FALSE;
561 DiskPerformanceData * disk_performance = (DiskPerformanceData *)hook_data;
562 GArray *disk_array = disk_performance->disk_array; // pho
563 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
564 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
565
566 //e = tfc->e;
567 e = ltt_tracefile_get_event(tfc->tf);
568 previous_time = event_time;
569 field = ltt_event_field(e);
570 event_time = ltt_event_time(e);
571 event_type = ltt_event_eventtype(e);
572 cpu_id = ltt_event_cpu_id(e);
573 GString * detail_event = g_string_new("");
574
575 if ((ltt_time_compare(event_time,disk_performance->time_window.start_time) == TRUE) &&
576 (ltt_time_compare(disk_performance->time_window.end_time,event_time) == TRUE)){
577 if (strcmp( g_quark_to_string(ltt_eventtype_name(event_type)),"block_read") == 0) {
578 get_event_detail(e, field, detail_event, &block_read);
579 diskname = major_minor_to_diskname(&block_read);
580 sum_data(diskname, block_read.size,LTTV_READ_OPERATION, disk_array);
581
582 }
583 if (strcmp( g_quark_to_string(ltt_eventtype_name(event_type)),"block_write") == 0) {
584 get_event_detail(e, field, detail_event, &block_write);
585 diskname = major_minor_to_diskname(&block_write);
586 sum_data(diskname, block_write.size,LTTV_WRITE_OPERATION, disk_array);
587 }
588
589 }
590 g_string_free(detail_event, TRUE);
591 return FALSE;
592}
593
594
595void disk_destructor_full(DiskPerformanceData *disk_data)
596{
597
598 if(GTK_IS_WIDGET(disk_data->hbox_v))
599 gtk_widget_destroy(disk_data->hbox_v);
600
601}
602
603static void disk_destroy_walk(gpointer data, gpointer user_data)
604{
605 g_info("Walk destroy GUI disk performance Viewer");
606 disk_destructor_full((DiskPerformanceData*)data);
607}
608
609static void init()
610{
611
612 g_info("Init diskPerformance.c");
613
614 lttvwindow_register_constructor("diskperformance",
615 "/",
616 "Insert Disk Performance",
617 hDiskPerformanceInsert_xpm,
618 "Insert Disk Performance",
619 disk_performance);
620
621}
622
623
624static void destroy()
625{
626 g_info("Destroy diskPerformance");
627 g_slist_foreach(g_disk_data_list, disk_destroy_walk, NULL );
628 g_slist_free(g_disk_data_list);
629
630 lttvwindow_unregister_constructor(disk_performance);
631
632}
633
634
635LTTV_MODULE("diskperformance", "disk info view", \
636 "Produce disk I/O performance", \
637 init, destroy, "lttvwindow")
638
This page took 0.047414 seconds and 4 git commands to generate.