6 #include <lttv/module.h>
7 #include <lttv/gtkTraceSet.h>
8 #include <lttv/processTrace.h>
10 #include <lttv/common.h>
11 #include <lttv/state.h>
12 #include <lttv/stats.h>
15 #include <ltt/event.h>
17 #include <ltt/trace.h>
21 #include "../icons/hGuiStatisticInsert.xpm"
23 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
24 #define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
26 #define PATH_LENGTH 256
28 static LttvModule
*statistic_main_win_module
;
30 /** Array containing instanced objects. Used when module is unloaded */
31 static GSList
*g_statistic_viewer_data_list
= NULL
;
33 typedef struct _StatisticViewerData StatisticViewerData
;
35 //! Statistic Viewer's constructor hook
36 GtkWidget
*h_gui_statistic(MainWindow
*parent_window
);
37 //! Statistic Viewer's constructor
38 StatisticViewerData
*gui_statistic(MainWindow
*parent_window
);
39 //! Statistic Viewer's destructor
40 void gui_statistic_destructor(StatisticViewerData
*statistic_viewer_data
);
41 void gui_statistic_free(StatisticViewerData
*statistic_viewer_data
);
43 void grab_focus(GtkWidget
*widget
, gpointer data
);
44 static void tree_selection_changed_cb (GtkTreeSelection
*selection
, gpointer data
);
46 void statistic_destroy_hash_key(gpointer key
);
47 void statistic_destroy_hash_data(gpointer data
);
49 void get_traceset_stats(StatisticViewerData
* statistic_viewer_data
);
50 void show_traceset_stats(StatisticViewerData
* statistic_viewer_data
);
51 void show_tree(StatisticViewerData
* statistic_viewer_data
,
52 LttvAttribute
* stats
, GtkTreeIter
* parent
);
53 void show_statistic(StatisticViewerData
* statistic_viewer_data
,
54 LttvAttribute
* stats
, GtkTextBuffer
* buf
);
63 struct _StatisticViewerData
{
65 LttvTracesetStats
* stats
;
68 GtkTreeStore
* store_m
;
71 //scroll window containing Tree View
72 GtkWidget
* scroll_win_tree
;
75 //scroll window containing Text View
76 GtkWidget
* scroll_win_text
;
79 GtkTreeSelection
*select_c
;
82 GHashTable
*statistic_hash
;
87 * plugin's init function
89 * This function initializes the Statistic Viewer functionnality through the
92 G_MODULE_EXPORT
void init(LttvModule
*self
, int argc
, char *argv
[]) {
94 statistic_main_win_module
= lttv_module_require(self
, "mainwin", argc
, argv
);
96 if(statistic_main_win_module
== NULL
){
97 g_critical("Can't load Statistic Viewer : missing mainwin\n");
101 /* Register the toolbar insert button */
102 ToolbarItemReg(hGuiStatisticInsert_xpm
, "Insert Statistic Viewer", h_gui_statistic
);
104 /* Register the menu item insert entry */
105 MenuItemReg("/", "Insert Statistic Viewer", h_gui_statistic
);
109 void statistic_destroy_walk(gpointer data
, gpointer user_data
)
111 gui_statistic_destructor((StatisticViewerData
*)data
);
115 * plugin's destroy function
117 * This function releases the memory reserved by the module and unregisters
118 * everything that has been registered in the gtkTraceSet API.
120 G_MODULE_EXPORT
void destroy() {
123 if(g_statistic_viewer_data_list
){
124 g_slist_foreach(g_statistic_viewer_data_list
, statistic_destroy_walk
, NULL
);
125 g_slist_free(g_statistic_viewer_data_list
);
128 /* Unregister the toolbar insert button */
129 ToolbarItemUnreg(h_gui_statistic
);
131 /* Unregister the menu item insert entry */
132 MenuItemUnreg(h_gui_statistic
);
137 gui_statistic_free(StatisticViewerData
*statistic_viewer_data
)
139 if(statistic_viewer_data
){
140 g_hash_table_destroy(statistic_viewer_data
->statistic_hash
);
141 g_statistic_viewer_data_list
= g_slist_remove(g_statistic_viewer_data_list
, statistic_viewer_data
);
142 g_free(statistic_viewer_data
);
147 gui_statistic_destructor(StatisticViewerData
*statistic_viewer_data
)
149 /* May already been done by GTK window closing */
150 if(GTK_IS_WIDGET(statistic_viewer_data
->hpaned_v
)){
151 gtk_widget_destroy(statistic_viewer_data
->hpaned_v
);
152 statistic_viewer_data
= NULL
;
154 //gui_statistic_free(statistic_viewer_data);
159 * Statistic Viewer's constructor hook
161 * This constructor is given as a parameter to the menuitem and toolbar button
162 * registration. It creates the list.
163 * @param parent_window A pointer to the parent window.
164 * @return The widget created.
167 h_gui_statistic(MainWindow
* parent_window
)
169 StatisticViewerData
* statistic_viewer_data
= gui_statistic(parent_window
) ;
171 if(statistic_viewer_data
)
172 return statistic_viewer_data
->hpaned_v
;
178 * Statistic Viewer's constructor
180 * This constructor is used to create StatisticViewerData data structure.
181 * @return The Statistic viewer data created.
183 StatisticViewerData
*
184 gui_statistic(MainWindow
*parent_window
)
186 GtkCellRenderer
*renderer
;
187 GtkTreeViewColumn
*column
;
189 StatisticViewerData
* statistic_viewer_data
= g_new(StatisticViewerData
,1);
191 statistic_viewer_data
->mw
= parent_window
;
192 statistic_viewer_data
->stats
= getTracesetStats(statistic_viewer_data
->mw
);
194 statistic_viewer_data
->statistic_hash
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
195 statistic_destroy_hash_key
,
196 statistic_destroy_hash_data
);
198 statistic_viewer_data
->hpaned_v
= gtk_hpaned_new();
199 statistic_viewer_data
->store_m
= gtk_tree_store_new (N_COLUMNS
, G_TYPE_STRING
);
200 statistic_viewer_data
->tree_v
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (statistic_viewer_data
->store_m
));
201 g_object_unref (G_OBJECT (statistic_viewer_data
->store_m
));
203 g_signal_connect (G_OBJECT (statistic_viewer_data
->tree_v
), "grab-focus",
204 G_CALLBACK (grab_focus
),
205 statistic_viewer_data
);
207 // Setup the selection handler
208 statistic_viewer_data
->select_c
= gtk_tree_view_get_selection (GTK_TREE_VIEW (statistic_viewer_data
->tree_v
));
209 gtk_tree_selection_set_mode (statistic_viewer_data
->select_c
, GTK_SELECTION_SINGLE
);
210 g_signal_connect (G_OBJECT (statistic_viewer_data
->select_c
), "changed",
211 G_CALLBACK (tree_selection_changed_cb
),
212 statistic_viewer_data
);
214 renderer
= gtk_cell_renderer_text_new ();
215 column
= gtk_tree_view_column_new_with_attributes ("Statistic Name",
219 gtk_tree_view_column_set_alignment (column
, 0.0);
220 // gtk_tree_view_column_set_fixed_width (column, 45);
221 gtk_tree_view_append_column (GTK_TREE_VIEW (statistic_viewer_data
->tree_v
), column
);
224 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (statistic_viewer_data
->tree_v
), FALSE
);
226 statistic_viewer_data
->scroll_win_tree
= gtk_scrolled_window_new (NULL
, NULL
);
227 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(statistic_viewer_data
->scroll_win_tree
),
228 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
230 gtk_container_add (GTK_CONTAINER (statistic_viewer_data
->scroll_win_tree
), statistic_viewer_data
->tree_v
);
231 gtk_paned_pack1(GTK_PANED(statistic_viewer_data
->hpaned_v
),statistic_viewer_data
->scroll_win_tree
, TRUE
, FALSE
);
232 gtk_paned_set_position(GTK_PANED(statistic_viewer_data
->hpaned_v
), 160);
234 statistic_viewer_data
->scroll_win_text
= gtk_scrolled_window_new (NULL
, NULL
);
235 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(statistic_viewer_data
->scroll_win_text
),
236 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
238 statistic_viewer_data
->text_v
= gtk_text_view_new ();
239 g_signal_connect (G_OBJECT (statistic_viewer_data
->text_v
), "grab-focus",
240 G_CALLBACK (grab_focus
),
241 statistic_viewer_data
);
243 gtk_text_view_set_editable(GTK_TEXT_VIEW(statistic_viewer_data
->text_v
),FALSE
);
244 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(statistic_viewer_data
->text_v
),FALSE
);
245 gtk_container_add (GTK_CONTAINER (statistic_viewer_data
->scroll_win_text
), statistic_viewer_data
->text_v
);
246 gtk_paned_pack2(GTK_PANED(statistic_viewer_data
->hpaned_v
), statistic_viewer_data
->scroll_win_text
, TRUE
, FALSE
);
248 gtk_widget_show(statistic_viewer_data
->scroll_win_tree
);
249 gtk_widget_show(statistic_viewer_data
->scroll_win_text
);
250 gtk_widget_show(statistic_viewer_data
->tree_v
);
251 gtk_widget_show(statistic_viewer_data
->text_v
);
252 gtk_widget_show(statistic_viewer_data
->hpaned_v
);
254 g_object_set_data_full(
255 G_OBJECT(statistic_viewer_data
->hpaned_v
),
256 "statistic_viewer_data",
257 statistic_viewer_data
,
258 (GDestroyNotify
)gui_statistic_free
);
260 /* Add the object's information to the module's array */
261 g_statistic_viewer_data_list
= g_slist_append(
262 g_statistic_viewer_data_list
,
263 statistic_viewer_data
);
265 get_traceset_stats(statistic_viewer_data
);
267 return statistic_viewer_data
;
270 void grab_focus(GtkWidget
*widget
, gpointer data
)
272 StatisticViewerData
*statistic_viewer_data
= (StatisticViewerData
*)data
;
273 MainWindow
* mw
= statistic_viewer_data
->mw
;
274 SetFocusedPane(mw
, gtk_widget_get_parent(statistic_viewer_data
->hpaned_v
));
278 tree_selection_changed_cb (GtkTreeSelection
*selection
, gpointer data
)
280 StatisticViewerData
*statistic_viewer_data
= (StatisticViewerData
*)data
;
282 GtkTreeModel
*model
= GTK_TREE_MODEL(statistic_viewer_data
->store_m
);
287 GtkTextIter text_iter
;
288 LttvAttribute
* stats
;
290 if (gtk_tree_selection_get_selected (selection
, &model
, &iter
))
292 gtk_tree_model_get (model
, &iter
, NAME_COLUMN
, &event
, -1);
294 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(model
),&iter
);
295 str
= gtk_tree_path_to_string (path
);
296 stats
= (LttvAttribute
*)g_hash_table_lookup (statistic_viewer_data
->statistic_hash
,str
);
299 buf
= gtk_text_view_get_buffer((GtkTextView
*)statistic_viewer_data
->text_v
);
300 gtk_text_buffer_set_text(buf
,"Statistic for '", -1);
301 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
302 gtk_text_buffer_insert(buf
, &text_iter
, event
, strlen(event
));
303 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
304 gtk_text_buffer_insert(buf
, &text_iter
, "' :\n\n",5);
306 show_statistic(statistic_viewer_data
, stats
, buf
);
312 void statistic_destroy_hash_key(gpointer key
)
317 void statistic_destroy_hash_data(gpointer data
)
322 void get_traceset_stats(StatisticViewerData
* statistic_viewer_data
)
328 end
.tv_sec
= G_MAXULONG
;
329 end
.tv_nsec
= G_MAXULONG
;
331 stateAddEventHooks(statistic_viewer_data
->mw
);
332 statsAddEventHooks(statistic_viewer_data
->mw
);
334 processTraceset(statistic_viewer_data
->mw
, start
, end
, G_MAXULONG
);
336 stateRemoveEventHooks(statistic_viewer_data
->mw
);
337 statsRemoveEventHooks(statistic_viewer_data
->mw
);
339 //establish tree view for stats
340 show_traceset_stats(statistic_viewer_data
);
343 void show_traceset_stats(StatisticViewerData
* statistic_viewer_data
)
348 LttSystemDescription
*desc
;
349 LttvTracesetStats
* tscs
= statistic_viewer_data
->stats
;
350 gchar
* str
, trace_str
[PATH_LENGTH
];
353 GtkTreeStore
* store
= statistic_viewer_data
->store_m
;
355 if(tscs
->stats
== NULL
) return;
357 gtk_tree_store_append (store
, &iter
, NULL
);
358 gtk_tree_store_set (store
, &iter
,
359 NAME_COLUMN
, "Traceset statistics",
361 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
362 str
= gtk_tree_path_to_string (path
);
363 g_hash_table_insert(statistic_viewer_data
->statistic_hash
,
364 (gpointer
)str
, tscs
->stats
);
365 show_tree(statistic_viewer_data
, tscs
->stats
, &iter
);
367 //show stats for all traces
368 ts
= tscs
->parent
.parent
.ts
;
369 nb
= lttv_traceset_number(ts
);
371 for(i
= 0 ; i
< nb
; i
++) {
372 tcs
= (LttvTraceStats
*)(LTTV_TRACESET_CONTEXT(tscs
)->traces
[i
]);
373 desc
= ltt_trace_system_description(tcs
->parent
.parent
.t
);
374 sprintf(trace_str
, "Trace on system %s at time %d secs",
375 desc
->node_name
,desc
->trace_start
.tv_sec
);
377 gtk_tree_store_append (store
, &iter
, NULL
);
378 gtk_tree_store_set (store
, &iter
,NAME_COLUMN
,trace_str
,-1);
379 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
380 str
= gtk_tree_path_to_string (path
);
381 g_hash_table_insert(statistic_viewer_data
->statistic_hash
,
382 (gpointer
)str
,tcs
->stats
);
383 show_tree(statistic_viewer_data
, tcs
->stats
, &iter
);
387 void show_tree(StatisticViewerData
* statistic_viewer_data
,
388 LttvAttribute
* stats
, GtkTreeIter
* parent
)
391 LttvAttribute
*subtree
;
392 LttvAttributeName name
;
393 LttvAttributeValue value
;
394 LttvAttributeType type
;
395 gchar
* str
, dir_str
[PATH_LENGTH
];
398 GtkTreeStore
* store
= statistic_viewer_data
->store_m
;
400 nb
= lttv_attribute_get_number(stats
);
401 for(i
= 0 ; i
< nb
; i
++) {
402 type
= lttv_attribute_get(stats
, i
, &name
, &value
);
405 if(LTTV_IS_ATTRIBUTE(*(value
.v_gobject
))) {
406 sprintf(dir_str
, "%s", g_quark_to_string(name
));
407 subtree
= (LttvAttribute
*)*(value
.v_gobject
);
408 gtk_tree_store_append (store
, &iter
, parent
);
409 gtk_tree_store_set (store
, &iter
,NAME_COLUMN
,dir_str
,-1);
410 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
411 str
= gtk_tree_path_to_string (path
);
412 g_hash_table_insert(statistic_viewer_data
->statistic_hash
,
413 (gpointer
)str
, subtree
);
414 show_tree(statistic_viewer_data
, subtree
, &iter
);
423 void show_statistic(StatisticViewerData
* statistic_viewer_data
,
424 LttvAttribute
* stats
, GtkTextBuffer
* buf
)
427 LttvAttribute
*subtree
;
428 LttvAttributeName name
;
429 LttvAttributeValue value
;
430 LttvAttributeType type
;
431 gchar type_name
[PATH_LENGTH
], type_value
[PATH_LENGTH
];
432 GtkTextIter text_iter
;
435 nb
= lttv_attribute_get_number(stats
);
436 for(i
= 0 ; i
< nb
; i
++) {
437 type
= lttv_attribute_get(stats
, i
, &name
, &value
);
438 sprintf(type_name
,"%s", g_quark_to_string(name
));
439 type_value
[0] = '\0';
442 sprintf(type_value
, " : %d\n", *value
.v_int
);
445 sprintf(type_value
, " : %u\n", *value
.v_uint
);
448 sprintf(type_value
, " : %ld\n", *value
.v_long
);
451 sprintf(type_value
, " : %lu\n", *value
.v_ulong
);
454 sprintf(type_value
, " : %f\n", (double)*value
.v_float
);
457 sprintf(type_value
, " : %f\n", *value
.v_double
);
460 sprintf(type_value
, " : %10u.%09u\n", value
.v_time
->tv_sec
,
461 value
.v_time
->tv_nsec
);
464 sprintf(type_value
, " : POINTER\n");
467 sprintf(type_value
, " : %s\n", *value
.v_string
);
472 if(strlen(type_value
)){
474 strcat(type_name
,type_value
);
475 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
476 gtk_text_buffer_insert(buf
, &text_iter
, type_name
, strlen(type_name
));
481 sprintf(type_value
, "No statistic information in this directory.\nCheck in subdirectories please.\n");
482 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
483 gtk_text_buffer_insert(buf
, &text_iter
, type_value
, strlen(type_value
));