[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