summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/threadimpl.h
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-29 15:33:26 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-30 07:57:44 +0200
commit029877282edb8aa7a2095702742ce95c8246729e (patch)
treeb1fbd380bac4071d05712957f9d03c6cc7521299 /cpukit/score/include/rtems/score/threadimpl.h
parentscore: Fix thread lock on SMP configurations (diff)
downloadrtems-029877282edb8aa7a2095702742ce95c8246729e.tar.bz2
score: Avoid atomic fences for thread wait flags
The use of atomic fences is brittle and may break due to changes in different areas which is hard to manage.
Diffstat (limited to 'cpukit/score/include/rtems/score/threadimpl.h')
-rw-r--r--cpukit/score/include/rtems/score/threadimpl.h42
1 files changed, 30 insertions, 12 deletions
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index a4e746957a..b4d2f4f13e 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -1311,8 +1311,10 @@ RTEMS_INLINE_ROUTINE Thread_Wait_flags _Thread_Wait_flags_get(
}
/**
- * @brief Tries to change the thread wait flags inside a critical section
- * (interrupts disabled).
+ * @brief Tries to change the thread wait flags with release semantics in case
+ * of success.
+ *
+ * Must be called inside a critical section (interrupts disabled).
*
* In case the wait flags are equal to the expected wait flags, then the wait
* flags are set to the desired wait flags.
@@ -1324,22 +1326,24 @@ RTEMS_INLINE_ROUTINE Thread_Wait_flags _Thread_Wait_flags_get(
* @retval true The wait flags were equal to the expected wait flags.
* @retval false Otherwise.
*/
-RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change_critical(
+RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change_release(
Thread_Control *the_thread,
Thread_Wait_flags expected_flags,
Thread_Wait_flags desired_flags
)
{
+ _Assert( _ISR_Get_level() != 0 );
+
#if defined(RTEMS_SMP)
return _Atomic_Compare_exchange_uint(
&the_thread->Wait.flags,
&expected_flags,
desired_flags,
- ATOMIC_ORDER_RELAXED,
+ ATOMIC_ORDER_RELEASE,
ATOMIC_ORDER_RELAXED
);
#else
- bool success = the_thread->Wait.flags == expected_flags;
+ bool success = ( the_thread->Wait.flags == expected_flags );
if ( success ) {
the_thread->Wait.flags = desired_flags;
@@ -1350,30 +1354,44 @@ RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change_critical(
}
/**
- * @brief Tries to change the thread wait flags.
+ * @brief Tries to change the thread wait flags with acquire semantics.
+ *
+ * In case the wait flags are equal to the expected wait flags, then the wait
+ * flags are set to the desired wait flags.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] expected_flags The expected wait flags.
+ * @param[in] desired_flags The desired wait flags.
*
- * @see _Thread_Wait_flags_try_change_critical().
+ * @retval true The wait flags were equal to the expected wait flags.
+ * @retval false Otherwise.
*/
-RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change(
+RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change_acquire(
Thread_Control *the_thread,
Thread_Wait_flags expected_flags,
Thread_Wait_flags desired_flags
)
{
bool success;
-#if !defined(RTEMS_SMP)
+#if defined(RTEMS_SMP)
+ return _Atomic_Compare_exchange_uint(
+ &the_thread->Wait.flags,
+ &expected_flags,
+ desired_flags,
+ ATOMIC_ORDER_ACQUIRE,
+ ATOMIC_ORDER_ACQUIRE
+ );
+#else
ISR_Level level;
_ISR_Local_disable( level );
-#endif
- success = _Thread_Wait_flags_try_change_critical(
+ success = _Thread_Wait_flags_try_change_release(
the_thread,
expected_flags,
desired_flags
);
-#if !defined(RTEMS_SMP)
_ISR_Local_enable( level );
#endif