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