[PATCH 1/5] capture: Removal of capture task tracking.

Chris Johns chrisj at rtems.org
Mon Sep 22 21:57:15 UTC 2014


On 23/09/2014 12:00 am, Jennifer Averett wrote:
> This patch removes functionality for stack checking from
> the capture engine and requiresi the use of existing rtems
> functions for this information.  It modifies ctload to use
> functionality similar to rtems cpuusage.  It removes the
> capture task and stores a new capture task record the first
> time the task is seen.  The per task data that was still
> needed is scaled down and stored in the tcb.

If the capture engine is not needed for ctload to work why not move that 
code out of here and into the cpuuse command ? It would appear more 
available to users.

> ---
>   cpukit/libmisc/capture/capture-cli.c            | 383 ++++++++++++++----------
>   cpukit/libmisc/capture/capture.c                | 367 ++++++-----------------
>   cpukit/libmisc/capture/capture.h                | 295 ++++--------------
>   cpukit/libmisc/capture/capture_user_extension.c | 219 +++-----------
>   cpukit/libmisc/capture/captureimpl.h            |  53 +---
>   5 files changed, 420 insertions(+), 897 deletions(-)
>
> diff --git a/cpukit/libmisc/capture/capture-cli.c b/cpukit/libmisc/capture/capture-cli.c
> index 2aa7c9c..6fe7e6c 100644
> --- a/cpukit/libmisc/capture/capture-cli.c
> +++ b/cpukit/libmisc/capture/capture-cli.c
> @@ -35,12 +35,28 @@
>   #include <rtems.h>
>   #include <rtems/capture-cli.h>
>   #include <rtems/monitor.h>
> -
> +#include <rtems/cpuuse.h>
> +#
>   #define RC_UNUSED __attribute__((unused))
>
>   #define RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS (20)
>
>   /*
> + * Counter used to count the number of active tasks.
> + */
> +static int                   rtems_capture_cli_task_count = 0;
> +
> +/*
> + * Array of tasks sorted by load.
> + */
> +static rtems_tcb*            rtems_capture_cli_load_tasks[RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS + 1];
> +
> +/*
> + * The load for each tcb at the moment rtems_capture_cli_load_tasks was generated.
> + */
> +static unsigned long long    rtems_capture_cli_load[RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS + 1];
> +
> +/*
>    * The user capture timestamper.
>    */
>   static rtems_capture_timestamp capture_timestamp;
> @@ -233,6 +249,104 @@ rtems_capture_cli_print_timestamp (uint64_t uptime)
>     fprintf (stdout, "%5lu:%02lu:%02lu.%09lu", hours, minutes, seconds, nanosecs);
>   }
>
> +static void
> +rtems_capture_cli_print_task (rtems_tcb *tcb)
> +{
> +  rtems_task_priority   ceiling = rtems_capture_watch_get_ceiling ();
> +  rtems_task_priority   floor = rtems_capture_watch_get_floor ();
> +  rtems_task_priority   priority;
> +  int                   length;
> +
> +  priority = rtems_capture_task_real_priority (tcb);
> +
> +  fprintf (stdout, " ");
> +  rtems_monitor_dump_id (rtems_capture_task_id (tcb));
> +  fprintf (stdout, " ");
> +  rtems_monitor_dump_name (rtems_capture_task_id (tcb));
> +  fprintf (stdout, " ");
> +  rtems_monitor_dump_priority (rtems_capture_task_start_priority (tcb));
> +  fprintf (stdout, " ");
> +  rtems_monitor_dump_priority (rtems_capture_task_real_priority (tcb));
> +  fprintf (stdout, " ");
> +  rtems_monitor_dump_priority (rtems_capture_task_curr_priority (tcb));
> +  fprintf (stdout, " ");
> +  length = rtems_monitor_dump_state (rtems_capture_task_state (tcb));
> +  fprintf (stdout, "%*c", 14 - length, ' ');
> +  fprintf (stdout, " %c%c",
> +           'a',
> +           rtems_capture_task_flags (tcb) & RTEMS_CAPTURE_TRACED ? 't' : '-');
> +
> +  if ((floor > ceiling) && (ceiling > priority))
> +    fprintf (stdout, "--");
> +  else
> +  {
> +    uint32_t flags = rtems_capture_task_control_flags (tcb);
> +    fprintf (stdout, "%c%c",
> +             rtems_capture_task_control (tcb) ?
> +             (flags & RTEMS_CAPTURE_WATCH ? 'w' : '+') : '-',
> +             rtems_capture_watch_global_on () ? 'g' : '-');
> +  }
> +  fprintf (stdout, "\n");
> +}
> +static void
> +rtems_caputure_cli_print_record_std(rtems_capture_record_t* rec, uint64_t diff)
> +{
> +  uint32_t                     event;
> +  int                          e;
> +
> +  event = rec->events >> RTEMS_CAPTURE_EVENT_START;
> +
> +  for (e = RTEMS_CAPTURE_EVENT_START; e < RTEMS_CAPTURE_EVENT_END; e++)
> +  {
> +    if (event & 1)
> +    {
> +      rtems_capture_cli_print_timestamp (rec->time);
> +      fprintf (stdout, " %9" PRId64 " ", diff);
> +      rtems_monitor_dump_id (rec->task_id);
> +      fprintf(stdout, "      %3" PRId32 " %3" PRId32 " %s\n",
> +             (rec->events >> RTEMS_CAPTURE_REAL_PRIORITY_EVENT) & 0xff,
> +             (rec->events >> RTEMS_CAPTURE_CURR_PRIORITY_EVENT) & 0xff,
> +             rtems_capture_event_text (e));
> +    }
> +    event >>= 1;
> +  }
> +}
> +
> +static void
> +rtems_caputre_cli_print_record_task(rtems_capture_record_t* rec)
> +{
> +  rtems_capture_task_record_t* task_rec = (rtems_capture_task_record_t*) rec;
> +
> +  rtems_capture_cli_print_timestamp (rec->time);
> +  fprintf (stdout, "           ");
> +  rtems_monitor_dump_id (rec->task_id);
> +   fprintf (stdout, " %c%c%c%c",
> +            (char) (task_rec->name >> 24) & 0xff,
> +            (char) (task_rec->name >> 16) & 0xff,
> +            (char) (task_rec->name >> 8) & 0xff,
> +            (char) (task_rec->name >> 0) & 0xff);
> +   fprintf (stdout, " %3" PRId32   " %3" PRId32 "\n",
> +            task_rec->start_priority,
> +            task_rec->stack_size);
> +}
> +
> +/*
> + * rtems_capture_cli_count_tasks
> + *
> + *  DESCRIPTION:
> + *
> + * This function is called for each tcb and counts the
> + * number of tasks.
> + *
> + */
> +
> +static void
> +rtems_capture_cli_count_tasks (rtems_tcb *tcb)
> +{
> +  rtems_capture_cli_task_count++;
> +}
> +
> +
>   /*
>    * rtems_capture_cli_task_list
>    *
> @@ -248,71 +362,49 @@ rtems_capture_cli_task_list (int                                argc RC_UNUSED,
>                                const rtems_monitor_command_arg_t* command_arg RC_UNUSED,
>                                bool                               verbose RC_UNUSED)
>   {
> -  rtems_task_priority   ceiling = rtems_capture_watch_get_ceiling ();
> -  rtems_task_priority   floor = rtems_capture_watch_get_floor ();
> -  rtems_capture_task_t* task = rtems_capture_get_task_list ();
> -  int                   count = rtems_capture_task_count ();
>     rtems_capture_time_t  uptime;
>
>     rtems_capture_time (&uptime);
>
> +  rtems_capture_cli_task_count = 0;
> +  rtems_iterate_over_all_threads (rtems_capture_cli_count_tasks);
> +
>     fprintf (stdout, "uptime: ");
>     rtems_capture_cli_print_timestamp (uptime);
> -  fprintf (stdout, "\ntotal %i\n", count);
> -
> -  while (task)
> -  {
> -    rtems_task_priority priority;
> -    int32_t             stack_used;
> -    int32_t             time_used;
> -    int                 length;
> +  fprintf (stdout, "\ntotal %i\n", rtems_capture_cli_task_count);
> +  rtems_iterate_over_all_threads (rtems_capture_cli_print_task);
> +}
>
> -    stack_used = rtems_capture_task_stack_usage (task);
> -    if (stack_used)
> -      stack_used = (stack_used * 100) / rtems_capture_task_stack_size (task);
> +static void
> +rtems_capture_cli_task_sort (rtems_tcb* tcb)
> +{
> +  int                   i;
> +  int                   j;
>
> -    if (stack_used > 100)
> -      stack_used = 100;
> +  if (tcb)
> +  {
> +    rtems_capture_time_t l = tcb->cpu_time_used;
>
> -    time_used = (rtems_capture_task_time (task) * 100) / uptime;
> +    rtems_capture_cli_task_count++;
>
> -    if (time_used > 100)
> -      time_used = 100;
> +    for (i = 0; i < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS; i++)
> +    {
> +      if (rtems_capture_cli_load_tasks[i])
> +      {
> +        if ((l == 0) || (l < rtems_capture_cli_load[i]))
> +          continue;
>
> -    priority = rtems_capture_task_real_priority (task);
> +        for (j = (RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS - 1); j >= i; j--)
> +        {
> +          rtems_capture_cli_load_tasks[j + 1] = rtems_capture_cli_load_tasks[j];
> +          rtems_capture_cli_load[j + 1]  = rtems_capture_cli_load[j];
> +        }
> +      }
>
> -    fprintf (stdout, " ");
> -    rtems_monitor_dump_id (rtems_capture_task_id (task));
> -    fprintf (stdout, " ");
> -    rtems_monitor_dump_name (rtems_capture_task_id (task));
> -    fprintf (stdout, " ");
> -    rtems_monitor_dump_priority (rtems_capture_task_start_priority (task));
> -    fprintf (stdout, " ");
> -    rtems_monitor_dump_priority (rtems_capture_task_real_priority (task));
> -    fprintf (stdout, " ");
> -    rtems_monitor_dump_priority (rtems_capture_task_curr_priority (task));
> -    fprintf (stdout, " ");
> -    length = rtems_monitor_dump_state (rtems_capture_task_state (task));
> -    fprintf (stdout, "%*c", 14 - length, ' ');
> -    fprintf (stdout, " %c%c",
> -             rtems_capture_task_valid (task) ? 'a' : 'd',
> -             rtems_capture_task_flags (task) & RTEMS_CAPTURE_TRACED ? 't' : '-');
> -
> -    if ((floor > ceiling) && (ceiling > priority))
> -      fprintf (stdout, "--");
> -    else
> -    {
> -      uint32_t flags = rtems_capture_task_control_flags (task);
> -      fprintf (stdout, "%c%c",
> -               rtems_capture_task_control (task) ?
> -               (flags & RTEMS_CAPTURE_WATCH ? 'w' : '+') : '-',
> -               rtems_capture_watch_global_on () ? 'g' : '-');
> +      rtems_capture_cli_load_tasks[i] = tcb;
> +      rtems_capture_cli_load[i]  = l;
> +      break;
>       }
> -    fprintf (stdout, " %3" PRId32 "%% %3" PRId32 "%% ", stack_used, time_used);
> -    rtems_capture_cli_print_timestamp (rtems_capture_task_time (task));
> -    fprintf (stdout, "\n");
> -
> -    task = rtems_capture_next_task (task);
>     }
>   }
>
> @@ -328,26 +420,22 @@ rtems_capture_cli_task_list (int                                argc RC_UNUSED,
>   static void
>   rtems_capture_cli_task_load_thread (rtems_task_argument arg)
>   {
> +  rtems_tcb*          tcb;
>     rtems_task_priority ceiling = rtems_capture_watch_get_ceiling ();
>     rtems_task_priority floor = rtems_capture_watch_get_floor ();
>     int                 last_count = 0;
>     FILE*               pstdout = (FILE*) arg;
> +  int                 i;
> +  int                 j;
>
>     fileno(stdout);
>     stdout = pstdout;
>
>     while (true)
>     {
> -    rtems_capture_task_t* tasks[RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS + 1];
> -    unsigned long long    load[RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS + 1];
> -    rtems_capture_task_t* task;
> -    rtems_capture_time_t  uptime;
> -    rtems_capture_time_t  total_time;
> -    int                   count = 0;
> -    int                   i;
> -    int                   j;
> -
> -    rtems_capture_time (&uptime);
> +    Timestamp_Control  uptime, total, ran, uptime_at_last_reset;
> +    uint32_t seconds, nanoseconds;
> +    size_t                size;
>
>       cli_load_thread_active = 1;
>
> @@ -356,114 +444,98 @@ rtems_capture_cli_task_load_thread (rtems_task_argument arg)
>        * into our local arrays. We only handle a limited number of
>        * tasks.
>        */
> +    size = sizeof (rtems_capture_cli_load_tasks);
> +    memset (rtems_capture_cli_load_tasks, 0, size);
> +    memset (rtems_capture_cli_load, 0, sizeof (rtems_capture_cli_load));
>
> -    memset (tasks, 0, sizeof (tasks));
> -    memset (load, 0, sizeof (load));
> +    _Timestamp_Set_to_zero( &total );
> +    uptime_at_last_reset = CPU_usage_Uptime_at_last_reset;
> +    _TOD_Get_uptime( &uptime );
> +    seconds = _Timestamp_Get_seconds( &uptime );
> +    nanoseconds = _Timestamp_Get_nanoseconds( &uptime ) /
> +                  TOD_NANOSECONDS_PER_MICROSECOND;
>
> -    task = rtems_capture_get_task_list ();
> -
> -    total_time = 0;
> -
> -    while (task)
> -    {
> -      if (rtems_capture_task_valid (task))
> -      {
> -        rtems_capture_time_t l = rtems_capture_task_delta_time (task);
> -
> -        count++;
> -
> -        total_time += l;
> -
> -        for (i = 0; i < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS; i++)
> -        {
> -          if (tasks[i])
> -          {
> -            if ((l == 0) || (l < load[i]))
> -              continue;
> -
> -            for (j = (RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS - 1); j >= i; j--)
> -            {
> -              tasks[j + 1] = tasks[j];
> -              load[j + 1]  = load[j];
> -            }
> -          }
> -
> -          tasks[i] = task;
> -          load[i]  = l;
> -          break;
> -        }
> -      }
> -      task = rtems_capture_next_task (task);
> -    }
> +    rtems_iterate_over_all_threads (rtems_capture_cli_task_sort);
>
>       fprintf (stdout, "\x1b[H\x1b[J Press ENTER to exit.\n\n");
>       fprintf (stdout, "uptime: ");
> -    rtems_capture_cli_print_timestamp (uptime);
> +    fprintf (stdout, "%7" PRIu32 ".%06" PRIu32 "\n",  seconds, nanoseconds);
>       fprintf (stdout,
>                "\n\n"
> -             "     PID NAME RPRI CPRI STATE          %%CPU     %%STK FLGS    EXEC TIME\n");
> +             "     PID NAME RPRI CPRI STATE      EXEC TIME   %%CPU\n");
>
> -    if (count > last_count)
> -      j = count;
> +    if (rtems_capture_cli_task_count > last_count)
> +      j = rtems_capture_cli_task_count;
>       else
>         j = last_count;
>
>       for (i = 0; i < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS; i++)
>       {
>         rtems_task_priority priority;
> -      int                 stack_used;
> -      int                 task_load;
> -      int                 k;
> -
> -      if (!tasks[i])
> +      Timestamp_Control   last;
> +      uint32_t            ival, fval;
> +
> +      if (!rtems_capture_cli_load_tasks[i])
>           break;
>
>         j--;
>
> -      stack_used = rtems_capture_task_stack_usage (tasks[i]);
> -      if (stack_used)
> -        stack_used = (stack_used * 100) / rtems_capture_task_stack_size (tasks[i]);
> -
> -      if (stack_used > 100)
> -        stack_used = 100;
> -
> -      task_load = (int) ((load[i] * 100000) / total_time);
> -
> -      priority = rtems_capture_task_real_priority (tasks[i]);
> +      /*
> +       * If this is the currently executing thread, account for time
> +       * since the last context switch.
> +       */
> +      tcb = rtems_capture_cli_load_tasks[i];
> +      ran = rtems_capture_cli_load[i];
> +      if ( _Thread_is_executing_on_a_core( tcb, &last ) ) {
> +        Timestamp_Control used;
> +        _TOD_Get_uptime( &uptime );
> +        _Timestamp_Subtract( &last, &uptime, &used );
> +        _Timestamp_Add_to( &ran, &used );
> +      } else {
> +        _TOD_Get_uptime( &uptime );
> +      }
> +      _Timestamp_Subtract( &uptime_at_last_reset, &uptime, &total );
> +      _Timestamp_Divide( &ran, &total, &ival, &fval );
> +      seconds = _Timestamp_Get_seconds( &ran );
> +      nanoseconds = _Timestamp_Get_nanoseconds( &ran ) /
> +             TOD_NANOSECONDS_PER_MICROSECOND;
> +
> +      priority = rtems_capture_task_real_priority (tcb);
>
>         fprintf (stdout, "\x1b[K");
> -      rtems_monitor_dump_id (rtems_capture_task_id (tasks[i]));
> +      rtems_monitor_dump_id (rtems_capture_task_id (tcb));
>         fprintf (stdout, " ");
> -      rtems_monitor_dump_name (rtems_capture_task_id (tasks[i]));
> +      rtems_monitor_dump_name (rtems_capture_task_id (tcb));
>         fprintf (stdout, "  ");
>         rtems_monitor_dump_priority (priority);
>         fprintf (stdout, "  ");
> -      rtems_monitor_dump_priority (rtems_capture_task_curr_priority (tasks[i]));
> +      rtems_monitor_dump_priority (rtems_capture_task_curr_priority (tcb));
>         fprintf (stdout, " ");
> -      k = rtems_monitor_dump_state (rtems_capture_task_state (tasks[i]));
> -      fprintf (stdout, "%*c %3i.%03i%% ", 14 - k, ' ',
> -               task_load / 1000, task_load % 1000);
> -      fprintf (stdout, "%3i%% %c%c", stack_used,
> -              rtems_capture_task_valid (tasks[i]) ? 'a' : 'd',
> -              rtems_capture_task_flags (tasks[i]) & RTEMS_CAPTURE_TRACED ? 't' : '-');
> +      rtems_monitor_dump_state (rtems_capture_task_state (tcb));
> +      fprintf (stdout,
> +            "%7" PRIu32 ".%06" PRIu32 " |%4" PRIu32 ".%03" PRIu32 ,
> +            seconds, nanoseconds, ival, fval
> +       );
> +      fprintf (stdout, "    %c%c",
> +              'a',
> +              rtems_capture_task_flags (tcb) & RTEMS_CAPTURE_TRACED ? 't' : '-');
>
>         if ((floor > ceiling) && (ceiling > priority))
>           fprintf (stdout, "--");
>         else
>           fprintf (stdout, "%c%c",
> -                rtems_capture_task_control (tasks[i]) ?
> -                (rtems_capture_task_control_flags (tasks[i]) &
> +                rtems_capture_task_control (tcb) ?
> +                (rtems_capture_task_control_flags (tcb) &
>                    RTEMS_CAPTURE_WATCH ? 'w' : '+') : '-',
>                   rtems_capture_watch_global_on () ? 'g' : '-');
>
>         fprintf (stdout, "   ");
> -      rtems_capture_cli_print_timestamp (rtems_capture_task_time (tasks[i]));
>         fprintf (stdout, "\n");
>       }
>
> -    if (count < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS)
> +    if (rtems_capture_cli_task_count < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS)
>       {
> -      j = RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS - count;
> +      j = RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS - rtems_capture_cli_task_count;
>         while (j > 0)
>         {
>           fprintf (stdout, "\x1b[K\n");
> @@ -471,7 +543,7 @@ rtems_capture_cli_task_load_thread (rtems_task_argument arg)
>         }
>       }
>
> -    last_count = count;
> +    last_count = rtems_capture_cli_task_count;
>
>       cli_load_thread_active = 0;
>
> @@ -1415,42 +1487,23 @@ rtems_capture_cli_trace_records (int                                argc,
>         rec = (rtems_capture_record_t*) ptr;
>
>         if (csv)
> -        fprintf (stdout, "%08" PRIxPTR ",%03" PRIu32
> +        fprintf (stdout, "%08" PRIu32 ",%03" PRIu32
>                      ",%03" PRIu32 ",%04" PRIx32 ",%" PRId64 "\n",
> -                 (uintptr_t) rec->task,
> +                 rec->task_id,
>                    (rec->events >> RTEMS_CAPTURE_REAL_PRIORITY_EVENT) & 0xff,
>                    (rec->events >> RTEMS_CAPTURE_CURR_PRIORITY_EVENT) & 0xff,
>                    (rec->events >> RTEMS_CAPTURE_EVENT_START),
>                    (uint64_t) rec->time);
> -      else
> -      {
> -        uint64_t diff = 0;
> -        uint32_t event;
> -        int      e;
> -
> -        event = rec->events >> RTEMS_CAPTURE_EVENT_START;
> -
> -        for (e = RTEMS_CAPTURE_EVENT_START; e < RTEMS_CAPTURE_EVENT_END; e++)
> -        {
> -          if (event & 1)
> -          {
> -            rtems_capture_cli_print_timestamp (rec->time);
> -            if (last_t)
> -              diff = rec->time - last_t;
> -            last_t = rec->time;
> -            fprintf (stdout, " %9" PRId64 " ", diff);
> -            rtems_monitor_dump_id (rtems_capture_task_id (rec->task));
> -            fprintf (stdout, " %c%c%c%c",
> -                     (char) (rec->task->name >> 24) & 0xff,
> -                     (char) (rec->task->name >> 16) & 0xff,
> -                     (char) (rec->task->name >> 8) & 0xff,
> -                     (char) (rec->task->name >> 0) & 0xff);
> -            fprintf (stdout, " %3" PRId32 " %3" PRId32 " %s\n",
> -                    (rec->events >> RTEMS_CAPTURE_REAL_PRIORITY_EVENT) & 0xff,
> -                    (rec->events >> RTEMS_CAPTURE_CURR_PRIORITY_EVENT) & 0xff,
> -                    rtems_capture_event_text (e));
> -          }
> -          event >>= 1;
> +      else {
> +        if ((rec->events >> RTEMS_CAPTURE_EVENT_START) == 0)
> +          rtems_caputre_cli_print_record_task( rec );
> +        else {
> +          uint64_t diff = 0;
> +          if (last_t)
> +            diff = rec->time - last_t;
> +          last_t = rec->time;
> +
> +          rtems_caputure_cli_print_record_std( rec, diff );
>           }
>         }
>         ptr += rec->size;
> diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c
> index 64d2699..6c839d9 100644
> --- a/cpukit/libmisc/capture/capture.c
> +++ b/cpukit/libmisc/capture/capture.c
> @@ -27,7 +27,6 @@
>
>   #include <stdlib.h>
>   #include <string.h>
> -#include <rtems/rtems/tasksimpl.h>
>
>   #include "captureimpl.h"
>   #include "capture_buffer.h"
> @@ -64,10 +63,9 @@
>   /*
>    * RTEMS Capture Data.
>    */
> -static rtems_capture_buffer_t         capture_records = {NULL, 0, 0, 0, 0, 0};
> +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_task_t*    capture_tasks;
>   static rtems_capture_control_t* capture_controls;
>   static int                      capture_extension_index;
>   static rtems_capture_timestamp  capture_timestamp;
> @@ -118,18 +116,6 @@ 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.
> @@ -207,7 +193,7 @@ rtems_capture_dup_name (rtems_name* dst, rtems_name src)
>    */
>   static inline bool
>   rtems_capture_by_in_to (uint32_t                 events,
> -                        rtems_capture_task_t*    by,
> +                        rtems_tcb*               by,
>                           rtems_capture_control_t* to)
>   {
>     uint32_t valid_mask = RTEMS_CAPTURE_CONTROL_FROM_MASK (0);
> @@ -235,7 +221,8 @@ rtems_capture_by_in_to (uint32_t                 events,
>          * not set.
>          */
>         if (rtems_capture_match_name_id (to->by[i].name, to->by[i].id,
> -                                       by->name, by->id))
> +                                       rtems_capture_task_name( by ),
> +                                       by->Object.id))
>           return 1;
>       }
>
> @@ -247,47 +234,6 @@ rtems_capture_by_in_to (uint32_t                 events,
>   }
>
>   /*
> - * This function raises the reference count.
> - */
> -static inline void
> -rtems_capture_refcount_up (rtems_capture_task_t* task)
> -{
> -  task->refcount++;
> -}
> -
> -/*
> - * This function lowers the reference count and if the count
> - * reaches 0 the task control block is returned to the heap.
> - */
> -static inline void
> -rtems_capture_refcount_down (rtems_capture_task_t* task)
> -{
> -  if (task->refcount)
> -    task->refcount--;
> -}
> -
> -/*
> - * This function setups a stack so its usage can be monitored.
> - */
> -void
> -rtems_capture_init_stack_usage (rtems_capture_task_t* task)
> -{
> -  if (task->tcb)
> -  {
> -    uint32_t* s;
> -    uint32_t  i;
> -
> -    task->stack_size  = task->tcb->Start.Initial_stack.size;
> -    task->stack_clean = task->stack_size;
> -
> -    s = task->tcb->Start.Initial_stack.area;
> -
> -    for (i = 0; i < (task->stack_size - 128); i += 4)
> -      *(s++) = 0xdeaddead;
> -  }
> -}
> -
> -/*
>    * This function searches for a trigger given a name.
>    */
>   static inline rtems_capture_control_t*
> @@ -302,6 +248,27 @@ rtems_capture_find_control (rtems_name name, rtems_id id)
>   }
>
>   /*
> + * This function checks if a new control structure matches
> + * the given task and sets the control if it does.
> + */
> +static void
> +rtems_capture_initialize_control (rtems_tcb *tcb)
> +{
> +  rtems_name                   name;
> +  rtems_capture_control_t*     control;
> +
> +  /*
> +   * We need to scan the default control list to initialise
> +   * this control.
> +   */
> +  rtems_object_get_classic_name( tcb->Object.id, &name );
> +  control = capture_controls;
> +  if (rtems_capture_match_name_id (control->name, control->id,
> +                                   name, tcb->Object.id))
> +    tcb->capture.control = control;
> +}
> +
> +/*
>    * This function creates a capture control for the capture engine.
>    */
>   static inline rtems_capture_control_t*
> @@ -309,7 +276,6 @@ rtems_capture_create_control (rtems_name name, rtems_id id)
>   {
>     rtems_interrupt_lock_context lock_context;
>     rtems_capture_control_t*     control;
> -  rtems_capture_task_t*        task;
>
>     if ((name == 0) && (id == 0))
>       return NULL;
> @@ -339,14 +305,7 @@ rtems_capture_create_control (rtems_name name, rtems_id id)
>
>       control->next    = capture_controls;
>       capture_controls = control;
> -
> -    /*
> -     * We need to scan the task list as set the control to the
> -     * tasks.
> -     */
> -    for (task = capture_tasks; task != NULL; task = task->forw)
> -      if (rtems_capture_match_name_id (name, id, task->name, task->id))
> -        task->control = control;
> +    rtems_iterate_over_all_threads (rtems_capture_initialize_control);
>
>       rtems_interrupt_lock_release (&capture_lock, &lock_context);
>     }
> @@ -354,130 +313,73 @@ rtems_capture_create_control (rtems_name name, rtems_id id)
>     return control;
>   }
>
> -/*
> - * This function create the task control.
> - */
> -rtems_capture_task_t*
> -rtems_capture_create_capture_task (rtems_tcb* new_task)
> +void rtems_capture_record_task( rtems_tcb* tcb )
>   {
> -  rtems_interrupt_lock_context lock_context;
> -  rtems_capture_task_t*        task;
> -  rtems_capture_control_t*     control;
> -  rtems_name                   name;
> -  rtems_capture_time_t         time;
> -  bool                         ok;
> -
> -  ok = rtems_workspace_allocate (sizeof (*task), (void **) &task);
> -
> -  if (!ok)
> -  {
> -    capture_flags |= RTEMS_CAPTURE_NO_MEMORY;
> -    return NULL;
> -  }
> -
> -  /*
> -   * Get the current time.
> -   */
> -  rtems_capture_get_time (&time);
> +  rtems_capture_control_t*    control;
> +  rtems_capture_task_record_t rec;
> +  void*                       ptr;
>
> +  rtems_object_get_classic_name( tcb->Object.id, &rec.name );
> +
>     /*
> -   * Check the type of name the object has.
> +   * We need to scan the default control list to initialise
> +   * this control if it is a new task.
>      */
>
> -  rtems_object_get_classic_name( new_task->Object.id, &name );
> -
> -  rtems_capture_dup_name (&task->name, name);
> -
> -  task->id               = new_task->Object.id;
> -  task->flags            = 0;
> -  task->in               = 0;
> -  task->refcount         = 0;
> -  task->out              = 0;
> -  task->tcb              = new_task;
> -  task->time             = 0;
> -  task->time_in          = time;
> -  task->control          = 0;
> -  task->last_time        = 0;
> -
> -  task->tcb->extensions[capture_extension_index] = task;
> -
> -  task->start_priority = _RTEMS_tasks_Priority_from_Core(
> -                           new_task->Start.initial_priority
> -                         );
> -  task->stack_size     = new_task->Start.Initial_stack.size;
> -  task->stack_clean    = task->stack_size;
> -
> -  rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
> -
> -  task->forw    = capture_tasks;
> -  if (task->forw)
> -    task->forw->back = task;
> -  task->back    = NULL;
> -  capture_tasks = task;
> +  if (tcb->capture.control == NULL) {
> +    for (control = capture_controls; control != NULL; control = control->next)
> +      if (rtems_capture_match_name_id (control->name, control->id,
> +                                       rec.name, tcb->Object.id))
> +        tcb->capture.control = control;
> +  }
>
> -  rtems_interrupt_lock_release (&capture_lock, &lock_context);
> +  rec.stack_size = tcb->Start.Initial_stack.size;
> +  rec.start_priority = _RTEMS_tasks_Priority_from_Core(
> +    tcb->Start.initial_priority
> +  );
>
> +  tcb->capture.flags |= RTEMS_CAPTURE_RECORD_TASK;
> +
>     /*
> -   * We need to scan the default control list to initialise
> -   * this control.
> +   *  Log the task information. The first time a task is
> +   *  seen a record is logged.  This record can be identified
> +   *  by a 0 in the event identifier.
>      */
>
> -  for (control = capture_controls; control != NULL; control = control->next)
> -    if (rtems_capture_match_name_id (control->name, control->id,
> -                                     task->name, task->id))
> -      task->control = control;
> -
> -  return 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.
> - */
> -void
> -rtems_capture_destroy_capture_task (rtems_capture_task_t* task)
> -{
> -  if (task)
> -  {
> -    rtems_interrupt_lock_context lock_context;
> -
> -    rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
> -
> -    if (task->tcb || task->refcount)
> -      task = 0;
> -
> -    if (task)
> -    {
> -      if (task->forw)
> -        task->forw->back = task->back;
> -      if (task->back)
> -        task->back->forw = task->forw;
> -      else
> -        capture_tasks = task->forw;
> -    }
> -
> -    rtems_interrupt_lock_release (&capture_lock, &lock_context);
> -
> -    rtems_workspace_free (task);
> -  }
> +  rtems_capture_begin_add_record (tcb, 0, sizeof(rec), &ptr);
> +  ptr = rtems_capture_append_to_record(
> +    ptr,
> +    &rec.name,
> +    sizeof( rec.name )
> +  );
> +  ptr = rtems_capture_append_to_record(
> +    ptr,
> +    &rec.start_priority,
> +    sizeof( rec.start_priority)
> +  );
> +  ptr = rtems_capture_append_to_record(
> +    ptr,
> +    &rec.stack_size,
> +    sizeof( rec.stack_size)
> +  );
> +  rtems_capture_end_add_record ( ptr );
>   }
>
>   /*
>    * This function indicates if data should be filtered from the
>    * log.
>    */
> -bool rtems_capture_filter( rtems_capture_task_t* task,
> +bool rtems_capture_filter( rtems_tcb*            tcb,
>                              uint32_t              events)
>   {
> -  if (task &&
> +  if (tcb &&
>         ((capture_flags &
>           (RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_ONLY_MONITOR)) ==
>          RTEMS_CAPTURE_TRIGGERED))
>     {
>       rtems_capture_control_t* control;
>
> -    control = task->control;
> +    control = tcb->capture.control;
>
>       /*
>        * Capture the record if we have an event that is always
> @@ -485,8 +387,8 @@ bool rtems_capture_filter( rtems_capture_task_t* task,
>        * watch ceiling, and the global watch or task watch is enabled.
>        */
>       if ((events & RTEMS_CAPTURE_RECORD_EVENTS) ||
> -        ((task->tcb->real_priority >= capture_ceiling) &&
> -         (task->tcb->real_priority <= capture_floor) &&
> +        ((tcb->real_priority >= capture_ceiling) &&
> +         (tcb->real_priority <= capture_floor) &&
>            ((capture_flags & RTEMS_CAPTURE_GLOBAL_WATCH) ||
>             (control && (control->flags & RTEMS_CAPTURE_WATCH)))))
>       {
> @@ -501,7 +403,7 @@ bool rtems_capture_filter( rtems_capture_task_t* task,
>    * This function records a capture record into the capture buffer.
>    */
>   void *
> -rtems_capture_record_open (rtems_capture_task_t*         task,
> +rtems_capture_record_open (rtems_tcb*                    tcb,
>                              uint32_t                      events,
>                              size_t                        size,
>                              rtems_interrupt_lock_context* lock_context)
> @@ -516,18 +418,17 @@ rtems_capture_record_open (rtems_capture_task_t*         task,
>     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));
> +    capture_in->size    = size;
> +    capture_in->task_id = tcb->Object.id;
> +    capture_in->events  = (events |
> +                          (tcb->real_priority) |
> +                          (tcb->current_priority << 8));
>
>       if ((events & RTEMS_CAPTURE_RECORD_EVENTS) == 0)
> -      task->flags |= RTEMS_CAPTURE_TRACED;
> +      tcb->capture.flags |= RTEMS_CAPTURE_TRACED;
>
>       rtems_capture_get_time (&capture_in->time);
>
> -    rtems_capture_refcount_up (task);
>       ptr = ptr + sizeof(*capture_in);
>     }
>     else
> @@ -546,10 +447,11 @@ void rtems_capture_record_close( void *rec, rtems_interrupt_lock_context* lock_c
>    * cause of a trigger.
>    */
>   bool
> -rtems_capture_trigger (rtems_capture_task_t* ft,
> -                       rtems_capture_task_t* tt,
> -                       uint32_t              events)
> +rtems_capture_trigger (rtems_tcb* ft,
> +                       rtems_tcb* tt,
> +                       uint32_t   events)
>   {
> +
>     /*
>      * If we have not triggered then see if this is a trigger condition.
>      */
> @@ -563,18 +465,18 @@ rtems_capture_trigger (rtems_capture_task_t* ft,
>
>       if (ft)
>       {
> -      fc = ft->control;
> +      fc = ft->capture.control;
>         if (fc)
>           from_events = fc->from_triggers & events;
>       }
>
>       if (tt)
>       {
> -      tc = tt->control;
> +      tc = tt->capture.control;
>         if (tc)
>         {
>           to_events = tc->to_triggers & events;
> -        if (ft && tc->by_valid)
> +        if (ft && tc->by_valid)
>             from_to_events = tc->by_triggers & events;
>         }
>       }
> @@ -633,7 +535,6 @@ rtems_capture_open (uint32_t   size, rtems_capture_timestamp timestamp __attribu
>
>     capture_count   = 0;
>     capture_flags   = 0;
> -  capture_tasks   = NULL;
>     capture_ceiling = 0;
>     capture_floor   = 255;
>
> @@ -659,7 +560,6 @@ rtems_status_code
>   rtems_capture_close (void)
>   {
>     rtems_interrupt_lock_context lock_context;
> -  rtems_capture_task_t*        task;
>     rtems_capture_control_t*     control;
>     rtems_status_code            sc;
>
> @@ -685,17 +585,6 @@ rtems_capture_close (void)
>     if (sc != RTEMS_SUCCESSFUL)
>       return sc;
>
> -  task = capture_tasks;
> -
> -  while (task)
> -  {
> -    rtems_capture_task_t* delete = task;
> -    task = task->forw;
> -    rtems_workspace_free (delete);
> -  }
> -
> -  capture_tasks = NULL;
> -
>     control = capture_controls;
>
>     while (control)
> @@ -715,15 +604,6 @@ rtems_capture_close (void)
>     return RTEMS_SUCCESSFUL;
>   }
>
> -/*
> - * This function allows control of tracing at a global level.
> - */
> -static void
> -rtems_capture_task_setup (Thread_Control *tcb)
> -{
> -  rtems_capture_create_capture_task (tcb);
> -}
> -
>   rtems_status_code
>   rtems_capture_control (bool enable)
>   {
> @@ -742,8 +622,6 @@ rtems_capture_control (bool enable)
>     else
>       capture_flags &= ~RTEMS_CAPTURE_ON;
>
> -  rtems_iterate_over_all_threads (rtems_capture_task_setup);
> -
>     rtems_interrupt_lock_release (&capture_lock, &lock_context);
>
>     return RTEMS_SUCCESSFUL;
> @@ -778,6 +656,16 @@ rtems_capture_monitor (bool enable)
>   }
>
>   /*
> + * This function clears the capture trace flag in the tcb.
> + */
> +static void
> +rtems_capture_flush_tcb (rtems_tcb *tcb)
> +{
> +  tcb->capture.flags &= ~RTEMS_CAPTURE_TRACED;
> +}
> +
> +
> +/*
>    * This function flushes the capture buffer. The prime parameter allows the
>    * capture engine to also be primed again.
>    */
> @@ -785,15 +673,10 @@ rtems_status_code
>   rtems_capture_flush (bool prime)
>   {
>     rtems_interrupt_lock_context lock_context;
> -  rtems_capture_task_t*        task;
>
>     rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
>
> -  for (task = capture_tasks; task != NULL; task = task->forw)
> -  {
> -    task->flags &= ~RTEMS_CAPTURE_TRACED;
> -    task->refcount = 0;
> -  }
> +  rtems_iterate_over_all_threads (rtems_capture_flush_tcb);
>
>     if (prime)
>       capture_flags &= ~(RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_OVERFLOW);
> @@ -805,15 +688,6 @@ rtems_capture_flush (bool prime)
>
>     rtems_interrupt_lock_release (&capture_lock, &lock_context);
>
> -  task = capture_tasks;
> -
> -  while (task)
> -  {
> -    rtems_capture_task_t* check = task;
> -    task = task->forw;
> -    rtems_capture_destroy_capture_task (check);
> -  }
> -
>     return RTEMS_SUCCESSFUL;
>   }
>
> @@ -856,7 +730,6 @@ rtems_capture_watch_del (rtems_name name, rtems_id id)
>     rtems_interrupt_lock_context lock_context;
>     rtems_capture_control_t*     control;
>     rtems_capture_control_t**    prev_control;
> -  rtems_capture_task_t*        task;
>     bool                         found = false;
>
>     /*
> @@ -870,10 +743,6 @@ rtems_capture_watch_del (rtems_name name, rtems_id id)
>       {
>         rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
>
> -      for (task = capture_tasks; task != NULL; task = task->forw)
> -        if (task->control == control)
> -          task->control = 0;
> -
>         *prev_control = control->next;
>
>         rtems_interrupt_lock_release (&capture_lock, &lock_context);
> @@ -1373,8 +1242,6 @@ rtems_capture_release (uint32_t count)
>     {
>       rec = (rtems_capture_record_t*) ptr;
>       ptr_size += rec->size;
> -    rtems_capture_refcount_down (rec->task);
> -    rtems_capture_destroy_capture_task (rec->task);
>       ptr += rec->size;
>     }
>
> @@ -1416,48 +1283,6 @@ rtems_capture_event_text (int event)
>   }
>
>   /*
> - * This function returns the head of the list of tasks that the
> - * capture engine has detected.
> - */
> -rtems_capture_task_t*
> -rtems_capture_get_task_list (void)
> -{
> -  return capture_tasks;
> -}
> -
> -/*
> - * This function updates the stack usage. The task control block
> - * is updated.
> - */
> -uint32_t
> -rtems_capture_task_stack_usage (rtems_capture_task_t* task)
> -{
> -  if (task->tcb)
> -  {
> -    uint32_t* st;
> -    uint32_t* s;
> -
> -    /*
> -     * @todo: Assumes all stacks move the same way.
> -     */
> -    st = task->tcb->Start.Initial_stack.area + task->stack_size;
> -    s  = task->tcb->Start.Initial_stack.area;
> -
> -    while (s < st)
> -    {
> -      if (*s != 0xdeaddead)
> -        break;
> -      s++;
> -    }
> -
> -    task->stack_clean =
> -      s - (uint32_t*) task->tcb->Start.Initial_stack.area;
> -  }
> -
> -  return task->stack_clean;
> -}
> -
> -/*
>    * This function returns the head of the list of control in the
>    * capture engine.
>    */
> diff --git a/cpukit/libmisc/capture/capture.h b/cpukit/libmisc/capture/capture.h
> index 8bc2fc3..bd07922 100644
> --- a/cpukit/libmisc/capture/capture.h
> +++ b/cpukit/libmisc/capture/capture.h
> @@ -46,6 +46,7 @@ extern "C" {
>   #endif
>
>   #include <rtems.h>
> +#include <rtems/rtems/tasksimpl.h>
>
>   /**
>    * The number of tasks in a trigger group.
> @@ -137,47 +138,10 @@ typedef struct rtems_capture_control_s
>                                        RTEMS_CAPTURE_EXITTED)
>
>   /**
> - * @brief Catpure task control
> - *
> - * RTEMS capture control provdes the information about a task, along
> - * with its trigger state. The control is referenced by each
> - * capture record. This is information neeed by the decoder. The
> - * capture record cannot assume the task will exist when the record is
> - * dumped via the target interface so task info needed for tracing is
> - * copied and held here. Once the references in the trace buffer
> - * have been removed and the task is deleted this structure is
> - * released back to the heap.
> - *
> - * The inline helper functions provide more details about the info
> - * contained in this structure.
> - *
> - * Note, the tracer code exploits the fact an rtems_name is a
> - * 32bit value.
> - */
> -typedef struct rtems_capture_task_s
> -{
> -  rtems_name                   name;
> -  rtems_id                     id;
> -  uint32_t                     flags;
> -  uint32_t                     refcount;
> -  rtems_tcb*                   tcb;
> -  uint32_t                     in;
> -  uint32_t                     out;
> -  rtems_task_priority          start_priority;
> -  uint32_t                     stack_size;
> -  uint32_t                     stack_clean;
> -  rtems_capture_time_t         time;
> -  rtems_capture_time_t         time_in;
> -  rtems_capture_time_t         last_time;
> -  rtems_capture_control_t*     control;
> -  struct rtems_capture_task_s* forw;
> -  struct rtems_capture_task_s* back;
> -} rtems_capture_task_t;
> -
> -/**
>    * Task flags.
>    */
> -#define RTEMS_CAPTURE_TRACED  (1U << 0)
> +#define RTEMS_CAPTURE_TRACED      (1U << 0)
> +#define RTEMS_CAPTURE_RECORD_TASK (1U << 1)
>
>   /*
>    * @brief Capture record.
> @@ -188,12 +152,27 @@ typedef struct rtems_capture_task_s
>    */
>   typedef struct rtems_capture_record_s
>   {
> -  rtems_capture_task_t* task;
>     uint32_t              events;
>     rtems_capture_time_t  time;
>     size_t                size;
> +  rtems_id              task_id;
>   } rtems_capture_record_t;
>
> +/*
> + * @brief Capture task record.
> + *
> + * This is a record that is written into
> + * the buffer. The events includes the priority of the task
> + * at the time of the context switch.
> + */
> +typedef struct rtems_capture_task_record_s
> +{
> +  rtems_capture_record_t rec;
> +  rtems_name             name;
> +  rtems_task_priority    start_priority;
> +  uint32_t               stack_size;
> +} rtems_capture_task_record_t;
> +
>   /**
>    * The capture record event flags.
>    */
> @@ -619,49 +598,24 @@ const char*
>   rtems_capture_event_text (int event);
>
>   /**
> - * @brief Capture get task list.
> - *
> - * This function returns the head of the list of tasks that the
> - * capture engine has detected.
> - *
> - * @retval  This function returns the head of the list of tasks that
> - *          the capture engine has detected.
> - */
> -rtems_capture_task_t*
> -rtems_capture_get_task_list (void);
> -
> -/**
> - * @brief Capture get next task in list.
> - *
> - * This function returns the pointer to the next task in the list. The
> - * pointer NULL terminates the list.
> - *
> - * @param[in] task The capture task to get the next entry from.
> + * @brief Capture record task.
>    *
> - * @retval This function returns the pointer to the next task in the list. The
> - * pointer NULL terminates the list.
> + * This function records a new capture task record.
> + *
> + * @param[in] tcb is the task control block for the task
>    */
> -static inline rtems_capture_task_t*
> -rtems_capture_next_task (rtems_capture_task_t* task)
> -{
> -  return task->forw;
> -}
> +void rtems_capture_record_task( rtems_tcb* tcb );
>
>   /**
> - * @brief Capture is valid task control block
> + * @brief Capture task recorded
>    *
> - * This function returns true if the task control block points to
> - * a valid task.
> + * This function returns true if this task information has been
> + * recorded.
>    *
> - * @param[in] task The capture task.
> - *
> - * @retval This function returns true if the task control block points to
> - * a valid task. Otherwise, it returns false.
> + * @param[in] tcb is the task control block for the task
>    */
> -static inline bool
> -rtems_capture_task_valid (rtems_capture_task_t* task)
> -{
> -  return task->tcb != NULL;
> +static inline bool rtems_capture_task_recorded( rtems_tcb* tcb ) {
> +  return ( (tcb->capture.flags & RTEMS_CAPTURE_RECORD_TASK) != 0 );
>   }
>
>   /**
> @@ -674,9 +628,9 @@ rtems_capture_task_valid (rtems_capture_task_t* task)
>    * @retval This function returns the task id.
>    */
>   static inline rtems_id
> -rtems_capture_task_id (rtems_capture_task_t* task)
> +rtems_capture_task_id (rtems_tcb* tcb)
>   {
> -  return task->id;
> +  return tcb->Object.id;
>   }
>
>   /**
> @@ -689,10 +643,10 @@ rtems_capture_task_id (rtems_capture_task_t* task)
>    * @retval This function returns the task state.
>    */
>   static inline States_Control
> -rtems_capture_task_state (rtems_capture_task_t* task)
> +rtems_capture_task_state (rtems_tcb* tcb)
>   {
> -  if (rtems_capture_task_valid (task))
> -    return task->tcb->current_state;
> +  if (tcb)
> +    return tcb->current_state;
>     return 0;
>   }
>
> @@ -706,9 +660,11 @@ rtems_capture_task_state (rtems_capture_task_t* task)
>    * @retval This function returns the task name.
>    */
>   static inline rtems_name
> -rtems_capture_task_name (rtems_capture_task_t* task)
> +rtems_capture_task_name (rtems_tcb* tcb)
>   {
> -  return task->name;
> +  rtems_name  name;
> +  rtems_object_get_classic_name( tcb->Object.id, &name );
> +  return name;
>   }
>
>   /**
> @@ -721,9 +677,9 @@ rtems_capture_task_name (rtems_capture_task_t* task)
>    * @retval This function returns the task flags.
>    */
>   static inline uint32_t
> -rtems_capture_task_flags (rtems_capture_task_t* task)
> +rtems_capture_task_flags (rtems_tcb* tcb)
>   {
> -  return task->flags;
> +  return tcb->capture.flags;
>   }
>
>   /**
> @@ -736,9 +692,9 @@ rtems_capture_task_flags (rtems_capture_task_t* task)
>    * @retval This function returns the task control if present.
>    */
>   static inline rtems_capture_control_t*
> -rtems_capture_task_control (rtems_capture_task_t* task)
> +rtems_capture_task_control (rtems_tcb* tcb)
>   {
> -  return task->control;
> +  return tcb->capture.control;
>   }
>
>   /**
> @@ -751,45 +707,12 @@ rtems_capture_task_control (rtems_capture_task_t* task)
>    * @retval This function returns the task control flags if a control is present.
>    */
>   static inline uint32_t
> -rtems_capture_task_control_flags (rtems_capture_task_t* task)
> +rtems_capture_task_control_flags (rtems_tcb* tcb)
>   {
> -  if (!task->control)
> +  rtems_capture_control_t*  control = tcb->capture.control;
> +  if (!control)
>       return 0;
> -  return task->control->flags;
> -}
> -
> -/**
> - * @brief Capture get number of times task switched in.
> - *
> - * This function returns the number of times the task has
> - * been switched into context.
> - *
> - * @param[in] task The capture task.
> - *
> - * @retval This function returns the number of times the task has
> - * been switched into context.
> - */
> -static inline uint32_t
> -rtems_capture_task_switched_in (rtems_capture_task_t* task)
> -{
> -  return task->in;
> -}
> -
> -/**
> - * @brief Capture get number of times task switched out.
> - *
> - * This function returns the number of times the task has
> - * been switched out of context.
> - *
> - * @param[in] task The capture task.
> - *
> - * @retval This function returns the number of times the task has
> - * been switched out of context.
> - */
> -static inline uint32_t
> -rtems_capture_task_switched_out (rtems_capture_task_t* task)
> -{
> -  return task->out;
> +  return control->flags;
>   }
>
>   /**
> @@ -804,9 +727,11 @@ rtems_capture_task_switched_out (rtems_capture_task_t* task)
>    * to track where the task's priority goes.
>    */
>   static inline rtems_task_priority
> -rtems_capture_task_start_priority (rtems_capture_task_t* task)
> +rtems_capture_task_start_priority (rtems_tcb* tcb)
>   {
> -  return task->start_priority;
> +  return _RTEMS_tasks_Priority_from_Core(
> +    tcb->Start.initial_priority
> +  );
>   }
>
>   /**
> @@ -819,11 +744,9 @@ rtems_capture_task_start_priority (rtems_capture_task_t* task)
>    * @retval This function returns the tasks real priority.
>    */
>   static inline rtems_task_priority
> -rtems_capture_task_real_priority (rtems_capture_task_t* task)
> +rtems_capture_task_real_priority (rtems_tcb* tcb)
>   {
> -  if (rtems_capture_task_valid (task))
> -    return task->tcb->real_priority;
> -  return 0;
> +  return tcb->real_priority;
>   }
>
>   /**
> @@ -836,113 +759,9 @@ rtems_capture_task_real_priority (rtems_capture_task_t* task)
>    * @retval This function returns the tasks current priority.
>    */
>   static inline rtems_task_priority
> -rtems_capture_task_curr_priority (rtems_capture_task_t* task)
> +rtems_capture_task_curr_priority (rtems_tcb* tcb)
>   {
> -  if (rtems_capture_task_valid (task))
> -    return task->tcb->current_priority;
> -  return 0;
> -}
> -
> -/**
> - * @brief Capture update stack usage.
> - *
> - * This function updates the stack usage. The task control block
> - * is updated.
> - *
> - * @param[in] task The capture task.
> - *
> - * @retval This function updates the stack usage. The task control block
> - * is updated.
> - */
> -uint32_t
> -rtems_capture_task_stack_usage (rtems_capture_task_t* task);
> -
> -/**
> - * @brief Capture get stack size.
> - *
> - * This function returns the task's stack size.
> - *
> - * @param[in] task The capture task.
> - *
> - * @retval This function returns the task's stack size.
> - */
> -static inline uint32_t
> -rtems_capture_task_stack_size (rtems_capture_task_t* task)
> -{
> -  return task->stack_size;
> -}
> -
> -/**
> - * @brief Capture get stack used.
> - *
> - * This function returns the amount of stack used.
> - *
> - * @param[in] task The capture task.
> - *
> - * @retval This function returns the amount of stack used.
> - */
> -static inline uint32_t
> -rtems_capture_task_stack_used (rtems_capture_task_t* task)
> -{
> -  return task->stack_size - task->stack_clean;
> -}
> -
> -/**
> - * @brief Capture get task execution time.
> - *
> - * This function returns the current execution time.
> - *
> - * @param[in] task The capture task.
> - *
> - * @retval This function returns the current execution time.
> - */
> -static inline uint64_t
> -rtems_capture_task_time (rtems_capture_task_t* task)
> -{
> -  return task->time;
> -}
> -
> -/**
> - * @brief Capture get delta in execution time.
> - *
> - * This function returns the execution time as a different between the
> - * last time the detla time was and now.
> - *
> - * @param[in] task The capture task.
> - *
> - * @retval This function returns the execution time as a different between the
> - * last time the detla time was and now.
> - */
> -static inline uint64_t
> -rtems_capture_task_delta_time (rtems_capture_task_t* task)
> -{
> -  uint64_t t = task->time - task->last_time;
> -  task->last_time = task->time;
> -  return t;
> -}
> -
> -/**
> - * @brief Capture get task count.
> - *
> - * This function returns the number of tasks the capture
> - * engine knows about.
> - *
> - * @retval This function returns the number of tasks the capture
> - * engine knows about.
> - */
> -static inline uint32_t
> -rtems_capture_task_count (void)
> -{
> -  rtems_capture_task_t* task = rtems_capture_get_task_list ();
> -  uint32_t              count = 0;
> -
> -  while (task)
> -  {
> -    count++;
> -    task = rtems_capture_next_task (task);
> -  }
> -
> -  return count;
> +  return tcb->current_priority;
>   }
>
>   /**
> @@ -1070,7 +889,7 @@ rtems_capture_control_all_by_triggers (rtems_capture_control_t* control)
>    * This function returns the control valid BY flags.
>    *
>    * @param[in] control The capture control.
> - * @param[in] slot The XXX.
> + * @param[in] slot The slot.
>    *
>    * @retval This function returns the control valid BY flags.
>    */
> @@ -1086,7 +905,7 @@ rtems_capture_control_by_valid (rtems_capture_control_t* control, int slot)
>    * This function returns the control @a by task name.
>    *
>    * @param[in] control The capture control.
> - * @param[in] by The XXX.
> + * @param[in] by The by index.
>    *
>    * @retval This function returns the control @a by task name.
>    */
> diff --git a/cpukit/libmisc/capture/capture_user_extension.c b/cpukit/libmisc/capture/capture_user_extension.c
> index 4236d8c..4c7bc1d 100644
> --- a/cpukit/libmisc/capture/capture_user_extension.c
> +++ b/cpukit/libmisc/capture/capture_user_extension.c
> @@ -84,20 +84,20 @@ 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_tcb*    tcb,
> +  uint32_t      events
>   )
>   {
>     rtems_capture_record_t*  rec;
> +  void*                    ptr;
> +  size_t                   size = sizeof(*rec);
>
> -  if (rtems_capture_filter( task, events) )
> +  if (rtems_capture_filter( tcb, events) )
>       return;
> -
> -  rtems_capture_begin_add_record (task, events, sizeof(*rec), &rec);
>
> -  rtems_capture_end_add_record ( rec );
> +  rtems_capture_begin_add_record (tcb, events, size, &ptr);
> +  rtems_capture_end_add_record ( ptr );
>   }
>
>
> @@ -133,27 +133,21 @@ rtems_status_code rtems_capture_user_extension_close(void)
>    * 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_create_task (rtems_tcb* ct,
> +                           rtems_tcb* nt)

Any specific reason to shorten the names ?

>   {
> -  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);
> +  if (!rtems_capture_task_recorded (ct))
> +    rtems_capture_record_task (ct);
>
>     /*
>      * Create the new task's capture control block.
>      */
> -  nt = rtems_capture_create_capture_task (new_task);
> +  rtems_capture_record_task (nt);
>
>     if (rtems_capture_trigger (ct, nt, RTEMS_CAPTURE_CREATE))
>     {
> @@ -168,147 +162,85 @@ rtems_capture_create_task (rtems_tcb* current_task,
>    * This function is called when a task is started.
>    */
>   static void
> -rtems_capture_start_task (rtems_tcb* current_task,
> -                          rtems_tcb* started_task)
> +rtems_capture_start_task (rtems_tcb* ct,
> +                          rtems_tcb* st)
>   {
>     /*
> -   * 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 (!rtems_capture_task_recorded (ct))
> +    rtems_capture_record_task (ct);
>
>     if (st == NULL)
> -    st = rtems_capture_create_capture_task (started_task);
> +    rtems_capture_record_task (st);
>
>     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)
> +rtems_capture_restart_task (rtems_tcb* ct,
> +                            rtems_tcb* rt)
>   {
>     /*
> -   * 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 (!rtems_capture_task_recorded (ct))
> +    rtems_capture_record_task (ct);
>
> -  if (rt == NULL)
> -    rt = rtems_capture_create_capture_task (restarted_task);
> +  if (!rtems_capture_task_recorded (rt))
> +    rtems_capture_record_task (rt);
>
>     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)
> +rtems_capture_delete_task (rtems_tcb* ct,
> +                           rtems_tcb* dt)
>   {
> -  /*
> -   * 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 (!rtems_capture_task_recorded (ct))
> +    rtems_capture_record_task (ct);
>
> -  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_task_recorded (dt))
> +    rtems_capture_record_task (dt);
>
>     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)
> +rtems_capture_begin_task (rtems_tcb* bt)
>   {
>     /*
> -   * 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_task_recorded (bt))
> +    rtems_capture_record_task (bt);
>
>     if (rtems_capture_trigger (NULL, bt, RTEMS_CAPTURE_BEGIN))
>       rtems_capture_record (bt, RTEMS_CAPTURE_BEGIN_EVENT);
> @@ -319,69 +251,46 @@ rtems_capture_begin_task (rtems_tcb* begin_task)
>    * returned rather than was deleted.
>    */
>   static void
> -rtems_capture_exitted_task (rtems_tcb* exitted_task)
> +rtems_capture_exitted_task (rtems_tcb* et)
>   {
>     /*
> -   * 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_task_recorded (et))
> +    rtems_capture_record_task (et);
>
>     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)
> +rtems_capture_terminated_task (rtems_tcb* tt)
>   {
>     /*
> -   * 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_task_recorded (tt))
> +    rtems_capture_record_task (tt);
>
>     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)
> +rtems_capture_switch_task (rtems_tcb* ct,
> +                           rtems_tcb* ht)
>   {
>     uint32_t flags = rtems_capture_get_flags();
> -  int      index = rtems_capture_get_extension_index();
>
>     /*
>      * Only perform context switch trace processing if tracing is
> @@ -391,33 +300,11 @@ rtems_capture_switch_task (rtems_tcb* current_task,
>     {
>       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 (!rtems_capture_task_recorded (ct))
> +      rtems_capture_record_task (ct);
>
> -    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);
> +    if (!rtems_capture_task_recorded (ht))
> +      rtems_capture_record_task (ht);
>
>       /*
>        * Update the execution time. Assume the time will not overflow
> @@ -425,24 +312,6 @@ rtems_capture_switch_task (rtems_tcb* current_task,
>        */
>       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);
> diff --git a/cpukit/libmisc/capture/captureimpl.h b/cpukit/libmisc/capture/captureimpl.h
> index fa36688..3c2f6c3 100644
> --- a/cpukit/libmisc/capture/captureimpl.h
> +++ b/cpukit/libmisc/capture/captureimpl.h
> @@ -116,29 +116,6 @@ rtems_status_code rtems_capture_user_extension_open(void);
>   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
> @@ -151,9 +128,9 @@ rtems_capture_task_t* rtems_capture_create_capture_task (rtems_tcb* new_task);
>    * @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);
> +bool rtems_capture_trigger (rtems_tcb* ft,
> +                            rtems_tcb* tt,
> +                            uint32_t   events);
>
>   /**
>    * @brief Capture append to record
> @@ -188,7 +165,7 @@ static void *rtems_capture_append_to_record(void*  rec,
>    * filtered from the log.  It returns false if this data
>    * should be logged.
>    */
> -bool rtems_capture_filter( rtems_capture_task_t* task,
> +bool rtems_capture_filter( rtems_tcb*            task,
>                              uint32_t              events);
>   /**
>    * @brief Capture begin add record.
> @@ -238,26 +215,6 @@ static inline void *rtems_capture_append_to_record(void*  rec,
>     } while (0)
>
>   /**
> - * @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
> @@ -287,7 +244,7 @@ void rtems_capture_get_time (rtems_capture_time_t* time);
>    * @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,
> +void* rtems_capture_record_open (rtems_tcb*                    task,
>                                    uint32_t                      events,
>                                    size_t                        size,
>                                    rtems_interrupt_lock_context* lock_context);
>



More information about the devel mailing list