[PATCH 2/2] capture: Begin splitting global and percpu information

Jennifer Averett jennifer.averett at oarcorp.com
Tue Oct 7 18:43:23 UTC 2014


This patch is not to be committed but is for discussion purposes.
Adding percpu instances will be implemented prior to committing.
---
 cpukit/libmisc/capture/capture.c     | 243 +++++++++++++++++++++++------------
 cpukit/libmisc/capture/captureimpl.h |  19 ++-
 2 files changed, 171 insertions(+), 91 deletions(-)

diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c
index 74b563d..153b340 100644
--- a/cpukit/libmisc/capture/capture.c
+++ b/cpukit/libmisc/capture/capture.c
@@ -5,7 +5,7 @@
   All rights reserved Objective Design Systems Pty Ltd, 2002
   Chris Johns (ccj at acm.org)
 
-  COPYRIGHT (c) 1989-2009.
+  COPYRIGHT (c) 1989-2014.
   On-Line Applications Research Corporation (OAR).
 
   The license and distribution terms for this file may be
@@ -59,21 +59,49 @@
 #define RTEMS_CAPTURE_RECORD_EVENTS  (0)
 #endif
 
+typedef struct {
+  rtems_capture_buffer_t   records;
+  uint32_t                 count;
+  rtems_id                 reader;
+  rtems_interrupt_lock     lock;
+  uint32_t                 flags;
+} rtems_capture_per_cpu_data_t;
+
+typedef struct {
+  uint32_t                 flags;
+  rtems_capture_control_t* controls;
+  int                      extension_index;
+  rtems_capture_timestamp  timestamp;
+  rtems_task_priority      ceiling;
+  rtems_task_priority      floor;
+  rtems_interrupt_lock     lock;
+} rtems_capture_global_data_t;
+
+static rtems_capture_per_cpu_data_t  capture_per_cpu = {
+  {NULL, 0, 0, 0, 0, 0},
+  0,
+  0,
+  RTEMS_INTERRUPT_LOCK_INITIALIZER("capture")
+};
 
+static rtems_capture_global_data_t capture_global;
+  
 /*
  * RTEMS Capture Data.
  */
-static rtems_capture_buffer_t   capture_records = {NULL, 0, 0, 0, 0, 0};
-static uint32_t                 capture_count;
-static uint32_t                 capture_flags;
-static rtems_capture_control_t* capture_controls;
-static int                      capture_extension_index;
-static rtems_capture_timestamp  capture_timestamp;
-static rtems_task_priority      capture_ceiling;
-static rtems_task_priority      capture_floor;
-static rtems_id                 capture_reader;
-static rtems_interrupt_lock     capture_lock =
-  RTEMS_INTERRUPT_LOCK_INITIALIZER("capture");
+
+#define capture_records          capture_per_cpu.records
+#define capture_count            capture_per_cpu.count
+#define capture_flags_per_cpu    capture_per_cpu.flags
+#define capture_flags_global     capture_global.flags
+#define capture_controls         capture_global.controls
+#define capture_extension_index  capture_global.extension_index
+#define capture_timestamp        capture_global.timestamp
+#define capture_ceiling          capture_global.ceiling
+#define capture_floor            capture_global.floor
+#define capture_reader           capture_per_cpu.reader
+#define capture_lock_per_cpu     capture_per_cpu.lock
+#define capture_lock_global      capture_global.lock
 
 /*
  * RTEMS Event text.
@@ -106,14 +134,18 @@ int  rtems_capture_get_extension_index(void)
   return capture_extension_index;
 }
 
+/*
+ * XXX - Do both global and per_cpu flags
+ *       need outside access?
+ */
 uint32_t rtems_capture_get_flags(void)
 {
-  return capture_flags;
+  return capture_flags_global;
 }
 
 void rtems_capture_set_flags(uint32_t mask)
 {
-  capture_flags |= mask;
+  capture_flags_global |= mask;
 }
 
 /*
@@ -288,7 +320,7 @@ rtems_capture_create_control (rtems_name name, rtems_id id)
 
     if (!ok)
     {
-      capture_flags |= RTEMS_CAPTURE_NO_MEMORY;
+      capture_flags_global |= RTEMS_CAPTURE_NO_MEMORY;
       return NULL;
     }
 
@@ -301,13 +333,13 @@ rtems_capture_create_control (rtems_name name, rtems_id id)
 
     memset (control->by, 0, sizeof (control->by));
 
-    rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+    rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);
 
     control->next    = capture_controls;
     capture_controls = control;
     rtems_iterate_over_all_threads (rtems_capture_initialize_control);
 
-    rtems_interrupt_lock_release (&capture_lock, &lock_context);
+    rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
   }
 
   return control;
@@ -319,7 +351,7 @@ void rtems_capture_initialize_task( rtems_tcb* tcb )
   rtems_name                  name;
 
   /*
-   * We need to scan the default control list to initialise
+   * We need to scan the default control list to initialize
    * this control if it is a new task.
    */
 
