<div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr">On Tue, Jul 24, 2018, 2:03 AM Sebastian Huber <<a href="mailto:sebastian.huber@embedded-brains.de">sebastian.huber@embedded-brains.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Add RTEMS_PREDICT_TRUE() and RTEMS_PREDICT_FALSE() for static branch<br>
prediction hints.<br>
<br>
Close #3475.<br>
---<br>
 cpukit/include/rtems/score/basedefs.h | 28 ++++++++++++++++++++++++++++<br>
 cpukit/posix/src/sempost.c            |  4 ++--<br>
 cpukit/posix/src/semtimedwait.c       |  2 +-<br>
 cpukit/posix/src/semtrywait.c         |  2 +-<br>
 cpukit/score/src/condition.c          |  4 +++-<br>
 cpukit/score/src/futex.c              |  2 +-<br>
 cpukit/score/src/mutex.c              | 16 ++++++++--------<br>
 cpukit/score/src/semaphore.c          | 10 +++++-----<br>
 testsuites/sptests/spmisc01/init.c    | 25 +++++++++++++++++++++++++<br>
 9 files changed, 74 insertions(+), 19 deletions(-)<br>
<br>
diff --git a/cpukit/include/rtems/score/basedefs.h b/cpukit/include/rtems/score/basedefs.h<br>
index 8169f6db8c..7a52de895d 100644<br>
--- a/cpukit/include/rtems/score/basedefs.h<br>
+++ b/cpukit/include/rtems/score/basedefs.h<br>
@@ -281,6 +281,34 @@<br>
   #define RTEMS_DEFINE_GLOBAL_SYMBOL( _name, _value )<br>
 #endif<br>
