diff options
-rw-r--r-- | cpukit/libmisc/capture/capture-cli.c | 379 | ||||
-rw-r--r-- | cpukit/libmisc/capture/capture.c | 361 | ||||
-rw-r--r-- | cpukit/libmisc/capture/capture.h | 295 | ||||
-rw-r--r-- | cpukit/libmisc/capture/capture_user_extension.c | 219 | ||||
-rw-r--r-- | cpukit/libmisc/capture/captureimpl.h | 53 |
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); |