Module Name: src Committed By: riastradh Date: Sun Mar 9 16:19:14 UTC 2014
Modified Files: src/common/lib/libc/atomic: atomic_cas_by_cas32.c Log Message: 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! To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/common/lib/libc/atomic/atomic_cas_by_cas32.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/common/lib/libc/atomic/atomic_cas_by_cas32.c diff -u src/common/lib/libc/atomic/atomic_cas_by_cas32.c:1.2 src/common/lib/libc/atomic/atomic_cas_by_cas32.c:1.3 --- src/common/lib/libc/atomic/atomic_cas_by_cas32.c:1.2 Fri Mar 7 08:42:58 2014 +++ src/common/lib/libc/atomic/atomic_cas_by_cas32.c Sun Mar 9 16:19:14 2014 @@ -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 @@ _atomic_cas_16(volatile uint16_t *addr, 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 @@ _atomic_cas_8(volatile uint8_t *addr, ui 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; }