Add state saving functions and update processTrace accordingly.
[lttv.git] / ltt / branches / poly / ltt / tracefile.c
index 05978a489b306d15f632a086674c6919506ab7ac..07b8ab3a837a1f3d5cb7a69124a1f58f5482df87 100644 (file)
@@ -33,10 +33,6 @@ void updateTracefile(LttTracefile * tf);
 /* go to the next event */
 int skipEvent(LttTracefile * t);
 
-/* compare two time (LttTime), 0:t1=t2, -1:t1<t2, 1:t1>t2 */
-int timecmp(LttTime * t1, LttTime * t2);
-
-
 
 /*****************************************************************************
  *Function name
@@ -404,7 +400,7 @@ void getCpuFileInfo(LttTrace *t, char* cpu)
  *are released as well.
  ****************************************************************************/
 
-LttTrace *ltt_trace_open(char *pathname)
+LttTrace *ltt_trace_open(const char *pathname)
 {
   LttTrace  * t;
   LttSystemDescription * sys_description;
@@ -463,6 +459,16 @@ LttTrace *ltt_trace_open(char *pathname)
   return t;
 }
 
+/******************************************************************************
+ * When we copy a trace, we want all the opening actions to happen again :
+ * the trace will be reopened and totally independant from the original.
+ * That's why we call ltt_trace_open.
+ *****************************************************************************/
+LttTrace *ltt_trace_copy(LttTrace *self)
+{
+  return ltt_trace_open(self->pathname);
+}
+
 void ltt_trace_close(LttTrace *t)
 {
   int i;
@@ -571,7 +577,7 @@ unsigned ltt_trace_eventtype_number(LttTrace *t)
   int i;
   unsigned count = 0;
   LttFacility * f;
-  for(i=0;i=t->facility_number;i++){
+  for(i=0;i<t->facility_number;i++){
     f = (LttFacility*)g_ptr_array_index(t->facilities, i);
     count += f->event_number;
   }
@@ -661,6 +667,52 @@ LttTracefile *ltt_trace_per_cpu_tracefile_get(LttTrace *t, unsigned i)
   return (LttTracefile*)g_ptr_array_index(t->per_cpu_tracefiles, i);
 }
 
+/*****************************************************************************
+ * Get the start time and end time of the trace 
+ ****************************************************************************/
+
+void ltt_trace_time_span_get(LttTrace *t, LttTime *start, LttTime *end)
+{
+  LttTime startSmall, startTmp, endBig, endTmp;
+  int i, j=0;
+  LttTracefile * tf;
+
+  for(i=0;i<t->control_tracefile_number;i++){
+    tf = g_ptr_array_index(t->control_tracefiles, i);
+    readBlock(tf,1);
+    startTmp = tf->a_block_start->time;    
+    readBlock(tf,tf->block_number);
+    endTmp = tf->a_block_end->time;
+    if(i==0){
+      startSmall = startTmp;
+      endBig     = endTmp;
+      j = 1;
+      continue;
+    }
+    if(ltt_time_compare(startSmall,startTmp) > 0) startSmall = startTmp;
+    if(ltt_time_compare(endBig,endTmp) < 0) endBig = endTmp;
+  }
+
+  for(i=0;i<t->per_cpu_tracefile_number;i++){
+    tf = g_ptr_array_index(t->per_cpu_tracefiles, i);
+    readBlock(tf,1);
+    startTmp = tf->a_block_start->time;    
+    readBlock(tf,tf->block_number);
+    endTmp = tf->a_block_end->time;
+    if(j == 0 && i==0){
+      startSmall = startTmp;
+      endBig     = endTmp;
+      continue;
+    }
+    if(ltt_time_compare(startSmall,startTmp) > 0) startSmall = startTmp;
+    if(ltt_time_compare(endBig,endTmp) < 0) endBig = endTmp;
+  }
+
+  *start = startSmall;
+  *end = endBig;
+}
+
+
 /*****************************************************************************
  *Get the name of a tracefile
  ****************************************************************************/
@@ -670,6 +722,15 @@ char *ltt_tracefile_name(LttTracefile *tf)
   return tf->name;
 }
 
