[rtems commit] score: Simplify linker set API

Sebastian Huber sebh at rtems.org
Tue Dec 6 11:03:17 UTC 2016


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Dec  6 11:35:34 2016 +0100

score: Simplify linker set API

Resurrect RTEMS_LINKER_SET_BEGIN() and RTEMS_LINKER_SET_END().

Add new macros RTEMS_LINKER_SET_ITEM_COUNT(),
RTEMS_LINKER_SET_IS_EMPTY(), and
RTEMS_LINKER_SET_FOREACH().

Remove confusing RTEMS_LINKER_SET_ASSIGN_BEGIN() and
RTEMS_LINKER_SET_ASSIGN_END().

Fix RTEMS_LINKER_SET_SIZE() to return the size in characters as
specified by the documentation.

Update #2408.
Update #2790.

---

 cpukit/sapi/src/exinit.c                 |  11 +--
 cpukit/score/include/rtems/linkersets.h  |  63 +++++++++-------
 testsuites/sptests/splinkersets01/init.c | 124 ++++++++++++++++++++++++++-----
 3 files changed, 145 insertions(+), 53 deletions(-)

diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c
index f4bea7c..ed269d5 100644
--- a/cpukit/sapi/src/exinit.c
+++ b/cpukit/sapi/src/exinit.c
@@ -131,16 +131,11 @@ RTEMS_SYSINIT_ITEM(
 
 void rtems_initialize_executive(void)
 {
-  const rtems_sysinit_item *cur;
-  const rtems_sysinit_item *end;
-
-  RTEMS_LINKER_SET_ASSIGN_BEGIN(_Sysinit, cur );
-  RTEMS_LINKER_SET_ASSIGN_END( _Sysinit, end );
+  const rtems_sysinit_item *item;
 
   /* Invoke the registered system initialization handlers */
-  while ( cur != end ) {
-    ( *cur->handler )();
-    ++cur;
+  RTEMS_LINKER_SET_FOREACH( _Sysinit, item ) {
+    ( *item->handler )();
   }
 
   _System_state_Set( SYSTEM_STATE_UP );
diff --git a/cpukit/score/include/rtems/linkersets.h b/cpukit/score/include/rtems/linkersets.h
index 390d2cb..bad0469 100644
--- a/cpukit/score/include/rtems/linkersets.h
+++ b/cpukit/score/include/rtems/linkersets.h
@@ -21,35 +21,20 @@
 extern "C" {
 #endif /* __cplusplus */
 
-#define _LINKER_SET_BEGIN( set ) \
+#define RTEMS_LINKER_SET_BEGIN( set ) \
   _Linker_set_##set##_begin
 
-#define _LINKER_SET_END( set ) \
+#define RTEMS_LINKER_SET_END( set ) \
   _Linker_set_##set##_end
 
-#define RTEMS_LINKER_SET_ASSIGN_BEGIN( set, item ) \
-  do { \
-    item = _LINKER_SET_BEGIN( set ); \
-    RTEMS_OBFUSCATE_VARIABLE( item ); \
-  } while ( 0 )
-
-#define RTEMS_LINKER_SET_ASSIGN_END( set, item ) \
-  do { \
-    item = _LINKER_SET_END( set ); \
-    RTEMS_OBFUSCATE_VARIABLE( item ); \
-  } while ( 0 )
-
-#define RTEMS_LINKER_SET_SIZE( set ) \
-  ( (size_t) ( _Linker_set_##set##_end - _Linker_set_##set##_begin ) )
-
 #define RTEMS_LINKER_ROSET_DECLARE( set, type ) \
-  extern type const _LINKER_SET_BEGIN( set )[0]; \
-  extern type const _LINKER_SET_END( set )[0]
+  extern type const RTEMS_LINKER_SET_BEGIN( set )[0]; \
+  extern type const RTEMS_LINKER_SET_END( set )[0]
 
 #define RTEMS_LINKER_ROSET( set, type ) \
-  type const _LINKER_SET_BEGIN( set )[0] \
+  type const RTEMS_LINKER_SET_BEGIN( set )[0] \
   RTEMS_SECTION( ".rtemsroset." #set ".begin" ) RTEMS_USED; \
-  type const _LINKER_SET_END( set )[0] \
+  type const RTEMS_LINKER_SET_END( set )[0] \
   RTEMS_SECTION( ".rtemsroset." #set ".end" ) RTEMS_USED
 
 #define RTEMS_LINKER_ROSET_ITEM_DECLARE( set, type, item ) \
@@ -74,13 +59,13 @@ extern "C" {
   RTEMS_SECTION( ".rtemsroset." #set ".content" )
 
 #define RTEMS_LINKER_RWSET_DECLARE( set, type ) \
-  extern type _LINKER_SET_BEGIN( set )[0]; \
-  extern type _LINKER_SET_END( set )[0]
+  extern type RTEMS_LINKER_SET_BEGIN( set )[0]; \
+  extern type RTEMS_LINKER_SET_END( set )[0]
 
 #define RTEMS_LINKER_RWSET( set, type ) \
-  type _LINKER_SET_BEGIN( set )[0] \
+  type RTEMS_LINKER_SET_BEGIN( set )[0] \
   RTEMS_SECTION( ".rtemsrwset." #set ".begin" ) RTEMS_USED; \
-  type _LINKER_SET_END( set )[0] \
+  type RTEMS_LINKER_SET_END( set )[0] \
   RTEMS_SECTION( ".rtemsrwset." #set ".end" ) RTEMS_USED
 
 #define RTEMS_LINKER_RWSET_ITEM_DECLARE( set, type, item ) \
@@ -109,6 +94,34 @@ extern "C" {
   decl \
   RTEMS_SECTION( ".rtemsrwset." #set ".content" )
 
+RTEMS_INLINE_ROUTINE uintptr_t _Linker_set_Obfuscate( const void *ptr )
+{
+  uintptr_t addr;
+
+  addr = (uintptr_t) ptr;
+  RTEMS_OBFUSCATE_VARIABLE( addr );
+
+  return addr;
+}
+
+#define RTEMS_LINKER_SET_SIZE( set ) \
+  ( _Linker_set_Obfuscate( RTEMS_LINKER_SET_END( set ) ) \
+    - _Linker_set_Obfuscate( RTEMS_LINKER_SET_BEGIN( set ) ) )
+
+#define RTEMS_LINKER_SET_ITEM_COUNT( set ) \
+  ( RTEMS_LINKER_SET_SIZE( set ) \
+    / sizeof( RTEMS_LINKER_SET_BEGIN( set )[ 0 ] ) )
+
+#define RTEMS_LINKER_SET_IS_EMPTY( set ) \
+  ( RTEMS_LINKER_SET_SIZE( set ) == 0 )
+
+#define RTEMS_LINKER_SET_FOREACH( set, item ) \
+  for ( \
+    item = (void *) _Linker_set_Obfuscate( RTEMS_LINKER_SET_BEGIN( set ) ) ; \
+    item != RTEMS_LINKER_SET_END( set ) ; \
+    ++item \
+  )
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/testsuites/sptests/splinkersets01/init.c b/testsuites/sptests/splinkersets01/init.c
index 71f69b7..4e19c6e 100644
--- a/testsuites/sptests/splinkersets01/init.c
+++ b/testsuites/sptests/splinkersets01/init.c
@@ -83,6 +83,10 @@ ITEM(s2, SAFE_ORDER_C);
 ITEM(s1, SAFE_ORDER_B);
 ITEM(s0, SAFE_ORDER_A);
 
+RTEMS_LINKER_RWSET(test_rw_empty, const int *);
+
+RTEMS_LINKER_ROSET(test_ro_empty, const int *);
+
 static void test(void)
 {
   const int **b;
@@ -96,29 +100,65 @@ static void test(void)
   const int * const *sb;
   const int * const *se;
   size_t i;
-
-  RTEMS_LINKER_SET_ASSIGN_BEGIN(test_rw, b);
-  RTEMS_LINKER_SET_ASSIGN_END(test_rw, e);
-  RTEMS_LINKER_SET_ASSIGN_BEGIN(test_ro, cb);
-  RTEMS_LINKER_SET_ASSIGN_END(test_ro, ce);
-  RTEMS_LINKER_SET_ASSIGN_BEGIN(test_rw_i, bi);
-  RTEMS_LINKER_SET_ASSIGN_END(test_rw_i, ei);
-  RTEMS_LINKER_SET_ASSIGN_BEGIN(test_ro_i, cbi);
-  RTEMS_LINKER_SET_ASSIGN_END(test_ro_i, cei);
-  RTEMS_LINKER_SET_ASSIGN_BEGIN(test_ro_s, sb);
-  RTEMS_LINKER_SET_ASSIGN_END(test_ro_s, se);
+  const int **item;
+
+  b = RTEMS_LINKER_SET_BEGIN(test_rw);
+  e = RTEMS_LINKER_SET_END(test_rw);
+  cb = RTEMS_LINKER_SET_BEGIN(test_ro);
+  ce = RTEMS_LINKER_SET_END(test_ro);
+  bi = RTEMS_LINKER_SET_BEGIN(test_rw_i);
+  ei = RTEMS_LINKER_SET_END(test_rw_i);
+  cbi = RTEMS_LINKER_SET_BEGIN(test_ro_i);
+  cei = RTEMS_LINKER_SET_END(test_ro_i);
+  sb = RTEMS_LINKER_SET_BEGIN(test_ro_s);
+  se = RTEMS_LINKER_SET_END(test_ro_s);
+  RTEMS_OBFUSCATE_VARIABLE(b);
+  RTEMS_OBFUSCATE_VARIABLE(e);
+  RTEMS_OBFUSCATE_VARIABLE(cb);
+  RTEMS_OBFUSCATE_VARIABLE(ce);
+  RTEMS_OBFUSCATE_VARIABLE(bi);
+  RTEMS_OBFUSCATE_VARIABLE(ei);
+  RTEMS_OBFUSCATE_VARIABLE(cbi);
+  RTEMS_OBFUSCATE_VARIABLE(cei);
+  RTEMS_OBFUSCATE_VARIABLE(sb);
+  RTEMS_OBFUSCATE_VARIABLE(se);
 
   rtems_test_assert((size_t) (e - b) == RTEMS_ARRAY_SIZE(a));
   rtems_test_assert((size_t) (ce - cb) == RTEMS_ARRAY_SIZE(ca));
-  rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_rw) == RTEMS_ARRAY_SIZE(a));
-  rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro) == RTEMS_ARRAY_SIZE(ca));
+  rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_rw) == sizeof(a));
+  rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro) == sizeof(ca));
+  rtems_test_assert(
+    RTEMS_LINKER_SET_ITEM_COUNT(test_rw) == RTEMS_ARRAY_SIZE(a)
+  );
+  rtems_test_assert(
+    RTEMS_LINKER_SET_ITEM_COUNT(test_ro) == RTEMS_ARRAY_SIZE(ca)
+  );
+  rtems_test_assert(!RTEMS_LINKER_SET_IS_EMPTY(test_rw));
+  rtems_test_assert(!RTEMS_LINKER_SET_IS_EMPTY(test_ro));
 
   rtems_test_assert((size_t) (ei - bi) == RTEMS_ARRAY_SIZE(a));
   rtems_test_assert((size_t) (cei - cbi) == RTEMS_ARRAY_SIZE(ca));
   rtems_test_assert((size_t) (se - sb) == 3);
-  rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_rw_i) == RTEMS_ARRAY_SIZE(a));
-  rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro_i) == RTEMS_ARRAY_SIZE(ca));
-  rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro_s) == 3);
+  rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_rw_i) == sizeof(a));
+  rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro_i) == sizeof(ca));
+  rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro_s) == 3 * sizeof(int *));
+  rtems_test_assert(
+    RTEMS_LINKER_SET_ITEM_COUNT(test_rw_i) == RTEMS_ARRAY_SIZE(a)
+  );
+  rtems_test_assert(
+    RTEMS_LINKER_SET_ITEM_COUNT(test_ro_i) == RTEMS_ARRAY_SIZE(ca)
+  );
+  rtems_test_assert(RTEMS_LINKER_SET_ITEM_COUNT(test_ro_s) == 3);
+  rtems_test_assert(!RTEMS_LINKER_SET_IS_EMPTY(test_rw_i));
+  rtems_test_assert(!RTEMS_LINKER_SET_IS_EMPTY(test_ro_i));
+  rtems_test_assert(!RTEMS_LINKER_SET_IS_EMPTY(test_ro_s));
+
+  rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_rw_empty) == 0);
+  rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro_empty) == 0);
+  rtems_test_assert(RTEMS_LINKER_SET_ITEM_COUNT(test_rw_empty) == 0);
+  rtems_test_assert(RTEMS_LINKER_SET_ITEM_COUNT(test_ro_empty) == 0);
+  rtems_test_assert(RTEMS_LINKER_SET_IS_EMPTY(test_rw_empty));
+  rtems_test_assert(RTEMS_LINKER_SET_IS_EMPTY(test_ro_empty));
 
   for (i = 0; i < RTEMS_ARRAY_SIZE(a); ++i) {
     rtems_test_assert(&a[i] == b[i]);
@@ -136,9 +176,49 @@ static void test(void)
     rtems_test_assert(&ca[i] == cbi[i]);
   }
 