@@ -382,7 +414,7 @@ bool rtems_capture_filter( rtems_tcb*            tcb,
                            uint32_t              events)
 {
   if (tcb &&
-      ((capture_flags &
+      ((capture_flags_global &
         (RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_ONLY_MONITOR)) ==
        RTEMS_CAPTURE_TRIGGERED))
   {
@@ -398,7 +430,7 @@ bool rtems_capture_filter( rtems_tcb*            tcb,
     if ((events & RTEMS_CAPTURE_RECORD_EVENTS) ||
         ((tcb->real_priority >= capture_ceiling) &&
          (tcb->real_priority <= capture_floor) &&
-         ((capture_flags & RTEMS_CAPTURE_GLOBAL_WATCH) ||
+         ((capture_flags_global & RTEMS_CAPTURE_GLOBAL_WATCH) ||
           (control && (control->flags & RTEMS_CAPTURE_WATCH)))))
     {
       return false;
@@ -420,7 +452,7 @@ rtems_capture_record_open (rtems_tcb*                    tcb,
   uint8_t*                     ptr;
   rtems_capture_record_t*      capture_in;
 
-  rtems_interrupt_lock_acquire (&capture_lock, lock_context);
+  rtems_interrupt_lock_acquire (&capture_lock_per_cpu, lock_context);
 
   ptr = rtems_capture_buffer_allocate(&capture_records, size);
   capture_in = (rtems_capture_record_t *) ptr;
@@ -441,14 +473,14 @@ rtems_capture_record_open (rtems_tcb*                    tcb,
     ptr = ptr + sizeof(*capture_in);
   }
   else
-    capture_flags |= RTEMS_CAPTURE_OVERFLOW;
+    capture_flags_per_cpu |= 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);
+  rtems_interrupt_lock_release (&capture_lock_per_cpu, lock_context);
 }
 
 /*
@@ -464,7 +496,7 @@ rtems_capture_trigger (rtems_tcb* ft,
   /*
    * If we have not triggered then see if this is a trigger condition.
    */
-  if (!(capture_flags & RTEMS_CAPTURE_TRIGGERED))
+  if (!(capture_flags_global & RTEMS_CAPTURE_TRIGGERED))
   {
     rtems_capture_control_t* fc = NULL;
     rtems_capture_control_t* tc = NULL;
@@ -499,7 +531,7 @@ rtems_capture_trigger (rtems_tcb* ft,
      */
     if (from_events || to_events)
     {
-      capture_flags |= RTEMS_CAPTURE_TRIGGERED;
+      capture_flags_global |= RTEMS_CAPTURE_TRIGGERED;
       return 1;
     }
 
@@ -510,7 +542,7 @@ rtems_capture_trigger (rtems_tcb* ft,
     {
       if (rtems_capture_by_in_to (events, ft, tc))
       {
-        capture_flags |= RTEMS_CAPTURE_TRIGGERED;
+        capture_flags_global |= RTEMS_CAPTURE_TRIGGERED;
         return 1;
       }
     }
@@ -523,7 +555,7 @@ rtems_capture_trigger (rtems_tcb* ft,
 
 /*
  * This function initialises the realtime capture engine allocating the trace
- * buffer. It is assumed we have a working heap at stage of initialisation.
+ * buffer. It is assumed we have a working heap at stage of initialization.
  */
 rtems_status_code
 rtems_capture_open (uint32_t   size, rtems_capture_timestamp timestamp __attribute__((unused)))
@@ -534,7 +566,7 @@ rtems_capture_open (uint32_t   size, rtems_capture_timestamp timestamp __attribu
    * See if the capture engine is already open.
    */
 
-  if (capture_records.buffer)
+  if ((capture_flags_global & RTEMS_CAPTURE_INIT) == RTEMS_CAPTURE_INIT)
     return RTEMS_RESOURCE_IN_USE;
 
   rtems_capture_buffer_create( &capture_records, size );
@@ -543,7 +575,8 @@ rtems_capture_open (uint32_t   size, rtems_capture_timestamp timestamp __attribu
     return RTEMS_NO_MEMORY;
 
   capture_count   = 0;
-  capture_flags   = 0;
+  capture_flags_global   = 0;
+  capture_flags_per_cpu  = 0;
   capture_ceiling = 0;
   capture_floor   = 255;
 
@@ -554,16 +587,14 @@ rtems_capture_open (uint32_t   size, rtems_capture_timestamp timestamp __attribu
     rtems_capture_buffer_destroy( &capture_records);
   }
 
-  /*
-   * Iterate over the list of existing tasks.
-   */
+  capture_flags_global |= RTEMS_CAPTURE_INIT;
 
   return sc;
 }
 
 /*
  * This function shutdowns the capture engine and release any claimed
- * resources.
+ * resources.  Capture control must be disabled prior to calling a close.
  */
 rtems_status_code
 rtems_capture_close (void)
@@ -572,17 +603,24 @@ rtems_capture_close (void)
   rtems_capture_control_t*     control;
   rtems_status_code            sc;
 
-  rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+  rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);
 
-  if (!capture_records.buffer)
+  if ((capture_flags_global & RTEMS_CAPTURE_INIT) != RTEMS_CAPTURE_INIT)
   {
-    rtems_interrupt_lock_release (&capture_lock, &lock_context);
+    rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
     return RTEMS_SUCCESSFUL;
   }
+  
+  if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+  {
+    rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
+    return RTEMS_UNSATISFIED;
+  }
 
-  capture_flags &= ~(RTEMS_CAPTURE_ON | RTEMS_CAPTURE_ONLY_MONITOR);
+  capture_flags_global &= 
+    ~(RTEMS_CAPTURE_ON | RTEMS_CAPTURE_ONLY_MONITOR | RTEMS_CAPTURE_INIT);
 
-  rtems_interrupt_lock_release (&capture_lock, &lock_context);
+  rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
 
   /*
    * Delete the extension first. This means we are now able to
@@ -604,7 +642,6 @@ rtems_capture_close (void)
   }
 
   capture_controls = NULL;
-
   if (capture_records.buffer)
   {
     rtems_capture_buffer_destroy( &capture_records);
@@ -618,20 +655,20 @@ rtems_capture_control (bool enable)
 {
   rtems_interrupt_lock_context lock_context;
 
-  rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+  rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);
 
-  if (!capture_records.buffer)
+  if ((capture_flags_global & RTEMS_CAPTURE_INIT) != RTEMS_CAPTURE_INIT)
   {
-    rtems_interrupt_lock_release (&capture_lock, &lock_context);
+    rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
     return RTEMS_UNSATISFIED;
   }
 
   if (enable)
-    capture_flags |= RTEMS_CAPTURE_ON;
+    capture_flags_global |= RTEMS_CAPTURE_ON;
   else
-    capture_flags &= ~RTEMS_CAPTURE_ON;
+    capture_flags_global &= ~RTEMS_CAPTURE_ON;
 
-  rtems_interrupt_lock_release (&capture_lock, &lock_context);
+  rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
 
   return RTEMS_SUCCESSFUL;
 }
@@ -646,20 +683,20 @@ rtems_capture_monitor (bool enable)
 {
   rtems_interrupt_lock_context lock_context;
 
-  rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+  rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);
 
-  if (!capture_records.buffer)
+  if ((capture_flags_global & RTEMS_CAPTURE_INIT) != RTEMS_CAPTURE_INIT)
   {
-    rtems_interrupt_lock_release (&capture_lock, &lock_context);
+    rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
     return RTEMS_UNSATISFIED;
   }
 
   if (enable)
-    capture_flags |= RTEMS_CAPTURE_ONLY_MONITOR;
+    capture_flags_global |= RTEMS_CAPTURE_ONLY_MONITOR;
   else
-    capture_flags &= ~RTEMS_CAPTURE_ONLY_MONITOR;
+    capture_flags_global &= ~RTEMS_CAPTURE_ONLY_MONITOR;
 
-  rtems_interrupt_lock_release (&capture_lock, &lock_context);
+  rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
 
   return RTEMS_SUCCESSFUL;
 }
@@ -681,21 +718,31 @@ rtems_capture_flush_tcb (rtems_tcb *tcb)
 rtems_status_code
 rtems_capture_flush (bool prime)
 {
-  rtems_interrupt_lock_context lock_context;
+  rtems_interrupt_lock_context lock_context_global;
+  rtems_interrupt_lock_context lock_context_per_cpu;
+
+  rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context_global);
 
-  rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+  if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+  {
+    rtems_interrupt_lock_release (&capture_lock_global, &lock_context_global);
+    return RTEMS_UNSATISFIED;
+  }
 
   rtems_iterate_over_all_threads (rtems_capture_flush_tcb);
 
   if (prime)
-    capture_flags &= ~(RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_OVERFLOW);
+    capture_flags_global &= ~(RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_OVERFLOW);
   else
-    capture_flags &= ~RTEMS_CAPTURE_OVERFLOW;
+    capture_flags_global &= ~RTEMS_CAPTURE_OVERFLOW;
+
+  rtems_interrupt_lock_acquire (&capture_lock_per_cpu, &lock_context_per_cpu);
 
   rtems_capture_buffer_flush( &capture_records );
   capture_count = 0;
 
-  rtems_interrupt_lock_release (&capture_lock, &lock_context);
+  rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context_per_cpu);
+  rtems_interrupt_lock_release (&capture_lock_global, &lock_context_global);
 
   return RTEMS_SUCCESSFUL;
 }
@@ -704,13 +751,16 @@ rtems_capture_flush (bool prime)
  * This function defines a watch for a specific task given a name. A watch
  * causes it to be traced either in or out of context. The watch can be
  * optionally enabled or disabled with the set routine. It is disabled by
- * default.
+ * default.  A watch can only be defined when capture control is disabled
  */
 rtems_status_code
 rtems_capture_watch_add (rtems_name name, rtems_id id)
 {
   rtems_capture_control_t* control;
 
+  if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+    return RTEMS_UNSATISFIED;
+
   if ((name == 0) && (id == 0))
     return RTEMS_UNSATISFIED;
 
@@ -731,7 +781,8 @@ rtems_capture_watch_add (rtems_name name, rtems_id id)
 /*
  * This function removes a watch for a specific task given a name. The task
  * description will still exist if referenced by a trace record in the trace
- * buffer or a global watch is defined.
+ * buffer or a global watch is defined.  A watch can only be deleted when 
+ * capture control is disabled.
  */
 rtems_status_code
 rtems_capture_watch_del (rtems_name name, rtems_id id)
@@ -741,6 +792,9 @@ rtems_capture_watch_del (rtems_name name, rtems_id id)
   rtems_capture_control_t**    prev_control;
   bool                         found = false;
 
+  if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+    return RTEMS_UNSATISFIED;
+
   /*
    * Should this test be for wildcards ?
    */
@@ -750,11 +804,11 @@ rtems_capture_watch_del (rtems_name name, rtems_id id)
   {
     if (rtems_capture_match_name_id (control->name, control->id, name, id))
     {
-      rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+      rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);
 
       *prev_control = control->next;
 
-      rtems_interrupt_lock_release (&capture_lock, &lock_context);
+      rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
 
       rtems_workspace_free (control);
 
@@ -786,6 +840,9 @@ rtems_capture_watch_ctrl (rtems_name name, rtems_id id, bool enable)
   rtems_capture_control_t*     control;
   bool                         found = false;
 
+  if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+    return RTEMS_UNSATISFIED;
+
   /*
    * Find the control and then set the watch. It must exist before it can
    * be controlled.
@@ -794,14 +851,14 @@ rtems_capture_watch_ctrl (rtems_name name, rtems_id id, bool enable)
   {
     if (rtems_capture_match_name_id (control->name, control->id, name, id))
     {
-      rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+      rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);
 
       if (enable)
         control->flags |= RTEMS_CAPTURE_WATCH;
       else
         control->flags &= ~RTEMS_CAPTURE_WATCH;
 
-      rtems_interrupt_lock_release (&capture_lock, &lock_context);
+      rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
 
       found = true;
     }
@@ -823,18 +880,18 @@ rtems_capture_watch_global (bool enable)
 {
   rtems_interrupt_lock_context lock_context;
 
-  rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+  rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);
 
   /*
    * We need to keep specific and global watches separate so
    * a global enable/disable does not lose a specific watch.
    */
   if (enable)
-    capture_flags |= RTEMS_CAPTURE_GLOBAL_WATCH;
+    capture_flags_global |= RTEMS_CAPTURE_GLOBAL_WATCH;
   else
-    capture_flags &= ~RTEMS_CAPTURE_GLOBAL_WATCH;
+    capture_flags_global &= ~RTEMS_CAPTURE_GLOBAL_WATCH;
 
-  rtems_interrupt_lock_release (&capture_lock, &lock_context);
+  rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
 
   return RTEMS_SUCCESSFUL;
 }
@@ -845,7 +902,7 @@ rtems_capture_watch_global (bool enable)
 bool
 rtems_capture_watch_global_on (void)
 {
-  return capture_flags & RTEMS_CAPTURE_GLOBAL_WATCH ? 1 : 0;
+  return capture_flags_global & RTEMS_CAPTURE_GLOBAL_WATCH ? 1 : 0;
 }
 
 /*
@@ -1126,6 +1183,10 @@ static inline uint32_t rtems_capture_count_records( void* recs, size_t size )
  *
  * The 'timeout' parameter is in micro-seconds. A value of 0 will disable
  * the timeout.
+ *
+ * XXX - When per_cpu is implemented threshold and timeout will be removed as
+ * parameters.  The capture on flag must not be set when this command is called.
+ * A cpu index will be added to indicate which per_cpu buffer is needed.
  */
 rtems_status_code
 rtems_capture_read (uint32_t                 threshold,
@@ -1141,24 +1202,31 @@ rtems_capture_read (uint32_t                 threshold,
   *read = 0;
   *recs = NULL;
 
-  rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+  rtems_interrupt_lock_acquire (&capture_lock_per_cpu, &lock_context);
 
   /*
    * Only one reader is allowed.
    */
 
-  if (capture_flags & RTEMS_CAPTURE_READER_ACTIVE)
+  if (capture_flags_per_cpu & RTEMS_CAPTURE_READER_ACTIVE)
   {
-    rtems_interrupt_lock_release (&capture_lock, &lock_context);
+    rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);
     return RTEMS_RESOURCE_IN_USE;
   }
 
-  capture_flags |= RTEMS_CAPTURE_READER_ACTIVE;
+  if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+  {
+    rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);
+    return RTEMS_UNSATISFIED;
+  }
+
+  capture_flags_per_cpu |= RTEMS_CAPTURE_READER_ACTIVE;
 
   *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);
+  rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);
 
   for (;;)
   {
@@ -1182,11 +1250,11 @@ rtems_capture_read (uint32_t                 threshold,
 
         rtems_task_ident (RTEMS_SELF, RTEMS_LOCAL, &capture_reader);
 
-        rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+        rtems_interrupt_lock_acquire (&capture_lock_per_cpu, &lock_context);
 
-        capture_flags |= RTEMS_CAPTURE_READER_WAITING;
+        capture_flags_per_cpu |= RTEMS_CAPTURE_READER_WAITING;
 
-        rtems_interrupt_lock_release (&capture_lock, &lock_context);
+        rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);
 
         sc = rtems_event_receive (RTEMS_EVENT_0,
                                   RTEMS_WAIT | RTEMS_EVENT_ANY,
@@ -1201,12 +1269,12 @@ rtems_capture_read (uint32_t                 threshold,
         if ((sc != RTEMS_SUCCESSFUL) && (sc != RTEMS_TIMEOUT))
           break;
 
-        rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+        rtems_interrupt_lock_acquire (&capture_lock_per_cpu, &lock_context);
 
         *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);
+        rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);
 
         continue;
       }
@@ -1224,6 +1292,9 @@ rtems_capture_read (uint32_t                 threshold,
 /*
  * This function releases the requested number of record slots back
  * to the capture engine. The count must match the number read.
+ *
+ * XXX - A cpu index to indicate which per_cpu buffer to release data
+ * from will be added.
  */
 rtems_status_code
 rtems_capture_release (uint32_t count)
@@ -1236,12 +1307,18 @@ rtems_capture_release (uint32_t count)
   size_t                       rel_size = 0;
   rtems_status_code            ret_val = RTEMS_SUCCESSFUL;
 
-  rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+  rtems_interrupt_lock_acquire (&capture_lock_per_cpu, &lock_context);
 
   if (count > capture_count)
     count = capture_count;
 
-  rtems_interrupt_lock_release (&capture_lock, &lock_context);
+  if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+  {
+    rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);
+    return RTEMS_UNSATISFIED;
+  }
+
+  rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);
 
   counted = count;
  
@@ -1257,7 +1334,7 @@ rtems_capture_release (uint32_t count)
     ptr += rec->size;
   }
 
-  rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+  rtems_interrupt_lock_acquire (&capture_lock_per_cpu, &lock_context);
 
   if (rel_size > ptr_size ) {
     ret_val = RTEMS_INVALID_NUMBER;
@@ -1269,9 +1346,9 @@ rtems_capture_release (uint32_t count)
   if (count) 
     rtems_capture_buffer_free( &capture_records, rel_size );
 
-  capture_flags &= ~RTEMS_CAPTURE_READER_ACTIVE;
+  capture_flags_per_cpu &= ~RTEMS_CAPTURE_READER_ACTIVE;
 
-  rtems_interrupt_lock_release (&capture_lock, &lock_context);
+  rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);
 
   return ret_val;
 }
@@ -1308,5 +1385,3 @@ rtems_capture_get_control_list (void)
 {
   return capture_controls;
 }
-
-
diff --git a/cpukit/libmisc/capture/captureimpl.h b/cpukit/libmisc/capture/captureimpl.h
index 3c2f6c3..d9597e0 100644
--- a/cpukit/libmisc/capture/captureimpl.h
+++ b/cpukit/libmisc/capture/captureimpl.h
@@ -43,14 +43,19 @@ extern "C" {
 /*
  * Global capture flags.
  */
-#define RTEMS_CAPTURE_ON             (1U << 0)
-#define RTEMS_CAPTURE_NO_MEMORY      (1U << 1)
-#define RTEMS_CAPTURE_OVERFLOW       (1U << 2)
+#define RTEMS_CAPTURE_INIT           (1u << 0)
+#define RTEMS_CAPTURE_ON             (1U << 1)
+#define RTEMS_CAPTURE_NO_MEMORY      (1U << 2)
 #define RTEMS_CAPTURE_TRIGGERED      (1U << 3)
-#define RTEMS_CAPTURE_READER_ACTIVE  (1U << 4)
-#define RTEMS_CAPTURE_READER_WAITING (1U << 5)
-#define RTEMS_CAPTURE_GLOBAL_WATCH   (1U << 6)
-#define RTEMS_CAPTURE_ONLY_MONITOR   (1U << 7)
+#define RTEMS_CAPTURE_GLOBAL_WATCH   (1U << 4)
+#define RTEMS_CAPTURE_ONLY_MONITOR   (1U << 5)
+
+/*
+ * Per-CPU capture flags.
+ */
+#define RTEMS_CAPTURE_OVERFLOW       (1U << 0)
+#define RTEMS_CAPTURE_READER_ACTIVE  (1U << 1)
+#define RTEMS_CAPTURE_READER_WAITING (1U << 2)
 
 /**
  * @brief Capture set extension index.
-- 
1.8.1.4




More information about the devel mailing list