Since neither malloc nor rtems_workspace_alloc should be called during a task switch the capture task was changed to manage a pool of capture tasks that is allocated at open. --- cpukit/libmisc/capture/capture-cli.c | 32 ++++++++------- cpukit/libmisc/capture/capture.c | 79 +++++++++++++++++++++++++----------- cpukit/libmisc/capture/capture.h | 40 ++++++++++++++++++ 3 files changed, 113 insertions(+), 38 deletions(-)
diff --git a/cpukit/libmisc/capture/capture-cli.c b/cpukit/libmisc/capture/capture-cli.c index 9c978d2..5e4f9b4 100644 --- a/cpukit/libmisc/capture/capture-cli.c +++ b/cpukit/libmisc/capture/capture-cli.c @@ -60,7 +60,7 @@ static volatile int cli_load_thread_active; * */ -static const char* open_usage = "usage: copen [-i] size\n"; +static const char* open_usage = "usage: copen [-i] size tasks\n"; static void rtems_capture_cli_open (int argc, @@ -68,7 +68,8 @@ rtems_capture_cli_open (int argc, const rtems_monitor_command_arg_t* command_arg RC_UNUSED, bool verbose RC_UNUSED) { - uint32_t size = 0; + uint32_t size[2] = {0,0}; + int i = 0; bool enable = false; rtems_status_code sc; int arg; @@ -90,17 +91,21 @@ rtems_capture_cli_open (int argc, } else { - size = strtoul (argv[arg], 0, 0); - - if (size < 100) - { - fprintf (stdout, "error: size must be greater than or equal to 100\n"); - return; + if (i>1) + fprintf (stdout, "warning: extra parameter %s ignored\n", argv[arg]); + else { + size[i] = strtoul (argv[arg], 0, 0); + if ((i==0) && (size[i] < 100)) + { + fprintf (stdout, "error: size must be greater than or equal to 100\n"); + return; + } + i++; } } } - sc = rtems_capture_open (size, capture_timestamp); + sc = rtems_capture_open (size[0], size[1], capture_timestamp); if (sc != RTEMS_SUCCESSFUL) { @@ -1431,17 +1436,16 @@ rtems_capture_cli_trace_records (int argc, { if (event & 1) { + char name[5]; + rtems_capture_name_to_string( rec->task->name, 5, name ); + 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, " %s", name ); fprintf (stdout, " %3" PRId32 " %3" PRId32 " %s\n", (rec->events >> RTEMS_CAPTURE_REAL_PRIORITY_EVENT) & 0xff, (rec->events >> RTEMS_CAPTURE_CURR_PRIORITY_EVENT) & 0xff, diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c index 9ec07b8..6ede91d 100644 --- a/cpukit/libmisc/capture/capture.c +++ b/cpukit/libmisc/capture/capture.c @@ -108,6 +108,8 @@ static rtems_capture_record_t* capture_in; static uint32_t capture_out; static uint32_t capture_flags; static rtems_capture_task_t* capture_tasks; +static rtems_capture_task_t* capture_task_pool; +static rtems_capture_task_t* capture_task_next; static rtems_capture_control_t* capture_controls; static int capture_extension_index; static rtems_id capture_id; @@ -151,6 +153,20 @@ static const char* capture_event_text[] = "TIMESTAMP" }; +static inline void +rtems_capture_add_task_to_pool( + rtems_capture_task_t* task +) +{ + if (task) { + task->forw = capture_task_next; + if (task->forw) + task->forw->back = task; + task->back = NULL; + capture_task_next = task; + } +} + /* * This function returns the current time. If a handler is provided * by the user get the time from that. @@ -339,9 +355,9 @@ rtems_capture_create_control (rtems_name name, rtems_id id) if (control == NULL) { - bool ok = rtems_workspace_allocate (sizeof (*control), (void **) &control); + control = malloc (sizeof (*control)); - if (!ok) + if (control == NULL) { capture_flags |= RTEMS_CAPTURE_NO_MEMORY; return NULL; @@ -386,16 +402,18 @@ rtems_capture_create_capture_task (rtems_tcb* new_task) rtems_capture_control_t* control; rtems_name name; rtems_capture_time_t time; - bool ok; - - ok = rtems_workspace_allocate (sizeof (*task), (void **) &task); - if (!ok) + task = capture_task_next; + if (task == NULL) { capture_flags |= RTEMS_CAPTURE_NO_MEMORY; return NULL; } + capture_task_next = task->forw; + if (capture_task_next) + capture_task_next->back = NULL; + /* * Get the current time. */ @@ -480,7 +498,7 @@ rtems_capture_destroy_capture_task (rtems_capture_task_t* task) rtems_interrupt_lock_release (&capture_lock, &lock_context); - rtems_workspace_free (task); + rtems_capture_add_task_to_pool( task ); } } @@ -764,7 +782,8 @@ rtems_capture_delete_task (rtems_tcb* current_task, * This task's tcb will be invalid. This signals the * task has been deleted. */ - dt->tcb = 0; + if (dt) + dt->tcb = 0; rtems_capture_destroy_capture_task (dt); } @@ -935,10 +954,12 @@ rtems_capture_switch_task (rtems_tcb* current_task, * buffer. It is assumed we have a working heap at stage of initialisation. */ rtems_status_code -rtems_capture_open (uint32_t size, rtems_capture_timestamp timestamp __attribute__((unused))) +rtems_capture_open (uint32_t cr_size, uint32_t task_count, rtems_capture_timestamp timestamp __attribute__((unused))) { rtems_name name; rtems_status_code sc; + rtems_capture_task_t* task; + uint32_t i; /* * See if the capture engine is already open. @@ -947,12 +968,19 @@ rtems_capture_open (uint32_t size, rtems_capture_timestamp timestamp __attribu if (capture_records) return RTEMS_RESOURCE_IN_USE; - capture_records = malloc (size * sizeof (rtems_capture_record_t)); + capture_records = malloc (cr_size * sizeof (rtems_capture_record_t)); if (capture_records == NULL) return RTEMS_NO_MEMORY; - capture_size = size; + capture_task_pool = malloc (task_count * sizeof (*task)); + if (capture_task_pool == NULL){ + free (capture_records); + capture_records = NULL; + return RTEMS_NO_MEMORY; + } + + capture_size = cr_size; capture_count = 0; capture_in = capture_records; capture_out = 0; @@ -961,6 +989,14 @@ rtems_capture_open (uint32_t size, rtems_capture_timestamp timestamp __attribu capture_ceiling = 0; capture_floor = 255; + task = capture_task_pool; + capture_task_next = NULL; + for( i=0; i<task_count; i++) + { + rtems_capture_add_task_to_pool( task ); + task++; + } + /* * Register the user extension handlers for the CAPture Engine. */ @@ -993,7 +1029,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; @@ -1007,8 +1042,6 @@ rtems_capture_close (void) capture_flags &= ~(RTEMS_CAPTURE_ON | RTEMS_CAPTURE_ONLY_MONITOR); - capture_records = NULL; - rtems_interrupt_lock_release (&capture_lock, &lock_context); /* @@ -1021,16 +1054,11 @@ 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); - } + free( capture_task_pool ); + capture_task_pool = NULL; capture_tasks = NULL; + capture_task_next = NULL; control = capture_controls; @@ -1038,7 +1066,7 @@ rtems_capture_close (void) { rtems_capture_control_t* delete = control; control = control->next; - rtems_workspace_free (delete); + free (delete); } capture_controls = NULL; @@ -1216,7 +1244,7 @@ rtems_capture_watch_del (rtems_name name, rtems_id id) rtems_interrupt_lock_release (&capture_lock, &lock_context); - rtems_workspace_free (control); + free (control); control = *prev_control; @@ -1742,6 +1770,9 @@ rtems_capture_get_task_list (void) uint32_t rtems_capture_task_stack_usage (rtems_capture_task_t* task) { + if (!task) + return 0; + if (task->tcb) { uint32_t* st; diff --git a/cpukit/libmisc/capture/capture.h b/cpukit/libmisc/capture/capture.h index 737c73f..12458f0 100644 --- a/cpukit/libmisc/capture/capture.h +++ b/cpukit/libmisc/capture/capture.h @@ -46,6 +46,7 @@ extern "C" { #endif #include <rtems.h> +#include <ctype.h> /** * The number of tasks in a trigger group. @@ -274,6 +275,7 @@ typedef void (*rtems_capture_timestamp)(rtems_capture_time_t* time); */ rtems_status_code rtems_capture_open (uint32_t size, + uint32_t task_count, rtems_capture_timestamp timestamp); /** @@ -675,6 +677,9 @@ rtems_capture_task_valid (rtems_capture_task_t* task) static inline rtems_id rtems_capture_task_id (rtems_capture_task_t* task) { + if (!task) + return 0; + return task->id; } @@ -1152,6 +1157,41 @@ rtems_capture_control_count (void) return count; } +/* + * XXX + * The following is based on source in + * _Objects_Get_name_as_string it may need to move + * into a common score method. + */ + +static inline void rtems_capture_name_to_string( + rtems_name object_name, + size_t length, + char* string_name +) +{ + const char* s; + char* d; + uint32_t i; + char lname[5]; + uint32_t u32_name = (uint32_t) object_name; + + lname[ 0 ] = (u32_name >> 24) & 0xff; + lname[ 1 ] = (u32_name >> 16) & 0xff; + lname[ 2 ] = (u32_name >> 8) & 0xff; + lname[ 3 ] = (u32_name >> 0) & 0xff; + lname[ 4 ] = '\0'; + s = lname; + + d = string_name; + if ( s ) { + for ( i=0 ; i<(length-1) && *s ; i++, s++, d++ ) { + *d = (isprint((unsigned char)*s)) ? *s : '*'; + } + } + *d = '\0'; +} + #ifdef __cplusplus } #endif -- 1.8.1.4 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel