[rtems commit] record: Add support for thread names

Sebastian Huber sebh at rtems.org
Tue Jul 30 05:25:26 UTC 2019


Module:    rtems
Branch:    master
Commit:    036717eda4de437336a86ca67253b7e32f67463c
Changeset: http://git.rtems.org/rtems/commit/?id=036717eda4de437336a86ca67253b7e32f67463c

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Jul 26 16:36:10 2019 +0200

record: Add support for thread names

---

 cpukit/include/rtems/recorddata.h       |  4 +-
 cpukit/libtrace/record/record-server.c  | 70 +++++++++++++++++++++++++++++++++
 cpukit/libtrace/record/record-text.c    |  2 +-
 cpukit/libtrace/record/record-userext.c | 36 ++++++++++++++---
 testsuites/libtests/record01/init.c     | 32 +++++++++++++++
 5 files changed, 136 insertions(+), 8 deletions(-)

diff --git a/cpukit/include/rtems/recorddata.h b/cpukit/include/rtems/recorddata.h
index 61a6311..607955c 100644
--- a/cpukit/include/rtems/recorddata.h
+++ b/cpukit/include/rtems/recorddata.h
@@ -55,7 +55,7 @@ extern "C" {
  * The record version reflects the record event definitions.  It is reported by
  * the RTEMS_RECORD_VERSION event.
  */
-#define RTEMS_RECORD_THE_VERSION 4
+#define RTEMS_RECORD_THE_VERSION 5
 
 /**
  * @brief The items are in 32-bit little-endian format.
@@ -291,6 +291,7 @@ typedef enum {
   RTEMS_RECORD_THREAD_EXIT,
   RTEMS_RECORD_THREAD_EXITTED,
   RTEMS_RECORD_THREAD_ID,
+  RTEMS_RECORD_THREAD_NAME,
   RTEMS_RECORD_THREAD_PRIO_CURRENT_HIGH,
   RTEMS_RECORD_THREAD_PRIO_CURRENT_LOW,
   RTEMS_RECORD_THREAD_PRIO_REAL_HIGH,
@@ -607,7 +608,6 @@ typedef enum {
   RTEMS_RECORD_SYSTEM_508,
   RTEMS_RECORD_SYSTEM_509,
   RTEMS_RECORD_SYSTEM_510,
-  RTEMS_RECORD_SYSTEM_511,
 
   /* There are 512 events reserved for the user */
   RTEMS_RECORD_USER_0,
diff --git a/cpukit/libtrace/record/record-server.c b/cpukit/libtrace/record/record-server.c
index 840924a..b8519cc 100644
--- a/cpukit/libtrace/record/record-server.c
+++ b/cpukit/libtrace/record/record-server.c
@@ -30,6 +30,7 @@
 #endif
 
 #include <rtems/record.h>
+#include <rtems/score/threadimpl.h>
 #include <rtems.h>
 
 #include <sys/endian.h>
@@ -165,6 +166,74 @@ static void send_header( int fd )
   (void) write( fd, &header, sizeof( header ) );
 }
 
