interrupts gui: make it work again
[lttv.git] / ltt / branches / poly / lttv / modules / gui / interrupts / interrupts.c
index fd3ad580c2a33856a5ac9af236f1141514a1ae34..6d0f07e3a210fba5717f69c1147a52e2e82b35f2 100644 (file)
  */
  
  /******************************************************************
-   
- The standard deviation  calculation is based on: 
- http://en.wikipedia.org/wiki/Standard_deviation
- Standard_deviation  = sqrt(1/N Sum ((xi -Xa)^2))
- To compute the standard deviation, we need to make  EventRequests to LTTV. In 
- the first EventRequest, we  compute the average duration (Xa)  and the 
- frequency (N) of each IrqID.  We store the information calculated in the first 
- EventRequest in an array  called  FirstRequestIrqExit.
- In the second  EventRequest, we compute the Sum ((xi -Xa)^2) and store this information 
- in a array called SumArray. The function CalculateDurationStandardDeviation() uses FirstRequestIrqExit 
- and SumArray arrays to calculate the standard deviation.
-   
-
-
-CPUID: processor ID
-
-IrqId: IRQ ID
 
-Frequency (Hz): the number of interruptions per second (Hz)
-
-Total Duration (nsec): the sum of each interrupt duration in nsec
+Each field of the interrupt viewer is summarized as follows:
+   
+- CPUID: processor ID
+
+- IrqId: IRQ ID
+
+- Frequency (Hz): the number of interrupts per second (Hz). 
+                  We compute the total number of interrupts. Then 
+                 we divide it by the time interval.
+
+- Total Duration (nsec): the sum of each interrupt duration in nsec. 
+                For a given Irq ID, we sum the duration of each interrupt
+                to give us the total duration 
+
+- Duration Standard_deviation  = sqrt(1/N Sum ((xi -Xa)^2)) where
+       N: number of interrupts 
+       xi: duration of an interrupt (nsec)
+       Xa: average duration (nsec)
+  The formula is taken from wikipedia: http://en.wikipedia.org/wiki/Standard_deviation.        
+  To calculate the duration standard deviation, we make two EventsRequest passes to the main window.
+  In the first EventsRequest pass, we calculate the total number of interrupts to compute for 
+  the average Xa. In the second  EventsRequest pass, calculate the standard deviation.
+  
 
-Duration standard deviation (nsec):   taken from http://en.wikipedia.org/wiki/Standard_deviation
-Duration Standard_deviation  = sqrt(1/N Sum ((xi -Xa)^2)) where
-N: number of interrupts 
-xi: duration of an interrupt (nsec)
-Xa: average duration (nsec)
+- Max IRQ handler duration (nsec) [time interval]:   the longest IRQ handler duration in nsec.  
 
-Max IRQ handler duration (nsec) [time interval]:   the longest IRQ handler duration in nsec.  
+- Min IRQ handler duration (nsec) [time interval]:   the shortest IRQ handler duration in nsec.  
 
-Average period (nsec): 1/frequency
+- Average period (nsec): 1/Frequency(in HZ). The frequency is computed above.
 
-Period Standard_deviation  = sqrt(1/N Sum ((xi -Xa)^2)) where
+-Period Standard_deviation  = sqrt(1/N Sum ((xi -Xa)^2)) where
 N: number of interrupts 
 xi: duration of an interrupt
-Xa: 1/frequency  
+Xa: Period = 1/Frequency  (in Hz)
  
- *******************************************************************/
+-Frequency Standard_deviation  = sqrt(1/N Sum ((xi -Xa)^2)) 
+N:  number of interrupts 
+xi: duration of an interrupt
+Xa: Frequency  (Hz)
+
+  
+*******************************************************************/
 
  
 
@@ -71,21 +73,19 @@ Xa: 1/frequency
 #include <string.h>
 #include <ltt/ltt.h>
 #include <ltt/event.h>
-#include <ltt/type.h>
 #include <ltt/trace.h>
-#include <ltt/facility.h>
 #include <lttv/module.h>
 #include <lttv/hook.h>
 #include <lttv/tracecontext.h>
 #include <lttv/state.h>
 #include <lttv/filter.h>
 #include <lttvwindow/lttvwindow.h>
+#include <lttvwindow/lttv_plugin_tab.h>
 #include <ltt/time.h>
 
 #include "hInterruptsInsert.xpm" 
 
 #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)
 #define NO_ITEMS 0
   
 typedef struct 
@@ -93,16 +93,16 @@ typedef struct
   LttTime duration;
   LttTime start_time;  
   LttTime end_time;    