+/*****************************************************************************
+ * Get the number of blocks in the tracefile 
+ ****************************************************************************/
+
+unsigned ltt_tracefile_block_number(LttTracefile *tf)
+{
+  return tf->block_number; 
+}
+
 /*****************************************************************************
  *Function name
  *    ltt_tracefile_seek_time: seek to the first event of the trace with time 
@@ -683,37 +744,42 @@ void ltt_tracefile_seek_time(LttTracefile *t, LttTime time)
 {
   int err;
   LttTime lttTime;
-  int headTime = timecmp(&(t->a_block_start->time), &time);
-  int tailTime = timecmp(&(t->a_block_end->time), &time);
+  int headTime = ltt_time_compare(t->a_block_start->time, time);
+  int tailTime = ltt_time_compare(t->a_block_end->time, time);
   LttEvent * ev;
 
   if(headTime < 0 && tailTime > 0){
-    lttTime = getEventTime(t);
-    err = timecmp(&lttTime, &time);
-    if(err > 0){
-      if(t->which_event==2 || timecmp(&t->prev_event_time,&time)<0){
-       return;
-      }else{
-       updateTracefile(t);
-       return ltt_tracefile_seek_time(t, time);
-      }
-    }else if(err < 0){
-      while(1){
-       ev = ltt_tracefile_read(t);
-       if(ev == NULL){
-         g_print("End of file\n");      
+    if(ltt_time_compare(t->a_block_end->time, t->current_event_time) !=0) {
+      lttTime = getEventTime(t);
+      err = ltt_time_compare(lttTime, time);
+      if(err > 0){
+       if(t->which_event==2 || (&t->prev_event_time,&time)<0){
          return;
+       }else{
+         updateTracefile(t);
+         return ltt_tracefile_seek_time(t, time);
        }
-       lttTime = getEventTime(t);
-       err = timecmp(&lttTime, &time);
-       if(err >= 0)return;
-      }
-    }else return;    
-  }else if(headTime > 0){
+      }else if(err < 0){
+       while(1){
+         ev = ltt_tracefile_read(t);
+         if(ev == NULL){
+           g_print("End of file\n");      
+           return;
+         }
+         lttTime = getEventTime(t);
+         err = ltt_time_compare(lttTime, time);
+         if(err >= 0)return;
+       }
+      }else return;    
+    }else{//we are at the end of the block
+      updateTracefile(t);
+      return ltt_tracefile_seek_time(t, time);      
+    }
+  }else if(headTime >= 0){
     if(t->which_block == 1){
       updateTracefile(t);      
     }else{
-      if(timecmp(&(t->prev_block_end_time),&time) >= 0 ){
+      if(ltt_time_compare(t->prev_block_end_time, time) >= 0 ){
        err=readBlock(t,t->which_block-1);
        if(err) g_error("Can not read tracefile: %s\n", t->name); 
        return ltt_tracefile_seek_time(t, time) ;
@@ -730,10 +796,8 @@ void ltt_tracefile_seek_time(LttTracefile *t, LttTime time)
       return;      
     }    
     if(tailTime < 0) return ltt_tracefile_seek_time(t, time);
-  }else if(headTime == 0){
-    updateTracefile(t);
   }else if(tailTime == 0){
-    t->cur_event_pos = t->a_block_end - EVENT_HEADER_SIZE;
+    t->cur_event_pos = t->last_event_pos;
     t->current_event_time = time;  
     t->cur_heart_beat_number = 0;
     t->prev_event_time.tv_sec = 0;
@@ -742,6 +806,32 @@ void ltt_tracefile_seek_time(LttTracefile *t, LttTime time)
   }
 }
 
+/*****************************************************************************
+ * Seek to the first event with position equal or larger to ep 
+ ****************************************************************************/
+
+void ltt_tracefile_seek_position(LttTracefile *t, LttEventPosition *ep)
+{
+  //if we are at the right place, just return
+  if(t->which_block == ep->block_num && t->which_event == ep->event_num)
+    return;
+  
+  if(t->which_block == ep->block_num) updateTracefile(t);
+  else readBlock(t,ep->block_num);
+
+  //event offset is availiable
+  if(ep->old_position){
+    t->cur_heart_beat_number = ep->heart_beat_number;
+    t->cur_event_pos = t->buffer + ep->event_offset;
+    return;
+  }
+
+  //only block number and event index are availiable
+  while(t->which_event < ep->event_num) ltt_tracefile_read(t);
+
+  return;
+}
+
 /*****************************************************************************
  *Function name
  *    ltt_tracefile_read : read the current event, set the pointer to the next
@@ -758,7 +848,6 @@ LttEvent *ltt_tracefile_read(LttTracefile *t)
 
   if(t->cur_event_pos == t->buffer + t->block_size){
     if(t->which_block == t->block_number){
-      g_free(lttEvent);
       return NULL;
     }
     err = readBlock(t, t->which_block + 1);
@@ -775,9 +864,6 @@ LttEvent *ltt_tracefile_read(LttTracefile *t)
   lttEvent->time_delta = *(uint32_t*)(t->cur_event_pos + EVENT_ID_SIZE);
   lttEvent->event_time = t->current_event_time;
 
-  lttEvent->event_cycle_count = ((uint64_t)1)<<32  * t->cur_heart_beat_number 
-                                + lttEvent->time_delta;
-
   lttEvent->tracefile = t;
   lttEvent->data = t->cur_event_pos + EVENT_HEADER_SIZE;  
   lttEvent->which_block = t->which_block;
@@ -787,6 +873,8 @@ LttEvent *ltt_tracefile_read(LttTracefile *t)
   err = skipEvent(t);
   if(err == ERANGE) g_error("event id is out of range\n");
 
+  lttEvent->event_cycle_count = t->cur_cycle_count;
+
   return lttEvent;
 }
 
@@ -851,6 +939,7 @@ int readBlock(LttTracefile * tf, int whichBlock)
   lostSize = *(uint32_t*)(tf->buffer + tf->block_size - sizeof(uint32_t));
   tf->a_block_end=(BlockEnd *)(tf->buffer + tf->block_size - 
                                lostSize + EVENT_HEADER_SIZE); 
+  tf->last_event_pos = tf->buffer + tf->block_size - lostSize;
 
   tf->which_block = whichBlock;
   tf->which_event = 1;
@@ -945,14 +1034,16 @@ void getCyclePerNsec(LttTracefile * t)
   LttCycleCount     lBufTotalCycle;/* Total cycles for this buffer */
 
   /* Calculate the total time for this buffer */
