• Chris Metcalf's avatar
    tile: rework <asm/cmpxchg.h> · 6dc9658f
    Chris Metcalf authored
    The macrology in cmpxchg.h was designed to allow arbitrary pointer
    and integer values to be passed through the routines.  To support
    cmpxchg() on 64-bit values on the 32-bit tilepro architecture, we
    used the idiom "(typeof(val))(typeof(val-val))".  This way, in the
    "size 8" branch of the switch, when the underlying cmpxchg routine
    returns a 64-bit quantity, we cast it first to a typeof(val-val)
    quantity (i.e. size_t if "val" is a pointer) with no warnings about
    casting between pointers and integers of different sizes, then cast
    onwards to typeof(val), again with no warnings.  If val is not a
    pointer type, the additional cast is a no-op.  We can't replace the
    typeof(val-val) cast with (for example) unsigned long, since then if
    "val" is really a 64-bit type, we cast away the high bits.
    
    HOWEVER, this fails with current gcc (through 4.7 at least) if "val"
    is a pointer to an incomplete type.  Unfortunately gcc isn't smart
    enough to realize that "val - val" will always be a size_t type
    even if it's an incomplete type pointer.
    
    Accordingly, I've reworked the way we handle the casting.  We have
    given up the ability to use cmpxchg() on 64-bit values on tilepro,
    which is OK in the kernel since we should use cmpxchg64() explicitly
    on such values anyway.  As a result, I can just use simple "unsigned
    long" casts internally.
    
    As I reworked it, I realized it would be cleaner to move the
    architecture-specific conditionals for cmpxchg and xchg out of the
    atomic.h headers and into cmpxchg, and then use the cmpxchg() and
    xchg() primitives directly in atomic.h and elsewhere.  This allowed
    the cmpxchg.h header to stand on its own without relying on the
    implicit include of it that is performed by <asm/atomic.h>.
    It also allowed collapsing the atomic_xchg/atomic_cmpxchg routines
    from atomic_{32,64}.h into atomic.h.
    
    I improved the tests that guard the allowed size of the arguments
    to the routines to use a __compiletime_error() test.  (By avoiding
    the use of BUILD_BUG, I could include cmpxchg.h into bitops.h as
    well and use the macros there, which is otherwise impossible due
    to include order dependency issues.)
    
    The tilepro _atomic_xxx internal methods were previously set up to
    take atomic_t and atomic64_t arguments, which isn't as convenient
    with the new model, so I modified them to take int or u64 arguments,
    which is consistent with how they used the arguments internally
    anyway, so provided some nice simplification there too.
    Signed-off-by: default avatarChris Metcalf <cmetcalf@tilera.com>
    6dc9658f
bitops_32.h 4.13 KB