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

Chris Johns chrisj at rtems.org
Thu Sep 4 02:26:18 UTC 2014


Hi,

These patches look fine.

Chris

On 4/09/2014 4:03 am, Jennifer Averett wrote:
> ---
>   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
>



More information about the devel mailing list