LTTV 0.8.6 : support for architecture without TSC
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 20 Jan 2006 18:10:51 +0000 (18:10 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 20 Jan 2006 18:10:51 +0000 (18:10 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@1484 04897980-b3bd-0310-b5e0-8ef037075253

ltt/branches/poly/configure.in
ltt/branches/poly/doc/developer/format.html
ltt/branches/poly/doc/developer/lttng-lttv-compatibility.html
ltt/branches/poly/doc/developer/lttng-userspace-tracing.txt
ltt/branches/poly/ltt/ltt-private.h
ltt/branches/poly/ltt/tracefile.c

index 171331a461f9b8e8a9f7e758e6bb7c007fb21133..5ecb494f1e6073ef44e52330057e0ebd7f990d1b 100644 (file)
@@ -23,7 +23,7 @@
 AC_PREREQ(2.57)
 AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
 #AC_WITH_LTDL  # not needed ?
-AM_INIT_AUTOMAKE(LinuxTraceToolkitViewer,0.8.5-17012006)
+AM_INIT_AUTOMAKE(LinuxTraceToolkitViewer,0.8.6-20012006)
 AM_CONFIG_HEADER(config.h)
 AM_PROG_LIBTOOL
 
index ee98fc203c92ab9906a85aee0ace6ef1cb5aad91..a211ace1e9c6e9e6370e0aa77310df4901aedf7f 100644 (file)
@@ -125,20 +125,12 @@ The block start/end header
 <PRE><TT>
 begin
        * the beginning of buffer information
-       timestamp
-               * Used only when no TSC is available.
-               uint32 seconds
-               uint32 microseconds
        uint64 cycle_count
                * TSC at the beginning of the buffer
        uint64 freq
                * frequency of the CPUs at the beginning of the buffer.
 end
        * the end of buffer information
-       timestamp
-               * Used only when no TSC is available.
-               uint32 seconds
-               uint32 microseconds
        uint64 cycle_count
                * TSC at the beginning of the buffer
        uint64 freq
@@ -181,15 +173,9 @@ uint8 has_alignment
        * Is the information in this trace aligned ?
                Yes (1) -> aligned on min(arch size, atomic data size).
                No (0) -> data is packed.
-uint8 has_tsc
-       * Does the traced machine has a working TSC ?
-               Yes (1) -> event time is calculated from :
-                       trace_start_time + ((event_tsc - trace_start_tsc) * freq)
-               No (0) -> event time is calculated from :
-                       trace_start_time 
-                       + (buffer start timestamp - trace start_monotonic) 
-                       + (event_time_delta)
-                       (not supported)
+uint328 freq_scale
+               event time is always calculated from :
+                       trace_start_time + ((event_tsc - trace_start_tsc) * (freq / freq_scale))
 uint64 start_freq
        * CPUs clock frequency at the beginnig of the trace.
 uint64 start_tsc
@@ -222,9 +208,6 @@ Event header :
        uint64 timestamp }
        * if has_heartbeat : 32 LSB of the cycle counter at the event record time.
        * else : 64 bits complete cycle counter.
-       * note : if there is no working TSC (has_tsc == 0), then this field contains
-         either the complete monotonically increasing time or the time delta from the
-               previous heartbeat event. (unsupported)
 uint8 facility_id
        * Numerical ID of the facility corresponding to the event. See the facility
          tracefile to know which facility ID matches which facility name and
index 6cdd6d6362ba5f2a106bfb7f21ca7485de75e432..2ae961dbc1a4c4cdf5aa6695dc195290daafe38e 100644 (file)
@@ -193,6 +193,30 @@ Use atomic_cmpxchg()<br>
 </td>
 </tr>
 
+<tr>
+<td style="vertical-align: top;">
+0.8.6<br>
+</td>
+<td style="vertical-align: top;">
+0.5.7<br>
+</td>
+<td style="vertical-align: top;">0.4<br>
+</td>
+<td style="vertical-align: top;">
+0.7<br>
+</td>
+<td style="vertical-align: top;">0.6<br>
+</td>
+<td style="vertical-align: top;">
+2.6.15-i386 (git)<br>
+2.6.15-i386 (tarball)<br>
+</td>
+<td style="vertical-align: top;">
+Support for architectures without TSC.<br>
+<br>
+</td>
+</tr>
+
 
 
 </tbody>
index 85a31b3da9da30389be67010c34a7b5eb7026c4d..4bf221c3e0ef5fec2a53cce2ca03e85e08f4f9c4 100644 (file)
@@ -48,8 +48,13 @@ status.
 
 My suggestion is to go for a system call, but only call it :
 
-- when the process starts
-- when receiving a SIG_UPDTRACING
+- when the thread starts
+- when receiving a SIG_UPDTRACING (multithread ?)
+
+Note : save the thread ID (process ID) in the logging function and the update
+handler. Use it as a comparison to check if we are a forked child thread.
+Start a brand new buffer list in that case.
+
 
 Two possibilities :
 
@@ -66,7 +71,9 @@ I would tend to adopt :
 
 syscall get_tracing_info
 
-first parameter : active traces mask (32 bits : 32 traces).
+parameter 1 : trace buffer map address. (id)
+
+parameter 2 : active ? (int)
 
 
 Concurrency
@@ -79,15 +86,15 @@ that) and removes false sharing.
 Multiple traces
 
 By having the number of active traces, we can allocate as much buffers as we