-}MaxDuration;
+}IrqDuration;
 
 typedef struct {
        guint cpu_id;
        guint id;
-       guint frequency;
+       guint TotalNumberOfInterrupts;
        LttTime total_duration; 
        guint average_duration;
-       MaxDuration max_irq_handler;
-       
+       IrqDuration max_irq_handler;
+       IrqDuration min_irq_handler;
 }Irq;
 
 typedef struct {
@@ -115,9 +115,10 @@ typedef struct {
 typedef struct 
 {
        guint irqId;
-       guint frequency;
-       guint64 sumOfDurations;
-       guint64 sumOfPeriods;
+       guint TotalNumberOfInterrupts;//frequency;// 
+       guint64 sumOfDurations; // to store the Sum ((xi -Xa)^2) of the duration Standard deviation
+       guint64 sumOfPeriods;   // to store  the Sum ((xi -Xa)^2) of the period Standard deviation
+       guint64 sumOfFrequencies;// to store the Sum ((xi -Xa)^2) of the frequency Standard deviation
        
 }SumId;
 
@@ -130,7 +131,7 @@ enum type_t {
 static GSList *interrupt_data_list = NULL ;
  
 
-#define TRACE_NUMBER 0
+//fixed #define TRACE_NUMBER 0
 
 typedef struct _InterruptEventData {
 
@@ -142,6 +143,7 @@ typedef struct _InterruptEventData {
   GtkTreeSelection *SelectionTree;
   
   Tab       * tab; /* tab that contains this plug-in*/ 
+  LttvPluginTab *ptab;
   LttvHooks  * event_hooks;
   LttvHooks  * hooks_trace_after;
   LttvHooks  * hooks_trace_before;
@@ -159,28 +161,30 @@ typedef struct _InterruptEventData {
 /* Function prototypes */
  
 static gboolean interrupt_update_time_window(void * hook_data, void * call_data);
-static GtkWidget *interrupts(Tab *tab);
-static InterruptEventData *system_info(Tab *tab);
+static GtkWidget *interrupts(LttvPlugin *plugin);
+static InterruptEventData *system_info(LttvPluginTab *ptab);
 void interrupt_destructor(InterruptEventData *event_viewer_data);
 static void FirstRequest(InterruptEventData *event_data );  
-static guint64 get_interrupt_id(LttEvent *e);
 static gboolean trace_header(void *hook_data, void *call_data);
 static gboolean DisplayViewer (void *hook_data, void *call_data);
 static void CalculateData(LttTime time_exit,  guint cpu_id,  InterruptEventData *event_data);
-static void TotalDurationMaxIrqDuration(irq_entry *e, LttTime time_exit, GArray *FirstRequestIrqExit);
+static void CalculateTotalDurationAndMaxIrqDurationAndMinIrqDuration(irq_entry *e, LttTime time_exit, GArray *FirstRequestIrqExit);
 static gboolean FirstRequestIrqEntryCallback(void *hook_data, void *call_data);
 static gboolean FirstRequestIrqExitCallback(void *hook_data, void *call_data);
 static gboolean SecondRequest(void *hook_data, void *call_data);
 static void CalculateAverageDurationForEachIrqId(InterruptEventData *event_data);
 static gboolean SecondRequestIrqEntryCallback(void *hook_data, void *call_data);
 static gboolean SecondRequestIrqExitCallback(void *hook_data, void *call_data);
-static void CalculateXi(LttEvent *event, InterruptEventData *event_data);
+static void CalculateXi(LttEvent *event, InterruptEventData *event_data, guint cpu_id);
 static void  SumItems(gint irq_id, LttTime Xi, InterruptEventData *event_data);
 static int CalculateDurationStandardDeviation(gint id, InterruptEventData *event_data);
 static int CalculatePeriodStandardDeviation(gint id, InterruptEventData *event_data);
-static int FrequencyInHZ(gint frequency, TimeWindow time_window);
+static int FrequencyInHZ(gint NumberOfInterruptions, TimeWindow time_window);
 static  guint64 CalculatePeriodInnerPart(guint Xi, guint FrequencyHZ);
+static  guint64 CalculateFrequencyInnerPart(guint Xi_in_ns,  guint FrequencyHZ); 
 static void InterruptFree(InterruptEventData *event_viewer_data);
+static int CalculateFrequencyStandardDeviation(gint id, InterruptEventData *event_data);
+
 /* Enumeration of the columns */
 enum{
   CPUID_COLUMN,
@@ -189,8 +193,10 @@ enum{
   DURATION_COLUMN,
   DURATION_STANDARD_DEV_COLUMN,
   MAX_IRQ_HANDLER_COLUMN,
+  MIN_IRQ_HANDLER_COLUMN,
   AVERAGE_PERIOD,
-  PERIOD_STANDARD_DEV_COLUMN, 
+  PERIOD_STANDARD_DEV_COLUMN,
+  FREQUENCY_STANDARD_DEV_COLUMN, 
   N_COLUMNS
 };
  
@@ -219,10 +225,10 @@ static void init() {
  *  Constructor hook
  *
  */
-static GtkWidget *interrupts(Tab * tab)
+static GtkWidget *interrupts(LttvPlugin *plugin)
 {
-
-  InterruptEventData* event_data = system_info(tab) ;
+  LttvPluginTab *ptab = LTTV_PLUGIN_TAB(plugin);
+  InterruptEventData* event_data = system_info(ptab) ;
   if(event_data)
     return event_data->Hbox;
   else 
@@ -233,14 +239,15 @@ static GtkWidget *interrupts(Tab * tab)
  * This function initializes the Event Viewer functionnality through the
  * GTK  API. 
  */
-InterruptEventData *system_info(Tab *tab)
+InterruptEventData *system_info(LttvPluginTab *ptab)
 {
   
   LttTime end;
   GtkTreeViewColumn *column;
   GtkCellRenderer *renderer;
   InterruptEventData* event_viewer_data = g_new(InterruptEventData,1) ;
-      
+  Tab *tab = ptab->tab;   
+  event_viewer_data->ptab = ptab;
   event_viewer_data->tab = tab;
   
   /*Get the current time frame from the main window */
@@ -271,8 +278,11 @@ InterruptEventData *system_info(Tab *tab)
     G_TYPE_UINT64,   /* Duration                   */
     G_TYPE_INT,            /* standard deviation          */
     G_TYPE_STRING,         /* Max IRQ handler             */
+    G_TYPE_STRING,         /* Min IRQ handler             */
     G_TYPE_INT,                    /* Average period              */
-    G_TYPE_INT             /* period standard deviation   */
+    G_TYPE_INT,            /* period standard deviation   */
+    G_TYPE_INT                     /* frequency standard deviation   */
+    
     );  
  
   event_viewer_data->TreeView = gtk_tree_view_new_with_model (GTK_TREE_MODEL (event_viewer_data->ListStore)); 
@@ -280,7 +290,7 @@ InterruptEventData *system_info(Tab *tab)
   g_object_unref (G_OBJECT (event_viewer_data->ListStore));
     
   renderer = gtk_cell_renderer_text_new ();
-  column = gtk_tree_view_column_new_with_attributes ("CPUID",
+  column = gtk_tree_view_column_new_with_attributes ("CPU ID",
                  renderer,
                  "text", CPUID_COLUMN,
                  NULL);
@@ -290,7 +300,7 @@ InterruptEventData *system_info(Tab *tab)
 
    
   renderer = gtk_cell_renderer_text_new ();
-  column = gtk_tree_view_column_new_with_attributes ("IrqId",
+  column = gtk_tree_view_column_new_with_attributes ("IRQ ID",
                  renderer,
                  "text", IRQ_ID_COLUMN,
                  NULL);
@@ -334,7 +344,16 @@ InterruptEventData *system_info(Tab *tab)
   gtk_tree_view_column_set_alignment (column, 0.0);
   gtk_tree_view_column_set_fixed_width (column, 250);
   gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->TreeView), column);
-  
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Min IRQ handler duration (nsec) [time interval]",
+                 renderer,
+                 "text", MIN_IRQ_HANDLER_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 250);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->TreeView), column);
+    
   renderer = gtk_cell_renderer_text_new ();
   column = gtk_tree_view_column_new_with_attributes (" Average period (nsec)",
                  renderer,
@@ -353,6 +372,14 @@ InterruptEventData *system_info(Tab *tab)
   gtk_tree_view_column_set_fixed_width (column, 200);
   gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->TreeView), column);
   
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Frequency standard deviation (Hz)",
+                 renderer,
+                 "text", FREQUENCY_STANDARD_DEV_COLUMN,
+                 NULL);
+  gtk_tree_view_column_set_alignment (column, 0.0);
+  gtk_tree_view_column_set_fixed_width (column, 200);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (event_viewer_data->TreeView), column);
   
   
   event_viewer_data->SelectionTree = gtk_tree_view_get_selection (GTK_TREE_VIEW (event_viewer_data->TreeView));
@@ -405,7 +432,7 @@ static void FirstRequest(InterruptEventData *event_data )
    
   EventsRequest *events_request;
   
-  LttvTraceHookByFacility *thf;
+  LttvTraceHook *th;
   
   LttvTracesetContext *tsc = lttvwindow_get_traceset_context(event_data->tab);
   
@@ -416,13 +443,11 @@ static void FirstRequest(InterruptEventData *event_data )
   nb_trace = lttv_traceset_number(traceset);
   
   /* There are many traces in a traceset. Iteration for each trace. */  
-  for(i = 0; i<MIN(TRACE_NUMBER+1, nb_trace);i++)
-  {
+  //for(i = 0; i<MIN(TRACE_NUMBER+1, nb_trace);i++) {
+  for(i = 0 ; i < nb_trace ; i++) {
         events_request = g_new(EventsRequest, 1); 
        
-       hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
-       
-       hooks = g_array_set_size(hooks, 2);
+       hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 2);
     
        event_data->hooks_trace_before = lttv_hooks_new();
        
@@ -436,37 +461,34 @@ static void FirstRequest(InterruptEventData *event_data )
        /* Get a trace state */
        ts = (LttvTraceState *)tsc->traces[i];
        /* Create event_by_Id hooks */
-       event_data->event_by_id_hooks = lttv_hooks_by_id_new();
+       event_data->event_by_id_hooks = lttv_hooks_by_id_new();
   
        /*Register event_by_id_hooks with a callback function*/ 
-          ret = lttv_trace_find_hook(ts->parent.t,
-               LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
-               LTT_FIELD_IRQ_ID, 0, 0,
+        lttv_trace_find_hook(ts->parent.t,
+               LTT_FACILITY_KERNEL,
+                LTT_EVENT_IRQ_ENTRY,
+               FIELD_ARRAY(LTT_FIELD_IRQ_ID),
                FirstRequestIrqEntryCallback,
                events_request,
-               &g_array_index(hooks, LttvTraceHook, 0));
+               &hooks);
         
-        ret = lttv_trace_find_hook(ts->parent.t,
-               LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
-               LTT_FIELD_IRQ_ID, 0, 0,
+       lttv_trace_find_hook(ts->parent.t,
+               LTT_FACILITY_KERNEL,
+                LTT_EVENT_IRQ_EXIT,
+               NULL,
                FirstRequestIrqExitCallback,
                events_request,
-               &g_array_index(hooks, LttvTraceHook, 1));
+               &hooks);
                
-         g_assert(!ret);
         /*iterate through the facility list*/
        for(k = 0 ; k < hooks->len; k++) 
        { 
-               hook = &g_array_index(hooks, LttvTraceHook, k);
-               for(l=0; l<hook->fac_list->len; l++) 
-               {
-                       thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l); 
-                       lttv_hooks_add(lttv_hooks_by_id_find(event_data->event_by_id_hooks, thf->id),
-                               thf->h,
-                               event_data,
-                               LTTV_PRIO_DEFAULT);
+               th = &g_array_index(hooks, LttvTraceHook, k); 
+               lttv_hooks_add(lttv_hooks_by_id_find(event_data->event_by_id_hooks, th->id),
+                       th->h,
+                       th,
+                       LTTV_PRIO_DEFAULT);
                         
-               }
        }
        /* Initalize the EventsRequest structure */
        events_request->owner       = event_data; 
@@ -510,14 +532,16 @@ static gboolean FirstRequestIrqEntryCallback(void *hook_data, void *call_data)
   irq_entry entry;
   LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
   LttvTracefileState *tfs = (LttvTracefileState *)call_data;
-  InterruptEventData *event_data = (InterruptEventData *)hook_data;
+  LttvTraceHook *th = (LttvTraceHook*) hook_data;
+  EventsRequest *events_request = (EventsRequest*)th->hook_data;
+  InterruptEventData *event_data = events_request->viewer_data;
   GArray* FirstRequestIrqEntry  = event_data->FirstRequestIrqEntry; 
   LttEvent *e = ltt_tracefile_get_event(tfc->tf); 
   event_time = ltt_event_time(e);
-  cpu_id = ltt_event_cpu_id(e);
+  cpu_id = tfs->cpu;
    
   
-  entry.id =get_interrupt_id(e);         
+  entry.id = ltt_event_get_long_unsigned(e, lttv_trace_get_hook_field(th, 0));   
   entry.cpu_id = cpu_id;
   entry.event_time =  event_time;              
   g_array_append_val (FirstRequestIrqEntry, entry);
@@ -525,27 +549,6 @@ static gboolean FirstRequestIrqEntryCallback(void *hook_data, void *call_data)
   return FALSE;
 }
 
-/**
- *  This function gets the id of the interrupt. The id is stored in a dynamic structure. 
- *  Refer to the print.c file for howto extract data from a dynamic structure.
- */ 
-static guint64 get_interrupt_id(LttEvent *e)
-{
-  guint i, num_fields;
-  LttEventType *event_type;
-  LttField *element;  
-  LttField *field;
-   guint64  irq_id;
-  event_type = ltt_event_eventtype(e);
-  num_fields = ltt_eventtype_num_fields(event_type);
-  for(i = 0 ; i < num_fields-1 ; i++) 
-  {   
-        field = ltt_eventtype_field(event_type, i);
-       irq_id = ltt_event_get_long_unsigned(e,field);
-  }
-  return  irq_id;
-
-} 
 /**
  *  This function is called whenever an irq_exit event occurs.  
  *  
@@ -556,11 +559,12 @@ gboolean FirstRequestIrqExitCallback(void *hook_data, void *call_data)
   unsigned cpu_id;
   LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
   LttvTracefileState *tfs = (LttvTracefileState *)call_data;
-  InterruptEventData *event_data = (InterruptEventData *)hook_data;
+  LttvTraceHook *th = (LttvTraceHook*) hook_data;
+  EventsRequest *events_request = (EventsRequest*)th->hook_data;
+  InterruptEventData *event_data = events_request->viewer_data;
   LttEvent *e = ltt_tracefile_get_event(tfc->tf);
-  LttEventType *type = ltt_event_eventtype(e);
   event_time = ltt_event_time(e);
-  cpu_id = ltt_event_cpu_id(e);
+  cpu_id = tfs->cpu;
   
   CalculateData( event_time,  cpu_id, event_data);
    
@@ -584,18 +588,20 @@ static void CalculateData(LttTime time_exit,  guint cpu_id,InterruptEventData *e
     element = &g_array_index(FirstRequestIrqEntry,irq_entry,i);
     if(element->cpu_id == cpu_id)
     {
-      TotalDurationMaxIrqDuration(element,time_exit,  FirstRequestIrqExit);    
+      CalculateTotalDurationAndMaxIrqDurationAndMinIrqDuration(element,time_exit,  FirstRequestIrqExit);    
       g_array_remove_index(FirstRequestIrqEntry, i);
       break;
     }
   }
 } 
 
 /**
- *  This function calculates the total duration  of an interrupt and the longest Irq handler.  
+ *  This function calculates the total duration  of an interrupt and the longest & shortest Irq handlers.  
  *  
  */ 
-static void TotalDurationMaxIrqDuration(irq_entry *e, LttTime time_exit, GArray *FirstRequestIrqExit){
+static void CalculateTotalDurationAndMaxIrqDurationAndMinIrqDuration(irq_entry *e, LttTime time_exit, GArray *FirstRequestIrqExit)
+{
   Irq irq;
   Irq *element; 
   guint i;
@@ -608,12 +614,16 @@ static void TotalDurationMaxIrqDuration(irq_entry *e, LttTime time_exit, GArray
   {
     irq.cpu_id = e->cpu_id;
     irq.id    =  e->id;
-    irq.frequency++;
+    irq.TotalNumberOfInterrupts++;
     irq.total_duration =  ltt_time_sub(time_exit, e->event_time);
      
     irq.max_irq_handler.start_time = e->event_time;
     irq.max_irq_handler.end_time = time_exit;
     irq.max_irq_handler.duration = ltt_time_sub(time_exit, e->event_time);
+    
+    irq.min_irq_handler.start_time = e->event_time;
+    irq.min_irq_handler.end_time = time_exit;
+    irq.min_irq_handler.duration = ltt_time_sub(time_exit, e->event_time);
      
     g_array_append_val (FirstRequestIrqExit, irq);
   }
@@ -627,25 +637,37 @@ static void TotalDurationMaxIrqDuration(irq_entry *e, LttTime time_exit, GArray
        notFound = TRUE;
        duration =  ltt_time_sub(time_exit, e->event_time);
        element->total_duration = ltt_time_add(element->total_duration, duration);
-       element->frequency++;
+       element->TotalNumberOfInterrupts++;
+       // Max irq handler
        if(ltt_time_compare(duration,element->max_irq_handler.duration) > 0)
        {
            element->max_irq_handler.duration = duration;
            element->max_irq_handler.start_time = e->event_time;
            element->max_irq_handler.end_time  = time_exit;
        }
+       // Min irq handler
+       if(ltt_time_compare(duration,element->min_irq_handler.duration) < 0)
+       {
+           element->min_irq_handler.duration = duration;
+           element->min_irq_handler.start_time = e->event_time;
+           element->min_irq_handler.end_time  = time_exit;
+       }
       }
     }
     if(!notFound)
     {
       irq.cpu_id = e->cpu_id;
       irq.id    =  e->id;
-      irq.frequency++;
+      irq.TotalNumberOfInterrupts++;
       irq.total_duration =  ltt_time_sub(time_exit, e->event_time);
-      
+      // Max irq handler
       irq.max_irq_handler.start_time = e->event_time;
       irq.max_irq_handler.end_time = time_exit;
       irq.max_irq_handler.duration = ltt_time_sub(time_exit, e->event_time);
+      // Min irq handler
+      irq.min_irq_handler.start_time = e->event_time;
+      irq.min_irq_handler.end_time = time_exit;
+      irq.min_irq_handler.duration = ltt_time_sub(time_exit, e->event_time);
       
       g_array_append_val (FirstRequestIrqExit, irq);
     }
@@ -671,7 +693,7 @@ static gboolean SecondRequest(void *hook_data, void *call_data)
    
   EventsRequest *events_request;
   
-  LttvTraceHookByFacility *thf;
+  LttvTraceHook *th;
   
   InterruptEventData *event_data = (InterruptEventData *)hook_data;
   
@@ -685,14 +707,12 @@ static gboolean SecondRequest(void *hook_data, void *call_data)
   nb_trace = lttv_traceset_number(traceset);
   
   /* There are many traces in a traceset. Iteration for each trace. */  
-  for(i = 0; i<MIN(TRACE_NUMBER+1, nb_trace);i++)
-  {
+  for(i = 0 ; i < nb_trace ; i++) {
+  // fixed for(i = 0; i<MIN(TRACE_NUMBER+1, nb_trace);i++) {
         events_request = g_new(EventsRequest, 1); 
        
-       hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
+       hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 2);
        
-       hooks = g_array_set_size(hooks, 2);
-    
        event_data->hooks_trace_after = lttv_hooks_new();
        
        /* Registers a hook function */
@@ -705,34 +725,32 @@ static gboolean SecondRequest(void *hook_data, void *call_data)
   
        /*Register event_by_id_hooks with a callback function*/ 
           ret = lttv_trace_find_hook(ts->parent.t,
-               LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
-               LTT_FIELD_IRQ_ID, 0, 0,
+               LTT_FACILITY_KERNEL,
+               LTT_EVENT_IRQ_ENTRY,
+               FIELD_ARRAY(LTT_FIELD_IRQ_ID),
                SecondRequestIrqEntryCallback,
                events_request,
-               &g_array_index(hooks, LttvTraceHook, 0));
+               &hooks);
         
         ret = lttv_trace_find_hook(ts->parent.t,
-               LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
-               LTT_FIELD_IRQ_ID, 0, 0,
+               LTT_FACILITY_KERNEL,
+               LTT_EVENT_IRQ_EXIT,
+               NULL,
                SecondRequestIrqExitCallback,
                events_request,
-               &g_array_index(hooks, LttvTraceHook, 1));
+               &hooks);
                
          g_assert(!ret);
          
        /* iterate through the facility list */
        for(k = 0 ; k < hooks->len; k++) 
        { 
-               hook = &g_array_index(hooks, LttvTraceHook, k);
-               for(l=0; l<hook->fac_list->len; l++) 
-               {
-                       thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l); 
-                       lttv_hooks_add(lttv_hooks_by_id_find(event_data->event_by_id_hooks, thf->id),
-                               thf->h,
-                               event_data,
-                               LTTV_PRIO_DEFAULT);
+               th = &g_array_index(hooks, LttvTraceHook, k); 
+               lttv_hooks_add(lttv_hooks_by_id_find(event_data->event_by_id_hooks, th->id),
+                       th->h,
+                       th,
+                       LTTV_PRIO_DEFAULT);
                         
-               }
        }
        /* Initalize the EventsRequest structure */
        events_request->owner       = event_data; 
@@ -764,6 +782,10 @@ static gboolean SecondRequest(void *hook_data, void *call_data)
    return FALSE;
 }
 
+/**
+ *  This function calculates the average  duration for each Irq Id
+ *  
+ */ 
 static void CalculateAverageDurationForEachIrqId(InterruptEventData *event_data)
 {
   guint64 real_data;
@@ -776,7 +798,10 @@ static void CalculateAverageDurationForEachIrqId(InterruptEventData *event_data)
     real_data = element->total_duration.tv_sec;
     real_data *= NANOSECONDS_PER_SECOND;
     real_data += element->total_duration.tv_nsec;
-    element->average_duration = real_data / element->frequency;
+    if(element->TotalNumberOfInterrupts != 0)
+       element->average_duration = real_data / element->TotalNumberOfInterrupts;
+    else
+       element->average_duration = 0;
   }
 
 }