+  i = 0;
+  RTEMS_LINKER_SET_FOREACH(test_rw, item) {
+    rtems_test_assert(&a[i] == *item);
+    ++i;
+  }
+  rtems_test_assert(i == RTEMS_ARRAY_SIZE(a));
+
+  i = 0;
+  RTEMS_LINKER_SET_FOREACH(test_ro, item) {
+    rtems_test_assert(&ca[i] == *item);
+    ++i;
+  }
+  rtems_test_assert(i == RTEMS_ARRAY_SIZE(ca));
+
+  i = 0;
+  RTEMS_LINKER_SET_FOREACH(test_rw_i, item) {
+    rtems_test_assert(&a[i] == *item);
+    ++i;
+  }
+  rtems_test_assert(i == RTEMS_ARRAY_SIZE(a));
+
+  i = 0;
+  RTEMS_LINKER_SET_FOREACH(test_ro_i, item) {
+    rtems_test_assert(&ca[i] == *item);
+    ++i;
+  }
+  rtems_test_assert(i == RTEMS_ARRAY_SIZE(ca));
+
   rtems_test_assert(&s0 == sb[0]);
   rtems_test_assert(&s1 == sb[1]);
   rtems_test_assert(&s2 == sb[2]);
+
+  i = 0;
+  RTEMS_LINKER_SET_FOREACH(test_rw_empty, item) {
+    ++i;
+  }
+  rtems_test_assert(i == 0);
+
+  i = 0;
+  RTEMS_LINKER_SET_FOREACH(test_ro_empty, item) {
+    ++i;
+  }
+  rtems_test_assert(i == 0);
 }
 
 static void test_content(void)