-need. The only thing is that the buffers will only be allocated when receiving
-the signal/starting the process and getting the number of traces actives.
+need. Allocation is done in the kernel with relay_open. User space mapping is
+done when receiving the signal/starting the process and getting the number of
+traces actives.
 
 It means that we must make sure to only update the data structures used by
 tracing functions once the buffers are created.
 
-When adding a new buffer, we should call the set_tracing_info syscall and give
-the new buffers array to the kernel. It's an array of 32 pointers to user pages.
-They will be used by the kernel to get the last pages when the thread dies.
+We could have a syscall "get_next_buffer" that would basically mmap the next
+unmmapped buffer, or return NULL is all buffers are mapped.
 
 If we remove a trace, the kernel should stop the tracing, and then get the last
 buffer for this trace. What is important is to make sure no writers are still
@@ -115,8 +122,7 @@ We could do that trace removal in two operations :
        accessing this memory area. When the control comes back to the writer, at the
        end of the write in a trace, if the trace is marked for switch/delete and the
        tracing_level is 0 (after the decrement of the writer itself), then the
-       writer must buffer switch, set_tracing_info to NULL and then delete the
-       memory area.
+       writer must buffer switch, and then delete the memory area.
 
 
 Filter
@@ -124,9 +130,7 @@ Filter
 The update tracing info signal will make the thread get the new filter
 information. Getting this information will also happen upon process creation.
 
-parameter 2 for the get tracing info : array of 32 ints (32 bits).
-Each integer is the filter mask for a trace. As there are up to 32 active
-traces, we have 32 integers for filter.
+parameter 3 for the get tracing info : a integer containing the 32 bits mask.
 
 
 Buffer switch
@@ -142,15 +146,10 @@ The kernel should be aware of the current pages used for tracing in each thread.
 If a thread dies unexpectedly, we want the kernel to get the last bits of
 information before the thread crashes.
 
-syscall set_tracing_info
-
-parameter 1 : array of 32 user space pointers to current pages or NULL.
-
-
 Memory protection
 
-We want each process to be usable to make a trace unreadable, and each process
-to have its own memory space.
+If a process corrupt its own mmaped buffers, the rest of the trace will be
+readable, and each process have its own memory space.
 
 Two possibilities :
 
@@ -189,6 +188,34 @@ trace, per process.
 
 
 
+API :
+
+syscall 1 :
+
+int update_tracing_info(void *buffer, int *active, int *filter);
+
+
+syscall 2 :
+
+int tracing_buffer_switch(void *buffer);
+
+
+Signal :
+
+UPD_TRACING
+Default : SIG IGNORE
+(like hardware fault and expiring timer : to the thread, see p. 413 of Advances
+prog. in the UNIX env.)
+
+Will update for itself only : it will remove unnecessary concurrency.
+
+
+
+
+
+
+
+
 
 
 
