From: dagenais Date: Wed, 14 Apr 2004 20:13:25 +0000 (+0000) Subject: Moving files around to get rid of the shared include tree. Some other X-Git-Tag: v0.12.20~2988 X-Git-Url: https://git.lttng.org/?a=commitdiff_plain;h=d8f124de0295aea546b6debf5945bfeea2bbeb2a;hp=f95bc8309fe113855266f4445874248b6a285062;p=lttv.git Moving files around to get rid of the shared include tree. Some other cleaning and renaming at the same time. Unfortunately such moves must be done in more than one commit. This is not final yet! git-svn-id: http://ltt.polymtl.ca/svn@501 04897980-b3bd-0310-b5e0-8ef037075253 --- diff --git a/ltt/branches/poly/configure.in b/ltt/branches/poly/configure.in index 193f3414..f245ffd3 100644 --- a/ltt/branches/poly/configure.in +++ b/ltt/branches/poly/configure.in @@ -77,28 +77,31 @@ lttlibdir="${libdir}/ltt" AC_SUBST(lttlibdir) -top_includedir="\$(top_srcdir)/include" -AC_SUBST(top_includedir) +top_guidir="\$(top_srcdir)/lttv/modules/gui" +AC_SUBST(top_guidir) -DEFAULT_INCLUDES="-I\$(top_includedir) -I\$(top_srcdir)" +DEFAULT_INCLUDES="-I\$(top_guidir) -I\$(top_srcdir)" AC_SUBST(DEFAULT_INCLUDES) #CPPFLAGS="${GLIB_CFLAGS}" #AC_SUBST(CPPFLAGS) +lttincludedir="${includedir}/ltt" +AC_SUBST(lttincludedir) + lttvincludedir="${includedir}/lttv" AC_SUBST(lttvincludedir) -lttincludedir="${includedir}/ltt" -AC_SUBST(lttincludedir) +lttvguiincludedir="${includedir}/lttvgui" +AC_SUBST(lttvguiincludedir) AC_CONFIG_FILES([Makefile lttv/Makefile - lttv/main/Makefile + lttv/lttv/Makefile lttv/modules/Makefile lttv/modules/text/Makefile lttv/modules/gui/Makefile - lttv/modules/gui/mainlib/Makefile + lttv/modules/gui/lttvgui/Makefile lttv/modules/gui/main/Makefile lttv/modules/gui/main/src/Makefile lttv/modules/gui/main/pixmaps/Makefile @@ -108,7 +111,5 @@ AC_CONFIG_FILES([Makefile lttv/modules/gui/statistics/Makefile lttd/Makefile ltt/Makefile - include/Makefile - ltt/convert/Makefile - include/lttv/Makefile]) + ltt/convert/Makefile]) AC_OUTPUT diff --git a/ltt/branches/poly/include/Makefile.am b/ltt/branches/poly/include/Makefile.am deleted file mode 100644 index 1a1d52d1..00000000 --- a/ltt/branches/poly/include/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = lttv diff --git a/ltt/branches/poly/include/lttv/Makefile.am b/ltt/branches/poly/include/lttv/Makefile.am deleted file mode 100644 index 2f4c997d..00000000 --- a/ltt/branches/poly/include/lttv/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -lttvinclude_HEADERS = \ - attribute.h\ - batchAnalysis.h\ - common.h\ - filter.h\ - gtktraceset.h\ - gtkmultivpaned.h\ - hook.h\ - iattribute.h\ - lttv.h\ - mainwindow.h\ - menu.h\ - module.h\ - option.h\ - processTrace.h\ - state.h\ - stats.h\ - textDump.h\ - toolbar.h\ - traceset.h\ - lttvfilter.h diff --git a/ltt/branches/poly/include/lttv/attribute.h b/ltt/branches/poly/include/lttv/attribute.h deleted file mode 100644 index e721b3bf..00000000 --- a/ltt/branches/poly/include/lttv/attribute.h +++ /dev/null @@ -1,121 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef ATTRIBUTE_H -#define ATTRIBUTE_H - -#include -#include -#include - -#define LTTV_ATTRIBUTE_TYPE (lttv_attribute_get_type ()) -#define LTTV_ATTRIBUTE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_ATTRIBUTE_TYPE, LttvAttribute)) -#define LTTV_ATTRIBUTE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_ATTRIBUTE_TYPE, LttvAttributeClass)) -#define LTTV_IS_ATTRIBUTE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_ATTRIBUTE_TYPE)) -#define LTTV_IS_ATTRIBUTE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_ATTRIBUTE_TYPE)) -#define LTTV_ATTRIBUTE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_ATTRIBUTE_TYPE, LttvAttributeClass)) - - -typedef struct _LttvAttribute LttvAttribute; -typedef struct _LttvAttributeClass LttvAttributeClass; - -struct _LttvAttribute { - GObject parent; - - /* private members */ - GHashTable *names; - GArray *attributes; -}; - -struct _LttvAttributeClass { - GObjectClass parent; -}; - -GType lttv_attribute_get_type (void); - - -/* The functions exported in the IAttribute interface are also available - directly. */ - - -/* Total number of attributes */ - -unsigned int lttv_attribute_get_number(LttvAttribute *self); - - -/* Container type. Named (fields in struct or elements in a hash table) - or unnamed (elements in an array) attributes, homogeneous type or not. */ - -gboolean lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous); - - -/* Get the i th attribute along with its type and a pointer to its value. */ - -LttvAttributeType lttv_attribute_get(LttvAttribute *self, unsigned i, - LttvAttributeName *name, LttvAttributeValue *v); - - -/* Get the named attribute in the table along with its type and a pointer to - its value. If the named attribute does not exist, the type is LTTV_NONE. */ - -LttvAttributeType lttv_attribute_get_by_name(LttvAttribute *self, - LttvAttributeName name, LttvAttributeValue *v); - - -/* Add an attribute, which must not exist. The name is an empty string for - containers with unnamed attributes. */ - -LttvAttributeValue lttv_attribute_add(LttvAttribute *self, - LttvAttributeName name, LttvAttributeType t); - - -/* Remove an attribute */ - -void lttv_attribute_remove(LttvAttribute *self, unsigned i); - -void lttv_attribute_remove_by_name(LttvAttribute *self, - LttvAttributeName name); - - -/* Create an empty iattribute object and add it as an attribute under the - specified name, or return an existing iattribute attribute. If an - attribute of that name already exists but is not a GObject supporting the - iattribute interface, return NULL. */ - -LttvAttribute* lttv_attribute_find_subdir(LttvAttribute *self, - LttvAttributeName name); - -gboolean lttv_attribute_find(LttvAttribute *self, LttvAttributeName name, - LttvAttributeType t, LttvAttributeValue *v); - - -/* Free recursively a tree of attributes. All contained gobject of type - LttvAttribute are freed (unreferenced) recursively. */ - -void lttv_attribute_recursive_free(LttvAttribute *self); - -/* Add items from a tree of attributes to another tree. */ - -void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src); - -void -lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent); - -void lttv_attribute_read_xml(LttvAttribute *self, FILE *fp); - -#endif // ATTRIBUTE_H diff --git a/ltt/branches/poly/include/lttv/batchAnalysis.h b/ltt/branches/poly/include/lttv/batchAnalysis.h deleted file mode 100644 index 19fda358..00000000 --- a/ltt/branches/poly/include/lttv/batchAnalysis.h +++ /dev/null @@ -1,62 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef BATCH_ANALYSIS_H -#define BATCH_ANALYSIS_H - -/* The batch analysis module defines a main traceset and command line options - to specify the traces in the main traceset. It then processes that - traceset calling hooks lists at various stages of the analysis. - - The hooks lists are defined in the global attributes for these various - stages of the analysis. Loaded modules may add hooks to these lists. - Thus, by requesting that a certain module be loaded, the analysis may - produce additional information as the module adds hooks and these hooks - are called during the analysis. - - The hooks lists defined are as follows. These may be split in more - specific lists eventually to select the hooks applicable to state update, - incremental or batch processing... - - /hooks/traceset/before - Before analyzing a traceset. - - /hooks/traceset/after - After analyzing a traceset. - - /hooks/trace/before - Before each trace. - - /hooks/trace/after - After each trace. - - /hooks/tracefile/before - Before each tracefile. - - /hooks/tracefile/after - After each tracefile. - - /hooks/event/before - Before each event. - - /hooks/event/after - After each event. - -*/ - -#endif // BATCH_ANALYSIS_H diff --git a/ltt/branches/poly/include/lttv/common.h b/ltt/branches/poly/include/lttv/common.h deleted file mode 100644 index a3e557f3..00000000 --- a/ltt/branches/poly/include/lttv/common.h +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Xiangxiu Yang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef COMMON_H -#define COMMON_H - -#include -#include -#include -#include - -#define MAX_NUMBER_EVENT "MAX_NUMBER_EVENT" -#define TRACESET_TIME_SPAN "TRACESET_TIME_SPAN" - -typedef struct _MainWindow MainWindow; -typedef struct _Tab Tab; - -/* constructor of the viewer */ -typedef GtkWidget * (*lttv_constructor)(MainWindow * main_window, - LttvTracesetSelector * s, char *key); -typedef lttv_constructor view_constructor; - -typedef struct _TimeWindow { - LttTime start_time; - LttTime time_width; -} TimeWindow; - -#endif // COMMON_H diff --git a/ltt/branches/poly/include/lttv/filter.h b/ltt/branches/poly/include/lttv/filter.h deleted file mode 100644 index 560c45d1..00000000 --- a/ltt/branches/poly/include/lttv/filter.h +++ /dev/null @@ -1,63 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef FILTER_H -#define FILTER_H - -/* A filter expression consists in nested AND, OR and NOT expressions - involving boolean relation (>, >=, =, !=, <, <=) between event fields and - specific values. It is compiled into an efficient data structure which - is used in functions to check if a given event or tracefile satisfies the - filter. - - The grammar for filters is: - - filter = expression - - expression = "(" expression ")" | "!" expression | - expression "&&" expression | expression "||" expression | - simpleExpression - - simpleExpression = fieldPath op value - - fieldPath = fieldComponent [ "." fieldPath ] - - fieldComponent = name [ "[" integer "]" ] - - value = integer | double | string - -*/ - - -typedef struct _lttv_filter lttv_filter; - - -/* Compile the filter expression into an efficient data structure */ - -lttv_filter *lttv_filter_new(char *expression, lttv_trace *t); - - -/* Check if the tracefile or event satisfies the filter. The arguments are - declared as void * to allow these functions to be used as hooks. */ - -bool lttv_filter_tracefile(void *filter, void *tracefile); - -bool lttv_filter_event(void *filter, void *event); - -#endif // FILTER_H - diff --git a/ltt/branches/poly/include/lttv/gtkdirsel.h b/ltt/branches/poly/include/lttv/gtkdirsel.h deleted file mode 100644 index 103ced2d..00000000 --- a/ltt/branches/poly/include/lttv/gtkdirsel.h +++ /dev/null @@ -1,115 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Xiangxiu Yang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - - -#ifndef __GTK_DIR_SEL_H__ -#define __GTK_DIR_SEL_H__ - - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define GTK_TYPE_DIR_SELECTION (gtk_dir_selection_get_type ()) -#define GTK_DIR_SELECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_DIR_SELECTION, GtkDirSelection)) -#define GTK_DIR_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_DIR_SELECTION, GtkDirSelectionClass)) -#define GTK_IS_DIR_SELECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_DIR_SELECTION)) -#define GTK_IS_DIR_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_DIR_SELECTION)) -#define GTK_DIR_SELECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_DIR_SELECTION, GtkDirSelectionClass)) - - -typedef struct _GtkDirSelection GtkDirSelection; -typedef struct _GtkDirSelectionClass GtkDirSelectionClass; - -struct _GtkDirSelection -{ - GtkDialog parent_instance; - - GtkWidget *dir_list; - GtkWidget *file_list; - GtkWidget *selection_entry; - GtkWidget *selection_text; - GtkWidget *main_vbox; - GtkWidget *ok_button; - GtkWidget *cancel_button; - GtkWidget *help_button; - GtkWidget *history_pulldown; - GtkWidget *history_menu; - GList *history_list; - GtkWidget *fileop_dialog; - GtkWidget *fileop_entry; - gchar *fileop_file; - gpointer cmpl_state; - - GtkWidget *fileop_c_dir; - GtkWidget *fileop_del_file; - GtkWidget *fileop_ren_file; - - GtkWidget *button_area; - GtkWidget *action_area; - - GPtrArray *selected_names; - gchar *last_selected; -}; - -struct _GtkDirSelectionClass -{ - GtkDialogClass parent_class; - - /* Padding for future expansion */ - void (*_gtk_reserved1) (void); - void (*_gtk_reserved2) (void); - void (*_gtk_reserved3) (void); - void (*_gtk_reserved4) (void); -}; - - -GType gtk_dir_selection_get_type (void) G_GNUC_CONST; -GtkWidget* gtk_dir_selection_new (const gchar *title); -void gtk_dir_selection_set_filename (GtkDirSelection *filesel, - const gchar *filename); -/* This function returns the selected filename in the C runtime's - * multibyte string encoding, which may or may not be the same as that - * used by GDK (UTF-8). To convert to UTF-8, call g_filename_to_utf8(). - * The returned string points to a statically allocated buffer and - * should be copied away. - */ -G_CONST_RETURN gchar* gtk_dir_selection_get_filename (GtkDirSelection *filesel); - -void gtk_dir_selection_complete (GtkDirSelection *filesel, - const gchar *pattern); -void gtk_dir_selection_show_fileop_buttons (GtkDirSelection *filesel); -void gtk_dir_selection_hide_fileop_buttons (GtkDirSelection *filesel); - -gchar** gtk_dir_selection_get_selections (GtkDirSelection *filesel); -const gchar * gtk_dir_selection_get_dir (GtkDirSelection *filesel); -void gtk_dir_selection_set_select_multiple (GtkDirSelection *filesel, - gboolean select_multiple); -gboolean gtk_dir_selection_get_select_multiple (GtkDirSelection *filesel); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __GTK_DIR_SEL_H__ */ diff --git a/ltt/branches/poly/include/lttv/gtkmultivpaned.h b/ltt/branches/poly/include/lttv/gtkmultivpaned.h deleted file mode 100644 index ff8334e2..00000000 --- a/ltt/branches/poly/include/lttv/gtkmultivpaned.h +++ /dev/null @@ -1,92 +0,0 @@ - -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Xiangxiu Yang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef __GTK_MULTI_VPANED_H__ -#define __GTK_MULTI_VPANED_H__ - - -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define GTK_TYPE_MULTI_VPANED (gtk_multi_vpaned_get_type ()) -#define GTK_MULTI_VPANED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MULTI_VPANED, GtkMultiVPaned)) -#define GTK_MULTI_VPANED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MULTI_VPANED, GtkMultiVPanedClass)) -#define GTK_IS_MULTI_VPANED(obj ) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MULTI_VPANED)) -#define GTK_IS_MULTI_VPANED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MULTI_VPANED)) -#define GTK_MULTI_VPANED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MULTI_VPANED, GtkMultiVPanedClass)) - - -typedef struct _GtkMultiVPaned GtkMultiVPaned; -typedef struct _GtkMultiVPanedClass GtkMultiVPanedClass; - -struct _GtkMultiVPaned -{ - GtkPaned container; - - /*< public >*/ - GtkPaned * first_pane; - GtkPaned * last_pane; - GtkPaned * focused_pane; - GtkPaned * iter; - guint num_children; - - GtkWidget * vbox; - // GtkWidget * scrollWindow; - // GtkWidget * viewport; - GtkWidget * hscrollbar; - GtkAdjustment *hadjust; - MainWindow * mw; -}; - -struct _GtkMultiVPanedClass -{ - GtkPanedClass parent_class; -}; - - -GType gtk_multi_vpaned_get_type (void) G_GNUC_CONST; -GtkWidget* gtk_multi_vpaned_new (void); - -void gtk_multi_vpaned_set_focus (GtkWidget * widget, gpointer user_data); -void gtk_multi_vpaned_widget_add(GtkMultiVPaned * multi_vpaned, GtkWidget * widget1); -void gtk_multi_vpaned_widget_delete(GtkMultiVPaned * multi_vpaned); -void gtk_multi_vpaned_widget_move_up(GtkMultiVPaned * multi_vpaned); -void gtk_multi_vpaned_widget_move_down(GtkMultiVPaned * multi_vpaned); -void gtk_multi_vpaned_set_adjust(GtkMultiVPaned * multi_vpaned, gboolean first_time); -void gtk_multi_vpaned_set_data(GtkMultiVPaned * multi_vpaned, char * key, gpointer value); -gpointer gtk_multi_vpaned_get_data(GtkMultiVPaned * multi_vpaned, char * key); -GtkWidget * gtk_multi_vpaned_get_widget(GtkMultiVPaned * multi_vpaned); -GtkWidget * gtk_multi_vpaned_get_first_widget(GtkMultiVPaned * multi_vpaned); -GtkWidget * gtk_multi_vpaned_get_next_widget(GtkMultiVPaned * multi_vpaned); -void gtk_multi_vpaned_set_scroll_value(GtkMultiVPaned * multi_vpaned, double value); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __GTK_MULTI_VPANED_H__ */ diff --git a/ltt/branches/poly/include/lttv/gtktraceset.h b/ltt/branches/poly/include/lttv/gtktraceset.h deleted file mode 100644 index 19035482..00000000 --- a/ltt/branches/poly/include/lttv/gtktraceset.h +++ /dev/null @@ -1,476 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Xiangxiu Yang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/* -CHECK Rename to viewer.h - -Things that can happen to a viewer: - -update_time_window -update_current_time -update_traceset -update_filter -show_viewer -update_dividor -?? Reshape, damage ?? - -Things that a viewer can do: - -update_status -set_time_window -set_current_time -update_traceset? -update_filter? -show_viewer? -set_focused_pane -set_hpane_dividor -*/ - - - - -/*! \file gtktraceset.h - * \brief API used by the graphical viewers to interact with their top window. - * - * Main window (gui module) is the place to contain and display viewers. - * Viewers (lttv plugins) interacte with main window through this API and - * events sent by gtk. - * This header file should be included in each graphic module. - * This library is used by graphical modules to interact with the - * tracesetWindow. - * - */ - -#include -#include -#include -#include -#include - -/** - * Function to register a view constructor so that main window can generate - * a toolbar item for the viewer in order to generate a new instance easily. - * It will be called by init function of the module. - * @param ButtonPixmap image shown on the toolbar item. - * @param tooltip tooltip of the toolbar item. - * @param view_constructor constructor of the viewer. - */ - -void toolbar_item_reg(char ** pixmap, char *tooltip, lttv_constructor view_constructor); - - -/** - * Function to unregister the viewer's constructor, release the space - * occupied by pixmap, tooltip and constructor of the viewer. - * It will be called when a module is unloaded. - * @param view_constructor constructor of the viewer which is used as - * a reference to find out where the pixmap and tooltip are. - */ - -void toolbar_item_unreg(lttv_constructor view_constructor); - - -/** - * Function to register a view constructor so that main window can generate - * a menu item for the viewer in order to generate a new instance easily. - * It will be called by init function of the module. - * @param menu_path path of the menu item. - * @param menu_text text of the menu item. - * @param view_constructor constructor of the viewer. - */ - -void menu_item_reg(char *menu_path, char *menu_text, lttv_constructor view_constructor); - - -/** - * Function to unregister the viewer's constructor, release the space - * occupied by menu_path, menu_text and constructor of the viewer. - * It will be called when a module is unloaded. - * @param view_constructor constructor of the viewer which is used as - * a reference to find out where the menu_path and menu_text are. - */ - -void menu_item_unreg(lttv_constructor view_constructor); - - -/** - * Update the status bar whenever something changed in the viewer. - * @param main_win the main window the viewer belongs to. - * @param info the message which will be shown in the status bar. - */ - -void update_status(MainWindow *main_win, char *info); - - -/** - * Function to get the current time window of the current tab. - * It will be called by a viewer's hook function to update the - * time window of the viewer and also be called by the constructor - * of the viewer. - * @param main_win the main window the viewer belongs to. - * @param time_interval a pointer where time interval will be stored. - */ - -void get_time_window(MainWindow *main_win, TimeWindow *time_window); - - -/** - * Function to set the time interval of the current tab. - * It will be called by a viewer's signal handle associated with - * the move_slider signal - * @param main_win the main window the viewer belongs to. - * @param time_interval a pointer where time interval is stored. - */ - -void set_time_window(MainWindow *main_win, TimeWindow *time_window); - -/** - * Function to get the current time/event of the current tab. - * It will be called by a viewer's hook function to update the - * current time/event of the viewer. - * @param main_win the main window the viewer belongs to. - * @param time a pointer where time will be stored. - */ - -void get_current_time(MainWindow *main_win, LttTime *time); - - -/** - * Function to set the current time/event of the current tab. - * It will be called by a viewer's signal handle associated with - * the button-release-event signal - * @param main_win the main window the viewer belongs to. - * @param time a pointer where time is stored. - */ - -void set_current_time(MainWindow *main_win, LttTime *time); - - -/** - * Function to get the traceset from the current tab. - * It will be called by the constructor of the viewer and also be - * called by a hook funtion of the viewer to update its traceset. - * @param main_win the main window the viewer belongs to. - * @param traceset a pointer to a traceset. - */ - -//void get_traceset(MainWindow *main_win, Traceset *traceset); - - -/** - * Function to get the filter of the current tab. - * It will be called by the constructor of the viewer and also be - * called by a hook funtion of the viewer to update its filter. - * @param main_win, the main window the viewer belongs to. - * @param filter, a pointer to a filter. - */ - -//void get_filter(MainWindow *main_win, Filter *filter); - - -/** - * Function to register a hook function for a viewer to set/update its - * time interval. - * It will be called by the constructor of the viewer. - * @param hook hook function of the viewer. Takes a TimeInterval* as call_data. - * @param hook_data hook data associated with the hook function. - * @param main_win the main window the viewer belongs to. - */ - -void reg_update_time_window(LttvHook hook, gpointer hook_data, - MainWindow * main_win); - - -/** - * Function to unregister a viewer's hook function which is used to - * set/update the time interval of the viewer. - * It will be called by the destructor of the viewer. - * @param hook hook function of the viewer. Takes a TimeInterval as call_data. - * @param hook_data hook data associated with the hook function. - * @param main_win the main window the viewer belongs to. - */ - -void unreg_update_time_window(LttvHook hook, gpointer hook_data, - MainWindow * main_win); - - -/** - * Function to register a hook function for a viewer to set/update its - * traceset. - * It will be called by the constructor of the viewer. - * @param hook hook function of the viewer. - * @param hook_data hook data associated with the hook function. - * @param main_win the main window the viewer belongs to. - */ - -void reg_update_traceset(LttvHook hook, gpointer hook_data, - MainWindow * main_win); - - -/** - * Function to unregister a viewer's hook function which is used to - * set/update the traceset of the viewer. - * It will be called by the destructor of the viewer. - * @param hook hook function of the viewer. - * @param hook_data hook data associated with the hook function. - * @param main_win the main window the viewer belongs to. - */ - -void unreg_update_traceset(LttvHook hook, gpointer hook_data, - MainWindow * main_win); - - -/** - * Function to redraw each viewer belonging to the current tab - * @param main_win the main window the viewer belongs to. - */ - -void update_traceset(MainWindow * main_win); - - -/** - * Function to register a hook function for a viewer to set/update its - * filter. - * It will be called by the constructor of the viewer. - * @param hook hook function of the viewer. - * @param hook_data hook data associated with the hook function. - * @param main_win the main window the viewer belongs to. - */ - -void reg_update_filter(LttvHook hook, gpointer hook_data, - MainWindow *main_win); - - -/** - * Function to unregister a viewer's hook function which is used to - * set/update the filter of the viewer. - * It will be called by the destructor of the viewer. - * @param hook hook function of the viewer. - * @param hook_data hook data associated with the hook function. - * @param main_win the main window the viewer belongs to. - */ - -void unreg_update_filter(LttvHook hook, gpointer hook_data, - MainWindow * main_win); - - -/** - * Function to register a hook function for a viewer to set/update its - * current time. - * It will be called by the constructor of the viewer. - * @param hook hook function of the viewer. - * @param hook_data hook data associated with the hook function. - * @param main_win the main window the viewer belongs to. - */ - -void reg_update_current_time(LttvHook hook, gpointer hook_data, - MainWindow *main_win); - - -/** - * Function to unregister a viewer's hook function which is used to - * set/update the current time of the viewer. - * It will be called by the destructor of the viewer. - * @param hook hook function of the viewer. - * @param hook_data hook data associated with the hook function. - * @param main_win the main window the viewer belongs to. - */ - -void unreg_update_current_time(LttvHook hook, gpointer hook_data, - MainWindow * main_win); - - -/** - * Function to register a hook function for a viewer to show - *the content of the viewer. - * It will be called by the constructor of the viewer. - * @param hook hook function of the viewer. - * @param hook_data hook data associated with the hook function. - * @param main_win the main window the viewer belongs to. - */ - -void reg_show_viewer(LttvHook hook, gpointer hook_data, - MainWindow *main_win); - - -/** - * Function to unregister a viewer's hook function which is used to - * show the content of the viewer.. - * It will be called by the destructor of the viewer. - * @param hook hook function of the viewer. - * @param hook_data hook data associated with the hook function. - * @param main_win the main window the viewer belongs to. - */ - -void unreg_show_viewer(LttvHook hook, gpointer hook_data, - MainWindow * main_win); - - -/** - * Function to show each viewer in the current tab. - * It will be called by main window after it called process_traceset - * @param main_win the main window the viewer belongs to. - */ - -void show_viewer(MainWindow *main_win); - - -/** - * Function to set the focused pane (viewer). - * It will be called by a viewer's signal handle associated with - * the grab_focus signal - * @param main_win the main window the viewer belongs to. - * @param paned a pointer to a pane where the viewer is contained. - */ - -void set_focused_pane(MainWindow *main_win, gpointer paned); - - -/** - * Function to register a hook function for a viewer to set/update the - * dividor of the hpane. - * It will be called by the constructor of the viewer. - * @param hook hook function of the viewer. - * @param hook_data hook data associated with the hook function. - * @param main_win the main window the viewer belongs to. - */ - -void reg_update_dividor(LttvHook hook, gpointer hook_data, - MainWindow *main_win); - - -/** - * Function to unregister a viewer's hook function which is used to - * set/update hpane's dividor of the viewer. - * It will be called by the destructor of the viewer. - * @param hook hook function of the viewer. - * @param hook_data hook data associated with the hook function. - * @param main_win the main window the viewer belongs to. - */ - -void unreg_update_dividor(LttvHook hook, gpointer hook_data, - MainWindow *main_win); - - -/** - * Function to set the position of the hpane's dividor (viewer). - * It will be called by a viewer's signal handle associated with - * the motion_notify_event event/signal - * @param main_win the main window the viewer belongs to. - * @param position position of the hpane's dividor. - */ - -void set_hpane_dividor(MainWindow *main_win, gint position); - - -/* -CHECK These functions really should not appear here. Directr calls would -be OK unless there is a linker problem. -*/ -/** - * Function to process traceset. It will call lttv_process_trace, - * each view will call this api to get events. - * @param main_win the main window the viewer belongs to. - * @param start the start time of the first event to be processed. - * @param end the end time of the last event to be processed. - */ - -void process_traceset_api(MainWindow *main_win, LttTime start, - LttTime end, unsigned maxNumEvents); - - -/** - * Function to add hooks into the context of a traceset, - * before reading events from traceset, viewer will call this api to - * register hooks - * @param main_win the main window the viewer belongs to. - * @param LttvHooks hooks to be registered. - */ - -void context_add_hooks_api(MainWindow *main_win , - LttvHooks *before_traceset, - LttvHooks *after_traceset, - LttvHooks *check_trace, - LttvHooks *before_trace, - LttvHooks *after_trace, - LttvHooks *check_tracefile, - LttvHooks *before_tracefile, - LttvHooks *after_tracefile, - LttvHooks *check_event, - LttvHooks *before_event, - LttvHooks *after_event); - - -/** - * Function to remove hooks from the context of a traceset, - * before reading events from traceset, viewer will call this api to - * unregister hooks - * @param main_win the main window the viewer belongs to. - * @param LttvHooks hooks to be registered. - */ - -void context_remove_hooks_api(MainWindow *main_win , - LttvHooks *before_traceset, - LttvHooks *after_traceset, - LttvHooks *check_trace, - LttvHooks *before_trace, - LttvHooks *after_trace, - LttvHooks *check_tracefile, - LttvHooks *before_tracefile, - LttvHooks *after_tracefile, - LttvHooks *check_event, - LttvHooks *before_event, - LttvHooks *after_event); - - -/** - * Function to get the life span of the traceset - * @param main_win the main window the viewer belongs to. - * @param start start time of the traceset. - * @param end end time of the traceset. - */ - -void get_traceset_time_span(MainWindow *main_win, TimeInterval *time_span); - - -/** - * Function to add/remove event hooks for state - * @param main_win the main window the viewer belongs to. - */ - -void state_add_event_hooks_api(MainWindow *main_win ); -void state_remove_event_hooks_api(MainWindow *main_win ); - - -/** - * Function to add/remove event hooks for stats - * @param main_win the main window the viewer belongs to. - */ - -void stats_add_event_hooks_api(MainWindow *main_win ); -void stats_remove_event_hooks_api(MainWindow *main_win ); - - -/** - * Function to get the stats of the traceset - * @param main_win the main window the viewer belongs to. - */ - -LttvTracesetStats* get_traceset_stats_api(MainWindow *main_win); - -LttvTracesetContext* get_traceset_context(MainWindow *main_win); diff --git a/ltt/branches/poly/include/lttv/hook.h b/ltt/branches/poly/include/lttv/hook.h deleted file mode 100644 index 803304c0..00000000 --- a/ltt/branches/poly/include/lttv/hook.h +++ /dev/null @@ -1,127 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef HOOK_H -#define HOOK_H - -#include - -/* A hook is a function to call with the supplied hook data, and with - call site specific data (e.g., hooks for events are called with a - pointer to the current event). */ - -typedef gboolean (*LttvHook)(void *hook_data, void *call_data); - - -/* A list of hooks allows registering hooks to be called later. */ - -typedef GArray LttvHooks; - - -/* Create and destroy a list of hooks */ - -LttvHooks *lttv_hooks_new(); - -void lttv_hooks_destroy(LttvHooks *h); - - -/* Add a hook and its hook data to the list */ - -void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data); - - -/* Add a list of hooks to the list h */ - -void lttv_hooks_add_list(LttvHooks *h, LttvHooks *list); - - -/* Remove a hook from the list. Return the hook data. */ - -void *lttv_hooks_remove(LttvHooks *h, LttvHook f); - - -/* Remove a hook from the list checking that the hook data match. */ - -void lttv_hooks_remove_data(LttvHooks *h, LttvHook f, void *hook_data); - - -/* Remove a list of hooks from the hooks list in h. */ - -void lttv_hooks_remove_data_list(LttvHooks *h, LttvHook *list); - - -/* Return the number of hooks in the list */ - -unsigned lttv_hooks_number(LttvHooks *h); - - -/* Return the hook at the specified position in the list */ - -void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data); - - -/* Remove the specified hook. The position of the following hooks may change */ - -void lttv_hooks_remove_by_position(LttvHooks *h, unsigned i); - - -/* Call all the hooks in the list, each with its hook data, - with the specified call data. Return TRUE if one hook returned TRUE. */ - -gboolean lttv_hooks_call(LttvHooks *h, void *call_data); - - -/* Call the hooks in the list until one returns true, in which case TRUE is - returned. */ - -gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data); - - -/* Sometimes different hooks need to be called based on the case. The - case is represented by an unsigned integer id */ - -typedef GPtrArray LttvHooksById; - - -/* Create and destroy a hooks by id list */ - -LttvHooksById *lttv_hooks_by_id_new(); - -void lttv_hooks_by_id_destroy(LttvHooksById *h); - - -/* Obtain the hooks for a given id, creating a list if needed */ - -LttvHooks *lttv_hooks_by_id_find(LttvHooksById *h, unsigned id); - - -/* Return an id larger than any for which a list exists. */ - -unsigned lttv_hooks_by_id_max_id(LttvHooksById *h); - - -/* Get the list of hooks for an id, NULL if none exists */ - -LttvHooks *lttv_hooks_by_id_get(LttvHooksById *h, unsigned id); - - -/* Remove the list of hooks associated with an id */ - -void lttv_hooks_by_id_remove(LttvHooksById *h, unsigned id); - -#endif // HOOK_H diff --git a/ltt/branches/poly/include/lttv/iattribute.h b/ltt/branches/poly/include/lttv/iattribute.h deleted file mode 100644 index 11dccd10..00000000 --- a/ltt/branches/poly/include/lttv/iattribute.h +++ /dev/null @@ -1,173 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef IATTRIBUTE_H -#define IATTRIBUTE_H - - -#include -#include - -/* The content of a data structure may be seen as an array of pairs of - attribute name and value. This simple model allows generic navigation - and access functions over a wide range of structures. The names are - represented by unique integer identifiers, GQuarks. */ - -typedef GQuark LttvAttributeName; - -typedef enum _LttvAttributeType { - LTTV_INT, LTTV_UINT, LTTV_LONG, LTTV_ULONG, LTTV_FLOAT, LTTV_DOUBLE, - LTTV_TIME, LTTV_POINTER, LTTV_STRING, LTTV_GOBJECT, LTTV_NONE -} LttvAttributeType; - -typedef union LttvAttributeValue { - int *v_int; - unsigned *v_uint; - long *v_long; - unsigned long *v_ulong; - float *v_float; - double *v_double; - LttTime *v_time; - gpointer *v_pointer; - char **v_string; - GObject **v_gobject; -} LttvAttributeValue; - - -/* GObject interface type macros */ - -#define LTTV_IATTRIBUTE_TYPE (lttv_iattribute_get_type ()) -#define LTTV_IATTRIBUTE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_IATTRIBUTE_TYPE, LttvIAttribute)) -#define LTTV_IATTRIBUTE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_IATTRIBUTE_TYPE, LttvIAttributeClass)) -#define LTTV_IS_IATTRIBUTE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_IATTRIBUTE_TYPE)) -#define LTTV_IS_IATTRIBUTE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_IATTRIBUTE_TYPE)) -#define LTTV_IATTRIBUTE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), LTTV_IATTRIBUTE_TYPE, LttvIAttributeClass)) - - -typedef struct _LttvIattribute LttvIAttribute; /* dummy object */ -typedef struct _LttvIAttributeClass LttvIAttributeClass; - - -struct _LttvIAttributeClass { - GTypeInterface parent; - - unsigned int (*get_number) (LttvIAttribute *self); - - gboolean (*named) (LttvIAttribute *self, gboolean *homogeneous); - - LttvAttributeType (*get) (LttvIAttribute *self, unsigned i, - LttvAttributeName *name, LttvAttributeValue *v); - - LttvAttributeType (*get_by_name) (LttvIAttribute *self, - LttvAttributeName name, LttvAttributeValue *v); - - LttvAttributeValue (*add) (LttvIAttribute *self, LttvAttributeName name, - LttvAttributeType t); - - void (*remove) (LttvIAttribute *self, unsigned i); - - void (*remove_by_name) (LttvIAttribute *self, - LttvAttributeName name); - - LttvIAttribute* (*find_subdir) (LttvIAttribute *self, - LttvAttributeName name); -}; - - -GType lttv_iattribute_get_type(void); - - -/* Total number of attributes */ - -unsigned int lttv_iattribute_get_number(LttvIAttribute *self); - - -/* Container type. Named (fields in struct or elements in a hash table) - or unnamed (elements in an array) attributes, homogeneous type or not. */ - -gboolean lttv_iattribute_named(LttvIAttribute *self, gboolean *homogeneous); - - -/* Get the i th attribute along with its type and a pointer to its value. */ - -LttvAttributeType lttv_iattribute_get(LttvIAttribute *self, unsigned i, - LttvAttributeName *name, LttvAttributeValue *v); - - -/* Get the named attribute in the table along with its type and a pointer to - its value. If the named attribute does not exist, the type is LTTV_NONE. */ - -LttvAttributeType lttv_iattribute_get_by_name(LttvIAttribute *self, - LttvAttributeName name, LttvAttributeValue *v); - - -/* Add an attribute, which must not exist. The name is an empty string for - containers with unnamed attributes. Its value is initialized to 0 or NULL - and its pointer returned. */ - -LttvAttributeValue lttv_iattribute_add(LttvIAttribute *self, - LttvAttributeName name, LttvAttributeType t); - - -/* Remove an attribute */ - -void lttv_iattribute_remove(LttvIAttribute *self, unsigned i); - -void lttv_iattribute_remove_by_name(LttvIAttribute *self, - LttvAttributeName name); - - -/* Create an empty iattribute object and add it as an attribute under the - specified name, or return an existing iattribute attribute. If an - attribute of that name already exists but is not a GObject supporting the - iattribute interface, return NULL. */ - -LttvIAttribute* lttv_iattribute_find_subdir(LttvIAttribute *self, - LttvAttributeName name); - - -/* The remaining utility functions are not part of the LttvIAttribute - interface but operate on objects implementing it. */ - -/* Find the named attribute in the table, which must be of the specified type. - If it does not exist, it is created with a default value of 0 (NULL for - pointer types). Since the address of the value is obtained, it may be - changed easily afterwards. The function returns false when the attribute - exists but is of incorrect type. */ - -gboolean lttv_iattribute_find(LttvIAttribute *self, LttvAttributeName name, - LttvAttributeType t, LttvAttributeValue *v); - - -/* Trees of attribute tables may be accessed using a hierarchical path with - components separated by /, like in filesystems */ - -gboolean lttv_iattribute_find_by_path(LttvIAttribute *self, char *path, - LttvAttributeType t, LttvAttributeValue *v); - - -/* Shallow and deep copies */ - -void lttv_iattribute_copy_value(LttvAttributeType t, LttvAttributeValue dest, - LttvAttributeValue src); - -LttvIAttribute *lttv_iattribute_shallow_copy(LttvIAttribute *self); - -LttvIAttribute *lttv_iattribute_deep_copy(LttvIAttribute *self); - -#endif // IATTRIBUTE_H diff --git a/ltt/branches/poly/include/lttv/lttv.h b/ltt/branches/poly/include/lttv/lttv.h deleted file mode 100644 index 27c610a2..00000000 --- a/ltt/branches/poly/include/lttv/lttv.h +++ /dev/null @@ -1,60 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef LTTV_H -#define LTTV_H - -#include - -/* The modules in the visualizer communicate with the main module and - with each other through attributes. There is a global set of attributes */ - -LttvAttribute *lttv_global_attributes(); - -extern gboolean lttv_profile_memory; - -extern int lttv_argc; - -extern char **lttv_argv; - -/* A number of global attributes are initialized before modules are - loaded, for example hooks lists. More global attributes are defined - in individual mudules to store information or to communicate with other - modules (GUI windows, menus...). - - The hooks lists (lttv_hooks) are initialized in the main module and may be - used by other modules. Each corresponds to a specific location in the main - module processing loop. The attribute key and typical usage for each - is indicated. - - /hooks/options/before - Good place to define new command line options to be parsed. - - /hooks/options/after - Read the values set by the command line options. - - /hooks/main/before - - /hooks/main/after - -*/ - -#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format) -#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format) - -#endif // LTTV_H diff --git a/ltt/branches/poly/include/lttv/lttvfilter.h b/ltt/branches/poly/include/lttv/lttvfilter.h deleted file mode 100644 index f2dab415..00000000 --- a/ltt/branches/poly/include/lttv/lttvfilter.h +++ /dev/null @@ -1,89 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Xiangxiu Yang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef LTTV_FILTER_H -#define LTTV_FILTER_H - -#include - - -typedef struct _LttvTracesetSelector LttvTracesetSelector; -typedef struct _LttvTraceSelector LttvTraceSelector; -typedef struct _LttvTracefileSelector LttvTracefileSelector; -typedef struct _LttvEventtypeSelector LttvEventtypeSelector; - - -LttvTracesetSelector *lttv_traceset_selector_new(char * name); -LttvTraceSelector *lttv_trace_selector_new(LttTrace *t); -LttvTracefileSelector *lttv_tracefile_selector_new(LttTracefile *t); -LttvEventtypeSelector *lttv_eventtype_selector_new(LttEventType * et); -void lttv_traceset_selector_destroy(LttvTracesetSelector *s); -void lttv_trace_selector_destroy(LttvTraceSelector *t); -void lttv_tracefile_selector_destroy(LttvTracefileSelector *t); -void lttv_eventtype_selector_destroy(LttvEventtypeSelector *t); - - -void lttv_traceset_selector_trace_add(LttvTracesetSelector *s, - LttvTraceSelector *t); -unsigned lttv_traceset_selector_trace_number(LttvTracesetSelector *s); -LttvTraceSelector *lttv_traceset_selector_trace_get(LttvTracesetSelector *s, - unsigned i); -void lttv_traceset_selector_trace_remove(LttvTracesetSelector *s, - unsigned i); - - -void lttv_trace_selector_tracefile_add(LttvTraceSelector *s, - LttvTracefileSelector *t); -unsigned lttv_trace_selector_tracefile_number(LttvTraceSelector *s); -LttvTracefileSelector *lttv_trace_selector_tracefile_get(LttvTraceSelector *s, - unsigned i); -void lttv_trace_selector_tracefile_remove(LttvTraceSelector *s, unsigned i); - -void lttv_trace_selector_eventtype_add(LttvTraceSelector *s, - LttvEventtypeSelector *et); -unsigned lttv_trace_selector_eventtype_number(LttvTraceSelector *s); -LttvEventtypeSelector *lttv_trace_selector_eventtype_get(LttvTraceSelector *s, - unsigned i); -void lttv_trace_selector_eventtype_remove(LttvTraceSelector *s, unsigned i); - - -void lttv_tracefile_selector_eventtype_add(LttvTracefileSelector *s, - LttvEventtypeSelector *et); -unsigned lttv_tracefile_selector_eventtype_number(LttvTracefileSelector *s); -LttvEventtypeSelector *lttv_tracefile_selector_eventtype_get(LttvTracefileSelector *s, - unsigned i); -void lttv_tracefile_selector_eventtype_remove(LttvTracefileSelector *s, unsigned i); - - -void lttv_trace_selector_set_selected(LttvTraceSelector *s, gboolean g); -void lttv_tracefile_selector_set_selected(LttvTracefileSelector *s, gboolean g); -void lttv_eventtype_selector_set_selected(LttvEventtypeSelector *s, gboolean g); -gboolean lttv_trace_selector_get_selected(LttvTraceSelector *s); -gboolean lttv_tracefile_selector_get_selected(LttvTracefileSelector *s); -gboolean lttv_eventtype_selector_get_selected(LttvEventtypeSelector *s); -char * lttv_traceset_selector_get_name(LttvTracesetSelector *s); -char * lttv_trace_selector_get_name(LttvTraceSelector *s); -char * lttv_tracefile_selector_get_name(LttvTracefileSelector *s); -char * lttv_eventtype_selector_get_name(LttvEventtypeSelector *s); - -LttvEventtypeSelector * lttv_eventtype_selector_clone(LttvEventtypeSelector * s); -void lttv_eventtype_selector_copy(LttvTraceSelector *s, LttvTracefileSelector *d); - - -#endif // LTTV_FILTER_H - diff --git a/ltt/branches/poly/include/lttv/mainwindow.h b/ltt/branches/poly/include/lttv/mainwindow.h deleted file mode 100644 index ffdeefe5..00000000 --- a/ltt/branches/poly/include/lttv/mainwindow.h +++ /dev/null @@ -1,100 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Xiangxiu Yang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef _MAIN_WINDOW_ -#define _MAIN_WINDOW_ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -typedef struct _TracesetInfo { - //FIXME? TracesetContext and stats in same or different variable ? - LttvTracesetStats * traceset_context; - LttvTraceset * traceset; -} TracesetInfo ; - - -struct _MainWindow{ - GtkWidget* mwindow; /* Main Window */ - int window_width; - - /* Status bar information */ - // guint MainSBarContextID; /* Context ID of main status bar */ - // guint BegTimeSBarContextID; /* Context ID of BegTime status bar */ - // guint EndTimeSBarContextID; /* Context ID of EndTime status bar */ - - /* Child windows */ - //openTracesetWindow* OpenTracesetWindow;/* Window to get prof and proc file*/ - //viewTimeFrameWindow* ViewTimeFrameWindow;/*Window to select time frame */ - //gotoEventWindow* GotoEventWindow; /*search for event description*/ - //openFilterWindow* OpenFilterWindow; /* Open a filter selection window */ - GtkWidget* help_contents;/* Window to display help contents */ - GtkWidget* about_box; /* Window about information */ - - // lttv_trace_filter * filter; /* trace filter associated with the window */ - - /* Attributes for trace reading hooks local to the main window */ - LttvIAttribute * attributes; - - Tab * tab; - Tab * current_tab; - - GHashTable * hash_menu_item; - GHashTable * hash_toolbar_item; -}; - - -struct _Tab{ - GtkWidget * label; - GtkMultiVPaned * multi_vpaned; - - // startTime is the left of the visible area. Corresponds to the scrollbar - // value. - // Time_Width is a zoom dependant value (corresponding to page size) - TimeWindow time_window; - - // The current time is the time selected in the visible area by the user, - // not the scrollbar value. - LttTime current_time; - LttvIAttribute * attributes; - - struct _Tab * next; - MainWindow * mw; - - /* Traceset related information */ - TracesetInfo * traceset_info; -}; - -/** - * Remove menu and toolbar item when a module unloaded - */ -void main_window_remove_menu_item(lttv_constructor view_constructor); -void main_window_remove_toolbar_item(lttv_constructor view_constructor); - -#endif /* _MAIN_WINDOW_ */ - - diff --git a/ltt/branches/poly/include/lttv/menu.h b/ltt/branches/poly/include/lttv/menu.h deleted file mode 100644 index ec20c099..00000000 --- a/ltt/branches/poly/include/lttv/menu.h +++ /dev/null @@ -1,47 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Xiangxiu Yang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef MENU_H -#define MENU_H - -#include - -/* constructor of the viewer */ -//typedef GtkWidget* (*lttv_constructor)(void * main_window); - - -typedef GArray LttvMenus; - -typedef struct _lttv_menu_closure { - lttv_constructor con; - char * menuPath; - char * menuText; -} lttv_menu_closure; - - -LttvMenus *lttv_menus_new(); - -void lttv_menus_destroy(LttvMenus *h); - -void lttv_menus_add(LttvMenus *h, lttv_constructor f, char* menuPath, char * menuText); - -gboolean lttv_menus_remove(LttvMenus *h, lttv_constructor f); - -unsigned lttv_menus_number(LttvMenus *h); - -#endif // MENU_H diff --git a/ltt/branches/poly/include/lttv/module.h b/ltt/branches/poly/include/lttv/module.h deleted file mode 100644 index e88b7b92..00000000 --- a/ltt/branches/poly/include/lttv/module.h +++ /dev/null @@ -1,207 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef MODULES_H -#define MODULES_H - -#include - -/* A module contains some functionality which becomes available atfer it is - initialized and before it is destroyed. A module is characterized by a name, - a description (short and long), a list of names of other modules on which - it depends, and an initialization and a destruction function. - - A library contains one or more modules and may be loaded dynamically. - The modules contained in a library are automatically registered through - constructors which are called when the library is loaded. For modules - directly linked with the main program (builtin), the constructors are - called before the main program starts. (However, neither malloc nor glib - functions are used during the registration process). - - The library loading path is a set of directories, where requested - libraries and modules are searched for. -*/ - -typedef struct _LttvModule LttvModule; - -typedef struct _LttvLibrary LttvLibrary; - -typedef void (*LttvModuleInit)(); - -typedef void (*LttvModuleDestroy)(); - -typedef struct _LttvModuleInfo -{ - char *name; - char *short_description; - char *description; - LttvModuleInit init; - LttvModuleDestroy destroy; - LttvLibrary *library; - unsigned require_count; - unsigned use_count; - unsigned prerequisites_number; -} LttvModuleInfo; - - -typedef struct _LttvLibraryInfo -{ - char *name; - char *path; - unsigned load_count; -} LttvLibraryInfo; - - -typedef enum _LttvModuleError -{ - LTTV_MODULE_NOT_FOUND, - LTTV_MODULE_NO_INIT -} LttvModuleError; - - -/* Insure that a module is loaded and initialized. Require count - (number of times the module was required) and use count - (number of times required or used as prerequisite) serve to - insure that a module is destroyed only after it has been released - as many times as it was required (and prerequired). - - The module is searched among the modules currently loaded, then as a - similarly named library to load which should contain the named module. - If the module cannot be found or loaded, NULL is returned and an - explanation is provided in error. */ - -LttvModule *lttv_module_require(char *name, GError **error); - -void lttv_module_release(LttvModule *m); - - -/* Obtain information about the module, including the containing library */ - -void lttv_module_info(LttvModule *m, LttvModuleInfo *info); - - -/* List the modules on which this module depends */ - -unsigned lttv_module_prerequisite_number(LttvModule *m); - -LttvModule *lttv_module_prerequisite_get(LttvModule *m, unsigned i); - - -/* Insure that a library is loaded. A load count insures that a library - is unloaded only after it has been asked to unload as - many times as it was loaded, and its modules are not in use. The library - is searched along the library path if name is a relative pathname. - If the library cannot be found or loaded, NULL is returned and an - explanation is provided in error. */ - -LttvLibrary *lttv_library_load(char *name, GError **error); - -void lttv_library_unload(LttvLibrary *l); - - -/* Obtain information about the library */ - -void lttv_library_info(LttvLibrary *l, LttvLibraryInfo *info); - - -/* List the modules contained in a library */ - -unsigned lttv_library_module_number(LttvLibrary *l); - -LttvModule *lttv_library_module_get(LttvLibrary *l, unsigned i); - - -/* List the currently loaded libraries */ - -unsigned lttv_library_number(); - -LttvLibrary *lttv_library_get(unsigned i); - - - -/* Add or remove directory names to the library search path */ - -void lttv_library_path_add(char *name); - -void lttv_library_path_remove(char *name); - - -/* List the directory names in the library search path */ - -unsigned lttv_library_path_number(); - -char *lttv_library_path_get(unsigned i); - - -/* To define a module, simply call the LTTV_MODULE macro with the needed - arguments: single word name, one line short description, larger - description, initialization function, destruction function, and - list of names for required modules (e.g., "moduleA", "moduleB"). - This will insure that the module is registered at library load time. - - Example: - - LTTV_MODULE("option", "Command line options processing", "...", \ - init, destroy, "moduleA", "moduleB") -*/ - -#define LTTV_MODULE(name, short_desc, desc, init, destroy, ...) \ - \ - static void _LTTV_MODULE_REGISTER(__LINE__)() \ - __attribute__((constructor)); \ - \ - static void _LTTV_MODULE_REGISTER(__LINE__)() \ - { \ - static char *module_prerequisites[] = { __VA_ARGS__ }; \ - \ - static struct _LttvModuleDescription module = { \ - name, short_desc, desc, init, destroy, \ - sizeof(module_prerequisites) / sizeof(char *), \ - module_prerequisites, NULL}; \ - \ - lttv_module_register(&module); \ - } - - -/* Internal structure and function used to register modules, called by - LTTV_MODULE */ - -#define __LTTV_MODULE_REGISTER(line) _lttv_module_register_ ## line -#define _LTTV_MODULE_REGISTER(line) __LTTV_MODULE_REGISTER(line) - -struct _LttvModuleDescription -{ - char *name; - char *short_description; - char *description; - LttvModuleInit init; - LttvModuleDestroy destroy; - unsigned prerequisites_number; - char **prerequisites; - struct _LttvModuleDescription *next; -}; - -void lttv_module_register(struct _LttvModuleDescription *d); - -#endif // MODULES_H - - - - - - diff --git a/ltt/branches/poly/include/lttv/option.h b/ltt/branches/poly/include/lttv/option.h deleted file mode 100644 index fc8f14d5..00000000 --- a/ltt/branches/poly/include/lttv/option.h +++ /dev/null @@ -1,53 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef OPTION_H -#define OPTION_H - -/* Define a new option with a long name (--long_name), a short - one character name (-c), a descriptive text, the argument type, and a - pointer to where the argument value will be stored. For an option of - type LTTV_OPT_NONE, the argument is a boolean value set to true when the - option is present. The option hook is called if non NULL. */ - -typedef enum _LttvOptionType -{LTTV_OPT_NONE, LTTV_OPT_STRING, LTTV_OPT_INT, LTTV_OPT_LONG } -LttvOptionType; - -typedef void (*LttvOptionHook)(void *hook_data); - -void lttv_option_add(const char *long_name, const char char_name, - const char *description, const char *arg_description, - const LttvOptionType t, void *p, - const LttvOptionHook h, void *hook_data); - - -/* Remove an option */ - -void lttv_option_remove(const char *long_name); - - -/* Parse command line options. It is possible to add options (through the - hooks being called) while the parsing is done. The new options will be - used for subsequent command line arguments. */ - -void lttv_option_parse(int argc, char **argv); - -void lttv_option_show_help(void); - -#endif // OPTION_H diff --git a/ltt/branches/poly/include/lttv/processTrace.h b/ltt/branches/poly/include/lttv/processTrace.h deleted file mode 100644 index 6afff0ff..00000000 --- a/ltt/branches/poly/include/lttv/processTrace.h +++ /dev/null @@ -1,288 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef PROCESSTRACE_H -#define PROCESSTRACE_H - -#include -#include -#include -#include - -/* This is the generic part of trace processing. All events within a - certain time interval are accessed and processing hooks are called for - each. The events are examined in monotonically increasing time to more - closely follow the traced system behavior. - - Hooks are called at several different places during the processing: - before traceset, after traceset, check trace, before trace, after trace, - check tracefile, before tracefile, after tracefile, - check_event, before_event, before_event_by_id, - after_event, after_event_by_id. - - In each case the "check" hooks are called first to determine if further - processing of the trace, tracefile or event is wanted. Then, the before - hooks and the after hooks are called. The before hooks for a traceset - are called before those for the contained traces, which are called before - those for the contained tracefiles. The after hooks are called in reverse - order. The event hooks are called after all the before_tracefile hooks - and before all the after_tracefile hooks. - - The hooks receive two arguments, the hook_data and call_data. The hook_data - is specified when the hook is registered and typically links to the - object registering the hook (e.g. a graphical events viewer). The call_data - must contain all the context related to the call. The traceset hooks receive - the LttvTracesetContext provided by the caller. The trace hooks receive - the LttvTraceContext from the traces array in the LttvTracesetContext. - The tracefile and event hooks receive the LttvTracefileContext from - the tracefiles array in the LttvTraceContext. The LttEvent and LttTime - fields in the tracefile context are set to the current event and current - event time before calling the event hooks. No other context field is - modified. - - The contexts in the traces and tracefiles arrays must be allocated by - the caller, either before the call or during the before hooks of the - enclosing traceset or trace. The order in the traces array must - correspond to the lttv_traceset_get function. The order in the tracefiles - arrays must correspond to the ltt_trace_control_tracefile_get and - ltt_trace_per_cpu_tracefile_get functions. The traceset, trace and - tracefile contexts may be subtyped as needed. Indeed, both the contexts - and the hooks are defined by the caller. */ - - -typedef struct _LttvTracesetContext LttvTracesetContext; -typedef struct _LttvTracesetContextClass LttvTracesetContextClass; - -typedef struct _LttvTraceContext LttvTraceContext; -typedef struct _LttvTraceContextClass LttvTraceContextClass; - -typedef struct _LttvTracefileContext LttvTracefileContext; -typedef struct _LttvTracefileContextClass LttvTracefileContextClass; - -#define LTTV_TRACESET_CONTEXT_TYPE (lttv_traceset_context_get_type ()) -#define LTTV_TRACESET_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACESET_CONTEXT_TYPE, LttvTracesetContext)) -#define LTTV_TRACESET_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACESET_CONTEXT_TYPE, LttvTracesetContextClass)) -#define LTTV_IS_TRACESET_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACESET_CONTEXT_TYPE)) -#define LTTV_IS_TRACESET_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACESET_CONTEXT_TYPE)) -#define LTTV_TRACESET_CONTEXT_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACESET_CONTEXT_TYPE, LttvTracesetContextClass)) - -struct _LttvTracesetContext { - GObject parent; - - LttvTraceset *ts; - LttvHooks *before; - LttvHooks *after; - LttvTraceContext **traces; - LttvAttribute *a; - LttvAttribute *ts_a; - TimeInterval *Time_Span; - GTree *pqueue; -}; - -struct _LttvTracesetContextClass { - GObjectClass parent; - - void (*init) (LttvTracesetContext *self, LttvTraceset *ts); - void (*fini) (LttvTracesetContext *self); - LttvTracesetContext* (*new_traceset_context) (LttvTracesetContext *self); - LttvTraceContext* (*new_trace_context) (LttvTracesetContext *self); - LttvTracefileContext* (*new_tracefile_context) (LttvTracesetContext *self); -}; - -GType lttv_traceset_context_get_type (void); - -void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts); - -void lttv_context_fini(LttvTracesetContext *self); - -LttvTracesetContext * -lttv_context_new_traceset_context(LttvTracesetContext *self); - -LttvTraceContext * -lttv_context_new_trace_context(LttvTracesetContext *self); - -LttvTracefileContext * -lttv_context_new_tracefile_context(LttvTracesetContext *self); - - -#define LTTV_TRACE_CONTEXT_TYPE (lttv_trace_context_get_type ()) -#define LTTV_TRACE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACE_CONTEXT_TYPE, LttvTraceContext)) -#define LTTV_TRACE_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACE_CONTEXT_TYPE, LttvTraceContextClass)) -#define LTTV_IS_TRACE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACE_CONTEXT_TYPE)) -#define LTTV_IS_TRACE_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACE_CONTEXT_TYPE)) -#define LTTV_TRACE_CONTEXT_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACE_CONTEXT_TYPE, LttvTraceContextClass)) - -struct _LttvTraceContext { - GObject parent; - - LttvTracesetContext *ts_context; - guint index; /* in ts_context->traces */ - LttTrace *t; - LttvTrace *vt; - LttvHooks *check; - LttvHooks *before; - LttvHooks *after; - LttvTracefileContext **tracefiles; - LttvAttribute *a; - LttvAttribute *t_a; -}; - -struct _LttvTraceContextClass { - GObjectClass parent; -}; - -GType lttv_trace_context_get_type (void); - -#define LTTV_TRACEFILE_CONTEXT_TYPE (lttv_tracefile_context_get_type ()) -#define LTTV_TRACEFILE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACEFILE_CONTEXT_TYPE, LttvTracefileContext)) -#define LTTV_TRACEFILE_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACEFILE_CONTEXT_TYPE, LttvTracefileContextClass)) -#define LTTV_IS_TRACEFILE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACEFILE_CONTEXT_TYPE)) -#define LTTV_IS_TRACEFILE_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACEFILE_CONTEXT_TYPE)) -#define LTTV_TRACEFILE_CONTEXT_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACEFILE_CONTEXT_TYPE, LttvTracefileContextClass)) - -struct _LttvTracefileContext { - GObject parent; - - LttvTraceContext *t_context; - gboolean control; - guint index; /* in ts_context->tracefiles */ - LttTracefile *tf; - LttvHooks *check; - LttvHooks *before; - LttvHooks *after; - LttEvent *e; - LttvHooks *check_event; - LttvHooks *before_event; - LttvHooksById *before_event_by_id; - LttvHooks *after_event; - LttvHooksById *after_event_by_id; - LttTime timestamp; - LttvAttribute *a; -}; - -struct _LttvTracefileContextClass { - GObjectClass parent; -}; - -GType lttv_tracefile_context_get_type (void); - -/* Run through the events in a traceset in sorted order calling all the - hooks appropriately. It starts at the current time and runs until end or - nb_events are processed. */ - -void lttv_process_traceset(LttvTracesetContext *self, LttTime end, - unsigned nb_events); - -/* Process traceset can also be done in smaller pieces calling begin, middle - repeatedly, and end. The middle function return the number of events - processed. It may be larger than nb_events if several events have the - same timestamp. It will be smaller than nb_events if the end time - is reached. */ - -void lttv_process_traceset_begin(LttvTracesetContext *self, LttTime end); - -guint lttv_process_traceset_middle(LttvTracesetContext *self, LttTime end, - unsigned nb_events); - -void lttv_process_traceset_end(LttvTracesetContext *self); - - -void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start); - -void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start); - -void lttv_traceset_context_add_hooks(LttvTracesetContext *self, - LttvHooks *before_traceset, - LttvHooks *after_traceset, - LttvHooks *check_trace, - LttvHooks *before_trace, - LttvHooks *after_trace, - LttvHooks *check_tracefile, - LttvHooks *before_tracefile, - LttvHooks *after_tracefile, - LttvHooks *check_event, - LttvHooks *before_event, - LttvHooks *after_event); - -void lttv_traceset_context_remove_hooks(LttvTracesetContext *self, - LttvHooks *before_traceset, - LttvHooks *after_traceset, - LttvHooks *check_trace, - LttvHooks *before_trace, - LttvHooks *after_trace, - LttvHooks *check_tracefile, - LttvHooks *before_tracefile, - LttvHooks *after_tracefile, - LttvHooks *check_event, - LttvHooks *before_event, - LttvHooks *after_event); - -void lttv_trace_context_add_hooks(LttvTraceContext *self, - LttvHooks *check_trace, - LttvHooks *before_trace, - LttvHooks *after_trace); - -void lttv_trace_context_remove_hooks(LttvTraceContext *self, - LttvHooks *check_trace, - LttvHooks *before_trace, - LttvHooks *after_trace); - -void lttv_tracefile_context_add_hooks(LttvTracefileContext *self, - LttvHooks *check_tracefile, - LttvHooks *before_tracefile, - LttvHooks *after_tracefile, - LttvHooks *check_event, - LttvHooks *before_event, - LttvHooks *after_event); - -void lttv_tracefile_context_remove_hooks(LttvTracefileContext *self, - LttvHooks *check_tracefile, - LttvHooks *before_tracefile, - LttvHooks *after_tracefile, - LttvHooks *check_event, - LttvHooks *before_event, - LttvHooks *after_event); - -void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext *self, - unsigned i, - LttvHooks *before_event_by_id, - LttvHooks *after_event_by_id); - -void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext *self, - unsigned i); - -typedef struct _LttvTraceHook { - LttvHook h; - guint id; - LttField *f1; - LttField *f2; - LttField *f3; -} LttvTraceHook; - - -/* Search in the trace for the id of the named event type within the named - facility. Then, find the three (if non null) named fields. All that - information is then used to fill the LttvTraceHook structure. This - is useful to find the specific id for an event within a trace, for - registering a hook using this structure as event data; - it already contains the (up to three) needed fields handles. */ - -void lttv_trace_find_hook(LttTrace *t, char *facility, char *event_type, - char *field1, char *field2, char *field3, LttvHook h, LttvTraceHook *th); - -#endif // PROCESSTRACE_H diff --git a/ltt/branches/poly/include/lttv/state.h b/ltt/branches/poly/include/lttv/state.h deleted file mode 100644 index 85b90498..00000000 --- a/ltt/branches/poly/include/lttv/state.h +++ /dev/null @@ -1,243 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef STATE_H -#define STATE_H - -#include -#include -#include - -/* The operating system state, kept during the trace analysis, - contains a subset of the real operating system state, - sufficient for the analysis, and possibly organized quite differently. - - The state information is added to LttvTracesetContext, LttvTraceContext - and LttvTracefileContext objects, used by processTrace, through - subtyping. The context objects already reflect the multiple tracefiles - (one per cpu) per trace and multiple traces per trace set. The state - objects defined here simply add fields to the relevant context objects. - - There is no traceset specific state yet. It may eventually contains such - things as clock differences over time. - - The trace state currently consists in a process table. - - The tracefile level state relates to the associated cpu. It contains the - position of the current event in the tracefile (since the state depends on - which events have been processed) and a pointer to the current process, - in the process table, being run on that cpu. - - For each process in the process table, various informations such as exec - file name, pid, ppid and creation time are stored. Each process state also - contains an execution mode stack (e.g. irq within system call, called - from user mode). */ - -typedef struct _LttvTracesetState LttvTracesetState; -typedef struct _LttvTracesetStateClass LttvTracesetStateClass; - -typedef struct _LttvTraceState LttvTraceState; -typedef struct _LttvTraceStateClass LttvTraceStateClass; - -typedef struct _LttvTracefileState LttvTracefileState; -typedef struct _LttvTracefileStateClass LttvTracefileStateClass; - -void lttv_state_add_event_hooks(LttvTracesetState *self); - -void lttv_state_remove_event_hooks(LttvTracesetState *self); - -void lttv_state_save_add_event_hooks(LttvTracesetState *self); - -void lttv_state_save_remove_event_hooks(LttvTracesetState *self); - -void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t); - -/* The LttvProcessState structure defines the current state for each process. - A process can make system calls (in some rare cases nested) and receive - interrupts/faults. For instance, a process may issue a system call, - generate a page fault while reading an argument from user space, and - get caught by an interrupt. To represent these nested states, an - execution mode stack is maintained. The stack bottom is normal user mode - and the top of stack is the current execution mode. - - The execution mode stack tells about the process status, execution mode and - submode (interrupt, system call or IRQ number). All these could be - defined as enumerations but may need extensions (e.g. new process state). - GQuark are thus used. They are as easy to manipulate as integers but have - a string associated, just like enumerations. - - The execution mode is one of "user mode", "kernel thread", "system call", - "interrupt request", "fault". */ - -typedef GQuark LttvExecutionMode; - -extern LttvExecutionMode - LTTV_STATE_USER_MODE, - LTTV_STATE_SYSCALL, - LTTV_STATE_TRAP, - LTTV_STATE_IRQ, - LTTV_STATE_MODE_UNKNOWN; - - -/* The submode number depends on the execution mode. For user mode or kernel - thread, which are the normal mode (execution mode stack bottom), - it is set to "none". For interrupt requests, faults and system calls, - it is set respectively to the interrupt name (e.g. "timer"), fault name - (e.g. "page fault"), and system call name (e.g. "select"). */ - -typedef GQuark LttvExecutionSubmode; - -extern LttvExecutionSubmode - LTTV_STATE_SUBMODE_NONE, - LTTV_STATE_SUBMODE_UNKNOWN; - -/* The process status is one of "running", "wait-cpu" (runnable), or "wait-*" - where "*" describes the resource waited for (e.g. timer, process, - disk...). */ - -typedef GQuark LttvProcessStatus; - -extern LttvProcessStatus - LTTV_STATE_UNNAMED, - LTTV_STATE_WAIT_FORK, - LTTV_STATE_WAIT_CPU, - LTTV_STATE_EXIT, - LTTV_STATE_WAIT, - LTTV_STATE_RUN; - - -typedef struct _LttvExecutionState { - LttvExecutionMode t; - LttvExecutionSubmode n; - LttTime entry; - LttTime change; - LttvProcessStatus s; -} LttvExecutionState; - - -typedef struct _LttvProcessState { - guint pid; - guint ppid; - LttTime creation_time; - LttTime insertion_time; - GQuark name; - GQuark pid_time; - GArray *execution_stack; /* Array of LttvExecutionState */ - LttvExecutionState *state; /* Top of interrupt stack */ - GQuark last_cpu; /* Last CPU where process was scheduled */ - /* opened file descriptors, address map?... */ -} LttvProcessState; - - -LttvProcessState * -lttv_state_find_process(LttvTracefileState *tfs, guint pid); - -LttvProcessState * -lttv_state_find_process_from_trace(LttvTraceState *ts, GQuark cpu, guint pid); - -LttvProcessState * -lttv_state_find_process_or_create(LttvTracefileState *tfs, guint pid); - -LttvProcessState * -lttv_state_create_process(LttvTracefileState *tfs, LttvProcessState *parent, - guint pid); - -void lttv_state_write(LttvTraceState *self, LttTime t, FILE *fp); - -/* The LttvTracesetState, LttvTraceState and LttvTracefileState types - inherit from the corresponding Context objects defined in processTrace. */ - -#define LTTV_TRACESET_STATE_TYPE (lttv_traceset_state_get_type ()) -#define LTTV_TRACESET_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACESET_STATE_TYPE, LttvTracesetState)) -#define LTTV_TRACESET_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACESET_STATE_TYPE, LttvTracesetStateClass)) -#define LTTV_IS_TRACESET_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACESET_STATE_TYPE)) -#define LTTV_IS_TRACESET_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACESET_STATE_TYPE)) -#define LTTV_TRACESET_STATE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACESET_STATE_TYPE, LttvTracesetStateClass)) - -struct _LttvTracesetState { - LttvTracesetContext parent; -}; - -struct _LttvTracesetStateClass { - LttvTracesetContextClass parent; -}; - -GType lttv_traceset_state_get_type (void); - - -#define LTTV_TRACE_STATE_TYPE (lttv_trace_state_get_type ()) -#define LTTV_TRACE_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACE_STATE_TYPE, LttvTraceState)) -#define LTTV_TRACE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACE_STATE_TYPE, LttvTraceStateClass)) -#define LTTV_IS_TRACE_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACE_STATE_TYPE)) -#define LTTV_IS_TRACE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACE_STATE_TYPE)) -#define LTTV_TRACE_STATE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACE_STATE_TYPE, LttvTraceStateClass)) - -struct _LttvTraceState { - LttvTraceContext parent; - - GHashTable *processes; /* LttvProcessState objects indexed by pid */ - guint nb_event, save_interval; - /* Block/char devices, locks, memory pages... */ - GQuark *eventtype_names; - GQuark *syscall_names; - GQuark *trap_names; - GQuark *irq_names; - LttTime *max_time_state_recomputed_in_seek; -}; - -struct _LttvTraceStateClass { - LttvTraceContextClass parent; - - void (*state_save) (LttvTraceState *self, LttvAttribute *container); - void (*state_restore) (LttvTraceState *self, LttvAttribute *container); - void (*state_saved_free) (LttvTraceState *self, LttvAttribute *container); -}; - -GType lttv_trace_state_get_type (void); - -void lttv_state_save(LttvTraceState *self, LttvAttribute *container); - -void lttv_state_restore(LttvTraceState *self, LttvAttribute *container); - -void lttv_state_state_saved_free(LttvTraceState *self, - LttvAttribute *container); - - -#define LTTV_TRACEFILE_STATE_TYPE (lttv_tracefile_state_get_type ()) -#define LTTV_TRACEFILE_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACEFILE_STATE_TYPE, LttvTracefileState)) -#define LTTV_TRACEFILE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACEFILE_STATE_TYPE, LttvTracefileStateClass)) -#define LTTV_IS_TRACEFILE_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACEFILE_STATE_TYPE)) -#define LTTV_IS_TRACEFILE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACEFILE_STATE_TYPE)) -#define LTTV_TRACEFILE_STATE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACEFILE_STATE_TYPE, LttvTracefileStateClass)) - -struct _LttvTracefileState { - LttvTracefileContext parent; - - LttvProcessState *process; - GQuark cpu_name; - guint saved_position; -}; - -struct _LttvTracefileStateClass { - LttvTracefileContextClass parent; -}; - -GType lttv_tracefile_state_get_type (void); - - -#endif // STATE_H diff --git a/ltt/branches/poly/include/lttv/stats.h b/ltt/branches/poly/include/lttv/stats.h deleted file mode 100644 index 37d36945..00000000 --- a/ltt/branches/poly/include/lttv/stats.h +++ /dev/null @@ -1,223 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef STATS_H -#define STATS_H - -#include -#include - -/* The statistics are for a complete time interval. These structures differ - from the system state since they relate to static components of the - system (all processes which existed instead of just the currently - existing processes). - - The basic attributes tree to gather for several different execution modes - (e.g., user mode, syscall, irq), thereafter called the "events tree", - contains the following attributes: the number of events of each type, - the total number of events, the number of bytes written, the time spent - executing, waiting for a resource, waiting for a cpu, and possibly many - others. The name "facility-event_type" below is to be replaced - by specific event types (e.g., core-schedchange, code-syscall_entry...). - - event_types/ - "facility-event_type" - events_count - cpu_time - elapsed_time - wait_time - bytes_written - packets_sent - ... - - The events for several different execution modes are joined together to - form the "execution modes tree". The name "execution mode" is to be replaced - by "system call", "trap", "irq", "user mode" or "kernel thread". - The name "submode" is to be replaced by the specific system call, trap or - irq name. The "submode" is an empty string if none is applicable, which is - the case for "user mode" and "kernel thread". - - An "events tree" for each "execution mode" contains the sum for all its - different submodes. An "events tree" in the "execution modes tree" contains - the sum for all its different execution modes. - - mode_types/ - "execution mode"/ - submodes/ - "submode"/ - Events Tree - events/ - Event Tree - events/ - Events Tree - - Each trace set contains an "execution modes tree". While the traces - come from possibly different systems, which may differ in their system - calls..., most of the system calls will have the same name, even if their - actual internal numeric id differs. Categories such as cpu id and process - id are not kept since these are specific to each system. When several - traces are taken from the same system, these categories may make sense and - could eventually be considered. - - Each trace contains a global "execution modes tree", one for each - cpu and process, and one for each process/cpu combination. The name - "cpu number" stands for the cpu identifier, and "process_id-start_time" - is a unique process identifier composed of the process id - (unique at any given time but which may be reused over time) concatenated - with the process start time. - - modes/ - Execution Modes Tree - cpu/ - "cpu number"/ - Execution Modes Tree - processes/ - "process_id-start_time"/ - exec_file_name - parent - start_time - end_time - modes/ - Execution Modes Tree - cpu/ - "cpu number"/ - Execution Modes Tree - - All the events and derived values (cpu, elapsed and wait time) are - added during the trace analysis in the relevant - trace / processes / * / cpu / * / mode_types / * /submodes / * - "events tree". To achieve this efficiently, each tracefile context - contains a pointer to the current relevant "events tree" and "event_types" - tree within it. - - Once all the events are processed, the total number of events is computed - within each trace / processes / * / cpu / * / mode_types / * / submodes / *. - Then, the "events tree" are summed for all submodes within each mode type - and for all mode types within a processes / * / cpu / * - "execution modes tree". - - Finally, the "execution modes trees" for all cpu within a process, - for all processes, and for all traces are computed. Separately, - the "execution modes tree" for each cpu but for all processes within a - trace are summed in the trace / cpu / * subtrees. - - */ - - -/* The various statistics branch names are GQuarks. They are pre-computed for - easy and efficient access */ - -extern GQuark - LTTV_STATS_PROCESS_UNKNOWN, - LTTV_STATS_PROCESSES, - LTTV_STATS_CPU, - LTTV_STATS_MODE_TYPES, - LTTV_STATS_SUBMODES, - LTTV_STATS_EVENT_TYPES, - LTTV_STATS_CPU_TIME, - LTTV_STATS_ELAPSED_TIME, - LTTV_STATS_EVENTS, - LTTV_STATS_EVENTS_COUNT, - LTTV_STATS_BEFORE_HOOKS, - LTTV_STATS_AFTER_HOOKS; - - -typedef struct _LttvTracesetStats LttvTracesetStats; -typedef struct _LttvTracesetStatsClass LttvTracesetStatsClass; - -typedef struct _LttvTraceStats LttvTraceStats; -typedef struct _LttvTraceStatsClass LttvTraceStatsClass; - -typedef struct _LttvTracefileStats LttvTracefileStats; -typedef struct _LttvTracefileStatsClass LttvTracefileStatsClass; - -gboolean lttv_stats_add_event_hooks(LttvTracesetStats *self); - -gboolean lttv_stats_remove_event_hooks(LttvTracesetStats *self); - -void lttv_stats_sum_traceset(LttvTracesetStats *self); - -void lttv_stats_sum_trace(LttvTraceStats *self); - - -/* The LttvTracesetStats, LttvTraceStats and LttvTracefileStats types - inherit from the corresponding State objects defined in state.h.. */ - -#define LTTV_TRACESET_STATS_TYPE (lttv_traceset_stats_get_type ()) -#define LTTV_TRACESET_STATS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACESET_STATS_TYPE, LttvTracesetStats)) -#define LTTV_TRACESET_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACESET_STATS_TYPE, LttvTracesetStatsClass)) -#define LTTV_IS_TRACESET_STATS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACESET_STATS_TYPE)) -#define LTTV_IS_TRACESET_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACESET_STATS_TYPE)) -#define LTTV_TRACESET_STATS_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACESET_STATS_TYPE, LttvTracesetStatsClass)) - -struct _LttvTracesetStats { - LttvTracesetState parent; - - LttvAttribute *stats; -}; - -struct _LttvTracesetStatsClass { - LttvTracesetStateClass parent; -}; - -GType lttv_traceset_stats_get_type (void); - - -#define LTTV_TRACE_STATS_TYPE (lttv_trace_stats_get_type ()) -#define LTTV_TRACE_STATS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACE_STATS_TYPE, LttvTraceStats)) -#define LTTV_TRACE_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACE_STATS_TYPE, LttvTraceStatsClass)) -#define LTTV_IS_TRACE_STATS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACE_STATS_TYPE)) -#define LTTV_IS_TRACE_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACE_STATS_TYPE)) -#define LTTV_TRACE_STATS_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACE_STATS_TYPE, LttvTraceStatsClass)) - -struct _LttvTraceStats { - LttvTraceState parent; - - LttvAttribute *stats; -}; - -struct _LttvTraceStatsClass { - LttvTraceStateClass parent; -}; - -GType lttv_trace_stats_get_type (void); - - -#define LTTV_TRACEFILE_STATS_TYPE (lttv_tracefile_stats_get_type ()) -#define LTTV_TRACEFILE_STATS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACEFILE_STATS_TYPE, LttvTracefileStats)) -#define LTTV_TRACEFILE_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACEFILE_STATS_TYPE, LttvTracefileStatsClass)) -#define LTTV_IS_TRACEFILE_STATS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACEFILE_STATS_TYPE)) -#define LTTV_IS_TRACEFILE_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACEFILE_STATS_TYPE)) -#define LTTV_TRACEFILE_STATS_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACEFILE_STATS_TYPE, LttvTracefileStatsClass)) - -struct _LttvTracefileStats { - LttvTracefileState parent; - - LttvAttribute *stats; - LttvAttribute *current_events_tree; - LttvAttribute *current_event_types_tree; -}; - -struct _LttvTracefileStatsClass { - LttvTracefileStateClass parent; -}; - -GType lttv_tracefile_stats_get_type (void); - - -#endif // STATS_H diff --git a/ltt/branches/poly/include/lttv/textDump.h b/ltt/branches/poly/include/lttv/textDump.h deleted file mode 100644 index e69de29b..00000000 diff --git a/ltt/branches/poly/include/lttv/toolbar.h b/ltt/branches/poly/include/lttv/toolbar.h deleted file mode 100644 index af12d937..00000000 --- a/ltt/branches/poly/include/lttv/toolbar.h +++ /dev/null @@ -1,46 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Xiangxiu Yang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef TOOLBAR_H -#define TOOLBAR_H - -#include - -/* constructor of the viewer */ -//typedef GtkWidget* (*lttv_constructor)(void * main_window); - - -typedef GArray LttvToolbars; - -typedef struct _lttv_toolbar_closure { - lttv_constructor con; - char * tooltip; - char ** pixmap; -} lttv_toolbar_closure; - -LttvToolbars *lttv_toolbars_new(); - -void lttv_toolbars_destroy(LttvToolbars *h); - -void lttv_toolbars_add(LttvToolbars *h, lttv_constructor f, char* tooltip, char ** pixmap); - -gboolean lttv_toolbars_remove(LttvToolbars *h, lttv_constructor f); - -unsigned lttv_toolbars_number(LttvToolbars *h); - -#endif // TOOLBAR_H diff --git a/ltt/branches/poly/include/lttv/traceset.h b/ltt/branches/poly/include/lttv/traceset.h deleted file mode 100644 index 9d29d7a3..00000000 --- a/ltt/branches/poly/include/lttv/traceset.h +++ /dev/null @@ -1,69 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef TRACESET_H -#define TRACESET_H - -#include -#include -#include - -/* A traceset is a set of traces to be analyzed together. */ - -typedef struct _LttvTraceset LttvTraceset; - -typedef struct _LttvTrace LttvTrace; - -/* Tracesets may be added to, removed from and their content listed. */ - -LttvTraceset *lttv_traceset_new(); - -char * lttv_traceset_name(LttvTraceset * s); - -LttvTrace *lttv_trace_new(LttTrace *t); - -LttvTraceset *lttv_traceset_copy(LttvTraceset *s_orig); - -LttvTraceset *lttv_traceset_load(const gchar *filename); - -gint lttv_traceset_save(LttvTraceset *s); - -void lttv_traceset_destroy(LttvTraceset *s); - -void lttv_trace_destroy(LttvTrace *t); - -void lttv_traceset_add(LttvTraceset *s, LttvTrace *t); - -unsigned lttv_traceset_number(LttvTraceset *s); - -LttvTrace *lttv_traceset_get(LttvTraceset *s, unsigned i); - -void lttv_traceset_remove(LttvTraceset *s, unsigned i); - -/* An attributes table is attached to the set and to each trace in the set. */ - -LttvAttribute *lttv_traceset_attribute(LttvTraceset *s); - -LttvAttribute *lttv_trace_attribute(LttvTrace *t); - -LttTrace *lttv_trace(LttvTrace *t); - -guint lttv_trace_get_ref_number(LttvTrace * t); - -#endif // TRACESET_H - diff --git a/ltt/branches/poly/lttv/lttv/Makefile.am b/ltt/branches/poly/lttv/lttv/Makefile.am new file mode 100644 index 00000000..2023fc93 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/Makefile.am @@ -0,0 +1,32 @@ +AM_CFLAGS = $(GLIB_CFLAGS) +LIBS += $(GLIB_LIBS) -lgobject-2.0 -L$(top_srcdir)/ltt -ltraceread + +bin_PROGRAMS = lttv + +INCLUDES = \ + -DPACKAGE_PLUGIN_DIR=\""$(lttvplugindir)"\" \ + @PACKAGE_CFLAGS@ \ + $(DEFAULT_INCLUDES) + +libdir = ${lttvplugindir} + +lttvinclude_HEADERS = \ + attribute.h\ + hook.h\ + iattribute.h\ + lttv.h\ + module.h\ + option.h\ + state.h\ + stats.h\ + tracecontext.h\ + traceset.h + +noinst_HEADERS = \ + filter.h + +lttv_SOURCES = batchtest.c main.c module.c option.c \ + hook.c attribute.c \ + iattribute.c state.c stats.c \ + processTrace.c traceset.c + diff --git a/ltt/branches/poly/lttv/lttv/attribute.c b/ltt/branches/poly/lttv/lttv/attribute.c new file mode 100644 index 00000000..a3f8ab9a --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/attribute.c @@ -0,0 +1,561 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include +#include + +typedef union _AttributeValue { + int dv_int; + unsigned dv_uint; + long dv_long; + unsigned long dv_ulong; + float dv_float; + double dv_double; + LttTime dv_time; + gpointer dv_pointer; + char *dv_string; + GObject *dv_gobject; +} AttributeValue; + + +typedef struct _Attribute { + LttvAttributeName name; + LttvAttributeType type; + AttributeValue value; +} Attribute; + + +LttvAttributeValue address_of_value(LttvAttributeType t, AttributeValue *v) +{ + LttvAttributeValue va; + + switch(t) { + case LTTV_INT: va.v_int = &v->dv_int; break; + case LTTV_UINT: va.v_uint = &v->dv_uint; break; + case LTTV_LONG: va.v_long = &v->dv_long; break; + case LTTV_ULONG: va.v_ulong = &v->dv_ulong; break; + case LTTV_FLOAT: va.v_float = &v->dv_float; break; + case LTTV_DOUBLE: va.v_double = &v->dv_double; break; + case LTTV_TIME: va.v_time = &v->dv_time; break; + case LTTV_POINTER: va.v_pointer = &v->dv_pointer; break; + case LTTV_STRING: va.v_string = &v->dv_string; break; + case LTTV_GOBJECT: va.v_gobject = &v->dv_gobject; break; + } + return va; +} + + +AttributeValue init_value(LttvAttributeType t) +{ + AttributeValue v; + + switch(t) { + case LTTV_INT: v.dv_int = 0; break; + case LTTV_UINT: v.dv_uint = 0; break; + case LTTV_LONG: v.dv_long = 0; break; + case LTTV_ULONG: v.dv_ulong = 0; break; + case LTTV_FLOAT: v.dv_float = 0; break; + case LTTV_DOUBLE: v.dv_double = 0; break; + case LTTV_TIME: v.dv_time.tv_sec = 0; v.dv_time.tv_nsec = 0; break; + case LTTV_POINTER: v.dv_pointer = NULL; break; + case LTTV_STRING: v.dv_string = NULL; break; + case LTTV_GOBJECT: v.dv_gobject = NULL; break; + } + return v; +} + + +unsigned int +lttv_attribute_get_number(LttvAttribute *self) +{ + return self->attributes->len; +} + + +gboolean +lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous) +{ + *homogeneous = FALSE; + return TRUE; +} + + +LttvAttributeType +lttv_attribute_get(LttvAttribute *self, unsigned i, LttvAttributeName *name, + LttvAttributeValue *v) +{ + Attribute *a; + + a = &g_array_index(self->attributes, Attribute, i); + *name = a->name; + *v = address_of_value(a->type, &(a->value)); + return a->type; +} + + +LttvAttributeType +lttv_attribute_get_by_name(LttvAttribute *self, LttvAttributeName name, + LttvAttributeValue *v) +{ + Attribute *a; + + unsigned i; + + gpointer p; + + p = g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); + if(p == NULL) return LTTV_NONE; + + i = GPOINTER_TO_UINT(p); + i--; + a = &g_array_index(self->attributes, Attribute, i); + *v = address_of_value(a->type, &(a->value)); + return a->type; +} + + +LttvAttributeValue +lttv_attribute_add(LttvAttribute *self, LttvAttributeName name, + LttvAttributeType t) +{ + unsigned i; + + Attribute a, *pa; + + i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); + if(i != 0) g_error("duplicate entry in attribute table"); + + a.name = name; + a.type = t; + a.value = init_value(t); + g_array_append_val(self->attributes, a); + i = self->attributes->len - 1; + pa = &g_array_index(self->attributes, Attribute, i); + g_hash_table_insert(self->names, GUINT_TO_POINTER(name), + GUINT_TO_POINTER(i + 1)); + return address_of_value(t, &(pa->value)); +} + + +/* Remove an attribute */ + +void +lttv_attribute_remove(LttvAttribute *self, unsigned i) +{ + Attribute *a; + + a = &g_array_index(self->attributes, Attribute, i); + + /* Remove the array element and its entry in the name index */ + + g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name)); + g_array_remove_index_fast(self->attributes, i); + + /* The element used to replace the removed element has its index entry + all wrong now. Reinsert it with its new position. */ + + if(self->attributes->len != i){ + g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name)); + g_hash_table_insert(self->names, GUINT_TO_POINTER(a->name), GUINT_TO_POINTER(i + 1)); + } +} + +void +lttv_attribute_remove_by_name(LttvAttribute *self, LttvAttributeName name) +{ + unsigned i; + + i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); + if(i == 0) g_error("remove by name non existent attribute"); + + lttv_attribute_remove(self, i - 1); +} + +/* Create an empty iattribute object and add it as an attribute under the + specified name, or return an existing iattribute attribute. If an + attribute of that name already exists but is not a GObject supporting the + iattribute interface, return NULL. */ + +/*CHECK*/LttvAttribute* +lttv_attribute_find_subdir(LttvAttribute *self, LttvAttributeName name) +{ + unsigned i; + + Attribute a; + + LttvAttribute *new; + + i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); + if(i != 0) { + a = g_array_index(self->attributes, Attribute, i - 1); + if(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject)) { + return LTTV_ATTRIBUTE(a.value.dv_gobject); + } + else return NULL; + } + new = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); + *(lttv_attribute_add(self, name, LTTV_GOBJECT).v_gobject) = G_OBJECT(new); + return (LttvAttribute *)new; +} + +gboolean +lttv_attribute_find(LttvAttribute *self, LttvAttributeName name, + LttvAttributeType t, LttvAttributeValue *v) +{ + unsigned i; + + Attribute *a; + + i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); + if(i != 0) { + a = &g_array_index(self->attributes, Attribute, i - 1); + if(a->type != t) return FALSE; + *v = address_of_value(t, &(a->value)); + return TRUE; + } + + *v = lttv_attribute_add(self, name, t); + return TRUE; +} + + +void lttv_attribute_recursive_free(LttvAttribute *self) +{ + int i, nb; + + Attribute *a; + + nb = self->attributes->len; + + for(i = 0 ; i < nb ; i++) { + a = &g_array_index(self->attributes, Attribute, i); + if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) { + lttv_attribute_recursive_free((LttvAttribute *)(a->value.dv_gobject)); + } + } + g_object_unref(self); +} + + +void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src) +{ + int i, nb; + + Attribute *a; + + LttvAttributeValue value; + + nb = src->attributes->len; + + for(i = 0 ; i < nb ; i++) { + a = &g_array_index(src->attributes, Attribute, i); + if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) { + lttv_attribute_recursive_add( + /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir(dest, a->name), + (LttvAttribute *)(a->value.dv_gobject)); + } + else { + g_assert(lttv_attribute_find(dest, a->name, a->type, &value)); + switch(a->type) { + case LTTV_INT: + *value.v_int += a->value.dv_int; + break; + case LTTV_UINT: + *value.v_uint += a->value.dv_uint; + break; + case LTTV_LONG: + *value.v_long += a->value.dv_long; + break; + case LTTV_ULONG: + *value.v_ulong += a->value.dv_ulong; + break; + case LTTV_FLOAT: + *value.v_float += a->value.dv_float; + break; + case LTTV_DOUBLE: + *value.v_double += a->value.dv_double; + break; + case LTTV_TIME: + *value.v_time = ltt_time_add(*value.v_time, a->value.dv_time); + break; + case LTTV_POINTER: + break; + case LTTV_STRING: + break; + case LTTV_GOBJECT: + break; + case LTTV_NONE: + break; + } + } + } +} + + +static void +print_indent(FILE *fp, int pos) +{ + int i; + + for(i = 0 ; i < pos ; i++) putc(' ', fp); +} + + +void +lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent) +{ + int i, nb; + + Attribute *a; + + nb = self->attributes->len; + + fprintf(fp,"\n"); + for(i = 0 ; i < nb ; i++) { + a = &g_array_index(self->attributes, Attribute, i); + print_indent(fp, pos); + fprintf(fp, "name); + if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) { + fprintf(fp, "TYPE=ATTRS>"); + lttv_attribute_write_xml((LttvAttribute *)(a->value.dv_gobject), fp, + pos + indent, indent); + } + else { + switch(a->type) { + case LTTV_INT: + fprintf(fp, "TYPE=INT VALUE=%d/>\n", a->value.dv_int); + break; + case LTTV_UINT: + fprintf(fp, "TYPE=UINT VALUE=%u/>\n", a->value.dv_uint); + break; + case LTTV_LONG: + fprintf(fp, "TYPE=LONG VALUE=%ld/>\n", a->value.dv_long); + break; + case LTTV_ULONG: + fprintf(fp, "TYPE=ULONG VALUE=%lu/>\n", a->value.dv_ulong); + break; + case LTTV_FLOAT: + fprintf(fp, "TYPE=FLOAT VALUE=%f/>\n", a->value.dv_float); + break; + case LTTV_DOUBLE: + fprintf(fp, "TYPE=DOUBLE VALUE=%f/>\n", a->value.dv_double); + break; + case LTTV_TIME: + fprintf(fp, "TYPE=TIME SEC=%u NSEC=%u/>\n", a->value.dv_time.tv_sec, + a->value.dv_time.tv_nsec); + break; + case LTTV_POINTER: + fprintf(fp, "TYPE=POINTER VALUE=%p/>\n", a->value.dv_pointer); + break; + case LTTV_STRING: + fprintf(fp, "TYPE=STRING VALUE=\"%s\"/>\n", a->value.dv_string); + break; + case LTTV_GOBJECT: + fprintf(fp, "TYPE=GOBJECT VALUE=%p/>\n", a->value.dv_gobject); + break; + case LTTV_NONE: + fprintf(fp, "TYPE=NONE/>\n"); + break; + } + } + } + print_indent(fp, pos); + fprintf(fp,"\n"); +} + + +void +lttv_attribute_read_xml(LttvAttribute *self, FILE *fp) +{ + int i, nb, res; + + Attribute *a; + + char buffer[256], type[10]; + + LttvAttributeName name; + + LttvAttributeValue value; + + LttvAttribute *subtree; + + fscanf(fp,""); + while(1) { + res = fscanf(fp, "]", buffer, type); + g_assert(res == 2); + name = g_quark_from_string(buffer); + if(strcmp(type, "ATTRS") == 0) { + fscanf(fp, ">"); + subtree = lttv_attribute_find_subdir(self, name); + lttv_attribute_read_xml(subtree, fp); + } + else if(strcmp(type, "INT") == 0) { + value = lttv_attribute_add(self, name, LTTV_INT); + res = fscanf(fp, " VALUE=%d/>", value.v_int); + g_assert(res == 1); + } + else if(strcmp(type, "UINT") == 0) { + value = lttv_attribute_add(self, name, LTTV_UINT); + res = fscanf(fp, " VALUE=%u/>", value.v_uint); + g_assert(res == 1); + } + else if(strcmp(type, "LONG") == 0) { + value = lttv_attribute_add(self, name, LTTV_LONG); + res = fscanf(fp, " VALUE=%ld/>", value.v_long); + g_assert(res == 1); + } + else if(strcmp(type, "ULONG") == 0) { + value = lttv_attribute_add(self, name, LTTV_ULONG); + res = fscanf(fp, " VALUE=%lu/>", value.v_ulong); + g_assert(res == 1); + } + else if(strcmp(type, "FLOAT") == 0) { + float d; + value = lttv_attribute_add(self, name, LTTV_FLOAT); + res = fscanf(fp, " VALUE=%f/>", &d); + *(value.v_float) = d; + g_assert(res == 1); + } + else if(strcmp(type, "DOUBLE") == 0) { + value = lttv_attribute_add(self, name, LTTV_DOUBLE); + res = fscanf(fp, " VALUE=%f/>", value.v_double); + g_assert(res == 1); + } + else if(strcmp(type, "TIME") == 0) { + value = lttv_attribute_add(self, name, LTTV_TIME); + res = fscanf(fp, " SEC=%u NSEC=%u/>", &(value.v_time->tv_sec), + &(value.v_time->tv_nsec)); + g_assert(res == 2); + } + else if(strcmp(type, "POINTER") == 0) { + value = lttv_attribute_add(self, name, LTTV_POINTER); + res = fscanf(fp, " VALUE=%p/>", value.v_pointer); + g_error("Cannot read a pointer"); + } + else if(strcmp(type, "STRING") == 0) { + value = lttv_attribute_add(self, name, LTTV_STRING); + res = fscanf(fp, " VALUE=\"%256[^\"]\"/>", buffer); + *(value.v_string) = g_strdup(buffer); + g_assert(res == 1); + } + else if(strcmp(type, "GOBJECT") == 0) { + value = lttv_attribute_add(self, name, LTTV_GOBJECT); + res = fscanf(fp, " VALUE=%p/>", value.v_gobject); + g_error("Cannot read a pointer"); + } + else if(strcmp(type, "NONE") == 0) { + value = lttv_attribute_add(self, name, LTTV_NONE); + fscanf(fp, "/>"); + } + else g_error("Unknown type to read"); + } + fscanf(fp,""); +} + + +static void +attribute_interface_init (gpointer g_iface, gpointer iface_data) +{ + LttvIAttributeClass *klass = (LttvIAttributeClass *)g_iface; + + klass->get_number = (unsigned int (*) (LttvIAttribute *self)) + lttv_attribute_get_number; + + klass->named = (gboolean (*) (LttvIAttribute *self, gboolean *homogeneous)) + lttv_attribute_named; + + klass->get = (LttvAttributeType (*) (LttvIAttribute *self, unsigned i, + LttvAttributeName *name, LttvAttributeValue *v)) lttv_attribute_get; + + klass->get_by_name = (LttvAttributeType (*) (LttvIAttribute *self, + LttvAttributeName name, LttvAttributeValue *v)) + lttv_attribute_get_by_name; + + klass->add = (LttvAttributeValue (*) (LttvIAttribute *self, + LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add; + + klass->remove = (void (*) (LttvIAttribute *self, unsigned i)) + lttv_attribute_remove; + + klass->remove_by_name = (void (*) (LttvIAttribute *self, + LttvAttributeName name)) lttv_attribute_remove_by_name; + + klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self, + LttvAttributeName name)) lttv_attribute_find_subdir; +} + + +static void +attribute_instance_init (GTypeInstance *instance, gpointer g_class) +{ + LttvAttribute *self = (LttvAttribute *)instance; + self->names = g_hash_table_new(g_direct_hash, g_direct_equal); + self->attributes = g_array_new(FALSE, FALSE, sizeof(Attribute)); +} + + +static void +attribute_finalize (LttvAttribute *self) +{ + g_hash_table_destroy(self->names); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "attribute_finalize()"); + g_array_free(self->attributes, TRUE); + G_OBJECT_CLASS(g_type_class_peek_parent( + g_type_class_peek(LTTV_ATTRIBUTE_TYPE)))->finalize(G_OBJECT(self)); +} + + +static void +attribute_class_init (LttvAttributeClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = (void (*)(GObject *self))attribute_finalize; +} + +GType +lttv_attribute_get_type (void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof (LttvAttributeClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) attribute_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (LttvAttribute), + 0, /* n_preallocs */ + (GInstanceInitFunc) attribute_instance_init /* instance_init */ + }; + + static const GInterfaceInfo iattribute_info = { + (GInterfaceInitFunc) attribute_interface_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + type = g_type_register_static (G_TYPE_OBJECT, "LttvAttributeType", &info, + 0); + g_type_add_interface_static (type, LTTV_IATTRIBUTE_TYPE, &iattribute_info); + } + return type; +} + + diff --git a/ltt/branches/poly/lttv/lttv/attribute.h b/ltt/branches/poly/lttv/lttv/attribute.h new file mode 100644 index 00000000..e721b3bf --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/attribute.h @@ -0,0 +1,121 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef ATTRIBUTE_H +#define ATTRIBUTE_H + +#include +#include +#include + +#define LTTV_ATTRIBUTE_TYPE (lttv_attribute_get_type ()) +#define LTTV_ATTRIBUTE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_ATTRIBUTE_TYPE, LttvAttribute)) +#define LTTV_ATTRIBUTE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_ATTRIBUTE_TYPE, LttvAttributeClass)) +#define LTTV_IS_ATTRIBUTE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_ATTRIBUTE_TYPE)) +#define LTTV_IS_ATTRIBUTE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_ATTRIBUTE_TYPE)) +#define LTTV_ATTRIBUTE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_ATTRIBUTE_TYPE, LttvAttributeClass)) + + +typedef struct _LttvAttribute LttvAttribute; +typedef struct _LttvAttributeClass LttvAttributeClass; + +struct _LttvAttribute { + GObject parent; + + /* private members */ + GHashTable *names; + GArray *attributes; +}; + +struct _LttvAttributeClass { + GObjectClass parent; +}; + +GType lttv_attribute_get_type (void); + + +/* The functions exported in the IAttribute interface are also available + directly. */ + + +/* Total number of attributes */ + +unsigned int lttv_attribute_get_number(LttvAttribute *self); + + +/* Container type. Named (fields in struct or elements in a hash table) + or unnamed (elements in an array) attributes, homogeneous type or not. */ + +gboolean lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous); + + +/* Get the i th attribute along with its type and a pointer to its value. */ + +LttvAttributeType lttv_attribute_get(LttvAttribute *self, unsigned i, + LttvAttributeName *name, LttvAttributeValue *v); + + +/* Get the named attribute in the table along with its type and a pointer to + its value. If the named attribute does not exist, the type is LTTV_NONE. */ + +LttvAttributeType lttv_attribute_get_by_name(LttvAttribute *self, + LttvAttributeName name, LttvAttributeValue *v); + + +/* Add an attribute, which must not exist. The name is an empty string for + containers with unnamed attributes. */ + +LttvAttributeValue lttv_attribute_add(LttvAttribute *self, + LttvAttributeName name, LttvAttributeType t); + + +/* Remove an attribute */ + +void lttv_attribute_remove(LttvAttribute *self, unsigned i); + +void lttv_attribute_remove_by_name(LttvAttribute *self, + LttvAttributeName name); + + +/* Create an empty iattribute object and add it as an attribute under the + specified name, or return an existing iattribute attribute. If an + attribute of that name already exists but is not a GObject supporting the + iattribute interface, return NULL. */ + +LttvAttribute* lttv_attribute_find_subdir(LttvAttribute *self, + LttvAttributeName name); + +gboolean lttv_attribute_find(LttvAttribute *self, LttvAttributeName name, + LttvAttributeType t, LttvAttributeValue *v); + + +/* Free recursively a tree of attributes. All contained gobject of type + LttvAttribute are freed (unreferenced) recursively. */ + +void lttv_attribute_recursive_free(LttvAttribute *self); + +/* Add items from a tree of attributes to another tree. */ + +void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src); + +void +lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent); + +void lttv_attribute_read_xml(LttvAttribute *self, FILE *fp); + +#endif // ATTRIBUTE_H diff --git a/ltt/branches/poly/lttv/lttv/batchtest.c b/ltt/branches/poly/lttv/lttv/batchtest.c new file mode 100644 index 00000000..2fc7fd99 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/batchtest.c @@ -0,0 +1,702 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/* This module inserts a hook in the program main loop. This hook processes + all the events in the main tracefile while testing the speed and + functionality of the state and stats computations. */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static LttvTraceset *traceset; + +static LttvHooks + *before_traceset, + *after_traceset, + *before_trace, + *after_trace, + *before_tracefile, + *after_tracefile, + *before_event, + *after_event, + *main_hooks; + +static char *a_trace; + +static char *a_dump_tracefiles; + +static char *a_save_sample; + +static int + a_sample_interval, + a_sample_number, + a_save_interval; + +static gboolean + a_trace_event, + a_save_state_copy, + a_test1, + a_test2, + a_test3, + a_test4, + a_test5, + a_test6, + a_test7, + a_test_all; + +LttEventPosition *a_event_position; + +typedef struct _save_state { + guint count; + FILE *fp; + guint interval; + guint position; + guint size; + LttTime *write_time; + guint version; +} SaveState; + + +static void lttv_trace_option(void *hook_data) +{ + LttTrace *trace; + + trace = ltt_trace_open(a_trace); + if(trace == NULL) g_critical("cannot open trace %s", a_trace); + lttv_traceset_add(traceset, lttv_trace_new(trace)); +} + +static double get_time() +{ + GTimeVal gt; + + g_get_current_time(>); + return gt.tv_sec + (double)gt.tv_usec / (double)1000000.0; +} + +static double run_one_test(LttvTracesetState *ts, LttTime start, LttTime end) +{ + double t0, t1; + + int i; + + lttv_traceset_context_add_hooks(&ts->parent, + before_traceset, after_traceset, NULL, before_trace, after_trace, + NULL, before_tracefile, after_tracefile, NULL, before_event, after_event); + + for(i = 0 ; i < lttv_traceset_number(traceset) ; i++) { + ((LttvTraceState *)(ts->parent.traces[i]))->save_interval =a_save_interval; + } + + t0 = get_time(); + lttv_state_traceset_seek_time_closest(ts, start); + lttv_process_traceset(&ts->parent, end, G_MAXULONG); + t1 = get_time(); + + lttv_traceset_context_remove_hooks(&ts->parent, + before_traceset, after_traceset, NULL, before_trace, after_trace, + NULL, before_tracefile, after_tracefile, NULL, before_event, after_event); + + return t1 - t0; +} + + +gboolean trace_event(void *hook_data, void *call_data) +{ + LttvTracefileState *tfs = (LttvTracefileState *)call_data; + + guint nb_block, nb_event; + + LttTracefile *tf; + + ltt_event_position(tfs->parent.e, a_event_position); + ltt_event_position_get(a_event_position, &nb_block, &nb_event, &tf); + fprintf(stderr,"Event %s %lu.%09lu [%lu %lu]\n", + ltt_eventtype_name(ltt_event_eventtype(tfs->parent.e)), + tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec, + nb_block, nb_event); + return FALSE; +} + + +gboolean count_event(void *hook_data, void *call_data) +{ + guint *pcount = (guint *)hook_data; + + (*pcount)++; + return FALSE; +} + + +gboolean save_state_copy_event(void *hook_data, void *call_data) +{ + SaveState *save_state = (SaveState *)hook_data; + + LttvTracefileState *tfs = (LttvTracefileState *)call_data; + + LttvTraceState *ts = (LttvTraceState *)tfs->parent.t_context; + + GString *filename; + + FILE *fp; + + if(ts->nb_event == 0 && strcmp(ltt_eventtype_name( + ltt_event_eventtype(tfs->parent.e)), "block_start") == 0) { + if(a_save_sample != NULL) { + filename = g_string_new(""); + g_string_printf(filename, "%s.copy.%lu.%09lu.xml", a_save_sample, + tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec); + fp = fopen(filename->str, "w"); + if(fp == NULL) g_error("Cannot open %s", filename->str); + g_string_free(filename, TRUE); + lttv_state_write(ts, tfs->parent.timestamp, fp); + fclose(fp); + } //else lttv_state_write(ts, tfs->parent.timestamp, save_state->fp); + } + return FALSE; +} + + +gboolean save_state_event(void *hook_data, void *call_data) +{ + SaveState *save_state = (SaveState *)hook_data; + + LttvTracefileState *tfs = (LttvTracefileState *)call_data; + + LttvTraceState *ts = (LttvTraceState *)tfs->parent.t_context; + + GString *filename; + + FILE *fp; + + (save_state->count)++; + if(save_state->count % save_state->interval == 0 && + save_state->position < save_state->size) { + if(a_save_sample != NULL) { + filename = g_string_new(""); + g_string_printf(filename, "%s.%u.xml.%u", a_save_sample, + save_state->position, save_state->version); + fp = fopen(filename->str, "w"); + if(fp == NULL) g_error("Cannot open %s", filename->str); + g_string_free(filename, TRUE); + lttv_state_write(ts, tfs->parent.timestamp, fp); + fclose(fp); + } //else lttv_state_write(ts, tfs->parent.timestamp, save_state->fp); + + save_state->write_time[save_state->position] = tfs->parent.timestamp; + save_state->position++; + } + return FALSE; +} + + +static gboolean process_traceset(void *hook_data, void *call_data) +{ + LttvTracesetStats *tscs; + + LttvTracesetState *ts; + + LttvTracesetContext *tc; + + GString *filename; + + FILE *fp; + + double t; + + guint i, j, count, nb_control, nb_tracefile, nb_block, nb_event, nb_equal; + + LttTrace *trace; + + LttTracefile *tracefile, *tf; + + LttEvent *event; + + LttFacility *facility; + + LttType *type; + + LttEventType *event_type; + + LttTime time, previous_time; + + long long unsigned cycle_count, start_count, delta_cycle; + + long long unsigned start_nsec, end_nsec, delta_nsec, added_nsec, added_nsec2; + + double cycle_per_nsec, nsec_per_cycle; + + long long interpolated_nsec, interpolated_nsec2, end_nsec_sec, end_nsec_nsec; + + LttTime start_time; + + LttTime zero_time = ltt_time_zero; + + LttTime max_time = { G_MAXULONG, G_MAXULONG }; + + a_event_position = ltt_event_position_new(); + + if(a_dump_tracefiles != NULL) { + for(i = 0 ; i < lttv_traceset_number(traceset) ; i++) { + trace = lttv_trace(lttv_traceset_get(traceset, i)); + nb_control = ltt_trace_control_tracefile_number(trace); + nb_tracefile = nb_control + ltt_trace_per_cpu_tracefile_number(trace); + for(j = 0 ; j < nb_tracefile ; j++) { + if(j < nb_control) { + tracefile = ltt_trace_control_tracefile_get(trace,j); + } + else { + tracefile = ltt_trace_per_cpu_tracefile_get(trace,j - nb_control); + } + + filename = g_string_new(""); + g_string_printf(filename, "%s.%u.%u.trace", a_dump_tracefiles, i, j); + fp = fopen(filename->str, "w"); + if(fp == NULL) g_error("Cannot open %s", filename->str); + g_string_free(filename, TRUE); + ltt_tracefile_seek_time(tracefile, zero_time); + previous_time = zero_time; + nb_equal = 0; + while((event = ltt_tracefile_read(tracefile)) != NULL) { + facility = ltt_event_facility(event); + event_type = ltt_event_eventtype(event); + time = ltt_event_time(event); + cycle_count = ltt_event_cycle_count(event); + ltt_event_position(event, a_event_position); + ltt_event_position_get(a_event_position, &nb_block, &nb_event, &tf); + fprintf(fp,"%s.%s: %llu %lu.%09lu position %u/%u\n", + ltt_facility_name(facility), ltt_eventtype_name(event_type), + cycle_count, (unsigned long)time.tv_sec, + (unsigned long)time.tv_nsec, + nb_block, nb_event); + + if(ltt_time_compare(time, previous_time) < 0) { + g_warning("Time decreasing trace %d tracefile %d position %u/%u", + i, j, nb_block, nb_event); + } + + if(strcmp(ltt_eventtype_name(event_type),"block_start") == 0) { + start_count = cycle_count; + start_time = time; + } + else if(strcmp(ltt_eventtype_name(event_type),"block_end") == 0) { + delta_cycle = cycle_count - start_count; + end_nsec_sec = (long long unsigned)time.tv_sec * (long long unsigned)1000000000; + end_nsec_nsec = time.tv_nsec; + end_nsec = end_nsec_sec + end_nsec_nsec; + start_nsec = (long long unsigned)start_time.tv_sec * (long long unsigned)1000000000 + (long long unsigned)start_time.tv_nsec; + delta_nsec = end_nsec - start_nsec; + cycle_per_nsec = (double)delta_cycle / (double)delta_nsec; + nsec_per_cycle = (double)delta_nsec / (double)delta_cycle; + added_nsec = (double)delta_cycle * nsec_per_cycle; + interpolated_nsec = start_nsec + added_nsec; + added_nsec2 = (double)delta_cycle / cycle_per_nsec; + interpolated_nsec2 = start_nsec + added_nsec2; + + fprintf(fp,"Time: start_count %llu, end_count %llu, delta_cycle %llu, start_nsec %llu, end_nsec_sec %llu, end_nsec_nsec %llu, end_nsec %llu, delta_nsec %llu, cycle_per_nsec %.25f, nsec_per_cycle %.25f, added_nsec %llu, added_nsec2 %llu, interpolated_nsec %llu, interpolated_nsec2 %llu\n", start_count, cycle_count, delta_cycle, start_nsec, end_nsec_sec, end_nsec_nsec, end_nsec, delta_nsec, cycle_per_nsec, nsec_per_cycle, added_nsec, added_nsec2, interpolated_nsec, interpolated_nsec2); + } + else { + if(ltt_time_compare(time, previous_time) == 0) nb_equal++; + else if(nb_equal > 0) { + g_warning("Consecutive %d events with time %lu.%09lu", + nb_equal + 1, previous_time.tv_sec, previous_time.tv_nsec); + nb_equal = 0; + } + previous_time = time; + } + } + fclose(fp); + } + } + } + + tscs = g_object_new(LTTV_TRACESET_STATS_TYPE, NULL); + ts = &tscs->parent; + tc = &tscs->parent.parent; + + lttv_context_init(tc, traceset); + + /* For each case compute and print the elapsed time. + The first case is simply to run through all events with a + simple counter. */ + + if(a_test1 || a_test_all) { + count = 0; + lttv_hooks_add(after_event, count_event, &count); + t = run_one_test(ts, zero_time, max_time); + lttv_hooks_remove_data(after_event, count_event, &count); + g_warning( + "Processing trace while counting events (%u events in %g seconds)", + count, t); + } + + /* Run through all events computing the state. */ + + if(a_test2 || a_test_all) { + lttv_state_add_event_hooks(ts); + t = run_one_test(ts, zero_time, max_time); + lttv_state_remove_event_hooks(ts); + g_warning("Processing trace while updating state (%g seconds)", t); + } + + /* Run through all events computing the state and writing it out + periodically. */ + + SaveState save_state; + + save_state.interval = a_sample_interval; + save_state.size = a_sample_number; + save_state.fp = stderr; + save_state.write_time = g_new(LttTime, a_sample_number); + + + if(a_test3 || a_test_all) { + for(i = 0 ; i < 2 ; i++) { + save_state.count = 0; + save_state.position = 0; + save_state.version = i; + lttv_state_add_event_hooks(ts); + lttv_hooks_add(after_event, save_state_event, &save_state); + t = run_one_test(ts, zero_time, max_time); + lttv_state_remove_event_hooks(ts); + lttv_hooks_remove_data(after_event, save_state_event, &save_state); + g_warning("Processing while updating/writing state (%g seconds)", t); + } + } + + /* Run through all events computing the stats. */ + + if(a_test4 || a_test_all) { + if(lttv_profile_memory) { + g_message("Memory summary before computing stats"); + g_mem_profile(); + } + + lttv_stats_add_event_hooks(tscs); + t = run_one_test(ts, zero_time, max_time); + lttv_stats_remove_event_hooks(tscs); + g_warning("Processing trace while counting stats (%g seconds)", t); + + if(lttv_profile_memory) { + g_message("Memory summary after computing stats"); + g_mem_profile(); + } + + lttv_stats_sum_traceset(tscs); + + if(lttv_profile_memory) { + g_message("Memory summary after summing stats"); + g_mem_profile(); + } + + lttv_context_fini(tc); + lttv_context_init(tc, traceset); + + if(lttv_profile_memory) { + g_message("Memory summary after cleaning up the stats"); + g_mem_profile(); + } + } + + /* Run through all events computing the state and stats. */ + + if(a_test5 || a_test_all) { + if(lttv_profile_memory) { + g_message("Memory summary before computing state and stats"); + g_mem_profile(); + } + + lttv_state_add_event_hooks(ts); + lttv_stats_add_event_hooks(tscs); + t = run_one_test(ts, zero_time, max_time); + lttv_state_remove_event_hooks(ts); + lttv_stats_remove_event_hooks(tscs); + g_warning( + "Processing trace while counting state and stats (%g seconds)", t); + + if(lttv_profile_memory) { + g_message("Memory summary after computing and state and stats"); + g_mem_profile(); + } + + lttv_context_fini(tc); + lttv_context_init(tc, traceset); + + if(lttv_profile_memory) { + g_message("Memory summary after cleaning up the stats"); + g_mem_profile(); + } + } + + /* Run through all events computing and saving the state. */ + + if(a_trace_event) lttv_hooks_add(after_event, trace_event, NULL); + + if(a_test6 || a_test_all) { + if(lttv_profile_memory) { + g_message("Memory summary before computing and saving state"); + g_mem_profile(); + } + + lttv_state_add_event_hooks(ts); + lttv_state_save_add_event_hooks(ts); + if(a_save_state_copy) + lttv_hooks_add(after_event, save_state_copy_event, &save_state); + t = run_one_test(ts, zero_time, max_time); + lttv_state_remove_event_hooks(ts); + lttv_state_save_remove_event_hooks(ts); + if(a_save_state_copy) + lttv_hooks_remove_data(after_event,save_state_copy_event, &save_state); + + g_warning("Processing trace while updating/saving state (%g seconds)", t); + + if(lttv_profile_memory) { + g_message("Memory summary after computing/saving state"); + g_mem_profile(); + } + } + + /* Seek a few times to each saved position */ + + if((a_test7 && a_test3) || a_test_all) { + int i, j; + + for(i = 0 ; i < 2 ; i++) { + for(j = save_state.position - 1 ; j >= 0 ; j--) { + lttv_state_add_event_hooks(ts); + t = run_one_test(ts, save_state.write_time[j], + save_state.write_time[j]); + lttv_state_remove_event_hooks(ts); + g_warning("Seeking to %lu.%lu (%g seconds)", + save_state.write_time[j].tv_sec, save_state.write_time[j].tv_nsec, + t); + + if(a_save_sample != NULL) { + filename = g_string_new(""); + g_string_printf(filename, "%s.%d.xml.bak%d", a_save_sample, j, i); + fp = fopen(filename->str, "w"); + if(fp == NULL) g_error("Cannot open %s", filename->str); + g_string_free(filename, TRUE); + lttv_state_write((LttvTraceState *)tc->traces[0], + save_state.write_time[j], fp); + fclose(fp); + } + //else lttv_state_write((LttvTraceState *)tc->traces[0], + // save_state.write_time[j], save_state.fp); + } + } + } + + if(a_trace_event) lttv_hooks_remove_data(after_event, trace_event, NULL); + + g_free(save_state.write_time); + g_free(a_event_position); + lttv_context_fini(tc); + g_object_unref(tscs); + + if(lttv_profile_memory) { + g_message("Memory summary at the end of batchtest"); + g_mem_profile(); + } + + g_info("BatchTest end process traceset"); +} + + +static void init() +{ + LttvAttributeValue value; + + LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes()); + + g_info("Init batchtest.c"); + + lttv_option_add("trace", 't', + "add a trace to the trace set to analyse", + "pathname of the directory containing the trace", + LTTV_OPT_STRING, &a_trace, lttv_trace_option, NULL); + + a_trace_event = FALSE; + + a_dump_tracefiles = NULL; + lttv_option_add("dump-tracefiles", 'D', + "Write event by event the content of tracefiles", + "basename for the files where to dump events", + LTTV_OPT_STRING, &a_dump_tracefiles, NULL, NULL); + + a_save_sample = NULL; + lttv_option_add("save-sample", 's', + "Save state samples to multiple files", + "basename for the files containing the state samples", + LTTV_OPT_STRING, &a_save_sample, NULL, NULL); + + a_save_state_copy = FALSE; + lttv_option_add("save-state-copy", 'S', "Write the state saved for seeking", + "", LTTV_OPT_NONE, &a_save_state_copy, NULL, NULL); + + a_save_interval = 100000; + lttv_option_add("save-interval", 'i', + "Interval between saving state", + "number of events before a block start triggers saving state", + LTTV_OPT_INT, &a_save_interval, NULL, NULL); + + a_sample_interval = 100000; + lttv_option_add("sample-interval", 'S', + "Interval between sampling state", + "number of events before sampling and writing state", + LTTV_OPT_INT, &a_sample_interval, NULL, NULL); + + a_sample_number = 20; + lttv_option_add("sample-number", 'N', + "Number of state samples", + "maximum number", + LTTV_OPT_INT, &a_sample_number, NULL, NULL); + + a_test1 = FALSE; + lttv_option_add("test1", '1', "Test just counting events", "", + LTTV_OPT_NONE, &a_test1, NULL, NULL); + + a_test2 = FALSE; + lttv_option_add("test2", '2', "Test computing the state", "", + LTTV_OPT_NONE, &a_test2, NULL, NULL); + + a_test3 = FALSE; + lttv_option_add("test3", '3', "Test computing the state, writing out a few", + "", LTTV_OPT_NONE, &a_test3, NULL, NULL); + + a_test4 = FALSE; + lttv_option_add("test4", '4', "Test computing the stats", "", + LTTV_OPT_NONE, &a_test4, NULL, NULL); + + a_test5 = FALSE; + lttv_option_add("test5", '5', "Test computing the state and stats", "", + LTTV_OPT_NONE, &a_test5, NULL, NULL); + + a_test6 = FALSE; + lttv_option_add("test6", '6', "Test computing and saving the state", "", + LTTV_OPT_NONE, &a_test6, NULL, NULL); + + a_test7 = FALSE; + lttv_option_add("test7", '7', "Test seeking to positions written out in 3", + "", LTTV_OPT_NONE, &a_test7, NULL, NULL); + + a_test_all = FALSE; + lttv_option_add("testall", 'a', "Run all tests ", "", + LTTV_OPT_NONE, &a_test_all, NULL, NULL); + + traceset = lttv_traceset_new(); + + before_traceset = lttv_hooks_new(); + after_traceset = lttv_hooks_new(); + before_trace = lttv_hooks_new(); + after_trace = lttv_hooks_new(); + before_tracefile = lttv_hooks_new(); + after_tracefile = lttv_hooks_new(); + before_event = lttv_hooks_new(); + after_event = lttv_hooks_new(); + + g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/before", + LTTV_POINTER, &value)); + *(value.v_pointer) = before_traceset; + g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/after", + LTTV_POINTER, &value)); + *(value.v_pointer) = after_traceset; + g_assert(lttv_iattribute_find_by_path(attributes, "hooks/trace/before", + LTTV_POINTER, &value)); + *(value.v_pointer) = before_trace; + g_assert(lttv_iattribute_find_by_path(attributes, "hooks/trace/after", + LTTV_POINTER, &value)); + *(value.v_pointer) = after_trace; + g_assert(lttv_iattribute_find_by_path(attributes, "hooks/tracefile/before", + LTTV_POINTER, &value)); + *(value.v_pointer) = before_tracefile; + g_assert(lttv_iattribute_find_by_path(attributes, "hooks/tracefile/after", + LTTV_POINTER, &value)); + *(value.v_pointer) = after_tracefile; + g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event/before", + LTTV_POINTER, &value)); + *(value.v_pointer) = before_event; + g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event/after", + LTTV_POINTER, &value)); + *(value.v_pointer) = after_event; + + g_assert(lttv_iattribute_find_by_path(attributes, "hooks/main/before", + LTTV_POINTER, &value)); + g_assert((main_hooks = *(value.v_pointer)) != NULL); + lttv_hooks_add(main_hooks, process_traceset, NULL); +} + + +static void destroy() +{ + guint i, nb; + + LttvTrace *trace; + + g_info("Destroy batchAnalysis.c"); + + lttv_option_remove("trace"); + lttv_option_remove("dump-tracefiles"); + lttv_option_remove("save-sample"); + lttv_option_remove("save-state-copy"); + lttv_option_remove("sample-interval"); + lttv_option_remove("sample-number"); + lttv_option_remove("save-interval"); + lttv_option_remove("test1"); + lttv_option_remove("test2"); + lttv_option_remove("test3"); + lttv_option_remove("test4"); + lttv_option_remove("test5"); + lttv_option_remove("test6"); + lttv_option_remove("test7"); + lttv_option_remove("testall"); + + lttv_hooks_destroy(before_traceset); + lttv_hooks_destroy(after_traceset); + lttv_hooks_destroy(before_trace); + lttv_hooks_destroy(after_trace); + lttv_hooks_destroy(before_tracefile); + lttv_hooks_destroy(after_tracefile); + lttv_hooks_destroy(before_event); + lttv_hooks_destroy(after_event); + lttv_hooks_remove_data(main_hooks, process_traceset, NULL); + + nb = lttv_traceset_number(traceset); + for(i = 0 ; i < nb ; i++) { + trace = lttv_traceset_get(traceset, i); + ltt_trace_close(lttv_trace(trace)); + lttv_trace_destroy(trace); + } + + lttv_traceset_destroy(traceset); +} + + +LTTV_MODULE("batchtest", "Batch processing of a trace for tests", \ + "Run through a trace calling all the registered hooks for tests", \ + init, destroy, "state", "stats", "option" ) diff --git a/ltt/branches/poly/lttv/lttv/filter.c b/ltt/branches/poly/lttv/lttv/filter.c new file mode 100644 index 00000000..74cd30e1 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/filter.c @@ -0,0 +1,76 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + + + consist in AND, OR and NOT nested expressions, forming a tree with + simple relations as leaves. The simple relations test is a field + in an event is equal, not equal, smaller, smaller or equal, larger, or + larger or equal to a specified value. */ + +typedef enum _lttv_expression_op +{ LTTV_FIELD_EQ, + LTTV_FIELD_NE, + LTTV_FIELD_LT, + LTTV_FIELD_LE, + LTTV_FIELD_GT, + LTTV_FIELD_GE +} lttv_expression_op; + +typedef _lttv_simple_expression +{ lttv_expression_op op; + char *field_name; + char *value; +} lttv_simple_expression; + +typedef _lttv_expression_type +{ LTTV_EXPRESSION, + LTTV_SIMPLE_EXPRESSION + +} +typedef struct _lttv_expression +{ bool or; + bool not; + bool simple_expression; + union + { lttv_expression *e; + lttv_field_relation *se; + } e; +} lttv_expression; + +read_token + +read_expression + ( read expr ) + simple expr [ op expr ] + +read_simple_expression + read_field_path [ rel value ] + +read_field_path + read_field_component [. field path] + +read_field_component + name [ \[ value \] ] + +data struct: +and/or(left/right) +not(child) +op(left/right) +path(component...) -> field + + diff --git a/ltt/branches/poly/lttv/lttv/filter.h b/ltt/branches/poly/lttv/lttv/filter.h new file mode 100644 index 00000000..560c45d1 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/filter.h @@ -0,0 +1,63 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef FILTER_H +#define FILTER_H + +/* A filter expression consists in nested AND, OR and NOT expressions + involving boolean relation (>, >=, =, !=, <, <=) between event fields and + specific values. It is compiled into an efficient data structure which + is used in functions to check if a given event or tracefile satisfies the + filter. + + The grammar for filters is: + + filter = expression + + expression = "(" expression ")" | "!" expression | + expression "&&" expression | expression "||" expression | + simpleExpression + + simpleExpression = fieldPath op value + + fieldPath = fieldComponent [ "." fieldPath ] + + fieldComponent = name [ "[" integer "]" ] + + value = integer | double | string + +*/ + + +typedef struct _lttv_filter lttv_filter; + + +/* Compile the filter expression into an efficient data structure */ + +lttv_filter *lttv_filter_new(char *expression, lttv_trace *t); + + +/* Check if the tracefile or event satisfies the filter. The arguments are + declared as void * to allow these functions to be used as hooks. */ + +bool lttv_filter_tracefile(void *filter, void *tracefile); + +bool lttv_filter_event(void *filter, void *event); + +#endif // FILTER_H + diff --git a/ltt/branches/poly/lttv/lttv/hook.c b/ltt/branches/poly/lttv/lttv/hook.c new file mode 100644 index 00000000..a7f0960d --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/hook.c @@ -0,0 +1,230 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + + +#include + + +typedef struct _LttvHookClosure { + LttvHook hook; + void *hook_data; +} LttvHookClosure; + + +LttvHooks *lttv_hooks_new() +{ + return g_array_new(FALSE, FALSE, sizeof(LttvHookClosure)); +} + + +void lttv_hooks_destroy(LttvHooks *h) +{ + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "lttv_hooks_destroy()"); + g_array_free(h, TRUE); +} + + +void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data) +{ + LttvHookClosure c; + + if(h == NULL)g_error("Null hook added"); + + c.hook = f; + c.hook_data = hook_data; + g_array_append_val(h,c); +} + + +void lttv_hooks_add_list(LttvHooks *h, LttvHooks *list) +{ + guint i; + + if(list == NULL) return; + for(i = 0 ; i < list->len; i++) { + g_array_append_val(h,g_array_index(list, LttvHookClosure, i)); + } +} + + +void *lttv_hooks_remove(LttvHooks *h, LttvHook f) +{ + unsigned i; + + void *hook_data; + + LttvHookClosure *c; + + for(i = 0 ; i < h->len ; i++) { + c = &g_array_index(h, LttvHookClosure, i); + if(c->hook == f) { + hook_data = c->hook_data; + lttv_hooks_remove_by_position(h, i); + return hook_data; + } + } + return NULL; +} + + +void lttv_hooks_remove_data(LttvHooks *h, LttvHook f, void *hook_data) +{ + unsigned i; + + LttvHookClosure *c; + + for(i = 0 ; i < h->len ; i++) { + c = &g_array_index(h, LttvHookClosure, i); + if(c->hook == f && c->hook_data == hook_data) { + lttv_hooks_remove_by_position(h, i); + return; + } + } +} + + +void lttv_hooks_remove_list(LttvHooks *h, LttvHooks *list) +{ + guint i, j; + + LttvHookClosure *c, *c_list; + + if(list == NULL) return; + for(i = 0, j = 0 ; i < h->len && j < list->len ;) { + c = &g_array_index(h, LttvHookClosure, i); + c_list = &g_array_index(list, LttvHookClosure, j); + if(c->hook == c_list->hook && c->hook_data == c_list->hook_data) { + lttv_hooks_remove_by_position(h, i); + j++; + } + else i++; + } + + /* Normally the hooks in h are ordered as in list. If this is not the case, + try harder here. */ + + if(j < list->len) { + for(; j < list->len ; j++) { + c_list = &g_array_index(list, LttvHookClosure, j); + lttv_hooks_remove_data(h, c_list->hook, c_list->hook_data); + } + } +} + + +unsigned lttv_hooks_number(LttvHooks *h) +{ + return h->len; +} + + +void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data) +{ + LttvHookClosure *c; + + c = &g_array_index(h, LttvHookClosure, i); + *f = c->hook; + *hook_data = c->hook_data; +} + + +void lttv_hooks_remove_by_position(LttvHooks *h, unsigned i) +{ + g_array_remove_index(h, i); +} + + +gboolean lttv_hooks_call(LttvHooks *h, void *call_data) +{ + gboolean ret, sum_ret = FALSE; + + LttvHookClosure *c; + + guint i; + + if(h != NULL) { + for(i = 0 ; i < h->len ; i++) { + c = &g_array_index(h, LttvHookClosure, i); + ret = c->hook(c->hook_data,call_data); + sum_ret = sum_ret || ret; + } + } + return sum_ret; +} + + +gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data) +{ + LttvHookClosure *c; + + guint i; + + for(i = 0 ; i < h->len ; i++) { + c = &g_array_index(h, LttvHookClosure, i); + if(c->hook(c->hook_data,call_data)) return TRUE; + } + return FALSE; +} + + +LttvHooksById *lttv_hooks_by_id_new() +{ + return g_ptr_array_new(); +} + + +void lttv_hooks_by_id_destroy(LttvHooksById *h) +{ + guint i; + + for(i = 0 ; i < h->len ; i++) { + if(h->pdata[i] != NULL) lttv_hooks_destroy((LttvHooks *)(h->pdata[i])); + } + g_ptr_array_free(h, TRUE); +} + + +LttvHooks *lttv_hooks_by_id_find(LttvHooksById *h, unsigned id) +{ + if(h->len <= id) g_ptr_array_set_size(h, id + 1); + if(h->pdata[id] == NULL) h->pdata[id] = lttv_hooks_new(); + return h->pdata[id]; +} + + +unsigned lttv_hooks_by_id_max_id(LttvHooksById *h) +{ + return h->len; +} + + +LttvHooks *lttv_hooks_by_id_get(LttvHooksById *h, unsigned id) +{ + if(id < h->len) return h->pdata[id]; + return NULL; +} + + +void lttv_hooks_by_id_remove(LttvHooksById *h, unsigned id) +{ + if(id < h->len && h->pdata[id] != NULL) { + lttv_hooks_destroy((LttvHooks *)h->pdata[id]); + h->pdata[id] = NULL; + } +} + diff --git a/ltt/branches/poly/lttv/lttv/hook.h b/ltt/branches/poly/lttv/lttv/hook.h new file mode 100644 index 00000000..803304c0 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/hook.h @@ -0,0 +1,127 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef HOOK_H +#define HOOK_H + +#include + +/* A hook is a function to call with the supplied hook data, and with + call site specific data (e.g., hooks for events are called with a + pointer to the current event). */ + +typedef gboolean (*LttvHook)(void *hook_data, void *call_data); + + +/* A list of hooks allows registering hooks to be called later. */ + +typedef GArray LttvHooks; + + +/* Create and destroy a list of hooks */ + +LttvHooks *lttv_hooks_new(); + +void lttv_hooks_destroy(LttvHooks *h); + + +/* Add a hook and its hook data to the list */ + +void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data); + + +/* Add a list of hooks to the list h */ + +void lttv_hooks_add_list(LttvHooks *h, LttvHooks *list); + + +/* Remove a hook from the list. Return the hook data. */ + +void *lttv_hooks_remove(LttvHooks *h, LttvHook f); + + +/* Remove a hook from the list checking that the hook data match. */ + +void lttv_hooks_remove_data(LttvHooks *h, LttvHook f, void *hook_data); + + +/* Remove a list of hooks from the hooks list in h. */ + +void lttv_hooks_remove_data_list(LttvHooks *h, LttvHook *list); + + +/* Return the number of hooks in the list */ + +unsigned lttv_hooks_number(LttvHooks *h); + + +/* Return the hook at the specified position in the list */ + +void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data); + + +/* Remove the specified hook. The position of the following hooks may change */ + +void lttv_hooks_remove_by_position(LttvHooks *h, unsigned i); + + +/* Call all the hooks in the list, each with its hook data, + with the specified call data. Return TRUE if one hook returned TRUE. */ + +gboolean lttv_hooks_call(LttvHooks *h, void *call_data); + + +/* Call the hooks in the list until one returns true, in which case TRUE is + returned. */ + +gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data); + + +/* Sometimes different hooks need to be called based on the case. The + case is represented by an unsigned integer id */ + +typedef GPtrArray LttvHooksById; + + +/* Create and destroy a hooks by id list */ + +LttvHooksById *lttv_hooks_by_id_new(); + +void lttv_hooks_by_id_destroy(LttvHooksById *h); + + +/* Obtain the hooks for a given id, creating a list if needed */ + +LttvHooks *lttv_hooks_by_id_find(LttvHooksById *h, unsigned id); + + +/* Return an id larger than any for which a list exists. */ + +unsigned lttv_hooks_by_id_max_id(LttvHooksById *h); + + +/* Get the list of hooks for an id, NULL if none exists */ + +LttvHooks *lttv_hooks_by_id_get(LttvHooksById *h, unsigned id); + + +/* Remove the list of hooks associated with an id */ + +void lttv_hooks_by_id_remove(LttvHooksById *h, unsigned id); + +#endif // HOOK_H diff --git a/ltt/branches/poly/lttv/lttv/iattribute.c b/ltt/branches/poly/lttv/lttv/iattribute.c new file mode 100644 index 00000000..ba17e3a2 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/iattribute.c @@ -0,0 +1,278 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + + +#include + +static void +lttv_iattribute_base_init (gpointer klass) +{ + static gboolean initialized = FALSE; + + if (!initialized) { + initialized = TRUE; + } +} + + +GType +lttv_iattribute_get_type (void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof (LttvIAttributeClass), + lttv_iattribute_base_init, /* base_init */ + NULL, /* base_finalize */ + NULL, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL /* instance_init */ + }; + type = g_type_register_static (G_TYPE_INTERFACE, "LttvIAttribute", + &info, 0); + } + return type; +} + + +unsigned int lttv_iattribute_get_number(LttvIAttribute *self) +{ + return LTTV_IATTRIBUTE_GET_CLASS (self)->get_number (self); +} + + +gboolean lttv_iattribute_named(LttvIAttribute *self, gboolean *homogeneous) +{ + return LTTV_IATTRIBUTE_GET_CLASS (self)->named (self, homogeneous); +} + + +LttvAttributeType lttv_iattribute_get(LttvIAttribute *self, unsigned i, + LttvAttributeName *name, LttvAttributeValue *v) +{ + return LTTV_IATTRIBUTE_GET_CLASS (self)->get (self, i, name, v); +} + + +LttvAttributeType lttv_iattribute_get_by_name(LttvIAttribute *self, + LttvAttributeName name, LttvAttributeValue *v) +{ + return LTTV_IATTRIBUTE_GET_CLASS (self)->get_by_name (self, name, v); +} + + +LttvAttributeValue lttv_iattribute_add(LttvIAttribute *self, + LttvAttributeName name, LttvAttributeType t) +{ + return LTTV_IATTRIBUTE_GET_CLASS (self)->add (self, name, t); +} + + +void lttv_iattribute_remove(LttvIAttribute *self, unsigned i) +{ + return LTTV_IATTRIBUTE_GET_CLASS (self)->remove (self, i); +} + + +void lttv_iattribute_remove_by_name(LttvIAttribute *self, + LttvAttributeName name) +{ + return LTTV_IATTRIBUTE_GET_CLASS (self)->remove_by_name (self, name); +} + +LttvIAttribute* lttv_iattribute_find_subdir(LttvIAttribute *self, + LttvAttributeName name) +{ + return LTTV_IATTRIBUTE_GET_CLASS (self)->find_subdir (self, name); +} + + +/* Find the named attribute in the table, which must be of the specified type. + If it does not exist, it is created with a default value of 0 (NULL for + pointer types). Since the address of the value is obtained, it may be + changed easily afterwards. The function returns false when the attribute + exists but is of incorrect type. */ + +gboolean lttv_iattribute_find(LttvIAttribute *self, LttvAttributeName name, + LttvAttributeType t, LttvAttributeValue *v) +{ + LttvAttributeType found_type; + + found_type = lttv_iattribute_get_by_name(self, name, v); + if(found_type == t) return TRUE; + + if(found_type == LTTV_NONE) { + *v = lttv_iattribute_add(self, name, t); + return TRUE; + } + + return FALSE; +} + + +/* Trees of attribute tables may be accessed using a hierarchical path with + components separated by /, like in filesystems */ + +gboolean lttv_iattribute_find_by_path(LttvIAttribute *self, char *path, + LttvAttributeType t, LttvAttributeValue *v) +{ + LttvIAttribute *node = self; + + LttvAttributeType found_type; + + LttvAttributeName name; + + gchar **components, **cursor; + + components = g_strsplit(path, "\"", G_MAXINT); + + if(components == NULL || *components == NULL) { + g_strfreev(components); + return FALSE; + } + + for(cursor = components;;) { + name = g_quark_from_string(*cursor); + cursor++; + + if(*cursor == NULL) { + g_strfreev(components); + return lttv_iattribute_find(node, name, t, v); + } + else { + found_type = lttv_iattribute_get_by_name(node, name, v); + if(found_type == LTTV_NONE) { + node = lttv_iattribute_find_subdir(node, name); + } + else if(found_type == LTTV_GOBJECT && + LTTV_IS_IATTRIBUTE(*(v->v_gobject))) { + node = LTTV_IATTRIBUTE(*(v->v_gobject)); + } + else { + g_strfreev(components); + return FALSE; + } + } + } +} + +/* Shallow and deep copies */ + +LttvIAttribute *lttv_iattribute_shallow_copy(LttvIAttribute *self) +{ + LttvIAttribute *copy; + + LttvAttributeType t; + + LttvAttributeValue v, v_copy; + + LttvAttributeName name; + + int i; + + int nb_attributes = lttv_iattribute_get_number(self); + + copy = LTTV_IATTRIBUTE(g_object_new(G_OBJECT_TYPE(self),NULL)); + + for(i = 0 ; i < nb_attributes ; i++) { + t = lttv_iattribute_get(self, i, &name, &v); + v_copy = lttv_iattribute_add(copy, name, t); + lttv_iattribute_copy_value(t, v_copy, v); + } +} + +LttvIAttribute *lttv_iattribute_deep_copy(LttvIAttribute *self) +{ + LttvIAttribute *copy, *child; + + LttvAttributeType t; + + LttvAttributeValue v, v_copy; + + LttvAttributeName name; + + int i; + + int nb_attributes = lttv_iattribute_get_number(self); + + copy = LTTV_IATTRIBUTE(g_object_new(G_OBJECT_TYPE(self), NULL)); + + for(i = 0 ; i < nb_attributes ; i++) { + t = lttv_iattribute_get(self, i, &name, &v); + v_copy = lttv_iattribute_add(copy, name, t); + if(t == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(*(v.v_gobject))) { + child = LTTV_IATTRIBUTE(*(v.v_gobject)); + *(v_copy.v_gobject) = G_OBJECT(lttv_iattribute_deep_copy(child)); + } + else lttv_iattribute_copy_value(t, v_copy, v); + } +} + +void lttv_iattribute_copy_value(LttvAttributeType t, LttvAttributeValue dest, + LttvAttributeValue src) +{ + switch(t) { + case LTTV_INT: + *(dest.v_int) = *(src.v_int); + break; + + case LTTV_UINT: + *(dest.v_uint) = *(src.v_uint); + break; + + case LTTV_LONG: + *(dest.v_long) = *(src.v_long); + break; + + case LTTV_ULONG: + *(dest.v_ulong) = *(src.v_ulong); + break; + + case LTTV_FLOAT: + *(dest.v_float) = *(src.v_float); + break; + + case LTTV_DOUBLE: + *(dest.v_double) = *(src.v_double); + break; + + case LTTV_TIME: + *(dest.v_time) = *(src.v_time); + break; + + case LTTV_POINTER: + *(dest.v_pointer) = *(src.v_pointer); + break; + + case LTTV_STRING: + *(dest.v_string) = *(src.v_string); + break; + + case LTTV_GOBJECT: + *(dest.v_gobject) = *(src.v_gobject); + break; + + case LTTV_NONE: + break; + } +} + + diff --git a/ltt/branches/poly/lttv/lttv/iattribute.h b/ltt/branches/poly/lttv/lttv/iattribute.h new file mode 100644 index 00000000..11dccd10 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/iattribute.h @@ -0,0 +1,173 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef IATTRIBUTE_H +#define IATTRIBUTE_H + + +#include +#include + +/* The content of a data structure may be seen as an array of pairs of + attribute name and value. This simple model allows generic navigation + and access functions over a wide range of structures. The names are + represented by unique integer identifiers, GQuarks. */ + +typedef GQuark LttvAttributeName; + +typedef enum _LttvAttributeType { + LTTV_INT, LTTV_UINT, LTTV_LONG, LTTV_ULONG, LTTV_FLOAT, LTTV_DOUBLE, + LTTV_TIME, LTTV_POINTER, LTTV_STRING, LTTV_GOBJECT, LTTV_NONE +} LttvAttributeType; + +typedef union LttvAttributeValue { + int *v_int; + unsigned *v_uint; + long *v_long; + unsigned long *v_ulong; + float *v_float; + double *v_double; + LttTime *v_time; + gpointer *v_pointer; + char **v_string; + GObject **v_gobject; +} LttvAttributeValue; + + +/* GObject interface type macros */ + +#define LTTV_IATTRIBUTE_TYPE (lttv_iattribute_get_type ()) +#define LTTV_IATTRIBUTE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_IATTRIBUTE_TYPE, LttvIAttribute)) +#define LTTV_IATTRIBUTE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_IATTRIBUTE_TYPE, LttvIAttributeClass)) +#define LTTV_IS_IATTRIBUTE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_IATTRIBUTE_TYPE)) +#define LTTV_IS_IATTRIBUTE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_IATTRIBUTE_TYPE)) +#define LTTV_IATTRIBUTE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), LTTV_IATTRIBUTE_TYPE, LttvIAttributeClass)) + + +typedef struct _LttvIattribute LttvIAttribute; /* dummy object */ +typedef struct _LttvIAttributeClass LttvIAttributeClass; + + +struct _LttvIAttributeClass { + GTypeInterface parent; + + unsigned int (*get_number) (LttvIAttribute *self); + + gboolean (*named) (LttvIAttribute *self, gboolean *homogeneous); + + LttvAttributeType (*get) (LttvIAttribute *self, unsigned i, + LttvAttributeName *name, LttvAttributeValue *v); + + LttvAttributeType (*get_by_name) (LttvIAttribute *self, + LttvAttributeName name, LttvAttributeValue *v); + + LttvAttributeValue (*add) (LttvIAttribute *self, LttvAttributeName name, + LttvAttributeType t); + + void (*remove) (LttvIAttribute *self, unsigned i); + + void (*remove_by_name) (LttvIAttribute *self, + LttvAttributeName name); + + LttvIAttribute* (*find_subdir) (LttvIAttribute *self, + LttvAttributeName name); +}; + + +GType lttv_iattribute_get_type(void); + + +/* Total number of attributes */ + +unsigned int lttv_iattribute_get_number(LttvIAttribute *self); + + +/* Container type. Named (fields in struct or elements in a hash table) + or unnamed (elements in an array) attributes, homogeneous type or not. */ + +gboolean lttv_iattribute_named(LttvIAttribute *self, gboolean *homogeneous); + + +/* Get the i th attribute along with its type and a pointer to its value. */ + +LttvAttributeType lttv_iattribute_get(LttvIAttribute *self, unsigned i, + LttvAttributeName *name, LttvAttributeValue *v); + + +/* Get the named attribute in the table along with its type and a pointer to + its value. If the named attribute does not exist, the type is LTTV_NONE. */ + +LttvAttributeType lttv_iattribute_get_by_name(LttvIAttribute *self, + LttvAttributeName name, LttvAttributeValue *v); + + +/* Add an attribute, which must not exist. The name is an empty string for + containers with unnamed attributes. Its value is initialized to 0 or NULL + and its pointer returned. */ + +LttvAttributeValue lttv_iattribute_add(LttvIAttribute *self, + LttvAttributeName name, LttvAttributeType t); + + +/* Remove an attribute */ + +void lttv_iattribute_remove(LttvIAttribute *self, unsigned i); + +void lttv_iattribute_remove_by_name(LttvIAttribute *self, + LttvAttributeName name); + + +/* Create an empty iattribute object and add it as an attribute under the + specified name, or return an existing iattribute attribute. If an + attribute of that name already exists but is not a GObject supporting the + iattribute interface, return NULL. */ + +LttvIAttribute* lttv_iattribute_find_subdir(LttvIAttribute *self, + LttvAttributeName name); + + +/* The remaining utility functions are not part of the LttvIAttribute + interface but operate on objects implementing it. */ + +/* Find the named attribute in the table, which must be of the specified type. + If it does not exist, it is created with a default value of 0 (NULL for + pointer types). Since the address of the value is obtained, it may be + changed easily afterwards. The function returns false when the attribute + exists but is of incorrect type. */ + +gboolean lttv_iattribute_find(LttvIAttribute *self, LttvAttributeName name, + LttvAttributeType t, LttvAttributeValue *v); + + +/* Trees of attribute tables may be accessed using a hierarchical path with + components separated by /, like in filesystems */ + +gboolean lttv_iattribute_find_by_path(LttvIAttribute *self, char *path, + LttvAttributeType t, LttvAttributeValue *v); + + +/* Shallow and deep copies */ + +void lttv_iattribute_copy_value(LttvAttributeType t, LttvAttributeValue dest, + LttvAttributeValue src); + +LttvIAttribute *lttv_iattribute_shallow_copy(LttvIAttribute *self); + +LttvIAttribute *lttv_iattribute_deep_copy(LttvIAttribute *self); + +#endif // IATTRIBUTE_H diff --git a/ltt/branches/poly/lttv/lttv/lttv.h b/ltt/branches/poly/lttv/lttv/lttv.h new file mode 100644 index 00000000..27c610a2 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/lttv.h @@ -0,0 +1,60 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef LTTV_H +#define LTTV_H + +#include + +/* The modules in the visualizer communicate with the main module and + with each other through attributes. There is a global set of attributes */ + +LttvAttribute *lttv_global_attributes(); + +extern gboolean lttv_profile_memory; + +extern int lttv_argc; + +extern char **lttv_argv; + +/* A number of global attributes are initialized before modules are + loaded, for example hooks lists. More global attributes are defined + in individual mudules to store information or to communicate with other + modules (GUI windows, menus...). + + The hooks lists (lttv_hooks) are initialized in the main module and may be + used by other modules. Each corresponds to a specific location in the main + module processing loop. The attribute key and typical usage for each + is indicated. + + /hooks/options/before + Good place to define new command line options to be parsed. + + /hooks/options/after + Read the values set by the command line options. + + /hooks/main/before + + /hooks/main/after + +*/ + +#define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format) +#define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format) + +#endif // LTTV_H diff --git a/ltt/branches/poly/lttv/lttv/main.c b/ltt/branches/poly/lttv/lttv/main.c new file mode 100644 index 00000000..a27519e8 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/main.c @@ -0,0 +1,283 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* The main program maintains a few central data structures and relies + on modules for the rest. These data structures may be accessed by modules + through an exported API */ + +static LttvIAttribute *attributes; + +static LttvHooks + *before_options, + *after_options, + *before_main, + *after_main; + +static char + *a_module, + *a_module_path; + +static gboolean + a_verbose, + a_debug; + +gboolean lttv_profile_memory; + +int lttv_argc; + +char **lttv_argv; + +static void lttv_module_option(void *hook_data); + +static void lttv_module_path_option(void *hook_data); + +static void lttv_verbose(void *hook_data); + +static void lttv_debug(void *hook_data); + +static void lttv_help(void *hook_data); + +/* This is the handler to specify when we dont need all the debugging + messages. It receives the message and does nothing. */ + +void ignore_and_drop_message(const gchar *log_domain, GLogLevelFlags log_level, + const gchar *message, gpointer user_data) { +} + + +/* Since everything is done in modules, the main program only takes care + of the infrastructure. */ + +int main(int argc, char **argv) { + + int i; + + char + *profile_memory_short_option = "-M", + *profile_memory_long_option = "--memory"; + + gboolean profile_memory = FALSE; + + LttvAttributeValue value; + + lttv_argc = argc; + lttv_argv = argv; + + /* Before anything else, check if memory profiling is requested */ + + for(i = 1 ; i < argc ; i++) { + if(*(argv[i]) != '-') break; + if(strcmp(argv[i], profile_memory_short_option) == 0 || + strcmp(argv[i], profile_memory_long_option) == 0) { + g_mem_set_vtable(glib_mem_profiler_table); + g_message("Memory summary before main"); + g_mem_profile(); + profile_memory = TRUE; + break; + } + } + + + /* Initialize glib and by default ignore info and debug messages */ + + g_type_init(); + //g_type_init_with_debug_flags (G_TYPE_DEBUG_OBJECTS | G_TYPE_DEBUG_SIGNALS); + g_log_set_handler(NULL, G_LOG_LEVEL_INFO, ignore_and_drop_message, NULL); + g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, ignore_and_drop_message, NULL); + + + /* Have an attributes subtree to store hooks to be registered by modules. */ + + attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL)); + + before_options = lttv_hooks_new(); + after_options = lttv_hooks_new(); + before_main = lttv_hooks_new(); + after_main = lttv_hooks_new(); + + + /* Create a number of hooks lists */ + + g_assert(lttv_iattribute_find_by_path(attributes, "hooks/options/before", + LTTV_POINTER, &value)); + *(value.v_pointer) = before_options; + g_assert(lttv_iattribute_find_by_path(attributes, "hooks/options/after", + LTTV_POINTER, &value)); + *(value.v_pointer) = after_options; + g_assert(lttv_iattribute_find_by_path(attributes, "hooks/main/before", + LTTV_POINTER, &value)); + *(value.v_pointer) = before_main; + g_assert(lttv_iattribute_find_by_path(attributes, "hooks/main/after", + LTTV_POINTER, &value)); + *(value.v_pointer) = after_main; + + + /* Initialize the command line options processing */ + + GError *error = NULL; + + LttvModule *module_module = lttv_module_require("module", &error); + if(error != NULL) g_error(error->message); + LttvModule *module_option = lttv_module_require("option", &error); + if(error != NULL) g_error(error->message); + + /* Initialize the module loading */ + + lttv_library_path_add(PACKAGE_PLUGIN_DIR); + + + /* Add some built-in options */ + + lttv_option_add("module",'m', "load a module", "name of module to load", + LTTV_OPT_STRING, &a_module, lttv_module_option, NULL); + + lttv_option_add("modules-path", 'L', + "add a directory to the module search path", + "directory to add to the path", LTTV_OPT_STRING, &a_module_path, + lttv_module_path_option, NULL); + + lttv_option_add("help",'h', "basic help", "none", + LTTV_OPT_NONE, NULL, lttv_help, NULL); + + a_verbose = FALSE; + lttv_option_add("verbose",'v', "print information messages", "none", + LTTV_OPT_NONE, NULL, lttv_verbose, NULL); + + a_debug = FALSE; + lttv_option_add("debug",'d', "print debugging messages", "none", + LTTV_OPT_NONE, NULL, lttv_debug, NULL); + + lttv_profile_memory = FALSE; + lttv_option_add(profile_memory_long_option + 2, + profile_memory_short_option[1], "print memory information", "none", + LTTV_OPT_NONE, <tv_profile_memory, NULL, NULL); + + + /* Process the options */ + + lttv_hooks_call(before_options, NULL); + lttv_option_parse(argc, argv); + lttv_hooks_call(after_options, NULL); + + + /* Memory profiling to be useful must be activated as early as possible */ + + if(profile_memory != lttv_profile_memory) + g_error("Memory profiling options must appear before other options"); + + + /* Do the main work */ + + lttv_hooks_call(before_main, NULL); + lttv_hooks_call(after_main, NULL); + + + /* Clean up everything */ + + lttv_module_release(module_option); + lttv_module_release(module_module); + + lttv_hooks_destroy(before_options); + lttv_hooks_destroy(after_options); + lttv_hooks_destroy(before_main); + lttv_hooks_destroy(after_main); + g_object_unref(attributes); + + if(profile_memory) { + g_message("Memory summary after main"); + g_mem_profile(); + } + return 0; +} + + +LttvAttribute *lttv_global_attributes() +{ + return (LttvAttribute*)attributes; +} + + +void lttv_module_option(void *hook_data) +{ + GError *error = NULL; + + lttv_module_require(a_module, &error); + if(error != NULL) g_error(error->message); +} + + +void lttv_module_path_option(void *hook_data) +{ + lttv_library_path_add(a_module_path); +} + + +void lttv_verbose(void *hook_data) +{ + g_log_set_handler(NULL, G_LOG_LEVEL_INFO, g_log_default_handler, NULL); + g_info("Logging set to include INFO level messages"); +} + +void lttv_debug(void *hook_data) +{ + g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, g_log_default_handler, NULL); + g_info("Logging set to include DEBUG level messages"); +} + +void lttv_help(void *hook_data) +{ + printf("Linux Trace Toolkit Visualizer\n"); + printf("\n"); + lttv_option_show_help(); + printf("\n"); +} + +/* + +- Define formally traceset/trace in the GUI for the user and decide how + trace/traceset sharing goes in the application. + +- Use appropriately the new functions in time.h + +- remove the separate tracefiles (control/per cpu) arrays/loops in context. + +- split processTrace into context.c and processTrace.c + +- check spelling conventions. + +- get all the copyright notices. + +- remove all the warnings. + +- get all the .h files properly doxygen commented to produce useful documents. + +- have an intro/architecture document. + +- write a tutorial */ diff --git a/ltt/branches/poly/lttv/lttv/module.c b/ltt/branches/poly/lttv/lttv/module.c new file mode 100644 index 00000000..c4d3d6b0 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/module.c @@ -0,0 +1,584 @@ + +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + + +/* module.c : Implementation of the module loading/unloading mechanism. */ + +#include +#include + + +struct _LttvLibrary +{ + LttvLibraryInfo info; + GPtrArray *modules; + GModule *gm; + guint locked_loaded; +}; + + +struct _LttvModule +{ + LttvModuleInfo info; + char **prerequisites_names; + GPtrArray *prerequisites; +}; + + +/* Modules are searched by name. However, a library may be loaded which + provides a module with the same name as an existing one. A stack of + modules is thus maintained for each name. + + Libraries correspond to glib modules. The g_module function is + responsible for loading each library only once. */ + +static GHashTable *modules_by_name = NULL; + +static GPtrArray *libraries = NULL; + +static GHashTable *libraries_by_g_module = NULL; + +static GPtrArray *library_paths = NULL; + +static gboolean initialized = FALSE; + +static gboolean destroyed = TRUE; + +static struct _LttvModuleDescription *builtin_chain = NULL; + +static struct _LttvModuleDescription *module_chain = NULL; + +static struct _LttvModuleDescription **module_next = &module_chain; + +static GQuark lttv_module_error; + +static void init(); + +static finish_destroy(); + +static void module_release(LttvModule *m); + + +static LttvLibrary *library_add(char *name, char *path, GModule *gm) +{ + LttvLibrary *l; + + LttvModule *m; + + struct _LttvModuleDescription *link; + + GPtrArray *modules; + + l = g_new(LttvLibrary, 1); + l->modules = g_ptr_array_new(); + l->gm = gm; + l->locked_loaded = 0; + l->info.name = g_strdup(name); + l->info.path = g_strdup(path); + l->info.load_count = 0; + + g_ptr_array_add(libraries, l); + g_hash_table_insert(libraries_by_g_module, gm, l); + + *module_next = NULL; + for(link = module_chain; link != NULL; link = link->next) { + m = g_new(LttvModule, 1); + g_ptr_array_add(l->modules, m); + + modules = g_hash_table_lookup(modules_by_name, link->name); + if(modules == NULL) { + modules = g_ptr_array_new(); + g_hash_table_insert(modules_by_name, g_strdup(link->name), modules); + } + g_ptr_array_add(modules, m); + + m->prerequisites_names = link->prerequisites; + m->prerequisites = g_ptr_array_new(); + m->info.name = link->name; + m->info.short_description = link->short_description; + m->info.description = link->description; + m->info.init = link->init; + m->info.destroy = link->destroy; + m->info.library = l; + m->info.require_count = 0; + m->info.use_count = 0; + m->info.prerequisites_number = link->prerequisites_number; + } + return l; +} + + +static void library_remove(LttvLibrary *l) +{ + LttvModule *m; + + GPtrArray *modules; + + guint i; + + char *key; + + for(i = 0 ; i < l->modules->len ; i++) { + m = (LttvModule *)(l->modules->pdata[i]); + + g_hash_table_lookup_extended(modules_by_name, m->info.name, + (gpointer *)&key, (gpointer *)&modules); + g_assert(modules != NULL); + g_ptr_array_remove(modules, m); + if(modules->len == 0) { + g_hash_table_remove(modules_by_name, m->info.name); + g_ptr_array_free(modules, TRUE); + g_free(key); + } + + g_ptr_array_free(m->prerequisites, TRUE); + g_free(m); + } + + g_ptr_array_remove(libraries, l); + g_hash_table_remove(libraries_by_g_module, l->gm); + g_ptr_array_free(l->modules, TRUE); + g_free(l->info.name); + g_free(l->info.path); + g_free(l); +} + + +static LttvLibrary *library_load(char *name, GError **error) +{ + GModule *gm; + + int i, nb; + + char *path, *pathname; + + LttvLibrary *l; + + GString *messages = g_string_new(""); + + /* insure that module.c is initialized */ + + init(); + + /* Try to find the library along all the user specified paths */ + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Load library %s", name); + nb = lttv_library_path_number(); + for(i = 0 ; i <= nb ; i++) { + if(i < nb) path = lttv_library_path_get(i); + else path = NULL; + + pathname = g_module_build_path(path ,name); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Try path %s", pathname); + module_chain = NULL; + module_next = &module_chain; + gm = g_module_open(pathname,0); + g_free(pathname); + + if(gm != NULL) break; + + g_string_append(messages, g_module_error()); + g_string_append(messages, "\n"); + g_log(G_LOG_DOMAIN,G_LOG_LEVEL_INFO,"Trial failed, %s", g_module_error()); + } + + /* Module cannot be found */ + + if(gm == NULL) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Failed to load %s", name); + g_set_error(error, lttv_module_error, LTTV_MODULE_NOT_FOUND, + "Cannot load library %s: %s", name, messages->str); + g_string_free(messages, TRUE); + return NULL; + } + g_string_free(messages, TRUE); + + /* Check if the library was already loaded */ + + l = g_hash_table_lookup(libraries_by_g_module, gm); + + /* This library was not already loaded */ + + if(l == NULL) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Library %s (%s) loaded", name, + g_module_name(gm)); + l = library_add(name, path, gm); + } + return l; +} + + +LttvLibrary *lttv_library_load(char *name, GError **error) +{ + LttvLibrary *l = library_load(name, error); + l->info.load_count++; + return l; +} + + +static void library_unload(LttvLibrary *l) +{ + guint i, len; + + GModule *gm; + + LttvModule *m; + + if(l->locked_loaded > 0) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Unload library %s: locked loaded", + l->info.name); + return; + } + + if(l->info.load_count > 0) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Unload library %s: load count %d", + l->info.name, l->info.load_count); + return; + } + + /* Check if all its modules have been released */ + + for(i = 0 ; i < l->modules->len ; i++) { + m = (LttvModule *)(l->modules->pdata[i]); + if(m->info.use_count > 0) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO,"Unload library %s: module %s used", + l->info.name, m->info.name); + return; + } + } + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Unload library %s: close the GModule", + l->info.name); + gm = l->gm; + library_remove(l); + if(gm != NULL) g_module_close(gm); + + /* insure that module.c will be finalized */ + + finish_destroy(); +} + + +void lttv_library_unload(LttvLibrary *l) +{ + l->info.load_count--; + library_unload(l); +} + + +static void library_lock_loaded(LttvLibrary *l) +{ + l->locked_loaded++; +} + + +static void library_unlock_loaded(LttvLibrary *l) +{ + l->locked_loaded--; + library_unload(l); +} + + +static LttvModule *module_require(char *name, GError **error) +{ + GError *tmp_error = NULL; + + guint i, j; + + LttvModule *m, *required; + + LttvLibrary *l = NULL; + + GPtrArray *modules; + + /* Insure that module.c is initialized */ + + init(); + + /* Check if the module is already loaded */ + + modules = g_hash_table_lookup(modules_by_name, name); + + /* Try to load a library having the module name */ + + if(modules == NULL) { + l = library_load(name, error); + if(l == NULL) return NULL; + else library_lock_loaded(l); + + /* A library was found, does it contain the named module */ + + modules = g_hash_table_lookup(modules_by_name, name); + if(modules == NULL) { + g_set_error(error, lttv_module_error, LTTV_MODULE_NOT_FOUND, + "Module %s not found in library %s", name, l->info.name); + library_unlock_loaded(l); + return NULL; + } + } + m = (LttvModule *)(modules->pdata[modules->len - 1]); + + /* We have the module */ + + m->info.use_count++; + + /* First use of the module. Initialize after getting the prerequisites */ + + if(m->info.use_count == 1) { + for(i = 0 ; i < m->info.prerequisites_number ; i++) { + required = module_require(m->prerequisites_names[i], &tmp_error); + + /* A prerequisite could not be found, undo everything and fail */ + + if(required == NULL) { + for(j = 0 ; j < m->prerequisites->len ; j++) { + module_release((LttvModule *)(m->prerequisites->pdata[j])); + } + g_ptr_array_set_size(m->prerequisites, 0); + if(l != NULL) library_unlock_loaded(l); + g_set_error(error, lttv_module_error, LTTV_MODULE_NOT_FOUND, + "Cannot find prerequisite for module %s: %s", name, + tmp_error->message); + g_clear_error(&tmp_error); + return NULL; + } + g_ptr_array_add(m->prerequisites, required); + } + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Module %s: init()", m->info.name); + m->info.init(); + } + + /* Decrement the load count of the library. It will not really be + unloaded since it contains a currently used module. */ + + if(l != NULL) library_unlock_loaded(l); + + return(m); +} + + +/* The require_count for a module is the number of explicit calls to + lttv_module_require, while the use_count also counts the number of times + a module is needed as a prerequisite. */ + +LttvModule *lttv_module_require(char *name, GError **error) +{ + LttvModule *m = module_require(name, error); + if(m != NULL) m->info.require_count++; + return(m); +} + + +static void module_release(LttvModule *m) +{ + guint i; + + library_lock_loaded(m->info.library); + + m->info.use_count--; + if(m->info.use_count == 0) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Module %s: destroy()",m->info.name); + m->info.destroy(); + for(i = 0 ; i < m->prerequisites->len ; i++) { + module_release((LttvModule *)(m->prerequisites->pdata[i])); + } + g_ptr_array_set_size(m->prerequisites, 0); + } + library_unlock_loaded(m->info.library); +} + + +void lttv_module_release(LttvModule *m) +{ + m->info.require_count--; + module_release(m); +} + + +void lttv_module_info(LttvModule *m, LttvModuleInfo *info) +{ + *info = m->info; +} + + +unsigned lttv_module_prerequisite_number(LttvModule *m) +{ + return m->prerequisites->len; +} + + +LttvModule *lttv_module_prerequisite_get(LttvModule *m, unsigned i) +{ + return (LttvModule *)(m->prerequisites->pdata[i]); +} + + +void lttv_library_info(LttvLibrary *l, LttvLibraryInfo *info) +{ + *info = l->info; +} + + +unsigned lttv_library_module_number(LttvLibrary *l) +{ + return l->modules->len; +} + + +LttvModule *lttv_library_module_get(LttvLibrary *l, unsigned i) +{ + return (LttvModule *)(l->modules->pdata[i]); +} + + +unsigned lttv_library_number() +{ + return libraries->len; +} + + +LttvLibrary *lttv_library_get(unsigned i) +{ + return (LttvLibrary *)(libraries->pdata[i]); +} + + +void lttv_library_path_add(char *name) +{ + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Add library path %s", name); + g_ptr_array_add(library_paths,(char*)g_strdup(name)); +} + + +void lttv_library_path_remove(char *name) +{ + guint i; + + for(i = 0 ; i < library_paths->len ; i++) { + if(g_str_equal(name, library_paths->pdata[i])) { + g_free(library_paths->pdata[i]); + g_ptr_array_remove_index(library_paths,i); + return; + } + } +} + + +unsigned lttv_library_path_number() +{ + return library_paths->len; +} + + +char *lttv_library_path_get(unsigned i) +{ + return (char *)(library_paths->pdata[library_paths->len - i - 1]); +} + + +void lttv_module_register(struct _LttvModuleDescription *d) +{ + *module_next = d; + module_next = &(d->next); +} + + +static void init() +{ + if(initialized) return; + g_assert(destroyed); + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Init module.c"); + + initialized = TRUE; + destroyed = FALSE; + lttv_module_error = g_quark_from_string("LTTV_MODULE_ERROR"); + modules_by_name = g_hash_table_new(g_str_hash, g_str_equal); + libraries = g_ptr_array_new(); + libraries_by_g_module = g_hash_table_new(g_direct_hash, g_direct_equal); + library_paths = g_ptr_array_new(); + + if(builtin_chain == NULL) builtin_chain = module_chain; + module_chain = builtin_chain; + library_add("builtin", NULL, NULL); +} + + +static finish_destroy() +{ + guint i; + + if(initialized) return; + g_assert(!destroyed); + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Finish destroy module.c"); + g_hash_table_destroy(modules_by_name); + g_ptr_array_free(libraries, TRUE); + g_hash_table_destroy(libraries_by_g_module); + for(i = 0 ; i < library_paths->len ; i++) { + g_free(library_paths->pdata[i]); + } + g_ptr_array_free(library_paths, TRUE); + destroyed = TRUE; +} + + +static void destroy() +{ + guint i, j, nb; + + LttvLibrary *l, **locked_libraries; + + LttvModule *m; + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Destroy module.c"); + + /* Unload all libraries */ + + nb = libraries->len; + locked_libraries = g_new(LttvLibrary *, nb); + + for(i = 0 ; i < nb ; i++) { + l = (LttvLibrary *)(libraries->pdata[i]); + locked_libraries[i] = l; + library_lock_loaded(l); + for(j = 0 ; j < l->modules->len ; j++) { + m = (LttvModule *)(l->modules->pdata[j]); + while(m->info.require_count > 0) lttv_module_release(m); + } + while(l->info.load_count > 0) lttv_library_unload(l); + } + + for(i = 0 ; i < nb ; i++) { + l = locked_libraries[i]; + library_unlock_loaded(l); + } + g_free(locked_libraries); + + /* The library containing module.c may be locked by our caller */ + + g_assert(libraries->len <= 1); + + initialized = FALSE; +} + +LTTV_MODULE("module", "Modules in libraries", \ + "Load libraries, list, require and initialize contained modules", \ + init, destroy) + diff --git a/ltt/branches/poly/lttv/lttv/module.h b/ltt/branches/poly/lttv/lttv/module.h new file mode 100644 index 00000000..e88b7b92 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/module.h @@ -0,0 +1,207 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef MODULES_H +#define MODULES_H + +#include + +/* A module contains some functionality which becomes available atfer it is + initialized and before it is destroyed. A module is characterized by a name, + a description (short and long), a list of names of other modules on which + it depends, and an initialization and a destruction function. + + A library contains one or more modules and may be loaded dynamically. + The modules contained in a library are automatically registered through + constructors which are called when the library is loaded. For modules + directly linked with the main program (builtin), the constructors are + called before the main program starts. (However, neither malloc nor glib + functions are used during the registration process). + + The library loading path is a set of directories, where requested + libraries and modules are searched for. +*/ + +typedef struct _LttvModule LttvModule; + +typedef struct _LttvLibrary LttvLibrary; + +typedef void (*LttvModuleInit)(); + +typedef void (*LttvModuleDestroy)(); + +typedef struct _LttvModuleInfo +{ + char *name; + char *short_description; + char *description; + LttvModuleInit init; + LttvModuleDestroy destroy; + LttvLibrary *library; + unsigned require_count; + unsigned use_count; + unsigned prerequisites_number; +} LttvModuleInfo; + + +typedef struct _LttvLibraryInfo +{ + char *name; + char *path; + unsigned load_count; +} LttvLibraryInfo; + + +typedef enum _LttvModuleError +{ + LTTV_MODULE_NOT_FOUND, + LTTV_MODULE_NO_INIT +} LttvModuleError; + + +/* Insure that a module is loaded and initialized. Require count + (number of times the module was required) and use count + (number of times required or used as prerequisite) serve to + insure that a module is destroyed only after it has been released + as many times as it was required (and prerequired). + + The module is searched among the modules currently loaded, then as a + similarly named library to load which should contain the named module. + If the module cannot be found or loaded, NULL is returned and an + explanation is provided in error. */ + +LttvModule *lttv_module_require(char *name, GError **error); + +void lttv_module_release(LttvModule *m); + + +/* Obtain information about the module, including the containing library */ + +void lttv_module_info(LttvModule *m, LttvModuleInfo *info); + + +/* List the modules on which this module depends */ + +unsigned lttv_module_prerequisite_number(LttvModule *m); + +LttvModule *lttv_module_prerequisite_get(LttvModule *m, unsigned i); + + +/* Insure that a library is loaded. A load count insures that a library + is unloaded only after it has been asked to unload as + many times as it was loaded, and its modules are not in use. The library + is searched along the library path if name is a relative pathname. + If the library cannot be found or loaded, NULL is returned and an + explanation is provided in error. */ + +LttvLibrary *lttv_library_load(char *name, GError **error); + +void lttv_library_unload(LttvLibrary *l); + + +/* Obtain information about the library */ + +void lttv_library_info(LttvLibrary *l, LttvLibraryInfo *info); + + +/* List the modules contained in a library */ + +unsigned lttv_library_module_number(LttvLibrary *l); + +LttvModule *lttv_library_module_get(LttvLibrary *l, unsigned i); + + +/* List the currently loaded libraries */ + +unsigned lttv_library_number(); + +LttvLibrary *lttv_library_get(unsigned i); + + + +/* Add or remove directory names to the library search path */ + +void lttv_library_path_add(char *name); + +void lttv_library_path_remove(char *name); + + +/* List the directory names in the library search path */ + +unsigned lttv_library_path_number(); + +char *lttv_library_path_get(unsigned i); + + +/* To define a module, simply call the LTTV_MODULE macro with the needed + arguments: single word name, one line short description, larger + description, initialization function, destruction function, and + list of names for required modules (e.g., "moduleA", "moduleB"). + This will insure that the module is registered at library load time. + + Example: + + LTTV_MODULE("option", "Command line options processing", "...", \ + init, destroy, "moduleA", "moduleB") +*/ + +#define LTTV_MODULE(name, short_desc, desc, init, destroy, ...) \ + \ + static void _LTTV_MODULE_REGISTER(__LINE__)() \ + __attribute__((constructor)); \ + \ + static void _LTTV_MODULE_REGISTER(__LINE__)() \ + { \ + static char *module_prerequisites[] = { __VA_ARGS__ }; \ + \ + static struct _LttvModuleDescription module = { \ + name, short_desc, desc, init, destroy, \ + sizeof(module_prerequisites) / sizeof(char *), \ + module_prerequisites, NULL}; \ + \ + lttv_module_register(&module); \ + } + + +/* Internal structure and function used to register modules, called by + LTTV_MODULE */ + +#define __LTTV_MODULE_REGISTER(line) _lttv_module_register_ ## line +#define _LTTV_MODULE_REGISTER(line) __LTTV_MODULE_REGISTER(line) + +struct _LttvModuleDescription +{ + char *name; + char *short_description; + char *description; + LttvModuleInit init; + LttvModuleDestroy destroy; + unsigned prerequisites_number; + char **prerequisites; + struct _LttvModuleDescription *next; +}; + +void lttv_module_register(struct _LttvModuleDescription *d); + +#endif // MODULES_H + + + + + + diff --git a/ltt/branches/poly/lttv/lttv/option.c b/ltt/branches/poly/lttv/lttv/option.c new file mode 100644 index 00000000..7532073e --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/option.c @@ -0,0 +1,287 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + + +#include +#include +#include +#include + +typedef struct _LttvOption { + char *long_name; + char char_name; + char *description; + char *arg_description; + LttvOptionType t; + gpointer p; + LttvOptionHook hook; + gpointer hook_data; +} LttvOption; + +GHashTable *options; + + +static void +list_options(gpointer key, gpointer value, gpointer user_data) +{ + g_ptr_array_add((GPtrArray *)user_data, value); +} + + +static void +free_option(LttvOption *option) +{ + g_free(option->long_name); + g_free(option->description); + g_free(option->arg_description); + g_free(option); +} + + +void lttv_option_add(const char *long_name, const char char_name, + const char *description, const char *arg_description, + const LttvOptionType t, void *p, + const LttvOptionHook h, void *hook_data) +{ + LttvOption *option; + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Add option %s", long_name); + if(g_hash_table_lookup(options, long_name) != NULL) { + g_warning("duplicate option"); + return; + } + + option = g_new(LttvOption, 1); + option->long_name = g_strdup(long_name); + option->char_name = char_name; + option->description = g_strdup(description); + option->arg_description = g_strdup(arg_description); + option->t = t; + option->p = p; + option->hook = h; + option->hook_data = hook_data; + g_hash_table_insert(options, option->long_name, option); +} + + +void +lttv_option_remove(const char *long_name) +{ + LttvOption *option = g_hash_table_lookup(options, long_name); + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Remove option %s", long_name); + if(option == NULL) { + g_warning("trying to remove unknown option %s", long_name); + return; + } + g_hash_table_remove(options, long_name); + free_option(option); +} + + +static int poptToLTT[] = { + POPT_ARG_NONE, POPT_ARG_STRING, POPT_ARG_INT, POPT_ARG_LONG +}; + +static struct poptOption endOption = { NULL, '\0', 0, NULL, 0}; + + +static void +build_popts(GPtrArray **plist, struct poptOption **ppopts, poptContext *pc, + int argc, char **argv) +{ + LttvOption *option; + + GPtrArray *list; + + struct poptOption *popts; + + poptContext c; + + guint i; + + list = g_ptr_array_new(); + + g_hash_table_foreach(options, list_options, list); + + /* Build a popt options array from our list */ + + popts = g_new(struct poptOption, list->len + 1); + + for(i = 0 ; i < list->len ; i++) { + option = (LttvOption *)list->pdata[i]; + popts[i].longName = option->long_name; + popts[i].shortName = option->char_name; + popts[i].descrip = option->description; + popts[i].argDescrip = option->arg_description; + popts[i].argInfo = poptToLTT[option->t]; + popts[i].arg = option->p; + popts[i].val = i + 1; + } + + /* Terminate the array for popt and create the context */ + + popts[list->len] = endOption; + c = poptGetContext(argv[0], argc, (const char**)argv, popts, 0); + + *plist = list; + *ppopts = popts; + *pc = c; +} + + +static void +destroy_popts(GPtrArray **plist, struct poptOption **ppopts, poptContext *pc) +{ + g_ptr_array_free(*plist, TRUE); *plist = NULL; + g_free(*ppopts); *ppopts = NULL; + poptFreeContext(*pc); +} + + +void lttv_option_parse(int argc, char **argv) +{ + GPtrArray *list; + + LttvOption *option; + + int i, rc, first_arg; + + struct poptOption *popts; + + poptContext c; + + i = 0; + + first_arg = 0; + + build_popts(&list, &popts, &c, argc, argv); + + /* Parse options while not end of options event */ + + while((rc = poptGetNextOpt(c)) != -1) { + + /* The option was recognized and the rc value returned is the argument + position in the array. Call the associated hook if present. */ + + if(rc > 0) { + option = (LttvOption *)(list->pdata[rc - 1]); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Option %s encountered", + option->long_name); + if(option->hook != NULL) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s hook called", + option->long_name); + option->hook(option->hook_data); + } + i++; + } + + else if(rc == POPT_ERROR_BADOPT && i != first_arg) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, + "Option %s not recognized, rescan options with new additions", + poptBadOption(c,0)); + + /* Perhaps this option is newly added, restart parsing */ + + destroy_popts(&list, &popts, &c); + build_popts(&list, &popts, &c, argc, argv); + + /* Get back to the same argument */ + + first_arg = i; + for(i = 0; i < first_arg; i++) { + rc = poptGetNextOpt(c); + option = (LttvOption *)(list->pdata[rc - 1]); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s rescanned, skipped", + option->long_name); + } + } + + else { + + /* The option has some error and it is not because this is a newly + added option not recognized. */ + + g_error("option %s: %s", poptBadOption(c,0), poptStrerror(rc)); + break; + } + + } + + destroy_popts(&list, &popts, &c); +} + +/* CHECK */ +static void show_help(LttvOption *option) +{ + printf("--%s -%c argument: %s\n" , option->long_name, + option->char_name, + option->arg_description); + printf(" %s\n" , option->description); + +} + +void lttv_option_show_help(void) +{ + LttvOption option; + + GPtrArray *list = g_ptr_array_new(); + + int i; + + g_hash_table_foreach(options, list_options, list); + + printf("Built-in commands available:\n"); + printf("\n"); + + for(i = 0 ; i < list->len ; i++) { + show_help((LttvOption *)list->pdata[i]); + } + g_ptr_array_free(list, TRUE); + + +} + +static void init() +{ + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Init option.c"); + options = g_hash_table_new(g_str_hash, g_str_equal); +} + + +static void destroy() +{ + LttvOption option; + + GPtrArray *list = g_ptr_array_new(); + + int i; + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Destroy option.c"); + g_hash_table_foreach(options, list_options, list); + g_hash_table_destroy(options); + + for(i = 0 ; i < list->len ; i++) { + free_option((LttvOption *)list->pdata[i]); + } + g_ptr_array_free(list, TRUE); +} + +LTTV_MODULE("option", "Command line options processing", \ + "Functions to add, remove and parse command line options", \ + init, destroy) diff --git a/ltt/branches/poly/lttv/lttv/option.h b/ltt/branches/poly/lttv/lttv/option.h new file mode 100644 index 00000000..fc8f14d5 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/option.h @@ -0,0 +1,53 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef OPTION_H +#define OPTION_H + +/* Define a new option with a long name (--long_name), a short + one character name (-c), a descriptive text, the argument type, and a + pointer to where the argument value will be stored. For an option of + type LTTV_OPT_NONE, the argument is a boolean value set to true when the + option is present. The option hook is called if non NULL. */ + +typedef enum _LttvOptionType +{LTTV_OPT_NONE, LTTV_OPT_STRING, LTTV_OPT_INT, LTTV_OPT_LONG } +LttvOptionType; + +typedef void (*LttvOptionHook)(void *hook_data); + +void lttv_option_add(const char *long_name, const char char_name, + const char *description, const char *arg_description, + const LttvOptionType t, void *p, + const LttvOptionHook h, void *hook_data); + + +/* Remove an option */ + +void lttv_option_remove(const char *long_name); + + +/* Parse command line options. It is possible to add options (through the + hooks being called) while the parsing is done. The new options will be + used for subsequent command line arguments. */ + +void lttv_option_parse(int argc, char **argv); + +void lttv_option_show_help(void); + +#endif // OPTION_H diff --git a/ltt/branches/poly/lttv/lttv/processTrace.c b/ltt/branches/poly/lttv/lttv/processTrace.c new file mode 100644 index 00000000..30f2da07 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/processTrace.c @@ -0,0 +1,840 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + + +#include +#include +#include +#include +#include + +void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts) +{ + LTTV_TRACESET_CONTEXT_GET_CLASS(self)->init(self, ts); +} + + +void lttv_context_fini(LttvTracesetContext *self) +{ + LTTV_TRACESET_CONTEXT_GET_CLASS(self)->fini(self); +} + + +LttvTracesetContext * +lttv_context_new_traceset_context(LttvTracesetContext *self) +{ + return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_traceset_context(self); +} + + + + +LttvTraceContext * +lttv_context_new_trace_context(LttvTracesetContext *self) +{ + return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self); +} + + +LttvTracefileContext * +lttv_context_new_tracefile_context(LttvTracesetContext *self) +{ + return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self); +} + +/**************************************************************************** + * lttv_traceset_context_compute_time_span + * + * Keep the Time_Span is sync with on the fly addition and removal of traces + * in a trace set. It must be called each time a trace is added/removed from + * the traceset. It could be more efficient to call it only once a bunch + * of traces are loaded, but the calculation is not long, so it's not + * critical. + * + * Author : Xang Xiu Yang + * Imported from gtkTraceSet.c by Mathieu Desnoyers + ***************************************************************************/ +static void lttv_traceset_context_compute_time_span( + LttvTracesetContext *self, + TimeInterval *Time_Span) +{ + LttvTraceset * traceset = self->ts; + int numTraces = lttv_traceset_number(traceset); + int i; + LttTime s, e; + LttvTraceContext *tc; + LttTrace * trace; + + Time_Span->startTime.tv_sec = 0; + Time_Span->startTime.tv_nsec = 0; + Time_Span->endTime.tv_sec = 0; + Time_Span->endTime.tv_nsec = 0; + + for(i=0; itraces[i]; + trace = tc->t; + + ltt_trace_time_span_get(trace, &s, &e); + + if(i==0){ + Time_Span->startTime = s; + Time_Span->endTime = e; + }else{ + if(s.tv_sec < Time_Span->startTime.tv_sec || + (s.tv_sec == Time_Span->startTime.tv_sec + && s.tv_nsec < Time_Span->startTime.tv_nsec)) + Time_Span->startTime = s; + if(e.tv_sec > Time_Span->endTime.tv_sec || + (e.tv_sec == Time_Span->endTime.tv_sec && + e.tv_nsec > Time_Span->endTime.tv_nsec)) + Time_Span->endTime = e; + } + } +} + + +static void +init(LttvTracesetContext *self, LttvTraceset *ts) +{ + guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile; + + LttvTraceContext *tc; + + LttvTracefileContext *tfc; + + LttTime null_time = {0, 0}; + + nb_trace = lttv_traceset_number(ts); + self->ts = ts; + self->traces = g_new(LttvTraceContext *, nb_trace); + self->before = lttv_hooks_new(); + self->after = lttv_hooks_new(); + self->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); + self->ts_a = lttv_traceset_attribute(ts); + for(i = 0 ; i < nb_trace ; i++) { + tc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self); + self->traces[i] = tc; + + tc->ts_context = self; + tc->index = i; + tc->vt = lttv_traceset_get(ts, i); + tc->t = lttv_trace(tc->vt); + tc->check = lttv_hooks_new(); + tc->before = lttv_hooks_new(); + tc->after = lttv_hooks_new(); + tc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); + tc->t_a = lttv_trace_attribute(tc->vt); + nb_control = ltt_trace_control_tracefile_number(tc->t); + nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t); + nb_tracefile = nb_control + nb_per_cpu; + tc->tracefiles = g_new(LttvTracefileContext *, nb_tracefile); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self); + tc->tracefiles[j] = tfc; + tfc->index = j; + + if(j < nb_control) { + tfc->control = TRUE; + tfc->tf = ltt_trace_control_tracefile_get(tc->t, j); + } + else { + tfc->control = FALSE; + tfc->tf = ltt_trace_per_cpu_tracefile_get(tc->t, j - nb_control); + } + tfc->t_context = tc; + tfc->check = lttv_hooks_new(); + tfc->before = lttv_hooks_new(); + tfc->after = lttv_hooks_new(); + tfc->check_event = lttv_hooks_new(); + tfc->before_event = lttv_hooks_new(); + tfc->before_event_by_id = lttv_hooks_by_id_new(); + tfc->after_event = lttv_hooks_new(); + tfc->after_event_by_id = lttv_hooks_by_id_new(); + tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); + } + } + lttv_process_traceset_seek_time(self, null_time); + /*CHECK why dynamically allocate the time span... and the casing is wroNg*/ + self->Time_Span = g_new(TimeInterval,1); + lttv_traceset_context_compute_time_span(self, self->Time_Span); +} + + +void fini(LttvTracesetContext *self) +{ + guint i, j, nb_trace, nb_tracefile; + + LttvTraceContext *tc; + + LttvTracefileContext *tfc; + + LttvTraceset *ts = self->ts; + + g_free(self->Time_Span); + + lttv_hooks_destroy(self->before); + lttv_hooks_destroy(self->after); + //FIXME : segfault + g_object_unref(self->a); + + nb_trace = lttv_traceset_number(ts); + + for(i = 0 ; i < nb_trace ; i++) { + tc = self->traces[i]; + + lttv_hooks_destroy(tc->check); + lttv_hooks_destroy(tc->before); + lttv_hooks_destroy(tc->after); + g_object_unref(tc->a); + + nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + + ltt_trace_per_cpu_tracefile_number(tc->t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfc = tc->tracefiles[j]; + lttv_hooks_destroy(tfc->check); + lttv_hooks_destroy(tfc->before); + lttv_hooks_destroy(tfc->after); + lttv_hooks_destroy(tfc->check_event); + lttv_hooks_destroy(tfc->before_event); + lttv_hooks_by_id_destroy(tfc->before_event_by_id); + lttv_hooks_destroy(tfc->after_event); + lttv_hooks_by_id_destroy(tfc->after_event_by_id); + g_object_unref(tfc->a); + g_object_unref(tfc); + } + g_free(tc->tracefiles); + g_object_unref(tc); + } + g_free(self->traces); +} + + +void lttv_traceset_context_add_hooks(LttvTracesetContext *self, + LttvHooks *before_traceset, + LttvHooks *after_traceset, + LttvHooks *check_trace, + LttvHooks *before_trace, + LttvHooks *after_trace, + LttvHooks *check_tracefile, + LttvHooks *before_tracefile, + LttvHooks *after_tracefile, + LttvHooks *check_event, + LttvHooks *before_event, + LttvHooks *after_event) +{ + LttvTraceset *ts = self->ts; + + guint i, j, nb_trace, nb_tracefile; + + LttvTraceContext *tc; + + LttvTracefileContext *tfc; + + void *hook_data; + + lttv_hooks_add_list(self->before, before_traceset); + lttv_hooks_add_list(self->after, after_traceset); + nb_trace = lttv_traceset_number(ts); + + for(i = 0 ; i < nb_trace ; i++) { + tc = self->traces[i]; + lttv_hooks_add_list(tc->check, check_trace); + lttv_hooks_add_list(tc->before, before_trace); + lttv_hooks_add_list(tc->after, after_trace); + nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + + ltt_trace_per_cpu_tracefile_number(tc->t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfc = tc->tracefiles[j]; + lttv_hooks_add_list(tfc->check, check_tracefile); + lttv_hooks_add_list(tfc->before, before_tracefile); + lttv_hooks_add_list(tfc->after, after_tracefile); + lttv_hooks_add_list(tfc->check_event, check_event); + lttv_hooks_add_list(tfc->before_event, before_event); + lttv_hooks_add_list(tfc->after_event, after_event); + } + } +} + + +void lttv_traceset_context_remove_hooks(LttvTracesetContext *self, + LttvHooks *before_traceset, + LttvHooks *after_traceset, + LttvHooks *check_trace, + LttvHooks *before_trace, + LttvHooks *after_trace, + LttvHooks *check_tracefile, + LttvHooks *before_tracefile, + LttvHooks *after_tracefile, + LttvHooks *check_event, + LttvHooks *before_event, + LttvHooks *after_event) +{ + LttvTraceset *ts = self->ts; + + guint i, j, nb_trace, nb_tracefile; + + LttvTraceContext *tc; + + LttvTracefileContext *tfc; + + void *hook_data; + + lttv_hooks_remove_list(self->before, before_traceset); + lttv_hooks_remove_list(self->after, after_traceset); + nb_trace = lttv_traceset_number(ts); + + for(i = 0 ; i < nb_trace ; i++) { + tc = self->traces[i]; + lttv_hooks_remove_list(tc->check, check_trace); + lttv_hooks_remove_list(tc->before, before_trace); + lttv_hooks_remove_list(tc->after, after_trace); + nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + + ltt_trace_per_cpu_tracefile_number(tc->t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfc = tc->tracefiles[j]; + lttv_hooks_remove_list(tfc->check, check_tracefile); + lttv_hooks_remove_list(tfc->before, before_tracefile); + lttv_hooks_remove_list(tfc->after, after_tracefile); + lttv_hooks_remove_list(tfc->check_event, check_event); + lttv_hooks_remove_list(tfc->before_event, before_event); + lttv_hooks_remove_list(tfc->after_event, after_event); + } + } +} + +void lttv_trace_context_add_hooks(LttvTraceContext *tc, + LttvHooks *check_trace, + LttvHooks *before_trace, + LttvHooks *after_trace) +{ + lttv_hooks_add_list(tc->check, check_trace); + lttv_hooks_add_list(tc->before, before_trace); + lttv_hooks_add_list(tc->after, after_trace); +} + +void lttv_trace_context_remove_hooks(LttvTraceContext *tc, + LttvHooks *check_trace, + LttvHooks *before_trace, + LttvHooks *after_trace) +{ + lttv_hooks_remove_list(tc->check, check_trace); + lttv_hooks_remove_list(tc->before, before_trace); + lttv_hooks_remove_list(tc->after, after_trace); +} + +void lttv_tracefile_context_add_hooks(LttvTracefileContext *tfc, + LttvHooks *check_tracefile, + LttvHooks *before_tracefile, + LttvHooks *after_tracefile, + LttvHooks *check_event, + LttvHooks *before_event, + LttvHooks *after_event) +{ + lttv_hooks_add_list(tfc->check, check_tracefile); + lttv_hooks_add_list(tfc->before, before_tracefile); + lttv_hooks_add_list(tfc->after, after_tracefile); + lttv_hooks_add_list(tfc->check_event, check_event); + lttv_hooks_add_list(tfc->before_event, before_event); + lttv_hooks_add_list(tfc->after_event, after_event); +} + +void lttv_tracefile_context_remove_hooks(LttvTracefileContext *tfc, + LttvHooks *check_tracefile, + LttvHooks *before_tracefile, + LttvHooks *after_tracefile, + LttvHooks *check_event, + LttvHooks *before_event, + LttvHooks *after_event) +{ + lttv_hooks_remove_list(tfc->check, check_tracefile); + lttv_hooks_remove_list(tfc->before, before_tracefile); + lttv_hooks_remove_list(tfc->after, after_tracefile); + lttv_hooks_remove_list(tfc->check_event, check_event); + lttv_hooks_remove_list(tfc->before_event, before_event); + lttv_hooks_remove_list(tfc->after_event, after_event); +} + +void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext *tfc, + unsigned i, + LttvHooks *before_event_by_id, + LttvHooks *after_event_by_id) +{ + LttvHooks * h; + h = lttv_hooks_by_id_find(tfc->before_event_by_id, i); + lttv_hooks_add_list(h, before_event_by_id); + h = lttv_hooks_by_id_find(tfc->after_event_by_id, i); + lttv_hooks_add_list(h, after_event_by_id); +} + +void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext *tfc, + unsigned i) +{ + lttv_hooks_by_id_remove(tfc->before_event_by_id, i); + lttv_hooks_by_id_remove(tfc->after_event_by_id, i); +} + +static LttvTracesetContext * +new_traceset_context(LttvTracesetContext *self) +{ + return g_object_new(LTTV_TRACESET_CONTEXT_TYPE, NULL); +} + + +static LttvTraceContext * +new_trace_context(LttvTracesetContext *self) +{ + return g_object_new(LTTV_TRACE_CONTEXT_TYPE, NULL); +} + + +static LttvTracefileContext * +new_tracefile_context(LttvTracesetContext *self) +{ + return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE, NULL); +} + + +static void +traceset_context_instance_init (GTypeInstance *instance, gpointer g_class) +{ + /* Be careful of anything which would not work well with shallow copies */ +} + + +static void +traceset_context_finalize (LttvTracesetContext *self) +{ + G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE))) + ->finalize(G_OBJECT(self)); +} + + +static void +traceset_context_class_init (LttvTracesetContextClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = (void (*)(GObject *self))traceset_context_finalize; + klass->init = init; + klass->fini = fini; + klass->new_traceset_context = new_traceset_context; + klass->new_trace_context = new_trace_context; + klass->new_tracefile_context = new_tracefile_context; +} + + +GType +lttv_traceset_context_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof (LttvTracesetContextClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) traceset_context_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (LttvTracesetContext), + 0, /* n_preallocs */ + (GInstanceInitFunc) traceset_context_instance_init /* instance_init */ + }; + + type = g_type_register_static (G_TYPE_OBJECT, "LttvTracesetContextType", + &info, 0); + } + return type; +} + + +static void +trace_context_instance_init (GTypeInstance *instance, gpointer g_class) +{ + /* Be careful of anything which would not work well with shallow copies */ +} + + +static void +trace_context_finalize (LttvTraceContext *self) +{ + G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE)))-> + finalize(G_OBJECT(self)); +} + + +static void +trace_context_class_init (LttvTraceContextClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = (void (*)(GObject *self)) trace_context_finalize; +} + + +GType +lttv_trace_context_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof (LttvTraceContextClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) trace_context_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (LttvTraceContext), + 0, /* n_preallocs */ + (GInstanceInitFunc) trace_context_instance_init /* instance_init */ + }; + + type = g_type_register_static (G_TYPE_OBJECT, "LttvTraceContextType", + &info, 0); + } + return type; +} + + +static void +tracefile_context_instance_init (GTypeInstance *instance, gpointer g_class) +{ + /* Be careful of anything which would not work well with shallow copies */ +} + + +static void +tracefile_context_finalize (LttvTracefileContext *self) +{ + G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE))) + ->finalize(G_OBJECT(self)); +} + + +static void +tracefile_context_class_init (LttvTracefileContextClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = (void (*)(GObject *self))tracefile_context_finalize; +} + + +GType +lttv_tracefile_context_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof (LttvTracefileContextClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) tracefile_context_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (LttvTracefileContext), + 0, /* n_preallocs */ + (GInstanceInitFunc) tracefile_context_instance_init /* instance_init */ + }; + + type = g_type_register_static (G_TYPE_OBJECT, "LttvTracefileContextType", + &info, 0); + } + return type; +} + + +gint compare_tracefile(gconstpointer a, gconstpointer b) +{ + gint comparison; + + LttvTracefileContext *trace_a = (LttvTracefileContext *)a; + + LttvTracefileContext *trace_b = (LttvTracefileContext *)b; + + if(trace_a == trace_b) return 0; + comparison = ltt_time_compare(trace_a->timestamp, trace_b->timestamp); + if(comparison != 0) return comparison; + if(trace_a->index < trace_b->index) return -1; + else if(trace_a->index > trace_b->index) return 1; + if(trace_a->t_context->index < trace_b->t_context->index) return -1; + else if(trace_a->t_context->index > trace_b->t_context->index) return 1; + g_assert(FALSE); +} + + +gboolean get_first(gpointer key, gpointer value, gpointer user_data) { + *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value; + return TRUE; +} + + +void lttv_process_traceset_begin(LttvTracesetContext *self, LttTime end) +{ + guint i, j, nbi, nb_tracefile; + + LttvTraceContext *tc; + + LttvTracefileContext *tfc; + + /* Call all before_traceset, before_trace, and before_tracefile hooks. + For all qualifying tracefiles, seek to the start time, create a context, + read one event and insert in the pqueue based on the event time. */ + + lttv_hooks_call(self->before, self); + nbi = lttv_traceset_number(self->ts); + self->pqueue = g_tree_new(compare_tracefile); + + for(i = 0 ; i < nbi ; i++) { + tc = self->traces[i]; + + if(!lttv_hooks_call_check(tc->check, tc)) { + lttv_hooks_call(tc->before, tc); + nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + + ltt_trace_per_cpu_tracefile_number(tc->t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfc = tc->tracefiles[j]; + + if(!lttv_hooks_call_check(tfc->check, tfc)) { + lttv_hooks_call(tfc->before, tfc); + + if(tfc->e != NULL) { + if(tfc->timestamp.tv_sec < end.tv_sec || + (tfc->timestamp.tv_sec == end.tv_sec && + tfc->timestamp.tv_nsec <= end.tv_nsec)) { + g_tree_insert(self->pqueue, tfc, tfc); + } + } + } + } + } + } +} + + +guint lttv_process_traceset_middle(LttvTracesetContext *self, LttTime end, + unsigned nb_events) +{ + GTree *pqueue = self->pqueue; + + guint id; + + LttvTraceContext *tc; + + LttvTracefileContext *tfc; + + LttEvent *event; + + unsigned count = 0; + + LttTime previous_timestamp = {0, 0}; + + /* Get the next event from the pqueue, call its hooks, + reinsert in the pqueue the following event from the same tracefile + unless the tracefile is finished or the event is later than the + start time. */ + + while(TRUE) { + tfc = NULL; + g_tree_foreach(pqueue, get_first, &tfc); + if(tfc == NULL) return count; + + /* Have we reached the maximum number of events specified? However, + continue for all the events with the same time stamp (CHECK?). Then, + empty the queue and break from the loop. */ + + if(count >= nb_events && + ltt_time_compare(tfc->timestamp, previous_timestamp) != 0) + return count; + + previous_timestamp = tfc->timestamp; + + + /* Get the tracefile with an event for the smallest time found. If two + or more tracefiles have events for the same time, hope that lookup + and remove are consistent. */ + + g_tree_remove(pqueue, tfc); + count++; + + if(!lttv_hooks_call(tfc->check_event, tfc)) { + id = ltt_event_eventtype_id(tfc->e); + lttv_hooks_call(lttv_hooks_by_id_get(tfc->before_event_by_id, id), tfc); + lttv_hooks_call(tfc->before_event, tfc); + lttv_hooks_call(lttv_hooks_by_id_get(tfc->after_event_by_id, id), tfc); + lttv_hooks_call(tfc->after_event, tfc); + } + + event = ltt_tracefile_read(tfc->tf); + if(event != NULL) { + tfc->e = event; + tfc->timestamp = ltt_event_time(event); + if(tfc->timestamp.tv_sec < end.tv_sec || + (tfc->timestamp.tv_sec == end.tv_sec && tfc->timestamp.tv_nsec <= end.tv_nsec)) + g_tree_insert(pqueue, tfc, tfc); + } + } +} + + +void lttv_process_traceset_end(LttvTracesetContext *self) +{ + guint i, j, nbi, nb_tracefile; + + LttvTraceContext *tc; + + LttvTracefileContext *tfc; + + /* Call all after_traceset, after_trace, and after_tracefile hooks. */ + + nbi = lttv_traceset_number(self->ts); + + for(i = 0 ; i < nbi ; i++) { + tc = self->traces[i]; + + /* The check hooks are called again to avoid memorizing the results + obtained at the beginning. CHECK if it poses a problem */ + + if(!lttv_hooks_call_check(tc->check, tc)) { + nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + + ltt_trace_per_cpu_tracefile_number(tc->t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfc = tc->tracefiles[j]; + + if(!lttv_hooks_call_check(tfc->check, tfc)) { + lttv_hooks_call(tfc->after, tfc); + } + } + lttv_hooks_call(tc->after, tc); + } + } + lttv_hooks_call(self->after, self); + + /* Empty and free the pqueue */ + + while(TRUE){ + tfc = NULL; + g_tree_foreach(self->pqueue, get_first, &tfc); + if(tfc == NULL) break; + g_tree_remove(self->pqueue, &(tfc->timestamp)); + } + g_tree_destroy(self->pqueue); +} + + +void lttv_process_traceset(LttvTracesetContext *self, LttTime end, + unsigned nb_events) +{ + lttv_process_traceset_begin(self, end); + lttv_process_traceset_middle(self, end, nb_events); + lttv_process_traceset_end(self); +} + + +void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start) +{ + guint i, nb_tracefile; + + LttvTracefileContext *tfc; + + LttEvent *event; + + nb_tracefile = ltt_trace_control_tracefile_number(self->t) + + ltt_trace_per_cpu_tracefile_number(self->t); + + for(i = 0 ; i < nb_tracefile ; i++) { + tfc = self->tracefiles[i]; + ltt_tracefile_seek_time(tfc->tf, start); + event = ltt_tracefile_read(tfc->tf); + tfc->e = event; + if(event != NULL) tfc->timestamp = ltt_event_time(event); + } +} + + +void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start) +{ + guint i, nb_trace; + + LttvTraceContext *tc; + + nb_trace = lttv_traceset_number(self->ts); + for(i = 0 ; i < nb_trace ; i++) { + tc = self->traces[i]; + lttv_process_trace_seek_time(tc, start); + } +} + + +static LttField * +find_field(LttEventType *et, const char *field) +{ + LttType *t; + + LttField *f; + + guint i, nb; + + char *name; + + if(field == NULL) return NULL; + + f = ltt_eventtype_field(et); + t = ltt_eventtype_type(et); + g_assert(ltt_type_class(t) == LTT_STRUCT); + nb = ltt_type_member_number(t); + for(i = 0 ; i < nb ; i++) { + ltt_type_member_type(t, i, &name); + if(strcmp(name, field) == 0) break; + } + g_assert(i < nb); + return ltt_field_member(f, i); +} + + +void +lttv_trace_find_hook(LttTrace *t, char *facility, char *event_type, + char *field1, char *field2, char *field3, LttvHook h, LttvTraceHook *th) +{ + LttFacility *f; + + LttEventType *et; + + guint nb, pos, i; + + char *name; + + nb = ltt_trace_facility_find(t, facility, &pos); + if(nb < 1) g_error("No %s facility", facility); + f = ltt_trace_facility_get(t, pos); + et = ltt_facility_eventtype_get_by_name(f, event_type); + if(et == NULL) g_error("Event %s does not exist", event_type); + + th->h = h; + th->id = ltt_eventtype_id(et); + th->f1 = find_field(et, field1); + th->f2 = find_field(et, field2); + th->f3 = find_field(et, field3); +} + + diff --git a/ltt/branches/poly/lttv/lttv/state.c b/ltt/branches/poly/lttv/lttv/state.c new file mode 100644 index 00000000..0624fe4b --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/state.c @@ -0,0 +1,1527 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +LttvExecutionMode + LTTV_STATE_MODE_UNKNOWN, + LTTV_STATE_USER_MODE, + LTTV_STATE_SYSCALL, + LTTV_STATE_TRAP, + LTTV_STATE_IRQ; + +LttvExecutionSubmode + LTTV_STATE_SUBMODE_UNKNOWN, + LTTV_STATE_SUBMODE_NONE; + +LttvProcessStatus + LTTV_STATE_UNNAMED, + LTTV_STATE_WAIT_FORK, + LTTV_STATE_WAIT_CPU, + LTTV_STATE_EXIT, + LTTV_STATE_WAIT, + LTTV_STATE_RUN; + +static GQuark + LTTV_STATE_TRACEFILES, + LTTV_STATE_PROCESSES, + LTTV_STATE_PROCESS, + LTTV_STATE_EVENT, + LTTV_STATE_SAVED_STATES, + LTTV_STATE_SAVED_STATES_TIME, + LTTV_STATE_TIME, + LTTV_STATE_HOOKS, + LTTV_STATE_NAME_TABLES, + LTTV_STATE_TRACE_STATE_USE_COUNT; + + +static void create_max_time(LttvTraceState *tcs); + +static void get_max_time(LttvTraceState *tcs); + +static void free_max_time(LttvTraceState *tcs); + +static void create_name_tables(LttvTraceState *tcs); + +static void get_name_tables(LttvTraceState *tcs); + +static void free_name_tables(LttvTraceState *tcs); + +static void free_saved_state(LttvTraceState *tcs); + +static void lttv_state_free_process_table(GHashTable *processes); + + +void lttv_state_save(LttvTraceState *self, LttvAttribute *container) +{ + LTTV_TRACE_STATE_GET_CLASS(self)->state_save(self, container); +} + + +void lttv_state_restore(LttvTraceState *self, LttvAttribute *container) +{ + LTTV_TRACE_STATE_GET_CLASS(self)->state_restore(self, container); +} + + +void lttv_state__state_saved_free(LttvTraceState *self, + LttvAttribute *container) +{ + LTTV_TRACE_STATE_GET_CLASS(self)->state_saved_free(self, container); +} + + +guint process_hash(gconstpointer key) +{ + return ((LttvProcessState *)key)->pid; +} + + +gboolean process_equal(gconstpointer a, gconstpointer b) +{ + LttvProcessState *process_a, *process_b; + + process_a = (LttvProcessState *)a; + process_b = (LttvProcessState *)b; + + if(process_a->pid != process_b->pid) return FALSE; + if(process_a->pid == 0 && + process_a->last_cpu != process_b->last_cpu) return FALSE; + return TRUE; +} + + +static void +restore_init_state(LttvTraceState *self) +{ + guint i, nb_tracefile; + + LttvTracefileState *tfcs; + + LttTime null_time = {0,0}; + + if(self->processes != NULL) lttv_state_free_process_table(self->processes); + self->processes = g_hash_table_new(process_hash, process_equal); + self->nb_event = 0; + + nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) + + ltt_trace_per_cpu_tracefile_number(self->parent.t); + + for(i = 0 ; i < nb_tracefile ; i++) { + tfcs = LTTV_TRACEFILE_STATE(self->parent.tracefiles[i]); + tfcs->parent.timestamp = null_time; + tfcs->saved_position = 0; + tfcs->process = lttv_state_create_process(tfcs, NULL,0); + tfcs->process->state->s = LTTV_STATE_RUN; + tfcs->process->last_cpu = tfcs->cpu_name; + } +} + +static LttTime time_zero = {0,0}; + +static void +init(LttvTracesetState *self, LttvTraceset *ts) +{ + guint i, j, nb_trace, nb_tracefile; + + LttvTraceContext *tc; + + LttvTraceState *tcs; + + LttvTracefileState *tfcs; + + LttvAttributeValue v; + + LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))-> + init((LttvTracesetContext *)self, ts); + + nb_trace = lttv_traceset_number(ts); + for(i = 0 ; i < nb_trace ; i++) { + tc = self->parent.traces[i]; + tcs = (LttvTraceState *)tc; + tcs->save_interval = 50000; + lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_TRACE_STATE_USE_COUNT, + LTTV_UINT, &v); + (*v.v_uint)++; + + if(*(v.v_uint) == 1) { + create_name_tables(tcs); + create_max_time(tcs); + } + get_name_tables(tcs); + get_max_time(tcs); + + nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + + ltt_trace_per_cpu_tracefile_number(tc->t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfcs = LTTV_TRACEFILE_STATE(tc->tracefiles[j]); + tfcs->cpu_name= g_quark_from_string(ltt_tracefile_name(tfcs->parent.tf)); + } + tcs->processes = NULL; + restore_init_state(tcs); + } +} + + +static void +fini(LttvTracesetState *self) +{ + guint i, j, nb_trace; + + LttvTraceState *tcs; + + LttvTracefileState *tfcs; + + LttvAttributeValue v; + + nb_trace = lttv_traceset_number(LTTV_TRACESET_CONTEXT(self)->ts); + for(i = 0 ; i < nb_trace ; i++) { + tcs = (LttvTraceState *)(LTTV_TRACESET_CONTEXT(self)->traces[i]); + lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_TRACE_STATE_USE_COUNT, + LTTV_UINT, &v); + (*v.v_uint)--; + + g_assert(*(v.v_uint) >= 0); + if(*(v.v_uint) == 0) { + free_name_tables(tcs); + free_max_time(tcs); + free_saved_state(tcs); + } + lttv_state_free_process_table(tcs->processes); + tcs->processes = NULL; + } + LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))-> + fini((LttvTracesetContext *)self); +} + + +static LttvTracesetContext * +new_traceset_context(LttvTracesetContext *self) +{ + return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATE_TYPE, NULL)); +} + + +static LttvTraceContext * +new_trace_context(LttvTracesetContext *self) +{ + return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATE_TYPE, NULL)); +} + + +static LttvTracefileContext * +new_tracefile_context(LttvTracesetContext *self) +{ + return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATE_TYPE, NULL)); +} + + +/* Write the process state of the trace */ + +static void write_process_state(gpointer key, gpointer value, + gpointer user_data) +{ + LttvProcessState *process; + + LttvExecutionState *es; + + FILE *fp = (FILE *)user_data; + + guint i; + + process = (LttvProcessState *)value; + fprintf(fp, +" \n", + process, process->pid, process->ppid, process->creation_time.tv_sec, + process->creation_time.tv_nsec, g_quark_to_string(process->name), + g_quark_to_string(process->last_cpu)); + + for(i = 0 ; i < process->execution_stack->len; i++) { + es = &g_array_index(process->execution_stack, LttvExecutionState, i); + fprintf(fp, " t), g_quark_to_string(es->n), + es->entry.tv_sec, es->entry.tv_nsec); + fprintf(fp, " CHANGE_S=%lu CHANGE_NS=%lu STATUS=\"%s\"/>\n", + es->change.tv_sec, es->change.tv_nsec, g_quark_to_string(es->s)); + } + fprintf(fp, " \n"); +} + + +void lttv_state_write(LttvTraceState *self, LttTime t, FILE *fp) +{ + guint i, nb_tracefile, nb_block, nb_event; + + LttvTracefileState *tfcs; + + LttTracefile *tf; + + LttEventPosition *ep; + + ep = ltt_event_position_new(); + + fprintf(fp,"\n", t.tv_sec, t.tv_nsec); + + g_hash_table_foreach(self->processes, write_process_state, fp); + + nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) + + ltt_trace_per_cpu_tracefile_number(self->parent.t); + + for(i = 0 ; i < nb_tracefile ; i++) { + tfcs = (LttvTracefileState *)self->parent.tracefiles[i]; + fprintf(fp, " process->pid, tfcs->parent.timestamp.tv_sec, + tfcs->parent.timestamp.tv_nsec); + if(tfcs->parent.e == NULL) fprintf(fp,"/>\n"); + else { + ltt_event_position(tfcs->parent.e, ep); + ltt_event_position_get(ep, &nb_block, &nb_event, &tf); + fprintf(fp, " BLOCK=%u EVENT=%u/>\n", nb_block, nb_event); + } + } + g_free(ep); + fprintf(fp,""); +} + + +/* Copy each process from an existing hash table to a new one */ + +static void copy_process_state(gpointer key, gpointer value,gpointer user_data) +{ + LttvProcessState *process, *new_process; + + GHashTable *new_processes = (GHashTable *)user_data; + + guint i; + + process = (LttvProcessState *)value; + new_process = g_new(LttvProcessState, 1); + *new_process = *process; + new_process->execution_stack = g_array_new(FALSE, FALSE, + sizeof(LttvExecutionState)); + g_array_set_size(new_process->execution_stack,process->execution_stack->len); + for(i = 0 ; i < process->execution_stack->len; i++) { + g_array_index(new_process->execution_stack, LttvExecutionState, i) = + g_array_index(process->execution_stack, LttvExecutionState, i); + } + new_process->state = &g_array_index(new_process->execution_stack, + LttvExecutionState, new_process->execution_stack->len - 1); + g_hash_table_insert(new_processes, new_process, new_process); +} + + +static GHashTable *lttv_state_copy_process_table(GHashTable *processes) +{ + GHashTable *new_processes = g_hash_table_new(process_hash, process_equal); + + g_hash_table_foreach(processes, copy_process_state, new_processes); + return new_processes; +} + + +/* The saved state for each trace contains a member "processes", which + stores a copy of the process table, and a member "tracefiles" with + one entry per tracefile. Each tracefile has a "process" member pointing + to the current process and a "position" member storing the tracefile + position (needed to seek to the current "next" event. */ + +static void state_save(LttvTraceState *self, LttvAttribute *container) +{ + guint i, nb_tracefile; + + LttvTracefileState *tfcs; + + LttvAttribute *tracefiles_tree, *tracefile_tree; + + LttvAttributeType type; + + LttvAttributeValue value; + + LttvAttributeName name; + + LttEventPosition *ep; + + tracefiles_tree = lttv_attribute_find_subdir(container, + LTTV_STATE_TRACEFILES); + + value = lttv_attribute_add(container, LTTV_STATE_PROCESSES, + LTTV_POINTER); + *(value.v_pointer) = lttv_state_copy_process_table(self->processes); + + nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) + + ltt_trace_per_cpu_tracefile_number(self->parent.t); + + for(i = 0 ; i < nb_tracefile ; i++) { + tfcs = (LttvTracefileState *)self->parent.tracefiles[i]; + tracefile_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); + value = lttv_attribute_add(tracefiles_tree, i, + LTTV_GOBJECT); + *(value.v_gobject) = (GObject *)tracefile_tree; + value = lttv_attribute_add(tracefile_tree, LTTV_STATE_PROCESS, + LTTV_UINT); + *(value.v_uint) = tfcs->process->pid; + value = lttv_attribute_add(tracefile_tree, LTTV_STATE_EVENT, + LTTV_POINTER); + if(tfcs->parent.e == NULL) *(value.v_pointer) = NULL; + else { + ep = ltt_event_position_new(); + ltt_event_position(tfcs->parent.e, ep); + *(value.v_pointer) = ep; + + guint nb_block, nb_event; + LttTracefile *tf; + ltt_event_position_get(ep, &nb_block, &nb_event, &tf); + g_debug("Block %u event %u time %lu.%lu", nb_block, nb_event, + tfcs->parent.timestamp.tv_sec, tfcs->parent.timestamp.tv_nsec); + } + } +} + + +static void state_restore(LttvTraceState *self, LttvAttribute *container) +{ + guint i, nb_tracefile, pid; + + LttvTracefileState *tfcs; + + LttvAttribute *tracefiles_tree, *tracefile_tree; + + LttvAttributeType type; + + LttvAttributeValue value; + + LttvAttributeName name; + + LttEventPosition *ep; + + tracefiles_tree = lttv_attribute_find_subdir(container, + LTTV_STATE_TRACEFILES); + + type = lttv_attribute_get_by_name(container, LTTV_STATE_PROCESSES, + &value); + g_assert(type == LTTV_POINTER); + lttv_state_free_process_table(self->processes); + self->processes = lttv_state_copy_process_table(*(value.v_pointer)); + + nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) + + ltt_trace_per_cpu_tracefile_number(self->parent.t); + + for(i = 0 ; i < nb_tracefile ; i++) { + tfcs = (LttvTracefileState *)self->parent.tracefiles[i]; + type = lttv_attribute_get(tracefiles_tree, i, &name, &value); + g_assert(type == LTTV_GOBJECT); + tracefile_tree = *((LttvAttribute **)(value.v_gobject)); + + type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_PROCESS, + &value); + g_assert(type == LTTV_UINT); + pid = *(value.v_uint); + tfcs->process = lttv_state_find_process_or_create(tfcs, pid); + + type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT, + &value); + g_assert(type == LTTV_POINTER); + if(*(value.v_pointer) == NULL) tfcs->parent.e = NULL; + else { + ep = *(value.v_pointer); + ltt_tracefile_seek_position(tfcs->parent.tf, ep); + tfcs->parent.e = ltt_tracefile_read(tfcs->parent.tf); + tfcs->parent.timestamp = ltt_event_time(tfcs->parent.e); + } + } +} + + +static void state_saved_free(LttvTraceState *self, LttvAttribute *container) +{ + guint i, nb_tracefile; + + LttvTracefileState *tfcs; + + LttvAttribute *tracefiles_tree, *tracefile_tree; + + LttvAttributeType type; + + LttvAttributeValue value; + + LttvAttributeName name; + + LttEventPosition *ep; + + tracefiles_tree = lttv_attribute_find_subdir(container, + LTTV_STATE_TRACEFILES); + lttv_attribute_remove_by_name(container, LTTV_STATE_TRACEFILES); + + type = lttv_attribute_get_by_name(container, LTTV_STATE_PROCESSES, + &value); + g_assert(type == LTTV_POINTER); + lttv_state_free_process_table(*(value.v_pointer)); + *(value.v_pointer) = NULL; + lttv_attribute_remove_by_name(container, LTTV_STATE_PROCESSES); + + nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) + + ltt_trace_per_cpu_tracefile_number(self->parent.t); + + for(i = 0 ; i < nb_tracefile ; i++) { + tfcs = (LttvTracefileState *)self->parent.tracefiles[i]; + type = lttv_attribute_get(tracefiles_tree, i, &name, &value); + g_assert(type == LTTV_GOBJECT); + tracefile_tree = *((LttvAttribute **)(value.v_gobject)); + + type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT, + &value); + g_assert(type == LTTV_POINTER); + if(*(value.v_pointer) != NULL) g_free(*(value.v_pointer)); + } + lttv_attribute_recursive_free(tracefiles_tree); +} + + +static void free_saved_state(LttvTraceState *self) +{ + guint i, nb; + + LttvAttributeType type; + + LttvAttributeValue value; + + LttvAttributeName name; + + LttvAttribute *saved_states; + + saved_states = lttv_attribute_find_subdir(self->parent.t_a, + LTTV_STATE_SAVED_STATES); + + nb = lttv_attribute_get_number(saved_states); + for(i = 0 ; i < nb ; i++) { + type = lttv_attribute_get(saved_states, i, &name, &value); + g_assert(type == LTTV_GOBJECT); + state_saved_free(self, *((LttvAttribute **)value.v_gobject)); + } + + lttv_attribute_remove_by_name(self->parent.t_a, LTTV_STATE_SAVED_STATES); + lttv_attribute_recursive_free(saved_states); +} + + +static void +create_max_time(LttvTraceState *tcs) +{ + LttvAttributeValue v; + + lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_SAVED_STATES_TIME, + LTTV_POINTER, &v); + g_assert(*(v.v_pointer) == NULL); + *(v.v_pointer) = g_new(LttTime,1); + *((LttTime *)*(v.v_pointer)) = time_zero; +} + + +static void +get_max_time(LttvTraceState *tcs) +{ + LttvAttributeValue v; + + lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_SAVED_STATES_TIME, + LTTV_POINTER, &v); + g_assert(*(v.v_pointer) != NULL); + tcs->max_time_state_recomputed_in_seek = (LttTime *)*(v.v_pointer); +} + + +static void +free_max_time(LttvTraceState *tcs) +{ + LttvAttributeValue v; + + lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_SAVED_STATES_TIME, + LTTV_POINTER, &v); + g_free(*(v.v_pointer)); + *(v.v_pointer) = NULL; +} + + +typedef struct _LttvNameTables { + GQuark *eventtype_names; + GQuark *syscall_names; + GQuark *trap_names; + GQuark *irq_names; +} LttvNameTables; + + +static void +create_name_tables(LttvTraceState *tcs) +{ + int i, nb; + + char *f_name, *e_name; + + LttvTraceHook h; + + LttEventType *et; + + LttType *t; + + GString *fe_name = g_string_new(""); + + LttvNameTables *name_tables = g_new(LttvNameTables, 1); + + LttvAttributeValue v; + + lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_NAME_TABLES, + LTTV_POINTER, &v); + g_assert(*(v.v_pointer) == NULL); + *(v.v_pointer) = name_tables; + + nb = ltt_trace_eventtype_number(tcs->parent.t); + name_tables->eventtype_names = g_new(GQuark, nb); + for(i = 0 ; i < nb ; i++) { + et = ltt_trace_eventtype_get(tcs->parent.t, i); + e_name = ltt_eventtype_name(et); + f_name = ltt_facility_name(ltt_eventtype_facility(et)); + g_string_printf(fe_name, "%s.%s", f_name, e_name); + name_tables->eventtype_names[i] = g_quark_from_string(fe_name->str); + } + + lttv_trace_find_hook(tcs->parent.t, "core", "syscall_entry", + "syscall_id", NULL, NULL, NULL, &h); + t = ltt_field_type(h.f1); + nb = ltt_type_element_number(t); + + /* CHECK syscalls should be an emun but currently are not! + name_tables->syscall_names = g_new(GQuark, nb); + + for(i = 0 ; i < nb ; i++) { + name_tables->syscall_names[i] = g_quark_from_string( + ltt_enum_string_get(t, i)); + } + */ + + name_tables->syscall_names = g_new(GQuark, 256); + for(i = 0 ; i < 256 ; i++) { + g_string_printf(fe_name, "syscall %d", i); + name_tables->syscall_names[i] = g_quark_from_string(fe_name->str); + } + + lttv_trace_find_hook(tcs->parent.t, "core", "trap_entry", + "trap_id", NULL, NULL, NULL, &h); + t = ltt_field_type(h.f1); + nb = ltt_type_element_number(t); + + /* + name_tables->trap_names = g_new(GQuark, nb); + for(i = 0 ; i < nb ; i++) { + name_tables->trap_names[i] = g_quark_from_string( + ltt_enum_string_get(t, i)); + } + */ + + name_tables->trap_names = g_new(GQuark, 256); + for(i = 0 ; i < 256 ; i++) { + g_string_printf(fe_name, "trap %d", i); + name_tables->trap_names[i] = g_quark_from_string(fe_name->str); + } + + lttv_trace_find_hook(tcs->parent.t, "core", "irq_entry", + "irq_id", NULL, NULL, NULL, &h); + t = ltt_field_type(h.f1); + nb = ltt_type_element_number(t); + + /* + name_tables->irq_names = g_new(GQuark, nb); + for(i = 0 ; i < nb ; i++) { + name_tables->irq_names[i] = g_quark_from_string(ltt_enum_string_get(t, i)); + } + */ + + name_tables->irq_names = g_new(GQuark, 256); + for(i = 0 ; i < 256 ; i++) { + g_string_printf(fe_name, "irq %d", i); + name_tables->irq_names[i] = g_quark_from_string(fe_name->str); + } + + g_string_free(fe_name, TRUE); +} + + +static void +get_name_tables(LttvTraceState *tcs) +{ + LttvNameTables *name_tables; + + LttvAttributeValue v; + + lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_NAME_TABLES, + LTTV_POINTER, &v); + g_assert(*(v.v_pointer) != NULL); + name_tables = (LttvNameTables *)*(v.v_pointer); + tcs->eventtype_names = name_tables->eventtype_names; + tcs->syscall_names = name_tables->syscall_names; + tcs->trap_names = name_tables->trap_names; + tcs->irq_names = name_tables->irq_names; +} + + +static void +free_name_tables(LttvTraceState *tcs) +{ + LttvNameTables *name_tables; + + LttvAttributeValue v; + + lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_NAME_TABLES, + LTTV_POINTER, &v); + name_tables = (LttvNameTables *)*(v.v_pointer); + *(v.v_pointer) = NULL; + + g_free(name_tables->eventtype_names); + g_free(name_tables->syscall_names); + g_free(name_tables->trap_names); + g_free(name_tables->irq_names); + g_free(name_tables); +} + + +static void push_state(LttvTracefileState *tfs, LttvExecutionMode t, + guint state_id) +{ + LttvExecutionState *es; + + LttvProcessState *process = tfs->process; + + guint depth = process->execution_stack->len; + + g_array_set_size(process->execution_stack, depth + 1); + es = &g_array_index(process->execution_stack, LttvExecutionState, depth); + es->t = t; + es->n = state_id; + es->entry = es->change = tfs->parent.timestamp; + es->s = process->state->s; + process->state = es; +} + + +static void pop_state(LttvTracefileState *tfs, LttvExecutionMode t) +{ + LttvProcessState *process = tfs->process; + + guint depth = process->execution_stack->len; + + if(process->state->t != t){ + g_info("Different execution mode type (%d.%09d): ignore it\n", + tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec); + g_info("process state has %s when pop_int is %s\n", + g_quark_to_string(process->state->t), + g_quark_to_string(t)); + g_info("{ %u, %u, %s, %s }\n", + process->pid, + process->ppid, + g_quark_to_string(process->name), + g_quark_to_string(process->state->s)); + return; + } + + if(depth == 1){ + g_info("Trying to pop last state on stack (%d.%09d): ignore it\n", + tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec); + return; + } + + g_array_set_size(process->execution_stack, depth - 1); + process->state = &g_array_index(process->execution_stack, LttvExecutionState, + depth - 2); + process->state->change = tfs->parent.timestamp; +} + + +LttvProcessState * +lttv_state_create_process(LttvTracefileState *tfs, LttvProcessState *parent, + guint pid) +{ + LttvProcessState *process = g_new(LttvProcessState, 1); + + LttvExecutionState *es; + + LttvTraceContext *tc; + + LttvTraceState *tcs; + + char buffer[128]; + + tcs = ((LttvTraceState *)tc = tfs->parent.t_context); + + process->pid = pid; + process->last_cpu = tfs->cpu_name; + g_warning("Process %u, core %p", process->pid, process); + g_hash_table_insert(tcs->processes, process, process); + + if(parent) { + process->ppid = parent->pid; + process->name = parent->name; + process->creation_time = tfs->parent.timestamp; + } + + /* No parent. This process exists but we are missing all information about + its creation. The birth time is set to zero but we remember the time of + insertion */ + + else { + process->ppid = 0; + process->name = LTTV_STATE_UNNAMED; + process->creation_time = ltt_time_zero; + } + + process->insertion_time = tfs->parent.timestamp; + sprintf(buffer,"%d-%lu.%lu",pid, process->creation_time.tv_sec, + process->creation_time.tv_nsec); + process->pid_time = g_quark_from_string(buffer); + process->last_cpu = tfs->cpu_name; + process->execution_stack = g_array_new(FALSE, FALSE, + sizeof(LttvExecutionState)); + g_array_set_size(process->execution_stack, 1); + es = process->state = &g_array_index(process->execution_stack, + LttvExecutionState, 0); + es->t = LTTV_STATE_USER_MODE; + es->n = LTTV_STATE_SUBMODE_NONE; + es->entry = tfs->parent.timestamp; + es->change = tfs->parent.timestamp; + es->s = LTTV_STATE_WAIT_FORK; + + return process; +} + + +LttvProcessState * +lttv_state_find_process_from_trace(LttvTraceState *ts, GQuark cpu, guint pid) +{ + LttvProcessState key; + LttvProcessState *process; + + key.pid = pid; + key.last_cpu = cpu; + process = g_hash_table_lookup(ts->processes, &key); + return process; +} + + +LttvProcessState *lttv_state_find_process(LttvTracefileState *tfs, + guint pid) +{ + LttvTraceState *ts =(LttvTraceState *)tfs->parent.t_context; + return lttv_state_find_process_from_trace(ts, tfs->cpu_name, pid); +} + + +LttvProcessState * +lttv_state_find_process_or_create(LttvTracefileState *tfs, guint pid) +{ + LttvProcessState *process = lttv_state_find_process(tfs, pid); + + if(process == NULL) process = lttv_state_create_process(tfs, NULL, pid); + return process; +} + + +static void exit_process(LttvTracefileState *tfs, LttvProcessState *process) +{ + LttvTraceState *ts = LTTV_TRACE_STATE(tfs->parent.t_context); + LttvProcessState key; + + key.pid = process->pid; + key.last_cpu = process->last_cpu; + g_hash_table_remove(ts->processes, &key); + g_array_free(process->execution_stack, TRUE); + g_free(process); +} + + +static void free_process_state(gpointer key, gpointer value,gpointer user_data) +{ + g_array_free(((LttvProcessState *)value)->execution_stack, TRUE); + g_free(value); +} + + +static void lttv_state_free_process_table(GHashTable *processes) +{ + g_hash_table_foreach(processes, free_process_state, NULL); + g_hash_table_destroy(processes); +} + + +static gboolean syscall_entry(void *hook_data, void *call_data) +{ + LttField *f = ((LttvTraceHook *)hook_data)->f1; + + LttvTracefileState *s = (LttvTracefileState *)call_data; + + LttvExecutionSubmode submode; + + submode = ((LttvTraceState *)(s->parent.t_context))->syscall_names[ + ltt_event_get_unsigned(s->parent.e, f)]; + push_state(s, LTTV_STATE_SYSCALL, submode); + return FALSE; +} + + +static gboolean syscall_exit(void *hook_data, void *call_data) +{ + LttvTracefileState *s = (LttvTracefileState *)call_data; + + pop_state(s, LTTV_STATE_SYSCALL); + return FALSE; +} + + +static gboolean trap_entry(void *hook_data, void *call_data) +{ + LttField *f = ((LttvTraceHook *)hook_data)->f1; + + LttvTracefileState *s = (LttvTracefileState *)call_data; + + LttvExecutionSubmode submode; + + submode = ((LttvTraceState *)(s->parent.t_context))->trap_names[ + ltt_event_get_unsigned(s->parent.e, f)]; + push_state(s, LTTV_STATE_TRAP, submode); + return FALSE; +} + + +static gboolean trap_exit(void *hook_data, void *call_data) +{ + LttvTracefileState *s = (LttvTracefileState *)call_data; + + pop_state(s, LTTV_STATE_TRAP); + return FALSE; +} + + +static gboolean irq_entry(void *hook_data, void *call_data) +{ + LttField *f = ((LttvTraceHook *)hook_data)->f1; + + LttvTracefileState *s = (LttvTracefileState *)call_data; + + LttvExecutionSubmode submode; + + submode = ((LttvTraceState *)(s->parent.t_context))->irq_names[ + ltt_event_get_unsigned(s->parent.e, f)]; + + /* Do something with the info about being in user or system mode when int? */ + push_state(s, LTTV_STATE_IRQ, submode); + return FALSE; +} + + +static gboolean irq_exit(void *hook_data, void *call_data) +{ + LttvTracefileState *s = (LttvTracefileState *)call_data; + + pop_state(s, LTTV_STATE_IRQ); + return FALSE; +} + + +static gboolean schedchange(void *hook_data, void *call_data) +{ + LttvTraceHook *h = (LttvTraceHook *)hook_data; + + LttvTracefileState *s = (LttvTracefileState *)call_data; + + guint pid_in, pid_out, state_out; + + pid_in = ltt_event_get_unsigned(s->parent.e, h->f1); + pid_out = ltt_event_get_unsigned(s->parent.e, h->f2); + state_out = ltt_event_get_unsigned(s->parent.e, h->f3); + + if(s->process != NULL) { + + /* We could not know but it was not the idle process executing. + This should only happen at the beginning, before the first schedule + event, and when the initial information (current process for each CPU) + is missing. It is not obvious how we could, after the fact, compensate + the wrongly attributed statistics. */ + + if(s->process->pid != pid_out) { + g_assert(s->process->pid == 0); + } + + if(state_out == 0) s->process->state->s = LTTV_STATE_WAIT_CPU; + else if(s->process->state->s == LTTV_STATE_EXIT) + exit_process(s, s->process); + else s->process->state->s = LTTV_STATE_WAIT; + + s->process->state->change = s->parent.timestamp; + } + s->process = lttv_state_find_process_or_create(s, pid_in); + s->process->state->s = LTTV_STATE_RUN; + s->process->last_cpu = s->cpu_name; + s->process->state->change = s->parent.timestamp; + return FALSE; +} + + +static gboolean process_fork(void *hook_data, void *call_data) +{ + LttField *f = ((LttvTraceHook *)hook_data)->f1; + + LttvTracefileState *s = (LttvTracefileState *)call_data; + + guint child_pid; + + child_pid = ltt_event_get_unsigned(s->parent.e, f); + lttv_state_create_process(s, s->process, child_pid); + return FALSE; +} + + +static gboolean process_exit(void *hook_data, void *call_data) +{ + LttvTracefileState *s = (LttvTracefileState *)call_data; + + if(s->process != NULL) { + s->process->state->s = LTTV_STATE_EXIT; + } + return FALSE; +} + + +void lttv_state_add_event_hooks(LttvTracesetState *self) +{ + LttvTraceset *traceset = self->parent.ts; + + guint i, j, k, nb_trace, nb_tracefile; + + LttvTraceState *ts; + + LttvTracefileState *tfs; + + GArray *hooks; + + LttvTraceHook hook; + + LttvAttributeValue val; + + nb_trace = lttv_traceset_number(traceset); + for(i = 0 ; i < nb_trace ; i++) { + ts = (LttvTraceState *)self->parent.traces[i]; + + /* Find the eventtype id for the following events and register the + associated by id hooks. */ + + hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook)); + g_array_set_size(hooks, 9); + + lttv_trace_find_hook(ts->parent.t, "core","syscall_entry","syscall_id", + NULL, NULL, syscall_entry, &g_array_index(hooks, LttvTraceHook, 0)); + + lttv_trace_find_hook(ts->parent.t, "core", "syscall_exit", NULL, NULL, + NULL, syscall_exit, &g_array_index(hooks, LttvTraceHook, 1)); + + lttv_trace_find_hook(ts->parent.t, "core", "trap_entry", "trap_id", + NULL, NULL, trap_entry, &g_array_index(hooks, LttvTraceHook, 2)); + + lttv_trace_find_hook(ts->parent.t, "core", "trap_exit", NULL, NULL, NULL, + trap_exit, &g_array_index(hooks, LttvTraceHook, 3)); + + lttv_trace_find_hook(ts->parent.t, "core", "irq_entry", "irq_id", NULL, + NULL, irq_entry, &g_array_index(hooks, LttvTraceHook, 4)); + + lttv_trace_find_hook(ts->parent.t, "core", "irq_exit", NULL, NULL, NULL, + irq_exit, &g_array_index(hooks, LttvTraceHook, 5)); + + lttv_trace_find_hook(ts->parent.t, "core", "schedchange", "in", "out", + "out_state", schedchange, &g_array_index(hooks, LttvTraceHook, 6)); + + lttv_trace_find_hook(ts->parent.t, "core", "process_fork", "child_pid", + NULL, NULL, process_fork, &g_array_index(hooks, LttvTraceHook, 7)); + + lttv_trace_find_hook(ts->parent.t, "core", "process_exit", NULL, NULL, + NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 8)); + + /* Add these hooks to each before_event_by_id hooks list */ + + nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.t) + + ltt_trace_per_cpu_tracefile_number(ts->parent.t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfs = LTTV_TRACEFILE_STATE(ts->parent.tracefiles[j]); + + for(k = 0 ; k < hooks->len ; k++) { + hook = g_array_index(hooks, LttvTraceHook, k); + lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id, + hook.id), hook.h, &g_array_index(hooks, LttvTraceHook, k)); + } + } + lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val); + *(val.v_pointer) = hooks; + } +} + + +void lttv_state_remove_event_hooks(LttvTracesetState *self) +{ + LttvTraceset *traceset = self->parent.ts; + + guint i, j, k, nb_trace, nb_tracefile; + + LttvTraceState *ts; + + LttvTracefileState *tfs; + + GArray *hooks; + + LttvTraceHook hook; + + LttvAttributeValue val; + + nb_trace = lttv_traceset_number(traceset); + for(i = 0 ; i < nb_trace ; i++) { + ts = LTTV_TRACE_STATE(self->parent.traces[i]); + lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val); + hooks = *(val.v_pointer); + + /* Add these hooks to each before_event_by_id hooks list */ + + nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.t) + + ltt_trace_per_cpu_tracefile_number(ts->parent.t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfs = LTTV_TRACEFILE_STATE(ts->parent.tracefiles[j]); + + for(k = 0 ; k < hooks->len ; k++) { + hook = g_array_index(hooks, LttvTraceHook, k); + lttv_hooks_remove_data( + lttv_hooks_by_id_find(tfs->parent.after_event_by_id, + hook.id), hook.h, &g_array_index(hooks, LttvTraceHook, k)); + } + } + g_array_free(hooks, TRUE); + } +} + + +static gboolean block_start(void *hook_data, void *call_data) +{ + LttvTracefileState *self = (LttvTracefileState *)call_data; + + LttvTracefileState *tfcs; + + LttvTraceState *tcs = (LttvTraceState *)(self->parent.t_context); + + LttEventPosition *ep; + + guint i, nb_block, nb_event, nb_tracefile; + + LttTracefile *tf; + + LttvAttribute *saved_states_tree, *saved_state_tree; + + LttvAttributeValue value; + + ep = ltt_event_position_new(); + nb_tracefile = ltt_trace_control_tracefile_number(tcs->parent.t) + + ltt_trace_per_cpu_tracefile_number(tcs->parent.t); + + /* Count the number of events added since the last block end in any + tracefile. */ + + for(i = 0 ; i < nb_tracefile ; i++) { + tfcs = (LttvTracefileState *)tcs->parent.tracefiles[i]; + ltt_event_position(tfcs->parent.e, ep); + ltt_event_position_get(ep, &nb_block, &nb_event, &tf); + tcs->nb_event += nb_event - tfcs->saved_position; + tfcs->saved_position = nb_event; + } + g_free(ep); + + if(tcs->nb_event >= tcs->save_interval) { + saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a, + LTTV_STATE_SAVED_STATES); + saved_state_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); + value = lttv_attribute_add(saved_states_tree, + lttv_attribute_get_number(saved_states_tree), LTTV_GOBJECT); + *(value.v_gobject) = (GObject *)saved_state_tree; + value = lttv_attribute_add(saved_state_tree, LTTV_STATE_TIME, LTTV_TIME); + *(value.v_time) = self->parent.timestamp; + lttv_state_save(tcs, saved_state_tree); + tcs->nb_event = 0; + g_debug("Saving state at time %lu.%lu", self->parent.timestamp.tv_sec, + self->parent.timestamp.tv_nsec); + } + *(tcs->max_time_state_recomputed_in_seek) = self->parent.timestamp; + return FALSE; +} + + +static gboolean block_end(void *hook_data, void *call_data) +{ + LttvTracefileState *self = (LttvTracefileState *)call_data; + + LttvTraceState *tcs = (LttvTraceState *)(self->parent.t_context); + + LttTracefile *tf; + + LttEventPosition *ep; + + guint nb_block, nb_event; + + ep = ltt_event_position_new(); + ltt_event_position(self->parent.e, ep); + ltt_event_position_get(ep, &nb_block, &nb_event, &tf); + tcs->nb_event += nb_event - self->saved_position + 1; + self->saved_position = 0; + *(tcs->max_time_state_recomputed_in_seek) = self->parent.timestamp; + g_free(ep); +} + + +void lttv_state_save_add_event_hooks(LttvTracesetState *self) +{ + LttvTraceset *traceset = self->parent.ts; + + guint i, j, k, nb_trace, nb_tracefile; + + LttvTraceState *ts; + + LttvTracefileState *tfs; + + LttvTraceHook hook_start, hook_end; + + nb_trace = lttv_traceset_number(traceset); + for(i = 0 ; i < nb_trace ; i++) { + ts = (LttvTraceState *)self->parent.traces[i]; + lttv_trace_find_hook(ts->parent.t, "core","block_start",NULL, + NULL, NULL, block_start, &hook_start); + lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL, + NULL, NULL, block_end, &hook_end); + + nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.t) + + ltt_trace_per_cpu_tracefile_number(ts->parent.t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfs = LTTV_TRACEFILE_STATE(ts->parent.tracefiles[j]); + lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id, + hook_start.id), hook_start.h, NULL); + lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id, + hook_end.id), hook_end.h, NULL); + } + } +} + + +void lttv_state_save_remove_event_hooks(LttvTracesetState *self) +{ + LttvTraceset *traceset = self->parent.ts; + + guint i, j, k, nb_trace, nb_tracefile; + + LttvTraceState *ts; + + LttvTracefileState *tfs; + + LttvTraceHook hook_start, hook_end; + + nb_trace = lttv_traceset_number(traceset); + for(i = 0 ; i < nb_trace ; i++) { + ts = LTTV_TRACE_STATE(self->parent.traces[i]); + lttv_trace_find_hook(ts->parent.t, "core","block_start",NULL, + NULL, NULL, block_start, &hook_start); + + lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL, + NULL, NULL, block_end, &hook_end); + + nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.t) + + ltt_trace_per_cpu_tracefile_number(ts->parent.t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfs = LTTV_TRACEFILE_STATE(ts->parent.tracefiles[j]); + lttv_hooks_remove_data(lttv_hooks_by_id_find( + tfs->parent.after_event_by_id, hook_start.id), hook_start.h, NULL); + lttv_hooks_remove_data(lttv_hooks_by_id_find( + tfs->parent.after_event_by_id, hook_end.id), hook_end.h, NULL); + } + } +} + + +void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t) +{ + LttvTraceset *traceset = self->parent.ts; + + guint i, j, nb_trace, nb_saved_state; + + int min_pos, mid_pos, max_pos; + + LttvTraceState *tcs; + + LttvAttributeValue value; + + LttvAttributeType type; + + LttvAttributeName name; + + LttvAttribute *saved_states_tree, *saved_state_tree, *closest_tree; + + nb_trace = lttv_traceset_number(traceset); + for(i = 0 ; i < nb_trace ; i++) { + tcs = (LttvTraceState *)self->parent.traces[i]; + + if(ltt_time_compare(t, *(tcs->max_time_state_recomputed_in_seek)) < 0) { + saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a, + LTTV_STATE_SAVED_STATES); + min_pos = -1; + + if(saved_states_tree) { + max_pos = lttv_attribute_get_number(saved_states_tree) - 1; + mid_pos = max_pos / 2; + while(min_pos < max_pos) { + type = lttv_attribute_get(saved_states_tree, mid_pos, &name, &value); + g_assert(type == LTTV_GOBJECT); + saved_state_tree = *((LttvAttribute **)(value.v_gobject)); + type = lttv_attribute_get_by_name(saved_state_tree, LTTV_STATE_TIME, + &value); + g_assert(type == LTTV_TIME); + if(ltt_time_compare(*(value.v_time), t) < 0) { + min_pos = mid_pos; + closest_tree = saved_state_tree; + } + else max_pos = mid_pos - 1; + + mid_pos = (min_pos + max_pos + 1) / 2; + } + } + + /* restore the closest earlier saved state */ + if(min_pos != -1) { + lttv_state_restore(tcs, closest_tree); + } + + /* There is no saved state, yet we want to have it. Restart at T0 */ + else { + restore_init_state(tcs); + lttv_process_trace_seek_time(&(tcs->parent), ltt_time_zero); + } + } + /* We want to seek quickly without restoring/updating the state */ + else { + restore_init_state(tcs); + lttv_process_trace_seek_time(&(tcs->parent), t); + } + } +} + + +static void +traceset_state_instance_init (GTypeInstance *instance, gpointer g_class) +{ +} + + +static void +traceset_state_finalize (LttvTracesetState *self) +{ + G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))-> + finalize(G_OBJECT(self)); +} + + +static void +traceset_state_class_init (LttvTracesetContextClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = (void (*)(GObject *self)) traceset_state_finalize; + klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init; + klass->fini = (void (*)(LttvTracesetContext *self))fini; + klass->new_traceset_context = new_traceset_context; + klass->new_trace_context = new_trace_context; + klass->new_tracefile_context = new_tracefile_context; +} + + +GType +lttv_traceset_state_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof (LttvTracesetStateClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) traceset_state_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (LttvTracesetState), + 0, /* n_preallocs */ + (GInstanceInitFunc) traceset_state_instance_init /* instance_init */ + }; + + type = g_type_register_static (LTTV_TRACESET_CONTEXT_TYPE, "LttvTracesetStateType", + &info, 0); + } + return type; +} + + +static void +trace_state_instance_init (GTypeInstance *instance, gpointer g_class) +{ +} + + +static void +trace_state_finalize (LttvTraceState *self) +{ + G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_CONTEXT_TYPE))-> + finalize(G_OBJECT(self)); +} + + +static void +trace_state_class_init (LttvTraceStateClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = (void (*)(GObject *self)) trace_state_finalize; + klass->state_save = state_save; + klass->state_restore = state_restore; + klass->state_saved_free = state_saved_free; +} + + +GType +lttv_trace_state_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof (LttvTraceStateClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) trace_state_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (LttvTraceState), + 0, /* n_preallocs */ + (GInstanceInitFunc) trace_state_instance_init /* instance_init */ + }; + + type = g_type_register_static (LTTV_TRACE_CONTEXT_TYPE, + "LttvTraceStateType", &info, 0); + } + return type; +} + + +static void +tracefile_state_instance_init (GTypeInstance *instance, gpointer g_class) +{ +} + + +static void +tracefile_state_finalize (LttvTracefileState *self) +{ + G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_CONTEXT_TYPE))-> + finalize(G_OBJECT(self)); +} + + +static void +tracefile_state_class_init (LttvTracefileStateClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = (void (*)(GObject *self)) tracefile_state_finalize; +} + + +GType +lttv_tracefile_state_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof (LttvTracefileStateClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) tracefile_state_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (LttvTracefileState), + 0, /* n_preallocs */ + (GInstanceInitFunc) tracefile_state_instance_init /* instance_init */ + }; + + type = g_type_register_static (LTTV_TRACEFILE_CONTEXT_TYPE, + "LttvTracefileStateType", &info, 0); + } + return type; +} + + +static void module_init() +{ + LTTV_STATE_UNNAMED = g_quark_from_string("unnamed"); + LTTV_STATE_MODE_UNKNOWN = g_quark_from_string("unknown execution mode"); + LTTV_STATE_USER_MODE = g_quark_from_string("user mode"); + LTTV_STATE_WAIT_FORK = g_quark_from_string("wait fork"); + LTTV_STATE_SYSCALL = g_quark_from_string("system call"); + LTTV_STATE_TRAP = g_quark_from_string("trap"); + LTTV_STATE_IRQ = g_quark_from_string("irq"); + LTTV_STATE_SUBMODE_UNKNOWN = g_quark_from_string("unknown submode"); + LTTV_STATE_SUBMODE_NONE = g_quark_from_string("(no submode)"); + LTTV_STATE_WAIT_CPU = g_quark_from_string("wait for cpu"); + LTTV_STATE_EXIT = g_quark_from_string("exiting"); + LTTV_STATE_WAIT = g_quark_from_string("wait for I/O"); + LTTV_STATE_RUN = g_quark_from_string("running"); + LTTV_STATE_TRACEFILES = g_quark_from_string("tracefiles"); + LTTV_STATE_PROCESSES = g_quark_from_string("processes"); + LTTV_STATE_PROCESS = g_quark_from_string("process"); + LTTV_STATE_EVENT = g_quark_from_string("event"); + LTTV_STATE_SAVED_STATES = g_quark_from_string("saved states"); + LTTV_STATE_SAVED_STATES_TIME = g_quark_from_string("saved states time"); + LTTV_STATE_TIME = g_quark_from_string("time"); + LTTV_STATE_HOOKS = g_quark_from_string("saved state hooks"); + LTTV_STATE_NAME_TABLES = g_quark_from_string("name tables"); + LTTV_STATE_TRACE_STATE_USE_COUNT = + g_quark_from_string("trace_state_use_count"); +} + +static void module_destroy() +{ +} + + +LTTV_MODULE("state", "State computation", \ + "Update the system state, possibly saving it at intervals", \ + module_init, module_destroy) + + + diff --git a/ltt/branches/poly/lttv/lttv/state.h b/ltt/branches/poly/lttv/lttv/state.h new file mode 100644 index 00000000..7529dc65 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/state.h @@ -0,0 +1,243 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef STATE_H +#define STATE_H + +#include +#include +#include + +/* The operating system state, kept during the trace analysis, + contains a subset of the real operating system state, + sufficient for the analysis, and possibly organized quite differently. + + The state information is added to LttvTracesetContext, LttvTraceContext + and LttvTracefileContext objects, used by processTrace, through + subtyping. The context objects already reflect the multiple tracefiles + (one per cpu) per trace and multiple traces per trace set. The state + objects defined here simply add fields to the relevant context objects. + + There is no traceset specific state yet. It may eventually contains such + things as clock differences over time. + + The trace state currently consists in a process table. + + The tracefile level state relates to the associated cpu. It contains the + position of the current event in the tracefile (since the state depends on + which events have been processed) and a pointer to the current process, + in the process table, being run on that cpu. + + For each process in the process table, various informations such as exec + file name, pid, ppid and creation time are stored. Each process state also + contains an execution mode stack (e.g. irq within system call, called + from user mode). */ + +typedef struct _LttvTracesetState LttvTracesetState; +typedef struct _LttvTracesetStateClass LttvTracesetStateClass; + +typedef struct _LttvTraceState LttvTraceState; +typedef struct _LttvTraceStateClass LttvTraceStateClass; + +typedef struct _LttvTracefileState LttvTracefileState; +typedef struct _LttvTracefileStateClass LttvTracefileStateClass; + +void lttv_state_add_event_hooks(LttvTracesetState *self); + +void lttv_state_remove_event_hooks(LttvTracesetState *self); + +void lttv_state_save_add_event_hooks(LttvTracesetState *self); + +void lttv_state_save_remove_event_hooks(LttvTracesetState *self); + +void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t); + +/* The LttvProcessState structure defines the current state for each process. + A process can make system calls (in some rare cases nested) and receive + interrupts/faults. For instance, a process may issue a system call, + generate a page fault while reading an argument from user space, and + get caught by an interrupt. To represent these nested states, an + execution mode stack is maintained. The stack bottom is normal user mode + and the top of stack is the current execution mode. + + The execution mode stack tells about the process status, execution mode and + submode (interrupt, system call or IRQ number). All these could be + defined as enumerations but may need extensions (e.g. new process state). + GQuark are thus used. They are as easy to manipulate as integers but have + a string associated, just like enumerations. + + The execution mode is one of "user mode", "kernel thread", "system call", + "interrupt request", "fault". */ + +typedef GQuark LttvExecutionMode; + +extern LttvExecutionMode + LTTV_STATE_USER_MODE, + LTTV_STATE_SYSCALL, + LTTV_STATE_TRAP, + LTTV_STATE_IRQ, + LTTV_STATE_MODE_UNKNOWN; + + +/* The submode number depends on the execution mode. For user mode or kernel + thread, which are the normal mode (execution mode stack bottom), + it is set to "none". For interrupt requests, faults and system calls, + it is set respectively to the interrupt name (e.g. "timer"), fault name + (e.g. "page fault"), and system call name (e.g. "select"). */ + +typedef GQuark LttvExecutionSubmode; + +extern LttvExecutionSubmode + LTTV_STATE_SUBMODE_NONE, + LTTV_STATE_SUBMODE_UNKNOWN; + +/* The process status is one of "running", "wait-cpu" (runnable), or "wait-*" + where "*" describes the resource waited for (e.g. timer, process, + disk...). */ + +typedef GQuark LttvProcessStatus; + +extern LttvProcessStatus + LTTV_STATE_UNNAMED, + LTTV_STATE_WAIT_FORK, + LTTV_STATE_WAIT_CPU, + LTTV_STATE_EXIT, + LTTV_STATE_WAIT, + LTTV_STATE_RUN; + + +typedef struct _LttvExecutionState { + LttvExecutionMode t; + LttvExecutionSubmode n; + LttTime entry; + LttTime change; + LttvProcessStatus s; +} LttvExecutionState; + + +typedef struct _LttvProcessState { + guint pid; + guint ppid; + LttTime creation_time; + LttTime insertion_time; + GQuark name; + GQuark pid_time; + GArray *execution_stack; /* Array of LttvExecutionState */ + LttvExecutionState *state; /* Top of interrupt stack */ + GQuark last_cpu; /* Last CPU where process was scheduled */ + /* opened file descriptors, address map?... */ +} LttvProcessState; + + +LttvProcessState * +lttv_state_find_process(LttvTracefileState *tfs, guint pid); + +LttvProcessState * +lttv_state_find_process_from_trace(LttvTraceState *ts, GQuark cpu, guint pid); + +LttvProcessState * +lttv_state_find_process_or_create(LttvTracefileState *tfs, guint pid); + +LttvProcessState * +lttv_state_create_process(LttvTracefileState *tfs, LttvProcessState *parent, + guint pid); + +void lttv_state_write(LttvTraceState *self, LttTime t, FILE *fp); + +/* The LttvTracesetState, LttvTraceState and LttvTracefileState types + inherit from the corresponding Context objects defined in processTrace. */ + +#define LTTV_TRACESET_STATE_TYPE (lttv_traceset_state_get_type ()) +#define LTTV_TRACESET_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACESET_STATE_TYPE, LttvTracesetState)) +#define LTTV_TRACESET_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACESET_STATE_TYPE, LttvTracesetStateClass)) +#define LTTV_IS_TRACESET_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACESET_STATE_TYPE)) +#define LTTV_IS_TRACESET_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACESET_STATE_TYPE)) +#define LTTV_TRACESET_STATE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACESET_STATE_TYPE, LttvTracesetStateClass)) + +struct _LttvTracesetState { + LttvTracesetContext parent; +}; + +struct _LttvTracesetStateClass { + LttvTracesetContextClass parent; +}; + +GType lttv_traceset_state_get_type (void); + + +#define LTTV_TRACE_STATE_TYPE (lttv_trace_state_get_type ()) +#define LTTV_TRACE_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACE_STATE_TYPE, LttvTraceState)) +#define LTTV_TRACE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACE_STATE_TYPE, LttvTraceStateClass)) +#define LTTV_IS_TRACE_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACE_STATE_TYPE)) +#define LTTV_IS_TRACE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACE_STATE_TYPE)) +#define LTTV_TRACE_STATE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACE_STATE_TYPE, LttvTraceStateClass)) + +struct _LttvTraceState { + LttvTraceContext parent; + + GHashTable *processes; /* LttvProcessState objects indexed by pid */ + guint nb_event, save_interval; + /* Block/char devices, locks, memory pages... */ + GQuark *eventtype_names; + GQuark *syscall_names; + GQuark *trap_names; + GQuark *irq_names; + LttTime *max_time_state_recomputed_in_seek; +}; + +struct _LttvTraceStateClass { + LttvTraceContextClass parent; + + void (*state_save) (LttvTraceState *self, LttvAttribute *container); + void (*state_restore) (LttvTraceState *self, LttvAttribute *container); + void (*state_saved_free) (LttvTraceState *self, LttvAttribute *container); +}; + +GType lttv_trace_state_get_type (void); + +void lttv_state_save(LttvTraceState *self, LttvAttribute *container); + +void lttv_state_restore(LttvTraceState *self, LttvAttribute *container); + +void lttv_state_state_saved_free(LttvTraceState *self, + LttvAttribute *container); + + +#define LTTV_TRACEFILE_STATE_TYPE (lttv_tracefile_state_get_type ()) +#define LTTV_TRACEFILE_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACEFILE_STATE_TYPE, LttvTracefileState)) +#define LTTV_TRACEFILE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACEFILE_STATE_TYPE, LttvTracefileStateClass)) +#define LTTV_IS_TRACEFILE_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACEFILE_STATE_TYPE)) +#define LTTV_IS_TRACEFILE_STATE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACEFILE_STATE_TYPE)) +#define LTTV_TRACEFILE_STATE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACEFILE_STATE_TYPE, LttvTracefileStateClass)) + +struct _LttvTracefileState { + LttvTracefileContext parent; + + LttvProcessState *process; + GQuark cpu_name; + guint saved_position; +}; + +struct _LttvTracefileStateClass { + LttvTracefileContextClass parent; +}; + +GType lttv_tracefile_state_get_type (void); + + +#endif // STATE_H diff --git a/ltt/branches/poly/lttv/lttv/stats.c b/ltt/branches/poly/lttv/lttv/stats.c new file mode 100644 index 00000000..d5cd80b4 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/stats.c @@ -0,0 +1,916 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 256 + +GQuark + LTTV_STATS_PROCESS_UNKNOWN, + LTTV_STATS_PROCESSES, + LTTV_STATS_CPU, + LTTV_STATS_MODE_TYPES, + LTTV_STATS_MODES, + LTTV_STATS_SUBMODES, + LTTV_STATS_EVENT_TYPES, + LTTV_STATS_CPU_TIME, + LTTV_STATS_ELAPSED_TIME, + LTTV_STATS_EVENTS, + LTTV_STATS_EVENTS_COUNT, + LTTV_STATS_USE_COUNT, + LTTV_STATS, + LTTV_STATS_TRACEFILES, + LTTV_STATS_SUMMED; + +static GQuark + LTTV_STATS_BEFORE_HOOKS, + LTTV_STATS_AFTER_HOOKS; + +static void remove_all_processes(GHashTable *processes); + +static void +find_event_tree(LttvTracefileStats *tfcs, GQuark process, GQuark cpu, + GQuark mode, GQuark sub_mode, LttvAttribute **events_tree, + LttvAttribute **event_types_tree); + +static void +init(LttvTracesetStats *self, LttvTraceset *ts) +{ + guint i, j, nb_trace, nb_tracefile; + + LttvTraceContext *tc; + + LttvTraceStats *tcs; + + LttvTracefileContext *tfc; + + LttvTracefileStats *tfcs; + + LttTime timestamp = {0,0}; + + LttvAttributeValue v; + + LttvAttribute + *stats_tree, + *tracefiles_stats; + + LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))-> + init((LttvTracesetContext *)self, ts); + + self->stats =lttv_attribute_find_subdir(self->parent.parent.ts_a,LTTV_STATS); + lttv_attribute_find(self->parent.parent.ts_a, LTTV_STATS_USE_COUNT, + LTTV_UINT, &v); + + *(v.v_uint)++; + if(*(v.v_uint) == 1) { + g_assert(lttv_attribute_get_number(self->stats) == 0); + } + + nb_trace = lttv_traceset_number(ts); + + for(i = 0 ; i < nb_trace ; i++) { + tcs = (LttvTraceStats *)tc = (LTTV_TRACESET_CONTEXT(self)->traces[i]); + + tcs->stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a,LTTV_STATS); + tracefiles_stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a, + LTTV_STATS_TRACEFILES); + lttv_attribute_find(tcs->parent.parent.t_a, LTTV_STATS_USE_COUNT, + LTTV_UINT, &v); + + *(v.v_uint)++; + if(*(v.v_uint) == 1) { + g_assert(lttv_attribute_get_number(tcs->stats) == 0); + } + + nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + + ltt_trace_per_cpu_tracefile_number(tc->t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfcs = LTTV_TRACEFILE_STATS(tc->tracefiles[j]); + tfcs->stats = lttv_attribute_find_subdir(tracefiles_stats, + tfcs->parent.cpu_name); + find_event_tree(tfcs, LTTV_STATS_PROCESS_UNKNOWN, + tfcs->parent.cpu_name, LTTV_STATE_MODE_UNKNOWN, + LTTV_STATE_SUBMODE_UNKNOWN, &tfcs->current_events_tree, + &tfcs->current_event_types_tree); + } + } +} + + +static void +fini(LttvTracesetStats *self) +{ + guint i, j, nb_trace, nb_tracefile; + + LttvTraceset *ts; + + LttvTraceContext *tc; + + LttvTraceStats *tcs; + + LttvTracefileContext *tfc; + + LttvTracefileStats *tfcs; + + LttTime timestamp = {0,0}; + + LttvAttributeValue v; + + LttvAttribute *tracefiles_stats; + + lttv_attribute_find(self->parent.parent.ts_a, LTTV_STATS_USE_COUNT, + LTTV_UINT, &v); + *(v.v_uint)--; + + if(*(v.v_uint) == 0) { + lttv_attribute_remove_by_name(self->parent.parent.ts_a, LTTV_STATS); + lttv_attribute_recursive_free(self->stats); + } + self->stats = NULL; + + ts = self->parent.parent.ts; + nb_trace = lttv_traceset_number(ts); + + for(i = 0 ; i < nb_trace ; i++) { + tcs = (LttvTraceStats *)(tc = (LTTV_TRACESET_CONTEXT(self)->traces[i])); + + lttv_attribute_find(tcs->parent.parent.t_a, LTTV_STATS_USE_COUNT, + LTTV_UINT, &v); + *(v.v_uint)--; + + if(*(v.v_uint) == 0) { + lttv_attribute_remove_by_name(tcs->parent.parent.t_a,LTTV_STATS); + lttv_attribute_recursive_free(tcs->stats); + tracefiles_stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a, + LTTV_STATS_TRACEFILES); + lttv_attribute_remove_by_name(tcs->parent.parent.t_a, + LTTV_STATS_TRACEFILES); + lttv_attribute_recursive_free(tracefiles_stats); + } + tcs->stats = NULL; + + nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + + ltt_trace_per_cpu_tracefile_number(tc->t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfcs = ((LttvTracefileStats *)tfc = tc->tracefiles[j]); + tfcs->stats = NULL; + tfcs->current_events_tree = NULL; + tfcs->current_event_types_tree = NULL; + } + } + LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))-> + fini((LttvTracesetContext *)self); +} + + +static LttvTracesetContext * +new_traceset_context(LttvTracesetContext *self) +{ + return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATS_TYPE, NULL)); +} + + +static LttvTraceContext * +new_trace_context(LttvTracesetContext *self) +{ + return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATS_TYPE, NULL)); +} + + +static LttvTracefileContext * +new_tracefile_context(LttvTracesetContext *self) +{ + return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATS_TYPE, NULL)); +} + + +static void +traceset_stats_instance_init (GTypeInstance *instance, gpointer g_class) +{ +} + + +static void +traceset_stats_finalize (LttvTracesetStats *self) +{ + G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))-> + finalize(G_OBJECT(self)); +} + + +static void +traceset_stats_class_init (LttvTracesetContextClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = (void (*)(GObject *self)) traceset_stats_finalize; + klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init; + klass->fini = (void (*)(LttvTracesetContext *self))fini; + klass->new_traceset_context = new_traceset_context; + klass->new_trace_context = new_trace_context; + klass->new_tracefile_context = new_tracefile_context; +} + + +GType +lttv_traceset_stats_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof (LttvTracesetStatsClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) traceset_stats_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (LttvTracesetStats), + 0, /* n_preallocs */ + (GInstanceInitFunc) traceset_stats_instance_init /* instance_init */ + }; + + type = g_type_register_static (LTTV_TRACESET_STATE_TYPE, "LttvTracesetStatsType", + &info, 0); + } + return type; +} + + +static void +trace_stats_instance_init (GTypeInstance *instance, gpointer g_class) +{ +} + + +static void +trace_stats_finalize (LttvTraceStats *self) +{ + G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_STATE_TYPE))-> + finalize(G_OBJECT(self)); +} + + +static void +trace_stats_class_init (LttvTraceContextClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = (void (*)(GObject *self)) trace_stats_finalize; +} + + +GType +lttv_trace_stats_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof (LttvTraceStatsClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) trace_stats_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (LttvTraceStats), + 0, /* n_preallocs */ + (GInstanceInitFunc) trace_stats_instance_init /* instance_init */ + }; + + type = g_type_register_static (LTTV_TRACE_STATE_TYPE, + "LttvTraceStatsType", &info, 0); + } + return type; +} + + +static void +tracefile_stats_instance_init (GTypeInstance *instance, gpointer g_class) +{ +} + + +static void +tracefile_stats_finalize (LttvTracefileStats *self) +{ + G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_STATE_TYPE))-> + finalize(G_OBJECT(self)); +} + + +static void +tracefile_stats_class_init (LttvTracefileStatsClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = (void (*)(GObject *self)) tracefile_stats_finalize; +} + + +GType +lttv_tracefile_stats_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof (LttvTracefileStatsClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) tracefile_stats_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (LttvTracefileStats), + 0, /* n_preallocs */ + (GInstanceInitFunc) tracefile_stats_instance_init /* instance_init */ + }; + + type = g_type_register_static (LTTV_TRACEFILE_STATE_TYPE, + "LttvTracefileStatsType", &info, 0); + } + return type; +} + + +static void +find_event_tree(LttvTracefileStats *tfcs, GQuark process, GQuark cpu, + GQuark mode, GQuark sub_mode, LttvAttribute **events_tree, + LttvAttribute **event_types_tree) +{ + LttvAttribute *a; + + LttvTraceStats *tcs = LTTV_TRACE_STATS(tfcs->parent.parent.t_context); + a = lttv_attribute_find_subdir(tcs->stats, LTTV_STATS_PROCESSES); + a = lttv_attribute_find_subdir(a, tfcs->parent.process->pid_time); + a = lttv_attribute_find_subdir(a, LTTV_STATS_CPU); + a = lttv_attribute_find_subdir(a, tfcs->parent.cpu_name); + a = lttv_attribute_find_subdir(a, LTTV_STATS_MODE_TYPES); + a = lttv_attribute_find_subdir(a, tfcs->parent.process->state->t); + a = lttv_attribute_find_subdir(a, LTTV_STATS_SUBMODES); + a = lttv_attribute_find_subdir(a, tfcs->parent.process->state->n); + *events_tree = a; + a = lttv_attribute_find_subdir(a, LTTV_STATS_EVENT_TYPES); + *event_types_tree = a; +} + + +static void update_event_tree(LttvTracefileStats *tfcs) +{ + LttvExecutionState *es = tfcs->parent.process->state; + + find_event_tree(tfcs, tfcs->parent.process->pid_time, tfcs->parent.cpu_name, + es->t, es->n, &(tfcs->current_events_tree), + &(tfcs->current_event_types_tree)); +} + + +static void mode_change(LttvTracefileStats *tfcs) +{ + LttvAttributeValue cpu_time; + + LttTime delta; + + lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME, + LTTV_TIME, &cpu_time); + delta = ltt_time_sub(tfcs->parent.parent.timestamp, + tfcs->parent.process->state->change); + *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta); +} + + +static void mode_end(LttvTracefileStats *tfcs) +{ + LttvAttributeValue elapsed_time, cpu_time; + + LttTime delta; + + lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_ELAPSED_TIME, + LTTV_TIME, &elapsed_time); + delta = ltt_time_sub(tfcs->parent.parent.timestamp, + tfcs->parent.process->state->entry); + *(elapsed_time.v_time) = ltt_time_add(*(elapsed_time.v_time), delta); + + lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME, + LTTV_TIME, &cpu_time); + delta = ltt_time_sub(tfcs->parent.parent.timestamp, + tfcs->parent.process->state->change); + *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta); +} + + +static gboolean before_syscall_entry(void *hook_data, void *call_data) +{ + mode_change((LttvTracefileStats *)call_data); + return FALSE; +} + + +static gboolean after_syscall_entry(void *hook_data, void *call_data) +{ + update_event_tree((LttvTracefileStats *)call_data); + return FALSE; +} + + +gboolean before_syscall_exit(void *hook_data, void *call_data) +{ + mode_end((LttvTracefileStats *)call_data); + return FALSE; +} + + +static gboolean after_syscall_exit(void *hook_data, void *call_data) +{ + update_event_tree((LttvTracefileStats *)call_data); + return FALSE; +} + + +gboolean before_trap_entry(void *hook_data, void *call_data) +{ + mode_change((LttvTracefileStats *)call_data); + return FALSE; +} + + +static gboolean after_trap_entry(void *hook_data, void *call_data) +{ + update_event_tree((LttvTracefileStats *)call_data); + return FALSE; +} + + +gboolean before_trap_exit(void *hook_data, void *call_data) +{ + mode_end((LttvTracefileStats *)call_data); + return FALSE; +} + + +gboolean after_trap_exit(void *hook_data, void *call_data) +{ + update_event_tree((LttvTracefileStats *)call_data); + return FALSE; +} + + +gboolean before_irq_entry(void *hook_data, void *call_data) +{ + mode_change((LttvTracefileStats *)call_data); + return FALSE; +} + + +gboolean after_irq_entry(void *hook_data, void *call_data) +{ + update_event_tree((LttvTracefileStats *)call_data); + return FALSE; +} + + +gboolean before_irq_exit(void *hook_data, void *call_data) +{ + mode_end((LttvTracefileStats *)call_data); + return FALSE; +} + + +gboolean after_irq_exit(void *hook_data, void *call_data) +{ + update_event_tree((LttvTracefileStats *)call_data); + return FALSE; +} + + +gboolean before_schedchange(void *hook_data, void *call_data) +{ + LttvTraceHook *h = (LttvTraceHook *)hook_data; + + LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data; + + guint pid_in, pid_out, state_out; + + LttvProcessState *process; + + pid_in = ltt_event_get_unsigned(tfcs->parent.parent.e, h->f1); + pid_out = ltt_event_get_unsigned(tfcs->parent.parent.e, h->f2); + state_out = ltt_event_get_unsigned(tfcs->parent.parent.e, h->f3); + + /* compute the time for the process to schedule out */ + + mode_change(tfcs); + + /* get the information for the process scheduled in */ + + process = lttv_state_find_process_or_create(&(tfcs->parent), pid_in); + + find_event_tree(tfcs, process->pid_time, tfcs->parent.cpu_name, + process->state->t, process->state->n, &(tfcs->current_events_tree), + &(tfcs->current_event_types_tree)); + + /* compute the time waiting for the process to schedule in */ + + mode_change(tfcs); + return FALSE; +} + + +gboolean process_fork(void *hook_data, void *call_data) +{ + /* nothing to do for now */ + return FALSE; +} + + +gboolean process_exit(void *hook_data, void *call_data) +{ + /* We should probably exit all modes here or we could do that at + schedule out. */ + return FALSE; +} + + +gboolean every_event(void *hook_data, void *call_data) +{ + LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data; + + LttvAttributeValue v; + + /* The current branch corresponds to the tracefile/process/interrupt state. + Statistics are added within it, to count the number of events of this + type occuring in this context. A quark has been pre-allocated for each + event type and is used as name. */ + + lttv_attribute_find(tfcs->current_event_types_tree, + ((LttvTraceState *)(tfcs->parent.parent.t_context))-> + eventtype_names[ltt_event_eventtype_id(tfcs->parent.parent.e)], + LTTV_UINT, &v); + (*(v.v_uint))++; + return FALSE; +} + + +void +lttv_stats_sum_trace(LttvTraceStats *self) +{ + LttvTraceStats *tcs; + + LttvAttributeType type; + + LttvAttributeValue value; + + LttvAttributeName name; + + unsigned sum; + + int i, j, k, l, m, nb_process, nb_cpu, nb_mode_type, nb_submode, + nb_event_type; + + LttvAttribute *main_tree, *processes_tree, *process_tree, *cpus_tree, + *cpu_tree, *mode_tree, *mode_types_tree, *submodes_tree, + *submode_tree, *event_types_tree, *mode_events_tree, + *cpu_events_tree, *process_modes_tree, *trace_cpu_tree, + *trace_modes_tree; + + main_tree = self->stats; + + lttv_attribute_find(self->parent.parent.t_a, LTTV_STATS_SUMMED, + LTTV_UINT, &value); + if(*(value.v_uint) != 0) return; + *(value.v_uint) = 1; + + processes_tree = lttv_attribute_find_subdir(main_tree, + LTTV_STATS_PROCESSES); + trace_modes_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_MODES); + nb_process = lttv_attribute_get_number(processes_tree); + + for(i = 0 ; i < nb_process ; i++) { + type = lttv_attribute_get(processes_tree, i, &name, &value); + process_tree = LTTV_ATTRIBUTE(*(value.v_gobject)); + + cpus_tree = lttv_attribute_find_subdir(process_tree, LTTV_STATS_CPU); + process_modes_tree = lttv_attribute_find_subdir(process_tree, + LTTV_STATS_MODES); + nb_cpu = lttv_attribute_get_number(cpus_tree); + + for(j = 0 ; j < nb_cpu ; j++) { + type = lttv_attribute_get(cpus_tree, j, &name, &value); + cpu_tree = LTTV_ATTRIBUTE(*(value.v_gobject)); + + mode_types_tree = lttv_attribute_find_subdir(cpu_tree, + LTTV_STATS_MODE_TYPES); + cpu_events_tree = lttv_attribute_find_subdir(cpu_tree, + LTTV_STATS_EVENTS); + trace_cpu_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_CPU); + trace_cpu_tree = lttv_attribute_find_subdir(trace_cpu_tree, name); + nb_mode_type = lttv_attribute_get_number(mode_types_tree); + + for(k = 0 ; k < nb_mode_type ; k++) { + type = lttv_attribute_get(mode_types_tree, k, &name, &value); + mode_tree = LTTV_ATTRIBUTE(*(value.v_gobject)); + + submodes_tree = lttv_attribute_find_subdir(mode_tree, + LTTV_STATS_SUBMODES); + mode_events_tree = lttv_attribute_find_subdir(mode_tree, + LTTV_STATS_EVENTS); + nb_submode = lttv_attribute_get_number(submodes_tree); + + for(l = 0 ; l < nb_submode ; l++) { + type = lttv_attribute_get(submodes_tree, l, &name, &value); + submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject)); + + event_types_tree = lttv_attribute_find_subdir(submode_tree, + LTTV_STATS_EVENT_TYPES); + nb_event_type = lttv_attribute_get_number(event_types_tree); + + sum = 0; + for(m = 0 ; m < nb_event_type ; m++) { + type = lttv_attribute_get(event_types_tree, m, &name, &value); + sum += *(value.v_uint); + } + lttv_attribute_find(submode_tree, LTTV_STATS_EVENTS_COUNT, + LTTV_UINT, &value); + *(value.v_uint) = sum; + lttv_attribute_recursive_add(mode_events_tree, submode_tree); + } + lttv_attribute_recursive_add(cpu_events_tree, mode_events_tree); + } + lttv_attribute_recursive_add(process_modes_tree, cpu_tree); + lttv_attribute_recursive_add(trace_cpu_tree, cpu_tree); + } + lttv_attribute_recursive_add(trace_modes_tree, process_modes_tree); + } +} + + +void +lttv_stats_sum_traceset(LttvTracesetStats *self) +{ + LttvTraceset *traceset = self->parent.parent.ts; + + LttvTraceStats *tcs; + + int i, nb_trace; + + LttvAttribute *main_tree, *trace_modes_tree, *traceset_modes_tree; + + LttvAttributeValue value; + + lttv_attribute_find(self->parent.parent.ts_a, LTTV_STATS_SUMMED, + LTTV_UINT, &value); + if(*(value.v_uint) != 0) return; + *(value.v_uint) = 1; + + traceset_modes_tree = lttv_attribute_find_subdir(self->stats, + LTTV_STATS_MODES); + nb_trace = lttv_traceset_number(traceset); + + for(i = 0 ; i < nb_trace ; i++) { + tcs = (LttvTraceStats *)(self->parent.parent.traces[i]); + lttv_stats_sum_trace(tcs); + main_tree = tcs->stats; + trace_modes_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_MODES); + lttv_attribute_recursive_add(traceset_modes_tree, trace_modes_tree); + } +} + + +lttv_stats_add_event_hooks(LttvTracesetStats *self) +{ + LttvTraceset *traceset = self->parent.parent.ts; + + guint i, j, k, nb_trace, nb_tracefile; + + LttFacility *f; + + LttEventType *et; + + LttvTraceStats *ts; + + LttvTracefileStats *tfs; + + void *hook_data; + + GArray *hooks, *before_hooks, *after_hooks; + + LttvTraceHook hook; + + LttvAttributeValue val; + + nb_trace = lttv_traceset_number(traceset); + for(i = 0 ; i < nb_trace ; i++) { + ts = (LttvTraceStats *)self->parent.parent.traces[i]; + + /* Find the eventtype id for the following events and register the + associated by id hooks. */ + + hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook)); + g_array_set_size(hooks, 7); + + lttv_trace_find_hook(ts->parent.parent.t, "core","syscall_entry", + "syscall_id", NULL, NULL, before_syscall_entry, + &g_array_index(hooks, LttvTraceHook, 0)); + + lttv_trace_find_hook(ts->parent.parent.t, "core", "syscall_exit", NULL, + NULL, NULL, before_syscall_exit, + &g_array_index(hooks, LttvTraceHook, 1)); + + lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_entry", "trap_id", + NULL, NULL, before_trap_entry, + &g_array_index(hooks, LttvTraceHook, 2)); + + lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_exit", NULL, NULL, + NULL, before_trap_exit, &g_array_index(hooks, LttvTraceHook, 3)); + + lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_entry", "irq_id", + NULL, NULL, before_irq_entry, &g_array_index(hooks, LttvTraceHook, 4)); + + lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_exit", NULL, NULL, + NULL, before_irq_exit, &g_array_index(hooks, LttvTraceHook, 5)); + + lttv_trace_find_hook(ts->parent.parent.t, "core", "schedchange", "in", + "out", "out_state", before_schedchange, + &g_array_index(hooks, LttvTraceHook, 6)); + + before_hooks = hooks; + + hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook)); + g_array_set_size(hooks, 8); + + lttv_trace_find_hook(ts->parent.parent.t, "core","syscall_entry", + "syscall_id", NULL, NULL, after_syscall_entry, + &g_array_index(hooks, LttvTraceHook, 0)); + + lttv_trace_find_hook(ts->parent.parent.t, "core", "syscall_exit", NULL, + NULL, NULL, after_syscall_exit, + &g_array_index(hooks, LttvTraceHook, 1)); + + lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_entry", "trap_id", + NULL, NULL, after_trap_entry, &g_array_index(hooks, LttvTraceHook, 2)); + + lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_exit", NULL, NULL, + NULL, after_trap_exit, &g_array_index(hooks, LttvTraceHook, 3)); + + lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_entry", "irq_id", + NULL, NULL, after_irq_entry, &g_array_index(hooks, LttvTraceHook, 4)); + + lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_exit", NULL, NULL, + NULL, after_irq_exit, &g_array_index(hooks, LttvTraceHook, 5)); + + lttv_trace_find_hook(ts->parent.parent.t, "core", "process_fork", + "child_pid", NULL, NULL, process_fork, + &g_array_index(hooks, LttvTraceHook, 6)); + + lttv_trace_find_hook(ts->parent.parent.t, "core", "process_exit", NULL, + NULL, NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 7)); + + after_hooks = hooks; + + /* Add these hooks to each before_event_by_id hooks list */ + + nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.parent.t) + + ltt_trace_per_cpu_tracefile_number(ts->parent.parent.t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfs = LTTV_TRACEFILE_STATS(ts->parent.parent.tracefiles[j]); + lttv_hooks_add(tfs->parent.parent.after_event, every_event, NULL); + + for(k = 0 ; k < before_hooks->len ; k++) { + hook = g_array_index(before_hooks, LttvTraceHook, k); + lttv_hooks_add(lttv_hooks_by_id_find( + tfs->parent.parent.before_event_by_id, + hook.id), hook.h, &g_array_index(before_hooks, LttvTraceHook, k)); + } + for(k = 0 ; k < after_hooks->len ; k++) { + hook = g_array_index(after_hooks, LttvTraceHook, k); + lttv_hooks_add(lttv_hooks_by_id_find( + tfs->parent.parent.after_event_by_id, + hook.id), hook.h, &g_array_index(after_hooks, LttvTraceHook, k)); + } + } + lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS, + LTTV_POINTER, &val); + *(val.v_pointer) = before_hooks; + lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS, + LTTV_POINTER, &val); + *(val.v_pointer) = after_hooks; + } +} + + +lttv_stats_remove_event_hooks(LttvTracesetStats *self) +{ + LttvTraceset *traceset = self->parent.parent.ts; + + guint i, j, k, nb_trace, nb_tracefile; + + LttvTraceStats *ts; + + LttvTracefileStats *tfs; + + void *hook_data; + + GArray *before_hooks, *after_hooks; + + LttvTraceHook hook; + + LttvAttributeValue val; + + nb_trace = lttv_traceset_number(traceset); + for(i = 0 ; i < nb_trace ; i++) { + ts = LTTV_TRACE_STATS(self->parent.parent.traces[i]); + lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS, + LTTV_POINTER, &val); + before_hooks = *(val.v_pointer); + lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS, + LTTV_POINTER, &val); + after_hooks = *(val.v_pointer); + + /* Add these hooks to each before_event_by_id hooks list */ + + nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.parent.t) + + ltt_trace_per_cpu_tracefile_number(ts->parent.parent.t); + + for(j = 0 ; j < nb_tracefile ; j++) { + tfs = LTTV_TRACEFILE_STATS(ts->parent.parent.tracefiles[j]); + lttv_hooks_remove_data(tfs->parent.parent.after_event, every_event, + NULL); + + for(k = 0 ; k < before_hooks->len ; k++) { + hook = g_array_index(before_hooks, LttvTraceHook, k); + lttv_hooks_remove_data( + lttv_hooks_by_id_find(tfs->parent.parent.before_event_by_id, + hook.id), hook.h, &g_array_index(before_hooks, LttvTraceHook, k)); + } + for(k = 0 ; k < after_hooks->len ; k++) { + hook = g_array_index(after_hooks, LttvTraceHook, k); + lttv_hooks_remove_data( + lttv_hooks_by_id_find(tfs->parent.parent.after_event_by_id, + hook.id), hook.h, &g_array_index(after_hooks, LttvTraceHook, k)); + } + } + g_debug("lttv_stats_remove_event_hooks()"); + g_array_free(before_hooks, TRUE); + g_array_free(after_hooks, TRUE); + } +} + + +static void module_init() +{ + LTTV_STATS_PROCESS_UNKNOWN = g_quark_from_string("unknown process"); + LTTV_STATS_PROCESSES = g_quark_from_string("processes"); + LTTV_STATS_CPU = g_quark_from_string("cpu"); + LTTV_STATS_MODE_TYPES = g_quark_from_string("mode_types"); + LTTV_STATS_MODES = g_quark_from_string("modes"); + LTTV_STATS_SUBMODES = g_quark_from_string("submodes"); + LTTV_STATS_EVENT_TYPES = g_quark_from_string("event_types"); + LTTV_STATS_CPU_TIME = g_quark_from_string("cpu time"); + LTTV_STATS_ELAPSED_TIME = g_quark_from_string("elapsed time"); + LTTV_STATS_EVENTS = g_quark_from_string("events"); + LTTV_STATS_EVENTS_COUNT = g_quark_from_string("events count"); + LTTV_STATS_BEFORE_HOOKS = g_quark_from_string("saved stats before hooks"); + LTTV_STATS_AFTER_HOOKS = g_quark_from_string("saved stats after hooks"); + LTTV_STATS_USE_COUNT = g_quark_from_string("stats_use_count"); + LTTV_STATS = g_quark_from_string("statistics"); + LTTV_STATS_TRACEFILES = g_quark_from_string("tracefiles statistics"); + LTTV_STATS_SUMMED = g_quark_from_string("statistics summed"); +} + +static void module_destroy() +{ +} + + +LTTV_MODULE("stats", "Compute processes statistics", \ + "Accumulate statistics for event types, processes and CPUs", \ + module_init, module_destroy, "state"); + +/* Change the places where stats are called (create/read/write stats) + + Check for options in batchtest.c to reduce writing and see what tests are + best candidates for performance analysis. Once OK, commit, move to main + and run tests. Update the gui for statistics. */ diff --git a/ltt/branches/poly/lttv/lttv/stats.h b/ltt/branches/poly/lttv/lttv/stats.h new file mode 100644 index 00000000..37d36945 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/stats.h @@ -0,0 +1,223 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef STATS_H +#define STATS_H + +#include +#include + +/* The statistics are for a complete time interval. These structures differ + from the system state since they relate to static components of the + system (all processes which existed instead of just the currently + existing processes). + + The basic attributes tree to gather for several different execution modes + (e.g., user mode, syscall, irq), thereafter called the "events tree", + contains the following attributes: the number of events of each type, + the total number of events, the number of bytes written, the time spent + executing, waiting for a resource, waiting for a cpu, and possibly many + others. The name "facility-event_type" below is to be replaced + by specific event types (e.g., core-schedchange, code-syscall_entry...). + + event_types/ + "facility-event_type" + events_count + cpu_time + elapsed_time + wait_time + bytes_written + packets_sent + ... + + The events for several different execution modes are joined together to + form the "execution modes tree". The name "execution mode" is to be replaced + by "system call", "trap", "irq", "user mode" or "kernel thread". + The name "submode" is to be replaced by the specific system call, trap or + irq name. The "submode" is an empty string if none is applicable, which is + the case for "user mode" and "kernel thread". + + An "events tree" for each "execution mode" contains the sum for all its + different submodes. An "events tree" in the "execution modes tree" contains + the sum for all its different execution modes. + + mode_types/ + "execution mode"/ + submodes/ + "submode"/ + Events Tree + events/ + Event Tree + events/ + Events Tree + + Each trace set contains an "execution modes tree". While the traces + come from possibly different systems, which may differ in their system + calls..., most of the system calls will have the same name, even if their + actual internal numeric id differs. Categories such as cpu id and process + id are not kept since these are specific to each system. When several + traces are taken from the same system, these categories may make sense and + could eventually be considered. + + Each trace contains a global "execution modes tree", one for each + cpu and process, and one for each process/cpu combination. The name + "cpu number" stands for the cpu identifier, and "process_id-start_time" + is a unique process identifier composed of the process id + (unique at any given time but which may be reused over time) concatenated + with the process start time. + + modes/ + Execution Modes Tree + cpu/ + "cpu number"/ + Execution Modes Tree + processes/ + "process_id-start_time"/ + exec_file_name + parent + start_time + end_time + modes/ + Execution Modes Tree + cpu/ + "cpu number"/ + Execution Modes Tree + + All the events and derived values (cpu, elapsed and wait time) are + added during the trace analysis in the relevant + trace / processes / * / cpu / * / mode_types / * /submodes / * + "events tree". To achieve this efficiently, each tracefile context + contains a pointer to the current relevant "events tree" and "event_types" + tree within it. + + Once all the events are processed, the total number of events is computed + within each trace / processes / * / cpu / * / mode_types / * / submodes / *. + Then, the "events tree" are summed for all submodes within each mode type + and for all mode types within a processes / * / cpu / * + "execution modes tree". + + Finally, the "execution modes trees" for all cpu within a process, + for all processes, and for all traces are computed. Separately, + the "execution modes tree" for each cpu but for all processes within a + trace are summed in the trace / cpu / * subtrees. + + */ + + +/* The various statistics branch names are GQuarks. They are pre-computed for + easy and efficient access */ + +extern GQuark + LTTV_STATS_PROCESS_UNKNOWN, + LTTV_STATS_PROCESSES, + LTTV_STATS_CPU, + LTTV_STATS_MODE_TYPES, + LTTV_STATS_SUBMODES, + LTTV_STATS_EVENT_TYPES, + LTTV_STATS_CPU_TIME, + LTTV_STATS_ELAPSED_TIME, + LTTV_STATS_EVENTS, + LTTV_STATS_EVENTS_COUNT, + LTTV_STATS_BEFORE_HOOKS, + LTTV_STATS_AFTER_HOOKS; + + +typedef struct _LttvTracesetStats LttvTracesetStats; +typedef struct _LttvTracesetStatsClass LttvTracesetStatsClass; + +typedef struct _LttvTraceStats LttvTraceStats; +typedef struct _LttvTraceStatsClass LttvTraceStatsClass; + +typedef struct _LttvTracefileStats LttvTracefileStats; +typedef struct _LttvTracefileStatsClass LttvTracefileStatsClass; + +gboolean lttv_stats_add_event_hooks(LttvTracesetStats *self); + +gboolean lttv_stats_remove_event_hooks(LttvTracesetStats *self); + +void lttv_stats_sum_traceset(LttvTracesetStats *self); + +void lttv_stats_sum_trace(LttvTraceStats *self); + + +/* The LttvTracesetStats, LttvTraceStats and LttvTracefileStats types + inherit from the corresponding State objects defined in state.h.. */ + +#define LTTV_TRACESET_STATS_TYPE (lttv_traceset_stats_get_type ()) +#define LTTV_TRACESET_STATS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACESET_STATS_TYPE, LttvTracesetStats)) +#define LTTV_TRACESET_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACESET_STATS_TYPE, LttvTracesetStatsClass)) +#define LTTV_IS_TRACESET_STATS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACESET_STATS_TYPE)) +#define LTTV_IS_TRACESET_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACESET_STATS_TYPE)) +#define LTTV_TRACESET_STATS_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACESET_STATS_TYPE, LttvTracesetStatsClass)) + +struct _LttvTracesetStats { + LttvTracesetState parent; + + LttvAttribute *stats; +}; + +struct _LttvTracesetStatsClass { + LttvTracesetStateClass parent; +}; + +GType lttv_traceset_stats_get_type (void); + + +#define LTTV_TRACE_STATS_TYPE (lttv_trace_stats_get_type ()) +#define LTTV_TRACE_STATS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACE_STATS_TYPE, LttvTraceStats)) +#define LTTV_TRACE_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACE_STATS_TYPE, LttvTraceStatsClass)) +#define LTTV_IS_TRACE_STATS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACE_STATS_TYPE)) +#define LTTV_IS_TRACE_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACE_STATS_TYPE)) +#define LTTV_TRACE_STATS_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACE_STATS_TYPE, LttvTraceStatsClass)) + +struct _LttvTraceStats { + LttvTraceState parent; + + LttvAttribute *stats; +}; + +struct _LttvTraceStatsClass { + LttvTraceStateClass parent; +}; + +GType lttv_trace_stats_get_type (void); + + +#define LTTV_TRACEFILE_STATS_TYPE (lttv_tracefile_stats_get_type ()) +#define LTTV_TRACEFILE_STATS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACEFILE_STATS_TYPE, LttvTracefileStats)) +#define LTTV_TRACEFILE_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACEFILE_STATS_TYPE, LttvTracefileStatsClass)) +#define LTTV_IS_TRACEFILE_STATS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACEFILE_STATS_TYPE)) +#define LTTV_IS_TRACEFILE_STATS_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACEFILE_STATS_TYPE)) +#define LTTV_TRACEFILE_STATS_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACEFILE_STATS_TYPE, LttvTracefileStatsClass)) + +struct _LttvTracefileStats { + LttvTracefileState parent; + + LttvAttribute *stats; + LttvAttribute *current_events_tree; + LttvAttribute *current_event_types_tree; +}; + +struct _LttvTracefileStatsClass { + LttvTracefileStateClass parent; +}; + +GType lttv_tracefile_stats_get_type (void); + + +#endif // STATS_H diff --git a/ltt/branches/poly/lttv/lttv/tracecontext.h b/ltt/branches/poly/lttv/lttv/tracecontext.h new file mode 100644 index 00000000..6afff0ff --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/tracecontext.h @@ -0,0 +1,288 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef PROCESSTRACE_H +#define PROCESSTRACE_H + +#include +#include +#include +#include + +/* This is the generic part of trace processing. All events within a + certain time interval are accessed and processing hooks are called for + each. The events are examined in monotonically increasing time to more + closely follow the traced system behavior. + + Hooks are called at several different places during the processing: + before traceset, after traceset, check trace, before trace, after trace, + check tracefile, before tracefile, after tracefile, + check_event, before_event, before_event_by_id, + after_event, after_event_by_id. + + In each case the "check" hooks are called first to determine if further + processing of the trace, tracefile or event is wanted. Then, the before + hooks and the after hooks are called. The before hooks for a traceset + are called before those for the contained traces, which are called before + those for the contained tracefiles. The after hooks are called in reverse + order. The event hooks are called after all the before_tracefile hooks + and before all the after_tracefile hooks. + + The hooks receive two arguments, the hook_data and call_data. The hook_data + is specified when the hook is registered and typically links to the + object registering the hook (e.g. a graphical events viewer). The call_data + must contain all the context related to the call. The traceset hooks receive + the LttvTracesetContext provided by the caller. The trace hooks receive + the LttvTraceContext from the traces array in the LttvTracesetContext. + The tracefile and event hooks receive the LttvTracefileContext from + the tracefiles array in the LttvTraceContext. The LttEvent and LttTime + fields in the tracefile context are set to the current event and current + event time before calling the event hooks. No other context field is + modified. + + The contexts in the traces and tracefiles arrays must be allocated by + the caller, either before the call or during the before hooks of the + enclosing traceset or trace. The order in the traces array must + correspond to the lttv_traceset_get function. The order in the tracefiles + arrays must correspond to the ltt_trace_control_tracefile_get and + ltt_trace_per_cpu_tracefile_get functions. The traceset, trace and + tracefile contexts may be subtyped as needed. Indeed, both the contexts + and the hooks are defined by the caller. */ + + +typedef struct _LttvTracesetContext LttvTracesetContext; +typedef struct _LttvTracesetContextClass LttvTracesetContextClass; + +typedef struct _LttvTraceContext LttvTraceContext; +typedef struct _LttvTraceContextClass LttvTraceContextClass; + +typedef struct _LttvTracefileContext LttvTracefileContext; +typedef struct _LttvTracefileContextClass LttvTracefileContextClass; + +#define LTTV_TRACESET_CONTEXT_TYPE (lttv_traceset_context_get_type ()) +#define LTTV_TRACESET_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACESET_CONTEXT_TYPE, LttvTracesetContext)) +#define LTTV_TRACESET_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACESET_CONTEXT_TYPE, LttvTracesetContextClass)) +#define LTTV_IS_TRACESET_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACESET_CONTEXT_TYPE)) +#define LTTV_IS_TRACESET_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACESET_CONTEXT_TYPE)) +#define LTTV_TRACESET_CONTEXT_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACESET_CONTEXT_TYPE, LttvTracesetContextClass)) + +struct _LttvTracesetContext { + GObject parent; + + LttvTraceset *ts; + LttvHooks *before; + LttvHooks *after; + LttvTraceContext **traces; + LttvAttribute *a; + LttvAttribute *ts_a; + TimeInterval *Time_Span; + GTree *pqueue; +}; + +struct _LttvTracesetContextClass { + GObjectClass parent; + + void (*init) (LttvTracesetContext *self, LttvTraceset *ts); + void (*fini) (LttvTracesetContext *self); + LttvTracesetContext* (*new_traceset_context) (LttvTracesetContext *self); + LttvTraceContext* (*new_trace_context) (LttvTracesetContext *self); + LttvTracefileContext* (*new_tracefile_context) (LttvTracesetContext *self); +}; + +GType lttv_traceset_context_get_type (void); + +void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts); + +void lttv_context_fini(LttvTracesetContext *self); + +LttvTracesetContext * +lttv_context_new_traceset_context(LttvTracesetContext *self); + +LttvTraceContext * +lttv_context_new_trace_context(LttvTracesetContext *self); + +LttvTracefileContext * +lttv_context_new_tracefile_context(LttvTracesetContext *self); + + +#define LTTV_TRACE_CONTEXT_TYPE (lttv_trace_context_get_type ()) +#define LTTV_TRACE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACE_CONTEXT_TYPE, LttvTraceContext)) +#define LTTV_TRACE_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACE_CONTEXT_TYPE, LttvTraceContextClass)) +#define LTTV_IS_TRACE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACE_CONTEXT_TYPE)) +#define LTTV_IS_TRACE_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACE_CONTEXT_TYPE)) +#define LTTV_TRACE_CONTEXT_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACE_CONTEXT_TYPE, LttvTraceContextClass)) + +struct _LttvTraceContext { + GObject parent; + + LttvTracesetContext *ts_context; + guint index; /* in ts_context->traces */ + LttTrace *t; + LttvTrace *vt; + LttvHooks *check; + LttvHooks *before; + LttvHooks *after; + LttvTracefileContext **tracefiles; + LttvAttribute *a; + LttvAttribute *t_a; +}; + +struct _LttvTraceContextClass { + GObjectClass parent; +}; + +GType lttv_trace_context_get_type (void); + +#define LTTV_TRACEFILE_CONTEXT_TYPE (lttv_tracefile_context_get_type ()) +#define LTTV_TRACEFILE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LTTV_TRACEFILE_CONTEXT_TYPE, LttvTracefileContext)) +#define LTTV_TRACEFILE_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), LTTV_TRACEFILE_CONTEXT_TYPE, LttvTracefileContextClass)) +#define LTTV_IS_TRACEFILE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LTTV_TRACEFILE_CONTEXT_TYPE)) +#define LTTV_IS_TRACEFILE_CONTEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), LTTV_TRACEFILE_CONTEXT_TYPE)) +#define LTTV_TRACEFILE_CONTEXT_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), LTTV_TRACEFILE_CONTEXT_TYPE, LttvTracefileContextClass)) + +struct _LttvTracefileContext { + GObject parent; + + LttvTraceContext *t_context; + gboolean control; + guint index; /* in ts_context->tracefiles */ + LttTracefile *tf; + LttvHooks *check; + LttvHooks *before; + LttvHooks *after; + LttEvent *e; + LttvHooks *check_event; + LttvHooks *before_event; + LttvHooksById *before_event_by_id; + LttvHooks *after_event; + LttvHooksById *after_event_by_id; + LttTime timestamp; + LttvAttribute *a; +}; + +struct _LttvTracefileContextClass { + GObjectClass parent; +}; + +GType lttv_tracefile_context_get_type (void); + +/* Run through the events in a traceset in sorted order calling all the + hooks appropriately. It starts at the current time and runs until end or + nb_events are processed. */ + +void lttv_process_traceset(LttvTracesetContext *self, LttTime end, + unsigned nb_events); + +/* Process traceset can also be done in smaller pieces calling begin, middle + repeatedly, and end. The middle function return the number of events + processed. It may be larger than nb_events if several events have the + same timestamp. It will be smaller than nb_events if the end time + is reached. */ + +void lttv_process_traceset_begin(LttvTracesetContext *self, LttTime end); + +guint lttv_process_traceset_middle(LttvTracesetContext *self, LttTime end, + unsigned nb_events); + +void lttv_process_traceset_end(LttvTracesetContext *self); + + +void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start); + +void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start); + +void lttv_traceset_context_add_hooks(LttvTracesetContext *self, + LttvHooks *before_traceset, + LttvHooks *after_traceset, + LttvHooks *check_trace, + LttvHooks *before_trace, + LttvHooks *after_trace, + LttvHooks *check_tracefile, + LttvHooks *before_tracefile, + LttvHooks *after_tracefile, + LttvHooks *check_event, + LttvHooks *before_event, + LttvHooks *after_event); + +void lttv_traceset_context_remove_hooks(LttvTracesetContext *self, + LttvHooks *before_traceset, + LttvHooks *after_traceset, + LttvHooks *check_trace, + LttvHooks *before_trace, + LttvHooks *after_trace, + LttvHooks *check_tracefile, + LttvHooks *before_tracefile, + LttvHooks *after_tracefile, + LttvHooks *check_event, + LttvHooks *before_event, + LttvHooks *after_event); + +void lttv_trace_context_add_hooks(LttvTraceContext *self, + LttvHooks *check_trace, + LttvHooks *before_trace, + LttvHooks *after_trace); + +void lttv_trace_context_remove_hooks(LttvTraceContext *self, + LttvHooks *check_trace, + LttvHooks *before_trace, + LttvHooks *after_trace); + +void lttv_tracefile_context_add_hooks(LttvTracefileContext *self, + LttvHooks *check_tracefile, + LttvHooks *before_tracefile, + LttvHooks *after_tracefile, + LttvHooks *check_event, + LttvHooks *before_event, + LttvHooks *after_event); + +void lttv_tracefile_context_remove_hooks(LttvTracefileContext *self, + LttvHooks *check_tracefile, + LttvHooks *before_tracefile, + LttvHooks *after_tracefile, + LttvHooks *check_event, + LttvHooks *before_event, + LttvHooks *after_event); + +void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext *self, + unsigned i, + LttvHooks *before_event_by_id, + LttvHooks *after_event_by_id); + +void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext *self, + unsigned i); + +typedef struct _LttvTraceHook { + LttvHook h; + guint id; + LttField *f1; + LttField *f2; + LttField *f3; +} LttvTraceHook; + + +/* Search in the trace for the id of the named event type within the named + facility. Then, find the three (if non null) named fields. All that + information is then used to fill the LttvTraceHook structure. This + is useful to find the specific id for an event within a trace, for + registering a hook using this structure as event data; + it already contains the (up to three) needed fields handles. */ + +void lttv_trace_find_hook(LttTrace *t, char *facility, char *event_type, + char *field1, char *field2, char *field3, LttvHook h, LttvTraceHook *th); + +#endif // PROCESSTRACE_H diff --git a/ltt/branches/poly/lttv/lttv/traceset.c b/ltt/branches/poly/lttv/lttv/traceset.c new file mode 100644 index 00000000..aa536488 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/traceset.c @@ -0,0 +1,189 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + + +#include +#include + +/* A trace is a sequence of events gathered in the same tracing session. The + events may be stored in several tracefiles in the same directory. + A trace set is defined when several traces are to be analyzed together, + possibly to study the interactions between events in the different traces. +*/ + +struct _LttvTraceset { + char * filename; + GPtrArray *traces; + LttvAttribute *a; +}; + + +struct _LttvTrace { + LttTrace *t; + LttvAttribute *a; + guint ref_count; +}; + + +LttvTraceset *lttv_traceset_new() +{ + LttvTraceset *s; + + s = g_new(LttvTraceset, 1); + s->filename = NULL; + s->traces = g_ptr_array_new(); + s->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); + return s; +} + +char * lttv_traceset_name(LttvTraceset * s) +{ + return s->filename; +} + +LttvTrace *lttv_trace_new(LttTrace *t) +{ + LttvTrace *new_trace; + + new_trace = g_new(LttvTrace, 1); + new_trace->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); + new_trace->t = t; + new_trace->ref_count = 0; + return new_trace; +} + + +LttvTraceset *lttv_traceset_copy(LttvTraceset *s_orig) +{ + int i; + LttvTraceset *s; + LttvTrace * trace; + + s = g_new(LttvTraceset, 1); + s->filename = NULL; + s->traces = g_ptr_array_new(); + for(i=0;itraces->len;i++) + { + trace = g_ptr_array_index(s_orig->traces, i); + trace->ref_count++; + + /*CHECK this used ltt_trace_copy while it may not be needed. Need to + define how traces and tracesets are shared */ + g_ptr_array_add( + s->traces, + g_ptr_array_index(s_orig->traces, i)); + } + s->a = LTTV_ATTRIBUTE(lttv_iattribute_deep_copy(LTTV_IATTRIBUTE(s_orig->a))); + return s; +} + + +LttvTraceset *lttv_traceset_load(const gchar *filename) +{ + LttvTraceset *s = g_new(LttvTraceset,1); + FILE *tf; + + s->filename = g_strdup(filename); + tf = fopen(filename,"r"); + + g_critical("NOT IMPLEMENTED : load traceset data from a XML file"); + + fclose(tf); + return s; +} + +gint lttv_traceset_save(LttvTraceset *s) +{ + FILE *tf; + + tf = fopen(s->filename, "w"); + + g_critical("NOT IMPLEMENTED : save traceset data in a XML file"); + + fclose(tf); + return 0; +} + +void lttv_traceset_destroy(LttvTraceset *s) +{ + g_ptr_array_free(s->traces, TRUE); + g_object_unref(s->a); + g_free(s); +} + +void lttv_trace_destroy(LttvTrace *t) +{ + g_object_unref(t->a); + g_free(t); +} + + +void lttv_traceset_add(LttvTraceset *s, LttvTrace *t) +{ + t->ref_count++; + g_ptr_array_add(s->traces, t); +} + + +unsigned lttv_traceset_number(LttvTraceset *s) +{ + return s->traces->len; +} + + +LttvTrace *lttv_traceset_get(LttvTraceset *s, unsigned i) +{ + g_assert(s->traces->len > i); + return ((LttvTrace *)s->traces->pdata[i]); +} + + +void lttv_traceset_remove(LttvTraceset *s, unsigned i) +{ + LttvTrace * t; + g_assert(s->traces->len > i); + t = (LttvTrace *)s->traces->pdata[i]; + t->ref_count--; + g_ptr_array_remove_index(s->traces, i); +} + + +/* A set of attributes is attached to each trace set, trace and tracefile + to store user defined data as needed. */ + +LttvAttribute *lttv_traceset_attribute(LttvTraceset *s) +{ + return s->a; +} + + +LttvAttribute *lttv_trace_attribute(LttvTrace *t) +{ + return t->a; +} + + +LttTrace *lttv_trace(LttvTrace *t) +{ + return t->t; +} + +guint lttv_trace_get_ref_number(LttvTrace * t) +{ + return t->ref_count; +} diff --git a/ltt/branches/poly/lttv/lttv/traceset.h b/ltt/branches/poly/lttv/lttv/traceset.h new file mode 100644 index 00000000..9d29d7a3 --- /dev/null +++ b/ltt/branches/poly/lttv/lttv/traceset.h @@ -0,0 +1,69 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef TRACESET_H +#define TRACESET_H + +#include +#include +#include + +/* A traceset is a set of traces to be analyzed together. */ + +typedef struct _LttvTraceset LttvTraceset; + +typedef struct _LttvTrace LttvTrace; + +/* Tracesets may be added to, removed from and their content listed. */ + +LttvTraceset *lttv_traceset_new(); + +char * lttv_traceset_name(LttvTraceset * s); + +LttvTrace *lttv_trace_new(LttTrace *t); + +LttvTraceset *lttv_traceset_copy(LttvTraceset *s_orig); + +LttvTraceset *lttv_traceset_load(const gchar *filename); + +gint lttv_traceset_save(LttvTraceset *s); + +void lttv_traceset_destroy(LttvTraceset *s); + +void lttv_trace_destroy(LttvTrace *t); + +void lttv_traceset_add(LttvTraceset *s, LttvTrace *t); + +unsigned lttv_traceset_number(LttvTraceset *s); + +LttvTrace *lttv_traceset_get(LttvTraceset *s, unsigned i); + +void lttv_traceset_remove(LttvTraceset *s, unsigned i); + +/* An attributes table is attached to the set and to each trace in the set. */ + +LttvAttribute *lttv_traceset_attribute(LttvTraceset *s); + +LttvAttribute *lttv_trace_attribute(LttvTrace *t); + +LttTrace *lttv_trace(LttvTrace *t); + +guint lttv_trace_get_ref_number(LttvTrace * t); + +#endif // TRACESET_H + diff --git a/ltt/branches/poly/lttv/main/Makefile.am b/ltt/branches/poly/lttv/main/Makefile.am deleted file mode 100644 index 4c891fc3..00000000 --- a/ltt/branches/poly/lttv/main/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -AM_CFLAGS = $(GLIB_CFLAGS) -LIBS += $(GLIB_LIBS) -lgobject-2.0 -L$(top_srcdir)/ltt -ltraceread - -bin_PROGRAMS = lttv - -INCLUDES = \ - -DPACKAGE_PLUGIN_DIR=\""$(lttvplugindir)"\" \ - @PACKAGE_CFLAGS@ \ - $(DEFAULT_INCLUDES) - -libdir = ${lttvplugindir} - -lttv_SOURCES = main.c module.c option.c \ - hook.c attribute.c \ - iattribute.c processTrace.c \ - state.c stats.c traceset.c - diff --git a/ltt/branches/poly/lttv/main/attribute.c b/ltt/branches/poly/lttv/main/attribute.c deleted file mode 100644 index a3f8ab9a..00000000 --- a/ltt/branches/poly/lttv/main/attribute.c +++ /dev/null @@ -1,561 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include -#include - -typedef union _AttributeValue { - int dv_int; - unsigned dv_uint; - long dv_long; - unsigned long dv_ulong; - float dv_float; - double dv_double; - LttTime dv_time; - gpointer dv_pointer; - char *dv_string; - GObject *dv_gobject; -} AttributeValue; - - -typedef struct _Attribute { - LttvAttributeName name; - LttvAttributeType type; - AttributeValue value; -} Attribute; - - -LttvAttributeValue address_of_value(LttvAttributeType t, AttributeValue *v) -{ - LttvAttributeValue va; - - switch(t) { - case LTTV_INT: va.v_int = &v->dv_int; break; - case LTTV_UINT: va.v_uint = &v->dv_uint; break; - case LTTV_LONG: va.v_long = &v->dv_long; break; - case LTTV_ULONG: va.v_ulong = &v->dv_ulong; break; - case LTTV_FLOAT: va.v_float = &v->dv_float; break; - case LTTV_DOUBLE: va.v_double = &v->dv_double; break; - case LTTV_TIME: va.v_time = &v->dv_time; break; - case LTTV_POINTER: va.v_pointer = &v->dv_pointer; break; - case LTTV_STRING: va.v_string = &v->dv_string; break; - case LTTV_GOBJECT: va.v_gobject = &v->dv_gobject; break; - } - return va; -} - - -AttributeValue init_value(LttvAttributeType t) -{ - AttributeValue v; - - switch(t) { - case LTTV_INT: v.dv_int = 0; break; - case LTTV_UINT: v.dv_uint = 0; break; - case LTTV_LONG: v.dv_long = 0; break; - case LTTV_ULONG: v.dv_ulong = 0; break; - case LTTV_FLOAT: v.dv_float = 0; break; - case LTTV_DOUBLE: v.dv_double = 0; break; - case LTTV_TIME: v.dv_time.tv_sec = 0; v.dv_time.tv_nsec = 0; break; - case LTTV_POINTER: v.dv_pointer = NULL; break; - case LTTV_STRING: v.dv_string = NULL; break; - case LTTV_GOBJECT: v.dv_gobject = NULL; break; - } - return v; -} - - -unsigned int -lttv_attribute_get_number(LttvAttribute *self) -{ - return self->attributes->len; -} - - -gboolean -lttv_attribute_named(LttvAttribute *self, gboolean *homogeneous) -{ - *homogeneous = FALSE; - return TRUE; -} - - -LttvAttributeType -lttv_attribute_get(LttvAttribute *self, unsigned i, LttvAttributeName *name, - LttvAttributeValue *v) -{ - Attribute *a; - - a = &g_array_index(self->attributes, Attribute, i); - *name = a->name; - *v = address_of_value(a->type, &(a->value)); - return a->type; -} - - -LttvAttributeType -lttv_attribute_get_by_name(LttvAttribute *self, LttvAttributeName name, - LttvAttributeValue *v) -{ - Attribute *a; - - unsigned i; - - gpointer p; - - p = g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); - if(p == NULL) return LTTV_NONE; - - i = GPOINTER_TO_UINT(p); - i--; - a = &g_array_index(self->attributes, Attribute, i); - *v = address_of_value(a->type, &(a->value)); - return a->type; -} - - -LttvAttributeValue -lttv_attribute_add(LttvAttribute *self, LttvAttributeName name, - LttvAttributeType t) -{ - unsigned i; - - Attribute a, *pa; - - i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); - if(i != 0) g_error("duplicate entry in attribute table"); - - a.name = name; - a.type = t; - a.value = init_value(t); - g_array_append_val(self->attributes, a); - i = self->attributes->len - 1; - pa = &g_array_index(self->attributes, Attribute, i); - g_hash_table_insert(self->names, GUINT_TO_POINTER(name), - GUINT_TO_POINTER(i + 1)); - return address_of_value(t, &(pa->value)); -} - - -/* Remove an attribute */ - -void -lttv_attribute_remove(LttvAttribute *self, unsigned i) -{ - Attribute *a; - - a = &g_array_index(self->attributes, Attribute, i); - - /* Remove the array element and its entry in the name index */ - - g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name)); - g_array_remove_index_fast(self->attributes, i); - - /* The element used to replace the removed element has its index entry - all wrong now. Reinsert it with its new position. */ - - if(self->attributes->len != i){ - g_hash_table_remove(self->names, GUINT_TO_POINTER(a->name)); - g_hash_table_insert(self->names, GUINT_TO_POINTER(a->name), GUINT_TO_POINTER(i + 1)); - } -} - -void -lttv_attribute_remove_by_name(LttvAttribute *self, LttvAttributeName name) -{ - unsigned i; - - i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); - if(i == 0) g_error("remove by name non existent attribute"); - - lttv_attribute_remove(self, i - 1); -} - -/* Create an empty iattribute object and add it as an attribute under the - specified name, or return an existing iattribute attribute. If an - attribute of that name already exists but is not a GObject supporting the - iattribute interface, return NULL. */ - -/*CHECK*/LttvAttribute* -lttv_attribute_find_subdir(LttvAttribute *self, LttvAttributeName name) -{ - unsigned i; - - Attribute a; - - LttvAttribute *new; - - i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); - if(i != 0) { - a = g_array_index(self->attributes, Attribute, i - 1); - if(a.type == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(a.value.dv_gobject)) { - return LTTV_ATTRIBUTE(a.value.dv_gobject); - } - else return NULL; - } - new = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); - *(lttv_attribute_add(self, name, LTTV_GOBJECT).v_gobject) = G_OBJECT(new); - return (LttvAttribute *)new; -} - -gboolean -lttv_attribute_find(LttvAttribute *self, LttvAttributeName name, - LttvAttributeType t, LttvAttributeValue *v) -{ - unsigned i; - - Attribute *a; - - i = (unsigned)g_hash_table_lookup(self->names, GUINT_TO_POINTER(name)); - if(i != 0) { - a = &g_array_index(self->attributes, Attribute, i - 1); - if(a->type != t) return FALSE; - *v = address_of_value(t, &(a->value)); - return TRUE; - } - - *v = lttv_attribute_add(self, name, t); - return TRUE; -} - - -void lttv_attribute_recursive_free(LttvAttribute *self) -{ - int i, nb; - - Attribute *a; - - nb = self->attributes->len; - - for(i = 0 ; i < nb ; i++) { - a = &g_array_index(self->attributes, Attribute, i); - if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) { - lttv_attribute_recursive_free((LttvAttribute *)(a->value.dv_gobject)); - } - } - g_object_unref(self); -} - - -void lttv_attribute_recursive_add(LttvAttribute *dest, LttvAttribute *src) -{ - int i, nb; - - Attribute *a; - - LttvAttributeValue value; - - nb = src->attributes->len; - - for(i = 0 ; i < nb ; i++) { - a = &g_array_index(src->attributes, Attribute, i); - if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) { - lttv_attribute_recursive_add( - /*CHECK*/(LttvAttribute *)lttv_attribute_find_subdir(dest, a->name), - (LttvAttribute *)(a->value.dv_gobject)); - } - else { - g_assert(lttv_attribute_find(dest, a->name, a->type, &value)); - switch(a->type) { - case LTTV_INT: - *value.v_int += a->value.dv_int; - break; - case LTTV_UINT: - *value.v_uint += a->value.dv_uint; - break; - case LTTV_LONG: - *value.v_long += a->value.dv_long; - break; - case LTTV_ULONG: - *value.v_ulong += a->value.dv_ulong; - break; - case LTTV_FLOAT: - *value.v_float += a->value.dv_float; - break; - case LTTV_DOUBLE: - *value.v_double += a->value.dv_double; - break; - case LTTV_TIME: - *value.v_time = ltt_time_add(*value.v_time, a->value.dv_time); - break; - case LTTV_POINTER: - break; - case LTTV_STRING: - break; - case LTTV_GOBJECT: - break; - case LTTV_NONE: - break; - } - } - } -} - - -static void -print_indent(FILE *fp, int pos) -{ - int i; - - for(i = 0 ; i < pos ; i++) putc(' ', fp); -} - - -void -lttv_attribute_write_xml(LttvAttribute *self, FILE *fp, int pos, int indent) -{ - int i, nb; - - Attribute *a; - - nb = self->attributes->len; - - fprintf(fp,"\n"); - for(i = 0 ; i < nb ; i++) { - a = &g_array_index(self->attributes, Attribute, i); - print_indent(fp, pos); - fprintf(fp, "name); - if(a->type == LTTV_GOBJECT && LTTV_IS_ATTRIBUTE(a->value.dv_gobject)) { - fprintf(fp, "TYPE=ATTRS>"); - lttv_attribute_write_xml((LttvAttribute *)(a->value.dv_gobject), fp, - pos + indent, indent); - } - else { - switch(a->type) { - case LTTV_INT: - fprintf(fp, "TYPE=INT VALUE=%d/>\n", a->value.dv_int); - break; - case LTTV_UINT: - fprintf(fp, "TYPE=UINT VALUE=%u/>\n", a->value.dv_uint); - break; - case LTTV_LONG: - fprintf(fp, "TYPE=LONG VALUE=%ld/>\n", a->value.dv_long); - break; - case LTTV_ULONG: - fprintf(fp, "TYPE=ULONG VALUE=%lu/>\n", a->value.dv_ulong); - break; - case LTTV_FLOAT: - fprintf(fp, "TYPE=FLOAT VALUE=%f/>\n", a->value.dv_float); - break; - case LTTV_DOUBLE: - fprintf(fp, "TYPE=DOUBLE VALUE=%f/>\n", a->value.dv_double); - break; - case LTTV_TIME: - fprintf(fp, "TYPE=TIME SEC=%u NSEC=%u/>\n", a->value.dv_time.tv_sec, - a->value.dv_time.tv_nsec); - break; - case LTTV_POINTER: - fprintf(fp, "TYPE=POINTER VALUE=%p/>\n", a->value.dv_pointer); - break; - case LTTV_STRING: - fprintf(fp, "TYPE=STRING VALUE=\"%s\"/>\n", a->value.dv_string); - break; - case LTTV_GOBJECT: - fprintf(fp, "TYPE=GOBJECT VALUE=%p/>\n", a->value.dv_gobject); - break; - case LTTV_NONE: - fprintf(fp, "TYPE=NONE/>\n"); - break; - } - } - } - print_indent(fp, pos); - fprintf(fp,"\n"); -} - - -void -lttv_attribute_read_xml(LttvAttribute *self, FILE *fp) -{ - int i, nb, res; - - Attribute *a; - - char buffer[256], type[10]; - - LttvAttributeName name; - - LttvAttributeValue value; - - LttvAttribute *subtree; - - fscanf(fp,""); - while(1) { - res = fscanf(fp, "]", buffer, type); - g_assert(res == 2); - name = g_quark_from_string(buffer); - if(strcmp(type, "ATTRS") == 0) { - fscanf(fp, ">"); - subtree = lttv_attribute_find_subdir(self, name); - lttv_attribute_read_xml(subtree, fp); - } - else if(strcmp(type, "INT") == 0) { - value = lttv_attribute_add(self, name, LTTV_INT); - res = fscanf(fp, " VALUE=%d/>", value.v_int); - g_assert(res == 1); - } - else if(strcmp(type, "UINT") == 0) { - value = lttv_attribute_add(self, name, LTTV_UINT); - res = fscanf(fp, " VALUE=%u/>", value.v_uint); - g_assert(res == 1); - } - else if(strcmp(type, "LONG") == 0) { - value = lttv_attribute_add(self, name, LTTV_LONG); - res = fscanf(fp, " VALUE=%ld/>", value.v_long); - g_assert(res == 1); - } - else if(strcmp(type, "ULONG") == 0) { - value = lttv_attribute_add(self, name, LTTV_ULONG); - res = fscanf(fp, " VALUE=%lu/>", value.v_ulong); - g_assert(res == 1); - } - else if(strcmp(type, "FLOAT") == 0) { - float d; - value = lttv_attribute_add(self, name, LTTV_FLOAT); - res = fscanf(fp, " VALUE=%f/>", &d); - *(value.v_float) = d; - g_assert(res == 1); - } - else if(strcmp(type, "DOUBLE") == 0) { - value = lttv_attribute_add(self, name, LTTV_DOUBLE); - res = fscanf(fp, " VALUE=%f/>", value.v_double); - g_assert(res == 1); - } - else if(strcmp(type, "TIME") == 0) { - value = lttv_attribute_add(self, name, LTTV_TIME); - res = fscanf(fp, " SEC=%u NSEC=%u/>", &(value.v_time->tv_sec), - &(value.v_time->tv_nsec)); - g_assert(res == 2); - } - else if(strcmp(type, "POINTER") == 0) { - value = lttv_attribute_add(self, name, LTTV_POINTER); - res = fscanf(fp, " VALUE=%p/>", value.v_pointer); - g_error("Cannot read a pointer"); - } - else if(strcmp(type, "STRING") == 0) { - value = lttv_attribute_add(self, name, LTTV_STRING); - res = fscanf(fp, " VALUE=\"%256[^\"]\"/>", buffer); - *(value.v_string) = g_strdup(buffer); - g_assert(res == 1); - } - else if(strcmp(type, "GOBJECT") == 0) { - value = lttv_attribute_add(self, name, LTTV_GOBJECT); - res = fscanf(fp, " VALUE=%p/>", value.v_gobject); - g_error("Cannot read a pointer"); - } - else if(strcmp(type, "NONE") == 0) { - value = lttv_attribute_add(self, name, LTTV_NONE); - fscanf(fp, "/>"); - } - else g_error("Unknown type to read"); - } - fscanf(fp,""); -} - - -static void -attribute_interface_init (gpointer g_iface, gpointer iface_data) -{ - LttvIAttributeClass *klass = (LttvIAttributeClass *)g_iface; - - klass->get_number = (unsigned int (*) (LttvIAttribute *self)) - lttv_attribute_get_number; - - klass->named = (gboolean (*) (LttvIAttribute *self, gboolean *homogeneous)) - lttv_attribute_named; - - klass->get = (LttvAttributeType (*) (LttvIAttribute *self, unsigned i, - LttvAttributeName *name, LttvAttributeValue *v)) lttv_attribute_get; - - klass->get_by_name = (LttvAttributeType (*) (LttvIAttribute *self, - LttvAttributeName name, LttvAttributeValue *v)) - lttv_attribute_get_by_name; - - klass->add = (LttvAttributeValue (*) (LttvIAttribute *self, - LttvAttributeName name, LttvAttributeType t)) lttv_attribute_add; - - klass->remove = (void (*) (LttvIAttribute *self, unsigned i)) - lttv_attribute_remove; - - klass->remove_by_name = (void (*) (LttvIAttribute *self, - LttvAttributeName name)) lttv_attribute_remove_by_name; - - klass->find_subdir = (LttvIAttribute* (*) (LttvIAttribute *self, - LttvAttributeName name)) lttv_attribute_find_subdir; -} - - -static void -attribute_instance_init (GTypeInstance *instance, gpointer g_class) -{ - LttvAttribute *self = (LttvAttribute *)instance; - self->names = g_hash_table_new(g_direct_hash, g_direct_equal); - self->attributes = g_array_new(FALSE, FALSE, sizeof(Attribute)); -} - - -static void -attribute_finalize (LttvAttribute *self) -{ - g_hash_table_destroy(self->names); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "attribute_finalize()"); - g_array_free(self->attributes, TRUE); - G_OBJECT_CLASS(g_type_class_peek_parent( - g_type_class_peek(LTTV_ATTRIBUTE_TYPE)))->finalize(G_OBJECT(self)); -} - - -static void -attribute_class_init (LttvAttributeClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->finalize = (void (*)(GObject *self))attribute_finalize; -} - -GType -lttv_attribute_get_type (void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (LttvAttributeClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) attribute_class_init, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (LttvAttribute), - 0, /* n_preallocs */ - (GInstanceInitFunc) attribute_instance_init /* instance_init */ - }; - - static const GInterfaceInfo iattribute_info = { - (GInterfaceInitFunc) attribute_interface_init, /* interface_init */ - NULL, /* interface_finalize */ - NULL /* interface_data */ - }; - - type = g_type_register_static (G_TYPE_OBJECT, "LttvAttributeType", &info, - 0); - g_type_add_interface_static (type, LTTV_IATTRIBUTE_TYPE, &iattribute_info); - } - return type; -} - - diff --git a/ltt/branches/poly/lttv/main/filter.c b/ltt/branches/poly/lttv/main/filter.c deleted file mode 100644 index 74cd30e1..00000000 --- a/ltt/branches/poly/lttv/main/filter.c +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - - - consist in AND, OR and NOT nested expressions, forming a tree with - simple relations as leaves. The simple relations test is a field - in an event is equal, not equal, smaller, smaller or equal, larger, or - larger or equal to a specified value. */ - -typedef enum _lttv_expression_op -{ LTTV_FIELD_EQ, - LTTV_FIELD_NE, - LTTV_FIELD_LT, - LTTV_FIELD_LE, - LTTV_FIELD_GT, - LTTV_FIELD_GE -} lttv_expression_op; - -typedef _lttv_simple_expression -{ lttv_expression_op op; - char *field_name; - char *value; -} lttv_simple_expression; - -typedef _lttv_expression_type -{ LTTV_EXPRESSION, - LTTV_SIMPLE_EXPRESSION - -} -typedef struct _lttv_expression -{ bool or; - bool not; - bool simple_expression; - union - { lttv_expression *e; - lttv_field_relation *se; - } e; -} lttv_expression; - -read_token - -read_expression - ( read expr ) - simple expr [ op expr ] - -read_simple_expression - read_field_path [ rel value ] - -read_field_path - read_field_component [. field path] - -read_field_component - name [ \[ value \] ] - -data struct: -and/or(left/right) -not(child) -op(left/right) -path(component...) -> field - - diff --git a/ltt/branches/poly/lttv/main/hook.c b/ltt/branches/poly/lttv/main/hook.c deleted file mode 100644 index a7f0960d..00000000 --- a/ltt/branches/poly/lttv/main/hook.c +++ /dev/null @@ -1,230 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - - -#include - - -typedef struct _LttvHookClosure { - LttvHook hook; - void *hook_data; -} LttvHookClosure; - - -LttvHooks *lttv_hooks_new() -{ - return g_array_new(FALSE, FALSE, sizeof(LttvHookClosure)); -} - - -void lttv_hooks_destroy(LttvHooks *h) -{ - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "lttv_hooks_destroy()"); - g_array_free(h, TRUE); -} - - -void lttv_hooks_add(LttvHooks *h, LttvHook f, void *hook_data) -{ - LttvHookClosure c; - - if(h == NULL)g_error("Null hook added"); - - c.hook = f; - c.hook_data = hook_data; - g_array_append_val(h,c); -} - - -void lttv_hooks_add_list(LttvHooks *h, LttvHooks *list) -{ - guint i; - - if(list == NULL) return; - for(i = 0 ; i < list->len; i++) { - g_array_append_val(h,g_array_index(list, LttvHookClosure, i)); - } -} - - -void *lttv_hooks_remove(LttvHooks *h, LttvHook f) -{ - unsigned i; - - void *hook_data; - - LttvHookClosure *c; - - for(i = 0 ; i < h->len ; i++) { - c = &g_array_index(h, LttvHookClosure, i); - if(c->hook == f) { - hook_data = c->hook_data; - lttv_hooks_remove_by_position(h, i); - return hook_data; - } - } - return NULL; -} - - -void lttv_hooks_remove_data(LttvHooks *h, LttvHook f, void *hook_data) -{ - unsigned i; - - LttvHookClosure *c; - - for(i = 0 ; i < h->len ; i++) { - c = &g_array_index(h, LttvHookClosure, i); - if(c->hook == f && c->hook_data == hook_data) { - lttv_hooks_remove_by_position(h, i); - return; - } - } -} - - -void lttv_hooks_remove_list(LttvHooks *h, LttvHooks *list) -{ - guint i, j; - - LttvHookClosure *c, *c_list; - - if(list == NULL) return; - for(i = 0, j = 0 ; i < h->len && j < list->len ;) { - c = &g_array_index(h, LttvHookClosure, i); - c_list = &g_array_index(list, LttvHookClosure, j); - if(c->hook == c_list->hook && c->hook_data == c_list->hook_data) { - lttv_hooks_remove_by_position(h, i); - j++; - } - else i++; - } - - /* Normally the hooks in h are ordered as in list. If this is not the case, - try harder here. */ - - if(j < list->len) { - for(; j < list->len ; j++) { - c_list = &g_array_index(list, LttvHookClosure, j); - lttv_hooks_remove_data(h, c_list->hook, c_list->hook_data); - } - } -} - - -unsigned lttv_hooks_number(LttvHooks *h) -{ - return h->len; -} - - -void lttv_hooks_get(LttvHooks *h, unsigned i, LttvHook *f, void **hook_data) -{ - LttvHookClosure *c; - - c = &g_array_index(h, LttvHookClosure, i); - *f = c->hook; - *hook_data = c->hook_data; -} - - -void lttv_hooks_remove_by_position(LttvHooks *h, unsigned i) -{ - g_array_remove_index(h, i); -} - - -gboolean lttv_hooks_call(LttvHooks *h, void *call_data) -{ - gboolean ret, sum_ret = FALSE; - - LttvHookClosure *c; - - guint i; - - if(h != NULL) { - for(i = 0 ; i < h->len ; i++) { - c = &g_array_index(h, LttvHookClosure, i); - ret = c->hook(c->hook_data,call_data); - sum_ret = sum_ret || ret; - } - } - return sum_ret; -} - - -gboolean lttv_hooks_call_check(LttvHooks *h, void *call_data) -{ - LttvHookClosure *c; - - guint i; - - for(i = 0 ; i < h->len ; i++) { - c = &g_array_index(h, LttvHookClosure, i); - if(c->hook(c->hook_data,call_data)) return TRUE; - } - return FALSE; -} - - -LttvHooksById *lttv_hooks_by_id_new() -{ - return g_ptr_array_new(); -} - - -void lttv_hooks_by_id_destroy(LttvHooksById *h) -{ - guint i; - - for(i = 0 ; i < h->len ; i++) { - if(h->pdata[i] != NULL) lttv_hooks_destroy((LttvHooks *)(h->pdata[i])); - } - g_ptr_array_free(h, TRUE); -} - - -LttvHooks *lttv_hooks_by_id_find(LttvHooksById *h, unsigned id) -{ - if(h->len <= id) g_ptr_array_set_size(h, id + 1); - if(h->pdata[id] == NULL) h->pdata[id] = lttv_hooks_new(); - return h->pdata[id]; -} - - -unsigned lttv_hooks_by_id_max_id(LttvHooksById *h) -{ - return h->len; -} - - -LttvHooks *lttv_hooks_by_id_get(LttvHooksById *h, unsigned id) -{ - if(id < h->len) return h->pdata[id]; - return NULL; -} - - -void lttv_hooks_by_id_remove(LttvHooksById *h, unsigned id) -{ - if(id < h->len && h->pdata[id] != NULL) { - lttv_hooks_destroy((LttvHooks *)h->pdata[id]); - h->pdata[id] = NULL; - } -} - diff --git a/ltt/branches/poly/lttv/main/iattribute.c b/ltt/branches/poly/lttv/main/iattribute.c deleted file mode 100644 index ba17e3a2..00000000 --- a/ltt/branches/poly/lttv/main/iattribute.c +++ /dev/null @@ -1,278 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - - -#include - -static void -lttv_iattribute_base_init (gpointer klass) -{ - static gboolean initialized = FALSE; - - if (!initialized) { - initialized = TRUE; - } -} - - -GType -lttv_iattribute_get_type (void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (LttvIAttributeClass), - lttv_iattribute_base_init, /* base_init */ - NULL, /* base_finalize */ - NULL, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, - 0, /* n_preallocs */ - NULL /* instance_init */ - }; - type = g_type_register_static (G_TYPE_INTERFACE, "LttvIAttribute", - &info, 0); - } - return type; -} - - -unsigned int lttv_iattribute_get_number(LttvIAttribute *self) -{ - return LTTV_IATTRIBUTE_GET_CLASS (self)->get_number (self); -} - - -gboolean lttv_iattribute_named(LttvIAttribute *self, gboolean *homogeneous) -{ - return LTTV_IATTRIBUTE_GET_CLASS (self)->named (self, homogeneous); -} - - -LttvAttributeType lttv_iattribute_get(LttvIAttribute *self, unsigned i, - LttvAttributeName *name, LttvAttributeValue *v) -{ - return LTTV_IATTRIBUTE_GET_CLASS (self)->get (self, i, name, v); -} - - -LttvAttributeType lttv_iattribute_get_by_name(LttvIAttribute *self, - LttvAttributeName name, LttvAttributeValue *v) -{ - return LTTV_IATTRIBUTE_GET_CLASS (self)->get_by_name (self, name, v); -} - - -LttvAttributeValue lttv_iattribute_add(LttvIAttribute *self, - LttvAttributeName name, LttvAttributeType t) -{ - return LTTV_IATTRIBUTE_GET_CLASS (self)->add (self, name, t); -} - - -void lttv_iattribute_remove(LttvIAttribute *self, unsigned i) -{ - return LTTV_IATTRIBUTE_GET_CLASS (self)->remove (self, i); -} - - -void lttv_iattribute_remove_by_name(LttvIAttribute *self, - LttvAttributeName name) -{ - return LTTV_IATTRIBUTE_GET_CLASS (self)->remove_by_name (self, name); -} - -LttvIAttribute* lttv_iattribute_find_subdir(LttvIAttribute *self, - LttvAttributeName name) -{ - return LTTV_IATTRIBUTE_GET_CLASS (self)->find_subdir (self, name); -} - - -/* Find the named attribute in the table, which must be of the specified type. - If it does not exist, it is created with a default value of 0 (NULL for - pointer types). Since the address of the value is obtained, it may be - changed easily afterwards. The function returns false when the attribute - exists but is of incorrect type. */ - -gboolean lttv_iattribute_find(LttvIAttribute *self, LttvAttributeName name, - LttvAttributeType t, LttvAttributeValue *v) -{ - LttvAttributeType found_type; - - found_type = lttv_iattribute_get_by_name(self, name, v); - if(found_type == t) return TRUE; - - if(found_type == LTTV_NONE) { - *v = lttv_iattribute_add(self, name, t); - return TRUE; - } - - return FALSE; -} - - -/* Trees of attribute tables may be accessed using a hierarchical path with - components separated by /, like in filesystems */ - -gboolean lttv_iattribute_find_by_path(LttvIAttribute *self, char *path, - LttvAttributeType t, LttvAttributeValue *v) -{ - LttvIAttribute *node = self; - - LttvAttributeType found_type; - - LttvAttributeName name; - - gchar **components, **cursor; - - components = g_strsplit(path, "\"", G_MAXINT); - - if(components == NULL || *components == NULL) { - g_strfreev(components); - return FALSE; - } - - for(cursor = components;;) { - name = g_quark_from_string(*cursor); - cursor++; - - if(*cursor == NULL) { - g_strfreev(components); - return lttv_iattribute_find(node, name, t, v); - } - else { - found_type = lttv_iattribute_get_by_name(node, name, v); - if(found_type == LTTV_NONE) { - node = lttv_iattribute_find_subdir(node, name); - } - else if(found_type == LTTV_GOBJECT && - LTTV_IS_IATTRIBUTE(*(v->v_gobject))) { - node = LTTV_IATTRIBUTE(*(v->v_gobject)); - } - else { - g_strfreev(components); - return FALSE; - } - } - } -} - -/* Shallow and deep copies */ - -LttvIAttribute *lttv_iattribute_shallow_copy(LttvIAttribute *self) -{ - LttvIAttribute *copy; - - LttvAttributeType t; - - LttvAttributeValue v, v_copy; - - LttvAttributeName name; - - int i; - - int nb_attributes = lttv_iattribute_get_number(self); - - copy = LTTV_IATTRIBUTE(g_object_new(G_OBJECT_TYPE(self),NULL)); - - for(i = 0 ; i < nb_attributes ; i++) { - t = lttv_iattribute_get(self, i, &name, &v); - v_copy = lttv_iattribute_add(copy, name, t); - lttv_iattribute_copy_value(t, v_copy, v); - } -} - -LttvIAttribute *lttv_iattribute_deep_copy(LttvIAttribute *self) -{ - LttvIAttribute *copy, *child; - - LttvAttributeType t; - - LttvAttributeValue v, v_copy; - - LttvAttributeName name; - - int i; - - int nb_attributes = lttv_iattribute_get_number(self); - - copy = LTTV_IATTRIBUTE(g_object_new(G_OBJECT_TYPE(self), NULL)); - - for(i = 0 ; i < nb_attributes ; i++) { - t = lttv_iattribute_get(self, i, &name, &v); - v_copy = lttv_iattribute_add(copy, name, t); - if(t == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(*(v.v_gobject))) { - child = LTTV_IATTRIBUTE(*(v.v_gobject)); - *(v_copy.v_gobject) = G_OBJECT(lttv_iattribute_deep_copy(child)); - } - else lttv_iattribute_copy_value(t, v_copy, v); - } -} - -void lttv_iattribute_copy_value(LttvAttributeType t, LttvAttributeValue dest, - LttvAttributeValue src) -{ - switch(t) { - case LTTV_INT: - *(dest.v_int) = *(src.v_int); - break; - - case LTTV_UINT: - *(dest.v_uint) = *(src.v_uint); - break; - - case LTTV_LONG: - *(dest.v_long) = *(src.v_long); - break; - - case LTTV_ULONG: - *(dest.v_ulong) = *(src.v_ulong); - break; - - case LTTV_FLOAT: - *(dest.v_float) = *(src.v_float); - break; - - case LTTV_DOUBLE: - *(dest.v_double) = *(src.v_double); - break; - - case LTTV_TIME: - *(dest.v_time) = *(src.v_time); - break; - - case LTTV_POINTER: - *(dest.v_pointer) = *(src.v_pointer); - break; - - case LTTV_STRING: - *(dest.v_string) = *(src.v_string); - break; - - case LTTV_GOBJECT: - *(dest.v_gobject) = *(src.v_gobject); - break; - - case LTTV_NONE: - break; - } -} - - diff --git a/ltt/branches/poly/lttv/main/main.c b/ltt/branches/poly/lttv/main/main.c deleted file mode 100644 index a27519e8..00000000 --- a/ltt/branches/poly/lttv/main/main.c +++ /dev/null @@ -1,283 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* The main program maintains a few central data structures and relies - on modules for the rest. These data structures may be accessed by modules - through an exported API */ - -static LttvIAttribute *attributes; - -static LttvHooks - *before_options, - *after_options, - *before_main, - *after_main; - -static char - *a_module, - *a_module_path; - -static gboolean - a_verbose, - a_debug; - -gboolean lttv_profile_memory; - -int lttv_argc; - -char **lttv_argv; - -static void lttv_module_option(void *hook_data); - -static void lttv_module_path_option(void *hook_data); - -static void lttv_verbose(void *hook_data); - -static void lttv_debug(void *hook_data); - -static void lttv_help(void *hook_data); - -/* This is the handler to specify when we dont need all the debugging - messages. It receives the message and does nothing. */ - -void ignore_and_drop_message(const gchar *log_domain, GLogLevelFlags log_level, - const gchar *message, gpointer user_data) { -} - - -/* Since everything is done in modules, the main program only takes care - of the infrastructure. */ - -int main(int argc, char **argv) { - - int i; - - char - *profile_memory_short_option = "-M", - *profile_memory_long_option = "--memory"; - - gboolean profile_memory = FALSE; - - LttvAttributeValue value; - - lttv_argc = argc; - lttv_argv = argv; - - /* Before anything else, check if memory profiling is requested */ - - for(i = 1 ; i < argc ; i++) { - if(*(argv[i]) != '-') break; - if(strcmp(argv[i], profile_memory_short_option) == 0 || - strcmp(argv[i], profile_memory_long_option) == 0) { - g_mem_set_vtable(glib_mem_profiler_table); - g_message("Memory summary before main"); - g_mem_profile(); - profile_memory = TRUE; - break; - } - } - - - /* Initialize glib and by default ignore info and debug messages */ - - g_type_init(); - //g_type_init_with_debug_flags (G_TYPE_DEBUG_OBJECTS | G_TYPE_DEBUG_SIGNALS); - g_log_set_handler(NULL, G_LOG_LEVEL_INFO, ignore_and_drop_message, NULL); - g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, ignore_and_drop_message, NULL); - - - /* Have an attributes subtree to store hooks to be registered by modules. */ - - attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL)); - - before_options = lttv_hooks_new(); - after_options = lttv_hooks_new(); - before_main = lttv_hooks_new(); - after_main = lttv_hooks_new(); - - - /* Create a number of hooks lists */ - - g_assert(lttv_iattribute_find_by_path(attributes, "hooks/options/before", - LTTV_POINTER, &value)); - *(value.v_pointer) = before_options; - g_assert(lttv_iattribute_find_by_path(attributes, "hooks/options/after", - LTTV_POINTER, &value)); - *(value.v_pointer) = after_options; - g_assert(lttv_iattribute_find_by_path(attributes, "hooks/main/before", - LTTV_POINTER, &value)); - *(value.v_pointer) = before_main; - g_assert(lttv_iattribute_find_by_path(attributes, "hooks/main/after", - LTTV_POINTER, &value)); - *(value.v_pointer) = after_main; - - - /* Initialize the command line options processing */ - - GError *error = NULL; - - LttvModule *module_module = lttv_module_require("module", &error); - if(error != NULL) g_error(error->message); - LttvModule *module_option = lttv_module_require("option", &error); - if(error != NULL) g_error(error->message); - - /* Initialize the module loading */ - - lttv_library_path_add(PACKAGE_PLUGIN_DIR); - - - /* Add some built-in options */ - - lttv_option_add("module",'m', "load a module", "name of module to load", - LTTV_OPT_STRING, &a_module, lttv_module_option, NULL); - - lttv_option_add("modules-path", 'L', - "add a directory to the module search path", - "directory to add to the path", LTTV_OPT_STRING, &a_module_path, - lttv_module_path_option, NULL); - - lttv_option_add("help",'h', "basic help", "none", - LTTV_OPT_NONE, NULL, lttv_help, NULL); - - a_verbose = FALSE; - lttv_option_add("verbose",'v', "print information messages", "none", - LTTV_OPT_NONE, NULL, lttv_verbose, NULL); - - a_debug = FALSE; - lttv_option_add("debug",'d', "print debugging messages", "none", - LTTV_OPT_NONE, NULL, lttv_debug, NULL); - - lttv_profile_memory = FALSE; - lttv_option_add(profile_memory_long_option + 2, - profile_memory_short_option[1], "print memory information", "none", - LTTV_OPT_NONE, <tv_profile_memory, NULL, NULL); - - - /* Process the options */ - - lttv_hooks_call(before_options, NULL); - lttv_option_parse(argc, argv); - lttv_hooks_call(after_options, NULL); - - - /* Memory profiling to be useful must be activated as early as possible */ - - if(profile_memory != lttv_profile_memory) - g_error("Memory profiling options must appear before other options"); - - - /* Do the main work */ - - lttv_hooks_call(before_main, NULL); - lttv_hooks_call(after_main, NULL); - - - /* Clean up everything */ - - lttv_module_release(module_option); - lttv_module_release(module_module); - - lttv_hooks_destroy(before_options); - lttv_hooks_destroy(after_options); - lttv_hooks_destroy(before_main); - lttv_hooks_destroy(after_main); - g_object_unref(attributes); - - if(profile_memory) { - g_message("Memory summary after main"); - g_mem_profile(); - } - return 0; -} - - -LttvAttribute *lttv_global_attributes() -{ - return (LttvAttribute*)attributes; -} - - -void lttv_module_option(void *hook_data) -{ - GError *error = NULL; - - lttv_module_require(a_module, &error); - if(error != NULL) g_error(error->message); -} - - -void lttv_module_path_option(void *hook_data) -{ - lttv_library_path_add(a_module_path); -} - - -void lttv_verbose(void *hook_data) -{ - g_log_set_handler(NULL, G_LOG_LEVEL_INFO, g_log_default_handler, NULL); - g_info("Logging set to include INFO level messages"); -} - -void lttv_debug(void *hook_data) -{ - g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, g_log_default_handler, NULL); - g_info("Logging set to include DEBUG level messages"); -} - -void lttv_help(void *hook_data) -{ - printf("Linux Trace Toolkit Visualizer\n"); - printf("\n"); - lttv_option_show_help(); - printf("\n"); -} - -/* - -- Define formally traceset/trace in the GUI for the user and decide how - trace/traceset sharing goes in the application. - -- Use appropriately the new functions in time.h - -- remove the separate tracefiles (control/per cpu) arrays/loops in context. - -- split processTrace into context.c and processTrace.c - -- check spelling conventions. - -- get all the copyright notices. - -- remove all the warnings. - -- get all the .h files properly doxygen commented to produce useful documents. - -- have an intro/architecture document. - -- write a tutorial */ diff --git a/ltt/branches/poly/lttv/main/module.c b/ltt/branches/poly/lttv/main/module.c deleted file mode 100644 index c4d3d6b0..00000000 --- a/ltt/branches/poly/lttv/main/module.c +++ /dev/null @@ -1,584 +0,0 @@ - -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - - -/* module.c : Implementation of the module loading/unloading mechanism. */ - -#include -#include - - -struct _LttvLibrary -{ - LttvLibraryInfo info; - GPtrArray *modules; - GModule *gm; - guint locked_loaded; -}; - - -struct _LttvModule -{ - LttvModuleInfo info; - char **prerequisites_names; - GPtrArray *prerequisites; -}; - - -/* Modules are searched by name. However, a library may be loaded which - provides a module with the same name as an existing one. A stack of - modules is thus maintained for each name. - - Libraries correspond to glib modules. The g_module function is - responsible for loading each library only once. */ - -static GHashTable *modules_by_name = NULL; - -static GPtrArray *libraries = NULL; - -static GHashTable *libraries_by_g_module = NULL; - -static GPtrArray *library_paths = NULL; - -static gboolean initialized = FALSE; - -static gboolean destroyed = TRUE; - -static struct _LttvModuleDescription *builtin_chain = NULL; - -static struct _LttvModuleDescription *module_chain = NULL; - -static struct _LttvModuleDescription **module_next = &module_chain; - -static GQuark lttv_module_error; - -static void init(); - -static finish_destroy(); - -static void module_release(LttvModule *m); - - -static LttvLibrary *library_add(char *name, char *path, GModule *gm) -{ - LttvLibrary *l; - - LttvModule *m; - - struct _LttvModuleDescription *link; - - GPtrArray *modules; - - l = g_new(LttvLibrary, 1); - l->modules = g_ptr_array_new(); - l->gm = gm; - l->locked_loaded = 0; - l->info.name = g_strdup(name); - l->info.path = g_strdup(path); - l->info.load_count = 0; - - g_ptr_array_add(libraries, l); - g_hash_table_insert(libraries_by_g_module, gm, l); - - *module_next = NULL; - for(link = module_chain; link != NULL; link = link->next) { - m = g_new(LttvModule, 1); - g_ptr_array_add(l->modules, m); - - modules = g_hash_table_lookup(modules_by_name, link->name); - if(modules == NULL) { - modules = g_ptr_array_new(); - g_hash_table_insert(modules_by_name, g_strdup(link->name), modules); - } - g_ptr_array_add(modules, m); - - m->prerequisites_names = link->prerequisites; - m->prerequisites = g_ptr_array_new(); - m->info.name = link->name; - m->info.short_description = link->short_description; - m->info.description = link->description; - m->info.init = link->init; - m->info.destroy = link->destroy; - m->info.library = l; - m->info.require_count = 0; - m->info.use_count = 0; - m->info.prerequisites_number = link->prerequisites_number; - } - return l; -} - - -static void library_remove(LttvLibrary *l) -{ - LttvModule *m; - - GPtrArray *modules; - - guint i; - - char *key; - - for(i = 0 ; i < l->modules->len ; i++) { - m = (LttvModule *)(l->modules->pdata[i]); - - g_hash_table_lookup_extended(modules_by_name, m->info.name, - (gpointer *)&key, (gpointer *)&modules); - g_assert(modules != NULL); - g_ptr_array_remove(modules, m); - if(modules->len == 0) { - g_hash_table_remove(modules_by_name, m->info.name); - g_ptr_array_free(modules, TRUE); - g_free(key); - } - - g_ptr_array_free(m->prerequisites, TRUE); - g_free(m); - } - - g_ptr_array_remove(libraries, l); - g_hash_table_remove(libraries_by_g_module, l->gm); - g_ptr_array_free(l->modules, TRUE); - g_free(l->info.name); - g_free(l->info.path); - g_free(l); -} - - -static LttvLibrary *library_load(char *name, GError **error) -{ - GModule *gm; - - int i, nb; - - char *path, *pathname; - - LttvLibrary *l; - - GString *messages = g_string_new(""); - - /* insure that module.c is initialized */ - - init(); - - /* Try to find the library along all the user specified paths */ - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Load library %s", name); - nb = lttv_library_path_number(); - for(i = 0 ; i <= nb ; i++) { - if(i < nb) path = lttv_library_path_get(i); - else path = NULL; - - pathname = g_module_build_path(path ,name); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Try path %s", pathname); - module_chain = NULL; - module_next = &module_chain; - gm = g_module_open(pathname,0); - g_free(pathname); - - if(gm != NULL) break; - - g_string_append(messages, g_module_error()); - g_string_append(messages, "\n"); - g_log(G_LOG_DOMAIN,G_LOG_LEVEL_INFO,"Trial failed, %s", g_module_error()); - } - - /* Module cannot be found */ - - if(gm == NULL) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Failed to load %s", name); - g_set_error(error, lttv_module_error, LTTV_MODULE_NOT_FOUND, - "Cannot load library %s: %s", name, messages->str); - g_string_free(messages, TRUE); - return NULL; - } - g_string_free(messages, TRUE); - - /* Check if the library was already loaded */ - - l = g_hash_table_lookup(libraries_by_g_module, gm); - - /* This library was not already loaded */ - - if(l == NULL) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Library %s (%s) loaded", name, - g_module_name(gm)); - l = library_add(name, path, gm); - } - return l; -} - - -LttvLibrary *lttv_library_load(char *name, GError **error) -{ - LttvLibrary *l = library_load(name, error); - l->info.load_count++; - return l; -} - - -static void library_unload(LttvLibrary *l) -{ - guint i, len; - - GModule *gm; - - LttvModule *m; - - if(l->locked_loaded > 0) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Unload library %s: locked loaded", - l->info.name); - return; - } - - if(l->info.load_count > 0) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Unload library %s: load count %d", - l->info.name, l->info.load_count); - return; - } - - /* Check if all its modules have been released */ - - for(i = 0 ; i < l->modules->len ; i++) { - m = (LttvModule *)(l->modules->pdata[i]); - if(m->info.use_count > 0) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO,"Unload library %s: module %s used", - l->info.name, m->info.name); - return; - } - } - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Unload library %s: close the GModule", - l->info.name); - gm = l->gm; - library_remove(l); - if(gm != NULL) g_module_close(gm); - - /* insure that module.c will be finalized */ - - finish_destroy(); -} - - -void lttv_library_unload(LttvLibrary *l) -{ - l->info.load_count--; - library_unload(l); -} - - -static void library_lock_loaded(LttvLibrary *l) -{ - l->locked_loaded++; -} - - -static void library_unlock_loaded(LttvLibrary *l) -{ - l->locked_loaded--; - library_unload(l); -} - - -static LttvModule *module_require(char *name, GError **error) -{ - GError *tmp_error = NULL; - - guint i, j; - - LttvModule *m, *required; - - LttvLibrary *l = NULL; - - GPtrArray *modules; - - /* Insure that module.c is initialized */ - - init(); - - /* Check if the module is already loaded */ - - modules = g_hash_table_lookup(modules_by_name, name); - - /* Try to load a library having the module name */ - - if(modules == NULL) { - l = library_load(name, error); - if(l == NULL) return NULL; - else library_lock_loaded(l); - - /* A library was found, does it contain the named module */ - - modules = g_hash_table_lookup(modules_by_name, name); - if(modules == NULL) { - g_set_error(error, lttv_module_error, LTTV_MODULE_NOT_FOUND, - "Module %s not found in library %s", name, l->info.name); - library_unlock_loaded(l); - return NULL; - } - } - m = (LttvModule *)(modules->pdata[modules->len - 1]); - - /* We have the module */ - - m->info.use_count++; - - /* First use of the module. Initialize after getting the prerequisites */ - - if(m->info.use_count == 1) { - for(i = 0 ; i < m->info.prerequisites_number ; i++) { - required = module_require(m->prerequisites_names[i], &tmp_error); - - /* A prerequisite could not be found, undo everything and fail */ - - if(required == NULL) { - for(j = 0 ; j < m->prerequisites->len ; j++) { - module_release((LttvModule *)(m->prerequisites->pdata[j])); - } - g_ptr_array_set_size(m->prerequisites, 0); - if(l != NULL) library_unlock_loaded(l); - g_set_error(error, lttv_module_error, LTTV_MODULE_NOT_FOUND, - "Cannot find prerequisite for module %s: %s", name, - tmp_error->message); - g_clear_error(&tmp_error); - return NULL; - } - g_ptr_array_add(m->prerequisites, required); - } - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Module %s: init()", m->info.name); - m->info.init(); - } - - /* Decrement the load count of the library. It will not really be - unloaded since it contains a currently used module. */ - - if(l != NULL) library_unlock_loaded(l); - - return(m); -} - - -/* The require_count for a module is the number of explicit calls to - lttv_module_require, while the use_count also counts the number of times - a module is needed as a prerequisite. */ - -LttvModule *lttv_module_require(char *name, GError **error) -{ - LttvModule *m = module_require(name, error); - if(m != NULL) m->info.require_count++; - return(m); -} - - -static void module_release(LttvModule *m) -{ - guint i; - - library_lock_loaded(m->info.library); - - m->info.use_count--; - if(m->info.use_count == 0) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Module %s: destroy()",m->info.name); - m->info.destroy(); - for(i = 0 ; i < m->prerequisites->len ; i++) { - module_release((LttvModule *)(m->prerequisites->pdata[i])); - } - g_ptr_array_set_size(m->prerequisites, 0); - } - library_unlock_loaded(m->info.library); -} - - -void lttv_module_release(LttvModule *m) -{ - m->info.require_count--; - module_release(m); -} - - -void lttv_module_info(LttvModule *m, LttvModuleInfo *info) -{ - *info = m->info; -} - - -unsigned lttv_module_prerequisite_number(LttvModule *m) -{ - return m->prerequisites->len; -} - - -LttvModule *lttv_module_prerequisite_get(LttvModule *m, unsigned i) -{ - return (LttvModule *)(m->prerequisites->pdata[i]); -} - - -void lttv_library_info(LttvLibrary *l, LttvLibraryInfo *info) -{ - *info = l->info; -} - - -unsigned lttv_library_module_number(LttvLibrary *l) -{ - return l->modules->len; -} - - -LttvModule *lttv_library_module_get(LttvLibrary *l, unsigned i) -{ - return (LttvModule *)(l->modules->pdata[i]); -} - - -unsigned lttv_library_number() -{ - return libraries->len; -} - - -LttvLibrary *lttv_library_get(unsigned i) -{ - return (LttvLibrary *)(libraries->pdata[i]); -} - - -void lttv_library_path_add(char *name) -{ - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Add library path %s", name); - g_ptr_array_add(library_paths,(char*)g_strdup(name)); -} - - -void lttv_library_path_remove(char *name) -{ - guint i; - - for(i = 0 ; i < library_paths->len ; i++) { - if(g_str_equal(name, library_paths->pdata[i])) { - g_free(library_paths->pdata[i]); - g_ptr_array_remove_index(library_paths,i); - return; - } - } -} - - -unsigned lttv_library_path_number() -{ - return library_paths->len; -} - - -char *lttv_library_path_get(unsigned i) -{ - return (char *)(library_paths->pdata[library_paths->len - i - 1]); -} - - -void lttv_module_register(struct _LttvModuleDescription *d) -{ - *module_next = d; - module_next = &(d->next); -} - - -static void init() -{ - if(initialized) return; - g_assert(destroyed); - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Init module.c"); - - initialized = TRUE; - destroyed = FALSE; - lttv_module_error = g_quark_from_string("LTTV_MODULE_ERROR"); - modules_by_name = g_hash_table_new(g_str_hash, g_str_equal); - libraries = g_ptr_array_new(); - libraries_by_g_module = g_hash_table_new(g_direct_hash, g_direct_equal); - library_paths = g_ptr_array_new(); - - if(builtin_chain == NULL) builtin_chain = module_chain; - module_chain = builtin_chain; - library_add("builtin", NULL, NULL); -} - - -static finish_destroy() -{ - guint i; - - if(initialized) return; - g_assert(!destroyed); - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Finish destroy module.c"); - g_hash_table_destroy(modules_by_name); - g_ptr_array_free(libraries, TRUE); - g_hash_table_destroy(libraries_by_g_module); - for(i = 0 ; i < library_paths->len ; i++) { - g_free(library_paths->pdata[i]); - } - g_ptr_array_free(library_paths, TRUE); - destroyed = TRUE; -} - - -static void destroy() -{ - guint i, j, nb; - - LttvLibrary *l, **locked_libraries; - - LttvModule *m; - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Destroy module.c"); - - /* Unload all libraries */ - - nb = libraries->len; - locked_libraries = g_new(LttvLibrary *, nb); - - for(i = 0 ; i < nb ; i++) { - l = (LttvLibrary *)(libraries->pdata[i]); - locked_libraries[i] = l; - library_lock_loaded(l); - for(j = 0 ; j < l->modules->len ; j++) { - m = (LttvModule *)(l->modules->pdata[j]); - while(m->info.require_count > 0) lttv_module_release(m); - } - while(l->info.load_count > 0) lttv_library_unload(l); - } - - for(i = 0 ; i < nb ; i++) { - l = locked_libraries[i]; - library_unlock_loaded(l); - } - g_free(locked_libraries); - - /* The library containing module.c may be locked by our caller */ - - g_assert(libraries->len <= 1); - - initialized = FALSE; -} - -LTTV_MODULE("module", "Modules in libraries", \ - "Load libraries, list, require and initialize contained modules", \ - init, destroy) - diff --git a/ltt/branches/poly/lttv/main/option.c b/ltt/branches/poly/lttv/main/option.c deleted file mode 100644 index 7532073e..00000000 --- a/ltt/branches/poly/lttv/main/option.c +++ /dev/null @@ -1,287 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - - -#include -#include -#include -#include - -typedef struct _LttvOption { - char *long_name; - char char_name; - char *description; - char *arg_description; - LttvOptionType t; - gpointer p; - LttvOptionHook hook; - gpointer hook_data; -} LttvOption; - -GHashTable *options; - - -static void -list_options(gpointer key, gpointer value, gpointer user_data) -{ - g_ptr_array_add((GPtrArray *)user_data, value); -} - - -static void -free_option(LttvOption *option) -{ - g_free(option->long_name); - g_free(option->description); - g_free(option->arg_description); - g_free(option); -} - - -void lttv_option_add(const char *long_name, const char char_name, - const char *description, const char *arg_description, - const LttvOptionType t, void *p, - const LttvOptionHook h, void *hook_data) -{ - LttvOption *option; - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Add option %s", long_name); - if(g_hash_table_lookup(options, long_name) != NULL) { - g_warning("duplicate option"); - return; - } - - option = g_new(LttvOption, 1); - option->long_name = g_strdup(long_name); - option->char_name = char_name; - option->description = g_strdup(description); - option->arg_description = g_strdup(arg_description); - option->t = t; - option->p = p; - option->hook = h; - option->hook_data = hook_data; - g_hash_table_insert(options, option->long_name, option); -} - - -void -lttv_option_remove(const char *long_name) -{ - LttvOption *option = g_hash_table_lookup(options, long_name); - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Remove option %s", long_name); - if(option == NULL) { - g_warning("trying to remove unknown option %s", long_name); - return; - } - g_hash_table_remove(options, long_name); - free_option(option); -} - - -static int poptToLTT[] = { - POPT_ARG_NONE, POPT_ARG_STRING, POPT_ARG_INT, POPT_ARG_LONG -}; - -static struct poptOption endOption = { NULL, '\0', 0, NULL, 0}; - - -static void -build_popts(GPtrArray **plist, struct poptOption **ppopts, poptContext *pc, - int argc, char **argv) -{ - LttvOption *option; - - GPtrArray *list; - - struct poptOption *popts; - - poptContext c; - - guint i; - - list = g_ptr_array_new(); - - g_hash_table_foreach(options, list_options, list); - - /* Build a popt options array from our list */ - - popts = g_new(struct poptOption, list->len + 1); - - for(i = 0 ; i < list->len ; i++) { - option = (LttvOption *)list->pdata[i]; - popts[i].longName = option->long_name; - popts[i].shortName = option->char_name; - popts[i].descrip = option->description; - popts[i].argDescrip = option->arg_description; - popts[i].argInfo = poptToLTT[option->t]; - popts[i].arg = option->p; - popts[i].val = i + 1; - } - - /* Terminate the array for popt and create the context */ - - popts[list->len] = endOption; - c = poptGetContext(argv[0], argc, (const char**)argv, popts, 0); - - *plist = list; - *ppopts = popts; - *pc = c; -} - - -static void -destroy_popts(GPtrArray **plist, struct poptOption **ppopts, poptContext *pc) -{ - g_ptr_array_free(*plist, TRUE); *plist = NULL; - g_free(*ppopts); *ppopts = NULL; - poptFreeContext(*pc); -} - - -void lttv_option_parse(int argc, char **argv) -{ - GPtrArray *list; - - LttvOption *option; - - int i, rc, first_arg; - - struct poptOption *popts; - - poptContext c; - - i = 0; - - first_arg = 0; - - build_popts(&list, &popts, &c, argc, argv); - - /* Parse options while not end of options event */ - - while((rc = poptGetNextOpt(c)) != -1) { - - /* The option was recognized and the rc value returned is the argument - position in the array. Call the associated hook if present. */ - - if(rc > 0) { - option = (LttvOption *)(list->pdata[rc - 1]); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Option %s encountered", - option->long_name); - if(option->hook != NULL) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s hook called", - option->long_name); - option->hook(option->hook_data); - } - i++; - } - - else if(rc == POPT_ERROR_BADOPT && i != first_arg) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, - "Option %s not recognized, rescan options with new additions", - poptBadOption(c,0)); - - /* Perhaps this option is newly added, restart parsing */ - - destroy_popts(&list, &popts, &c); - build_popts(&list, &popts, &c, argc, argv); - - /* Get back to the same argument */ - - first_arg = i; - for(i = 0; i < first_arg; i++) { - rc = poptGetNextOpt(c); - option = (LttvOption *)(list->pdata[rc - 1]); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s rescanned, skipped", - option->long_name); - } - } - - else { - - /* The option has some error and it is not because this is a newly - added option not recognized. */ - - g_error("option %s: %s", poptBadOption(c,0), poptStrerror(rc)); - break; - } - - } - - destroy_popts(&list, &popts, &c); -} - -/* CHECK */ -static void show_help(LttvOption *option) -{ - printf("--%s -%c argument: %s\n" , option->long_name, - option->char_name, - option->arg_description); - printf(" %s\n" , option->description); - -} - -void lttv_option_show_help(void) -{ - LttvOption option; - - GPtrArray *list = g_ptr_array_new(); - - int i; - - g_hash_table_foreach(options, list_options, list); - - printf("Built-in commands available:\n"); - printf("\n"); - - for(i = 0 ; i < list->len ; i++) { - show_help((LttvOption *)list->pdata[i]); - } - g_ptr_array_free(list, TRUE); - - -} - -static void init() -{ - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Init option.c"); - options = g_hash_table_new(g_str_hash, g_str_equal); -} - - -static void destroy() -{ - LttvOption option; - - GPtrArray *list = g_ptr_array_new(); - - int i; - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Destroy option.c"); - g_hash_table_foreach(options, list_options, list); - g_hash_table_destroy(options); - - for(i = 0 ; i < list->len ; i++) { - free_option((LttvOption *)list->pdata[i]); - } - g_ptr_array_free(list, TRUE); -} - -LTTV_MODULE("option", "Command line options processing", \ - "Functions to add, remove and parse command line options", \ - init, destroy) diff --git a/ltt/branches/poly/lttv/main/processTrace.c b/ltt/branches/poly/lttv/main/processTrace.c deleted file mode 100644 index cb50c0a3..00000000 --- a/ltt/branches/poly/lttv/main/processTrace.c +++ /dev/null @@ -1,840 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - - -#include -#include -#include -#include -#include - -void lttv_context_init(LttvTracesetContext *self, LttvTraceset *ts) -{ - LTTV_TRACESET_CONTEXT_GET_CLASS(self)->init(self, ts); -} - - -void lttv_context_fini(LttvTracesetContext *self) -{ - LTTV_TRACESET_CONTEXT_GET_CLASS(self)->fini(self); -} - - -LttvTracesetContext * -lttv_context_new_traceset_context(LttvTracesetContext *self) -{ - return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_traceset_context(self); -} - - - - -LttvTraceContext * -lttv_context_new_trace_context(LttvTracesetContext *self) -{ - return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self); -} - - -LttvTracefileContext * -lttv_context_new_tracefile_context(LttvTracesetContext *self) -{ - return LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self); -} - -/**************************************************************************** - * lttv_traceset_context_compute_time_span - * - * Keep the Time_Span is sync with on the fly addition and removal of traces - * in a trace set. It must be called each time a trace is added/removed from - * the traceset. It could be more efficient to call it only once a bunch - * of traces are loaded, but the calculation is not long, so it's not - * critical. - * - * Author : Xang Xiu Yang - * Imported from gtkTraceSet.c by Mathieu Desnoyers - ***************************************************************************/ -static void lttv_traceset_context_compute_time_span( - LttvTracesetContext *self, - TimeInterval *Time_Span) -{ - LttvTraceset * traceset = self->ts; - int numTraces = lttv_traceset_number(traceset); - int i; - LttTime s, e; - LttvTraceContext *tc; - LttTrace * trace; - - Time_Span->startTime.tv_sec = 0; - Time_Span->startTime.tv_nsec = 0; - Time_Span->endTime.tv_sec = 0; - Time_Span->endTime.tv_nsec = 0; - - for(i=0; itraces[i]; - trace = tc->t; - - ltt_trace_time_span_get(trace, &s, &e); - - if(i==0){ - Time_Span->startTime = s; - Time_Span->endTime = e; - }else{ - if(s.tv_sec < Time_Span->startTime.tv_sec || - (s.tv_sec == Time_Span->startTime.tv_sec - && s.tv_nsec < Time_Span->startTime.tv_nsec)) - Time_Span->startTime = s; - if(e.tv_sec > Time_Span->endTime.tv_sec || - (e.tv_sec == Time_Span->endTime.tv_sec && - e.tv_nsec > Time_Span->endTime.tv_nsec)) - Time_Span->endTime = e; - } - } -} - - -static void -init(LttvTracesetContext *self, LttvTraceset *ts) -{ - guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile; - - LttvTraceContext *tc; - - LttvTracefileContext *tfc; - - LttTime null_time = {0, 0}; - - nb_trace = lttv_traceset_number(ts); - self->ts = ts; - self->traces = g_new(LttvTraceContext *, nb_trace); - self->before = lttv_hooks_new(); - self->after = lttv_hooks_new(); - self->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); - self->ts_a = lttv_traceset_attribute(ts); - for(i = 0 ; i < nb_trace ; i++) { - tc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_trace_context(self); - self->traces[i] = tc; - - tc->ts_context = self; - tc->index = i; - tc->vt = lttv_traceset_get(ts, i); - tc->t = lttv_trace(tc->vt); - tc->check = lttv_hooks_new(); - tc->before = lttv_hooks_new(); - tc->after = lttv_hooks_new(); - tc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); - tc->t_a = lttv_trace_attribute(tc->vt); - nb_control = ltt_trace_control_tracefile_number(tc->t); - nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t); - nb_tracefile = nb_control + nb_per_cpu; - tc->tracefiles = g_new(LttvTracefileContext *, nb_tracefile); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfc = LTTV_TRACESET_CONTEXT_GET_CLASS(self)->new_tracefile_context(self); - tc->tracefiles[j] = tfc; - tfc->index = j; - - if(j < nb_control) { - tfc->control = TRUE; - tfc->tf = ltt_trace_control_tracefile_get(tc->t, j); - } - else { - tfc->control = FALSE; - tfc->tf = ltt_trace_per_cpu_tracefile_get(tc->t, j - nb_control); - } - tfc->t_context = tc; - tfc->check = lttv_hooks_new(); - tfc->before = lttv_hooks_new(); - tfc->after = lttv_hooks_new(); - tfc->check_event = lttv_hooks_new(); - tfc->before_event = lttv_hooks_new(); - tfc->before_event_by_id = lttv_hooks_by_id_new(); - tfc->after_event = lttv_hooks_new(); - tfc->after_event_by_id = lttv_hooks_by_id_new(); - tfc->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); - } - } - lttv_process_traceset_seek_time(self, null_time); - /*CHECK why dynamically allocate the time span... and the casing is wroNg*/ - self->Time_Span = g_new(TimeInterval,1); - lttv_traceset_context_compute_time_span(self, self->Time_Span); -} - - -void fini(LttvTracesetContext *self) -{ - guint i, j, nb_trace, nb_tracefile; - - LttvTraceContext *tc; - - LttvTracefileContext *tfc; - - LttvTraceset *ts = self->ts; - - g_free(self->Time_Span); - - lttv_hooks_destroy(self->before); - lttv_hooks_destroy(self->after); - //FIXME : segfault - g_object_unref(self->a); - - nb_trace = lttv_traceset_number(ts); - - for(i = 0 ; i < nb_trace ; i++) { - tc = self->traces[i]; - - lttv_hooks_destroy(tc->check); - lttv_hooks_destroy(tc->before); - lttv_hooks_destroy(tc->after); - g_object_unref(tc->a); - - nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + - ltt_trace_per_cpu_tracefile_number(tc->t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfc = tc->tracefiles[j]; - lttv_hooks_destroy(tfc->check); - lttv_hooks_destroy(tfc->before); - lttv_hooks_destroy(tfc->after); - lttv_hooks_destroy(tfc->check_event); - lttv_hooks_destroy(tfc->before_event); - lttv_hooks_by_id_destroy(tfc->before_event_by_id); - lttv_hooks_destroy(tfc->after_event); - lttv_hooks_by_id_destroy(tfc->after_event_by_id); - g_object_unref(tfc->a); - g_object_unref(tfc); - } - g_free(tc->tracefiles); - g_object_unref(tc); - } - g_free(self->traces); -} - - -void lttv_traceset_context_add_hooks(LttvTracesetContext *self, - LttvHooks *before_traceset, - LttvHooks *after_traceset, - LttvHooks *check_trace, - LttvHooks *before_trace, - LttvHooks *after_trace, - LttvHooks *check_tracefile, - LttvHooks *before_tracefile, - LttvHooks *after_tracefile, - LttvHooks *check_event, - LttvHooks *before_event, - LttvHooks *after_event) -{ - LttvTraceset *ts = self->ts; - - guint i, j, nb_trace, nb_tracefile; - - LttvTraceContext *tc; - - LttvTracefileContext *tfc; - - void *hook_data; - - lttv_hooks_add_list(self->before, before_traceset); - lttv_hooks_add_list(self->after, after_traceset); - nb_trace = lttv_traceset_number(ts); - - for(i = 0 ; i < nb_trace ; i++) { - tc = self->traces[i]; - lttv_hooks_add_list(tc->check, check_trace); - lttv_hooks_add_list(tc->before, before_trace); - lttv_hooks_add_list(tc->after, after_trace); - nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + - ltt_trace_per_cpu_tracefile_number(tc->t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfc = tc->tracefiles[j]; - lttv_hooks_add_list(tfc->check, check_tracefile); - lttv_hooks_add_list(tfc->before, before_tracefile); - lttv_hooks_add_list(tfc->after, after_tracefile); - lttv_hooks_add_list(tfc->check_event, check_event); - lttv_hooks_add_list(tfc->before_event, before_event); - lttv_hooks_add_list(tfc->after_event, after_event); - } - } -} - - -void lttv_traceset_context_remove_hooks(LttvTracesetContext *self, - LttvHooks *before_traceset, - LttvHooks *after_traceset, - LttvHooks *check_trace, - LttvHooks *before_trace, - LttvHooks *after_trace, - LttvHooks *check_tracefile, - LttvHooks *before_tracefile, - LttvHooks *after_tracefile, - LttvHooks *check_event, - LttvHooks *before_event, - LttvHooks *after_event) -{ - LttvTraceset *ts = self->ts; - - guint i, j, nb_trace, nb_tracefile; - - LttvTraceContext *tc; - - LttvTracefileContext *tfc; - - void *hook_data; - - lttv_hooks_remove_list(self->before, before_traceset); - lttv_hooks_remove_list(self->after, after_traceset); - nb_trace = lttv_traceset_number(ts); - - for(i = 0 ; i < nb_trace ; i++) { - tc = self->traces[i]; - lttv_hooks_remove_list(tc->check, check_trace); - lttv_hooks_remove_list(tc->before, before_trace); - lttv_hooks_remove_list(tc->after, after_trace); - nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + - ltt_trace_per_cpu_tracefile_number(tc->t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfc = tc->tracefiles[j]; - lttv_hooks_remove_list(tfc->check, check_tracefile); - lttv_hooks_remove_list(tfc->before, before_tracefile); - lttv_hooks_remove_list(tfc->after, after_tracefile); - lttv_hooks_remove_list(tfc->check_event, check_event); - lttv_hooks_remove_list(tfc->before_event, before_event); - lttv_hooks_remove_list(tfc->after_event, after_event); - } - } -} - -void lttv_trace_context_add_hooks(LttvTraceContext *tc, - LttvHooks *check_trace, - LttvHooks *before_trace, - LttvHooks *after_trace) -{ - lttv_hooks_add_list(tc->check, check_trace); - lttv_hooks_add_list(tc->before, before_trace); - lttv_hooks_add_list(tc->after, after_trace); -} - -void lttv_trace_context_remove_hooks(LttvTraceContext *tc, - LttvHooks *check_trace, - LttvHooks *before_trace, - LttvHooks *after_trace) -{ - lttv_hooks_remove_list(tc->check, check_trace); - lttv_hooks_remove_list(tc->before, before_trace); - lttv_hooks_remove_list(tc->after, after_trace); -} - -void lttv_tracefile_context_add_hooks(LttvTracefileContext *tfc, - LttvHooks *check_tracefile, - LttvHooks *before_tracefile, - LttvHooks *after_tracefile, - LttvHooks *check_event, - LttvHooks *before_event, - LttvHooks *after_event) -{ - lttv_hooks_add_list(tfc->check, check_tracefile); - lttv_hooks_add_list(tfc->before, before_tracefile); - lttv_hooks_add_list(tfc->after, after_tracefile); - lttv_hooks_add_list(tfc->check_event, check_event); - lttv_hooks_add_list(tfc->before_event, before_event); - lttv_hooks_add_list(tfc->after_event, after_event); -} - -void lttv_tracefile_context_remove_hooks(LttvTracefileContext *tfc, - LttvHooks *check_tracefile, - LttvHooks *before_tracefile, - LttvHooks *after_tracefile, - LttvHooks *check_event, - LttvHooks *before_event, - LttvHooks *after_event) -{ - lttv_hooks_remove_list(tfc->check, check_tracefile); - lttv_hooks_remove_list(tfc->before, before_tracefile); - lttv_hooks_remove_list(tfc->after, after_tracefile); - lttv_hooks_remove_list(tfc->check_event, check_event); - lttv_hooks_remove_list(tfc->before_event, before_event); - lttv_hooks_remove_list(tfc->after_event, after_event); -} - -void lttv_tracefile_context_add_hooks_by_id(LttvTracefileContext *tfc, - unsigned i, - LttvHooks *before_event_by_id, - LttvHooks *after_event_by_id) -{ - LttvHooks * h; - h = lttv_hooks_by_id_find(tfc->before_event_by_id, i); - lttv_hooks_add_list(h, before_event_by_id); - h = lttv_hooks_by_id_find(tfc->after_event_by_id, i); - lttv_hooks_add_list(h, after_event_by_id); -} - -void lttv_tracefile_context_remove_hooks_by_id(LttvTracefileContext *tfc, - unsigned i) -{ - lttv_hooks_by_id_remove(tfc->before_event_by_id, i); - lttv_hooks_by_id_remove(tfc->after_event_by_id, i); -} - -static LttvTracesetContext * -new_traceset_context(LttvTracesetContext *self) -{ - return g_object_new(LTTV_TRACESET_CONTEXT_TYPE, NULL); -} - - -static LttvTraceContext * -new_trace_context(LttvTracesetContext *self) -{ - return g_object_new(LTTV_TRACE_CONTEXT_TYPE, NULL); -} - - -static LttvTracefileContext * -new_tracefile_context(LttvTracesetContext *self) -{ - return g_object_new(LTTV_TRACEFILE_CONTEXT_TYPE, NULL); -} - - -static void -traceset_context_instance_init (GTypeInstance *instance, gpointer g_class) -{ - /* Be careful of anything which would not work well with shallow copies */ -} - - -static void -traceset_context_finalize (LttvTracesetContext *self) -{ - G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACESET_CONTEXT_TYPE))) - ->finalize(G_OBJECT(self)); -} - - -static void -traceset_context_class_init (LttvTracesetContextClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->finalize = (void (*)(GObject *self))traceset_context_finalize; - klass->init = init; - klass->fini = fini; - klass->new_traceset_context = new_traceset_context; - klass->new_trace_context = new_trace_context; - klass->new_tracefile_context = new_tracefile_context; -} - - -GType -lttv_traceset_context_get_type(void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (LttvTracesetContextClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) traceset_context_class_init, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (LttvTracesetContext), - 0, /* n_preallocs */ - (GInstanceInitFunc) traceset_context_instance_init /* instance_init */ - }; - - type = g_type_register_static (G_TYPE_OBJECT, "LttvTracesetContextType", - &info, 0); - } - return type; -} - - -static void -trace_context_instance_init (GTypeInstance *instance, gpointer g_class) -{ - /* Be careful of anything which would not work well with shallow copies */ -} - - -static void -trace_context_finalize (LttvTraceContext *self) -{ - G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACE_CONTEXT_TYPE)))-> - finalize(G_OBJECT(self)); -} - - -static void -trace_context_class_init (LttvTraceContextClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->finalize = (void (*)(GObject *self)) trace_context_finalize; -} - - -GType -lttv_trace_context_get_type(void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (LttvTraceContextClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) trace_context_class_init, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (LttvTraceContext), - 0, /* n_preallocs */ - (GInstanceInitFunc) trace_context_instance_init /* instance_init */ - }; - - type = g_type_register_static (G_TYPE_OBJECT, "LttvTraceContextType", - &info, 0); - } - return type; -} - - -static void -tracefile_context_instance_init (GTypeInstance *instance, gpointer g_class) -{ - /* Be careful of anything which would not work well with shallow copies */ -} - - -static void -tracefile_context_finalize (LttvTracefileContext *self) -{ - G_OBJECT_CLASS(g_type_class_peek(g_type_parent(LTTV_TRACEFILE_CONTEXT_TYPE))) - ->finalize(G_OBJECT(self)); -} - - -static void -tracefile_context_class_init (LttvTracefileContextClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->finalize = (void (*)(GObject *self))tracefile_context_finalize; -} - - -GType -lttv_tracefile_context_get_type(void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (LttvTracefileContextClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) tracefile_context_class_init, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (LttvTracefileContext), - 0, /* n_preallocs */ - (GInstanceInitFunc) tracefile_context_instance_init /* instance_init */ - }; - - type = g_type_register_static (G_TYPE_OBJECT, "LttvTracefileContextType", - &info, 0); - } - return type; -} - - -gint compare_tracefile(gconstpointer a, gconstpointer b) -{ - gint comparison; - - LttvTracefileContext *trace_a = (LttvTracefileContext *)a; - - LttvTracefileContext *trace_b = (LttvTracefileContext *)b; - - if(trace_a == trace_b) return 0; - comparison = ltt_time_compare(trace_a->timestamp, trace_b->timestamp); - if(comparison != 0) return comparison; - if(trace_a->index < trace_b->index) return -1; - else if(trace_a->index > trace_b->index) return 1; - if(trace_a->t_context->index < trace_b->t_context->index) return -1; - else if(trace_a->t_context->index > trace_b->t_context->index) return 1; - g_assert(FALSE); -} - - -gboolean get_first(gpointer key, gpointer value, gpointer user_data) { - *((LttvTracefileContext **)user_data) = (LttvTracefileContext *)value; - return TRUE; -} - - -void lttv_process_traceset_begin(LttvTracesetContext *self, LttTime end) -{ - guint i, j, nbi, nb_tracefile; - - LttvTraceContext *tc; - - LttvTracefileContext *tfc; - - /* Call all before_traceset, before_trace, and before_tracefile hooks. - For all qualifying tracefiles, seek to the start time, create a context, - read one event and insert in the pqueue based on the event time. */ - - lttv_hooks_call(self->before, self); - nbi = lttv_traceset_number(self->ts); - self->pqueue = g_tree_new(compare_tracefile); - - for(i = 0 ; i < nbi ; i++) { - tc = self->traces[i]; - - if(!lttv_hooks_call_check(tc->check, tc)) { - lttv_hooks_call(tc->before, tc); - nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + - ltt_trace_per_cpu_tracefile_number(tc->t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfc = tc->tracefiles[j]; - - if(!lttv_hooks_call_check(tfc->check, tfc)) { - lttv_hooks_call(tfc->before, tfc); - - if(tfc->e != NULL) { - if(tfc->timestamp.tv_sec < end.tv_sec || - (tfc->timestamp.tv_sec == end.tv_sec && - tfc->timestamp.tv_nsec <= end.tv_nsec)) { - g_tree_insert(self->pqueue, tfc, tfc); - } - } - } - } - } - } -} - - -guint lttv_process_traceset_middle(LttvTracesetContext *self, LttTime end, - unsigned nb_events) -{ - GTree *pqueue = self->pqueue; - - guint id; - - LttvTraceContext *tc; - - LttvTracefileContext *tfc; - - LttEvent *event; - - unsigned count = 0; - - LttTime previous_timestamp = {0, 0}; - - /* Get the next event from the pqueue, call its hooks, - reinsert in the pqueue the following event from the same tracefile - unless the tracefile is finished or the event is later than the - start time. */ - - while(TRUE) { - tfc = NULL; - g_tree_foreach(pqueue, get_first, &tfc); - if(tfc == NULL) return count; - - /* Have we reached the maximum number of events specified? However, - continue for all the events with the same time stamp (CHECK?). Then, - empty the queue and break from the loop. */ - - if(count >= nb_events && - ltt_time_compare(tfc->timestamp, previous_timestamp) != 0) - return count; - - previous_timestamp = tfc->timestamp; - - - /* Get the tracefile with an event for the smallest time found. If two - or more tracefiles have events for the same time, hope that lookup - and remove are consistent. */ - - g_tree_remove(pqueue, tfc); - count++; - - if(!lttv_hooks_call(tfc->check_event, tfc)) { - id = ltt_event_eventtype_id(tfc->e); - lttv_hooks_call(lttv_hooks_by_id_get(tfc->before_event_by_id, id), tfc); - lttv_hooks_call(tfc->before_event, tfc); - lttv_hooks_call(lttv_hooks_by_id_get(tfc->after_event_by_id, id), tfc); - lttv_hooks_call(tfc->after_event, tfc); - } - - event = ltt_tracefile_read(tfc->tf); - if(event != NULL) { - tfc->e = event; - tfc->timestamp = ltt_event_time(event); - if(tfc->timestamp.tv_sec < end.tv_sec || - (tfc->timestamp.tv_sec == end.tv_sec && tfc->timestamp.tv_nsec <= end.tv_nsec)) - g_tree_insert(pqueue, tfc, tfc); - } - } -} - - -void lttv_process_traceset_end(LttvTracesetContext *self) -{ - guint i, j, nbi, nb_tracefile; - - LttvTraceContext *tc; - - LttvTracefileContext *tfc; - - /* Call all after_traceset, after_trace, and after_tracefile hooks. */ - - nbi = lttv_traceset_number(self->ts); - - for(i = 0 ; i < nbi ; i++) { - tc = self->traces[i]; - - /* The check hooks are called again to avoid memorizing the results - obtained at the beginning. CHECK if it poses a problem */ - - if(!lttv_hooks_call_check(tc->check, tc)) { - nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + - ltt_trace_per_cpu_tracefile_number(tc->t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfc = tc->tracefiles[j]; - - if(!lttv_hooks_call_check(tfc->check, tfc)) { - lttv_hooks_call(tfc->after, tfc); - } - } - lttv_hooks_call(tc->after, tc); - } - } - lttv_hooks_call(self->after, self); - - /* Empty and free the pqueue */ - - while(TRUE){ - tfc = NULL; - g_tree_foreach(self->pqueue, get_first, &tfc); - if(tfc == NULL) break; - g_tree_remove(self->pqueue, &(tfc->timestamp)); - } - g_tree_destroy(self->pqueue); -} - - -void lttv_process_traceset(LttvTracesetContext *self, LttTime end, - unsigned nb_events) -{ - lttv_process_traceset_begin(self, end); - lttv_process_traceset_middle(self, end, nb_events); - lttv_process_traceset_end(self); -} - - -void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start) -{ - guint i, nb_tracefile; - - LttvTracefileContext *tfc; - - LttEvent *event; - - nb_tracefile = ltt_trace_control_tracefile_number(self->t) + - ltt_trace_per_cpu_tracefile_number(self->t); - - for(i = 0 ; i < nb_tracefile ; i++) { - tfc = self->tracefiles[i]; - ltt_tracefile_seek_time(tfc->tf, start); - event = ltt_tracefile_read(tfc->tf); - tfc->e = event; - if(event != NULL) tfc->timestamp = ltt_event_time(event); - } -} - - -void lttv_process_traceset_seek_time(LttvTracesetContext *self, LttTime start) -{ - guint i, nb_trace; - - LttvTraceContext *tc; - - nb_trace = lttv_traceset_number(self->ts); - for(i = 0 ; i < nb_trace ; i++) { - tc = self->traces[i]; - lttv_process_trace_seek_time(tc, start); - } -} - - -static LttField * -find_field(LttEventType *et, const char *field) -{ - LttType *t; - - LttField *f; - - guint i, nb; - - char *name; - - if(field == NULL) return NULL; - - f = ltt_eventtype_field(et); - t = ltt_eventtype_type(et); - g_assert(ltt_type_class(t) == LTT_STRUCT); - nb = ltt_type_member_number(t); - for(i = 0 ; i < nb ; i++) { - ltt_type_member_type(t, i, &name); - if(strcmp(name, field) == 0) break; - } - g_assert(i < nb); - return ltt_field_member(f, i); -} - - -void -lttv_trace_find_hook(LttTrace *t, char *facility, char *event_type, - char *field1, char *field2, char *field3, LttvHook h, LttvTraceHook *th) -{ - LttFacility *f; - - LttEventType *et; - - guint nb, pos, i; - - char *name; - - nb = ltt_trace_facility_find(t, facility, &pos); - if(nb < 1) g_error("No %s facility", facility); - f = ltt_trace_facility_get(t, pos); - et = ltt_facility_eventtype_get_by_name(f, event_type); - if(et == NULL) g_error("Event %s does not exist", event_type); - - th->h = h; - th->id = ltt_eventtype_id(et); - th->f1 = find_field(et, field1); - th->f2 = find_field(et, field2); - th->f3 = find_field(et, field3); -} - - diff --git a/ltt/branches/poly/lttv/main/state.c b/ltt/branches/poly/lttv/main/state.c deleted file mode 100644 index 0624fe4b..00000000 --- a/ltt/branches/poly/lttv/main/state.c +++ /dev/null @@ -1,1527 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include - -LttvExecutionMode - LTTV_STATE_MODE_UNKNOWN, - LTTV_STATE_USER_MODE, - LTTV_STATE_SYSCALL, - LTTV_STATE_TRAP, - LTTV_STATE_IRQ; - -LttvExecutionSubmode - LTTV_STATE_SUBMODE_UNKNOWN, - LTTV_STATE_SUBMODE_NONE; - -LttvProcessStatus - LTTV_STATE_UNNAMED, - LTTV_STATE_WAIT_FORK, - LTTV_STATE_WAIT_CPU, - LTTV_STATE_EXIT, - LTTV_STATE_WAIT, - LTTV_STATE_RUN; - -static GQuark - LTTV_STATE_TRACEFILES, - LTTV_STATE_PROCESSES, - LTTV_STATE_PROCESS, - LTTV_STATE_EVENT, - LTTV_STATE_SAVED_STATES, - LTTV_STATE_SAVED_STATES_TIME, - LTTV_STATE_TIME, - LTTV_STATE_HOOKS, - LTTV_STATE_NAME_TABLES, - LTTV_STATE_TRACE_STATE_USE_COUNT; - - -static void create_max_time(LttvTraceState *tcs); - -static void get_max_time(LttvTraceState *tcs); - -static void free_max_time(LttvTraceState *tcs); - -static void create_name_tables(LttvTraceState *tcs); - -static void get_name_tables(LttvTraceState *tcs); - -static void free_name_tables(LttvTraceState *tcs); - -static void free_saved_state(LttvTraceState *tcs); - -static void lttv_state_free_process_table(GHashTable *processes); - - -void lttv_state_save(LttvTraceState *self, LttvAttribute *container) -{ - LTTV_TRACE_STATE_GET_CLASS(self)->state_save(self, container); -} - - -void lttv_state_restore(LttvTraceState *self, LttvAttribute *container) -{ - LTTV_TRACE_STATE_GET_CLASS(self)->state_restore(self, container); -} - - -void lttv_state__state_saved_free(LttvTraceState *self, - LttvAttribute *container) -{ - LTTV_TRACE_STATE_GET_CLASS(self)->state_saved_free(self, container); -} - - -guint process_hash(gconstpointer key) -{ - return ((LttvProcessState *)key)->pid; -} - - -gboolean process_equal(gconstpointer a, gconstpointer b) -{ - LttvProcessState *process_a, *process_b; - - process_a = (LttvProcessState *)a; - process_b = (LttvProcessState *)b; - - if(process_a->pid != process_b->pid) return FALSE; - if(process_a->pid == 0 && - process_a->last_cpu != process_b->last_cpu) return FALSE; - return TRUE; -} - - -static void -restore_init_state(LttvTraceState *self) -{ - guint i, nb_tracefile; - - LttvTracefileState *tfcs; - - LttTime null_time = {0,0}; - - if(self->processes != NULL) lttv_state_free_process_table(self->processes); - self->processes = g_hash_table_new(process_hash, process_equal); - self->nb_event = 0; - - nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) + - ltt_trace_per_cpu_tracefile_number(self->parent.t); - - for(i = 0 ; i < nb_tracefile ; i++) { - tfcs = LTTV_TRACEFILE_STATE(self->parent.tracefiles[i]); - tfcs->parent.timestamp = null_time; - tfcs->saved_position = 0; - tfcs->process = lttv_state_create_process(tfcs, NULL,0); - tfcs->process->state->s = LTTV_STATE_RUN; - tfcs->process->last_cpu = tfcs->cpu_name; - } -} - -static LttTime time_zero = {0,0}; - -static void -init(LttvTracesetState *self, LttvTraceset *ts) -{ - guint i, j, nb_trace, nb_tracefile; - - LttvTraceContext *tc; - - LttvTraceState *tcs; - - LttvTracefileState *tfcs; - - LttvAttributeValue v; - - LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))-> - init((LttvTracesetContext *)self, ts); - - nb_trace = lttv_traceset_number(ts); - for(i = 0 ; i < nb_trace ; i++) { - tc = self->parent.traces[i]; - tcs = (LttvTraceState *)tc; - tcs->save_interval = 50000; - lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_TRACE_STATE_USE_COUNT, - LTTV_UINT, &v); - (*v.v_uint)++; - - if(*(v.v_uint) == 1) { - create_name_tables(tcs); - create_max_time(tcs); - } - get_name_tables(tcs); - get_max_time(tcs); - - nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + - ltt_trace_per_cpu_tracefile_number(tc->t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfcs = LTTV_TRACEFILE_STATE(tc->tracefiles[j]); - tfcs->cpu_name= g_quark_from_string(ltt_tracefile_name(tfcs->parent.tf)); - } - tcs->processes = NULL; - restore_init_state(tcs); - } -} - - -static void -fini(LttvTracesetState *self) -{ - guint i, j, nb_trace; - - LttvTraceState *tcs; - - LttvTracefileState *tfcs; - - LttvAttributeValue v; - - nb_trace = lttv_traceset_number(LTTV_TRACESET_CONTEXT(self)->ts); - for(i = 0 ; i < nb_trace ; i++) { - tcs = (LttvTraceState *)(LTTV_TRACESET_CONTEXT(self)->traces[i]); - lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_TRACE_STATE_USE_COUNT, - LTTV_UINT, &v); - (*v.v_uint)--; - - g_assert(*(v.v_uint) >= 0); - if(*(v.v_uint) == 0) { - free_name_tables(tcs); - free_max_time(tcs); - free_saved_state(tcs); - } - lttv_state_free_process_table(tcs->processes); - tcs->processes = NULL; - } - LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))-> - fini((LttvTracesetContext *)self); -} - - -static LttvTracesetContext * -new_traceset_context(LttvTracesetContext *self) -{ - return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATE_TYPE, NULL)); -} - - -static LttvTraceContext * -new_trace_context(LttvTracesetContext *self) -{ - return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATE_TYPE, NULL)); -} - - -static LttvTracefileContext * -new_tracefile_context(LttvTracesetContext *self) -{ - return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATE_TYPE, NULL)); -} - - -/* Write the process state of the trace */ - -static void write_process_state(gpointer key, gpointer value, - gpointer user_data) -{ - LttvProcessState *process; - - LttvExecutionState *es; - - FILE *fp = (FILE *)user_data; - - guint i; - - process = (LttvProcessState *)value; - fprintf(fp, -" \n", - process, process->pid, process->ppid, process->creation_time.tv_sec, - process->creation_time.tv_nsec, g_quark_to_string(process->name), - g_quark_to_string(process->last_cpu)); - - for(i = 0 ; i < process->execution_stack->len; i++) { - es = &g_array_index(process->execution_stack, LttvExecutionState, i); - fprintf(fp, " t), g_quark_to_string(es->n), - es->entry.tv_sec, es->entry.tv_nsec); - fprintf(fp, " CHANGE_S=%lu CHANGE_NS=%lu STATUS=\"%s\"/>\n", - es->change.tv_sec, es->change.tv_nsec, g_quark_to_string(es->s)); - } - fprintf(fp, " \n"); -} - - -void lttv_state_write(LttvTraceState *self, LttTime t, FILE *fp) -{ - guint i, nb_tracefile, nb_block, nb_event; - - LttvTracefileState *tfcs; - - LttTracefile *tf; - - LttEventPosition *ep; - - ep = ltt_event_position_new(); - - fprintf(fp,"\n", t.tv_sec, t.tv_nsec); - - g_hash_table_foreach(self->processes, write_process_state, fp); - - nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) + - ltt_trace_per_cpu_tracefile_number(self->parent.t); - - for(i = 0 ; i < nb_tracefile ; i++) { - tfcs = (LttvTracefileState *)self->parent.tracefiles[i]; - fprintf(fp, " process->pid, tfcs->parent.timestamp.tv_sec, - tfcs->parent.timestamp.tv_nsec); - if(tfcs->parent.e == NULL) fprintf(fp,"/>\n"); - else { - ltt_event_position(tfcs->parent.e, ep); - ltt_event_position_get(ep, &nb_block, &nb_event, &tf); - fprintf(fp, " BLOCK=%u EVENT=%u/>\n", nb_block, nb_event); - } - } - g_free(ep); - fprintf(fp,""); -} - - -/* Copy each process from an existing hash table to a new one */ - -static void copy_process_state(gpointer key, gpointer value,gpointer user_data) -{ - LttvProcessState *process, *new_process; - - GHashTable *new_processes = (GHashTable *)user_data; - - guint i; - - process = (LttvProcessState *)value; - new_process = g_new(LttvProcessState, 1); - *new_process = *process; - new_process->execution_stack = g_array_new(FALSE, FALSE, - sizeof(LttvExecutionState)); - g_array_set_size(new_process->execution_stack,process->execution_stack->len); - for(i = 0 ; i < process->execution_stack->len; i++) { - g_array_index(new_process->execution_stack, LttvExecutionState, i) = - g_array_index(process->execution_stack, LttvExecutionState, i); - } - new_process->state = &g_array_index(new_process->execution_stack, - LttvExecutionState, new_process->execution_stack->len - 1); - g_hash_table_insert(new_processes, new_process, new_process); -} - - -static GHashTable *lttv_state_copy_process_table(GHashTable *processes) -{ - GHashTable *new_processes = g_hash_table_new(process_hash, process_equal); - - g_hash_table_foreach(processes, copy_process_state, new_processes); - return new_processes; -} - - -/* The saved state for each trace contains a member "processes", which - stores a copy of the process table, and a member "tracefiles" with - one entry per tracefile. Each tracefile has a "process" member pointing - to the current process and a "position" member storing the tracefile - position (needed to seek to the current "next" event. */ - -static void state_save(LttvTraceState *self, LttvAttribute *container) -{ - guint i, nb_tracefile; - - LttvTracefileState *tfcs; - - LttvAttribute *tracefiles_tree, *tracefile_tree; - - LttvAttributeType type; - - LttvAttributeValue value; - - LttvAttributeName name; - - LttEventPosition *ep; - - tracefiles_tree = lttv_attribute_find_subdir(container, - LTTV_STATE_TRACEFILES); - - value = lttv_attribute_add(container, LTTV_STATE_PROCESSES, - LTTV_POINTER); - *(value.v_pointer) = lttv_state_copy_process_table(self->processes); - - nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) + - ltt_trace_per_cpu_tracefile_number(self->parent.t); - - for(i = 0 ; i < nb_tracefile ; i++) { - tfcs = (LttvTracefileState *)self->parent.tracefiles[i]; - tracefile_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); - value = lttv_attribute_add(tracefiles_tree, i, - LTTV_GOBJECT); - *(value.v_gobject) = (GObject *)tracefile_tree; - value = lttv_attribute_add(tracefile_tree, LTTV_STATE_PROCESS, - LTTV_UINT); - *(value.v_uint) = tfcs->process->pid; - value = lttv_attribute_add(tracefile_tree, LTTV_STATE_EVENT, - LTTV_POINTER); - if(tfcs->parent.e == NULL) *(value.v_pointer) = NULL; - else { - ep = ltt_event_position_new(); - ltt_event_position(tfcs->parent.e, ep); - *(value.v_pointer) = ep; - - guint nb_block, nb_event; - LttTracefile *tf; - ltt_event_position_get(ep, &nb_block, &nb_event, &tf); - g_debug("Block %u event %u time %lu.%lu", nb_block, nb_event, - tfcs->parent.timestamp.tv_sec, tfcs->parent.timestamp.tv_nsec); - } - } -} - - -static void state_restore(LttvTraceState *self, LttvAttribute *container) -{ - guint i, nb_tracefile, pid; - - LttvTracefileState *tfcs; - - LttvAttribute *tracefiles_tree, *tracefile_tree; - - LttvAttributeType type; - - LttvAttributeValue value; - - LttvAttributeName name; - - LttEventPosition *ep; - - tracefiles_tree = lttv_attribute_find_subdir(container, - LTTV_STATE_TRACEFILES); - - type = lttv_attribute_get_by_name(container, LTTV_STATE_PROCESSES, - &value); - g_assert(type == LTTV_POINTER); - lttv_state_free_process_table(self->processes); - self->processes = lttv_state_copy_process_table(*(value.v_pointer)); - - nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) + - ltt_trace_per_cpu_tracefile_number(self->parent.t); - - for(i = 0 ; i < nb_tracefile ; i++) { - tfcs = (LttvTracefileState *)self->parent.tracefiles[i]; - type = lttv_attribute_get(tracefiles_tree, i, &name, &value); - g_assert(type == LTTV_GOBJECT); - tracefile_tree = *((LttvAttribute **)(value.v_gobject)); - - type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_PROCESS, - &value); - g_assert(type == LTTV_UINT); - pid = *(value.v_uint); - tfcs->process = lttv_state_find_process_or_create(tfcs, pid); - - type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT, - &value); - g_assert(type == LTTV_POINTER); - if(*(value.v_pointer) == NULL) tfcs->parent.e = NULL; - else { - ep = *(value.v_pointer); - ltt_tracefile_seek_position(tfcs->parent.tf, ep); - tfcs->parent.e = ltt_tracefile_read(tfcs->parent.tf); - tfcs->parent.timestamp = ltt_event_time(tfcs->parent.e); - } - } -} - - -static void state_saved_free(LttvTraceState *self, LttvAttribute *container) -{ - guint i, nb_tracefile; - - LttvTracefileState *tfcs; - - LttvAttribute *tracefiles_tree, *tracefile_tree; - - LttvAttributeType type; - - LttvAttributeValue value; - - LttvAttributeName name; - - LttEventPosition *ep; - - tracefiles_tree = lttv_attribute_find_subdir(container, - LTTV_STATE_TRACEFILES); - lttv_attribute_remove_by_name(container, LTTV_STATE_TRACEFILES); - - type = lttv_attribute_get_by_name(container, LTTV_STATE_PROCESSES, - &value); - g_assert(type == LTTV_POINTER); - lttv_state_free_process_table(*(value.v_pointer)); - *(value.v_pointer) = NULL; - lttv_attribute_remove_by_name(container, LTTV_STATE_PROCESSES); - - nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) + - ltt_trace_per_cpu_tracefile_number(self->parent.t); - - for(i = 0 ; i < nb_tracefile ; i++) { - tfcs = (LttvTracefileState *)self->parent.tracefiles[i]; - type = lttv_attribute_get(tracefiles_tree, i, &name, &value); - g_assert(type == LTTV_GOBJECT); - tracefile_tree = *((LttvAttribute **)(value.v_gobject)); - - type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT, - &value); - g_assert(type == LTTV_POINTER); - if(*(value.v_pointer) != NULL) g_free(*(value.v_pointer)); - } - lttv_attribute_recursive_free(tracefiles_tree); -} - - -static void free_saved_state(LttvTraceState *self) -{ - guint i, nb; - - LttvAttributeType type; - - LttvAttributeValue value; - - LttvAttributeName name; - - LttvAttribute *saved_states; - - saved_states = lttv_attribute_find_subdir(self->parent.t_a, - LTTV_STATE_SAVED_STATES); - - nb = lttv_attribute_get_number(saved_states); - for(i = 0 ; i < nb ; i++) { - type = lttv_attribute_get(saved_states, i, &name, &value); - g_assert(type == LTTV_GOBJECT); - state_saved_free(self, *((LttvAttribute **)value.v_gobject)); - } - - lttv_attribute_remove_by_name(self->parent.t_a, LTTV_STATE_SAVED_STATES); - lttv_attribute_recursive_free(saved_states); -} - - -static void -create_max_time(LttvTraceState *tcs) -{ - LttvAttributeValue v; - - lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_SAVED_STATES_TIME, - LTTV_POINTER, &v); - g_assert(*(v.v_pointer) == NULL); - *(v.v_pointer) = g_new(LttTime,1); - *((LttTime *)*(v.v_pointer)) = time_zero; -} - - -static void -get_max_time(LttvTraceState *tcs) -{ - LttvAttributeValue v; - - lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_SAVED_STATES_TIME, - LTTV_POINTER, &v); - g_assert(*(v.v_pointer) != NULL); - tcs->max_time_state_recomputed_in_seek = (LttTime *)*(v.v_pointer); -} - - -static void -free_max_time(LttvTraceState *tcs) -{ - LttvAttributeValue v; - - lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_SAVED_STATES_TIME, - LTTV_POINTER, &v); - g_free(*(v.v_pointer)); - *(v.v_pointer) = NULL; -} - - -typedef struct _LttvNameTables { - GQuark *eventtype_names; - GQuark *syscall_names; - GQuark *trap_names; - GQuark *irq_names; -} LttvNameTables; - - -static void -create_name_tables(LttvTraceState *tcs) -{ - int i, nb; - - char *f_name, *e_name; - - LttvTraceHook h; - - LttEventType *et; - - LttType *t; - - GString *fe_name = g_string_new(""); - - LttvNameTables *name_tables = g_new(LttvNameTables, 1); - - LttvAttributeValue v; - - lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_NAME_TABLES, - LTTV_POINTER, &v); - g_assert(*(v.v_pointer) == NULL); - *(v.v_pointer) = name_tables; - - nb = ltt_trace_eventtype_number(tcs->parent.t); - name_tables->eventtype_names = g_new(GQuark, nb); - for(i = 0 ; i < nb ; i++) { - et = ltt_trace_eventtype_get(tcs->parent.t, i); - e_name = ltt_eventtype_name(et); - f_name = ltt_facility_name(ltt_eventtype_facility(et)); - g_string_printf(fe_name, "%s.%s", f_name, e_name); - name_tables->eventtype_names[i] = g_quark_from_string(fe_name->str); - } - - lttv_trace_find_hook(tcs->parent.t, "core", "syscall_entry", - "syscall_id", NULL, NULL, NULL, &h); - t = ltt_field_type(h.f1); - nb = ltt_type_element_number(t); - - /* CHECK syscalls should be an emun but currently are not! - name_tables->syscall_names = g_new(GQuark, nb); - - for(i = 0 ; i < nb ; i++) { - name_tables->syscall_names[i] = g_quark_from_string( - ltt_enum_string_get(t, i)); - } - */ - - name_tables->syscall_names = g_new(GQuark, 256); - for(i = 0 ; i < 256 ; i++) { - g_string_printf(fe_name, "syscall %d", i); - name_tables->syscall_names[i] = g_quark_from_string(fe_name->str); - } - - lttv_trace_find_hook(tcs->parent.t, "core", "trap_entry", - "trap_id", NULL, NULL, NULL, &h); - t = ltt_field_type(h.f1); - nb = ltt_type_element_number(t); - - /* - name_tables->trap_names = g_new(GQuark, nb); - for(i = 0 ; i < nb ; i++) { - name_tables->trap_names[i] = g_quark_from_string( - ltt_enum_string_get(t, i)); - } - */ - - name_tables->trap_names = g_new(GQuark, 256); - for(i = 0 ; i < 256 ; i++) { - g_string_printf(fe_name, "trap %d", i); - name_tables->trap_names[i] = g_quark_from_string(fe_name->str); - } - - lttv_trace_find_hook(tcs->parent.t, "core", "irq_entry", - "irq_id", NULL, NULL, NULL, &h); - t = ltt_field_type(h.f1); - nb = ltt_type_element_number(t); - - /* - name_tables->irq_names = g_new(GQuark, nb); - for(i = 0 ; i < nb ; i++) { - name_tables->irq_names[i] = g_quark_from_string(ltt_enum_string_get(t, i)); - } - */ - - name_tables->irq_names = g_new(GQuark, 256); - for(i = 0 ; i < 256 ; i++) { - g_string_printf(fe_name, "irq %d", i); - name_tables->irq_names[i] = g_quark_from_string(fe_name->str); - } - - g_string_free(fe_name, TRUE); -} - - -static void -get_name_tables(LttvTraceState *tcs) -{ - LttvNameTables *name_tables; - - LttvAttributeValue v; - - lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_NAME_TABLES, - LTTV_POINTER, &v); - g_assert(*(v.v_pointer) != NULL); - name_tables = (LttvNameTables *)*(v.v_pointer); - tcs->eventtype_names = name_tables->eventtype_names; - tcs->syscall_names = name_tables->syscall_names; - tcs->trap_names = name_tables->trap_names; - tcs->irq_names = name_tables->irq_names; -} - - -static void -free_name_tables(LttvTraceState *tcs) -{ - LttvNameTables *name_tables; - - LttvAttributeValue v; - - lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_NAME_TABLES, - LTTV_POINTER, &v); - name_tables = (LttvNameTables *)*(v.v_pointer); - *(v.v_pointer) = NULL; - - g_free(name_tables->eventtype_names); - g_free(name_tables->syscall_names); - g_free(name_tables->trap_names); - g_free(name_tables->irq_names); - g_free(name_tables); -} - - -static void push_state(LttvTracefileState *tfs, LttvExecutionMode t, - guint state_id) -{ - LttvExecutionState *es; - - LttvProcessState *process = tfs->process; - - guint depth = process->execution_stack->len; - - g_array_set_size(process->execution_stack, depth + 1); - es = &g_array_index(process->execution_stack, LttvExecutionState, depth); - es->t = t; - es->n = state_id; - es->entry = es->change = tfs->parent.timestamp; - es->s = process->state->s; - process->state = es; -} - - -static void pop_state(LttvTracefileState *tfs, LttvExecutionMode t) -{ - LttvProcessState *process = tfs->process; - - guint depth = process->execution_stack->len; - - if(process->state->t != t){ - g_info("Different execution mode type (%d.%09d): ignore it\n", - tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec); - g_info("process state has %s when pop_int is %s\n", - g_quark_to_string(process->state->t), - g_quark_to_string(t)); - g_info("{ %u, %u, %s, %s }\n", - process->pid, - process->ppid, - g_quark_to_string(process->name), - g_quark_to_string(process->state->s)); - return; - } - - if(depth == 1){ - g_info("Trying to pop last state on stack (%d.%09d): ignore it\n", - tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec); - return; - } - - g_array_set_size(process->execution_stack, depth - 1); - process->state = &g_array_index(process->execution_stack, LttvExecutionState, - depth - 2); - process->state->change = tfs->parent.timestamp; -} - - -LttvProcessState * -lttv_state_create_process(LttvTracefileState *tfs, LttvProcessState *parent, - guint pid) -{ - LttvProcessState *process = g_new(LttvProcessState, 1); - - LttvExecutionState *es; - - LttvTraceContext *tc; - - LttvTraceState *tcs; - - char buffer[128]; - - tcs = ((LttvTraceState *)tc = tfs->parent.t_context); - - process->pid = pid; - process->last_cpu = tfs->cpu_name; - g_warning("Process %u, core %p", process->pid, process); - g_hash_table_insert(tcs->processes, process, process); - - if(parent) { - process->ppid = parent->pid; - process->name = parent->name; - process->creation_time = tfs->parent.timestamp; - } - - /* No parent. This process exists but we are missing all information about - its creation. The birth time is set to zero but we remember the time of - insertion */ - - else { - process->ppid = 0; - process->name = LTTV_STATE_UNNAMED; - process->creation_time = ltt_time_zero; - } - - process->insertion_time = tfs->parent.timestamp; - sprintf(buffer,"%d-%lu.%lu",pid, process->creation_time.tv_sec, - process->creation_time.tv_nsec); - process->pid_time = g_quark_from_string(buffer); - process->last_cpu = tfs->cpu_name; - process->execution_stack = g_array_new(FALSE, FALSE, - sizeof(LttvExecutionState)); - g_array_set_size(process->execution_stack, 1); - es = process->state = &g_array_index(process->execution_stack, - LttvExecutionState, 0); - es->t = LTTV_STATE_USER_MODE; - es->n = LTTV_STATE_SUBMODE_NONE; - es->entry = tfs->parent.timestamp; - es->change = tfs->parent.timestamp; - es->s = LTTV_STATE_WAIT_FORK; - - return process; -} - - -LttvProcessState * -lttv_state_find_process_from_trace(LttvTraceState *ts, GQuark cpu, guint pid) -{ - LttvProcessState key; - LttvProcessState *process; - - key.pid = pid; - key.last_cpu = cpu; - process = g_hash_table_lookup(ts->processes, &key); - return process; -} - - -LttvProcessState *lttv_state_find_process(LttvTracefileState *tfs, - guint pid) -{ - LttvTraceState *ts =(LttvTraceState *)tfs->parent.t_context; - return lttv_state_find_process_from_trace(ts, tfs->cpu_name, pid); -} - - -LttvProcessState * -lttv_state_find_process_or_create(LttvTracefileState *tfs, guint pid) -{ - LttvProcessState *process = lttv_state_find_process(tfs, pid); - - if(process == NULL) process = lttv_state_create_process(tfs, NULL, pid); - return process; -} - - -static void exit_process(LttvTracefileState *tfs, LttvProcessState *process) -{ - LttvTraceState *ts = LTTV_TRACE_STATE(tfs->parent.t_context); - LttvProcessState key; - - key.pid = process->pid; - key.last_cpu = process->last_cpu; - g_hash_table_remove(ts->processes, &key); - g_array_free(process->execution_stack, TRUE); - g_free(process); -} - - -static void free_process_state(gpointer key, gpointer value,gpointer user_data) -{ - g_array_free(((LttvProcessState *)value)->execution_stack, TRUE); - g_free(value); -} - - -static void lttv_state_free_process_table(GHashTable *processes) -{ - g_hash_table_foreach(processes, free_process_state, NULL); - g_hash_table_destroy(processes); -} - - -static gboolean syscall_entry(void *hook_data, void *call_data) -{ - LttField *f = ((LttvTraceHook *)hook_data)->f1; - - LttvTracefileState *s = (LttvTracefileState *)call_data; - - LttvExecutionSubmode submode; - - submode = ((LttvTraceState *)(s->parent.t_context))->syscall_names[ - ltt_event_get_unsigned(s->parent.e, f)]; - push_state(s, LTTV_STATE_SYSCALL, submode); - return FALSE; -} - - -static gboolean syscall_exit(void *hook_data, void *call_data) -{ - LttvTracefileState *s = (LttvTracefileState *)call_data; - - pop_state(s, LTTV_STATE_SYSCALL); - return FALSE; -} - - -static gboolean trap_entry(void *hook_data, void *call_data) -{ - LttField *f = ((LttvTraceHook *)hook_data)->f1; - - LttvTracefileState *s = (LttvTracefileState *)call_data; - - LttvExecutionSubmode submode; - - submode = ((LttvTraceState *)(s->parent.t_context))->trap_names[ - ltt_event_get_unsigned(s->parent.e, f)]; - push_state(s, LTTV_STATE_TRAP, submode); - return FALSE; -} - - -static gboolean trap_exit(void *hook_data, void *call_data) -{ - LttvTracefileState *s = (LttvTracefileState *)call_data; - - pop_state(s, LTTV_STATE_TRAP); - return FALSE; -} - - -static gboolean irq_entry(void *hook_data, void *call_data) -{ - LttField *f = ((LttvTraceHook *)hook_data)->f1; - - LttvTracefileState *s = (LttvTracefileState *)call_data; - - LttvExecutionSubmode submode; - - submode = ((LttvTraceState *)(s->parent.t_context))->irq_names[ - ltt_event_get_unsigned(s->parent.e, f)]; - - /* Do something with the info about being in user or system mode when int? */ - push_state(s, LTTV_STATE_IRQ, submode); - return FALSE; -} - - -static gboolean irq_exit(void *hook_data, void *call_data) -{ - LttvTracefileState *s = (LttvTracefileState *)call_data; - - pop_state(s, LTTV_STATE_IRQ); - return FALSE; -} - - -static gboolean schedchange(void *hook_data, void *call_data) -{ - LttvTraceHook *h = (LttvTraceHook *)hook_data; - - LttvTracefileState *s = (LttvTracefileState *)call_data; - - guint pid_in, pid_out, state_out; - - pid_in = ltt_event_get_unsigned(s->parent.e, h->f1); - pid_out = ltt_event_get_unsigned(s->parent.e, h->f2); - state_out = ltt_event_get_unsigned(s->parent.e, h->f3); - - if(s->process != NULL) { - - /* We could not know but it was not the idle process executing. - This should only happen at the beginning, before the first schedule - event, and when the initial information (current process for each CPU) - is missing. It is not obvious how we could, after the fact, compensate - the wrongly attributed statistics. */ - - if(s->process->pid != pid_out) { - g_assert(s->process->pid == 0); - } - - if(state_out == 0) s->process->state->s = LTTV_STATE_WAIT_CPU; - else if(s->process->state->s == LTTV_STATE_EXIT) - exit_process(s, s->process); - else s->process->state->s = LTTV_STATE_WAIT; - - s->process->state->change = s->parent.timestamp; - } - s->process = lttv_state_find_process_or_create(s, pid_in); - s->process->state->s = LTTV_STATE_RUN; - s->process->last_cpu = s->cpu_name; - s->process->state->change = s->parent.timestamp; - return FALSE; -} - - -static gboolean process_fork(void *hook_data, void *call_data) -{ - LttField *f = ((LttvTraceHook *)hook_data)->f1; - - LttvTracefileState *s = (LttvTracefileState *)call_data; - - guint child_pid; - - child_pid = ltt_event_get_unsigned(s->parent.e, f); - lttv_state_create_process(s, s->process, child_pid); - return FALSE; -} - - -static gboolean process_exit(void *hook_data, void *call_data) -{ - LttvTracefileState *s = (LttvTracefileState *)call_data; - - if(s->process != NULL) { - s->process->state->s = LTTV_STATE_EXIT; - } - return FALSE; -} - - -void lttv_state_add_event_hooks(LttvTracesetState *self) -{ - LttvTraceset *traceset = self->parent.ts; - - guint i, j, k, nb_trace, nb_tracefile; - - LttvTraceState *ts; - - LttvTracefileState *tfs; - - GArray *hooks; - - LttvTraceHook hook; - - LttvAttributeValue val; - - nb_trace = lttv_traceset_number(traceset); - for(i = 0 ; i < nb_trace ; i++) { - ts = (LttvTraceState *)self->parent.traces[i]; - - /* Find the eventtype id for the following events and register the - associated by id hooks. */ - - hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook)); - g_array_set_size(hooks, 9); - - lttv_trace_find_hook(ts->parent.t, "core","syscall_entry","syscall_id", - NULL, NULL, syscall_entry, &g_array_index(hooks, LttvTraceHook, 0)); - - lttv_trace_find_hook(ts->parent.t, "core", "syscall_exit", NULL, NULL, - NULL, syscall_exit, &g_array_index(hooks, LttvTraceHook, 1)); - - lttv_trace_find_hook(ts->parent.t, "core", "trap_entry", "trap_id", - NULL, NULL, trap_entry, &g_array_index(hooks, LttvTraceHook, 2)); - - lttv_trace_find_hook(ts->parent.t, "core", "trap_exit", NULL, NULL, NULL, - trap_exit, &g_array_index(hooks, LttvTraceHook, 3)); - - lttv_trace_find_hook(ts->parent.t, "core", "irq_entry", "irq_id", NULL, - NULL, irq_entry, &g_array_index(hooks, LttvTraceHook, 4)); - - lttv_trace_find_hook(ts->parent.t, "core", "irq_exit", NULL, NULL, NULL, - irq_exit, &g_array_index(hooks, LttvTraceHook, 5)); - - lttv_trace_find_hook(ts->parent.t, "core", "schedchange", "in", "out", - "out_state", schedchange, &g_array_index(hooks, LttvTraceHook, 6)); - - lttv_trace_find_hook(ts->parent.t, "core", "process_fork", "child_pid", - NULL, NULL, process_fork, &g_array_index(hooks, LttvTraceHook, 7)); - - lttv_trace_find_hook(ts->parent.t, "core", "process_exit", NULL, NULL, - NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 8)); - - /* Add these hooks to each before_event_by_id hooks list */ - - nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.t) + - ltt_trace_per_cpu_tracefile_number(ts->parent.t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfs = LTTV_TRACEFILE_STATE(ts->parent.tracefiles[j]); - - for(k = 0 ; k < hooks->len ; k++) { - hook = g_array_index(hooks, LttvTraceHook, k); - lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id, - hook.id), hook.h, &g_array_index(hooks, LttvTraceHook, k)); - } - } - lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val); - *(val.v_pointer) = hooks; - } -} - - -void lttv_state_remove_event_hooks(LttvTracesetState *self) -{ - LttvTraceset *traceset = self->parent.ts; - - guint i, j, k, nb_trace, nb_tracefile; - - LttvTraceState *ts; - - LttvTracefileState *tfs; - - GArray *hooks; - - LttvTraceHook hook; - - LttvAttributeValue val; - - nb_trace = lttv_traceset_number(traceset); - for(i = 0 ; i < nb_trace ; i++) { - ts = LTTV_TRACE_STATE(self->parent.traces[i]); - lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val); - hooks = *(val.v_pointer); - - /* Add these hooks to each before_event_by_id hooks list */ - - nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.t) + - ltt_trace_per_cpu_tracefile_number(ts->parent.t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfs = LTTV_TRACEFILE_STATE(ts->parent.tracefiles[j]); - - for(k = 0 ; k < hooks->len ; k++) { - hook = g_array_index(hooks, LttvTraceHook, k); - lttv_hooks_remove_data( - lttv_hooks_by_id_find(tfs->parent.after_event_by_id, - hook.id), hook.h, &g_array_index(hooks, LttvTraceHook, k)); - } - } - g_array_free(hooks, TRUE); - } -} - - -static gboolean block_start(void *hook_data, void *call_data) -{ - LttvTracefileState *self = (LttvTracefileState *)call_data; - - LttvTracefileState *tfcs; - - LttvTraceState *tcs = (LttvTraceState *)(self->parent.t_context); - - LttEventPosition *ep; - - guint i, nb_block, nb_event, nb_tracefile; - - LttTracefile *tf; - - LttvAttribute *saved_states_tree, *saved_state_tree; - - LttvAttributeValue value; - - ep = ltt_event_position_new(); - nb_tracefile = ltt_trace_control_tracefile_number(tcs->parent.t) + - ltt_trace_per_cpu_tracefile_number(tcs->parent.t); - - /* Count the number of events added since the last block end in any - tracefile. */ - - for(i = 0 ; i < nb_tracefile ; i++) { - tfcs = (LttvTracefileState *)tcs->parent.tracefiles[i]; - ltt_event_position(tfcs->parent.e, ep); - ltt_event_position_get(ep, &nb_block, &nb_event, &tf); - tcs->nb_event += nb_event - tfcs->saved_position; - tfcs->saved_position = nb_event; - } - g_free(ep); - - if(tcs->nb_event >= tcs->save_interval) { - saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a, - LTTV_STATE_SAVED_STATES); - saved_state_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); - value = lttv_attribute_add(saved_states_tree, - lttv_attribute_get_number(saved_states_tree), LTTV_GOBJECT); - *(value.v_gobject) = (GObject *)saved_state_tree; - value = lttv_attribute_add(saved_state_tree, LTTV_STATE_TIME, LTTV_TIME); - *(value.v_time) = self->parent.timestamp; - lttv_state_save(tcs, saved_state_tree); - tcs->nb_event = 0; - g_debug("Saving state at time %lu.%lu", self->parent.timestamp.tv_sec, - self->parent.timestamp.tv_nsec); - } - *(tcs->max_time_state_recomputed_in_seek) = self->parent.timestamp; - return FALSE; -} - - -static gboolean block_end(void *hook_data, void *call_data) -{ - LttvTracefileState *self = (LttvTracefileState *)call_data; - - LttvTraceState *tcs = (LttvTraceState *)(self->parent.t_context); - - LttTracefile *tf; - - LttEventPosition *ep; - - guint nb_block, nb_event; - - ep = ltt_event_position_new(); - ltt_event_position(self->parent.e, ep); - ltt_event_position_get(ep, &nb_block, &nb_event, &tf); - tcs->nb_event += nb_event - self->saved_position + 1; - self->saved_position = 0; - *(tcs->max_time_state_recomputed_in_seek) = self->parent.timestamp; - g_free(ep); -} - - -void lttv_state_save_add_event_hooks(LttvTracesetState *self) -{ - LttvTraceset *traceset = self->parent.ts; - - guint i, j, k, nb_trace, nb_tracefile; - - LttvTraceState *ts; - - LttvTracefileState *tfs; - - LttvTraceHook hook_start, hook_end; - - nb_trace = lttv_traceset_number(traceset); - for(i = 0 ; i < nb_trace ; i++) { - ts = (LttvTraceState *)self->parent.traces[i]; - lttv_trace_find_hook(ts->parent.t, "core","block_start",NULL, - NULL, NULL, block_start, &hook_start); - lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL, - NULL, NULL, block_end, &hook_end); - - nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.t) + - ltt_trace_per_cpu_tracefile_number(ts->parent.t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfs = LTTV_TRACEFILE_STATE(ts->parent.tracefiles[j]); - lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id, - hook_start.id), hook_start.h, NULL); - lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id, - hook_end.id), hook_end.h, NULL); - } - } -} - - -void lttv_state_save_remove_event_hooks(LttvTracesetState *self) -{ - LttvTraceset *traceset = self->parent.ts; - - guint i, j, k, nb_trace, nb_tracefile; - - LttvTraceState *ts; - - LttvTracefileState *tfs; - - LttvTraceHook hook_start, hook_end; - - nb_trace = lttv_traceset_number(traceset); - for(i = 0 ; i < nb_trace ; i++) { - ts = LTTV_TRACE_STATE(self->parent.traces[i]); - lttv_trace_find_hook(ts->parent.t, "core","block_start",NULL, - NULL, NULL, block_start, &hook_start); - - lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL, - NULL, NULL, block_end, &hook_end); - - nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.t) + - ltt_trace_per_cpu_tracefile_number(ts->parent.t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfs = LTTV_TRACEFILE_STATE(ts->parent.tracefiles[j]); - lttv_hooks_remove_data(lttv_hooks_by_id_find( - tfs->parent.after_event_by_id, hook_start.id), hook_start.h, NULL); - lttv_hooks_remove_data(lttv_hooks_by_id_find( - tfs->parent.after_event_by_id, hook_end.id), hook_end.h, NULL); - } - } -} - - -void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t) -{ - LttvTraceset *traceset = self->parent.ts; - - guint i, j, nb_trace, nb_saved_state; - - int min_pos, mid_pos, max_pos; - - LttvTraceState *tcs; - - LttvAttributeValue value; - - LttvAttributeType type; - - LttvAttributeName name; - - LttvAttribute *saved_states_tree, *saved_state_tree, *closest_tree; - - nb_trace = lttv_traceset_number(traceset); - for(i = 0 ; i < nb_trace ; i++) { - tcs = (LttvTraceState *)self->parent.traces[i]; - - if(ltt_time_compare(t, *(tcs->max_time_state_recomputed_in_seek)) < 0) { - saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a, - LTTV_STATE_SAVED_STATES); - min_pos = -1; - - if(saved_states_tree) { - max_pos = lttv_attribute_get_number(saved_states_tree) - 1; - mid_pos = max_pos / 2; - while(min_pos < max_pos) { - type = lttv_attribute_get(saved_states_tree, mid_pos, &name, &value); - g_assert(type == LTTV_GOBJECT); - saved_state_tree = *((LttvAttribute **)(value.v_gobject)); - type = lttv_attribute_get_by_name(saved_state_tree, LTTV_STATE_TIME, - &value); - g_assert(type == LTTV_TIME); - if(ltt_time_compare(*(value.v_time), t) < 0) { - min_pos = mid_pos; - closest_tree = saved_state_tree; - } - else max_pos = mid_pos - 1; - - mid_pos = (min_pos + max_pos + 1) / 2; - } - } - - /* restore the closest earlier saved state */ - if(min_pos != -1) { - lttv_state_restore(tcs, closest_tree); - } - - /* There is no saved state, yet we want to have it. Restart at T0 */ - else { - restore_init_state(tcs); - lttv_process_trace_seek_time(&(tcs->parent), ltt_time_zero); - } - } - /* We want to seek quickly without restoring/updating the state */ - else { - restore_init_state(tcs); - lttv_process_trace_seek_time(&(tcs->parent), t); - } - } -} - - -static void -traceset_state_instance_init (GTypeInstance *instance, gpointer g_class) -{ -} - - -static void -traceset_state_finalize (LttvTracesetState *self) -{ - G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))-> - finalize(G_OBJECT(self)); -} - - -static void -traceset_state_class_init (LttvTracesetContextClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->finalize = (void (*)(GObject *self)) traceset_state_finalize; - klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init; - klass->fini = (void (*)(LttvTracesetContext *self))fini; - klass->new_traceset_context = new_traceset_context; - klass->new_trace_context = new_trace_context; - klass->new_tracefile_context = new_tracefile_context; -} - - -GType -lttv_traceset_state_get_type(void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (LttvTracesetStateClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) traceset_state_class_init, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (LttvTracesetState), - 0, /* n_preallocs */ - (GInstanceInitFunc) traceset_state_instance_init /* instance_init */ - }; - - type = g_type_register_static (LTTV_TRACESET_CONTEXT_TYPE, "LttvTracesetStateType", - &info, 0); - } - return type; -} - - -static void -trace_state_instance_init (GTypeInstance *instance, gpointer g_class) -{ -} - - -static void -trace_state_finalize (LttvTraceState *self) -{ - G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_CONTEXT_TYPE))-> - finalize(G_OBJECT(self)); -} - - -static void -trace_state_class_init (LttvTraceStateClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->finalize = (void (*)(GObject *self)) trace_state_finalize; - klass->state_save = state_save; - klass->state_restore = state_restore; - klass->state_saved_free = state_saved_free; -} - - -GType -lttv_trace_state_get_type(void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (LttvTraceStateClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) trace_state_class_init, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (LttvTraceState), - 0, /* n_preallocs */ - (GInstanceInitFunc) trace_state_instance_init /* instance_init */ - }; - - type = g_type_register_static (LTTV_TRACE_CONTEXT_TYPE, - "LttvTraceStateType", &info, 0); - } - return type; -} - - -static void -tracefile_state_instance_init (GTypeInstance *instance, gpointer g_class) -{ -} - - -static void -tracefile_state_finalize (LttvTracefileState *self) -{ - G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_CONTEXT_TYPE))-> - finalize(G_OBJECT(self)); -} - - -static void -tracefile_state_class_init (LttvTracefileStateClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->finalize = (void (*)(GObject *self)) tracefile_state_finalize; -} - - -GType -lttv_tracefile_state_get_type(void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (LttvTracefileStateClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) tracefile_state_class_init, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (LttvTracefileState), - 0, /* n_preallocs */ - (GInstanceInitFunc) tracefile_state_instance_init /* instance_init */ - }; - - type = g_type_register_static (LTTV_TRACEFILE_CONTEXT_TYPE, - "LttvTracefileStateType", &info, 0); - } - return type; -} - - -static void module_init() -{ - LTTV_STATE_UNNAMED = g_quark_from_string("unnamed"); - LTTV_STATE_MODE_UNKNOWN = g_quark_from_string("unknown execution mode"); - LTTV_STATE_USER_MODE = g_quark_from_string("user mode"); - LTTV_STATE_WAIT_FORK = g_quark_from_string("wait fork"); - LTTV_STATE_SYSCALL = g_quark_from_string("system call"); - LTTV_STATE_TRAP = g_quark_from_string("trap"); - LTTV_STATE_IRQ = g_quark_from_string("irq"); - LTTV_STATE_SUBMODE_UNKNOWN = g_quark_from_string("unknown submode"); - LTTV_STATE_SUBMODE_NONE = g_quark_from_string("(no submode)"); - LTTV_STATE_WAIT_CPU = g_quark_from_string("wait for cpu"); - LTTV_STATE_EXIT = g_quark_from_string("exiting"); - LTTV_STATE_WAIT = g_quark_from_string("wait for I/O"); - LTTV_STATE_RUN = g_quark_from_string("running"); - LTTV_STATE_TRACEFILES = g_quark_from_string("tracefiles"); - LTTV_STATE_PROCESSES = g_quark_from_string("processes"); - LTTV_STATE_PROCESS = g_quark_from_string("process"); - LTTV_STATE_EVENT = g_quark_from_string("event"); - LTTV_STATE_SAVED_STATES = g_quark_from_string("saved states"); - LTTV_STATE_SAVED_STATES_TIME = g_quark_from_string("saved states time"); - LTTV_STATE_TIME = g_quark_from_string("time"); - LTTV_STATE_HOOKS = g_quark_from_string("saved state hooks"); - LTTV_STATE_NAME_TABLES = g_quark_from_string("name tables"); - LTTV_STATE_TRACE_STATE_USE_COUNT = - g_quark_from_string("trace_state_use_count"); -} - -static void module_destroy() -{ -} - - -LTTV_MODULE("state", "State computation", \ - "Update the system state, possibly saving it at intervals", \ - module_init, module_destroy) - - - diff --git a/ltt/branches/poly/lttv/main/stats.c b/ltt/branches/poly/lttv/main/stats.c deleted file mode 100644 index d5cd80b4..00000000 --- a/ltt/branches/poly/lttv/main/stats.c +++ /dev/null @@ -1,916 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include - -#define BUF_SIZE 256 - -GQuark - LTTV_STATS_PROCESS_UNKNOWN, - LTTV_STATS_PROCESSES, - LTTV_STATS_CPU, - LTTV_STATS_MODE_TYPES, - LTTV_STATS_MODES, - LTTV_STATS_SUBMODES, - LTTV_STATS_EVENT_TYPES, - LTTV_STATS_CPU_TIME, - LTTV_STATS_ELAPSED_TIME, - LTTV_STATS_EVENTS, - LTTV_STATS_EVENTS_COUNT, - LTTV_STATS_USE_COUNT, - LTTV_STATS, - LTTV_STATS_TRACEFILES, - LTTV_STATS_SUMMED; - -static GQuark - LTTV_STATS_BEFORE_HOOKS, - LTTV_STATS_AFTER_HOOKS; - -static void remove_all_processes(GHashTable *processes); - -static void -find_event_tree(LttvTracefileStats *tfcs, GQuark process, GQuark cpu, - GQuark mode, GQuark sub_mode, LttvAttribute **events_tree, - LttvAttribute **event_types_tree); - -static void -init(LttvTracesetStats *self, LttvTraceset *ts) -{ - guint i, j, nb_trace, nb_tracefile; - - LttvTraceContext *tc; - - LttvTraceStats *tcs; - - LttvTracefileContext *tfc; - - LttvTracefileStats *tfcs; - - LttTime timestamp = {0,0}; - - LttvAttributeValue v; - - LttvAttribute - *stats_tree, - *tracefiles_stats; - - LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))-> - init((LttvTracesetContext *)self, ts); - - self->stats =lttv_attribute_find_subdir(self->parent.parent.ts_a,LTTV_STATS); - lttv_attribute_find(self->parent.parent.ts_a, LTTV_STATS_USE_COUNT, - LTTV_UINT, &v); - - *(v.v_uint)++; - if(*(v.v_uint) == 1) { - g_assert(lttv_attribute_get_number(self->stats) == 0); - } - - nb_trace = lttv_traceset_number(ts); - - for(i = 0 ; i < nb_trace ; i++) { - tcs = (LttvTraceStats *)tc = (LTTV_TRACESET_CONTEXT(self)->traces[i]); - - tcs->stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a,LTTV_STATS); - tracefiles_stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a, - LTTV_STATS_TRACEFILES); - lttv_attribute_find(tcs->parent.parent.t_a, LTTV_STATS_USE_COUNT, - LTTV_UINT, &v); - - *(v.v_uint)++; - if(*(v.v_uint) == 1) { - g_assert(lttv_attribute_get_number(tcs->stats) == 0); - } - - nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + - ltt_trace_per_cpu_tracefile_number(tc->t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfcs = LTTV_TRACEFILE_STATS(tc->tracefiles[j]); - tfcs->stats = lttv_attribute_find_subdir(tracefiles_stats, - tfcs->parent.cpu_name); - find_event_tree(tfcs, LTTV_STATS_PROCESS_UNKNOWN, - tfcs->parent.cpu_name, LTTV_STATE_MODE_UNKNOWN, - LTTV_STATE_SUBMODE_UNKNOWN, &tfcs->current_events_tree, - &tfcs->current_event_types_tree); - } - } -} - - -static void -fini(LttvTracesetStats *self) -{ - guint i, j, nb_trace, nb_tracefile; - - LttvTraceset *ts; - - LttvTraceContext *tc; - - LttvTraceStats *tcs; - - LttvTracefileContext *tfc; - - LttvTracefileStats *tfcs; - - LttTime timestamp = {0,0}; - - LttvAttributeValue v; - - LttvAttribute *tracefiles_stats; - - lttv_attribute_find(self->parent.parent.ts_a, LTTV_STATS_USE_COUNT, - LTTV_UINT, &v); - *(v.v_uint)--; - - if(*(v.v_uint) == 0) { - lttv_attribute_remove_by_name(self->parent.parent.ts_a, LTTV_STATS); - lttv_attribute_recursive_free(self->stats); - } - self->stats = NULL; - - ts = self->parent.parent.ts; - nb_trace = lttv_traceset_number(ts); - - for(i = 0 ; i < nb_trace ; i++) { - tcs = (LttvTraceStats *)(tc = (LTTV_TRACESET_CONTEXT(self)->traces[i])); - - lttv_attribute_find(tcs->parent.parent.t_a, LTTV_STATS_USE_COUNT, - LTTV_UINT, &v); - *(v.v_uint)--; - - if(*(v.v_uint) == 0) { - lttv_attribute_remove_by_name(tcs->parent.parent.t_a,LTTV_STATS); - lttv_attribute_recursive_free(tcs->stats); - tracefiles_stats = lttv_attribute_find_subdir(tcs->parent.parent.t_a, - LTTV_STATS_TRACEFILES); - lttv_attribute_remove_by_name(tcs->parent.parent.t_a, - LTTV_STATS_TRACEFILES); - lttv_attribute_recursive_free(tracefiles_stats); - } - tcs->stats = NULL; - - nb_tracefile = ltt_trace_control_tracefile_number(tc->t) + - ltt_trace_per_cpu_tracefile_number(tc->t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfcs = ((LttvTracefileStats *)tfc = tc->tracefiles[j]); - tfcs->stats = NULL; - tfcs->current_events_tree = NULL; - tfcs->current_event_types_tree = NULL; - } - } - LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))-> - fini((LttvTracesetContext *)self); -} - - -static LttvTracesetContext * -new_traceset_context(LttvTracesetContext *self) -{ - return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATS_TYPE, NULL)); -} - - -static LttvTraceContext * -new_trace_context(LttvTracesetContext *self) -{ - return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATS_TYPE, NULL)); -} - - -static LttvTracefileContext * -new_tracefile_context(LttvTracesetContext *self) -{ - return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATS_TYPE, NULL)); -} - - -static void -traceset_stats_instance_init (GTypeInstance *instance, gpointer g_class) -{ -} - - -static void -traceset_stats_finalize (LttvTracesetStats *self) -{ - G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_STATE_TYPE))-> - finalize(G_OBJECT(self)); -} - - -static void -traceset_stats_class_init (LttvTracesetContextClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->finalize = (void (*)(GObject *self)) traceset_stats_finalize; - klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init; - klass->fini = (void (*)(LttvTracesetContext *self))fini; - klass->new_traceset_context = new_traceset_context; - klass->new_trace_context = new_trace_context; - klass->new_tracefile_context = new_tracefile_context; -} - - -GType -lttv_traceset_stats_get_type(void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (LttvTracesetStatsClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) traceset_stats_class_init, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (LttvTracesetStats), - 0, /* n_preallocs */ - (GInstanceInitFunc) traceset_stats_instance_init /* instance_init */ - }; - - type = g_type_register_static (LTTV_TRACESET_STATE_TYPE, "LttvTracesetStatsType", - &info, 0); - } - return type; -} - - -static void -trace_stats_instance_init (GTypeInstance *instance, gpointer g_class) -{ -} - - -static void -trace_stats_finalize (LttvTraceStats *self) -{ - G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_STATE_TYPE))-> - finalize(G_OBJECT(self)); -} - - -static void -trace_stats_class_init (LttvTraceContextClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->finalize = (void (*)(GObject *self)) trace_stats_finalize; -} - - -GType -lttv_trace_stats_get_type(void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (LttvTraceStatsClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) trace_stats_class_init, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (LttvTraceStats), - 0, /* n_preallocs */ - (GInstanceInitFunc) trace_stats_instance_init /* instance_init */ - }; - - type = g_type_register_static (LTTV_TRACE_STATE_TYPE, - "LttvTraceStatsType", &info, 0); - } - return type; -} - - -static void -tracefile_stats_instance_init (GTypeInstance *instance, gpointer g_class) -{ -} - - -static void -tracefile_stats_finalize (LttvTracefileStats *self) -{ - G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_STATE_TYPE))-> - finalize(G_OBJECT(self)); -} - - -static void -tracefile_stats_class_init (LttvTracefileStatsClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - gobject_class->finalize = (void (*)(GObject *self)) tracefile_stats_finalize; -} - - -GType -lttv_tracefile_stats_get_type(void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (LttvTracefileStatsClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) tracefile_stats_class_init, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (LttvTracefileStats), - 0, /* n_preallocs */ - (GInstanceInitFunc) tracefile_stats_instance_init /* instance_init */ - }; - - type = g_type_register_static (LTTV_TRACEFILE_STATE_TYPE, - "LttvTracefileStatsType", &info, 0); - } - return type; -} - - -static void -find_event_tree(LttvTracefileStats *tfcs, GQuark process, GQuark cpu, - GQuark mode, GQuark sub_mode, LttvAttribute **events_tree, - LttvAttribute **event_types_tree) -{ - LttvAttribute *a; - - LttvTraceStats *tcs = LTTV_TRACE_STATS(tfcs->parent.parent.t_context); - a = lttv_attribute_find_subdir(tcs->stats, LTTV_STATS_PROCESSES); - a = lttv_attribute_find_subdir(a, tfcs->parent.process->pid_time); - a = lttv_attribute_find_subdir(a, LTTV_STATS_CPU); - a = lttv_attribute_find_subdir(a, tfcs->parent.cpu_name); - a = lttv_attribute_find_subdir(a, LTTV_STATS_MODE_TYPES); - a = lttv_attribute_find_subdir(a, tfcs->parent.process->state->t); - a = lttv_attribute_find_subdir(a, LTTV_STATS_SUBMODES); - a = lttv_attribute_find_subdir(a, tfcs->parent.process->state->n); - *events_tree = a; - a = lttv_attribute_find_subdir(a, LTTV_STATS_EVENT_TYPES); - *event_types_tree = a; -} - - -static void update_event_tree(LttvTracefileStats *tfcs) -{ - LttvExecutionState *es = tfcs->parent.process->state; - - find_event_tree(tfcs, tfcs->parent.process->pid_time, tfcs->parent.cpu_name, - es->t, es->n, &(tfcs->current_events_tree), - &(tfcs->current_event_types_tree)); -} - - -static void mode_change(LttvTracefileStats *tfcs) -{ - LttvAttributeValue cpu_time; - - LttTime delta; - - lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME, - LTTV_TIME, &cpu_time); - delta = ltt_time_sub(tfcs->parent.parent.timestamp, - tfcs->parent.process->state->change); - *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta); -} - - -static void mode_end(LttvTracefileStats *tfcs) -{ - LttvAttributeValue elapsed_time, cpu_time; - - LttTime delta; - - lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_ELAPSED_TIME, - LTTV_TIME, &elapsed_time); - delta = ltt_time_sub(tfcs->parent.parent.timestamp, - tfcs->parent.process->state->entry); - *(elapsed_time.v_time) = ltt_time_add(*(elapsed_time.v_time), delta); - - lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME, - LTTV_TIME, &cpu_time); - delta = ltt_time_sub(tfcs->parent.parent.timestamp, - tfcs->parent.process->state->change); - *(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta); -} - - -static gboolean before_syscall_entry(void *hook_data, void *call_data) -{ - mode_change((LttvTracefileStats *)call_data); - return FALSE; -} - - -static gboolean after_syscall_entry(void *hook_data, void *call_data) -{ - update_event_tree((LttvTracefileStats *)call_data); - return FALSE; -} - - -gboolean before_syscall_exit(void *hook_data, void *call_data) -{ - mode_end((LttvTracefileStats *)call_data); - return FALSE; -} - - -static gboolean after_syscall_exit(void *hook_data, void *call_data) -{ - update_event_tree((LttvTracefileStats *)call_data); - return FALSE; -} - - -gboolean before_trap_entry(void *hook_data, void *call_data) -{ - mode_change((LttvTracefileStats *)call_data); - return FALSE; -} - - -static gboolean after_trap_entry(void *hook_data, void *call_data) -{ - update_event_tree((LttvTracefileStats *)call_data); - return FALSE; -} - - -gboolean before_trap_exit(void *hook_data, void *call_data) -{ - mode_end((LttvTracefileStats *)call_data); - return FALSE; -} - - -gboolean after_trap_exit(void *hook_data, void *call_data) -{ - update_event_tree((LttvTracefileStats *)call_data); - return FALSE; -} - - -gboolean before_irq_entry(void *hook_data, void *call_data) -{ - mode_change((LttvTracefileStats *)call_data); - return FALSE; -} - - -gboolean after_irq_entry(void *hook_data, void *call_data) -{ - update_event_tree((LttvTracefileStats *)call_data); - return FALSE; -} - - -gboolean before_irq_exit(void *hook_data, void *call_data) -{ - mode_end((LttvTracefileStats *)call_data); - return FALSE; -} - - -gboolean after_irq_exit(void *hook_data, void *call_data) -{ - update_event_tree((LttvTracefileStats *)call_data); - return FALSE; -} - - -gboolean before_schedchange(void *hook_data, void *call_data) -{ - LttvTraceHook *h = (LttvTraceHook *)hook_data; - - LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data; - - guint pid_in, pid_out, state_out; - - LttvProcessState *process; - - pid_in = ltt_event_get_unsigned(tfcs->parent.parent.e, h->f1); - pid_out = ltt_event_get_unsigned(tfcs->parent.parent.e, h->f2); - state_out = ltt_event_get_unsigned(tfcs->parent.parent.e, h->f3); - - /* compute the time for the process to schedule out */ - - mode_change(tfcs); - - /* get the information for the process scheduled in */ - - process = lttv_state_find_process_or_create(&(tfcs->parent), pid_in); - - find_event_tree(tfcs, process->pid_time, tfcs->parent.cpu_name, - process->state->t, process->state->n, &(tfcs->current_events_tree), - &(tfcs->current_event_types_tree)); - - /* compute the time waiting for the process to schedule in */ - - mode_change(tfcs); - return FALSE; -} - - -gboolean process_fork(void *hook_data, void *call_data) -{ - /* nothing to do for now */ - return FALSE; -} - - -gboolean process_exit(void *hook_data, void *call_data) -{ - /* We should probably exit all modes here or we could do that at - schedule out. */ - return FALSE; -} - - -gboolean every_event(void *hook_data, void *call_data) -{ - LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data; - - LttvAttributeValue v; - - /* The current branch corresponds to the tracefile/process/interrupt state. - Statistics are added within it, to count the number of events of this - type occuring in this context. A quark has been pre-allocated for each - event type and is used as name. */ - - lttv_attribute_find(tfcs->current_event_types_tree, - ((LttvTraceState *)(tfcs->parent.parent.t_context))-> - eventtype_names[ltt_event_eventtype_id(tfcs->parent.parent.e)], - LTTV_UINT, &v); - (*(v.v_uint))++; - return FALSE; -} - - -void -lttv_stats_sum_trace(LttvTraceStats *self) -{ - LttvTraceStats *tcs; - - LttvAttributeType type; - - LttvAttributeValue value; - - LttvAttributeName name; - - unsigned sum; - - int i, j, k, l, m, nb_process, nb_cpu, nb_mode_type, nb_submode, - nb_event_type; - - LttvAttribute *main_tree, *processes_tree, *process_tree, *cpus_tree, - *cpu_tree, *mode_tree, *mode_types_tree, *submodes_tree, - *submode_tree, *event_types_tree, *mode_events_tree, - *cpu_events_tree, *process_modes_tree, *trace_cpu_tree, - *trace_modes_tree; - - main_tree = self->stats; - - lttv_attribute_find(self->parent.parent.t_a, LTTV_STATS_SUMMED, - LTTV_UINT, &value); - if(*(value.v_uint) != 0) return; - *(value.v_uint) = 1; - - processes_tree = lttv_attribute_find_subdir(main_tree, - LTTV_STATS_PROCESSES); - trace_modes_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_MODES); - nb_process = lttv_attribute_get_number(processes_tree); - - for(i = 0 ; i < nb_process ; i++) { - type = lttv_attribute_get(processes_tree, i, &name, &value); - process_tree = LTTV_ATTRIBUTE(*(value.v_gobject)); - - cpus_tree = lttv_attribute_find_subdir(process_tree, LTTV_STATS_CPU); - process_modes_tree = lttv_attribute_find_subdir(process_tree, - LTTV_STATS_MODES); - nb_cpu = lttv_attribute_get_number(cpus_tree); - - for(j = 0 ; j < nb_cpu ; j++) { - type = lttv_attribute_get(cpus_tree, j, &name, &value); - cpu_tree = LTTV_ATTRIBUTE(*(value.v_gobject)); - - mode_types_tree = lttv_attribute_find_subdir(cpu_tree, - LTTV_STATS_MODE_TYPES); - cpu_events_tree = lttv_attribute_find_subdir(cpu_tree, - LTTV_STATS_EVENTS); - trace_cpu_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_CPU); - trace_cpu_tree = lttv_attribute_find_subdir(trace_cpu_tree, name); - nb_mode_type = lttv_attribute_get_number(mode_types_tree); - - for(k = 0 ; k < nb_mode_type ; k++) { - type = lttv_attribute_get(mode_types_tree, k, &name, &value); - mode_tree = LTTV_ATTRIBUTE(*(value.v_gobject)); - - submodes_tree = lttv_attribute_find_subdir(mode_tree, - LTTV_STATS_SUBMODES); - mode_events_tree = lttv_attribute_find_subdir(mode_tree, - LTTV_STATS_EVENTS); - nb_submode = lttv_attribute_get_number(submodes_tree); - - for(l = 0 ; l < nb_submode ; l++) { - type = lttv_attribute_get(submodes_tree, l, &name, &value); - submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject)); - - event_types_tree = lttv_attribute_find_subdir(submode_tree, - LTTV_STATS_EVENT_TYPES); - nb_event_type = lttv_attribute_get_number(event_types_tree); - - sum = 0; - for(m = 0 ; m < nb_event_type ; m++) { - type = lttv_attribute_get(event_types_tree, m, &name, &value); - sum += *(value.v_uint); - } - lttv_attribute_find(submode_tree, LTTV_STATS_EVENTS_COUNT, - LTTV_UINT, &value); - *(value.v_uint) = sum; - lttv_attribute_recursive_add(mode_events_tree, submode_tree); - } - lttv_attribute_recursive_add(cpu_events_tree, mode_events_tree); - } - lttv_attribute_recursive_add(process_modes_tree, cpu_tree); - lttv_attribute_recursive_add(trace_cpu_tree, cpu_tree); - } - lttv_attribute_recursive_add(trace_modes_tree, process_modes_tree); - } -} - - -void -lttv_stats_sum_traceset(LttvTracesetStats *self) -{ - LttvTraceset *traceset = self->parent.parent.ts; - - LttvTraceStats *tcs; - - int i, nb_trace; - - LttvAttribute *main_tree, *trace_modes_tree, *traceset_modes_tree; - - LttvAttributeValue value; - - lttv_attribute_find(self->parent.parent.ts_a, LTTV_STATS_SUMMED, - LTTV_UINT, &value); - if(*(value.v_uint) != 0) return; - *(value.v_uint) = 1; - - traceset_modes_tree = lttv_attribute_find_subdir(self->stats, - LTTV_STATS_MODES); - nb_trace = lttv_traceset_number(traceset); - - for(i = 0 ; i < nb_trace ; i++) { - tcs = (LttvTraceStats *)(self->parent.parent.traces[i]); - lttv_stats_sum_trace(tcs); - main_tree = tcs->stats; - trace_modes_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_MODES); - lttv_attribute_recursive_add(traceset_modes_tree, trace_modes_tree); - } -} - - -lttv_stats_add_event_hooks(LttvTracesetStats *self) -{ - LttvTraceset *traceset = self->parent.parent.ts; - - guint i, j, k, nb_trace, nb_tracefile; - - LttFacility *f; - - LttEventType *et; - - LttvTraceStats *ts; - - LttvTracefileStats *tfs; - - void *hook_data; - - GArray *hooks, *before_hooks, *after_hooks; - - LttvTraceHook hook; - - LttvAttributeValue val; - - nb_trace = lttv_traceset_number(traceset); - for(i = 0 ; i < nb_trace ; i++) { - ts = (LttvTraceStats *)self->parent.parent.traces[i]; - - /* Find the eventtype id for the following events and register the - associated by id hooks. */ - - hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook)); - g_array_set_size(hooks, 7); - - lttv_trace_find_hook(ts->parent.parent.t, "core","syscall_entry", - "syscall_id", NULL, NULL, before_syscall_entry, - &g_array_index(hooks, LttvTraceHook, 0)); - - lttv_trace_find_hook(ts->parent.parent.t, "core", "syscall_exit", NULL, - NULL, NULL, before_syscall_exit, - &g_array_index(hooks, LttvTraceHook, 1)); - - lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_entry", "trap_id", - NULL, NULL, before_trap_entry, - &g_array_index(hooks, LttvTraceHook, 2)); - - lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_exit", NULL, NULL, - NULL, before_trap_exit, &g_array_index(hooks, LttvTraceHook, 3)); - - lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_entry", "irq_id", - NULL, NULL, before_irq_entry, &g_array_index(hooks, LttvTraceHook, 4)); - - lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_exit", NULL, NULL, - NULL, before_irq_exit, &g_array_index(hooks, LttvTraceHook, 5)); - - lttv_trace_find_hook(ts->parent.parent.t, "core", "schedchange", "in", - "out", "out_state", before_schedchange, - &g_array_index(hooks, LttvTraceHook, 6)); - - before_hooks = hooks; - - hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook)); - g_array_set_size(hooks, 8); - - lttv_trace_find_hook(ts->parent.parent.t, "core","syscall_entry", - "syscall_id", NULL, NULL, after_syscall_entry, - &g_array_index(hooks, LttvTraceHook, 0)); - - lttv_trace_find_hook(ts->parent.parent.t, "core", "syscall_exit", NULL, - NULL, NULL, after_syscall_exit, - &g_array_index(hooks, LttvTraceHook, 1)); - - lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_entry", "trap_id", - NULL, NULL, after_trap_entry, &g_array_index(hooks, LttvTraceHook, 2)); - - lttv_trace_find_hook(ts->parent.parent.t, "core", "trap_exit", NULL, NULL, - NULL, after_trap_exit, &g_array_index(hooks, LttvTraceHook, 3)); - - lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_entry", "irq_id", - NULL, NULL, after_irq_entry, &g_array_index(hooks, LttvTraceHook, 4)); - - lttv_trace_find_hook(ts->parent.parent.t, "core", "irq_exit", NULL, NULL, - NULL, after_irq_exit, &g_array_index(hooks, LttvTraceHook, 5)); - - lttv_trace_find_hook(ts->parent.parent.t, "core", "process_fork", - "child_pid", NULL, NULL, process_fork, - &g_array_index(hooks, LttvTraceHook, 6)); - - lttv_trace_find_hook(ts->parent.parent.t, "core", "process_exit", NULL, - NULL, NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 7)); - - after_hooks = hooks; - - /* Add these hooks to each before_event_by_id hooks list */ - - nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.parent.t) + - ltt_trace_per_cpu_tracefile_number(ts->parent.parent.t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfs = LTTV_TRACEFILE_STATS(ts->parent.parent.tracefiles[j]); - lttv_hooks_add(tfs->parent.parent.after_event, every_event, NULL); - - for(k = 0 ; k < before_hooks->len ; k++) { - hook = g_array_index(before_hooks, LttvTraceHook, k); - lttv_hooks_add(lttv_hooks_by_id_find( - tfs->parent.parent.before_event_by_id, - hook.id), hook.h, &g_array_index(before_hooks, LttvTraceHook, k)); - } - for(k = 0 ; k < after_hooks->len ; k++) { - hook = g_array_index(after_hooks, LttvTraceHook, k); - lttv_hooks_add(lttv_hooks_by_id_find( - tfs->parent.parent.after_event_by_id, - hook.id), hook.h, &g_array_index(after_hooks, LttvTraceHook, k)); - } - } - lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS, - LTTV_POINTER, &val); - *(val.v_pointer) = before_hooks; - lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS, - LTTV_POINTER, &val); - *(val.v_pointer) = after_hooks; - } -} - - -lttv_stats_remove_event_hooks(LttvTracesetStats *self) -{ - LttvTraceset *traceset = self->parent.parent.ts; - - guint i, j, k, nb_trace, nb_tracefile; - - LttvTraceStats *ts; - - LttvTracefileStats *tfs; - - void *hook_data; - - GArray *before_hooks, *after_hooks; - - LttvTraceHook hook; - - LttvAttributeValue val; - - nb_trace = lttv_traceset_number(traceset); - for(i = 0 ; i < nb_trace ; i++) { - ts = LTTV_TRACE_STATS(self->parent.parent.traces[i]); - lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS, - LTTV_POINTER, &val); - before_hooks = *(val.v_pointer); - lttv_attribute_find(self->parent.parent.a, LTTV_STATS_AFTER_HOOKS, - LTTV_POINTER, &val); - after_hooks = *(val.v_pointer); - - /* Add these hooks to each before_event_by_id hooks list */ - - nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.parent.t) + - ltt_trace_per_cpu_tracefile_number(ts->parent.parent.t); - - for(j = 0 ; j < nb_tracefile ; j++) { - tfs = LTTV_TRACEFILE_STATS(ts->parent.parent.tracefiles[j]); - lttv_hooks_remove_data(tfs->parent.parent.after_event, every_event, - NULL); - - for(k = 0 ; k < before_hooks->len ; k++) { - hook = g_array_index(before_hooks, LttvTraceHook, k); - lttv_hooks_remove_data( - lttv_hooks_by_id_find(tfs->parent.parent.before_event_by_id, - hook.id), hook.h, &g_array_index(before_hooks, LttvTraceHook, k)); - } - for(k = 0 ; k < after_hooks->len ; k++) { - hook = g_array_index(after_hooks, LttvTraceHook, k); - lttv_hooks_remove_data( - lttv_hooks_by_id_find(tfs->parent.parent.after_event_by_id, - hook.id), hook.h, &g_array_index(after_hooks, LttvTraceHook, k)); - } - } - g_debug("lttv_stats_remove_event_hooks()"); - g_array_free(before_hooks, TRUE); - g_array_free(after_hooks, TRUE); - } -} - - -static void module_init() -{ - LTTV_STATS_PROCESS_UNKNOWN = g_quark_from_string("unknown process"); - LTTV_STATS_PROCESSES = g_quark_from_string("processes"); - LTTV_STATS_CPU = g_quark_from_string("cpu"); - LTTV_STATS_MODE_TYPES = g_quark_from_string("mode_types"); - LTTV_STATS_MODES = g_quark_from_string("modes"); - LTTV_STATS_SUBMODES = g_quark_from_string("submodes"); - LTTV_STATS_EVENT_TYPES = g_quark_from_string("event_types"); - LTTV_STATS_CPU_TIME = g_quark_from_string("cpu time"); - LTTV_STATS_ELAPSED_TIME = g_quark_from_string("elapsed time"); - LTTV_STATS_EVENTS = g_quark_from_string("events"); - LTTV_STATS_EVENTS_COUNT = g_quark_from_string("events count"); - LTTV_STATS_BEFORE_HOOKS = g_quark_from_string("saved stats before hooks"); - LTTV_STATS_AFTER_HOOKS = g_quark_from_string("saved stats after hooks"); - LTTV_STATS_USE_COUNT = g_quark_from_string("stats_use_count"); - LTTV_STATS = g_quark_from_string("statistics"); - LTTV_STATS_TRACEFILES = g_quark_from_string("tracefiles statistics"); - LTTV_STATS_SUMMED = g_quark_from_string("statistics summed"); -} - -static void module_destroy() -{ -} - - -LTTV_MODULE("stats", "Compute processes statistics", \ - "Accumulate statistics for event types, processes and CPUs", \ - module_init, module_destroy, "state"); - -/* Change the places where stats are called (create/read/write stats) - - Check for options in batchtest.c to reduce writing and see what tests are - best candidates for performance analysis. Once OK, commit, move to main - and run tests. Update the gui for statistics. */ diff --git a/ltt/branches/poly/lttv/main/traceset.c b/ltt/branches/poly/lttv/main/traceset.c deleted file mode 100644 index aa536488..00000000 --- a/ltt/branches/poly/lttv/main/traceset.c +++ /dev/null @@ -1,189 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - - -#include -#include - -/* A trace is a sequence of events gathered in the same tracing session. The - events may be stored in several tracefiles in the same directory. - A trace set is defined when several traces are to be analyzed together, - possibly to study the interactions between events in the different traces. -*/ - -struct _LttvTraceset { - char * filename; - GPtrArray *traces; - LttvAttribute *a; -}; - - -struct _LttvTrace { - LttTrace *t; - LttvAttribute *a; - guint ref_count; -}; - - -LttvTraceset *lttv_traceset_new() -{ - LttvTraceset *s; - - s = g_new(LttvTraceset, 1); - s->filename = NULL; - s->traces = g_ptr_array_new(); - s->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); - return s; -} - -char * lttv_traceset_name(LttvTraceset * s) -{ - return s->filename; -} - -LttvTrace *lttv_trace_new(LttTrace *t) -{ - LttvTrace *new_trace; - - new_trace = g_new(LttvTrace, 1); - new_trace->a = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL); - new_trace->t = t; - new_trace->ref_count = 0; - return new_trace; -} - - -LttvTraceset *lttv_traceset_copy(LttvTraceset *s_orig) -{ - int i; - LttvTraceset *s; - LttvTrace * trace; - - s = g_new(LttvTraceset, 1); - s->filename = NULL; - s->traces = g_ptr_array_new(); - for(i=0;itraces->len;i++) - { - trace = g_ptr_array_index(s_orig->traces, i); - trace->ref_count++; - - /*CHECK this used ltt_trace_copy while it may not be needed. Need to - define how traces and tracesets are shared */ - g_ptr_array_add( - s->traces, - g_ptr_array_index(s_orig->traces, i)); - } - s->a = LTTV_ATTRIBUTE(lttv_iattribute_deep_copy(LTTV_IATTRIBUTE(s_orig->a))); - return s; -} - - -LttvTraceset *lttv_traceset_load(const gchar *filename) -{ - LttvTraceset *s = g_new(LttvTraceset,1); - FILE *tf; - - s->filename = g_strdup(filename); - tf = fopen(filename,"r"); - - g_critical("NOT IMPLEMENTED : load traceset data from a XML file"); - - fclose(tf); - return s; -} - -gint lttv_traceset_save(LttvTraceset *s) -{ - FILE *tf; - - tf = fopen(s->filename, "w"); - - g_critical("NOT IMPLEMENTED : save traceset data in a XML file"); - - fclose(tf); - return 0; -} - -void lttv_traceset_destroy(LttvTraceset *s) -{ - g_ptr_array_free(s->traces, TRUE); - g_object_unref(s->a); - g_free(s); -} - -void lttv_trace_destroy(LttvTrace *t) -{ - g_object_unref(t->a); - g_free(t); -} - - -void lttv_traceset_add(LttvTraceset *s, LttvTrace *t) -{ - t->ref_count++; - g_ptr_array_add(s->traces, t); -} - - -unsigned lttv_traceset_number(LttvTraceset *s) -{ - return s->traces->len; -} - - -LttvTrace *lttv_traceset_get(LttvTraceset *s, unsigned i) -{ - g_assert(s->traces->len > i); - return ((LttvTrace *)s->traces->pdata[i]); -} - - -void lttv_traceset_remove(LttvTraceset *s, unsigned i) -{ - LttvTrace * t; - g_assert(s->traces->len > i); - t = (LttvTrace *)s->traces->pdata[i]; - t->ref_count--; - g_ptr_array_remove_index(s->traces, i); -} - - -/* A set of attributes is attached to each trace set, trace and tracefile - to store user defined data as needed. */ - -LttvAttribute *lttv_traceset_attribute(LttvTraceset *s) -{ - return s->a; -} - - -LttvAttribute *lttv_trace_attribute(LttvTrace *t) -{ - return t->a; -} - - -LttTrace *lttv_trace(LttvTrace *t) -{ - return t->t; -} - -guint lttv_trace_get_ref_number(LttvTrace * t) -{ - return t->ref_count; -} diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c index e2138cdb..7f4ee2f4 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/drawing.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.c b/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.c index 6d535fa5..9445141e 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/drawitem.c @@ -102,7 +102,7 @@ #include #include -#include +#include #include #include "drawitem.h" diff --git a/ltt/branches/poly/lttv/modules/gui/detailedevents/events.c b/ltt/branches/poly/lttv/modules/gui/detailedevents/events.c index 43b81d03..51d51aa1 100644 --- a/ltt/branches/poly/lttv/modules/gui/detailedevents/events.c +++ b/ltt/branches/poly/lttv/modules/gui/detailedevents/events.c @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/ltt/branches/poly/lttv/modules/gui/main/src/init_module.c b/ltt/branches/poly/lttv/modules/gui/main/src/init_module.c index 781844ad..c1fcf1fc 100644 --- a/ltt/branches/poly/lttv/modules/gui/main/src/init_module.c +++ b/ltt/branches/poly/lttv/modules/gui/main/src/init_module.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/ltt/branches/poly/lttv/modules/gui/mainlib/Makefile.am b/ltt/branches/poly/lttv/modules/gui/mainlib/Makefile.am index b977108c..4562409b 100644 --- a/ltt/branches/poly/lttv/modules/gui/mainlib/Makefile.am +++ b/ltt/branches/poly/lttv/modules/gui/mainlib/Makefile.am @@ -15,4 +15,14 @@ lib_LTLIBRARIES = libmainwinapi.la libmainwinapi_la_SOURCES = toolbar.c menu.c gtktraceset.c #libmainwinapi_la_LDFLAGS = -L${top_srcdir}/lttv/modules/gui/API -lcustomBox +lttvguiinclude_HEADERS = \ + common.h\ + gtkdirsel.h\ + gtkmultivpaned.h\ + gtktraceset.h\ + lttvfilter.h\ + mainwindow.h\ + menu.h\ + toolbar.h + EXTRA_DIST = diff --git a/ltt/branches/poly/lttv/modules/gui/mainlib/common.h b/ltt/branches/poly/lttv/modules/gui/mainlib/common.h new file mode 100644 index 00000000..a3e557f3 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/mainlib/common.h @@ -0,0 +1,43 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Xiangxiu Yang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef COMMON_H +#define COMMON_H + +#include +#include +#include +#include + +#define MAX_NUMBER_EVENT "MAX_NUMBER_EVENT" +#define TRACESET_TIME_SPAN "TRACESET_TIME_SPAN" + +typedef struct _MainWindow MainWindow; +typedef struct _Tab Tab; + +/* constructor of the viewer */ +typedef GtkWidget * (*lttv_constructor)(MainWindow * main_window, + LttvTracesetSelector * s, char *key); +typedef lttv_constructor view_constructor; + +typedef struct _TimeWindow { + LttTime start_time; + LttTime time_width; +} TimeWindow; + +#endif // COMMON_H diff --git a/ltt/branches/poly/lttv/modules/gui/mainlib/gtkdirsel.h b/ltt/branches/poly/lttv/modules/gui/mainlib/gtkdirsel.h new file mode 100644 index 00000000..103ced2d --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/mainlib/gtkdirsel.h @@ -0,0 +1,115 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Xiangxiu Yang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + + +#ifndef __GTK_DIR_SEL_H__ +#define __GTK_DIR_SEL_H__ + + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define GTK_TYPE_DIR_SELECTION (gtk_dir_selection_get_type ()) +#define GTK_DIR_SELECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_DIR_SELECTION, GtkDirSelection)) +#define GTK_DIR_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_DIR_SELECTION, GtkDirSelectionClass)) +#define GTK_IS_DIR_SELECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_DIR_SELECTION)) +#define GTK_IS_DIR_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_DIR_SELECTION)) +#define GTK_DIR_SELECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_DIR_SELECTION, GtkDirSelectionClass)) + + +typedef struct _GtkDirSelection GtkDirSelection; +typedef struct _GtkDirSelectionClass GtkDirSelectionClass; + +struct _GtkDirSelection +{ + GtkDialog parent_instance; + + GtkWidget *dir_list; + GtkWidget *file_list; + GtkWidget *selection_entry; + GtkWidget *selection_text; + GtkWidget *main_vbox; + GtkWidget *ok_button; + GtkWidget *cancel_button; + GtkWidget *help_button; + GtkWidget *history_pulldown; + GtkWidget *history_menu; + GList *history_list; + GtkWidget *fileop_dialog; + GtkWidget *fileop_entry; + gchar *fileop_file; + gpointer cmpl_state; + + GtkWidget *fileop_c_dir; + GtkWidget *fileop_del_file; + GtkWidget *fileop_ren_file; + + GtkWidget *button_area; + GtkWidget *action_area; + + GPtrArray *selected_names; + gchar *last_selected; +}; + +struct _GtkDirSelectionClass +{ + GtkDialogClass parent_class; + + /* Padding for future expansion */ + void (*_gtk_reserved1) (void); + void (*_gtk_reserved2) (void); + void (*_gtk_reserved3) (void); + void (*_gtk_reserved4) (void); +}; + + +GType gtk_dir_selection_get_type (void) G_GNUC_CONST; +GtkWidget* gtk_dir_selection_new (const gchar *title); +void gtk_dir_selection_set_filename (GtkDirSelection *filesel, + const gchar *filename); +/* This function returns the selected filename in the C runtime's + * multibyte string encoding, which may or may not be the same as that + * used by GDK (UTF-8). To convert to UTF-8, call g_filename_to_utf8(). + * The returned string points to a statically allocated buffer and + * should be copied away. + */ +G_CONST_RETURN gchar* gtk_dir_selection_get_filename (GtkDirSelection *filesel); + +void gtk_dir_selection_complete (GtkDirSelection *filesel, + const gchar *pattern); +void gtk_dir_selection_show_fileop_buttons (GtkDirSelection *filesel); +void gtk_dir_selection_hide_fileop_buttons (GtkDirSelection *filesel); + +gchar** gtk_dir_selection_get_selections (GtkDirSelection *filesel); +const gchar * gtk_dir_selection_get_dir (GtkDirSelection *filesel); +void gtk_dir_selection_set_select_multiple (GtkDirSelection *filesel, + gboolean select_multiple); +gboolean gtk_dir_selection_get_select_multiple (GtkDirSelection *filesel); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GTK_DIR_SEL_H__ */ diff --git a/ltt/branches/poly/lttv/modules/gui/mainlib/gtkmultivpaned.h b/ltt/branches/poly/lttv/modules/gui/mainlib/gtkmultivpaned.h new file mode 100644 index 00000000..ff8334e2 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/mainlib/gtkmultivpaned.h @@ -0,0 +1,92 @@ + +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Xiangxiu Yang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef __GTK_MULTI_VPANED_H__ +#define __GTK_MULTI_VPANED_H__ + + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define GTK_TYPE_MULTI_VPANED (gtk_multi_vpaned_get_type ()) +#define GTK_MULTI_VPANED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MULTI_VPANED, GtkMultiVPaned)) +#define GTK_MULTI_VPANED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MULTI_VPANED, GtkMultiVPanedClass)) +#define GTK_IS_MULTI_VPANED(obj ) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MULTI_VPANED)) +#define GTK_IS_MULTI_VPANED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MULTI_VPANED)) +#define GTK_MULTI_VPANED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MULTI_VPANED, GtkMultiVPanedClass)) + + +typedef struct _GtkMultiVPaned GtkMultiVPaned; +typedef struct _GtkMultiVPanedClass GtkMultiVPanedClass; + +struct _GtkMultiVPaned +{ + GtkPaned container; + + /*< public >*/ + GtkPaned * first_pane; + GtkPaned * last_pane; + GtkPaned * focused_pane; + GtkPaned * iter; + guint num_children; + + GtkWidget * vbox; + // GtkWidget * scrollWindow; + // GtkWidget * viewport; + GtkWidget * hscrollbar; + GtkAdjustment *hadjust; + MainWindow * mw; +}; + +struct _GtkMultiVPanedClass +{ + GtkPanedClass parent_class; +}; + + +GType gtk_multi_vpaned_get_type (void) G_GNUC_CONST; +GtkWidget* gtk_multi_vpaned_new (void); + +void gtk_multi_vpaned_set_focus (GtkWidget * widget, gpointer user_data); +void gtk_multi_vpaned_widget_add(GtkMultiVPaned * multi_vpaned, GtkWidget * widget1); +void gtk_multi_vpaned_widget_delete(GtkMultiVPaned * multi_vpaned); +void gtk_multi_vpaned_widget_move_up(GtkMultiVPaned * multi_vpaned); +void gtk_multi_vpaned_widget_move_down(GtkMultiVPaned * multi_vpaned); +void gtk_multi_vpaned_set_adjust(GtkMultiVPaned * multi_vpaned, gboolean first_time); +void gtk_multi_vpaned_set_data(GtkMultiVPaned * multi_vpaned, char * key, gpointer value); +gpointer gtk_multi_vpaned_get_data(GtkMultiVPaned * multi_vpaned, char * key); +GtkWidget * gtk_multi_vpaned_get_widget(GtkMultiVPaned * multi_vpaned); +GtkWidget * gtk_multi_vpaned_get_first_widget(GtkMultiVPaned * multi_vpaned); +GtkWidget * gtk_multi_vpaned_get_next_widget(GtkMultiVPaned * multi_vpaned); +void gtk_multi_vpaned_set_scroll_value(GtkMultiVPaned * multi_vpaned, double value); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GTK_MULTI_VPANED_H__ */ diff --git a/ltt/branches/poly/lttv/modules/gui/mainlib/gtktraceset.c b/ltt/branches/poly/lttv/modules/gui/mainlib/gtktraceset.c index 51884a3f..772583f9 100644 --- a/ltt/branches/poly/lttv/modules/gui/mainlib/gtktraceset.c +++ b/ltt/branches/poly/lttv/modules/gui/mainlib/gtktraceset.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/ltt/branches/poly/lttv/modules/gui/mainlib/gtktraceset.h b/ltt/branches/poly/lttv/modules/gui/mainlib/gtktraceset.h new file mode 100644 index 00000000..19035482 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/mainlib/gtktraceset.h @@ -0,0 +1,476 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Xiangxiu Yang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/* +CHECK Rename to viewer.h + +Things that can happen to a viewer: + +update_time_window +update_current_time +update_traceset +update_filter +show_viewer +update_dividor +?? Reshape, damage ?? + +Things that a viewer can do: + +update_status +set_time_window +set_current_time +update_traceset? +update_filter? +show_viewer? +set_focused_pane +set_hpane_dividor +*/ + + + + +/*! \file gtktraceset.h + * \brief API used by the graphical viewers to interact with their top window. + * + * Main window (gui module) is the place to contain and display viewers. + * Viewers (lttv plugins) interacte with main window through this API and + * events sent by gtk. + * This header file should be included in each graphic module. + * This library is used by graphical modules to interact with the + * tracesetWindow. + * + */ + +#include +#include +#include +#include +#include + +/** + * Function to register a view constructor so that main window can generate + * a toolbar item for the viewer in order to generate a new instance easily. + * It will be called by init function of the module. + * @param ButtonPixmap image shown on the toolbar item. + * @param tooltip tooltip of the toolbar item. + * @param view_constructor constructor of the viewer. + */ + +void toolbar_item_reg(char ** pixmap, char *tooltip, lttv_constructor view_constructor); + + +/** + * Function to unregister the viewer's constructor, release the space + * occupied by pixmap, tooltip and constructor of the viewer. + * It will be called when a module is unloaded. + * @param view_constructor constructor of the viewer which is used as + * a reference to find out where the pixmap and tooltip are. + */ + +void toolbar_item_unreg(lttv_constructor view_constructor); + + +/** + * Function to register a view constructor so that main window can generate + * a menu item for the viewer in order to generate a new instance easily. + * It will be called by init function of the module. + * @param menu_path path of the menu item. + * @param menu_text text of the menu item. + * @param view_constructor constructor of the viewer. + */ + +void menu_item_reg(char *menu_path, char *menu_text, lttv_constructor view_constructor); + + +/** + * Function to unregister the viewer's constructor, release the space + * occupied by menu_path, menu_text and constructor of the viewer. + * It will be called when a module is unloaded. + * @param view_constructor constructor of the viewer which is used as + * a reference to find out where the menu_path and menu_text are. + */ + +void menu_item_unreg(lttv_constructor view_constructor); + + +/** + * Update the status bar whenever something changed in the viewer. + * @param main_win the main window the viewer belongs to. + * @param info the message which will be shown in the status bar. + */ + +void update_status(MainWindow *main_win, char *info); + + +/** + * Function to get the current time window of the current tab. + * It will be called by a viewer's hook function to update the + * time window of the viewer and also be called by the constructor + * of the viewer. + * @param main_win the main window the viewer belongs to. + * @param time_interval a pointer where time interval will be stored. + */ + +void get_time_window(MainWindow *main_win, TimeWindow *time_window); + + +/** + * Function to set the time interval of the current tab. + * It will be called by a viewer's signal handle associated with + * the move_slider signal + * @param main_win the main window the viewer belongs to. + * @param time_interval a pointer where time interval is stored. + */ + +void set_time_window(MainWindow *main_win, TimeWindow *time_window); + +/** + * Function to get the current time/event of the current tab. + * It will be called by a viewer's hook function to update the + * current time/event of the viewer. + * @param main_win the main window the viewer belongs to. + * @param time a pointer where time will be stored. + */ + +void get_current_time(MainWindow *main_win, LttTime *time); + + +/** + * Function to set the current time/event of the current tab. + * It will be called by a viewer's signal handle associated with + * the button-release-event signal + * @param main_win the main window the viewer belongs to. + * @param time a pointer where time is stored. + */ + +void set_current_time(MainWindow *main_win, LttTime *time); + + +/** + * Function to get the traceset from the current tab. + * It will be called by the constructor of the viewer and also be + * called by a hook funtion of the viewer to update its traceset. + * @param main_win the main window the viewer belongs to. + * @param traceset a pointer to a traceset. + */ + +//void get_traceset(MainWindow *main_win, Traceset *traceset); + + +/** + * Function to get the filter of the current tab. + * It will be called by the constructor of the viewer and also be + * called by a hook funtion of the viewer to update its filter. + * @param main_win, the main window the viewer belongs to. + * @param filter, a pointer to a filter. + */ + +//void get_filter(MainWindow *main_win, Filter *filter); + + +/** + * Function to register a hook function for a viewer to set/update its + * time interval. + * It will be called by the constructor of the viewer. + * @param hook hook function of the viewer. Takes a TimeInterval* as call_data. + * @param hook_data hook data associated with the hook function. + * @param main_win the main window the viewer belongs to. + */ + +void reg_update_time_window(LttvHook hook, gpointer hook_data, + MainWindow * main_win); + + +/** + * Function to unregister a viewer's hook function which is used to + * set/update the time interval of the viewer. + * It will be called by the destructor of the viewer. + * @param hook hook function of the viewer. Takes a TimeInterval as call_data. + * @param hook_data hook data associated with the hook function. + * @param main_win the main window the viewer belongs to. + */ + +void unreg_update_time_window(LttvHook hook, gpointer hook_data, + MainWindow * main_win); + + +/** + * Function to register a hook function for a viewer to set/update its + * traceset. + * It will be called by the constructor of the viewer. + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + * @param main_win the main window the viewer belongs to. + */ + +void reg_update_traceset(LttvHook hook, gpointer hook_data, + MainWindow * main_win); + + +/** + * Function to unregister a viewer's hook function which is used to + * set/update the traceset of the viewer. + * It will be called by the destructor of the viewer. + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + * @param main_win the main window the viewer belongs to. + */ + +void unreg_update_traceset(LttvHook hook, gpointer hook_data, + MainWindow * main_win); + + +/** + * Function to redraw each viewer belonging to the current tab + * @param main_win the main window the viewer belongs to. + */ + +void update_traceset(MainWindow * main_win); + + +/** + * Function to register a hook function for a viewer to set/update its + * filter. + * It will be called by the constructor of the viewer. + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + * @param main_win the main window the viewer belongs to. + */ + +void reg_update_filter(LttvHook hook, gpointer hook_data, + MainWindow *main_win); + + +/** + * Function to unregister a viewer's hook function which is used to + * set/update the filter of the viewer. + * It will be called by the destructor of the viewer. + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + * @param main_win the main window the viewer belongs to. + */ + +void unreg_update_filter(LttvHook hook, gpointer hook_data, + MainWindow * main_win); + + +/** + * Function to register a hook function for a viewer to set/update its + * current time. + * It will be called by the constructor of the viewer. + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + * @param main_win the main window the viewer belongs to. + */ + +void reg_update_current_time(LttvHook hook, gpointer hook_data, + MainWindow *main_win); + + +/** + * Function to unregister a viewer's hook function which is used to + * set/update the current time of the viewer. + * It will be called by the destructor of the viewer. + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + * @param main_win the main window the viewer belongs to. + */ + +void unreg_update_current_time(LttvHook hook, gpointer hook_data, + MainWindow * main_win); + + +/** + * Function to register a hook function for a viewer to show + *the content of the viewer. + * It will be called by the constructor of the viewer. + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + * @param main_win the main window the viewer belongs to. + */ + +void reg_show_viewer(LttvHook hook, gpointer hook_data, + MainWindow *main_win); + + +/** + * Function to unregister a viewer's hook function which is used to + * show the content of the viewer.. + * It will be called by the destructor of the viewer. + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + * @param main_win the main window the viewer belongs to. + */ + +void unreg_show_viewer(LttvHook hook, gpointer hook_data, + MainWindow * main_win); + + +/** + * Function to show each viewer in the current tab. + * It will be called by main window after it called process_traceset + * @param main_win the main window the viewer belongs to. + */ + +void show_viewer(MainWindow *main_win); + + +/** + * Function to set the focused pane (viewer). + * It will be called by a viewer's signal handle associated with + * the grab_focus signal + * @param main_win the main window the viewer belongs to. + * @param paned a pointer to a pane where the viewer is contained. + */ + +void set_focused_pane(MainWindow *main_win, gpointer paned); + + +/** + * Function to register a hook function for a viewer to set/update the + * dividor of the hpane. + * It will be called by the constructor of the viewer. + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + * @param main_win the main window the viewer belongs to. + */ + +void reg_update_dividor(LttvHook hook, gpointer hook_data, + MainWindow *main_win); + + +/** + * Function to unregister a viewer's hook function which is used to + * set/update hpane's dividor of the viewer. + * It will be called by the destructor of the viewer. + * @param hook hook function of the viewer. + * @param hook_data hook data associated with the hook function. + * @param main_win the main window the viewer belongs to. + */ + +void unreg_update_dividor(LttvHook hook, gpointer hook_data, + MainWindow *main_win); + + +/** + * Function to set the position of the hpane's dividor (viewer). + * It will be called by a viewer's signal handle associated with + * the motion_notify_event event/signal + * @param main_win the main window the viewer belongs to. + * @param position position of the hpane's dividor. + */ + +void set_hpane_dividor(MainWindow *main_win, gint position); + + +/* +CHECK These functions really should not appear here. Directr calls would +be OK unless there is a linker problem. +*/ +/** + * Function to process traceset. It will call lttv_process_trace, + * each view will call this api to get events. + * @param main_win the main window the viewer belongs to. + * @param start the start time of the first event to be processed. + * @param end the end time of the last event to be processed. + */ + +void process_traceset_api(MainWindow *main_win, LttTime start, + LttTime end, unsigned maxNumEvents); + + +/** + * Function to add hooks into the context of a traceset, + * before reading events from traceset, viewer will call this api to + * register hooks + * @param main_win the main window the viewer belongs to. + * @param LttvHooks hooks to be registered. + */ + +void context_add_hooks_api(MainWindow *main_win , + LttvHooks *before_traceset, + LttvHooks *after_traceset, + LttvHooks *check_trace, + LttvHooks *before_trace, + LttvHooks *after_trace, + LttvHooks *check_tracefile, + LttvHooks *before_tracefile, + LttvHooks *after_tracefile, + LttvHooks *check_event, + LttvHooks *before_event, + LttvHooks *after_event); + + +/** + * Function to remove hooks from the context of a traceset, + * before reading events from traceset, viewer will call this api to + * unregister hooks + * @param main_win the main window the viewer belongs to. + * @param LttvHooks hooks to be registered. + */ + +void context_remove_hooks_api(MainWindow *main_win , + LttvHooks *before_traceset, + LttvHooks *after_traceset, + LttvHooks *check_trace, + LttvHooks *before_trace, + LttvHooks *after_trace, + LttvHooks *check_tracefile, + LttvHooks *before_tracefile, + LttvHooks *after_tracefile, + LttvHooks *check_event, + LttvHooks *before_event, + LttvHooks *after_event); + + +/** + * Function to get the life span of the traceset + * @param main_win the main window the viewer belongs to. + * @param start start time of the traceset. + * @param end end time of the traceset. + */ + +void get_traceset_time_span(MainWindow *main_win, TimeInterval *time_span); + + +/** + * Function to add/remove event hooks for state + * @param main_win the main window the viewer belongs to. + */ + +void state_add_event_hooks_api(MainWindow *main_win ); +void state_remove_event_hooks_api(MainWindow *main_win ); + + +/** + * Function to add/remove event hooks for stats + * @param main_win the main window the viewer belongs to. + */ + +void stats_add_event_hooks_api(MainWindow *main_win ); +void stats_remove_event_hooks_api(MainWindow *main_win ); + + +/** + * Function to get the stats of the traceset + * @param main_win the main window the viewer belongs to. + */ + +LttvTracesetStats* get_traceset_stats_api(MainWindow *main_win); + +LttvTracesetContext* get_traceset_context(MainWindow *main_win); diff --git a/ltt/branches/poly/lttv/modules/gui/mainlib/lttvfilter.h b/ltt/branches/poly/lttv/modules/gui/mainlib/lttvfilter.h new file mode 100644 index 00000000..f2dab415 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/mainlib/lttvfilter.h @@ -0,0 +1,89 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Xiangxiu Yang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef LTTV_FILTER_H +#define LTTV_FILTER_H + +#include + + +typedef struct _LttvTracesetSelector LttvTracesetSelector; +typedef struct _LttvTraceSelector LttvTraceSelector; +typedef struct _LttvTracefileSelector LttvTracefileSelector; +typedef struct _LttvEventtypeSelector LttvEventtypeSelector; + + +LttvTracesetSelector *lttv_traceset_selector_new(char * name); +LttvTraceSelector *lttv_trace_selector_new(LttTrace *t); +LttvTracefileSelector *lttv_tracefile_selector_new(LttTracefile *t); +LttvEventtypeSelector *lttv_eventtype_selector_new(LttEventType * et); +void lttv_traceset_selector_destroy(LttvTracesetSelector *s); +void lttv_trace_selector_destroy(LttvTraceSelector *t); +void lttv_tracefile_selector_destroy(LttvTracefileSelector *t); +void lttv_eventtype_selector_destroy(LttvEventtypeSelector *t); + + +void lttv_traceset_selector_trace_add(LttvTracesetSelector *s, + LttvTraceSelector *t); +unsigned lttv_traceset_selector_trace_number(LttvTracesetSelector *s); +LttvTraceSelector *lttv_traceset_selector_trace_get(LttvTracesetSelector *s, + unsigned i); +void lttv_traceset_selector_trace_remove(LttvTracesetSelector *s, + unsigned i); + + +void lttv_trace_selector_tracefile_add(LttvTraceSelector *s, + LttvTracefileSelector *t); +unsigned lttv_trace_selector_tracefile_number(LttvTraceSelector *s); +LttvTracefileSelector *lttv_trace_selector_tracefile_get(LttvTraceSelector *s, + unsigned i); +void lttv_trace_selector_tracefile_remove(LttvTraceSelector *s, unsigned i); + +void lttv_trace_selector_eventtype_add(LttvTraceSelector *s, + LttvEventtypeSelector *et); +unsigned lttv_trace_selector_eventtype_number(LttvTraceSelector *s); +LttvEventtypeSelector *lttv_trace_selector_eventtype_get(LttvTraceSelector *s, + unsigned i); +void lttv_trace_selector_eventtype_remove(LttvTraceSelector *s, unsigned i); + + +void lttv_tracefile_selector_eventtype_add(LttvTracefileSelector *s, + LttvEventtypeSelector *et); +unsigned lttv_tracefile_selector_eventtype_number(LttvTracefileSelector *s); +LttvEventtypeSelector *lttv_tracefile_selector_eventtype_get(LttvTracefileSelector *s, + unsigned i); +void lttv_tracefile_selector_eventtype_remove(LttvTracefileSelector *s, unsigned i); + + +void lttv_trace_selector_set_selected(LttvTraceSelector *s, gboolean g); +void lttv_tracefile_selector_set_selected(LttvTracefileSelector *s, gboolean g); +void lttv_eventtype_selector_set_selected(LttvEventtypeSelector *s, gboolean g); +gboolean lttv_trace_selector_get_selected(LttvTraceSelector *s); +gboolean lttv_tracefile_selector_get_selected(LttvTracefileSelector *s); +gboolean lttv_eventtype_selector_get_selected(LttvEventtypeSelector *s); +char * lttv_traceset_selector_get_name(LttvTracesetSelector *s); +char * lttv_trace_selector_get_name(LttvTraceSelector *s); +char * lttv_tracefile_selector_get_name(LttvTracefileSelector *s); +char * lttv_eventtype_selector_get_name(LttvEventtypeSelector *s); + +LttvEventtypeSelector * lttv_eventtype_selector_clone(LttvEventtypeSelector * s); +void lttv_eventtype_selector_copy(LttvTraceSelector *s, LttvTracefileSelector *d); + + +#endif // LTTV_FILTER_H + diff --git a/ltt/branches/poly/lttv/modules/gui/mainlib/mainwindow.h b/ltt/branches/poly/lttv/modules/gui/mainlib/mainwindow.h new file mode 100644 index 00000000..8ef8defb --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/mainlib/mainwindow.h @@ -0,0 +1,100 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Xiangxiu Yang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef _MAIN_WINDOW_ +#define _MAIN_WINDOW_ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +typedef struct _TracesetInfo { + //FIXME? TracesetContext and stats in same or different variable ? + LttvTracesetStats * traceset_context; + LttvTraceset * traceset; +} TracesetInfo ; + + +struct _MainWindow{ + GtkWidget* mwindow; /* Main Window */ + int window_width; + + /* Status bar information */ + // guint MainSBarContextID; /* Context ID of main status bar */ + // guint BegTimeSBarContextID; /* Context ID of BegTime status bar */ + // guint EndTimeSBarContextID; /* Context ID of EndTime status bar */ + + /* Child windows */ + //openTracesetWindow* OpenTracesetWindow;/* Window to get prof and proc file*/ + //viewTimeFrameWindow* ViewTimeFrameWindow;/*Window to select time frame */ + //gotoEventWindow* GotoEventWindow; /*search for event description*/ + //openFilterWindow* OpenFilterWindow; /* Open a filter selection window */ + GtkWidget* help_contents;/* Window to display help contents */ + GtkWidget* about_box; /* Window about information */ + + // lttv_trace_filter * filter; /* trace filter associated with the window */ + + /* Attributes for trace reading hooks local to the main window */ + LttvIAttribute * attributes; + + Tab * tab; + Tab * current_tab; + + GHashTable * hash_menu_item; + GHashTable * hash_toolbar_item; +}; + + +struct _Tab{ + GtkWidget * label; + GtkMultiVPaned * multi_vpaned; + + // startTime is the left of the visible area. Corresponds to the scrollbar + // value. + // Time_Width is a zoom dependant value (corresponding to page size) + TimeWindow time_window; + + // The current time is the time selected in the visible area by the user, + // not the scrollbar value. + LttTime current_time; + LttvIAttribute * attributes; + + struct _Tab * next; + MainWindow * mw; + + /* Traceset related information */ + TracesetInfo * traceset_info; +}; + +/** + * Remove menu and toolbar item when a module unloaded + */ +void main_window_remove_menu_item(lttv_constructor view_constructor); +void main_window_remove_toolbar_item(lttv_constructor view_constructor); + +#endif /* _MAIN_WINDOW_ */ + + diff --git a/ltt/branches/poly/lttv/modules/gui/mainlib/menu.h b/ltt/branches/poly/lttv/modules/gui/mainlib/menu.h new file mode 100644 index 00000000..ec20c099 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/mainlib/menu.h @@ -0,0 +1,47 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Xiangxiu Yang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef MENU_H +#define MENU_H + +#include + +/* constructor of the viewer */ +//typedef GtkWidget* (*lttv_constructor)(void * main_window); + + +typedef GArray LttvMenus; + +typedef struct _lttv_menu_closure { + lttv_constructor con; + char * menuPath; + char * menuText; +} lttv_menu_closure; + + +LttvMenus *lttv_menus_new(); + +void lttv_menus_destroy(LttvMenus *h); + +void lttv_menus_add(LttvMenus *h, lttv_constructor f, char* menuPath, char * menuText); + +gboolean lttv_menus_remove(LttvMenus *h, lttv_constructor f); + +unsigned lttv_menus_number(LttvMenus *h); + +#endif // MENU_H diff --git a/ltt/branches/poly/lttv/modules/gui/mainlib/toolbar.h b/ltt/branches/poly/lttv/modules/gui/mainlib/toolbar.h new file mode 100644 index 00000000..af12d937 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/gui/mainlib/toolbar.h @@ -0,0 +1,46 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Xiangxiu Yang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef TOOLBAR_H +#define TOOLBAR_H + +#include + +/* constructor of the viewer */ +//typedef GtkWidget* (*lttv_constructor)(void * main_window); + + +typedef GArray LttvToolbars; + +typedef struct _lttv_toolbar_closure { + lttv_constructor con; + char * tooltip; + char ** pixmap; +} lttv_toolbar_closure; + +LttvToolbars *lttv_toolbars_new(); + +void lttv_toolbars_destroy(LttvToolbars *h); + +void lttv_toolbars_add(LttvToolbars *h, lttv_constructor f, char* tooltip, char ** pixmap); + +gboolean lttv_toolbars_remove(LttvToolbars *h, lttv_constructor f); + +unsigned lttv_toolbars_number(LttvToolbars *h); + +#endif // TOOLBAR_H diff --git a/ltt/branches/poly/lttv/modules/gui/statistics/statistics.c b/ltt/branches/poly/lttv/modules/gui/statistics/statistics.c index 9dbd162c..92cee3cc 100644 --- a/ltt/branches/poly/lttv/modules/gui/statistics/statistics.c +++ b/ltt/branches/poly/lttv/modules/gui/statistics/statistics.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/ltt/branches/poly/lttv/modules/text/Makefile.am b/ltt/branches/poly/lttv/modules/text/Makefile.am index a682e35f..88f9235f 100644 --- a/ltt/branches/poly/lttv/modules/text/Makefile.am +++ b/ltt/branches/poly/lttv/modules/text/Makefile.am @@ -5,11 +5,11 @@ LIBS += $(GLIB_LIBS) -lgobject-2.0 -L$(top_srcdir)/ltt -ltraceread libdir = ${lttvplugindir} -lib_LTLIBRARIES = libtextDump.la libbatchAnalysis.la libbatchtest.la +lib_LTLIBRARIES = libtextDump.la libbatchAnalysis.la libtextDump_la_LDFLAGS = -module libtextDump_la_SOURCES = textDump.c libbatchAnalysis_la_LDFLAGS = -module libbatchAnalysis_la_SOURCES = batchAnalysis.c -libbatchtest_la_LDFLAGS = -module -libbatchtest_la_SOURCES = batchtest.c +noinst_HEADERS = \ + batchanalysis.h diff --git a/ltt/branches/poly/lttv/modules/text/batchAnalysis.c b/ltt/branches/poly/lttv/modules/text/batchAnalysis.c index 0d8f1522..1c69df33 100644 --- a/ltt/branches/poly/lttv/modules/text/batchAnalysis.c +++ b/ltt/branches/poly/lttv/modules/text/batchAnalysis.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/ltt/branches/poly/lttv/modules/text/batchanalysis.h b/ltt/branches/poly/lttv/modules/text/batchanalysis.h new file mode 100644 index 00000000..19fda358 --- /dev/null +++ b/ltt/branches/poly/lttv/modules/text/batchanalysis.h @@ -0,0 +1,62 @@ +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2003-2004 Michel Dagenais + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef BATCH_ANALYSIS_H +#define BATCH_ANALYSIS_H + +/* The batch analysis module defines a main traceset and command line options + to specify the traces in the main traceset. It then processes that + traceset calling hooks lists at various stages of the analysis. + + The hooks lists are defined in the global attributes for these various + stages of the analysis. Loaded modules may add hooks to these lists. + Thus, by requesting that a certain module be loaded, the analysis may + produce additional information as the module adds hooks and these hooks + are called during the analysis. + + The hooks lists defined are as follows. These may be split in more + specific lists eventually to select the hooks applicable to state update, + incremental or batch processing... + + /hooks/traceset/before + Before analyzing a traceset. + + /hooks/traceset/after + After analyzing a traceset. + + /hooks/trace/before + Before each trace. + + /hooks/trace/after + After each trace. + + /hooks/tracefile/before + Before each tracefile. + + /hooks/tracefile/after + After each tracefile. + + /hooks/event/before + Before each event. + + /hooks/event/after + After each event. + +*/ + +#endif // BATCH_ANALYSIS_H diff --git a/ltt/branches/poly/lttv/modules/text/batchtest.c b/ltt/branches/poly/lttv/modules/text/batchtest.c deleted file mode 100644 index e57c4414..00000000 --- a/ltt/branches/poly/lttv/modules/text/batchtest.c +++ /dev/null @@ -1,702 +0,0 @@ -/* This file is part of the Linux Trace Toolkit viewer - * Copyright (C) 2003-2004 Michel Dagenais - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/* This module inserts a hook in the program main loop. This hook processes - all the events in the main tracefile while testing the speed and - functionality of the state and stats computations. */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static LttvTraceset *traceset; - -static LttvHooks - *before_traceset, - *after_traceset, - *before_trace, - *after_trace, - *before_tracefile, - *after_tracefile, - *before_event, - *after_event, - *main_hooks; - -static char *a_trace; - -static char *a_dump_tracefiles; - -static char *a_save_sample; - -static int - a_sample_interval, - a_sample_number, - a_save_interval; - -static gboolean - a_trace_event, - a_save_state_copy, - a_test1, - a_test2, - a_test3, - a_test4, - a_test5, - a_test6, - a_test7, - a_test_all; - -LttEventPosition *a_event_position; - -typedef struct _save_state { - guint count; - FILE *fp; - guint interval; - guint position; - guint size; - LttTime *write_time; - guint version; -} SaveState; - - -static void lttv_trace_option(void *hook_data) -{ - LttTrace *trace; - - trace = ltt_trace_open(a_trace); - if(trace == NULL) g_critical("cannot open trace %s", a_trace); - lttv_traceset_add(traceset, lttv_trace_new(trace)); -} - -static double get_time() -{ - GTimeVal gt; - - g_get_current_time(>); - return gt.tv_sec + (double)gt.tv_usec / (double)1000000.0; -} - -static double run_one_test(LttvTracesetState *ts, LttTime start, LttTime end) -{ - double t0, t1; - - int i; - - lttv_traceset_context_add_hooks(&ts->parent, - before_traceset, after_traceset, NULL, before_trace, after_trace, - NULL, before_tracefile, after_tracefile, NULL, before_event, after_event); - - for(i = 0 ; i < lttv_traceset_number(traceset) ; i++) { - ((LttvTraceState *)(ts->parent.traces[i]))->save_interval =a_save_interval; - } - - t0 = get_time(); - lttv_state_traceset_seek_time_closest(ts, start); - lttv_process_traceset(&ts->parent, end, G_MAXULONG); - t1 = get_time(); - - lttv_traceset_context_remove_hooks(&ts->parent, - before_traceset, after_traceset, NULL, before_trace, after_trace, - NULL, before_tracefile, after_tracefile, NULL, before_event, after_event); - - return t1 - t0; -} - - -gboolean trace_event(void *hook_data, void *call_data) -{ - LttvTracefileState *tfs = (LttvTracefileState *)call_data; - - guint nb_block, nb_event; - - LttTracefile *tf; - - ltt_event_position(tfs->parent.e, a_event_position); - ltt_event_position_get(a_event_position, &nb_block, &nb_event, &tf); - fprintf(stderr,"Event %s %lu.%09lu [%lu %lu]\n", - ltt_eventtype_name(ltt_event_eventtype(tfs->parent.e)), - tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec, - nb_block, nb_event); - return FALSE; -} - - -gboolean count_event(void *hook_data, void *call_data) -{ - guint *pcount = (guint *)hook_data; - - (*pcount)++; - return FALSE; -} - - -gboolean save_state_copy_event(void *hook_data, void *call_data) -{ - SaveState *save_state = (SaveState *)hook_data; - - LttvTracefileState *tfs = (LttvTracefileState *)call_data; - - LttvTraceState *ts = (LttvTraceState *)tfs->parent.t_context; - - GString *filename; - - FILE *fp; - - if(ts->nb_event == 0 && strcmp(ltt_eventtype_name( - ltt_event_eventtype(tfs->parent.e)), "block_start") == 0) { - if(a_save_sample != NULL) { - filename = g_string_new(""); - g_string_printf(filename, "%s.copy.%lu.%09lu.xml", a_save_sample, - tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec); - fp = fopen(filename->str, "w"); - if(fp == NULL) g_error("Cannot open %s", filename->str); - g_string_free(filename, TRUE); - lttv_state_write(ts, tfs->parent.timestamp, fp); - fclose(fp); - } //else lttv_state_write(ts, tfs->parent.timestamp, save_state->fp); - } - return FALSE; -} - - -gboolean save_state_event(void *hook_data, void *call_data) -{ - SaveState *save_state = (SaveState *)hook_data; - - LttvTracefileState *tfs = (LttvTracefileState *)call_data; - - LttvTraceState *ts = (LttvTraceState *)tfs->parent.t_context; - - GString *filename; - - FILE *fp; - - (save_state->count)++; - if(save_state->count % save_state->interval == 0 && - save_state->position < save_state->size) { - if(a_save_sample != NULL) { - filename = g_string_new(""); - g_string_printf(filename, "%s.%u.xml.%u", a_save_sample, - save_state->position, save_state->version); - fp = fopen(filename->str, "w"); - if(fp == NULL) g_error("Cannot open %s", filename->str); - g_string_free(filename, TRUE); - lttv_state_write(ts, tfs->parent.timestamp, fp); - fclose(fp); - } //else lttv_state_write(ts, tfs->parent.timestamp, save_state->fp); - - save_state->write_time[save_state->position] = tfs->parent.timestamp; - save_state->position++; - } - return FALSE; -} - - -static gboolean process_traceset(void *hook_data, void *call_data) -{ - LttvTracesetStats *tscs; - - LttvTracesetState *ts; - - LttvTracesetContext *tc; - - GString *filename; - - FILE *fp; - - double t; - - guint i, j, count, nb_control, nb_tracefile, nb_block, nb_event, nb_equal; - - LttTrace *trace; - - LttTracefile *tracefile, *tf; - - LttEvent *event; - - LttFacility *facility; - - LttType *type; - - LttEventType *event_type; - - LttTime time, previous_time; - - long long unsigned cycle_count, start_count, delta_cycle; - - long long unsigned start_nsec, end_nsec, delta_nsec, added_nsec, added_nsec2; - - double cycle_per_nsec, nsec_per_cycle; - - long long interpolated_nsec, interpolated_nsec2, end_nsec_sec, end_nsec_nsec; - - LttTime start_time; - - LttTime zero_time = ltt_time_zero; - - LttTime max_time = { G_MAXULONG, G_MAXULONG }; - - a_event_position = ltt_event_position_new(); - - if(a_dump_tracefiles != NULL) { - for(i = 0 ; i < lttv_traceset_number(traceset) ; i++) { - trace = lttv_trace(lttv_traceset_get(traceset, i)); - nb_control = ltt_trace_control_tracefile_number(trace); - nb_tracefile = nb_control + ltt_trace_per_cpu_tracefile_number(trace); - for(j = 0 ; j < nb_tracefile ; j++) { - if(j < nb_control) { - tracefile = ltt_trace_control_tracefile_get(trace,j); - } - else { - tracefile = ltt_trace_per_cpu_tracefile_get(trace,j - nb_control); - } - - filename = g_string_new(""); - g_string_printf(filename, "%s.%u.%u.trace", a_dump_tracefiles, i, j); - fp = fopen(filename->str, "w"); - if(fp == NULL) g_error("Cannot open %s", filename->str); - g_string_free(filename, TRUE); - ltt_tracefile_seek_time(tracefile, zero_time); - previous_time = zero_time; - nb_equal = 0; - while((event = ltt_tracefile_read(tracefile)) != NULL) { - facility = ltt_event_facility(event); - event_type = ltt_event_eventtype(event); - time = ltt_event_time(event); - cycle_count = ltt_event_cycle_count(event); - ltt_event_position(event, a_event_position); - ltt_event_position_get(a_event_position, &nb_block, &nb_event, &tf); - fprintf(fp,"%s.%s: %llu %lu.%09lu position %u/%u\n", - ltt_facility_name(facility), ltt_eventtype_name(event_type), - cycle_count, (unsigned long)time.tv_sec, - (unsigned long)time.tv_nsec, - nb_block, nb_event); - - if(ltt_time_compare(time, previous_time) < 0) { - g_warning("Time decreasing trace %d tracefile %d position %u/%u", - i, j, nb_block, nb_event); - } - - if(strcmp(ltt_eventtype_name(event_type),"block_start") == 0) { - start_count = cycle_count; - start_time = time; - } - else if(strcmp(ltt_eventtype_name(event_type),"block_end") == 0) { - delta_cycle = cycle_count - start_count; - end_nsec_sec = (long long unsigned)time.tv_sec * (long long unsigned)1000000000; - end_nsec_nsec = time.tv_nsec; - end_nsec = end_nsec_sec + end_nsec_nsec; - start_nsec = (long long unsigned)start_time.tv_sec * (long long unsigned)1000000000 + (long long unsigned)start_time.tv_nsec; - delta_nsec = end_nsec - start_nsec; - cycle_per_nsec = (double)delta_cycle / (double)delta_nsec; - nsec_per_cycle = (double)delta_nsec / (double)delta_cycle; - added_nsec = (double)delta_cycle * nsec_per_cycle; - interpolated_nsec = start_nsec + added_nsec; - added_nsec2 = (double)delta_cycle / cycle_per_nsec; - interpolated_nsec2 = start_nsec + added_nsec2; - - fprintf(fp,"Time: start_count %llu, end_count %llu, delta_cycle %llu, start_nsec %llu, end_nsec_sec %llu, end_nsec_nsec %llu, end_nsec %llu, delta_nsec %llu, cycle_per_nsec %.25f, nsec_per_cycle %.25f, added_nsec %llu, added_nsec2 %llu, interpolated_nsec %llu, interpolated_nsec2 %llu\n", start_count, cycle_count, delta_cycle, start_nsec, end_nsec_sec, end_nsec_nsec, end_nsec, delta_nsec, cycle_per_nsec, nsec_per_cycle, added_nsec, added_nsec2, interpolated_nsec, interpolated_nsec2); - } - else { - if(ltt_time_compare(time, previous_time) == 0) nb_equal++; - else if(nb_equal > 0) { - g_warning("Consecutive %d events with time %lu.%09lu", - nb_equal + 1, previous_time.tv_sec, previous_time.tv_nsec); - nb_equal = 0; - } - previous_time = time; - } - } - fclose(fp); - } - } - } - - tscs = g_object_new(LTTV_TRACESET_STATS_TYPE, NULL); - ts = &tscs->parent; - tc = &tscs->parent.parent; - - lttv_context_init(tc, traceset); - - /* For each case compute and print the elapsed time. - The first case is simply to run through all events with a - simple counter. */ - - if(a_test1 || a_test_all) { - count = 0; - lttv_hooks_add(after_event, count_event, &count); - t = run_one_test(ts, zero_time, max_time); - lttv_hooks_remove_data(after_event, count_event, &count); - g_warning( - "Processing trace while counting events (%u events in %g seconds)", - count, t); - } - - /* Run through all events computing the state. */ - - if(a_test2 || a_test_all) { - lttv_state_add_event_hooks(ts); - t = run_one_test(ts, zero_time, max_time); - lttv_state_remove_event_hooks(ts); - g_warning("Processing trace while updating state (%g seconds)", t); - } - - /* Run through all events computing the state and writing it out - periodically. */ - - SaveState save_state; - - save_state.interval = a_sample_interval; - save_state.size = a_sample_number; - save_state.fp = stderr; - save_state.write_time = g_new(LttTime, a_sample_number); - - - if(a_test3 || a_test_all) { - for(i = 0 ; i < 2 ; i++) { - save_state.count = 0; - save_state.position = 0; - save_state.version = i; - lttv_state_add_event_hooks(ts); - lttv_hooks_add(after_event, save_state_event, &save_state); - t = run_one_test(ts, zero_time, max_time); - lttv_state_remove_event_hooks(ts); - lttv_hooks_remove_data(after_event, save_state_event, &save_state); - g_warning("Processing while updating/writing state (%g seconds)", t); - } - } - - /* Run through all events computing the stats. */ - - if(a_test4 || a_test_all) { - if(lttv_profile_memory) { - g_message("Memory summary before computing stats"); - g_mem_profile(); - } - - lttv_stats_add_event_hooks(tscs); - t = run_one_test(ts, zero_time, max_time); - lttv_stats_remove_event_hooks(tscs); - g_warning("Processing trace while counting stats (%g seconds)", t); - - if(lttv_profile_memory) { - g_message("Memory summary after computing stats"); - g_mem_profile(); - } - - lttv_stats_sum_traceset(tscs); - - if(lttv_profile_memory) { - g_message("Memory summary after summing stats"); - g_mem_profile(); - } - - lttv_context_fini(tc); - lttv_context_init(tc, traceset); - - if(lttv_profile_memory) { - g_message("Memory summary after cleaning up the stats"); - g_mem_profile(); - } - } - - /* Run through all events computing the state and stats. */ - - if(a_test5 || a_test_all) { - if(lttv_profile_memory) { - g_message("Memory summary before computing state and stats"); - g_mem_profile(); - } - - lttv_state_add_event_hooks(ts); - lttv_stats_add_event_hooks(tscs); - t = run_one_test(ts, zero_time, max_time); - lttv_state_remove_event_hooks(ts); - lttv_stats_remove_event_hooks(tscs); - g_warning( - "Processing trace while counting state and stats (%g seconds)", t); - - if(lttv_profile_memory) { - g_message("Memory summary after computing and state and stats"); - g_mem_profile(); - } - - lttv_context_fini(tc); - lttv_context_init(tc, traceset); - - if(lttv_profile_memory) { - g_message("Memory summary after cleaning up the stats"); - g_mem_profile(); - } - } - - /* Run through all events computing and saving the state. */ - - if(a_trace_event) lttv_hooks_add(after_event, trace_event, NULL); - - if(a_test6 || a_test_all) { - if(lttv_profile_memory) { - g_message("Memory summary before computing and saving state"); - g_mem_profile(); - } - - lttv_state_add_event_hooks(ts); - lttv_state_save_add_event_hooks(ts); - if(a_save_state_copy) - lttv_hooks_add(after_event, save_state_copy_event, &save_state); - t = run_one_test(ts, zero_time, max_time); - lttv_state_remove_event_hooks(ts); - lttv_state_save_remove_event_hooks(ts); - if(a_save_state_copy) - lttv_hooks_remove_data(after_event,save_state_copy_event, &save_state); - - g_warning("Processing trace while updating/saving state (%g seconds)", t); - - if(lttv_profile_memory) { - g_message("Memory summary after computing/saving state"); - g_mem_profile(); - } - } - - /* Seek a few times to each saved position */ - - if((a_test7 && a_test3) || a_test_all) { - int i, j; - - for(i = 0 ; i < 2 ; i++) { - for(j = save_state.position - 1 ; j >= 0 ; j--) { - lttv_state_add_event_hooks(ts); - t = run_one_test(ts, save_state.write_time[j], - save_state.write_time[j]); - lttv_state_remove_event_hooks(ts); - g_warning("Seeking to %lu.%lu (%g seconds)", - save_state.write_time[j].tv_sec, save_state.write_time[j].tv_nsec, - t); - - if(a_save_sample != NULL) { - filename = g_string_new(""); - g_string_printf(filename, "%s.%d.xml.bak%d", a_save_sample, j, i); - fp = fopen(filename->str, "w"); - if(fp == NULL) g_error("Cannot open %s", filename->str); - g_string_free(filename, TRUE); - lttv_state_write((LttvTraceState *)tc->traces[0], - save_state.write_time[j], fp); - fclose(fp); - } - //else lttv_state_write((LttvTraceState *)tc->traces[0], - // save_state.write_time[j], save_state.fp); - } - } - } - - if(a_trace_event) lttv_hooks_remove_data(after_event, trace_event, NULL); - - g_free(save_state.write_time); - g_free(a_event_position); - lttv_context_fini(tc); - g_object_unref(tscs); - - if(lttv_profile_memory) { - g_message("Memory summary at the end of batchtest"); - g_mem_profile(); - } - - g_info("BatchTest end process traceset"); -} - - -static void init() -{ - LttvAttributeValue value; - - LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes()); - - g_info("Init batchtest.c"); - - lttv_option_add("trace", 't', - "add a trace to the trace set to analyse", - "pathname of the directory containing the trace", - LTTV_OPT_STRING, &a_trace, lttv_trace_option, NULL); - - a_trace_event = FALSE; - - a_dump_tracefiles = NULL; - lttv_option_add("dump-tracefiles", 'D', - "Write event by event the content of tracefiles", - "basename for the files where to dump events", - LTTV_OPT_STRING, &a_dump_tracefiles, NULL, NULL); - - a_save_sample = NULL; - lttv_option_add("save-sample", 's', - "Save state samples to multiple files", - "basename for the files containing the state samples", - LTTV_OPT_STRING, &a_save_sample, NULL, NULL); - - a_save_state_copy = FALSE; - lttv_option_add("save-state-copy", 'S', "Write the state saved for seeking", - "", LTTV_OPT_NONE, &a_save_state_copy, NULL, NULL); - - a_save_interval = 100000; - lttv_option_add("save-interval", 'i', - "Interval between saving state", - "number of events before a block start triggers saving state", - LTTV_OPT_INT, &a_save_interval, NULL, NULL); - - a_sample_interval = 100000; - lttv_option_add("sample-interval", 'S', - "Interval between sampling state", - "number of events before sampling and writing state", - LTTV_OPT_INT, &a_sample_interval, NULL, NULL); - - a_sample_number = 20; - lttv_option_add("sample-number", 'N', - "Number of state samples", - "maximum number", - LTTV_OPT_INT, &a_sample_number, NULL, NULL); - - a_test1 = FALSE; - lttv_option_add("test1", '1', "Test just counting events", "", - LTTV_OPT_NONE, &a_test1, NULL, NULL); - - a_test2 = FALSE; - lttv_option_add("test2", '2', "Test computing the state", "", - LTTV_OPT_NONE, &a_test2, NULL, NULL); - - a_test3 = FALSE; - lttv_option_add("test3", '3', "Test computing the state, writing out a few", - "", LTTV_OPT_NONE, &a_test3, NULL, NULL); - - a_test4 = FALSE; - lttv_option_add("test4", '4', "Test computing the stats", "", - LTTV_OPT_NONE, &a_test4, NULL, NULL); - - a_test5 = FALSE; - lttv_option_add("test5", '5', "Test computing the state and stats", "", - LTTV_OPT_NONE, &a_test5, NULL, NULL); - - a_test6 = FALSE; - lttv_option_add("test6", '6', "Test computing and saving the state", "", - LTTV_OPT_NONE, &a_test6, NULL, NULL); - - a_test7 = FALSE; - lttv_option_add("test7", '7', "Test seeking to positions written out in 3", - "", LTTV_OPT_NONE, &a_test7, NULL, NULL); - - a_test_all = FALSE; - lttv_option_add("testall", 'a', "Run all tests ", "", - LTTV_OPT_NONE, &a_test_all, NULL, NULL); - - traceset = lttv_traceset_new(); - - before_traceset = lttv_hooks_new(); - after_traceset = lttv_hooks_new(); - before_trace = lttv_hooks_new(); - after_trace = lttv_hooks_new(); - before_tracefile = lttv_hooks_new(); - after_tracefile = lttv_hooks_new(); - before_event = lttv_hooks_new(); - after_event = lttv_hooks_new(); - - g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/before", - LTTV_POINTER, &value)); - *(value.v_pointer) = before_traceset; - g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/after", - LTTV_POINTER, &value)); - *(value.v_pointer) = after_traceset; - g_assert(lttv_iattribute_find_by_path(attributes, "hooks/trace/before", - LTTV_POINTER, &value)); - *(value.v_pointer) = before_trace; - g_assert(lttv_iattribute_find_by_path(attributes, "hooks/trace/after", - LTTV_POINTER, &value)); - *(value.v_pointer) = after_trace; - g_assert(lttv_iattribute_find_by_path(attributes, "hooks/tracefile/before", - LTTV_POINTER, &value)); - *(value.v_pointer) = before_tracefile; - g_assert(lttv_iattribute_find_by_path(attributes, "hooks/tracefile/after", - LTTV_POINTER, &value)); - *(value.v_pointer) = after_tracefile; - g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event/before", - LTTV_POINTER, &value)); - *(value.v_pointer) = before_event; - g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event/after", - LTTV_POINTER, &value)); - *(value.v_pointer) = after_event; - - g_assert(lttv_iattribute_find_by_path(attributes, "hooks/main/before", - LTTV_POINTER, &value)); - g_assert((main_hooks = *(value.v_pointer)) != NULL); - lttv_hooks_add(main_hooks, process_traceset, NULL); -} - - -static void destroy() -{ - guint i, nb; - - LttvTrace *trace; - - g_info("Destroy batchAnalysis.c"); - - lttv_option_remove("trace"); - lttv_option_remove("dump-tracefiles"); - lttv_option_remove("save-sample"); - lttv_option_remove("save-state-copy"); - lttv_option_remove("sample-interval"); - lttv_option_remove("sample-number"); - lttv_option_remove("save-interval"); - lttv_option_remove("test1"); - lttv_option_remove("test2"); - lttv_option_remove("test3"); - lttv_option_remove("test4"); - lttv_option_remove("test5"); - lttv_option_remove("test6"); - lttv_option_remove("test7"); - lttv_option_remove("testall"); - - lttv_hooks_destroy(before_traceset); - lttv_hooks_destroy(after_traceset); - lttv_hooks_destroy(before_trace); - lttv_hooks_destroy(after_trace); - lttv_hooks_destroy(before_tracefile); - lttv_hooks_destroy(after_tracefile); - lttv_hooks_destroy(before_event); - lttv_hooks_destroy(after_event); - lttv_hooks_remove_data(main_hooks, process_traceset, NULL); - - nb = lttv_traceset_number(traceset); - for(i = 0 ; i < nb ; i++) { - trace = lttv_traceset_get(traceset, i); - ltt_trace_close(lttv_trace(trace)); - lttv_trace_destroy(trace); - } - - lttv_traceset_destroy(traceset); -} - - -LTTV_MODULE("batchtest", "Batch processing of a trace for tests", \ - "Run through a trace calling all the registered hooks for tests", \ - init, destroy, "state", "stats", "option" )