[PATCH 1/2] capture: Split user extension methods out.

Jennifer Averett jennifer.averett at oarcorp.com
Thu Aug 28 17:55:31 UTC 2014


---
 cpukit/libmisc/Makefile.am                      |   3 +-
 cpukit/libmisc/capture/capture.c                | 428 +++--------------------
 cpukit/libmisc/capture/capture_user_extension.c | 435 ++++++++++++++++++++++++
 cpukit/libmisc/capture/captureimpl.h            | 195 +++++++++++
 4 files changed, 673 insertions(+), 388 deletions(-)
 create mode 100644 cpukit/libmisc/capture/capture_user_extension.c
 create mode 100644 cpukit/libmisc/capture/captureimpl.h

diff --git a/cpukit/libmisc/Makefile.am b/cpukit/libmisc/Makefile.am
index bc9edd0..ee7745d 100644
--- a/cpukit/libmisc/Makefile.am
+++ b/cpukit/libmisc/Makefile.am
@@ -18,7 +18,8 @@ EXTRA_DIST += capture/README
 
 noinst_LIBRARIES += libcapture.a
 libcapture_a_SOURCES = capture/capture.c capture/capture-cli.c \
-    capture/capture.h capture/capture-cli.h
+    capture/capture_user_extension.c \
+    capture/capture.h capture/captureimpl.h capture/capture-cli.h 
 
 ## cpuuse
 EXTRA_DIST += cpuuse/README
diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c
index 9ec07b8..54b2894 100644
--- a/cpukit/libmisc/capture/capture.c
+++ b/cpukit/libmisc/capture/capture.c
@@ -29,7 +29,7 @@
 #include <string.h>
 #include <rtems/rtems/tasksimpl.h>
 
-#include "capture.h"
+#include "captureimpl.h"
 
 #include <rtems/score/statesimpl.h>
 #include <rtems/score/todimpl.h>
@@ -57,46 +57,6 @@
 #define RTEMS_CAPTURE_RECORD_EVENTS  (0)
 #endif
 
-static bool 
-rtems_capture_create_task (rtems_tcb* current_task, 
-                           rtems_tcb* new_task);
-
-static void
-rtems_capture_start_task (rtems_tcb* current_task,
-                          rtems_tcb* started_task);
-
-static void
-rtems_capture_restart_task (rtems_tcb* current_task,
-                            rtems_tcb* restarted_task);
-
-static void
-rtems_capture_delete_task (rtems_tcb* current_task,
-                           rtems_tcb* deleted_task);
-
-static void
-rtems_capture_switch_task (rtems_tcb* current_task,
-                           rtems_tcb* heir_task);
-
-static void
-rtems_capture_begin_task (rtems_tcb* begin_task);
-
-static void
-rtems_capture_exitted_task (rtems_tcb* exitted_task);
-
-static void
-rtems_capture_terminated_task (rtems_tcb* terminated_task);
-
-/*
- * 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_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)
 
 /*
  * RTEMS Capture Data.
@@ -110,7 +70,6 @@ static uint32_t                 capture_flags;
 static rtems_capture_task_t*    capture_tasks;
 static rtems_capture_control_t* capture_controls;
 static int                      capture_extension_index;
-static rtems_id                 capture_id;
 static rtems_capture_timestamp  capture_timestamp;
 static rtems_task_priority      capture_ceiling;
 static rtems_task_priority      capture_floor;
@@ -118,18 +77,6 @@ static rtems_id                 capture_reader;
 static rtems_interrupt_lock     capture_lock =
   RTEMS_INTERRUPT_LOCK_INITIALIZER("capture");
 
-static const rtems_extensions_table capture_extensions = {
-  .thread_create    = rtems_capture_create_task,
-  .thread_start     = rtems_capture_start_task,
-  .thread_restart   = rtems_capture_restart_task,
-  .thread_delete    = rtems_capture_delete_task,
-  .thread_switch    = rtems_capture_switch_task,
-  .thread_begin     = rtems_capture_begin_task,
-  .thread_exitted   = rtems_capture_exitted_task,
-  .fatal            = NULL,
-  .thread_terminate = rtems_capture_terminated_task
-};
-
 /*
  * RTEMS Event text.
  */
@@ -151,11 +98,43 @@ static const char* capture_event_text[] =
   "TIMESTAMP"
 };
 
