update roadmap
[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>
a4f37ccd 25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
a4f37ccd 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)
4ea3dbbf 46#define TRACE_NUMBER 0
a4f37ccd 47#define NO_ITEMS 0
48
49enum{
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};
4ea3dbbf 59
a4f37ccd 60enum operation_t {
61 LTTV_READ_OPERATION = 1,
62 LTTV_WRITE_OPERATION
63};
64
65typedef struct _DiskPerformanceData {
66
67 Tab * tab;
4ea3dbbf 68
a4f37ccd 69 LttvHooks * hooks_trace_after;
4ea3dbbf 70
a4f37ccd 71 LttvHooks * hooks_trace_before;
4ea3dbbf 72 /* time window */
73 TimeWindow time_window;
a4f37ccd 74
75 GtkWidget * scroll_win;
4ea3dbbf 76
a4f37ccd 77 /* Model containing list data */
78 GtkListStore *store_m;
4ea3dbbf 79
a4f37ccd 80 GtkWidget *hbox_v;
4ea3dbbf 81
a4f37ccd 82 /* Widget to display the data in a columned list */
83 GtkWidget *tree_v;
4ea3dbbf 84
a4f37ccd 85 /* Selection handler */
86 GtkTreeSelection *select_c;
87
88 GArray *disk_array;
89
4ea3dbbf 90 LttvHooksById * event_by_id_hooks;
91
a4f37ccd 92} DiskPerformanceData;
93
94
95typedef struct _lttv_block {
96 guint major_number;
97 guint minor_number;
98 guint size;
99} lttv_block;
100
101typedef 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
110GSList *g_disk_data_list = NULL ;
111
4ea3dbbf 112
113
114/* facility */
115GQuark LTT_FACILITY_BLOCK;
116
117/* events */
118GQuark LTT_EVENT_BLOCK_READ;
119GQuark LTT_EVENT_BLOCK_WRITE;
120
121static DiskPerformanceData *disk_performance_data(Tab *tab);
a4f37ccd 122static void disk_destroy_walk(gpointer data, gpointer user_data);
a4f37ccd 123static gboolean disk_show(void *hook_data, void *call_data);
124static gboolean trace_header(void *hook_data, void *call_data);
125static gboolean disk_update_time_window(void * hook_data, void * call_data);
a4f37ccd 126static void request_event( DiskPerformanceData *disk_performance);
127void gui_disperformance_free(DiskPerformanceData *event_viewer_data);
4ea3dbbf 128static void get_event_detail(LttEvent *e, lttv_block* disk_data);
a4f37ccd 129static char * major_minor_to_diskname( lttv_block* disk_data);
130static void sum_data(char* diskname, guint size, enum operation_t opt, GArray *disk_array);
4ea3dbbf 131static GtkWidget *disk_performance(Tab * tab);
132
133static gboolean block_read_callback(void *hook_data, void *call_data);
134
135static gboolean block_write_callback(void *hook_data, void *call_data);
136
137
138static 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
182static gboolean trace_header(void *hook_data, void *call_data){
183 return FALSE;
184}
185
186
187static 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
200void 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
225void 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
233static 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 */
245static 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}
a4f37ccd 261
4ea3dbbf 262/**
263 * Constructor hook
264 *
265 */
266GtkWidget *disk_performance(Tab * tab)
267{
a4f37ccd 268
269 DiskPerformanceData* disk_data = disk_performance_data(tab);
270 if(disk_data)
271 return disk_data->hbox_v;
272 else
273 return NULL;
a4f37ccd 274}
275
4ea3dbbf 276/**
277 * This function initializes the Event Viewer functionnality through the
278 * GTK API.
279 */
280DiskPerformanceData *disk_performance_data(Tab *tab)
281{
a4f37ccd 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),
4ea3dbbf 302 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
303
a4f37ccd 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 */
4ea3dbbf 307 G_TYPE_STRING, /* Diskname */
a4f37ccd 308 G_TYPE_INT64, /* Bytes read */
4ea3dbbf 309 G_TYPE_INT64, /* Bytes read/sec */
a4f37ccd 310 G_TYPE_INT,
4ea3dbbf 311 G_TYPE_INT64, /* bytes written */
312 G_TYPE_INT64, /* bytes written/sec */
a4f37ccd 313 G_TYPE_INT
314 );
315
316 disk_data->tree_v = gtk_tree_view_new_with_model (GTK_TREE_MODEL (disk_data->store_m));
4ea3dbbf 317
a4f37ccd 318 g_object_unref (G_OBJECT (disk_data->store_m));
319
320 renderer = gtk_cell_renderer_text_new ();
4ea3dbbf 321
a4f37ccd 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);
4ea3dbbf 386
a4f37ccd 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}
a4f37ccd 405
4ea3dbbf 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 */
415static void request_event(DiskPerformanceData *disk_performance)
416{
417 guint i, k, l, nb_trace;
a4f37ccd 418
4ea3dbbf 419 GArray *hooks;
a4f37ccd 420
4ea3dbbf 421 guint ret;
422
423 LttvTraceHook *hook;
424
425 LttvTraceState *ts;
a4f37ccd 426
4ea3dbbf 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);
a4f37ccd 434
4ea3dbbf 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);
a4f37ccd 511 }
a4f37ccd 512
a4f37ccd 513}
514
4ea3dbbf 515/**
516 * This function is called whenever a read event occurs.
517 *
518 */
519static 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;
a4f37ccd 544}
545
4ea3dbbf 546/**
547 * This function is called whenever a write event occurs.
548 *
549 */
550static 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;
a4f37ccd 572}
a4f37ccd 573
4ea3dbbf 574/**
575 * This function extracts the major, minor and size
576 *
577 */
578static 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++)
a4f37ccd 588 {
4ea3dbbf 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);
a4f37ccd 596 }
4ea3dbbf 597
a4f37ccd 598}
a4f37ccd 599
4ea3dbbf 600/**
601 * This function convert the major and minor number to the corresponding disk
602 *
603 */
604static char * major_minor_to_diskname( lttv_block* disk_data)
605{
a4f37ccd 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
4ea3dbbf 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 */
616static void sum_data(char* diskname, guint size, enum operation_t operation, GArray *disk_array)
617{
a4f37ccd 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
a4f37ccd 668
a4f37ccd 669static 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
680LTTV_MODULE("diskperformance", "disk info view", \
681 "Produce disk I/O performance", \
682 init, destroy, "lttvwindow")
683
This page took 0.056969 seconds and 4 git commands to generate.