index 57f0063e6f7126278ea8827d5f61d7f21220c976..6d51afbb73a753936c5a9ec4fb76c62a35669e6a 100644 (file)
@@ -160,7 +160,7 @@ struct ltt_trace_header_any {
   uint8_t         flight_recorder;
   uint8_t         has_heartbeat;
   uint8_t         has_alignment;  /* Event header alignment */
-       uint8_t                     has_tsc;
+       uint32_t                          freq_scale;
 } LTT_PACKED_STRUCT;
 
 
@@ -177,12 +177,12 @@ struct ltt_trace_header_0_3 {
   uint8_t         flight_recorder;
   uint8_t         has_heartbeat;
   uint8_t         has_alignment;  /* Event header alignment */
-       uint8_t                          has_tsc;
+       uint32_t                                freq_scale;
 } LTT_PACKED_STRUCT;
 
-/* For version 0.6 */
+/* For version 0.7 */
 
-struct ltt_trace_header_0_6 {
+struct ltt_trace_header_0_7 {
   uint32_t        magic_number;
   uint32_t        arch_type;
   uint32_t        arch_variant;
@@ -193,11 +193,10 @@ struct ltt_trace_header_0_6 {
   uint8_t         flight_recorder;
   uint8_t         has_heartbeat;
   uint8_t         has_alignment;  /* Event header alignment */
-  uint8_t         has_tsc;
+  uint32_t        freq_scale;
   uint64_t        start_freq;
   uint64_t        start_tsc;
   uint64_t        start_monotonic;
-  //struct timespec start_time; // not portable
   uint64_t        start_time_sec;
   uint64_t        start_time_usec;
 } LTT_PACKED_STRUCT;
@@ -205,16 +204,10 @@ struct ltt_trace_header_0_6 {
 
 struct ltt_block_start_header {
   struct { 
-    //struct timeval          timestamp;
-    uint64_t                timestamp_sec;
-    uint64_t                timestamp_usec;
     uint64_t                cycle_count;
     uint64_t                freq;
   } begin;
   struct {
-    //struct timeval          timestamp;
-    uint64_t                timestamp_sec;
-    uint64_t                timestamp_usec;
     uint64_t                cycle_count;
     uint64_t                freq;
   } end;
@@ -258,10 +251,7 @@ struct _LttEvent{
   
   /* End of LttEventPosition fields */
 
-       union {                                                                                 /* choice by trace has_tsc */
-         guint32  timestamp;                           /* truncated timestamp */
-       LttTime  delta;
-       } time;
+  guint32  timestamp;                          /* truncated timestamp */
 
   unsigned char facility_id;   /* facility ID are never reused. */
   unsigned char event_id;
@@ -406,7 +396,7 @@ struct _LttTrace{
   guint8    ltt_minor_version;
   guint8    flight_recorder;
   guint8    has_heartbeat;
-       guint8          has_tsc;
+       guint32         freq_scale;
   uint64_t  start_freq;
   uint64_t  start_tsc;
   uint64_t  start_monotonic;
index af99a23c4f241d6ace9ab9d503a25be778b98b64..5feb97f5e2a45fad890f1de8c267e62218942ff4 100644 (file)
@@ -232,7 +232,7 @@ int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t)
     t->ltt_minor_version = any->minor_version;
     t->flight_recorder = any->flight_recorder;
     t->has_heartbeat = any->has_heartbeat;
-    t->has_tsc = any->has_tsc;
+    t->freq_scale = any->freq_scale;
   }
  
 
@@ -250,13 +250,13 @@ int parse_trace_header(void *header, LttTracefile *tf, LttTrace *t)
         return 1;
       }
       break;
-    case 6:
+    case 7:
       {
-        struct ltt_trace_header_0_6 *vheader =
-          (struct ltt_trace_header_0_6 *)header;
+        struct ltt_trace_header_0_7 *vheader =
+          (struct ltt_trace_header_0_7 *)header;
         tf->buffer_header_size =
          sizeof(struct ltt_block_start_header) 
-            + sizeof(struct ltt_trace_header_0_6);
+            + sizeof(struct ltt_trace_header_0_7);
         if(t) {
           t->start_freq = ltt_get_uint64(LTT_GET_BO(tf),
                                          &vheader->start_freq);
@@ -1598,12 +1598,11 @@ LttTime ltt_interpolate_time(LttTracefile *tf, LttEvent *event)
 {
   LttTime time;
 
-  g_assert(tf->trace->has_tsc);
-
 //  time = ltt_time_from_uint64(
 //      cycles_2_ns(tf, (guint64)(tf->buffer.tsc - tf->buffer.begin.cycle_count)));
   time = ltt_time_from_uint64(
-      (double)(tf->buffer.tsc - tf->trace->start_tsc) * 1000000.0
+      (double)(tf->buffer.tsc - tf->trace->start_tsc) 
+                                                                                                                                       * (1000000000.0 / tf->trace->freq_scale)
                                   / (double)tf->trace->start_freq);
   //time = ltt_time_add(tf->buffer.begin.timestamp, time);
   time = ltt_time_add(tf->trace->start_time_from_tsc, time);
@@ -1719,43 +1718,30 @@ int ltt_tracefile_read_update_event(LttTracefile *tf)
        /* Align the head */
        pos += ltt_align((size_t)pos, tf->trace->arch_size, tf->has_alignment);
   
-  if(tf->trace->has_tsc) {
-    if(tf->trace->has_heartbeat) {
-      event->time.timestamp = ltt_get_uint32(LTT_GET_BO(tf),
-                                            pos);
-      /* 32 bits -> 64 bits tsc */
-      /* note : still works for seek and non seek cases. */
-      if(event->time.timestamp < (0xFFFFFFFFULL&tf->buffer.tsc)) {
-        tf->buffer.tsc = ((tf->buffer.tsc&0xFFFFFFFF00000000ULL)
-                            + 0x100000000ULL)
-                                | (guint64)event->time.timestamp;
-        event->tsc = tf->buffer.tsc;
-      } else {
-        /* no overflow */
-        tf->buffer.tsc = (tf->buffer.tsc&0xFFFFFFFF00000000ULL) 
-                                | (guint64)event->time.timestamp;
-        event->tsc = tf->buffer.tsc;
-      }
-      pos += sizeof(guint32);
-    } else {
-      event->tsc = ltt_get_uint64(LTT_GET_BO(tf), pos);
-      tf->buffer.tsc = event->tsc;
-      pos += sizeof(guint64);
-    }
-    
-    event->event_time = ltt_interpolate_time(tf, event);
-  } else {
-    event->time.delta.tv_sec = 0;
-    event->time.delta.tv_nsec = ltt_get_uint32(LTT_GET_BO(tf),
-                                          pos) * NSEC_PER_USEC;
-    tf->buffer.tsc = 0;
-    event->tsc = tf->buffer.tsc;
-
-    event->event_time = ltt_time_add(tf->buffer.begin.timestamp,
-                                     event->time.delta);
-    pos += sizeof(guint32);
-  }
-
+       if(tf->trace->has_heartbeat) {
+               event->timestamp = ltt_get_uint32(LTT_GET_BO(tf),
+                                                                                                                                                                       pos);
+               /* 32 bits -> 64 bits tsc */
+               /* note : still works for seek and non seek cases. */
+               if(event->timestamp < (0xFFFFFFFFULL&tf->buffer.tsc)) {
+                       tf->buffer.tsc = ((tf->buffer.tsc&0xFFFFFFFF00000000ULL)
+                                                                                                       + 0x100000000ULL)
+                                                                                                                       | (guint64)event->timestamp;
+                       event->tsc = tf->buffer.tsc;
+               } else {
+                       /* no overflow */
+                       tf->buffer.tsc = (tf->buffer.tsc&0xFFFFFFFF00000000ULL) 
+                                                                                                                       | (guint64)event->timestamp;
+                       event->tsc = tf->buffer.tsc;
+               }
+               pos += sizeof(guint32);
+       } else {
+               event->tsc = ltt_get_uint64(LTT_GET_BO(tf), pos);
+               tf->buffer.tsc = event->tsc;
+               pos += sizeof(guint64);
+       }
+       
+       event->event_time = ltt_interpolate_time(tf, event);
   event->facility_id = *(guint8*)pos;
   pos += sizeof(guint8);
 
This page took 0.029878 seconds and 4 git commands to generate.