[rtems commit] score: Fix _Thread_Lock_acquire()
Sebastian Huber
sebh at rtems.org
Wed Jun 1 09:27:10 UTC 2016
Module: rtems
Branch: master
Commit: f807b84ba0b7f55eead115aa66fba808ba561556
Changeset: http://git.rtems.org/rtems/commit/?id=f807b84ba0b7f55eead115aa66fba808ba561556
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Wed Jun 1 11:04:50 2016 +0200
score: Fix _Thread_Lock_acquire()
A read-modify-write operation is necessary to read the last value
written.
See for example C11 standard or Power ISA 2.07, Book II: Power ISA
Virtual Environment Architecture, Section 1.6.3 Memory Coherence
Required [Category: Memory Coherence] and Section 1.7.3 Atomic Update.
---
cpukit/score/include/rtems/score/threadimpl.h | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index d102212..bd2ec50 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -1128,16 +1128,16 @@ RTEMS_INLINE_ROUTINE void *_Thread_Lock_acquire(
SMP_ticket_lock_Control *lock;
while ( true ) {
- unsigned int first_generation;
- unsigned int second_generation;
+ unsigned int my_generation;
+ bool success;
_ISR_lock_ISR_disable( lock_context );
/*
- * Ensure that we read our first lock generation before we obtain our
+ * Ensure that we read our lock generation before we obtain our
* current lock. See _Thread_Lock_set_unprotected().
*/
- first_generation = _Atomic_Load_uint(
+ my_generation = _Atomic_Load_uint(
&the_thread->Lock.generation,
ATOMIC_ORDER_ACQUIRE
);
@@ -1150,17 +1150,18 @@ RTEMS_INLINE_ROUTINE void *_Thread_Lock_acquire(
);
/*
- * The C11 memory model doesn't guarantee that we read the latest
- * generation here. For this a read-modify-write operation would be
- * necessary. We read at least the new generation set up by the owner of
- * our current thread lock, and so on.
+ * We must use a read-modify-write operation to observe the last value
+ * written.
*/
- second_generation = _Atomic_Load_uint(
+ success = _Atomic_Compare_exchange_uint(
&the_thread->Lock.generation,
- ATOMIC_ORDER_ACQUIRE
+ &my_generation,
+ my_generation,
+ ATOMIC_ORDER_RELAXED,
+ ATOMIC_ORDER_RELAXED
);
- if ( first_generation == second_generation ) {
+ if ( success ) {
return lock;
}
More information about the vc
mailing list