[rtems commit] score: Next try to fix thread lock on SMP
Sebastian Huber
sebh at rtems.org
Fri Jul 1 09:58:30 UTC 2016
Module: rtems
Branch: master
Commit: 23dedc448edb864fe1819240d11615d87e278893
Changeset: http://git.rtems.org/rtems/commit/?id=23dedc448edb864fe1819240d11615d87e278893
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Fri Jul 1 07:31:18 2016 +0200
score: Next try to fix thread lock on SMP
---
cpukit/score/include/rtems/score/threadimpl.h | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index b4d2f4f..448f38d 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -1126,10 +1126,6 @@ RTEMS_INLINE_ROUTINE void *_Thread_Lock_acquire(
_ISR_lock_ISR_disable( lock_context );
/*
- * We must use a load acquire here paired with the store release in
- * _Thread_Lock_set_unprotected() to observe corresponding thread wait
- * queue and thread wait operations.
- *
* We assume that a normal load of pointer is identical to a relaxed atomic
* load. Here, we may read an out-of-date lock. However, only the owner
* of this out-of-date lock is allowed to set a new one. Thus, we read at
@@ -1137,7 +1133,7 @@ RTEMS_INLINE_ROUTINE void *_Thread_Lock_acquire(
*/
lock_0 = (SMP_ticket_lock_Control *) _Atomic_Load_uintptr(
&the_thread->Lock.current.atomic,
- ATOMIC_ORDER_ACQUIRE
+ ATOMIC_ORDER_RELAXED
);
_SMP_ticket_lock_Acquire(
@@ -1146,9 +1142,23 @@ RTEMS_INLINE_ROUTINE void *_Thread_Lock_acquire(
&lock_context->Lock_context.Stats_context
);
+ /*
+ * We must use a load acquire here paired with the store release in
+ * _Thread_Lock_set_unprotected() to observe corresponding thread wait
+ * queue and thread wait operations. It is important to do this after the
+ * lock acquire, since we may have the following scenario.
+ *
+ * - We read the default lock and try to acquire it.
+ * - The thread lock changes to a thread queue lock.
+ * - The thread lock is restored to the default lock.
+ * - We acquire the default lock and read it here again.
+ * - Now, we must read the restored default thread wait queue and thread
+ * wait operations and this is not synchronized via the default thread
+ * lock.
+ */
lock_1 = (SMP_ticket_lock_Control *) _Atomic_Load_uintptr(
&the_thread->Lock.current.atomic,
- ATOMIC_ORDER_RELAXED
+ ATOMIC_ORDER_ACQUIRE
);
/*
More information about the vc
mailing list