+/**
+ * This function passes the second EventsRequest to LTTV
+ *
+ */
+static gboolean SecondRequest(void *hook_data, void *call_data)
+{
+
+ guint i, k, l, nb_trace;
+
+ LttvTraceHook *hook;
+
+ guint ret;
+
+ LttvTraceState *ts;
+
+ GArray *hooks;
+
+ EventsRequest *events_request;
+
+ LttvTraceHookByFacility *thf;
+
+ InterruptEventData *event_data = (InterruptEventData *)hook_data;
+
+ LttvTracesetContext *tsc = lttvwindow_get_traceset_context(event_data->tab);
+
+ CalculateAverageDurationForEachIrqId(event_data);
+
+ /* Get the traceset */
+ LttvTraceset *traceset = tsc->ts;
+
+ 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++)
+ {
+ events_request = g_new(EventsRequest, 1);
+
+ hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
+
+ hooks = g_array_set_size(hooks, 2);
+
+ event_data->hooks_trace_after = lttv_hooks_new();
+
+ /* Registers a hook function */
+ lttv_hooks_add(event_data->hooks_trace_after, DisplayViewer, event_data, LTTV_PRIO_DEFAULT);
+
+ /* 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();
+
+ /*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,
+ SecondRequestIrqEntryCallback,
+ events_request,
+ &g_array_index(hooks, LttvTraceHook, 0));
+
+ ret = lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
+ LTT_FIELD_IRQ_ID, 0, 0,
+ SecondRequestIrqExitCallback,
+ events_request,
+ &g_array_index(hooks, LttvTraceHook, 1));
+
+ 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);
+
+ }
+ }
+ /* Initalize the EventsRequest structure */
+ events_request->owner = event_data;
+ events_request->viewer_data = event_data;
+ events_request->servicing = FALSE;
+ events_request->start_time = event_data->time_window.start_time;
+ events_request->start_position = NULL;
+ events_request->stop_flag = FALSE;
+ events_request->end_time = event_data->time_window.end_time;
+ events_request->num_events = G_MAXUINT;
+ events_request->end_position = NULL;
+ events_request->trace = i;
+
+ events_request->hooks = hooks;
+
+ events_request->before_chunk_traceset = NULL;
+ events_request->before_chunk_trace = NULL;
+ events_request->before_chunk_tracefile= NULL;
+ events_request->event = NULL;
+ events_request->event_by_id = event_data->event_by_id_hooks;
+ events_request->after_chunk_tracefile = NULL;
+ events_request->after_chunk_trace = NULL;
+ events_request->after_chunk_traceset = NULL;
+ events_request->before_request = NULL;
+ events_request->after_request = event_data->hooks_trace_after;
+
+ lttvwindow_events_request(event_data->tab, events_request);
+ }
+ return FALSE;
+}
+
+static void CalculateAverageDurationForEachIrqId(InterruptEventData *event_data)
+{
+ guint64 real_data;
+ Irq *element;
+ gint i;
+ GArray* FirstRequestIrqExit = event_data->FirstRequestIrqExit;
+ 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;
+ element->average_duration = real_data / element->frequency;
+ }
+
+}
+
+/**
+ * This function is called whenever an irq_entry event occurs. Use in the second request
+ *
+ */
+static gboolean SecondRequestIrqEntryCallback(void *hook_data, void *call_data)
+{
+
+ LttTime event_time;
+ unsigned cpu_id;
+ irq_entry entry;
+ LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+ LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+ InterruptEventData *event_data = (InterruptEventData *)hook_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);
+
+
+ entry.id =get_interrupt_id(e);
+ entry.cpu_id = cpu_id;
+ entry.event_time = event_time;
+ g_array_append_val (SecondRequestIrqEntry, entry);
+
+ return FALSE;
+}
+
+/**
+ * This function is called whenever an irq_exit event occurs in the second request.
+ *
+ */
+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;
+ LttEvent *event = ltt_tracefile_get_event(tfc->tf);
+
+ CalculateXi(event, event_data);
+ return FALSE;
+}
+
+
+/**
+ * This function is called whenever an irq_exit event occurs in the second request.
+ *
+ */
+static void CalculateXi(LttEvent *event_irq_exit, InterruptEventData *event_data)
+{
+ 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);
+ if(element->cpu_id == cpu_id)
+ {
+
+ /* time calculation */
+ exit_time = ltt_event_time(event_irq_exit);
+ Xi = ltt_time_sub(exit_time, element->event_time);
+ irq_id = element->id;
+
+ SumItems(irq_id, Xi,event_data);
+ g_array_remove_index(SecondRequestIrqEntry, i);
+ break;
+ }
+ }
+}
+
+
+/**
+ * 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 time_in_ns;
+
+ gint temp;
+ Irq *average;
+ SumId *sumItem;
+ SumId sum;
+ gboolean notFound = FALSE;
+ GArray *FirstRequestIrqExit = event_data->FirstRequestIrqExit;
+ GArray *SumArray = event_data->SumArray;
+ time_in_ns = Xi.tv_sec;
+ time_in_ns *= NANOSECONDS_PER_SECOND;
+ time_in_ns += Xi.tv_nsec;
+
+ for(i = 0; i < FirstRequestIrqExit->len; i++)
+ {
+ average = &g_array_index(FirstRequestIrqExit,Irq,i);
+ if(irq_id == average->id)
+ {
+ temp = time_in_ns - average->average_duration;
+ sum.sumOfDurations = pow (temp , 2);
+ //printf("one : %d\n", sum.sumOfDurations);
+ sum.irqId = irq_id;
+ sum.frequency = average->frequency;
+ 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;
+
+ }
+ }
+ if(!notFound)
+ {
+ g_array_append_val (SumArray, sum);
+ }
+
+
+ }
+
+ }
+ }
+}
+