[PATCH 2/2] capture: Add support for variable length records.

Jennifer Averett jennifer.averett at oarcorp.com
Wed Sep 3 18:03:52 UTC 2014


---
 cpukit/Makefile.am                              |   1 +
 cpukit/libmisc/Makefile.am                      |   5 +-
 cpukit/libmisc/capture/capture-cli.c            |   7 +-
 cpukit/libmisc/capture/capture.c                | 174 +++++++++++++++---------
 cpukit/libmisc/capture/capture.h                |   1 +
 cpukit/libmisc/capture/capture_buffer.c         | 117 ++++++++++++++++
 cpukit/libmisc/capture/capture_buffer.h         | 105 ++++++++++++++
 cpukit/libmisc/capture/capture_user_extension.c |  17 +++
 cpukit/libmisc/capture/captureimpl.h            | 116 ++++++++++++++++
 cpukit/preinstall.am                            |   4 +
 10 files changed, 475 insertions(+), 72 deletions(-)
 create mode 100644 cpukit/libmisc/capture/capture_buffer.c
 create mode 100644 cpukit/libmisc/capture/capture_buffer.h

diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am
index 3d83607..2693d46 100644
--- a/cpukit/Makefile.am
+++ b/cpukit/Makefile.am
@@ -149,6 +149,7 @@ include_rtems_HEADERS += libmisc/bspcmdline/bspcmdline.h
 ## capture
 include_rtems_HEADERS += libmisc/capture/capture.h
 include_rtems_HEADERS += libmisc/capture/capture-cli.h
+include_rtems_HEADERS += libmisc/capture/captureimpl.h
 
 ## cpuuse
 include_rtems_HEADERS += libmisc/cpuuse/cpuuse.h
diff --git a/cpukit/libmisc/Makefile.am b/cpukit/libmisc/Makefile.am
index ee7745d..421ddef 100644
--- a/cpukit/libmisc/Makefile.am
+++ b/cpukit/libmisc/Makefile.am
@@ -18,8 +18,9 @@ EXTRA_DIST += capture/README
 
 noinst_LIBRARIES += libcapture.a
 libcapture_a_SOURCES = capture/capture.c capture/capture-cli.c \
-    capture/capture_user_extension.c \
-    capture/capture.h capture/captureimpl.h capture/capture-cli.h 
+    capture/capture_user_extension.c capture/capture_buffer.c \
+    capture/capture.h capture/captureimpl.h capture/capture-cli.h \
+    capture/capture_buffer.h
 
 ## cpuuse
 EXTRA_DIST += cpuuse/README
