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
*Main_Win_Module
;
30 /** Array containing instanced objects. Used when module is unloaded */
31 static GSList
*gStatistic_Viewer_Data_List
= NULL
;
33 typedef struct _StatisticViewerData StatisticViewerData
;
35 //! Statistic Viewer's constructor hook
36 GtkWidget
*hGuiStatistic(mainWindow
*pmParentWindow
);
37 //! Statistic Viewer's constructor
38 StatisticViewerData
*GuiStatistic(mainWindow
*pmParentWindow
);
39 //! Statistic Viewer's destructor
40 void GuiStatistic_Destructor(StatisticViewerData
*Statistic_Viewer_Data
);
41 void GuiStatistic_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 Main_Win_Module
= lttv_module_require(self
, "mainwin", argc
, argv
);
96 if(Main_Win_Module
== NULL
){
97 g_critical("Can't load Statistic Viewer : missing mainwin\n");
101 g_critical("GUI Statistic Viewer init()");
103 /* Register the toolbar insert button */
104 ToolbarItemReg(hGuiStatisticInsert_xpm
, "Insert Statistic Viewer", hGuiStatistic
);
106 /* Register the menu item insert entry */
107 MenuItemReg("/", "Insert Statistic Viewer", hGuiStatistic
);
111 void statistic_destroy_walk(gpointer data
, gpointer user_data
)
113 GuiStatistic_Destructor((StatisticViewerData
*)data
);
117 * plugin's destroy function
119 * This function releases the memory reserved by the module and unregisters
120 * everything that has been registered in the gtkTraceSet API.
122 G_MODULE_EXPORT
void destroy() {
125 g_critical("GUI Statistic Viewer destroy()");
127 if(gStatistic_Viewer_Data_List
){
128 g_slist_foreach(gStatistic_Viewer_Data_List
, statistic_destroy_walk
, NULL
);
129 g_slist_free(gStatistic_Viewer_Data_List
);
132 /* Unregister the toolbar insert button */
133 ToolbarItemUnreg(hGuiStatistic
);
135 /* Unregister the menu item insert entry */
136 MenuItemUnreg(hGuiStatistic
);
141 GuiStatistic_free(StatisticViewerData
*Statistic_Viewer_Data
)
143 g_critical("GuiStatistic_free()");
144 if(Statistic_Viewer_Data
){
145 g_hash_table_destroy(Statistic_Viewer_Data
->Statistic_Hash
);
146 gStatistic_Viewer_Data_List
= g_slist_remove(gStatistic_Viewer_Data_List
, Statistic_Viewer_Data
);
147 g_warning("Delete Statistic data\n");
148 g_free(Statistic_Viewer_Data
);
153 GuiStatistic_Destructor(StatisticViewerData
*Statistic_Viewer_Data
)
155 g_critical("GuiStatistic_Destructor()");
156 /* May already been done by GTK window closing */
157 if(GTK_IS_WIDGET(Statistic_Viewer_Data
->HPaned_V
)){
158 gtk_widget_destroy(Statistic_Viewer_Data
->HPaned_V
);
159 Statistic_Viewer_Data
= NULL
;
161 //GuiStatistic_free(Statistic_Viewer_Data);
166 * Statistic Viewer's constructor hook
168 * This constructor is given as a parameter to the menuitem and toolbar button
169 * registration. It creates the list.
170 * @param pmParentWindow A pointer to the parent window.
171 * @return The widget created.
174 hGuiStatistic(mainWindow
* pmParentWindow
)
176 StatisticViewerData
* Statistic_Viewer_Data
= GuiStatistic(pmParentWindow
) ;
178 if(Statistic_Viewer_Data
)
179 return Statistic_Viewer_Data
->HPaned_V
;
185 * Statistic Viewer's constructor
187 * This constructor is used to create StatisticViewerData data structure.
188 * @return The Statistic viewer data created.
190 StatisticViewerData
*
191 GuiStatistic(mainWindow
*pmParentWindow
)
193 GtkCellRenderer
*renderer
;
194 GtkTreeViewColumn
*column
;
196 StatisticViewerData
* Statistic_Viewer_Data
= g_new(StatisticViewerData
,1);
198 Statistic_Viewer_Data
->mw
= pmParentWindow
;
199 Statistic_Viewer_Data
->stats
= getTracesetStats(Statistic_Viewer_Data
->mw
);
201 Statistic_Viewer_Data
->Statistic_Hash
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
202 statistic_destroy_hash_key
,
203 statistic_destroy_hash_data
);
205 Statistic_Viewer_Data
->HPaned_V
= gtk_hpaned_new();
206 Statistic_Viewer_Data
->Store_M
= gtk_tree_store_new (N_COLUMNS
, G_TYPE_STRING
);
207 Statistic_Viewer_Data
->Tree_V
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (Statistic_Viewer_Data
->Store_M
));
208 g_object_unref (G_OBJECT (Statistic_Viewer_Data
->Store_M
));
210 g_signal_connect (G_OBJECT (Statistic_Viewer_Data
->Tree_V
), "grab-focus",
211 G_CALLBACK (grab_focus
),
212 Statistic_Viewer_Data
);
214 // Setup the selection handler
215 Statistic_Viewer_Data
->Select_C
= gtk_tree_view_get_selection (GTK_TREE_VIEW (Statistic_Viewer_Data
->Tree_V
));
216 gtk_tree_selection_set_mode (Statistic_Viewer_Data
->Select_C
, GTK_SELECTION_SINGLE
);
217 g_signal_connect (G_OBJECT (Statistic_Viewer_Data
->Select_C
), "changed",
218 G_CALLBACK (tree_selection_changed_cb
),
219 Statistic_Viewer_Data
);
221 renderer
= gtk_cell_renderer_text_new ();
222 column
= gtk_tree_view_column_new_with_attributes ("Statistic Name",
226 gtk_tree_view_column_set_alignment (column
, 0.0);
227 // gtk_tree_view_column_set_fixed_width (column, 45);
228 gtk_tree_view_append_column (GTK_TREE_VIEW (Statistic_Viewer_Data
->Tree_V
), column
);
231 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (Statistic_Viewer_Data
->Tree_V
), FALSE
);
233 Statistic_Viewer_Data
->Scroll_Win_Tree
= gtk_scrolled_window_new (NULL
, NULL
);
234 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Statistic_Viewer_Data
->Scroll_Win_Tree
),
235 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
237 gtk_container_add (GTK_CONTAINER (Statistic_Viewer_Data
->Scroll_Win_Tree
), Statistic_Viewer_Data
->Tree_V
);
238 gtk_paned_pack1(GTK_PANED(Statistic_Viewer_Data
->HPaned_V
),Statistic_Viewer_Data
->Scroll_Win_Tree
, TRUE
, FALSE
);
239 gtk_paned_set_position(GTK_PANED(Statistic_Viewer_Data
->HPaned_V
), 160);
241 Statistic_Viewer_Data
->Scroll_Win_Text
= gtk_scrolled_window_new (NULL
, NULL
);
242 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Statistic_Viewer_Data
->Scroll_Win_Text
),
243 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
245 Statistic_Viewer_Data
->Text_V
= gtk_text_view_new ();
246 g_signal_connect (G_OBJECT (Statistic_Viewer_Data
->Text_V
), "grab-focus",
247 G_CALLBACK (grab_focus
),
248 Statistic_Viewer_Data
);
250 gtk_text_view_set_editable(GTK_TEXT_VIEW(Statistic_Viewer_Data
->Text_V
),FALSE
);
251 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(Statistic_Viewer_Data
->Text_V
),FALSE
);
252 gtk_container_add (GTK_CONTAINER (Statistic_Viewer_Data
->Scroll_Win_Text
), Statistic_Viewer_Data
->Text_V
);
253 gtk_paned_pack2(GTK_PANED(Statistic_Viewer_Data
->HPaned_V
), Statistic_Viewer_Data
->Scroll_Win_Text
, TRUE
, FALSE
);
255 gtk_widget_show(Statistic_Viewer_Data
->Scroll_Win_Tree
);
256 gtk_widget_show(Statistic_Viewer_Data
->Scroll_Win_Text
);
257 gtk_widget_show(Statistic_Viewer_Data
->Tree_V
);
258 gtk_widget_show(Statistic_Viewer_Data
->Text_V
);
259 gtk_widget_show(Statistic_Viewer_Data
->HPaned_V
);
261 g_object_set_data_full(
262 G_OBJECT(Statistic_Viewer_Data
->HPaned_V
),
263 "Statistic_Viewer_Data",
264 Statistic_Viewer_Data
,
265 (GDestroyNotify
)GuiStatistic_free
);
267 /* Add the object's information to the module's array */
268 gStatistic_Viewer_Data_List
= g_slist_append(
269 gStatistic_Viewer_Data_List
,
270 Statistic_Viewer_Data
);
272 get_traceset_stats(Statistic_Viewer_Data
);
274 return Statistic_Viewer_Data
;
277 void grab_focus(GtkWidget
*widget
, gpointer data
)
279 StatisticViewerData
*Statistic_Viewer_Data
= (StatisticViewerData
*)data
;
280 mainWindow
* mw
= Statistic_Viewer_Data
->mw
;
281 SetFocusedPane(mw
, gtk_widget_get_parent(Statistic_Viewer_Data
->HPaned_V
));
285 tree_selection_changed_cb (GtkTreeSelection
*selection
, gpointer data
)
287 StatisticViewerData
*Statistic_Viewer_Data
= (StatisticViewerData
*)data
;
289 GtkTreeModel
*model
= GTK_TREE_MODEL(Statistic_Viewer_Data
->Store_M
);
294 GtkTextIter text_iter
;
295 LttvAttribute
* stats
;
297 if (gtk_tree_selection_get_selected (selection
, &model
, &iter
))
299 gtk_tree_model_get (model
, &iter
, NAME_COLUMN
, &Event
, -1);
301 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(model
),&iter
);
302 str
= gtk_tree_path_to_string (path
);
303 stats
= (LttvAttribute
*)g_hash_table_lookup (Statistic_Viewer_Data
->Statistic_Hash
,str
);
306 buf
= gtk_text_view_get_buffer((GtkTextView
*)Statistic_Viewer_Data
->Text_V
);
307 gtk_text_buffer_set_text(buf
,"Statistic for '", -1);
308 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
309 gtk_text_buffer_insert(buf
, &text_iter
, Event
, strlen(Event
));
310 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
311 gtk_text_buffer_insert(buf
, &text_iter
, "' :\n\n",5);
313 show_statistic(Statistic_Viewer_Data
, stats
, buf
);
319 void statistic_destroy_hash_key(gpointer key
)
324 void statistic_destroy_hash_data(gpointer data
)
329 void get_traceset_stats(StatisticViewerData
* Statistic_Viewer_Data
)
335 end
.tv_sec
= G_MAXULONG
;
336 end
.tv_nsec
= G_MAXULONG
;
338 stateAddEventHooks(Statistic_Viewer_Data
->mw
);
339 statsAddEventHooks(Statistic_Viewer_Data
->mw
);
341 processTraceset(Statistic_Viewer_Data
->mw
, start
, end
, G_MAXULONG
);
343 stateRemoveEventHooks(Statistic_Viewer_Data
->mw
);
344 statsRemoveEventHooks(Statistic_Viewer_Data
->mw
);
346 //establish tree view for stats
347 show_traceset_stats(Statistic_Viewer_Data
);
350 void show_traceset_stats(StatisticViewerData
* Statistic_Viewer_Data
)
355 LttSystemDescription
*desc
;
356 LttvTracesetStats
* tscs
= Statistic_Viewer_Data
->stats
;
357 gchar
* str
, trace_str
[PATH_LENGTH
];
360 GtkTreeStore
* store
= Statistic_Viewer_Data
->Store_M
;
362 if(tscs
->stats
== NULL
) return;
364 gtk_tree_store_append (store
, &iter
, NULL
);
365 gtk_tree_store_set (store
, &iter
,
366 NAME_COLUMN
, "Traceset statistics",
368 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
369 str
= gtk_tree_path_to_string (path
);
370 g_hash_table_insert(Statistic_Viewer_Data
->Statistic_Hash
,
371 (gpointer
)str
, tscs
->stats
);
372 show_tree(Statistic_Viewer_Data
, tscs
->stats
, &iter
);
374 //show stats for all traces
375 ts
= tscs
->parent
.parent
.ts
;
376 nb
= lttv_traceset_number(ts
);
378 for(i
= 0 ; i
< nb
; i
++) {
379 tcs
= (LttvTraceStats
*)(LTTV_TRACESET_CONTEXT(tscs
)->traces
[i
]);
380 desc
= ltt_trace_system_description(tcs
->parent
.parent
.t
);
381 sprintf(trace_str
, "Trace on system %s at time %d secs",
382 desc
->node_name
,desc
->trace_start
.tv_sec
);
384 gtk_tree_store_append (store
, &iter
, NULL
);
385 gtk_tree_store_set (store
, &iter
,NAME_COLUMN
,trace_str
,-1);
386 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
387 str
= gtk_tree_path_to_string (path
);
388 g_hash_table_insert(Statistic_Viewer_Data
->Statistic_Hash
,
389 (gpointer
)str
,tcs
->stats
);
390 show_tree(Statistic_Viewer_Data
, tcs
->stats
, &iter
);
394 void show_tree(StatisticViewerData
* Statistic_Viewer_Data
,
395 LttvAttribute
* stats
, GtkTreeIter
* parent
)
398 LttvAttribute
*subtree
;
399 LttvAttributeName name
;
400 LttvAttributeValue value
;
401 LttvAttributeType type
;
402 gchar
* str
, dir_str
[PATH_LENGTH
];
405 GtkTreeStore
* store
= Statistic_Viewer_Data
->Store_M
;
407 nb
= lttv_attribute_get_number(stats
);
408 for(i
= 0 ; i
< nb
; i
++) {
409 type
= lttv_attribute_get(stats
, i
, &name
, &value
);
412 if(LTTV_IS_ATTRIBUTE(*(value
.v_gobject
))) {
413 sprintf(dir_str
, "%s", g_quark_to_string(name
));
414 subtree
= (LttvAttribute
*)*(value
.v_gobject
);
415 gtk_tree_store_append (store
, &iter
, parent
);
416 gtk_tree_store_set (store
, &iter
,NAME_COLUMN
,dir_str
,-1);
417 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
418 str
= gtk_tree_path_to_string (path
);
419 g_hash_table_insert(Statistic_Viewer_Data
->Statistic_Hash
,
420 (gpointer
)str
, subtree
);
421 show_tree(Statistic_Viewer_Data
, subtree
, &iter
);
430 void show_statistic(StatisticViewerData
* Statistic_Viewer_Data
,
431 LttvAttribute
* stats
, GtkTextBuffer
* buf
)
434 LttvAttribute
*subtree
;
435 LttvAttributeName name
;
436 LttvAttributeValue value
;
437 LttvAttributeType type
;
438 gchar type_name
[PATH_LENGTH
], type_value
[PATH_LENGTH
];
439 GtkTextIter text_iter
;
442 nb
= lttv_attribute_get_number(stats
);
443 for(i
= 0 ; i
< nb
; i
++) {
444 type
= lttv_attribute_get(stats
, i
, &name
, &value
);
445 sprintf(type_name
,"%s", g_quark_to_string(name
));
446 type_value
[0] = '\0';
449 sprintf(type_value
, " : %d\n", *value
.v_int
);
452 sprintf(type_value
, " : %u\n", *value
.v_uint
);
455 sprintf(type_value
, " : %ld\n", *value
.v_long
);
458 sprintf(type_value
, " : %lu\n", *value
.v_ulong
);
461 sprintf(type_value
, " : %f\n", (double)*value
.v_float
);
464 sprintf(type_value
, " : %f\n", *value
.v_double
);
467 sprintf(type_value
, " : %10u.%09u\n", value
.v_time
->tv_sec
,
468 value
.v_time
->tv_nsec
);
471 sprintf(type_value
, " : POINTER\n");
474 sprintf(type_value
, " : %s\n", *value
.v_string
);
479 if(strlen(type_value
)){
481 strcat(type_name
,type_value
);
482 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
483 gtk_text_buffer_insert(buf
, &text_iter
, type_name
, strlen(type_name
));
488 sprintf(type_value
, "No statistic information in this directory.\nCheck in subdirectories please.\n");
489 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
490 gtk_text_buffer_insert(buf
, &text_iter
, type_value
, strlen(type_value
));