+typedef struct {
+  int fd;
+  size_t index;
+  rtems_record_item items[ 128 ];
+} thread_names_context;
+
+static void thread_names_produce(
+  thread_names_context *ctx,
+  rtems_record_event    event,
+  rtems_record_data     data
+)
+{
+  size_t i;
+
+  i = ctx->index;
+  ctx->items[ i ].event = RTEMS_RECORD_TIME_EVENT( 0, event );
+  ctx->items[ i ].data = data;
+
+  if (i == RTEMS_ARRAY_SIZE(ctx->items) - 2) {
+    ctx->index = 0;
+    (void) write( ctx->fd, ctx->items, sizeof( ctx->items ) );
+  } else {
+    ctx->index = i + 1;
+  }
+}
+
+static bool thread_names_visitor( rtems_tcb *tcb, void *arg )
+{
+  thread_names_context *ctx;
+  char                  name[ 2 * THREAD_DEFAULT_MAXIMUM_NAME_SIZE ];
+  size_t                n;
+  size_t                i;
+  rtems_record_data     data;
+
+  ctx = arg;
+  thread_names_produce( ctx, RTEMS_RECORD_THREAD_ID, tcb->Object.id );
+  n = _Thread_Get_name( tcb, name, sizeof( name ) );
+  i = 0;
+
+  while ( i < n ) {
+    size_t j;
+
+    data = 0;
+
+    for ( j = 0; i < n && j < sizeof( data ); ++j ) {
+      data = ( data << 8 ) | name[ i ];
+      ++i;
+    }
+
+    thread_names_produce( ctx, RTEMS_RECORD_THREAD_NAME, data );
+  }
+
+  return false;
+}
+
+static void send_thread_names( int fd )
+{
+  thread_names_context ctx;
+
+  ctx.fd = fd;
+  ctx.index = 0;
+  rtems_task_iterate( thread_names_visitor, &ctx );
+
+  if ( ctx.index > 0 ) {
+    (void) write( ctx.fd, ctx.items, ctx.index * sizeof( ctx.items[ 0 ] ) );
+  }
+}
+
 void rtems_record_server( uint16_t port, rtems_interval period )
 {
   rtems_status_code sc;
@@ -216,6 +285,7 @@ void rtems_record_server( uint16_t port, rtems_interval period )
     wait( RTEMS_NO_WAIT );
     (void) rtems_timer_fire_after( timer, period, wakeup_timer, &self );
     send_header( cd );
+    send_thread_names( cd );
 
     while ( true ) {
       n = rtems_record_writev( cd, &written );
diff --git a/cpukit/libtrace/record/record-text.c b/cpukit/libtrace/record/record-text.c
index cbc623a..5652ab0 100644
--- a/cpukit/libtrace/record/record-text.c
+++ b/cpukit/libtrace/record/record-text.c
@@ -236,6 +236,7 @@ static const char * const event_text[] = {
   [ RTEMS_RECORD_THREAD_EXIT ] = "THREAD_EXIT",
   [ RTEMS_RECORD_THREAD_EXITTED ] = "THREAD_EXITTED",
   [ RTEMS_RECORD_THREAD_ID ] = "THREAD_ID",
+  [ RTEMS_RECORD_THREAD_NAME ] = "THREAD_NAME",
   [ RTEMS_RECORD_THREAD_PRIO_CURRENT_HIGH ] = "THREAD_PRIO_CURRENT_HIGH",
   [ RTEMS_RECORD_THREAD_PRIO_CURRENT_LOW ] = "THREAD_PRIO_CURRENT_LOW",
   [ RTEMS_RECORD_THREAD_PRIO_REAL_HIGH ] = "THREAD_PRIO_REAL_HIGH",
@@ -550,7 +551,6 @@ static const char * const event_text[] = {
   [ RTEMS_RECORD_SYSTEM_508 ] = "SYSTEM_508",
   [ RTEMS_RECORD_SYSTEM_509 ] = "SYSTEM_509",
   [ RTEMS_RECORD_SYSTEM_510 ] = "SYSTEM_510",
-  [ RTEMS_RECORD_SYSTEM_511 ] = "SYSTEM_511",
   [ RTEMS_RECORD_USER_0 ] = "USER_0",
   [ RTEMS_RECORD_USER_1 ] = "USER_1",
   [ RTEMS_RECORD_USER_2 ] = "USER_2",
diff --git a/cpukit/libtrace/record/record-userext.c b/cpukit/libtrace/record/record-userext.c
index a57a3f7..ff448e5 100644
--- a/cpukit/libtrace/record/record-userext.c
+++ b/cpukit/libtrace/record/record-userext.c
@@ -30,17 +30,43 @@
 #endif
 
 #include <rtems/record.h>
-#include <rtems/score/thread.h>
+#include <rtems/score/threadimpl.h>
 
 bool _Record_Thread_create(
   struct _Thread_Control *executing,
   struct _Thread_Control *created
 )
 {
-  rtems_record_produce(
-    RTEMS_RECORD_THREAD_CREATE,
-    created->Object.id
-  );
+  rtems_record_data data;
+  char              name[ 2 * THREAD_DEFAULT_MAXIMUM_NAME_SIZE ];
+  rtems_record_item items[ 1 + sizeof( name ) / sizeof( data ) ];
+  size_t            n;
+  size_t            i;
+  size_t            j;
+
+  i = 0;
+  items[ i ].event = RTEMS_RECORD_THREAD_CREATE;
+  items[ i ].data = created->Object.id;
+
+  n = _Thread_Get_name( created, name, sizeof( name ) );
+  j = 0;
+
+  while ( j < n ) {
+    size_t k;
+
+    data = 0;
+
+    for ( k = 0; j < n && k < sizeof( data ); ++k ) {
+      data = ( data << 8 ) | name[ j ];
+      ++j;
+    }
+
+    ++i;
+    items[ i ].event = RTEMS_RECORD_THREAD_NAME;
+    items[ i ].data = data;
+  }
+
+  rtems_record_produce_n( items, i + 1 );
 
   return true;
 }
diff --git a/testsuites/libtests/record01/init.c b/testsuites/libtests/record01/init.c
index 3a3680c..fdc2a85 100644
--- a/testsuites/libtests/record01/init.c
+++ b/testsuites/libtests/record01/init.c
@@ -151,6 +151,31 @@ static const rtems_record_item expected_items_12[] = {
   { .event = TE(44, UE(43)), .data = 45 }
 };
 
+#ifdef RTEMS_NETWORKING
+static const rtems_record_item expected_items_13[] = {
+  { .event = TE(0, RTEMS_RECORD_THREAD_ID), .data = 0x9010001 },
+  {
+    .event = TE(0, RTEMS_RECORD_THREAD_NAME),
+    .data = rtems_build_name('I', 'D', 'L', 'E')
+  },
+  { .event = TE(0, RTEMS_RECORD_THREAD_ID), .data = 0xa010001 },
+  {
+    .event = TE(0, RTEMS_RECORD_THREAD_NAME),
+    .data = rtems_build_name('U', 'I', '1', ' ')
+  },
+  { .event = TE(0, RTEMS_RECORD_THREAD_ID), .data = 0xa010002 },
+  {
+    .event = TE(0, RTEMS_RECORD_THREAD_NAME),
+    .data = rtems_build_name('n', 't', 'w', 'k')
+  },
+  { .event = TE(0, RTEMS_RECORD_THREAD_ID), .data = 0xa010003 },
+  {
+    .event = TE(0, RTEMS_RECORD_THREAD_NAME),
+    .data = rtems_build_name('R', 'C', 'R', 'D')
+  }
+};
+#endif
+
 static void init_context(test_context *ctx)
 {
   memset(ctx, 0, sizeof(*ctx));
@@ -521,6 +546,7 @@ static int connect_client(void)
   ssize_t n;
   uint32_t v;
   rtems_record_item item;
+  rtems_record_item items[8];
 
   fd = socket(PF_INET, SOCK_STREAM, 0);
   rtems_test_assert(fd >= 0);
@@ -560,6 +586,12 @@ static int connect_client(void)
   rtems_test_assert(item.event == TE(0, RTEMS_RECORD_FREQUENCY));
   rtems_test_assert(item.data == rtems_counter_frequency());
 
+  n = read(fd, items, sizeof(expected_items_13));
+  rtems_test_assert(n == (ssize_t) sizeof(expected_items_13));
+  rtems_test_assert(
+    memcmp(items, expected_items_13, sizeof(expected_items_13)) == 0
+  );
+
   return fd;
 }
 




More information about the vc mailing list