diff --git a/cpukit/libmisc/capture/capture-cli.c b/cpukit/libmisc/capture/capture-cli.c
index 9c978d2..ee3b5dc 100644
--- a/cpukit/libmisc/capture/capture-cli.c
+++ b/cpukit/libmisc/capture/capture-cli.c
@@ -1353,6 +1353,7 @@ rtems_capture_cli_trace_records (int                                argc,
   int                     count;
   uint32_t                read;
   rtems_capture_record_t* rec;
+  uint8_t*                ptr;
   int                     arg;
   rtems_capture_time_t    last_t = 0;
 
@@ -1387,7 +1388,7 @@ rtems_capture_cli_trace_records (int                                argc,
 
   while (total)
   {
-    sc = rtems_capture_read (0, 0, &read, &rec);
+    sc = rtems_capture_read (0, 0, &read, &ptr);
 
     if (sc != RTEMS_SUCCESSFUL)
     {
@@ -1411,6 +1412,8 @@ rtems_capture_cli_trace_records (int                                argc,
 
     while (count--)
     {
+      rec = ptr;
+
       if (csv)
         fprintf (stdout, "%08" PRIxPTR ",%03" PRIu32
                    ",%03" PRIu32 ",%04" PRIx32 ",%" PRId64 "\n",
@@ -1450,7 +1453,7 @@ rtems_capture_cli_trace_records (int                                argc,
           event >>= 1;
         }
       }
-      rec++;
+      ptr += rec->size;
     }
 
     count = total < read ? total : read;
diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c
index 54b2894..64d2699 100644
--- a/cpukit/libmisc/capture/capture.c
+++ b/cpukit/libmisc/capture/capture.c
@@ -30,6 +30,7 @@
 #include <rtems/rtems/tasksimpl.h>
 
 #include "captureimpl.h"
+#include "capture_buffer.h"
 
 #include <rtems/score/statesimpl.h>
 #include <rtems/score/todimpl.h>
@@ -52,7 +53,9 @@
                                       RTEMS_CAPTURE_DELETED_EVENT | \
                                       RTEMS_CAPTURE_BEGIN_EVENT | \
                                       RTEMS_CAPTURE_EXITTED_EVENT | \
-                                      RTEMS_CAPTURE_TERMINATED_EVENT)
+                                      RTEMS_CAPTURE_TERMINATED_EVENT | \
+                                      RTEMS_CAPTURE_AUTOGEN_ENTRY_EVENT | \
+                                      RTEMS_CAPTURE_AUTOGEN_EXIT_EVENT)
 #else
 #define RTEMS_CAPTURE_RECORD_EVENTS  (0)
 #endif
@@ -61,11 +64,8 @@
 /*
  * RTEMS Capture Data.
  */
-static rtems_capture_record_t*  capture_records;
-static uint32_t                 capture_size;
+static rtems_capture_buffer_t         capture_records = {NULL, 0, 0, 0, 0, 0};
 static uint32_t                 capture_count;
-static rtems_capture_record_t*  capture_in;
-static uint32_t                 capture_out;
 static uint32_t                 capture_flags;
 static rtems_capture_task_t*    capture_tasks;
 static rtems_capture_control_t* capture_controls;
@@ -464,16 +464,12 @@ rtems_capture_destroy_capture_task (rtems_capture_task_t* task)
 }
 
 /*
- * This function records a capture record into the capture buffer.
+ * This function indicates if data should be filtered from the 
+ * log.
  */
-void
-rtems_capture_record (rtems_capture_task_t* task,
-                      uint32_t              events)
+bool rtems_capture_filter( rtems_capture_task_t* task,
+                           uint32_t              events)
 {
-  /*
-   * Check the watch state if we have a task control, and
-   * the task's real priority is lower or equal to the ceiling.
-   */
   if (task &&
       ((capture_flags &
         (RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_ONLY_MONITOR)) ==
@@ -494,35 +490,55 @@ rtems_capture_record (rtems_capture_task_t* task,
          ((capture_flags & RTEMS_CAPTURE_GLOBAL_WATCH) ||
           (control && (control->flags & RTEMS_CAPTURE_WATCH)))))
     {
-      rtems_interrupt_lock_context lock_context;
+      return false;
+    }
+  }
 
-      rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+  return true;
+}
 
-      if (capture_count < capture_size)
-      {
-        capture_count++;
-        capture_in->task   = task;
-        capture_in->events = (events |
-                              (task->tcb->real_priority) |
-                              (task->tcb->current_priority << 8));
+/*
+ * This function records a capture record into the capture buffer.
+ */
+void *
+rtems_capture_record_open (rtems_capture_task_t*         task,
+                           uint32_t                      events,
+                           size_t                        size,
+                           rtems_interrupt_lock_context* lock_context)
+{
+  uint8_t*                     ptr;
+  rtems_capture_record_t*      capture_in;
 
-        if ((events & RTEMS_CAPTURE_RECORD_EVENTS) == 0)
-          task->flags |= RTEMS_CAPTURE_TRACED;
+  rtems_interrupt_lock_acquire (&capture_lock, lock_context);
 
-        rtems_capture_get_time (&capture_in->time);
+  ptr = rtems_capture_buffer_allocate(&capture_records, size);
+  capture_in = (rtems_capture_record_t *) ptr;
+  if ( capture_in )
+  {
+    capture_count++;
+    capture_in->size   = size;
+    capture_in->task   = task;
+    capture_in->events = (events |
+                          (task->tcb->real_priority) |
+                          (task->tcb->current_priority << 8));
 
-        if (capture_in == &capture_records[capture_size - 1])
-          capture_in = capture_records;
-        else
-          capture_in++;
+    if ((events & RTEMS_CAPTURE_RECORD_EVENTS) == 0)
+      task->flags |= RTEMS_CAPTURE_TRACED;
 
-        rtems_capture_refcount_up (task);
-      }
-      else
-        capture_flags |= RTEMS_CAPTURE_OVERFLOW;
-      rtems_interrupt_lock_release (&capture_lock, &lock_context);
-    }
+    rtems_capture_get_time (&capture_in->time);
+
+    rtems_capture_refcount_up (task);
+    ptr = ptr + sizeof(*capture_in);
   }
+  else
+    capture_flags |= RTEMS_CAPTURE_OVERFLOW;
+
+  return ptr;
+}
+
+void rtems_capture_record_close( void *rec, rtems_interrupt_lock_context* lock_context)
+{
+  rtems_interrupt_lock_release (&capture_lock, lock_context);
 }
 
 /*
@@ -607,18 +623,15 @@ rtems_capture_open (uint32_t   size, rtems_capture_timestamp timestamp __attribu
    * See if the capture engine is already open.
    */
 
-  if (capture_records)
+  if (capture_records.buffer)
     return RTEMS_RESOURCE_IN_USE;
 
-  capture_records = malloc (size * sizeof (rtems_capture_record_t));
+  rtems_capture_buffer_create( &capture_records, size );
 
-  if (capture_records == NULL)
+  if (capture_records.buffer == NULL)
     return RTEMS_NO_MEMORY;
 
-  capture_size    = size;
   capture_count   = 0;
-  capture_in      = capture_records;
-  capture_out     = 0;
   capture_flags   = 0;
   capture_tasks   = NULL;
   capture_ceiling = 0;
@@ -628,8 +641,7 @@ rtems_capture_open (uint32_t   size, rtems_capture_timestamp timestamp __attribu
 
   if (sc != RTEMS_SUCCESSFUL)
   {
-    free (capture_records);
-    capture_records = NULL;
+    rtems_capture_buffer_destroy( &capture_records);
   }
 
   /*
@@ -653,7 +665,7 @@ rtems_capture_close (void)
 
   rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
 
-  if (!capture_records)
+  if (!capture_records.buffer)
   {
     rtems_interrupt_lock_release (&capture_lock, &lock_context);
     return RTEMS_SUCCESSFUL;
@@ -661,8 +673,6 @@ rtems_capture_close (void)
 
   capture_flags &= ~(RTEMS_CAPTURE_ON | RTEMS_CAPTURE_ONLY_MONITOR);
 
-  capture_records = NULL;
-
   rtems_interrupt_lock_release (&capture_lock, &lock_context);
 
   /*
@@ -697,10 +707,9 @@ rtems_capture_close (void)
 
   capture_controls = NULL;
 
-  if (capture_records)
+  if (capture_records.buffer)
   {
-    free (capture_records);
-    capture_records = NULL;
+    rtems_capture_buffer_destroy( &capture_records);
   }
 
   return RTEMS_SUCCESSFUL;
@@ -722,7 +731,7 @@ rtems_capture_control (bool enable)
 
   rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
 
-  if (!capture_records)
+  if (!capture_records.buffer)
   {
     rtems_interrupt_lock_release (&capture_lock, &lock_context);
     return RTEMS_UNSATISFIED;
@@ -752,7 +761,7 @@ rtems_capture_monitor (bool enable)
 
   rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
 
-  if (!capture_records)
+  if (!capture_records.buffer)
   {
     rtems_interrupt_lock_release (&capture_lock, &lock_context);
     return RTEMS_UNSATISFIED;
@@ -791,9 +800,8 @@ rtems_capture_flush (bool prime)
   else
     capture_flags &= ~RTEMS_CAPTURE_OVERFLOW;
 
+  rtems_capture_buffer_flush( &capture_records );
   capture_count = 0;
-  capture_in    = capture_records;
-  capture_out   = 0;
 
   rtems_interrupt_lock_release (&capture_lock, &lock_context);
 
@@ -1195,6 +1203,26 @@ rtems_capture_clear_trigger (rtems_name                   from_name,
   return RTEMS_SUCCESSFUL;
 }
 
+static inline uint32_t rtems_capture_count_records( void* recs, size_t size )
+{ 
+  rtems_capture_record_t* rec;
+  uint8_t*                ptr = recs;
+  uint32_t                rec_count = 0;
+  size_t                  byte_count = 0;
+  
+ 
+ while (byte_count < size) {
+    rec = (rtems_capture_record_t*) ptr;
+    rec_count++;
+    _Assert( rec->size >= sizeof(*rec) );
+    ptr += rec->size;
+    byte_count += rec->size;
+    _Assert( rec_count <= capture_count ); 
+ };
+   
+ return rec_count;
+}
+
 /*
  * This function reads a number of records from the capture buffer.
  * The user can optionally block and wait until the buffer as a
@@ -1229,7 +1257,8 @@ rtems_capture_read (uint32_t                 threshold,
 {
   rtems_interrupt_lock_context lock_context;
   rtems_status_code            sc = RTEMS_SUCCESSFUL;
-  uint32_t                     count;
+  size_t                       recs_size = 0;
+  bool                         wrapped;
 
   *read = 0;
   *recs = NULL;
@@ -1247,25 +1276,24 @@ rtems_capture_read (uint32_t                 threshold,
   }
 
   capture_flags |= RTEMS_CAPTURE_READER_ACTIVE;
-  *read = count = capture_count;
 
-  rtems_interrupt_lock_release (&capture_lock, &lock_context);
+  *recs = rtems_capture_buffer_peek( &capture_records, &recs_size );
+  *read = rtems_capture_count_records( *recs, recs_size );
 
-  *recs = &capture_records[capture_out];
+  rtems_interrupt_lock_release (&capture_lock, &lock_context);
 
   for (;;)
   {
     /*
-     * See if the count wraps the end of the record buffer.
+     * See if the data wraps the end of the record buffer.
      */
-    if (count && ((capture_out + count) >= capture_size))
-      *read = capture_size - capture_out;
+    wrapped = rtems_capture_buffer_has_wrapped( &capture_records);
 
     /*
-     * Do we have a threshold and the current count has not wrapped
+     * Do we have a threshold and have not wrapped
      * around the end of the capture record buffer ?
      */
-    if ((*read == count) && threshold)
+    if ((!wrapped) && threshold)
     {
       /*
        * Do we have enough records ?
@@ -1297,7 +1325,8 @@ rtems_capture_read (uint32_t                 threshold,
 
         rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
 
-        *read = count = capture_count;
+        *recs = rtems_capture_buffer_peek( &capture_records, &recs_size );
+        *read = rtems_capture_count_records( *recs, recs_size );
 
         rtems_interrupt_lock_release (&capture_lock, &lock_context);
 
@@ -1322,8 +1351,10 @@ rtems_status_code
 rtems_capture_release (uint32_t count)
 {
   rtems_interrupt_lock_context lock_context;
+  uint8_t*                     ptr;
   rtems_capture_record_t*      rec;
   uint32_t                     counted;
+  size_t                       ptr_size = 0;
 
   rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
 
@@ -1333,21 +1364,26 @@ rtems_capture_release (uint32_t count)
   rtems_interrupt_lock_release (&capture_lock, &lock_context);
 
   counted = count;
+ 
+  ptr = rtems_capture_buffer_peek( &capture_records, &ptr_size );
+  _Assert(ptr_size >= (count * sizeof(*rec) ));
 
-  rec = &capture_records[capture_out];
-
+  ptr_size = 0;
   while (counted--)
-  {
+  { 
+    rec = (rtems_capture_record_t*) ptr;
+    ptr_size += rec->size;
     rtems_capture_refcount_down (rec->task);
     rtems_capture_destroy_capture_task (rec->task);
-    rec++;
+    ptr += rec->size;
   }
 
   rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
 
   capture_count -= count;
 
-  capture_out = (capture_out + count) % capture_size;
+  if (count) 
+    rtems_capture_buffer_free( &capture_records, ptr_size );
 
   capture_flags &= ~RTEMS_CAPTURE_READER_ACTIVE;
 
@@ -1430,3 +1466,5 @@ rtems_capture_get_control_list (void)
 {
   return capture_controls;
 }
+
+
diff --git a/cpukit/libmisc/capture/capture.h b/cpukit/libmisc/capture/capture.h
index 737c73f..8bc2fc3 100644
--- a/cpukit/libmisc/capture/capture.h
+++ b/cpukit/libmisc/capture/capture.h
@@ -191,6 +191,7 @@ typedef struct rtems_capture_record_s
   rtems_capture_task_t* task;
   uint32_t              events;
   rtems_capture_time_t  time;
+  size_t                size;
 } rtems_capture_record_t;
 
 /**
diff --git a/cpukit/libmisc/capture/capture_buffer.c b/cpukit/libmisc/capture/capture_buffer.c
new file mode 100644
index 0000000..9557f70
--- /dev/null
+++ b/cpukit/libmisc/capture/capture_buffer.c
@@ -0,0 +1,117 @@
+/*
+  ------------------------------------------------------------------------
+
+  COPYRIGHT (c) 2014.
+  On-Line Applications Research Corporation (OAR).
+
+  The license and distribution terms for this file may be
+  found in the file LICENSE in this distribution.
+
+  This software with is provided ``as is'' and with NO WARRANTY.
+
+  ------------------------------------------------------------------------
+
+  RTEMS Performance Monitoring and Measurement Framework.
+
+  This is the Target Interface Command Line Interface. You need
+  start the RTEMS monitor.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/assert.h>
+#include "capture_buffer.h"
+
+void * rtems_capture_buffer_allocate( rtems_capture_buffer_t* buffer, size_t size )
+{
+  static uint32_t   end;
+  static void       *ptr;
+
+  if ( rtems_capture_buffer_is_full( buffer ) )
+    return NULL;
+
+  if ( (buffer->count + size) > buffer->end )
+    return NULL;
+
+  /*
+   *  Determine if the end of free space is marked with
+   *  the end of buffer space, or the head of allocated
+   *  space.
+   *
+   *  |...|head| freespace |tail| ...| end
+   *
+   *  tail|.....|head| freespace| end
+   *
+   */
+  if (buffer->tail > buffer->head) {
+    end = buffer->tail;
+  } else {
+    end = buffer->end;
+  }
+
+  /*
+   *  Can we allocate it easily?
+   */
+  if ((buffer->head + size) <= end) {
+    ptr = &buffer->buffer[ buffer->head ];
+    buffer->head += size;
+    buffer->count = buffer->count + size;
+    return ptr;
+  }
+
+  /*
+   * We have to consider wrapping around to the front of the buffer
+   */
+
+  /* If there is not room at the end of the buffer         */
+  /* and we have we already wrapped then we can't allocate */
+  if ( end == buffer->tail )
+    return NULL;
+
+  /* Is there no room at the front of the buffer */
+  if ( (buffer->tail  < size ))
+    return NULL;
+
+  /* change the end pointer to the last used byte, so a read will wrap when out of data */
+  buffer->end = buffer->head;
+
+  /* now return the buffer */
+  ptr = buffer->buffer;
+  buffer->head = size;
+  buffer->count = buffer->count + size;
+
+  return ptr; 
+}
+
+void *rtems_capture_buffer_free( rtems_capture_buffer_t* buffer, size_t size ) 
+{
+    static void             *ptr;
+    static uint32_t         next;
+    size_t                  buff_size;
+
+    if (size == 0)
+      return NULL;
+
+    ptr = rtems_capture_buffer_peek(buffer, &buff_size);
+    next = buffer->tail + size;
+
+   /* Check if we are freeing space past the end of the buffer */
+    _Assert( ! rtems_capture_buffer_is_empty( buffer ) );
+    _Assert( !((buffer->tail > buffer->head) && (next > buffer->end)) );
+    _Assert( !((buffer->tail < buffer->head) && (next > buffer->head)) );
+
+    buffer->count = buffer->count - size;
+
+    if (next == buffer->end) {
+      buffer->end = buffer->size;
+      buffer->tail = 0;
+    } else {
+      buffer->tail = next;
+    }
+     
+    return ptr;
+}
diff --git a/cpukit/libmisc/capture/capture_buffer.h b/cpukit/libmisc/capture/capture_buffer.h
new file mode 100644
index 0000000..a01ca29
--- /dev/null
+++ b/cpukit/libmisc/capture/capture_buffer.h
@@ -0,0 +1,105 @@
+/**
+ * @file capture_buffer.h
+ *
+ * @brief Capture buffer
+ *
+ * This is a set of functions to control a variable length capture record buffer.
+ */
+
+/*
+  ------------------------------------------------------------------------
+
+  COPYRIGHT (c) 2014.
+  On-Line Applications Research Corporation (OAR).
+
+  The license and distribution terms for this file may be
+  found in the file LICENSE in this distribution.
+
+  This software with is provided ``as is'' and with NO WARRANTY.
+
+  ------------------------------------------------------------------------
+*/
+
+#ifndef __CAPTUREBUFFER_H_
+#define __CAPTUREBUFFER_H_
+
+#include <stdlib.h>
+
+
+/**@{*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+  uint8_t           *buffer;
+  size_t            size;
+  volatile uint32_t count;
+  volatile uint32_t head;
+  volatile uint32_t tail;
+  volatile uint32_t end;
+} rtems_capture_buffer_t;
+
+static inline void rtems_capture_buffer_flush(  rtems_capture_buffer_t* buffer )
+{
+  buffer->end = buffer->size;
+  buffer->head = buffer->tail =  0;
+  buffer->count = 0;
+}
+
+static inline void rtems_capture_buffer_create( rtems_capture_buffer_t* buffer, size_t size )
+{
+  buffer->buffer = malloc(size);
+  buffer->size = size;
+  rtems_capture_buffer_flush( buffer );
+}
+
+static inline void rtems_capture_buffer_destroy( rtems_capture_buffer_t*  buffer )
+{
+  rtems_capture_buffer_flush( buffer );
+  free( buffer->buffer);
+  buffer->buffer = NULL;
+}
+
+static inline bool rtems_capture_buffer_is_empty(  rtems_capture_buffer_t* buffer )
+{
+   return( buffer->count == 0 );
+}
+
+static inline bool rtems_capture_buffer_is_full( rtems_capture_buffer_t* buffer )
+{
+   return (buffer->count == buffer->size);
+}
+
+static inline bool rtems_capture_buffer_has_wrapped( rtems_capture_buffer_t* buffer )
+{
+  if ( buffer->tail > buffer->head)
+    return true;
+
+  return false;
+}
+
+static inline void *rtems_capture_buffer_peek(  rtems_capture_buffer_t* buffer, size_t *size ) 
+{
+  if (rtems_capture_buffer_is_empty(buffer)) {
+    *size = 0; 
+    return NULL;
+  }
+
+  if ( buffer->tail > buffer->head)  
+    *size = buffer->end - buffer->tail;
+  else
+    *size = buffer->head - buffer->tail;
+
+  return &buffer->buffer[ buffer->tail ];
+}
+
+void *rtems_capture_buffer_allocate( rtems_capture_buffer_t* buffer, size_t size );
+
+void *rtems_capture_buffer_free( rtems_capture_buffer_t* buffer, size_t size );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libmisc/capture/capture_user_extension.c b/cpukit/libmisc/capture/capture_user_extension.c
index f3bebc8..4236d8c 100644
--- a/cpukit/libmisc/capture/capture_user_extension.c
+++ b/cpukit/libmisc/capture/capture_user_extension.c
@@ -84,6 +84,23 @@ static const rtems_extensions_table capture_extensions = {
   .thread_terminate = rtems_capture_terminated_task
 };
 
+
+static inline void rtems_capture_record (
+  rtems_capture_task_t* task,
+  uint32_t              events
+)
+{
+  rtems_capture_record_t*  rec;
+
+  if (rtems_capture_filter( task, events) )
+    return;
+  
+  rtems_capture_begin_add_record (task, events, sizeof(*rec), &rec);
+
+  rtems_capture_end_add_record ( rec );
+}
+
+
 rtems_status_code rtems_capture_user_extension_open(void)
 {
   rtems_status_code sc;
diff --git a/cpukit/libmisc/capture/captureimpl.h b/cpukit/libmisc/capture/captureimpl.h
index ee18d82..fa36688 100644
--- a/cpukit/libmisc/capture/captureimpl.h
+++ b/cpukit/libmisc/capture/captureimpl.h
@@ -154,6 +154,89 @@ rtems_capture_task_t* rtems_capture_create_capture_task (rtems_tcb* new_task);
 bool rtems_capture_trigger (rtems_capture_task_t* ft,
                        rtems_capture_task_t* tt,
                        uint32_t              events);
+
+/**
+ * @brief Capture append to record 
+ *
+ * This function Capture appends data to a capture record.  It should
+ * be called between rtems_capture_begin_add_record and
+ * rtems_capture_end_add_record.
+ *
+ * @param[in] rec specifies the next location to write in the record
+ * @param[in] data specifies the data to write
+ * @param[in] size specifies specifies the size of the data
+ *
+ * @retval This method returns a pointer which is used as a marker
+ * for the next location in the capture record. it should only be
+ * used as input into rtems_capture_append_to_record or 
+ * rtems_capture_end_add_record.
+ */
+static void *rtems_capture_append_to_record(void*  rec, 
+                                     void*  data,
+                                     size_t size );
+
+/**
+ * @brief Capture filter
+ *
+ * This function this function specifies if the given task
+ * and events should be logged.
+ *
+ * @param[in] task specifies the capture task control block
+ * @param[in] events specifies the events
+ *
+ * @retval This method returns true if this data should be
+ * filtered from the log.  It returns false if this data 
+ * should be logged.
+ */
+bool rtems_capture_filter( rtems_capture_task_t* task,
+                           uint32_t              events);
+/**
+ * @brief Capture begin add record.
+ *
+ * This function opens a record for writing and inserts
+ * the header information
+ *
+ * @param[in] _task specifies the capture task block
+ * @param[in] _events specifies the events
+ * @param[in] _size specifies the expected size of the capture record
+ * @param[out] _rec specifies the next write point in the capture record
+ */
+#define rtems_capture_begin_add_record( _task, _events, _size, _rec) \
+  do { \
+    rtems_interrupt_lock_context _lock_context; \
+    *_rec = rtems_capture_record_open( _task, _events, _size, &_lock_context );
+
+/**
+ * @brief Capture append to record.
+ *
+ * This function appends data of a specifed size into a capture record.
+ *
+ * @param[in] rec specifies the next write point in the capture record 
+ * @param[in] data specifies the data to write
+ * @param[in] size specifies the size of the data
+ *
+ * @retval This method returns the next write point in the capture record.
+ */
+static inline void *rtems_capture_append_to_record(void*  rec, 
+                                                   void*  data,
+                                                   size_t size )
+{
+  uint8_t *ptr = rec;
+  memcpy( ptr, data, size );
+  return (ptr + size);
+}
+
+/**
+ * @brief Capture end add record.
+ *
+ * This function completes the add capture record process
+ *
+ * @param[in] _rec specifies the end of the capture record
+ */
+#define rtems_capture_end_add_record( _rec ) \
+    rtems_capture_record_close( _rec, &_lock_context ); \
+  } while (0)
+
 /**
  * @brief Capture initialize stack usage
  *
@@ -187,6 +270,39 @@ void rtems_capture_destroy_capture_task (rtems_capture_task_t* task);
  */
 void rtems_capture_get_time (rtems_capture_time_t* time);
 
+/**
+ * @brief Capture record open.
+ *
+ * This function allocates a record and fills in the 
+ * header information.  It does a lock acquire
+ * which will remain in effect until 
+ * rtems_capture_record_close is called.  This method
+ * should only be used by rtems_capture_begin_add_record.
+ *
+ * @param[in] task specifies the caputre task block
+ * @param[in] events specifies the events
+ * @param[in] size specifies capture record size
+ * @param[out] lock_context specifies the lock context
+ *
+ * @retval This method returns a pointer to the next location in
+ * the capture record to store data.
+ */
+void* rtems_capture_record_open (rtems_capture_task_t*         task,
+                                 uint32_t                      events,
+                                 size_t                        size,
+                                 rtems_interrupt_lock_context* lock_context);
+/**
+ * @brief Capture record close.
+ *
+ * This function closes writing to capure record and 
+ * releases the lock that was held on the record. This
+ * method should only be used by rtems_capture_end_add_record.
+ *
+ * @param[in] rec specifies the record
+ * @param[out] lock_context specifies the lock context
+ */
+void rtems_capture_record_close( void *rec, rtems_interrupt_lock_context* lock_context);
+
 
 #ifdef __cplusplus
 }
diff --git a/cpukit/preinstall.am b/cpukit/preinstall.am
index 70923f0..ccbb47f 100644
--- a/cpukit/preinstall.am
+++ b/cpukit/preinstall.am
@@ -330,6 +330,10 @@ $(PROJECT_INCLUDE)/rtems/capture-cli.h: libmisc/capture/capture-cli.h $(PROJECT_
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/capture-cli.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/capture-cli.h
 
+$(PROJECT_INCLUDE)/rtems/captureimpl.h: libmisc/capture/captureimpl.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/captureimpl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/captureimpl.h
+
 $(PROJECT_INCLUDE)/rtems/cpuuse.h: libmisc/cpuuse/cpuuse.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/cpuuse.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/cpuuse.h
-- 
1.8.1.4




More information about the devel mailing list