summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/libmisc/capture/capture-cli.c379
-rw-r--r--cpukit/libmisc/capture/capture.c361
-rw-r--r--cpukit/libmisc/capture/capture.h295
-rw-r--r--cpukit/libmisc/capture/capture_user_extension.c219
-rw-r--r--cpukit/libmisc/capture/captureimpl.h53
5 files changed, 415 insertions, 892 deletions
diff --git a/cpukit/libmisc/capture/capture-cli.c b/cpukit/libmisc/capture/capture-cli.c
index 2aa7c9c229..e911b2eacb 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));
-
- task = rtems_capture_get_task_list ();
+ _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;
- 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;
+ Timestamp_Control last;
+ uint32_t ival, fval;
- if (!tasks[i])
+ 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);
+ /*
+ * 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_Get_time_of_last_context_switch( 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 (tasks[i]);
+ 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 64d2699f88..28fa1dda1c 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;
+ rtems_capture_control_t* control;
+ rtems_capture_task_record_t rec;
+ void* ptr;
- ok = rtems_workspace_allocate (sizeof (*task), (void **) &task);
-
- if (!ok)
- {
- capture_flags |= RTEMS_CAPTURE_NO_MEMORY;
- return NULL;
- }
+ rtems_object_get_classic_name( tcb->Object.id, &rec.name );
/*
- * Get the current time.
- */
- rtems_capture_get_time (&time);
-
- /*
- * 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);
+ 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;
+ }
- task->forw = capture_tasks;
- if (task->forw)
- task->forw->back = task;
- task->back = NULL;
- capture_tasks = task;
+ rec.stack_size = tcb->Start.Initial_stack.size;
+ rec.start_priority = _RTEMS_tasks_Priority_from_Core(
+ tcb->Start.initial_priority
+ );
- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ 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,14 +465,14 @@ 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;
@@ -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 8bc2fc3f3b..a4c3310338 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 4236d8caeb..4c7bc1d260 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)
{
- 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 fa366889b7..3c2f6c30e2 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);