Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/common/lib/libc/atomic Fix subword atomic_cas.
details: https://anonhg.NetBSD.org/src/rev/e27d5865837a
branches: trunk
changeset: 327488:e27d5865837a
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sun Mar 09 16:19:14 2014 +0000
description:
Fix subword atomic_cas.
- Don't loop forever on failure.
- Don't shift away the result and return zero on success.
Evidently we lack automatic tests for these!
diffstat:
common/lib/libc/atomic/atomic_cas_by_cas32.c | 22 +++++++++++++++-------
1 files changed, 15 insertions(+), 7 deletions(-)
diffs (51 lines):
diff -r 51f93eadf38e -r e27d5865837a common/lib/libc/atomic/atomic_cas_by_cas32.c
--- a/common/lib/libc/atomic/atomic_cas_by_cas32.c Sun Mar 09 16:18:00 2014 +0000
+++ b/common/lib/libc/atomic/atomic_cas_by_cas32.c Sun Mar 09 16:19:14 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: atomic_cas_by_cas32.c,v 1.2 2014/03/07 08:42:58 martin Exp $ */
+/* $NetBSD: atomic_cas_by_cas32.c,v 1.3 2014/03/09 16:19:14 riastradh Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -48,14 +48,18 @@
volatile uint32_t * ptr = (volatile uint32_t *)base;
const size_t shift = off*8;
const uint32_t mask = 0x0ffff << shift;
+ const uint32_t old32_part = (uint32_t)old << shift;
+ const uint32_t new32_part = (uint32_t)new << shift;
uint32_t old32, new32;
do {
old32 = *ptr;
- new32 = (old32 & ~mask) | (uint32_t)new << shift;
- old32 = (old32 & ~mask) | (uint32_t)old << shift;
+ if ((old32 & mask) != old32_part)
+ return (uint16_t)((old32 & mask) >> shift);
+ new32 = (old32 & ~mask) | new32_part;
} while (_atomic_cas_32(ptr, old32, new32) != old32);
- return (old & mask) >> shift;
+
+ return old;
}
uint8_t
@@ -66,12 +70,16 @@
volatile uint32_t * ptr = (volatile uint32_t *)base;
const size_t shift = off*8;
const uint32_t mask = 0x0ff << shift;
+ const uint32_t old32_part = (uint32_t)old << shift;
+ const uint32_t new32_part = (uint32_t)new << shift;
uint32_t old32, new32;
do {
old32 = *ptr;
- new32 = (old32 & ~mask) | (uint32_t)new << shift;
- old32 = (old32 & ~mask) | (uint32_t)old << shift;
+ if ((old32 & mask) != old32_part)
+ return (uint8_t)((old32 & mask) >> shift);
+ new32 = (old32 & ~mask) | new32_part;
} while (_atomic_cas_32(ptr, old32, new32) != old32);
- return (old & mask) >> shift;
+
+ return old;
}
Home |
Main Index |
Thread Index |
Old Index