@@ -148,10 +228,14 @@ static void test_content(void)
   const char *b_ro;
   const char *e_ro;
 
-  RTEMS_LINKER_SET_ASSIGN_BEGIN(test_content_rw, b_rw);
-  RTEMS_LINKER_SET_ASSIGN_END(test_content_rw, e_rw);
-  RTEMS_LINKER_SET_ASSIGN_BEGIN(test_content_ro, b_ro);
-  RTEMS_LINKER_SET_ASSIGN_END(test_content_ro, e_ro);
+  b_rw = RTEMS_LINKER_SET_BEGIN(test_content_rw);
+  e_rw = RTEMS_LINKER_SET_END(test_content_rw);
+  b_ro = RTEMS_LINKER_SET_BEGIN(test_content_ro);
+  e_ro = RTEMS_LINKER_SET_END(test_content_ro);
+  RTEMS_OBFUSCATE_VARIABLE(b_rw);
+  RTEMS_OBFUSCATE_VARIABLE(e_rw);
+  RTEMS_OBFUSCATE_VARIABLE(b_ro);
+  RTEMS_OBFUSCATE_VARIABLE(e_ro);
 
   rtems_test_assert((uintptr_t) &content_rw_1 >= (uintptr_t) b_rw);
   rtems_test_assert((uintptr_t) &content_rw_2 >= (uintptr_t) b_rw);




More information about the vc mailing list