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 Destroy_hash_key(gpointer key
);
47 void 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 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()");
126 g_slist_foreach(gStatistic_Viewer_Data_List
, destroy_walk
, NULL
);
128 g_slist_free(gStatistic_Viewer_Data_List
);
130 /* Unregister the toolbar insert button */
131 ToolbarItemUnreg(hGuiStatistic
);
133 /* Unregister the menu item insert entry */
134 MenuItemUnreg(hGuiStatistic
);
139 GuiStatistic_free(StatisticViewerData
*Statistic_Viewer_Data
)
141 g_critical("GuiStatistic_free()");
142 if(Statistic_Viewer_Data
){
143 g_hash_table_destroy(Statistic_Viewer_Data
->Statistic_Hash
);
144 gStatistic_Viewer_Data_List
= g_slist_remove(gStatistic_Viewer_Data_List
, Statistic_Viewer_Data
);
145 g_warning("Delete Statistic data\n");
146 g_free(Statistic_Viewer_Data
);
151 GuiStatistic_Destructor(StatisticViewerData
*Statistic_Viewer_Data
)
153 g_critical("GuiStatistic_Destructor()");
154 /* May already been done by GTK window closing */
155 if(GTK_IS_WIDGET(Statistic_Viewer_Data
->HPaned_V
)){
156 gtk_widget_destroy(Statistic_Viewer_Data
->HPaned_V
);
157 Statistic_Viewer_Data
= NULL
;
159 GuiStatistic_free(Statistic_Viewer_Data
);
164 * Statistic Viewer's constructor hook
166 * This constructor is given as a parameter to the menuitem and toolbar button
167 * registration. It creates the list.
168 * @param pmParentWindow A pointer to the parent window.
169 * @return The widget created.
172 hGuiStatistic(mainWindow
* pmParentWindow
)
174 StatisticViewerData
* Statistic_Viewer_Data
= GuiStatistic(pmParentWindow
) ;
176 if(Statistic_Viewer_Data
)
177 return Statistic_Viewer_Data
->HPaned_V
;
183 * Statistic Viewer's constructor
185 * This constructor is used to create StatisticViewerData data structure.
186 * @return The Statistic viewer data created.
188 StatisticViewerData
*
189 GuiStatistic(mainWindow
*pmParentWindow
)
191 GtkCellRenderer
*renderer
;
192 GtkTreeViewColumn
*column
;
194 StatisticViewerData
* Statistic_Viewer_Data
= g_new(StatisticViewerData
,1);
196 Statistic_Viewer_Data
->mw
= pmParentWindow
;
197 Statistic_Viewer_Data
->stats
= getTracesetStats(Statistic_Viewer_Data
->mw
);
199 Statistic_Viewer_Data
->Statistic_Hash
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
200 Destroy_hash_key
, Destroy_hash_data
);
202 Statistic_Viewer_Data
->HPaned_V
= gtk_hpaned_new();
203 Statistic_Viewer_Data
->Store_M
= gtk_tree_store_new (N_COLUMNS
, G_TYPE_STRING
);
204 Statistic_Viewer_Data
->Tree_V
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (Statistic_Viewer_Data
->Store_M
));
205 g_object_unref (G_OBJECT (Statistic_Viewer_Data
->Store_M
));
207 g_signal_connect (G_OBJECT (Statistic_Viewer_Data
->Tree_V
), "grab-focus",
208 G_CALLBACK (grab_focus
),
209 Statistic_Viewer_Data
);
211 // Setup the selection handler
212 Statistic_Viewer_Data
->Select_C
= gtk_tree_view_get_selection (GTK_TREE_VIEW (Statistic_Viewer_Data
->Tree_V
));
213 gtk_tree_selection_set_mode (Statistic_Viewer_Data
->Select_C
, GTK_SELECTION_SINGLE
);
214 g_signal_connect (G_OBJECT (Statistic_Viewer_Data
->Select_C
), "changed",
215 G_CALLBACK (tree_selection_changed_cb
),
216 Statistic_Viewer_Data
);
218 renderer
= gtk_cell_renderer_text_new ();
219 column
= gtk_tree_view_column_new_with_attributes ("Statistic Name",
223 gtk_tree_view_column_set_alignment (column
, 0.0);
224 // gtk_tree_view_column_set_fixed_width (column, 45);
225 gtk_tree_view_append_column (GTK_TREE_VIEW (Statistic_Viewer_Data
->Tree_V
), column
);
228 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (Statistic_Viewer_Data
->Tree_V
), FALSE
);
230 Statistic_Viewer_Data
->Scroll_Win_Tree
= gtk_scrolled_window_new (NULL
, NULL
);
231 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Statistic_Viewer_Data
->Scroll_Win_Tree
),
232 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
234 gtk_container_add (GTK_CONTAINER (Statistic_Viewer_Data
->Scroll_Win_Tree
), Statistic_Viewer_Data
->Tree_V
);
235 gtk_paned_pack1(GTK_PANED(Statistic_Viewer_Data
->HPaned_V
),Statistic_Viewer_Data
->Scroll_Win_Tree
, TRUE
, FALSE
);
236 gtk_paned_set_position(GTK_PANED(Statistic_Viewer_Data
->HPaned_V
), 160);
238 Statistic_Viewer_Data
->Scroll_Win_Text
= gtk_scrolled_window_new (NULL
, NULL
);
239 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Statistic_Viewer_Data
->Scroll_Win_Text
),
240 GTK_POLICY_AUTOMATIC
,GTK_POLICY_AUTOMATIC
);
242 Statistic_Viewer_Data
->Text_V
= gtk_text_view_new ();
243 g_signal_connect (G_OBJECT (Statistic_Viewer_Data
->Text_V
), "grab-focus",
244 G_CALLBACK (grab_focus
),
245 Statistic_Viewer_Data
);
247 gtk_text_view_set_editable(GTK_TEXT_VIEW(Statistic_Viewer_Data
->Text_V
),FALSE
);
248 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(Statistic_Viewer_Data
->Text_V
),FALSE
);
249 gtk_container_add (GTK_CONTAINER (Statistic_Viewer_Data
->Scroll_Win_Text
), Statistic_Viewer_Data
->Text_V
);
250 gtk_paned_pack2(GTK_PANED(Statistic_Viewer_Data
->HPaned_V
), Statistic_Viewer_Data
->Scroll_Win_Text
, TRUE
, FALSE
);
252 gtk_widget_show(Statistic_Viewer_Data
->Scroll_Win_Tree
);
253 gtk_widget_show(Statistic_Viewer_Data
->Scroll_Win_Text
);
254 gtk_widget_show(Statistic_Viewer_Data
->Tree_V
);
255 gtk_widget_show(Statistic_Viewer_Data
->Text_V
);
256 gtk_widget_show(Statistic_Viewer_Data
->HPaned_V
);
258 g_object_set_data_full(
259 G_OBJECT(Statistic_Viewer_Data
->HPaned_V
),
260 "Statistic_Viewer_Data",
261 Statistic_Viewer_Data
,
262 (GDestroyNotify
)GuiStatistic_free
);
264 /* Add the object's information to the module's array */
265 gStatistic_Viewer_Data_List
= g_slist_append(
266 gStatistic_Viewer_Data_List
,
267 Statistic_Viewer_Data
);
269 get_traceset_stats(Statistic_Viewer_Data
);
271 return Statistic_Viewer_Data
;
274 void grab_focus(GtkWidget
*widget
, gpointer data
)
276 StatisticViewerData
*Statistic_Viewer_Data
= (StatisticViewerData
*)data
;
277 mainWindow
* mw
= Statistic_Viewer_Data
->mw
;
278 SetFocusedPane(mw
, gtk_widget_get_parent(Statistic_Viewer_Data
->HPaned_V
));
282 tree_selection_changed_cb (GtkTreeSelection
*selection
, gpointer data
)
284 StatisticViewerData
*Statistic_Viewer_Data
= (StatisticViewerData
*)data
;
286 GtkTreeModel
*model
= GTK_TREE_MODEL(Statistic_Viewer_Data
->Store_M
);
291 GtkTextIter text_iter
;
292 LttvAttribute
* stats
;
294 if (gtk_tree_selection_get_selected (selection
, &model
, &iter
))
296 gtk_tree_model_get (model
, &iter
, NAME_COLUMN
, &Event
, -1);
298 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(model
),&iter
);
299 str
= gtk_tree_path_to_string (path
);
300 stats
= (LttvAttribute
*)g_hash_table_lookup (Statistic_Viewer_Data
->Statistic_Hash
,str
);
303 buf
= gtk_text_view_get_buffer((GtkTextView
*)Statistic_Viewer_Data
->Text_V
);
304 gtk_text_buffer_set_text(buf
,"Statistic for '", -1);
305 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
306 gtk_text_buffer_insert(buf
, &text_iter
, Event
, strlen(Event
));
307 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
308 gtk_text_buffer_insert(buf
, &text_iter
, "' :\n\n",5);
310 show_statistic(Statistic_Viewer_Data
, stats
, buf
);
316 void Destroy_hash_key(gpointer key
)
321 void Destroy_hash_data(gpointer data
)
326 void get_traceset_stats(StatisticViewerData
* Statistic_Viewer_Data
)
332 end
.tv_sec
= G_MAXULONG
;
333 end
.tv_nsec
= G_MAXULONG
;
335 stateAddEventHooks(Statistic_Viewer_Data
->mw
);
336 statsAddEventHooks(Statistic_Viewer_Data
->mw
);
338 processTraceset(Statistic_Viewer_Data
->mw
, start
, end
, G_MAXULONG
);
340 stateRemoveEventHooks(Statistic_Viewer_Data
->mw
);
341 statsRemoveEventHooks(Statistic_Viewer_Data
->mw
);
343 //establish tree view for stats
344 show_traceset_stats(Statistic_Viewer_Data
);
347 void show_traceset_stats(StatisticViewerData
* Statistic_Viewer_Data
)
352 LttSystemDescription
*desc
;
353 LttvTracesetStats
* tscs
= Statistic_Viewer_Data
->stats
;
354 gchar
* str
, trace_str
[PATH_LENGTH
];
357 GtkTreeStore
* store
= Statistic_Viewer_Data
->Store_M
;
359 if(tscs
->stats
== NULL
) return;
361 gtk_tree_store_append (store
, &iter
, NULL
);
362 gtk_tree_store_set (store
, &iter
,
363 NAME_COLUMN
, "Traceset statistics",
365 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
366 str
= gtk_tree_path_to_string (path
);
367 g_hash_table_insert(Statistic_Viewer_Data
->Statistic_Hash
,
368 (gpointer
)str
, tscs
->stats
);
369 show_tree(Statistic_Viewer_Data
, tscs
->stats
, &iter
);
371 //show stats for all traces
372 ts
= tscs
->parent
.parent
.ts
;
373 nb
= lttv_traceset_number(ts
);
375 for(i
= 0 ; i
< nb
; i
++) {
376 tcs
= (LttvTraceStats
*)(LTTV_TRACESET_CONTEXT(tscs
)->traces
[i
]);
377 desc
= ltt_trace_system_description(tcs
->parent
.parent
.t
);
378 sprintf(trace_str
, "Trace on system %s at time %d secs",
379 desc
->node_name
,desc
->trace_start
.tv_sec
);
381 gtk_tree_store_append (store
, &iter
, NULL
);
382 gtk_tree_store_set (store
, &iter
,NAME_COLUMN
,trace_str
,-1);
383 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
384 str
= gtk_tree_path_to_string (path
);
385 g_hash_table_insert(Statistic_Viewer_Data
->Statistic_Hash
,
386 (gpointer
)str
,tcs
->stats
);
387 show_tree(Statistic_Viewer_Data
, tcs
->stats
, &iter
);
391 void show_tree(StatisticViewerData
* Statistic_Viewer_Data
,
392 LttvAttribute
* stats
, GtkTreeIter
* parent
)
395 LttvAttribute
*subtree
;
396 LttvAttributeName name
;
397 LttvAttributeValue value
;
398 LttvAttributeType type
;
399 gchar
* str
, dir_str
[PATH_LENGTH
];
402 GtkTreeStore
* store
= Statistic_Viewer_Data
->Store_M
;
404 nb
= lttv_attribute_get_number(stats
);
405 for(i
= 0 ; i
< nb
; i
++) {
406 type
= lttv_attribute_get(stats
, i
, &name
, &value
);
409 if(LTTV_IS_ATTRIBUTE(*(value
.v_gobject
))) {
410 sprintf(dir_str
, "%s", g_quark_to_string(name
));
411 subtree
= (LttvAttribute
*)*(value
.v_gobject
);
412 gtk_tree_store_append (store
, &iter
, parent
);
413 gtk_tree_store_set (store
, &iter
,NAME_COLUMN
,dir_str
,-1);
414 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &iter
);
415 str
= gtk_tree_path_to_string (path
);
416 g_hash_table_insert(Statistic_Viewer_Data
->Statistic_Hash
,
417 (gpointer
)str
, subtree
);
418 show_tree(Statistic_Viewer_Data
, subtree
, &iter
);
427 void show_statistic(StatisticViewerData
* Statistic_Viewer_Data
,
428 LttvAttribute
* stats
, GtkTextBuffer
* buf
)
431 LttvAttribute
*subtree
;
432 LttvAttributeName name
;
433 LttvAttributeValue value
;
434 LttvAttributeType type
;
435 gchar type_name
[PATH_LENGTH
], type_value
[PATH_LENGTH
];
436 GtkTextIter text_iter
;
439 nb
= lttv_attribute_get_number(stats
);
440 for(i
= 0 ; i
< nb
; i
++) {
441 type
= lttv_attribute_get(stats
, i
, &name
, &value
);
442 sprintf(type_name
,"%s", g_quark_to_string(name
));
443 type_value
[0] = '\0';
446 sprintf(type_value
, " : %d\n", *value
.v_int
);
449 sprintf(type_value
, " : %u\n", *value
.v_uint
);
452 sprintf(type_value
, " : %ld\n", *value
.v_long
);
455 sprintf(type_value
, " : %lu\n", *value
.v_ulong
);
458 sprintf(type_value
, " : %f\n", (double)*value
.v_float
);
461 sprintf(type_value
, " : %f\n", *value
.v_double
);
464 sprintf(type_value
, " : %10u.%09u\n", value
.v_time
->tv_sec
,
465 value
.v_time
->tv_nsec
);
468 sprintf(type_value
, " : POINTER\n");
471 sprintf(type_value
, " : %s\n", *value
.v_string
);
476 if(strlen(type_value
)){
478 strcat(type_name
,type_value
);
479 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
480 gtk_text_buffer_insert(buf
, &text_iter
, type_name
, strlen(type_name
));
485 sprintf(type_value
, "No statistic information in this directory.\nCheck in subdirectories please.\n");
486 gtk_text_buffer_get_end_iter(buf
, &text_iter
);
487 gtk_text_buffer_insert(buf
, &text_iter
, type_value
, strlen(type_value
));