-  TimeSub(lBufTotalTime,t->a_block_end->time, t->a_block_start->time);
+  lBufTotalTime = ltt_time_sub(t->a_block_end->time, t->a_block_start->time);
 
   /* Calculate the total cycles for this bufffer */
-  lBufTotalCycle = t->a_block_end->cycle_count 
-                   - t->a_block_start->cycle_count;
+  lBufTotalCycle  = t->a_block_end->cycle_count;
+  lBufTotalCycle -= t->a_block_start->cycle_count;
 
   /* Convert the total time to nsecs */
-  lBufTotalNSec = lBufTotalTime.tv_sec * 1000000000 + lBufTotalTime.tv_nsec;
+  lBufTotalNSec  = lBufTotalTime.tv_sec;
+  lBufTotalNSec *= NANOSECONDS_PER_SECOND; 
+  lBufTotalNSec += lBufTotalTime.tv_nsec;
   
   t->cycle_per_nsec = (double)lBufTotalCycle / (double)lBufTotalNSec;
 }
@@ -974,29 +1065,48 @@ LttTime getEventTime(LttTracefile * tf)
   double        lEventNSec;       // Total usecs from start for event
   LttTime       lTimeOffset;      // Time offset in struct LttTime
   uint16_t      evId;
-  
+  int64_t       nanoSec, tmpCycleCount = (((uint64_t)1)<<32);
+  static LttCycleCount preCycleCount = 0;
+  static int   count = 0;
+
   evId = *(uint16_t*)tf->cur_event_pos;
