+/**
+ * This function computes the Sum ((xi -Xa)^2) and store the result in SumArray
+ *
+ */
+static void SumItems(gint irq_id, LttTime Xi, InterruptEventData *event_data)
+{
+ gint i;
+ guint Xi_in_ns;
+
+ gint duration_inner_part;
+ guint64 period_inner_part;
+ guint64 frequency_inner_part;
+
+ Irq *average;
+ SumId *sumItem;
+ SumId sum;
+ int FrequencyHZ = 0;
+ gboolean notFound = FALSE;
+ GArray *FirstRequestIrqExit = event_data->FirstRequestIrqExit;
+ GArray *SumArray = event_data->SumArray;
+ Xi_in_ns = Xi.tv_sec;
+ Xi_in_ns *= NANOSECONDS_PER_SECOND;
+ Xi_in_ns += Xi.tv_nsec;
+
+ for(i = 0; i < FirstRequestIrqExit->len; i++)
+ {
+ average = &g_array_index(FirstRequestIrqExit,Irq,i);
+ if(irq_id == average->id)
+ {
+ duration_inner_part = Xi_in_ns - average->average_duration;
+ FrequencyHZ = FrequencyInHZ(average->TotalNumberOfInterrupts, event_data->time_window);
+ sum.irqId = irq_id;
+ // 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);
+ }
+ else
+ {
+ for(i = 0; i < SumArray->len; i++)
+ {
+ sumItem = &g_array_index(SumArray, SumId, i);
+ if(sumItem->irqId == irq_id)
+ {
+ notFound = TRUE;
+ sumItem->sumOfDurations += sum.sumOfDurations;
+ sumItem->sumOfPeriods += sum.sumOfPeriods;
+ sumItem->sumOfFrequencies += sum.sumOfFrequencies;
+ }
+ }
+ if(!notFound)
+ {
+ g_array_append_val (SumArray, sum);
+ }
+
+ }
+
+ }
+ }
+}
+
+/**
+ * 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)
+{
+
+ double periodInSec; /*period in sec*/
+ int periodInNSec;
+ gint difference;
+ guint64 result;
+ periodInSec = (double)1/FrequencyHZ;
+ periodInSec *= NANOSECONDS_PER_SECOND;
+ periodInNSec = (int)periodInSec;
+
+ 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
+ *
+ */
+static gboolean DisplayViewer(void *hook_data, void *call_data)
+{
+
+ guint average;
+ gint i;
+ Irq element;
+ LttTime average_duration;
+ 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;
+ periodInSec = 0;
+ gtk_list_store_clear(event_data->ListStore);
+ for(i = 0; i < FirstRequestIrqExit->len; i++)
+ {
+ element = g_array_index(FirstRequestIrqExit,Irq,i);
+ real_data = element.total_duration.tv_sec;
+ real_data *= NANOSECONDS_PER_SECOND;
+ real_data += element.total_duration.tv_nsec;
+
+
+ maxIRQduration = element.max_irq_handler.duration.tv_sec;
+ maxIRQduration *= NANOSECONDS_PER_SECOND;
+ maxIRQduration += element.max_irq_handler.duration.tv_nsec;
+
+ 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) ;
+
+ 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;
+
+ }
+
+ gtk_list_store_append (event_data->ListStore, &iter);
+ gtk_list_store_set (event_data->ListStore, &iter,
+ CPUID_COLUMN, element.cpu_id,
+ IRQ_ID_COLUMN, element.id,
+ FREQUENCY_COLUMN, FrequencyHZ,
+ 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),
+ FREQUENCY_STANDARD_DEV_COLUMN, CalculateFrequencyStandardDeviation(element.id, event_data),
+ -1);
+ }
+
+
+ if(event_data->FirstRequestIrqExit->len)
+ {
+ g_array_remove_range (event_data->FirstRequestIrqExit,0,event_data->FirstRequestIrqExit->len);
+ }
+
+ if(event_data->FirstRequestIrqEntry->len)
+ {
+ g_array_remove_range (event_data->FirstRequestIrqEntry,0,event_data->FirstRequestIrqEntry->len);
+ }
+
+ if(event_data->SecondRequestIrqEntry->len)
+ {
+ g_array_remove_range (event_data->SecondRequestIrqEntry,0,event_data->SecondRequestIrqEntry->len);
+ }
+
+ if(event_data->SecondRequestIrqExit->len)
+ {
+ g_array_remove_range (event_data->SecondRequestIrqExit,0, event_data->SecondRequestIrqExit->len);
+ }
+
+ if(event_data->SumArray->len)
+ {
+ g_array_remove_range (event_data->SumArray,0, event_data->SumArray->len);
+ }
+
+ return FALSE;
+}
+
+
+/**
+ * This function converts the number of interrupts over a time window to
+ * frequency in HZ
+ */
+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 = 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)
+{
+ int i;
+ SumId sumId;
+ double inner_component;
+ int 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.sumOfDurations/ sumId.TotalNumberOfInterrupts;
+ else
+ inner_component = 0.0;
+ deviation = sqrt(inner_component);
+ return deviation;
+ }
+ }
+ return deviation;
+}
+
+
+/**
+ * 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))