[PATCH 1/2] capture: change to use malloc/vs/rtems_workspace_alloc.
Jennifer Averett
jennifer.averett at oarcorp.com
Tue Aug 26 20:16:11 UTC 2014
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
More information about the devel
mailing list