[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