@@ -793,14 +818,16 @@ static gboolean SecondRequestIrqEntryCallback(void *hook_data, void *call_data)
   irq_entry entry;
   LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
   LttvTracefileState *tfs = (LttvTracefileState *)call_data;
-  InterruptEventData *event_data = (InterruptEventData *)hook_data;
+  LttvTraceHook *th = (LttvTraceHook *)hook_data;
+  EventsRequest *events_request = (EventsRequest*)th->hook_data;
+  InterruptEventData *event_data = events_request->viewer_data;
   GArray* SecondRequestIrqEntry  = event_data->SecondRequestIrqEntry; 
   LttEvent *e = ltt_tracefile_get_event(tfc->tf); 
   event_time = ltt_event_time(e);
-  cpu_id = ltt_event_cpu_id(e);
+  cpu_id = tfs->cpu;
    
   
-  entry.id =get_interrupt_id(e);         
+  entry.id = ltt_event_get_long_unsigned(e, lttv_trace_get_hook_field(th, 0));   
   entry.cpu_id = cpu_id;
   entry.event_time =  event_time;              
   g_array_append_val (SecondRequestIrqEntry, entry);
@@ -817,10 +844,13 @@ static gboolean SecondRequestIrqExitCallback(void *hook_data, void *call_data)
    
   LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
   LttvTracefileState *tfs = (LttvTracefileState *)call_data;
