move everything out of trunk
[lttv.git] / lttng-xenomai / LinuxTraceToolkitViewer-0.8.61-xenoltt / lttv / lttv / xenoltt_sim.c.bkp
diff --git a/lttng-xenomai/LinuxTraceToolkitViewer-0.8.61-xenoltt/lttv/lttv/xenoltt_sim.c.bkp b/lttng-xenomai/LinuxTraceToolkitViewer-0.8.61-xenoltt/lttv/lttv/xenoltt_sim.c.bkp
new file mode 100644 (file)
index 0000000..72bf823
--- /dev/null
@@ -0,0 +1,758 @@
+/* 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <lttv/module.h>
+#include <lttv/xenoltt_sim.h>
+#include <lttv/stats.h>
+#include <lttv/lttv.h>
+#include <lttv/attribute.h>
+#include <ltt/facility.h>
+#include <ltt/trace.h>
+#include <ltt/event.h>
+#include <ltt/type.h>
+
+
+/****************************************************************************************************************************/
+gboolean save_event(void *hook_data, void *call_data);
+/****************************************************************************************************************************/
+
+gboolean sim_every_event(void *hook_data, void *call_data)
+{
+  LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
+
+  LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
+
+  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, 
+      ltt_eventtype_name(ltt_event_eventtype(e)), 
+      LTTV_UINT, &v);
+  (*(v.v_uint))++;
+  return FALSE;
+}
+
+// Hook wrapper. call_data is a traceset context.
+gboolean lttv_xenoltt_sim_hook_add_event_hooks(void *hook_data, void *call_data)
+{
+  LttvTracesetStats *tss = (LttvTracesetStats*)call_data;
+
+  thread_event_list = g_array_new(FALSE, FALSE, sizeof(ThreadEventData*));
+  running_thread = g_array_new(FALSE, FALSE, sizeof(RunningThread*));  
+   
+  lttv_xenoltt_sim_add_event_hooks(tss);
+
+  return 0;
+}
+
+void lttv_xenoltt_sim_add_event_hooks(LttvTracesetStats *self)
+{
+  LttvTraceset *traceset = self->parent.parent.ts;
+
+  guint i, j, k, l, nb_trace, nb_tracefile;
+
+  LttvTraceStats *ts;
+
+  LttvTracefileStats *tfs;
+
+  GArray *hooks, *before_hooks;
+
+  LttvTraceHook *hook;
+
+  LttvTraceHookByFacility *thf;
+
+  LttvAttributeValue val;
+
+  gint ret;
+       gint hn;
+
+  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_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 16);
+    g_array_set_size(hooks, 16);
+    hn=0;
+    /*
+    LTT_EVENT_XENOLTT_THREAD_INIT,
+    LTT_EVENT_XENOLTT_THREAD_SET_PERIOD,
+    LTT_EVENT_XENOLTT_THREAD_WAIT_PERIOD,
+    LTT_EVENT_XENOLTT_THREAD_MISSED_PERIOD,
+    LTT_EVENT_XENOLTT_THREAD_SUSPEND,
+    LTT_EVENT_XENOLTT_THREAD_START,
+    LTT_EVENT_XENOLTT_THREAD_RESUME,
+    LTT_EVENT_XENOLTT_THREAD_DELETE,
+    LTT_EVENT_XENOLTT_THREAD_UNBLOCK,
+    LTT_EVENT_XENOLTT_THREAD_RENICE,
+    LTT_EVENT_XENOLTT_TIMER_TICK,
+    LTT_EVENT_XENOLTT_SYNCH_SET_OWNER,
+    LTT_EVENT_XENOLTT_SYNCH_UNLOCK,
+    LTT_EVENT_XENOLTT_SYNCH_WAKEUP1,
+    LTT_EVENT_XENOLTT_SYNCH_WAKEUPX,
+    LTT_EVENT_XENOLTT_SYNCH_SLEEP_ON,
+    LTT_EVENT_XENOLTT_SYNCH_FLUSH,
+    LTT_EVENT_XENOLTT_SYNCH_FORGET,
+    LTT_EVENT_XENOLTT_THREAD_SWITCH;
+    */
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_INIT,
+        LTT_FIELD_XENOLTT_ADDRESS, 0, 0,
+        save_event, NULL,
+        &g_array_index(hooks, LttvTraceHook, hn++));
+    if(ret) hn--;
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_SET_PERIOD,
+        LTT_FIELD_XENOLTT_ADDRESS, 0, 0,
+        save_event, NULL,
+        &g_array_index(hooks, LttvTraceHook, hn++));
+    if(ret) hn--;
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_WAIT_PERIOD,
+        LTT_FIELD_XENOLTT_ADDRESS, 0, 0,
+        save_event, NULL,
+        &g_array_index(hooks, LttvTraceHook, hn++));
+    if(ret) hn--;
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_MISSED_PERIOD,
+        LTT_FIELD_XENOLTT_ADDRESS, 0, 0,
+        save_event, NULL,
+        &g_array_index(hooks, LttvTraceHook, hn++));
+    if(ret) hn--;
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_SUSPEND,
+        LTT_FIELD_XENOLTT_ADDRESS, 0, 0,
+        save_event, NULL,
+        &g_array_index(hooks, LttvTraceHook, hn++));
+    if(ret) hn--;
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_START,
+        LTT_FIELD_XENOLTT_ADDRESS, 0, 0,
+        save_event, NULL,
+        &g_array_index(hooks, LttvTraceHook, hn++));
+    if(ret) hn--;
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_RESUME,
+        LTT_FIELD_XENOLTT_ADDRESS, 0, 0,
+        save_event, NULL,
+        &g_array_index(hooks, LttvTraceHook, hn++));
+    if(ret) hn--;
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_DELETE,
+        LTT_FIELD_XENOLTT_ADDRESS, 0, 0,
+        save_event, NULL,
+        &g_array_index(hooks, LttvTraceHook, hn++));
+    if(ret) hn--;
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_SWITCH,
+        LTT_FIELD_XENOLTT_ADDRESS, 0, 0,
+        save_event, NULL,
+        &g_array_index(hooks, LttvTraceHook, hn++));
+    if(ret) hn--;
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_THREAD_SWITCH,
+        LTT_FIELD_XENOLTT_ADDRESS_OUT, 0, 0,
+        save_event, NULL,
+        &g_array_index(hooks, LttvTraceHook, hn++));
+    if(ret) hn--;
+
+    ret = lttv_trace_find_hook(ts->parent.parent.t,
+        LTT_FACILITY_XENOLTT, LTT_EVENT_XENOLTT_TIMER_TICK,
+        LTT_FIELD_XENOLTT_ADDRESS, 0, 0,
+        save_event, NULL,
+        &g_array_index(hooks, LttvTraceHook, hn++));
+    if(ret) hn--;
+        
+    g_array_set_size(hooks, hn);
+
+    before_hooks = hooks;
+
+    /* Add these hooks to each event_by_id hooks list */
+
+    nb_tracefile = ts->parent.parent.tracefiles->len;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfs = LTTV_TRACEFILE_STATS(g_array_index(ts->parent.parent.tracefiles,
+                                  LttvTracefileContext*, j));
+      lttv_hooks_add(tfs->parent.parent.event, sim_every_event, NULL, 
+                     LTTV_PRIO_DEFAULT);
+
+      for(k = 0 ; k < before_hooks->len ; k++) {
+        hook = &g_array_index(before_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(tfs->parent.parent.event_by_id, thf->id),
+              thf->h,
+              thf,
+              LTTV_PRIO_DEFAULT);
+        }
+      }
+
+    }
+    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS, 
+        LTTV_POINTER, &val);
+    *(val.v_pointer) = before_hooks;
+  }
+}
+
+// Hook wrapper. call_data is a traceset context.
+gboolean lttv_xenoltt_sim_hook_remove_event_hooks(void *hook_data, void *call_data)
+{
+   LttvTracesetStats *tss = (LttvTracesetStats*)call_data;
+
+   lttv_xenoltt_sim_remove_event_hooks(tss);
+
+   return 0;
+}
+
+void lttv_xenoltt_sim_remove_event_hooks(LttvTracesetStats *self)
+{
+  LttvTraceset *traceset = self->parent.parent.ts;
+
+  guint i, j, k, l, nb_trace, nb_tracefile;
+
+  LttvTraceStats *ts;
+
+  LttvTracefileStats *tfs;
+
+  GArray *before_hooks;
+
+  LttvTraceHook *hook;
+  
+  LttvTraceHookByFacility *thf;
+
+  LttvAttributeValue val;
+
+  nb_trace = lttv_traceset_number(traceset);
+  for(i = 0 ; i < nb_trace ; i++) {
+    ts = (LttvTraceStats*)self->parent.parent.traces[i];
+    lttv_attribute_find(self->parent.parent.a, LTTV_STATS_BEFORE_HOOKS, 
+        LTTV_POINTER, &val);
+    before_hooks = *(val.v_pointer);
+
+    /* Remove these hooks from each event_by_id hooks list */
+
+    nb_tracefile = ts->parent.parent.tracefiles->len;
+
+    for(j = 0 ; j < nb_tracefile ; j++) {
+      tfs = LTTV_TRACEFILE_STATS(g_array_index(ts->parent.parent.tracefiles,
+                                  LttvTracefileContext*, j));
+      lttv_hooks_remove_data(tfs->parent.parent.event, sim_every_event, 
+          NULL);
+
+      for(k = 0 ; k < before_hooks->len ; k++) {
+        hook = &g_array_index(before_hooks, LttvTraceHook, k);
+        for(l = 0 ; l < hook->fac_list->len ; l++) {
+          thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
+          lttv_hooks_remove_data(
+              lttv_hooks_by_id_find(tfs->parent.parent.event_by_id, thf->id),
+              thf->h,
+              thf);
+        }
+      }
+    }
+    g_debug("lttv_stats_remove_event_hooks()");
+    g_array_free(before_hooks, TRUE);
+  }
+}
+
+
+
+/****************************************************************************************************************************/
+
+
+
+/* 
+ This function will look into the thread list to find the corresponding thread and returns it
+ This way we will be able to add a new event to this thread events list.
+*/
+ThreadEventData* lookup_or_create_thread(gulong address, guint prio, LttTime creation_time, GQuark name){
+  printf("lookup_or_create\n");
+  int i, index = 0;
+  ThreadEventData *temp_thread;
+  ThreadEventData *temp_thread_2 = g_new(ThreadEventData, 1);
+  temp_thread_2->address = address;
+  temp_thread_2->prio = prio;
+  temp_thread_2->creation_time = creation_time;
+  temp_thread_2->name = name;
+  temp_thread_2->event_list = g_array_new(FALSE, FALSE, sizeof(EventData*));
+  
+
+  for(i=0;i<thread_event_list->len;i++){
+    temp_thread = g_array_index(thread_event_list, ThreadEventData*, i);
+    if (temp_thread->address == temp_thread_2->address &&
+        ltt_time_compare(temp_thread->creation_time,temp_thread_2->creation_time) == 0)
+      return temp_thread;   // Thread is found we return it
+    /* Otherwise we check for the priority, this will help us to defined the 
+       index where to insert the thread. This way we don't to sort the thread list */
+    else if(temp_thread_2->prio <= temp_thread->prio) index++;
+  }
+    
+  g_array_insert_val(thread_event_list,index,temp_thread_2);
+
+  return temp_thread_2;     // New inserted thread is returned
+}
+
+void calculate_event_time(guint index, ThreadEventData *temp_thread){
+  LttTime next_tick = ltt_time_zero, delay, preempt_begin, preempt_time, 
+          last_write_event_time, last_read_event_time, original_event_time;
+  EventData *new_event, *event;
+  int i,j, overruns = 0;
+  gboolean wait_period_called = FALSE;
+  RunningThread *temp_running_thread;
+  GArray* new_event_list = g_array_new(FALSE, FALSE, sizeof(EventData*));
+  gboolean first_thread_switch, running = FALSE;
+  LttTime new_period = { 0, temp_thread->period };
+  
+  // We will iterate on all event of this thread
+  for(i=0;i<temp_thread->event_list->len;i++){
+    // for the first event read
+    if (i == 0){
+      new_event =  g_array_index(temp_thread->event_list, EventData*, i);
+      last_write_event_time = new_event->event_time;
+      last_read_event_time = new_event->event_time;
+      original_event_time = new_event->event_time;
+    }
+    else{
+      last_write_event_time = new_event->event_time;
+      last_read_event_time = original_event_time;
+      new_event =  g_array_index(temp_thread->event_list, EventData*, i);
+      original_event_time = new_event->event_time;
+    }
+    
+    // Calculate the delay between to following events
+    delay = ltt_time_sub(original_event_time,last_read_event_time);
+
+    // We need to save all events from the timer_tick until the wait_period event
+    // At the same time we can calculate the new time of the event
+    if (new_event->name == LTT_EVENT_XENOLTT_TIMER_TICK){
+      printf("NEW PERIOD\n");
+      // The first tick will be unchanged
+      if(ltt_time_compare(ltt_time_zero,next_tick) != 0){
+        new_event->event_time = next_tick;
+      }
+      next_tick = ltt_time_add(new_event->event_time,new_period);
+      wait_period_called = FALSE;      // We prepare for next period that should begin now
+
+      g_array_append_val(new_event_list,new_event);  // insert the new timer_tick
+      printf("\tTIMER_TICK - TIME: %lu.%lu - %lu.%lu\n", original_event_time.tv_sec,original_event_time.tv_nsec,
+                                                          new_event->event_time.tv_sec,new_event->event_time.tv_nsec);
+      
+      first_thread_switch = TRUE;
+      preempt_time = ltt_time_zero;
+      preempt_begin = ltt_time_zero;
+      
+      /************************************************************************
+       * Beginning of a new period
+       * We must check for thread_switching (preemption)
+       * new timer tick to create
+       * overrun to create
+       * event missed_period to create
+       ************************************************************************/
+      
+      while(new_event->name != LTT_EVENT_XENOLTT_THREAD_WAIT_PERIOD){  // Until the end of the period
+        i++;
+        last_write_event_time = new_event->event_time;
+        last_read_event_time = original_event_time;
+        new_event =  g_array_index(temp_thread->event_list, EventData*, i);
+        original_event_time = new_event->event_time;
+
+        // Calculate the delay between to following events
+        delay = ltt_time_sub(original_event_time,last_read_event_time);
+        delay = ltt_time_sub(delay,preempt_time);
+
+        // Need to test if we have exceeded the new period
+        if(new_event->name != LTT_EVENT_XENOLTT_TIMER_TICK){
+          if (ltt_time_compare(ltt_time_add(last_write_event_time,delay),next_tick) > 0){
+            EventData *tick_event = g_new(EventData, 1);
+            tick_event->event_time = next_tick;
+            tick_event->name = LTT_EVENT_XENOLTT_TIMER_TICK;
+            g_array_append_val(new_event_list,tick_event);
+            next_tick = ltt_time_add(tick_event->event_time,new_period);
+            printf("\t%s - TIME: \t%lu.%lu\n", g_quark_to_string(tick_event->name),tick_event->event_time.tv_sec,tick_event->event_time.tv_nsec);
+            overruns++;
+          }  
+        }
+        
+        if(new_event->name == LTT_EVENT_XENOLTT_THREAD_INIT ||
+          new_event->name == LTT_EVENT_XENOLTT_THREAD_SET_PERIOD ||
+          new_event->name == LTT_EVENT_XENOLTT_THREAD_START ||
+          new_event->name == LTT_EVENT_XENOLTT_THREAD_RESUME ||
+          new_event->name == LTT_EVENT_XENOLTT_THREAD_RENICE ||
+          new_event->name == LTT_EVENT_XENOLTT_THREAD_SUSPEND){
+          new_event->event_time = ltt_time_add(last_write_event_time,delay); // New time of the event
+          // Insert event in the period list
+          g_array_append_val(new_event_list,new_event);
+          printf("\t%s - TIME: %lu.%lu - %lu.%lu\n", g_quark_to_string(new_event->name),original_event_time.tv_sec,original_event_time.tv_nsec,
+                                                          new_event->event_time.tv_sec,new_event->event_time.tv_nsec);
+        }
+        // the first Thread_Switch indicate that the thread is now running
+        else if(new_event->name == LTT_EVENT_XENOLTT_THREAD_SWITCH){
+          if (first_thread_switch){
+            running = TRUE;
+            first_thread_switch = FALSE;
+            new_event->event_time = ltt_time_add(last_write_event_time,delay); // New time of the event  
+            // Insert event in the period list
+            g_array_append_val(new_event_list,new_event);
+            printf("\t%s - TIME: %lu.%lu - %lu.%lu\n", g_quark_to_string(new_event->name),original_event_time.tv_sec,original_event_time.tv_nsec,
+                                                            new_event->event_time.tv_sec,new_event->event_time.tv_nsec);
+          }
+          // Not the first thread switch, we will delete this event and the previous one that should be thread_suspend
+          else if(running){ 
+            running = FALSE;  // Stop the thread
+            new_event =  g_array_index(temp_thread->event_list, EventData*, (i-1));
+            preempt_begin = new_event->event_time;// Save the time of the preemption (time of the suspend event
+          }
+          // Thread is suspended and want to restart, delete the thread_switch and the following event that should be thread_resume
+          else{
+            running = TRUE; // restart thread
+            i++;
+            new_event =  g_array_index(temp_thread->event_list, EventData*, i);
+            preempt_time = ltt_time_add(preempt_time,ltt_time_sub(new_event->event_time,preempt_begin));// ignore the time spent in ready state
+          }
+        }
+        // Thread going in overrun
+        else if(new_event->name == LTT_EVENT_XENOLTT_TIMER_TICK){
+          new_event->event_time = next_tick;
+          next_tick = ltt_time_add(new_event->event_time,new_period);
+          overruns++;  // If wait_period has not been called, this means we are going in overrun
+          // Insert event in the period list
+          g_array_append_val(new_event_list,new_event);
+          printf("\t%s - TIME: %lu.%lu - %lu.%lu\n", g_quark_to_string(new_event->name),original_event_time.tv_sec,original_event_time.tv_nsec,
+                                                          new_event->event_time.tv_sec,new_event->event_time.tv_nsec);
+        }
+
+        if(new_event->name == LTT_EVENT_XENOLTT_THREAD_WAIT_PERIOD){
+          new_event->event_time = ltt_time_add(last_write_event_time,delay); // New time of the event
+          g_array_append_val(new_event_list,new_event);
+          printf("\t%s - TIME: %lu.%lu - %lu.%lu\n", g_quark_to_string(new_event->name),original_event_time.tv_sec,original_event_time.tv_nsec,
+                                                          new_event->event_time.tv_sec,new_event->event_time.tv_nsec);
+          printf("END PERIOD\n");
+          wait_period_called = TRUE;
+          if(overruns > 0){
+            EventData *missed_period_event = g_new(EventData, 1);
+            missed_period_event->event_time = new_event->event_time;  // Same time ??
+            missed_period_event->name = LTT_EVENT_XENOLTT_THREAD_MISSED_PERIOD;
+            g_array_append_val(new_event_list,missed_period_event);
+            printf("\t%s - TIME: %lu.%lu\n", g_quark_to_string(missed_period_event->name),
+                                                          missed_period_event->event_time.tv_sec,missed_period_event->event_time.tv_nsec);
+          }
+          overruns = 0;
+          // Period is finished
+          running = FALSE;
+        }
+         
+        if(new_event->name == LTT_EVENT_XENOLTT_THREAD_DELETE){
+          // Insert event in the period list
+          new_event->event_time = ltt_time_add(last_write_event_time,delay); // New time of the event
+          g_array_append_val(new_event_list,new_event);
+          printf("\t%s - TIME: %lu.%lu - %lu.%lu\n", g_quark_to_string(new_event->name),original_event_time.tv_sec,original_event_time.tv_nsec,
+                                                          new_event->event_time.tv_sec,new_event->event_time.tv_nsec);
+          break;
+        }
+      }
+    }
+    // For other events, simply save them with new time
+    else{
+      if (new_event->name != LTT_EVENT_XENOLTT_THREAD_MISSED_PERIOD){
+        new_event->event_time = ltt_time_add(last_write_event_time,delay); // New time of the event
+        g_array_append_val(new_event_list,new_event);
+        printf("NO_PERIOD %s - TIME: %lu.%lu - %lu.%lu\n", g_quark_to_string(new_event->name),original_event_time.tv_sec,original_event_time.tv_nsec,
+                                                            new_event->event_time.tv_sec,new_event->event_time.tv_nsec);
+      }
+    }
+  }
+  
+  // Now we have a full list of events representing the simulation of the current task
+  // Last step consist of checking if this thread will be preempted by others
+  // To see that, we will check in the running_thread list to find some free time space
+
+  // Iterate on the event_list and check for every thread_switch
+    // We will iterate on all event of this thread
+  gboolean not_running = TRUE;
+  
+  for(i=0;i<new_event_list->len;i++){
+    event =  g_array_index(new_event_list, EventData*, i);
+    if (event->name == LTT_EVENT_XENOLTT_THREAD_SWITCH){
+      if (not_running){
+        not_running = FALSE;
+        for(j=0;j<running_thread->len;j++){
+          temp_running_thread = g_array_index(running_thread, RunningThread*, j);
+          // First we need to get the thread running at the closest time before the current time
+          if (ltt_time_compare(temp_running_thread->begin_time,event->event_time) > 0){
+            // If thread finishes after current time, we must delay the task
+            // We will check the previous thread in the running list
+            temp_running_thread = g_array_index(running_thread, RunningThread*, (j-1));
+            if (ltt_time_compare(temp_running_thread->end_time,event->event_time) <= 0){
+              event->event_time = temp_running_thread->end_time;
+            }
+            else{ // Time is good
+              break;
+            }
+          }
+        }
+        
+        
+        // At this time we should have found a free starting position
+        RunningThread *new_running = g_new(RunningThread,1);
+        new_running->thread = temp_thread;
+        new_running->begin_time = event->event_time;
+        
+        j--;
+        
+        delay = ltt_time_zero;
+        // Next step is to chek before all event, if we must preempt the thread because a higher priority task is already running
+        // Preemption will cause the creation of 2 events thread_switch
+        for(i++;i<new_event_list->len;i++){
+          event =  g_array_index(new_event_list, EventData*, i);
+          // Don't delay Timer_Tick
+          if (event->name == LTT_EVENT_XENOLTT_TIMER_TICK){
+            if (wait_period_called) wait_period_called = FALSE;
+          }
+          // If event is a thread_switch, this means we have finish the period
+          else if (event->name == LTT_EVENT_XENOLTT_THREAD_SWITCH){
+              event->event_time = ltt_time_add(event->event_time,delay);
+              new_running->end_time = event->event_time;
+              // Add the thread in the running thread list
+              // j is the index where we found a free time space
+              g_array_insert_val(running_thread,j,new_running);
+              not_running = TRUE;
+              break;
+          }
+          else{
+            event->event_time = ltt_time_add(event->event_time,delay);
+
+            // We must check the if the next running thread is beginning before the event_time
+            temp_running_thread = g_array_index(running_thread, RunningThread*, j);
+
+            if(ltt_time_compare(event->event_time,temp_running_thread->begin_time) >= 0){
+              // if so, we must preempt the task and delay all event of the period
+              delay = ltt_time_add(delay,ltt_time_sub(event->event_time,temp_running_thread->begin_time));
+
+              // Insert a thread switch out
+              new_event = g_new(EventData, 1);
+              new_event->event_time = temp_running_thread->begin_time;
+              new_event->name = LTT_EVENT_XENOLTT_THREAD_SWITCH;
+              g_array_insert_val(new_event_list,i,new_event);
+
+              // Insert a thread switch in that will be check at next iteration
+              new_event = g_new(EventData, 1);
+              new_event->event_time = temp_running_thread->end_time;
+              new_event->name = LTT_EVENT_XENOLTT_THREAD_SWITCH;
+              g_array_insert_val(new_event_list,(i+1),new_event);
+              
+              // Insert the thread in the running thread
+              new_running->end_time = temp_running_thread->begin_time;
+              g_array_insert_val(running_thread,j,new_running);
+              not_running = TRUE;
+              
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+/*  
+  //Print the new thread simulation
+  for(j=0;j<new_event_list->len;j++){
+    event =  g_array_index(new_event_list, EventData*, j);
+    printf("%s - TIME: %lu.%lu\n", g_quark_to_string(event->name),event->event_time.tv_sec,event->event_time.tv_nsec);
+  }
+*/
+}
+
+void simulater_high_priority_thread(ThreadEventData* thread){
+  EventData *event;
+  gboolean running = FALSE;
+  RunningThread *run_thread  = g_new(RunningThread, 1);
+  RunningThread *temp_thread;
+  int i,j; 
+  LttTime begin_time = ltt_time_zero;
+  LttTime end_time = ltt_time_zero;
+  gboolean inserted;
+
+  for(i=0;i<thread->event_list->len;i++){
+    event =  g_array_index(thread->event_list, EventData*, i);
+    
+    if(event->name == LTT_EVENT_XENOLTT_THREAD_SWITCH){
+      if(running){
+        running = FALSE;
+        end_time = event->event_time;
+        run_thread  = g_new(RunningThread, 1);
+        run_thread->thread = thread;
+        run_thread->begin_time = begin_time;
+        run_thread->end_time = end_time;
+        
+        inserted = FALSE;
+        for(j=0;j<running_thread->len;j++){
+          temp_thread =  g_array_index(running_thread, RunningThread*, j);
+          if (ltt_time_compare(temp_thread->begin_time,run_thread->begin_time) > 0){
+            g_array_insert_val(running_thread,j,run_thread);
+            inserted = TRUE;
+            break;
+          }
+        }
+        if (!inserted) g_array_append_val(running_thread,run_thread);
+      }
+      else{
+        running = TRUE;
+        begin_time = event->event_time;
+      }
+    }
+    
+    
+  }  
+}
+
+gint sort_running_thread(gconstpointer a,gconstpointer b){
+  const RunningThread *pa = (const RunningThread*)a;
+  const RunningThread *pb = (const RunningThread*)b;
+  
+  return ltt_time_compare(pa->begin_time,pb->begin_time);
+}
+
+void compute_simulation(guint index,guint period){
+  
+  int i;
+  ThreadEventData *temp_thread;
+  RunningThread *run_thread;
+  
+  printf("---\n");
+  
+  printf("-> %u\n",thread_event_list->len);
+  // First, set the new period of the thread
+  temp_thread = g_array_index(thread_event_list, ThreadEventData*, index);
+  // We will double the simulation only if period has changed
+  if (period != temp_thread->period) temp_thread->period = period;
+  else{
+    printf("Period is the same, no need to simulate\n");
+    return;
+  }
+  
+  /* 
+   First, we need to ignore all task with higher priority 
+   than the task we want to simulate that's why we begin the simulation
+   from the thread index which we will modify the period
+  */
+  printf("simulater_high_priority_thread\n");
+  for(i=0;i<index;i++){
+    temp_thread = g_array_index(thread_event_list, ThreadEventData*, i);
+    simulater_high_priority_thread(temp_thread);    
+  }
+  
+  for(i=index;i<thread_event_list->len;i++){
+    temp_thread = g_array_index(thread_event_list, ThreadEventData*, i);
+    printf("%s - %u\n",g_quark_to_string(temp_thread->name), temp_thread->prio);
+
+    
+//    temp_thread->period = period;
+    temp_thread->period = 20000;
+
+    
+    // We will simulate this thread considering all higher priority threads
+    printf("calculate_event_time\n");
+    calculate_event_time(index, temp_thread);
+  }  
+
+
+  printf("print run_thread\n");
+  for(i=0;i<running_thread->len;i++){
+    run_thread = g_array_index(running_thread, RunningThread*, i);
+    printf("%s\tFROM:%lu.%lu\tTO:%lu.%lu\n",g_quark_to_string(run_thread->thread->name),run_thread->begin_time.tv_sec,run_thread->begin_time.tv_nsec,
+                                                                                      run_thread->end_time.tv_sec,run_thread->end_time.tv_nsec);
+  }  
+}
+
+gboolean save_event(void *hook_data, void *call_data){
+  LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
+  LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
+  LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
+  guint cpu = tfcs->parent.cpu;
+  LttvXenoThreadState *thread_info;
+
+  LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
+  LttEvent *e = ltt_tracefile_get_event(tfc->tf);  
+  GQuark event_name = ltt_eventtype_name(ltt_event_eventtype(e));  
+  LttTime evtime = ltt_event_time(e);
+  
+  if (event_name == LTT_EVENT_XENOLTT_TIMER_TICK){
+    gulong timer_address = ltt_event_get_long_unsigned(e, thf->f1);
+    thread_info = lttv_xeno_state_find_thread_from_timer(ts,cpu,timer_address);
+  }
+  else{
+    gulong address = ltt_event_get_long_unsigned(e, thf->f1);  
+    // First we need to lookup for the current thread in the list
+    thread_info = lttv_xeno_state_find_thread(ts,cpu,address);
+  }
+  
+  if (thread_info != NULL){
+    ThreadEventData *thread = lookup_or_create_thread(thread_info->address, thread_info->prio, thread_info->creation_time, thread_info->name);
+  //  printf("%s - %lu.%lu\n",g_quark_to_string(event_name), evtime.tv_sec, evtime.tv_nsec);
+    if (event_name == LTT_EVENT_XENOLTT_THREAD_SET_PERIOD) thread->period = thread_info->period;
+    //Thread is found in the table, we can insert the new event in the list
+    EventData *new_event = g_new(EventData, 1);
+    new_event->event_time = evtime;
+    new_event->name = event_name;
+    new_event->event = e;
+    g_array_append_val(thread->event_list,new_event); 
+  }
+
+  return FALSE;
+}
+
+/****************************************************************************************************************************/
+
+
+
+
+static void module_init()
+{
+}
+
+static void module_destroy() 
+{
+}
+
+
+LTTV_MODULE("xenoltt_sim", "Compute Xenomai Tasks simulation", \
+    "Simulate a task execution with a different period", \
+    module_init, module_destroy, "state");
This page took 0.029345 seconds and 4 git commands to generate.