<br>
+/**<br>
+ * @brief Returns the value of the specified integral expressen and tells the<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Spelling error here and in the other comment block. Search to make sure it isn't elsewhere.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ * compiler that the predicted value is true (1).<br>
+ *<br>
+ * @param[in] _exp The expression.<br>
+ *<br>
+ * @return The value of the expression.<br>
+ */<br>
+#if defined(__GNUC__)<br>
+  #define RTEMS_PREDICT_TRUE( _exp ) __builtin_expect( ( _exp ), 1 )<br>
+#else<br>
+  #define RTEMS_PREDICT_TRUE( _exp ) ( _exp )<br>
+#endif<br>
+<br>
+/**<br>
+ * @brief Returns the value of the specified integral expressen and tells the<br>
+ * compiler that the predicted value is false (0).<br>
+ *<br>
+ * @param[in] _exp The expression.<br>
+ *<br>
+ * @return The value of the expression.<br>
+ */<br>
+#if defined(__GNUC__)<br>
+  #define RTEMS_PREDICT_FALSE( _exp ) __builtin_expect( ( _exp ), 0 )<br>
+#else<br>
+  #define RTEMS_PREDICT_FALSE( _exp ) ( _exp )<br>
+#endif<br>
+<br>
 #if __cplusplus >= 201103L<br>
   #define RTEMS_STATIC_ASSERT(cond, msg) \<br>
     static_assert(cond, # msg)<br>
diff --git a/cpukit/posix/src/sempost.c b/cpukit/posix/src/sempost.c<br>
index de0ae71fc7..d750c1178c 100644<br>
--- a/cpukit/posix/src/sempost.c<br>
+++ b/cpukit/posix/src/sempost.c<br>
@@ -40,13 +40,13 @@ int sem_post( sem_t *_sem )<br>
   heads = sem->Queue.Queue.heads;<br>
   count = sem->count;<br>
<br>
-  if ( __predict_true( heads == NULL && count < SEM_VALUE_MAX ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( heads == NULL && count < SEM_VALUE_MAX ) ) {<br>
     sem->count = count + 1;<br>
     _Sem_Queue_release( sem, level, &queue_context );<br>
     return 0;<br>
   }<br>
<br>
-  if ( __predict_true( heads != NULL ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( heads != NULL ) ) {<br>
     const Thread_queue_Operations *operations;<br>
     Thread_Control *first;<br>
<br>
diff --git a/cpukit/posix/src/semtimedwait.c b/cpukit/posix/src/semtimedwait.c<br>
index 9e7bb466dd..16d0c24c9f 100644<br>
--- a/cpukit/posix/src/semtimedwait.c<br>
+++ b/cpukit/posix/src/semtimedwait.c<br>
@@ -46,7 +46,7 @@ int sem_timedwait(<br>
   executing = _Sem_Queue_acquire_critical( sem, &queue_context );<br>
<br>
   count = sem->count;<br>
-  if ( __predict_true( count > 0 ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( count > 0 ) ) {<br>
     sem->count = count - 1;<br>
     _Sem_Queue_release( sem, level, &queue_context );<br>
     return 0;<br>
diff --git a/cpukit/posix/src/semtrywait.c b/cpukit/posix/src/semtrywait.c<br>
index 673343d4b4..759744ec8e 100644<br>
--- a/cpukit/posix/src/semtrywait.c<br>
+++ b/cpukit/posix/src/semtrywait.c<br>
@@ -35,7 +35,7 @@ int sem_trywait( sem_t *_sem )<br>
   _Sem_Queue_acquire_critical( sem, &queue_context );<br>
<br>
   count = sem->count;<br>
-  if ( __predict_true( count > 0 ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( count > 0 ) ) {<br>
     sem->count = count - 1;<br>
     _Sem_Queue_release( sem, level, &queue_context );<br>
     return 0;<br>
diff --git a/cpukit/score/src/condition.c b/cpukit/score/src/condition.c<br>
index 9913d86d34..892245baf5 100644<br>
--- a/cpukit/score/src/condition.c<br>
+++ b/cpukit/score/src/condition.c<br>
@@ -279,7 +279,9 @@ static void _Condition_Wake( struct _Condition_Control *_condition, int count )<br>
    * In common uses cases of condition variables there are normally no threads<br>
    * on the queue, so check this condition early.<br>
    */<br>
-  if ( __predict_true( _Thread_queue_Is_empty( &condition->Queue.Queue ) ) ) {<br>
+  if (<br>
+    RTEMS_PREDICT_TRUE( _Thread_queue_Is_empty( &condition->Queue.Queue ) )<br>
+  ) {<br>
     _Condition_Queue_release( condition, &context.Base );<br>
     return;<br>
   }<br>
diff --git a/cpukit/score/src/futex.c b/cpukit/score/src/futex.c<br>
index 6487882819..f32a13c449 100644<br>
--- a/cpukit/score/src/futex.c<br>
+++ b/cpukit/score/src/futex.c<br>
@@ -151,7 +151,7 @@ int _Futex_Wake( struct _Futex_Control *_futex, int count )<br>
    * called in the fast path.  Normally there are no threads on the queue, so<br>
    * check this condition early.<br>
    */<br>
-  if ( __predict_true( _Thread_queue_Is_empty( &futex->Queue.Queue ) ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( _Thread_queue_Is_empty( &futex->Queue.Queue ) ) ) {<br>
     _Futex_Queue_release( futex, level, &context.Base );<br>
     return 0;<br>
   }<br>
diff --git a/cpukit/score/src/mutex.c b/cpukit/score/src/mutex.c<br>
index e2f5bb52fc..8cc47f28bb 100644<br>
--- a/cpukit/score/src/mutex.c<br>
+++ b/cpukit/score/src/mutex.c<br>
@@ -128,7 +128,7 @@ static void _Mutex_Release_critical(<br>
   mutex->Queue.Queue.owner = NULL;<br>
   _Thread_Resource_count_decrement( executing );<br>
<br>
-  if ( __predict_true( heads == NULL ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( heads == NULL ) ) {<br>
     _Mutex_Queue_release( mutex, level, queue_context );<br>
   } else {<br>
     _Thread_queue_Context_set_ISR_level( queue_context, level );<br>
@@ -157,7 +157,7 @@ void _Mutex_Acquire( struct _Mutex_Control *_mutex )<br>
<br>
   owner = mutex->Queue.Queue.owner;<br>
<br>
-  if ( __predict_true( owner == NULL ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( owner == NULL ) ) {<br>
     mutex->Queue.Queue.owner = executing;<br>
     _Thread_Resource_count_increment( executing );<br>
     _Mutex_Queue_release( mutex, level, &queue_context );<br>
@@ -185,7 +185,7 @@ int _Mutex_Acquire_timed(<br>
<br>
   owner = mutex->Queue.Queue.owner;<br>
<br>
-  if ( __predict_true( owner == NULL ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( owner == NULL ) ) {<br>
     mutex->Queue.Queue.owner = executing;<br>
     _Thread_Resource_count_increment( executing );<br>
     _Mutex_Queue_release( mutex, level, &queue_context );<br>
@@ -218,7 +218,7 @@ int _Mutex_Try_acquire( struct _Mutex_Control *_mutex )<br>
<br>
   owner = mutex->Queue.Queue.owner;<br>
<br>
-  if ( __predict_true( owner == NULL ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( owner == NULL ) ) {<br>
     mutex->Queue.Queue.owner = executing;<br>
     _Thread_Resource_count_increment( executing );<br>
     eno = 0;<br>
@@ -270,7 +270,7 @@ void _Mutex_recursive_Acquire( struct _Mutex_recursive_Control *_mutex )<br>
<br>
   owner = mutex->Mutex.Queue.Queue.owner;<br>
<br>
-  if ( __predict_true( owner == NULL ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( owner == NULL ) ) {<br>
     mutex->Mutex.Queue.Queue.owner = executing;<br>
     _Thread_Resource_count_increment( executing );<br>
     _Mutex_Queue_release( &mutex->Mutex, level, &queue_context );<br>
@@ -301,7 +301,7 @@ int _Mutex_recursive_Acquire_timed(<br>
<br>
   owner = mutex->Mutex.Queue.Queue.owner;<br>
<br>
-  if ( __predict_true( owner == NULL ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( owner == NULL ) ) {<br>
     mutex->Mutex.Queue.Queue.owner = executing;<br>
     _Thread_Resource_count_increment( executing );<br>
     _Mutex_Queue_release( &mutex->Mutex, level, &queue_context );<br>
@@ -339,7 +339,7 @@ int _Mutex_recursive_Try_acquire( struct _Mutex_recursive_Control *_mutex )<br>
<br>
   owner = mutex->Mutex.Queue.Queue.owner;<br>
<br>
-  if ( __predict_true( owner == NULL ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( owner == NULL ) ) {<br>
     mutex->Mutex.Queue.Queue.owner = executing;<br>
     _Thread_Resource_count_increment( executing );<br>
     eno = 0;<br>
@@ -372,7 +372,7 @@ void _Mutex_recursive_Release( struct _Mutex_recursive_Control *_mutex )<br>
<br>
   nest_level = mutex->nest_level;<br>
<br>
-  if ( __predict_true( nest_level == 0 ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( nest_level == 0 ) ) {<br>
     _Mutex_Release_critical( &mutex->Mutex, executing, level, &queue_context );<br>
   } else {<br>
     mutex->nest_level = nest_level - 1;<br>
diff --git a/cpukit/score/src/semaphore.c b/cpukit/score/src/semaphore.c<br>
index f76ee332a4..f9b8b48fe1 100644<br>
--- a/cpukit/score/src/semaphore.c<br>
+++ b/cpukit/score/src/semaphore.c<br>
@@ -53,7 +53,7 @@ void _Semaphore_Wait( struct _Semaphore_Control *_sem )<br>
   executing = _Sem_Queue_acquire_critical( sem, &queue_context );<br>
<br>
   count = sem->count;<br>
-  if ( __predict_true( count > 0 ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( count > 0 ) ) {<br>
     sem->count = count - 1;<br>
     _Sem_Queue_release( sem, level, &queue_context );<br>
   } else {<br>
@@ -86,7 +86,7 @@ int _Semaphore_Wait_timed_ticks( struct _Semaphore_Control *_sem, uint32_t ticks<br>
   executing = _Sem_Queue_acquire_critical( sem, &queue_context );<br>
<br>
   count = sem->count;<br>
-  if ( __predict_true( count > 0 ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( count > 0 ) ) {<br>
     sem->count = count - 1;<br>
     _Sem_Queue_release( sem, level, &queue_context );<br>
     return 0;<br>
@@ -121,7 +121,7 @@ int _Semaphore_Try_wait( struct _Semaphore_Control *_sem )<br>
   _Sem_Queue_acquire_critical( sem, &queue_context );<br>
<br>
   count = sem->count;<br>
-  if ( __predict_true( count > 0 ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( count > 0 ) ) {<br>
     sem->count = count - 1;<br>
     eno = 0;<br>
   } else {<br>
@@ -145,7 +145,7 @@ void _Semaphore_Post( struct _Semaphore_Control *_sem )<br>
   _Sem_Queue_acquire_critical( sem, &queue_context );<br>
<br>
   heads = sem->Queue.Queue.heads;<br>
-  if ( __predict_true( heads == NULL ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( heads == NULL ) ) {<br>
     ++sem->count;<br>
     _Sem_Queue_release( sem, level, &queue_context );<br>
   } else {<br>
@@ -178,7 +178,7 @@ void _Semaphore_Post_binary( struct _Semaphore_Control *_sem )<br>
   _Sem_Queue_acquire_critical( sem, &queue_context );<br>
<br>
   heads = sem->Queue.Queue.heads;<br>
-  if ( __predict_true( heads == NULL ) ) {<br>
+  if ( RTEMS_PREDICT_TRUE( heads == NULL ) ) {<br>
     sem->count = 1;<br>
     _Sem_Queue_release( sem, level, &queue_context );<br>
   } else {<br>
diff --git a/testsuites/sptests/spmisc01/init.c b/testsuites/sptests/spmisc01/init.c<br>
index 4fab3f0e84..c406cd07aa 100644<br>
--- a/testsuites/sptests/spmisc01/init.c<br>
+++ b/testsuites/sptests/spmisc01/init.c<br>
@@ -229,6 +229,31 @@ static void Init(rtems_task_argument arg)<br>
   rtems_test_assert(RTEMS_XCONCAT(CON, CAT)() == 91);<br>
   rtems_test_assert(strcmp(RTEMS_STRING(str), "str") == 0);<br>
   rtems_test_assert(strcmp(RTEMS_XSTRING(STR), "ing") == 0);<br>
+<br>
+  if (RTEMS_PREDICT_TRUE(true)) {<br>
+    rtems_test_assert(true);<br>
+  } else {<br>
+    rtems_test_assert(false);<br>
+  }<br>
+<br>
+  if (RTEMS_PREDICT_FALSE(true)) {<br>
+    rtems_test_assert(true);<br>
+  } else {<br>
+    rtems_test_assert(false);<br>
+  }<br>
+<br>
+  if (RTEMS_PREDICT_TRUE(false)) {<br>
+    rtems_test_assert(false);<br>
+  } else {<br>
+    rtems_test_assert(true);<br>
+  }<br>
+<br>
+  if (RTEMS_PREDICT_FALSE(false)) {<br>
+    rtems_test_assert(false);<br>
+  } else {<br>
+    rtems_test_assert(true);<br>
+  }<br>
+<br>
   TEST_END();<br>
   rtems_test_exit(0);<br>
 }<br>
-- <br>
2.13.7<br>
<br>
_______________________________________________<br>
devel mailing list<br>
<a href="mailto:devel@rtems.org" target="_blank" rel="noreferrer">devel@rtems.org</a><br>
<a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
</blockquote></div></div></div>