-  InterruptEventData *event_data = (InterruptEventData *)hook_data;
+  LttvTraceHook *th = (LttvTraceHook *)hook_data;
+  EventsRequest *events_request = (EventsRequest*)th->hook_data;
+  InterruptEventData *event_data = events_request->viewer_data;
+  
   LttEvent *event = ltt_tracefile_get_event(tfc->tf);
   
-  CalculateXi(event, event_data);
+  CalculateXi(event, event_data, tfs->cpu);
   return FALSE;
 } 
 
@@ -829,17 +859,15 @@ static gboolean SecondRequestIrqExitCallback(void *hook_data, void *call_data)
  *  This function is called whenever an irq_exit event occurs in the second request.  
  *  
  */ 
-static void CalculateXi(LttEvent *event_irq_exit, InterruptEventData *event_data)
+static void CalculateXi(LttEvent *event_irq_exit, InterruptEventData *event_data, guint cpu_id)
 {
   gint i, irq_id;
   irq_entry *element; 
   LttTime Xi;
   LttTime  exit_time; 
-  unsigned cpu_id;
   
   GArray *SecondRequestIrqExit = event_data->SecondRequestIrqExit;
   GArray *SecondRequestIrqEntry = event_data->SecondRequestIrqEntry;
-  cpu_id = ltt_event_cpu_id(event_irq_exit);
   for(i = 0; i < SecondRequestIrqEntry->len; i++)
   {
     element = &g_array_index(SecondRequestIrqEntry,irq_entry,i);
@@ -870,6 +898,8 @@ static void  SumItems(gint irq_id, LttTime Xi, InterruptEventData *event_data)
    
   gint duration_inner_part;
   guint64 period_inner_part;
+  guint64 frequency_inner_part;
+  
   Irq *average; 
   SumId *sumItem; 
   SumId sum;
@@ -887,13 +917,22 @@ static void  SumItems(gint irq_id, LttTime Xi, InterruptEventData *event_data)
        if(irq_id == average->id)
        {
            duration_inner_part = Xi_in_ns - average->average_duration;
-           FrequencyHZ = FrequencyInHZ(average->frequency, event_data->time_window);
-            
+           FrequencyHZ = FrequencyInHZ(average->TotalNumberOfInterrupts, event_data->time_window);
            sum.irqId = irq_id;
-           sum.frequency = average->frequency;
+           // compute  (xi -Xa)^2 of the duration Standard deviation
+           sum.TotalNumberOfInterrupts = average->TotalNumberOfInterrupts;
            sum.sumOfDurations =  pow (duration_inner_part , 2);
+            
+           // compute  (xi -Xa)^2 of the period Standard deviation
            period_inner_part = CalculatePeriodInnerPart(Xi_in_ns, FrequencyHZ); 
+           
+           // compute (xi -Xa)^2 of the frequency Standard deviation
+           frequency_inner_part =  CalculateFrequencyInnerPart(Xi_in_ns, FrequencyHZ); 
+           
            sum.sumOfPeriods = period_inner_part;
+           
+           sum.sumOfFrequencies = frequency_inner_part;
+           
            if(event_data->SumArray->len == NO_ITEMS)            
            {   
                g_array_append_val (SumArray, sum);
@@ -908,7 +947,8 @@ static void  SumItems(gint irq_id, LttTime Xi, InterruptEventData *event_data)
                     notFound = TRUE;
                     sumItem->sumOfDurations  += sum.sumOfDurations;
                     sumItem->sumOfPeriods += sum.sumOfPeriods;
-                 }
+                    sumItem->sumOfFrequencies += sum.sumOfFrequencies;
+                 }
                }
                if(!notFound)
                {
@@ -921,6 +961,10 @@ static void  SumItems(gint irq_id, LttTime Xi, InterruptEventData *event_data)
   }    
 }
 
