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