-  if(evId == TRACE_BLOCK_START)
+  if(evId == TRACE_BLOCK_START){
+    count = 0;
+    preCycleCount = 0;
+    tf->cur_cycle_count = tf->a_block_start->cycle_count;
     return tf->a_block_start->time;
-  else if(evId == TRACE_BLOCK_END)
+  }else if(evId == TRACE_BLOCK_END){
+    count = 0;
+    preCycleCount = 0;
+    tf->cur_cycle_count = tf->a_block_end->cycle_count;
     return tf->a_block_end->time;
+  }
   
-
-  // Calculate total time in cycles from start of buffer for this event 
+  // Calculate total time in cycles from start of buffer for this event
   cycle_count = (LttCycleCount)*(uint32_t*)(tf->cur_event_pos + EVENT_ID_SIZE);
-  if(tf->cur_heart_beat_number)
-    cycle_count += ((uint64_t)1)<<32  * tf->cur_heart_beat_number;
-  lEventTotalCycle = cycle_count - tf->a_block_start->cycle_count;
+  
+  if(cycle_count < preCycleCount)count++;
+  preCycleCount = cycle_count;
+  cycle_count += tmpCycleCount * count;  
+  
+  if(tf->cur_heart_beat_number > count)
+    cycle_count += tmpCycleCount * (tf->cur_heart_beat_number - count);  
+
+  tf->cur_cycle_count = cycle_count;
+
+  lEventTotalCycle  = cycle_count;
+  lEventTotalCycle -= tf->a_block_start->cycle_count;
 
   // Convert it to nsecs
   lEventNSec = lEventTotalCycle / tf->cycle_per_nsec;
-  
-  // Determine offset in struct LttTime 
-  lTimeOffset.tv_nsec = (long)lEventNSec % 1000000000;
-  lTimeOffset.tv_sec  = (long)lEventNSec / 1000000000;
+  nanoSec    = lEventNSec;
 
-  TimeAdd(time, tf->a_block_start->time, lTimeOffset);  
+  // Determine offset in struct LttTime 
+  lTimeOffset.tv_nsec = nanoSec % NANOSECONDS_PER_SECOND;
+  lTimeOffset.tv_sec  = nanoSec / NANOSECONDS_PER_SECOND;
 
+  time = ltt_time_add(tf->a_block_start->time, lTimeOffset);  
+  
   return time;
 }
 
@@ -1148,24 +1258,6 @@ int getFieldtypeSize(LttTracefile * t, LttEventType * evT, int offsetRoot,
   return size;
 }
 
-/*****************************************************************************
- *Function name
- *    timecmp   : compare two time
- *Input params 
- *    t1        : first time
- *    t2        : second time
- *Return value
- *    int       : 0: t1 == t2; -1: t1 < t2; 1: t1 > t2
- ****************************************************************************/
-
-int timecmp(LttTime * t1, LttTime * t2)
-{
-  if(t1->tv_sec < t2->tv_sec) return -1;
-  if(t1->tv_sec > t2->tv_sec) return 1;
-  if(t1->tv_nsec < t2->tv_nsec) return -1;
-  if(t1->tv_nsec > t2->tv_nsec) return 1;
-  return 0;
-}
 
 /*****************************************************************************
  *Function name
This page took 0.026561 seconds and 4 git commands to generate.