+/**
+ *  This function computes the inner part of the period standard deviation  = sqrt(1/N Sum ((xi -Xa)^2))  
+ *  The inner part is: (xi -Xa)^2
+ */  
 static  guint64 CalculatePeriodInnerPart(guint Xi, guint FrequencyHZ)
 {
 
@@ -934,12 +978,21 @@ static  guint64 CalculatePeriodInnerPart(guint Xi, guint FrequencyHZ)
   
   difference = Xi - periodInNSec;
   result = pow (difference , 2);
-  
-  
   return result; 
-  
-   
+}
 
+/**
+ *  This function computes the inner part of the frequency standard deviation  = sqrt(1/N Sum ((xi -Xa)^2))  
+ *  The inner part is: (xi -Xa)^2
+ */  
+static  guint64 CalculateFrequencyInnerPart(guint Xi_in_ns,  guint FrequencyHZ)
+{
+  guint64 result;
+  gint difference;
+  
+  difference = Xi_in_ns - FrequencyHZ;
+  result = pow (difference , 2);
+  return result;
 }
 /**
  *  This function displays the result on the viewer 
@@ -955,9 +1008,11 @@ static gboolean DisplayViewer(void *hook_data, void *call_data)
   GtkTreeIter    iter;
   guint64 real_data;
   guint maxIRQduration;
+  guint minIRQduration;
   double periodInSec;
   int periodInNsec;
   char maxIrqHandler[80];
+  char minIrqHandler[80];
   InterruptEventData *event_data = (InterruptEventData *)hook_data;
   GArray *FirstRequestIrqExit = event_data->FirstRequestIrqExit;  
   int FrequencyHZ =  0; 
@@ -978,14 +1033,23 @@ static gboolean DisplayViewer(void *hook_data, void *call_data)
     sprintf(maxIrqHandler, "%d [%d.%d - %d.%d]",maxIRQduration, element.max_irq_handler.start_time.tv_sec, \
     element.max_irq_handler.start_time.tv_nsec, element.max_irq_handler.end_time.tv_sec, \
     element.max_irq_handler.end_time.tv_nsec) ;
-   FrequencyHZ = FrequencyInHZ(element.frequency,event_data->time_window);
+    
+    minIRQduration  =  element.min_irq_handler.duration.tv_sec;
+    minIRQduration *= NANOSECONDS_PER_SECOND;
+    minIRQduration += element.min_irq_handler.duration.tv_nsec;
+    sprintf(minIrqHandler, "%d [%d.%d - %d.%d]",minIRQduration, element.min_irq_handler.start_time.tv_sec, \
+    element.min_irq_handler.start_time.tv_nsec, element.min_irq_handler.end_time.tv_sec, \
+    element.min_irq_handler.end_time.tv_nsec) ;
+    
+    FrequencyHZ = FrequencyInHZ(element.TotalNumberOfInterrupts,event_data->time_window);
    
    if(FrequencyHZ != 0)
    {
       periodInSec = (double)1/FrequencyHZ;
       periodInSec *= NANOSECONDS_PER_SECOND;
       periodInNsec = (int)periodInSec;
-      //printf("period1:%d\n", periodInNsec);
+     
    }
      
     gtk_list_store_append (event_data->ListStore, &iter);
@@ -996,11 +1060,11 @@ static gboolean DisplayViewer(void *hook_data, void *call_data)
       DURATION_COLUMN, real_data,
       DURATION_STANDARD_DEV_COLUMN, CalculateDurationStandardDeviation(element.id, event_data),
       MAX_IRQ_HANDLER_COLUMN, maxIrqHandler,
+      MIN_IRQ_HANDLER_COLUMN, minIrqHandler,
       AVERAGE_PERIOD , periodInNsec,
       PERIOD_STANDARD_DEV_COLUMN,  CalculatePeriodStandardDeviation(element.id, event_data),
-      -1);
-     
-     
+      FREQUENCY_STANDARD_DEV_COLUMN, CalculateFrequencyStandardDeviation(element.id, event_data),
+      -1); 
   } 
    
    
@@ -1037,20 +1101,24 @@ static gboolean DisplayViewer(void *hook_data, void *call_data)
  *  This function converts the number of interrupts over a time window to
  *  frequency in HZ
  */ 