+void rtems_capture_set_extension_index(int index)
+{
+  capture_extension_index = index;
+}
+
+int  rtems_capture_get_extension_index(void)
+{
+  return capture_extension_index;
+}
+
+uint32_t rtems_capture_get_flags(void)
+{
+  return capture_flags;
+}
+
+void rtems_capture_set_flags(uint32_t mask)
+{
+  capture_flags |= mask;
+}
+
+
+rtems_capture_task_t* rtems_capture_find_capture_task( rtems_id ct_id )
+{
+  rtems_capture_task_t* ct;
+
+  for (ct = capture_tasks; ct; ct = ct->forw) {
+    if (ct->id == ct_id)
+      break;
+  }
+  return ct;
+}
+
 /*
  * This function returns the current time. If a handler is provided
  * by the user get the time from that.
  */
-static inline void
+void
 rtems_capture_get_time (rtems_capture_time_t* time)
 {
   if (capture_timestamp)
@@ -290,7 +269,7 @@ rtems_capture_refcount_down (rtems_capture_task_t* task)
 /*
  * This function setups a stack so its usage can be monitored.
  */
-static inline void
+void
 rtems_capture_init_stack_usage (rtems_capture_task_t* task)
 {
   if (task->tcb)
@@ -378,7 +357,7 @@ rtems_capture_create_control (rtems_name name, rtems_id id)
 /*
  * This function create the task control.
  */
-static inline rtems_capture_task_t*
+rtems_capture_task_t*
 rtems_capture_create_capture_task (rtems_tcb* new_task)
 {
   rtems_interrupt_lock_context lock_context;
@@ -456,7 +435,7 @@ rtems_capture_create_capture_task (rtems_tcb* new_task)
  * is 0 and the tcb has been cleared signalling the task has been
  * deleted.
  */
-static inline void
+void
 rtems_capture_destroy_capture_task (rtems_capture_task_t* task)
 {
   if (task)
@@ -487,7 +466,7 @@ rtems_capture_destroy_capture_task (rtems_capture_task_t* task)
 /*
  * This function records a capture record into the capture buffer.
  */
-static inline void
+void
 rtems_capture_record (rtems_capture_task_t* task,
                       uint32_t              events)
 {
@@ -550,7 +529,7 @@ rtems_capture_record (rtems_capture_task_t* task,
  * See if we have triggered and if not see if this event is a
  * cause of a trigger.
  */
-static bool
+bool
 rtems_capture_trigger (rtems_capture_task_t* ft,
                        rtems_capture_task_t* tt,
                        uint32_t              events)
@@ -616,328 +595,12 @@ rtems_capture_trigger (rtems_capture_task_t* ft,
 }
 
 /*
- * This function is called when a task is created.
- */
-static bool
-rtems_capture_create_task (rtems_tcb* current_task,
-                           rtems_tcb* new_task)
-{
-  rtems_capture_task_t* ct;
-  rtems_capture_task_t* nt;
-
-  ct = current_task->extensions[capture_extension_index];
-
-  /*
-   * The task pointers may not be known as the task may have
-   * been created before the capture engine was open. Add them.
-   */
-
-  if (ct == NULL)
-    ct = rtems_capture_create_capture_task (current_task);
-
-  /*
-   * Create the new task's capture control block.
-   */
-  nt = rtems_capture_create_capture_task (new_task);
-
-  if (rtems_capture_trigger (ct, nt, RTEMS_CAPTURE_CREATE))
-  {
-    rtems_capture_record (ct, RTEMS_CAPTURE_CREATED_BY_EVENT);
-    rtems_capture_record (nt, RTEMS_CAPTURE_CREATED_EVENT);
-  }
-
-  return 1 == 1;
-}
-
-/*
- * This function is called when a task is started.
- */
-static void
-rtems_capture_start_task (rtems_tcb* current_task,
-                          rtems_tcb* started_task)
-{
-  /*
-   * Get the capture task control block so we can trace this
-   * event.
-   */
-  rtems_capture_task_t* ct;
-  rtems_capture_task_t* st;
-
-  ct = current_task->extensions[capture_extension_index];
-  st = started_task->extensions[capture_extension_index];
-
-  /*
-   * The task pointers may not be known as the task may have
-   * been created before the capture engine was open. Add them.
-   */
-
-  if (ct == NULL)
-    ct = rtems_capture_create_capture_task (current_task);
-
-  if (st == NULL)
-    st = rtems_capture_create_capture_task (started_task);
-
-  if (rtems_capture_trigger (ct, st, RTEMS_CAPTURE_START))
-  {
-    rtems_capture_record (ct, RTEMS_CAPTURE_STARTED_BY_EVENT);
-    rtems_capture_record (st, RTEMS_CAPTURE_STARTED_EVENT);
-  }
-
-  rtems_capture_init_stack_usage (st);
-}
-
-/*
- * This function is called when a task is restarted.
- */
-static void
-rtems_capture_restart_task (rtems_tcb* current_task,
-                            rtems_tcb* restarted_task)
-{
-  /*
-   * Get the capture task control block so we can trace this
-   * event.
-   */
-  rtems_capture_task_t* ct;
-  rtems_capture_task_t* rt;
-
-  ct = current_task->extensions[capture_extension_index];
-  rt = restarted_task->extensions[capture_extension_index];
-
-  /*
-   * The task pointers may not be known as the task may have
-   * been created before the capture engine was open. Add them.
-   */
-
-  if (ct == NULL)
-    ct = rtems_capture_create_capture_task (current_task);
-
-  if (rt == NULL)
-    rt = rtems_capture_create_capture_task (restarted_task);
-
-  if (rtems_capture_trigger (ct, rt, RTEMS_CAPTURE_RESTART))
-  {
-    rtems_capture_record (ct, RTEMS_CAPTURE_RESTARTED_BY_EVENT);
-    rtems_capture_record (rt, RTEMS_CAPTURE_RESTARTED_EVENT);
-  }
-
-  rtems_capture_task_stack_usage (rt);
-  rtems_capture_init_stack_usage (rt);
-}
-
-/*
- * This function is called when a task is deleted.
- */
-static void
-rtems_capture_delete_task (rtems_tcb* current_task,
-                           rtems_tcb* deleted_task)
-{
-  /*
-   * Get the capture task control block so we can trace this
-   * event.
-   */
-  rtems_capture_task_t* ct;
-  rtems_capture_task_t* dt;
-
-  /*
-   * The task pointers may not be known as the task may have
-   * been created before the capture engine was open. Add them.
-   */
-
-  ct = current_task->extensions[capture_extension_index];
-  dt = deleted_task->extensions[capture_extension_index];
-
-  if (ct == NULL)
-    ct = rtems_capture_create_capture_task (current_task);
-
-  if (dt == NULL)
-    dt = rtems_capture_create_capture_task (deleted_task);
-
-  if (rtems_capture_trigger (ct, dt, RTEMS_CAPTURE_DELETE))
-  {
-    rtems_capture_record (ct, RTEMS_CAPTURE_DELETED_BY_EVENT);
-    rtems_capture_record (dt, RTEMS_CAPTURE_DELETED_EVENT);
-  }
-
-  rtems_capture_task_stack_usage (dt);
-
-  /*
-   * This task's tcb will be invalid. This signals the
-   * task has been deleted.
-   */
-  dt->tcb = 0;
-
-  rtems_capture_destroy_capture_task (dt);
-}
-
-/*
- * This function is called when a task is begun.
- */
-static void
-rtems_capture_begin_task (rtems_tcb* begin_task)
-{
-  /*
-   * Get the capture task control block so we can trace this
-   * event.
-   */
-  rtems_capture_task_t* bt;
-
-  bt = begin_task->extensions[capture_extension_index];
-
-  /*
-   * The task pointers may not be known as the task may have
-   * been created before the capture engine was open. Add them.
-   */
-
-  if (bt == NULL)
-    bt = rtems_capture_create_capture_task (begin_task);
-
-  if (rtems_capture_trigger (NULL, bt, RTEMS_CAPTURE_BEGIN))
-    rtems_capture_record (bt, RTEMS_CAPTURE_BEGIN_EVENT);
-}
-
-/*
- * This function is called when a task is exitted. That is
- * returned rather than was deleted.
- */
-static void
-rtems_capture_exitted_task (rtems_tcb* exitted_task)
-{
-  /*
-   * Get the capture task control block so we can trace this
-   * event.
-   */
-  rtems_capture_task_t* et;
-
-  et = exitted_task->extensions[capture_extension_index];
-
-  /*
-   * The task pointers may not be known as the task may have
-   * been created before the capture engine was open. Add them.
-   */
-
-  if (et == NULL)
-    et = rtems_capture_create_capture_task (exitted_task);
-
-  if (rtems_capture_trigger (NULL, et, RTEMS_CAPTURE_EXITTED))
-    rtems_capture_record (et, RTEMS_CAPTURE_EXITTED_EVENT);
-
-  rtems_capture_task_stack_usage (et);
-}
-
-/*
- * This function is called when a termination request is identified.
- */
-static void
-rtems_capture_terminated_task (rtems_tcb* terminated_task)
-{
-  /*
-   * Get the capture task control block so we can trace this
-   * event.
-   */
-  rtems_capture_task_t* tt;
-
-  tt = terminated_task->extensions[capture_extension_index];
-
-  /*
-   * The task pointers may not be known as the task may have
-   * been created before the capture engine was open. Add them.
-   */
-
-  if (tt == NULL)
-    tt = rtems_capture_create_capture_task (terminated_task);
-
-  if (rtems_capture_trigger (NULL, tt, RTEMS_CAPTURE_TERMINATED))
-    rtems_capture_record (tt, RTEMS_CAPTURE_TERMINATED_EVENT);
-
-  rtems_capture_task_stack_usage (tt);
-}
-
-/*
- * This function is called when a context is switched.
- */
-static void
-rtems_capture_switch_task (rtems_tcb* current_task,
-                           rtems_tcb* heir_task)
-{
-  /*
-   * Only perform context switch trace processing if tracing is
-   * enabled.
-   */
-  if (capture_flags & RTEMS_CAPTURE_ON)
-  {
-    rtems_capture_time_t time;
-
-    /*
-     * Get the cpature task control block so we can update the
-     * reference and perform any watch or trigger functions.
-     * The task pointers may not be known as the task may have
-     * been created before the capture engine was open. Add them.
-     */
-    rtems_capture_task_t* ct;
-    rtems_capture_task_t* ht;
-
-
-    if (_States_Is_dormant (current_task->current_state))
-    {
-      rtems_id ct_id = current_task->Object.id;
-
-      for (ct = capture_tasks; ct; ct = ct->forw)
-        if (ct->id == ct_id)
-          break;
-    }
-    else
-    {
-      ct = current_task->extensions[capture_extension_index];
-
-      if (ct == NULL)
-        ct = rtems_capture_create_capture_task (current_task);
-    }
-
-    ht = heir_task->extensions[capture_extension_index];
-
-    if (ht == NULL)
-      ht = rtems_capture_create_capture_task (heir_task);
-
-    /*
-     * Update the execution time. Assume the time will not overflow
-     * for now. This may need to change.
-     */
-    rtems_capture_get_time (&time);
-
-    /*
-     * We could end up with null pointers for both the current task
-     * and the heir task.
-     */
-
-    if (ht)
-    {
-      ht->in++;
-      ht->time_in = time;
-    }
-
-    if (ct)
-    {
-      ct->out++;
-      if (ct->time_in)
-        ct->time += time - ct->time_in;
-    }
-
-    if (rtems_capture_trigger (ct, ht, RTEMS_CAPTURE_SWITCH))
-    {
-      rtems_capture_record (ct, RTEMS_CAPTURE_SWITCHED_OUT_EVENT);
-      rtems_capture_record (ht, RTEMS_CAPTURE_SWITCHED_IN_EVENT);
-    }
-  }
-}
-
-/*
  * This function initialises the realtime capture engine allocating the trace
  * buffer. It is assumed we have a working heap at stage of initialisation.
  */
 rtems_status_code
 rtems_capture_open (uint32_t   size, rtems_capture_timestamp timestamp __attribute__((unused)))
 {
-  rtems_name             name;
   rtems_status_code      sc;
 
   /*
@@ -961,22 +624,13 @@ rtems_capture_open (uint32_t   size, rtems_capture_timestamp timestamp __attribu
   capture_ceiling = 0;
   capture_floor   = 255;
 
-  /*
-   * Register the user extension handlers for the CAPture Engine.
-   */
-  name = rtems_build_name ('C', 'A', 'P', 'E');
-  sc   = rtems_extension_create (name, &capture_extensions, &capture_id);
+  sc = rtems_capture_user_extension_open();
 
   if (sc != RTEMS_SUCCESSFUL)
   {
-    capture_id = 0;
     free (capture_records);
     capture_records = NULL;
   }
-  else
-  {
-    capture_extension_index = rtems_object_id_get_index (capture_id);
-  }
 
   /*
    * Iterate over the list of existing tasks.
@@ -1016,7 +670,7 @@ rtems_capture_close (void)
    * release the resources we have without them being used.
    */
 
-  sc = rtems_extension_delete (capture_id);
+  sc = rtems_capture_user_extension_close();
 
   if (sc != RTEMS_SUCCESSFUL)
     return sc;
diff --git a/cpukit/libmisc/capture/capture_user_extension.c b/cpukit/libmisc/capture/capture_user_extension.c
new file mode 100644
index 0000000..f3bebc8
--- /dev/null
+++ b/cpukit/libmisc/capture/capture_user_extension.c
@@ -0,0 +1,435 @@
+/*
+  ------------------------------------------------------------------------
+
+  Copyright Objective Design Systems Pty Ltd, 2002
+  All rights reserved Objective Design Systems Pty Ltd, 2002
+  Chris Johns (ccj at acm.org)
+
+  COPYRIGHT (c) 1989-2009.
+  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 Capture Engine component.
+rtems_status_code rtems_capture_user_extension_open(void);
+rtems_status_code rtems_capture_user_extension_close(void);
+
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <rtems/rtems/tasksimpl.h>
+
+#include "captureimpl.h"
+
+#include <rtems/score/statesimpl.h>
+#include <rtems/score/todimpl.h>
+
+
+/*
+ * RTEMS Capture User Extension Data.
+ */
+static rtems_id                 capture_id;
+
+static bool 
+rtems_capture_create_task (rtems_tcb* current_task, 
+                           rtems_tcb* new_task);
+
+static void
+rtems_capture_start_task (rtems_tcb* current_task,
+                          rtems_tcb* started_task);
+
+static void
+rtems_capture_restart_task (rtems_tcb* current_task,
+                            rtems_tcb* restarted_task);
+
+static void
+rtems_capture_delete_task (rtems_tcb* current_task,
+                           rtems_tcb* deleted_task);
+
+static void
+rtems_capture_switch_task (rtems_tcb* current_task,
+                           rtems_tcb* heir_task);
+
+static void
+rtems_capture_begin_task (rtems_tcb* begin_task);
+
+static void
+rtems_capture_exitted_task (rtems_tcb* exitted_task);
+
+static void
+rtems_capture_terminated_task (rtems_tcb* terminated_task);
+
+static const rtems_extensions_table capture_extensions = {
+  .thread_create    = rtems_capture_create_task,
+  .thread_start     = rtems_capture_start_task,
+  .thread_restart   = rtems_capture_restart_task,
+  .thread_delete    = rtems_capture_delete_task,
+  .thread_switch    = rtems_capture_switch_task,
+  .thread_begin     = rtems_capture_begin_task,
+  .thread_exitted   = rtems_capture_exitted_task,
+  .fatal            = NULL,
+  .thread_terminate = rtems_capture_terminated_task
+};
+
+rtems_status_code rtems_capture_user_extension_open(void)
+{
+  rtems_status_code sc;
+  rtems_name        name;
+  int               index;
+
+  /*
+   * Register the user extension handlers for the CAPture Engine.
+   */
+  name = rtems_build_name ('C', 'A', 'P', 'E');
+  sc   = rtems_extension_create (name, &capture_extensions, &capture_id);
+  if (sc != RTEMS_SUCCESSFUL)
+    capture_id = 0;
+  else {
+    index = rtems_object_id_get_index (capture_id);
+    rtems_capture_set_extension_index( index );
+  }
+
+  return sc;
+}
+
+rtems_status_code rtems_capture_user_extension_close(void)
+{
+  rtems_status_code sc;
+  sc = rtems_extension_delete (capture_id);
+  return sc;
+}
+
+/*
+ * This function is called when a task is created.
+ */
+static bool
+rtems_capture_create_task (rtems_tcb* current_task,
+                           rtems_tcb* new_task)
+{
+  rtems_capture_task_t* ct;
+  rtems_capture_task_t* nt;
+  int                   index = rtems_capture_get_extension_index();
+
+  ct = current_task->extensions[index];
+
+  /*
+   * The task pointers may not be known as the task may have
+   * been created before the capture engine was open. Add them.
+   */
+
+  if (ct == NULL)
+    ct = rtems_capture_create_capture_task (current_task);
+
+  /*
+   * Create the new task's capture control block.
+   */
+  nt = rtems_capture_create_capture_task (new_task);
+
+  if (rtems_capture_trigger (ct, nt, RTEMS_CAPTURE_CREATE))
+  {
+    rtems_capture_record (ct, RTEMS_CAPTURE_CREATED_BY_EVENT);
+    rtems_capture_record (nt, RTEMS_CAPTURE_CREATED_EVENT);
+  }
+
+  return 1 == 1;
+}
+
+/*
+ * This function is called when a task is started.
+ */
+static void
+rtems_capture_start_task (rtems_tcb* current_task,
+                          rtems_tcb* started_task)
+{
+  /*
+   * Get the capture task control block so we can trace this
+   * event.
+   */
+  rtems_capture_task_t* ct;
+  rtems_capture_task_t* st;
+  int                   index = rtems_capture_get_extension_index();
+
+  ct = current_task->extensions[index];
+  st = started_task->extensions[index];
+
+  /*
+   * The task pointers may not be known as the task may have
+   * been created before the capture engine was open. Add them.
+   */
+
+  if (ct == NULL)
+    ct = rtems_capture_create_capture_task (current_task);
+
+  if (st == NULL)
+    st = rtems_capture_create_capture_task (started_task);
+
+  if (rtems_capture_trigger (ct, st, RTEMS_CAPTURE_START))
+  {
+    rtems_capture_record (ct, RTEMS_CAPTURE_STARTED_BY_EVENT);
+    rtems_capture_record (st, RTEMS_CAPTURE_STARTED_EVENT);
+  }
+
+  rtems_capture_init_stack_usage (st);
+}
+
+/*
+ * This function is called when a task is restarted.
+ */
+static void
+rtems_capture_restart_task (rtems_tcb* current_task,
+                            rtems_tcb* restarted_task)
+{
+  /*
+   * Get the capture task control block so we can trace this
+   * event.
+   */
+  rtems_capture_task_t* ct;
+  rtems_capture_task_t* rt;
+  int                   index = rtems_capture_get_extension_index();
+
+  ct = current_task->extensions[index];
+  rt = restarted_task->extensions[index];
+
+  /*
+   * The task pointers may not be known as the task may have
+   * been created before the capture engine was open. Add them.
+   */
+
+  if (ct == NULL)
+    ct = rtems_capture_create_capture_task (current_task);
+
+  if (rt == NULL)
+    rt = rtems_capture_create_capture_task (restarted_task);
+
+  if (rtems_capture_trigger (ct, rt, RTEMS_CAPTURE_RESTART))
+  {
+    rtems_capture_record (ct, RTEMS_CAPTURE_RESTARTED_BY_EVENT);
+    rtems_capture_record (rt, RTEMS_CAPTURE_RESTARTED_EVENT);
+  }
+
+  rtems_capture_task_stack_usage (rt);
+  rtems_capture_init_stack_usage (rt);
+}
+
+/*
+ * This function is called when a task is deleted.
+ */
+static void
+rtems_capture_delete_task (rtems_tcb* current_task,
+                           rtems_tcb* deleted_task)
+{
+  /*
+   * Get the capture task control block so we can trace this
+   * event.
+   */
+  rtems_capture_task_t* ct;
+  rtems_capture_task_t* dt;
+  int                   index = rtems_capture_get_extension_index();
+
+  /*
+   * The task pointers may not be known as the task may have
+   * been created before the capture engine was open. Add them.
+   */
+
+  ct = current_task->extensions[index];
+  dt = deleted_task->extensions[index];
+
+  if (ct == NULL)
+    ct = rtems_capture_create_capture_task (current_task);
+
+  if (dt == NULL)
+    dt = rtems_capture_create_capture_task (deleted_task);
+
+  if (rtems_capture_trigger (ct, dt, RTEMS_CAPTURE_DELETE))
+  {
+    rtems_capture_record (ct, RTEMS_CAPTURE_DELETED_BY_EVENT);
+    rtems_capture_record (dt, RTEMS_CAPTURE_DELETED_EVENT);
+  }
+
+  rtems_capture_task_stack_usage (dt);
+
+  /*
+   * This task's tcb will be invalid. This signals the
+   * task has been deleted.
+   */
+  dt->tcb = 0;
+
+  rtems_capture_destroy_capture_task (dt);
+}
+
+/*
+ * This function is called when a task is begun.
+ */
+static void
+rtems_capture_begin_task (rtems_tcb* begin_task)
+{
+  /*
+   * Get the capture task control block so we can trace this
+   * event.
+   */
+  rtems_capture_task_t* bt;
+  int                   index = rtems_capture_get_extension_index();
+
+  bt = begin_task->extensions[index];
+
+  /*
+   * The task pointers may not be known as the task may have
+   * been created before the capture engine was open. Add them.
+   */
+
+  if (bt == NULL)
+    bt = rtems_capture_create_capture_task (begin_task);
+
+  if (rtems_capture_trigger (NULL, bt, RTEMS_CAPTURE_BEGIN))
+    rtems_capture_record (bt, RTEMS_CAPTURE_BEGIN_EVENT);
+}
+
+/*
+ * This function is called when a task is exitted. That is
+ * returned rather than was deleted.
+ */
+static void
+rtems_capture_exitted_task (rtems_tcb* exitted_task)
+{
+  /*
+   * Get the capture task control block so we can trace this
+   * event.
+   */
+  rtems_capture_task_t* et;
+  int                   index = rtems_capture_get_extension_index();
+
+  et = exitted_task->extensions[index];
+
+  /*
+   * The task pointers may not be known as the task may have
+   * been created before the capture engine was open. Add them.
+   */
+
+  if (et == NULL)
+    et = rtems_capture_create_capture_task (exitted_task);
+
+  if (rtems_capture_trigger (NULL, et, RTEMS_CAPTURE_EXITTED))
+    rtems_capture_record (et, RTEMS_CAPTURE_EXITTED_EVENT);
+
+  rtems_capture_task_stack_usage (et);
+}
+
+/*
+ * This function is called when a termination request is identified.
+ */
+static void
+rtems_capture_terminated_task (rtems_tcb* terminated_task)
+{
+  /*
+   * Get the capture task control block so we can trace this
+   * event.
+   */
+  rtems_capture_task_t* tt;
+  int                   index = rtems_capture_get_extension_index();
+
+  tt = terminated_task->extensions[index];
+
+  /*
+   * The task pointers may not be known as the task may have
+   * been created before the capture engine was open. Add them.
+   */
+
+  if (tt == NULL)
+    tt = rtems_capture_create_capture_task (terminated_task);
+
+  if (rtems_capture_trigger (NULL, tt, RTEMS_CAPTURE_TERMINATED))
+    rtems_capture_record (tt, RTEMS_CAPTURE_TERMINATED_EVENT);
+
+  rtems_capture_task_stack_usage (tt);
+}
+
+/*
+ * This function is called when a context is switched.
+ */
+static void
+rtems_capture_switch_task (rtems_tcb* current_task,
+                           rtems_tcb* heir_task)
+{
+  uint32_t flags = rtems_capture_get_flags();
+  int      index = rtems_capture_get_extension_index();
+
+  /*
+   * Only perform context switch trace processing if tracing is
+   * enabled.
+   */
+  if (flags & RTEMS_CAPTURE_ON)
+  {
+    rtems_capture_time_t time;
+
+    /*
+     * Get the cpature task control block so we can update the
+     * reference and perform any watch or trigger functions.
+     * The task pointers may not be known as the task may have
+     * been created before the capture engine was open. Add them.
+     */
+    rtems_capture_task_t* ct;
+    rtems_capture_task_t* ht;
+
+
+    if (_States_Is_dormant (current_task->current_state))
+    {
+      rtems_id ct_id = current_task->Object.id;
+      ct = rtems_capture_find_capture_task( ct_id );
+    }
+    else
+    {
+      ct = current_task->extensions[index];
+
+      if (ct == NULL)
+        ct = rtems_capture_create_capture_task (current_task);
+    }
+
+    ht = heir_task->extensions[index];
+
+    if (ht == NULL)
+      ht = rtems_capture_create_capture_task (heir_task);
+
+    /*
+     * Update the execution time. Assume the time will not overflow
+     * for now. This may need to change.
+     */
+    rtems_capture_get_time (&time);
+
+    /*
+     * We could end up with null pointers for both the current task
+     * and the heir task.
+     */
+
+    if (ht)
+    {
+      ht->in++;
+      ht->time_in = time;
+    }
+
+    if (ct)
+    {
+      ct->out++;
+      if (ct->time_in)
+        ct->time += time - ct->time_in;
+    }
+
+    if (rtems_capture_trigger (ct, ht, RTEMS_CAPTURE_SWITCH))
+    {
+      rtems_capture_record (ct, RTEMS_CAPTURE_SWITCHED_OUT_EVENT);
+      rtems_capture_record (ht, RTEMS_CAPTURE_SWITCHED_IN_EVENT);
+    }
+  }
+}
diff --git a/cpukit/libmisc/capture/captureimpl.h b/cpukit/libmisc/capture/captureimpl.h
new file mode 100644
index 0000000..ee18d82
--- /dev/null
+++ b/cpukit/libmisc/capture/captureimpl.h
@@ -0,0 +1,195 @@
+/**
+ * @file rtems/captureimpl.h
+ *
+ * @brief Capture Implementation file 
+ *
+ * This file contains an interface between the capture engine and
+ * capture user extension methods.
+ */
+
+/*
+  ------------------------------------------------------------------------
+
+  Copyright Objective Design Systems Pty Ltd, 2002
+  All rights reserved Objective Design Systems Pty Ltd, 2002
+  Chris Johns (ccj at acm.org)
+
+  COPYRIGHT (c) 1989-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 Capture Engine component.
+
+*/
+
+#ifndef __CAPTUREIMPL_H_
+#define __CAPTUREIMPL_H_
+
+
+/**@{*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "capture.h"
+
+/*
+ * 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_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)
+
+/**
+ * @brief Capture set extension index.
+ *
+ * This function is used to set the extension index
+ * for the capture engine.  
+ *
+ * @param[in] index specifies the extension index to be
+ * used for capture engine data.
+ */
+void rtems_capture_set_extension_index(int index);
+
+/**
+ * @brief Capture get extension index.
+ *
+ * This function rturns the extension index for the
+ * capture engine.
+ *
+ * @retval This method returns the extension index.
+ */
+int  rtems_capture_get_extension_index(void);
+
+/**
+ * @brief Capture get flags.
+ *
+ * This function gets the current flag settings
+ * for the capture engine.
+ *
+ * @retval This method returns the global capture
+ * flags.
+ * 
+ */
+uint32_t rtems_capture_get_flags(void);
+
+/**
+ * @brief Capture set flags.
+ *
+ * This function sets a flag in the capture engine
+ *
+ * @param[in] mask specifies the flag to set
+ */
+void rtems_capture_set_flags(uint32_t mask);
+
+/**
+ * @brief Capture user extension open.
+ *
+ * This function creates the capture user extensions.
+ *
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL upon successful
+ * creation of the user extensions.
+ */
+rtems_status_code rtems_capture_user_extension_open(void);
+
+/**
+ * @brief Capture user extension close.
+ *
+ * This function closes the capture user extensions.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL upon a successful
+ * delete of the user extensions.
+ */
+rtems_status_code rtems_capture_user_extension_close(void);
+
+/**
+ * @brief Capture find capture task.
+ *
+ * This function finds the capture task control block
+ *
+ * @param[in] ct_id specifies the task_id
+ *
+ * @retval This method returns the capture task control block associated
+ * with the given task id.
+ */
+rtems_capture_task_t* rtems_capture_find_capture_task( rtems_id ct_id );
+
+/**
+ * @brief Capture create capture task control block.
+ *
+ * This function create the capture task control block
+ *
+ * @param[in] new_task specifies the rtems thread control block
+ *
+ * @retval This method returns a capture task control block.
+ */
+rtems_capture_task_t* rtems_capture_create_capture_task (rtems_tcb* new_task);
+
+/**
+ * @brief Capture trigger.
+ *
+ * This function checks if we have triggered or if this event is a
+ * cause of a trigger.
+ *
+ * @param[in] ft specifies specifices the capture from task
+ * @param[in] tt specifies specifices the capture to task
+ * @param[in] events specifies the events
+ *
+ * @retval This method returns true if we have triggered or
+ * if the event is a cause of a trigger.
+ */
+bool rtems_capture_trigger (rtems_capture_task_t* ft,
+                       rtems_capture_task_t* tt,
+                       uint32_t              events);
+/**
+ * @brief Capture initialize stack usage
+ *
+ * This function setups a stack so its usage can be monitored.
+ *
+ * @param[in] task specifies the capture task block
+ */
+void rtems_capture_init_stack_usage (rtems_capture_task_t* task);
+
+/**
+ * @brief Capture destroy task.
+ *
+ * This function destroy the task structure if the reference count
+ * is 0 and the tcb has been cleared signalling the task has been
+ * deleted.
+ *
+ * @param[in] task specifies the capture task block
+ */
+void rtems_capture_destroy_capture_task (rtems_capture_task_t* task);
+
+/**
+ * @brief .
+ *
+ * This function returns the current time. If a handler is provided
+ * by the user the time is gotten from that.
+ *
+ * @param[in] time specifies the capture time
+ *
+ * @retval This method returns a nano-second time if no user handler
+ * is provided.  Otherwise, it returns a resolution defined by the handler.
+ */
+void rtems_capture_get_time (rtems_capture_time_t* time);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
-- 
1.8.1.4



More information about the devel mailing list