-static int FrequencyInHZ(gint frequency, TimeWindow time_window)
+static int FrequencyInHZ(gint NumerofInterruptions, TimeWindow time_window)
 {
   guint64 frequencyHz = 0;
   double timeSec;  // time in second
   double result; 
   result  = ltt_time_to_double(time_window.time_width);
   timeSec = (result/NANOSECONDS_PER_SECOND);  //time in second
-  frequencyHz = frequency / timeSec;  
+  frequencyHz = NumerofInterruptions / timeSec;  
   return  frequencyHz;
 }
 
 /**
  *  This function calculates the duration standard deviation
- *  
+ *  Duration standard deviation = sqrt(1/N Sum ((xi -Xa)^2)) 
+ *  Where: 
+ *   sumId.sumOfDurations -> Sum ((xi -Xa)^2)
+ *   inner_component -> 1/N Sum ((xi -Xa)^2)
+ *   deviation-> sqrt(1/N Sum ((xi -Xa)^2)) 
  */ 
 static int CalculateDurationStandardDeviation(gint id, InterruptEventData *event_data)
 {
@@ -1063,7 +1131,10 @@ static int CalculateDurationStandardDeviation(gint id, InterruptEventData *event
     sumId  = g_array_index(event_data->SumArray, SumId, i);  
     if(id == sumId.irqId)
     {
-       inner_component = sumId.sumOfDurations/ sumId.frequency;
+        if(sumId.TotalNumberOfInterrupts != 0)
+         inner_component = sumId.sumOfDurations/ sumId.TotalNumberOfInterrupts;
+        else  
+         inner_component = 0.0;
        deviation =  sqrt(inner_component);
        return deviation;
     }    
@@ -1074,6 +1145,12 @@ static int CalculateDurationStandardDeviation(gint id, InterruptEventData *event
 
 /**
  *  This function calculates the period standard deviation
+ *  Period standard deviation = sqrt(1/N Sum ((xi -Xa)^2)) 
+ *  Where: 
+ *   sumId.sumOfPeriods -> Sum ((xi -Xa)^2)
+ *   inner_component -> 1/N Sum ((xi -Xa)^2)
+ *   period_standard_deviation-> sqrt(1/N Sum ((xi -Xa)^2)) 
  *  
  */ 
 static int CalculatePeriodStandardDeviation(gint id, InterruptEventData *event_data)
@@ -1082,18 +1159,55 @@ static int CalculatePeriodStandardDeviation(gint id, InterruptEventData *event_d
    SumId sumId;
    guint64 inner_component;
    guint64 period_standard_deviation = 0;
+   
    for(i = 0; i < event_data->SumArray->len; i++)
    {  
       sumId  = g_array_index(event_data->SumArray, SumId, i);  
       if(id == sumId.irqId)
       {
-        inner_component = sumId.sumOfPeriods / sumId.frequency;
+        if(sumId.TotalNumberOfInterrupts != 0)
+           inner_component = sumId.sumOfPeriods / sumId.TotalNumberOfInterrupts;
+       else
+          inner_component = 0;
+          
        period_standard_deviation =  sqrt(inner_component);
       }
    }
    
    return period_standard_deviation;
 }
+
+/**
+ *  This function calculates the frequency standard deviation
+ *  Frequency standard deviation = sqrt(1/N Sum ((xi -Xa)^2)) 
+ *  Where: 
+ *   sumId.sumOfFrequencies -> Sum ((xi -Xa)^2)
+ *   inner_component -> 1/N Sum ((xi -Xa)^2)
+ *   frequency_standard_deviation-> sqrt(1/N Sum ((xi -Xa)^2)) 
+ *  
+ */ 
+static int CalculateFrequencyStandardDeviation(gint id, InterruptEventData *event_data)
+{
+   int i;
+   SumId sumId;
+   guint64 inner_component;
+   guint64 frequency_standard_deviation = 0;
+   for(i = 0; i < event_data->SumArray->len; i++)
+   {  
+     sumId  = g_array_index(event_data->SumArray, SumId, i);   
+     if(id == sumId.irqId)
+     {
+        if(sumId.TotalNumberOfInterrupts != 0)
+           inner_component = sumId.sumOfFrequencies / sumId.TotalNumberOfInterrupts;
+       else
+          inner_component = 0;
+       
+        frequency_standard_deviation =  sqrt(inner_component);    
+     }
+   }
+   return frequency_standard_deviation;
+}
 /*
  * This function is called by the main window
  * when the time interval needs to be updated.
@@ -1125,10 +1239,7 @@ void interrupt_destroy_walk(gpointer data, gpointer user_data)
 {
   g_info("interrupt_destroy_walk");
   InterruptEventData *event_data = (InterruptEventData*) data;
-
-    
   interrupt_destructor((InterruptEventData*)data);
-
 }
 
 
This page took 0.03483 seconds and 4 git commands to generate.