PageRenderTime 28ms CodeModel.GetById 12ms app.highlight 10ms RepoModel.GetById 2ms app.codeStats 0ms

/contrib/bind9/lib/isc/ia64/include/isc/atomic.h

https://bitbucket.org/freebsd/freebsd-head/
C++ Header | 100 lines | 57 code | 12 blank | 31 comment | 3 complexity | 1c787fef15eca0cf25e3024a7a095fb4 MD5 | raw file
  1/*
  2 * Copyright (C) 2006, 2007, 2009  Internet Systems Consortium, Inc. ("ISC")
  3 *
  4 * Permission to use, copy, modify, and/or distribute this software for any
  5 * purpose with or without fee is hereby granted, provided that the above
  6 * copyright notice and this permission notice appear in all copies.
  7 *
  8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 10 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 14 * PERFORMANCE OF THIS SOFTWARE.
 15 */
 16
 17/* $Id: atomic.h,v 1.7 2009/06/24 02:22:50 marka Exp $ */
 18
 19#ifndef ISC_ATOMIC_H
 20#define ISC_ATOMIC_H 1
 21
 22#include <isc/platform.h>
 23#include <isc/types.h>
 24
 25#ifdef ISC_PLATFORM_USEGCCASM
 26/*
 27 * This routine atomically increments the value stored in 'p' by 'val', and
 28 * returns the previous value.
 29 *
 30 * Open issue: can 'fetchadd' make the code faster for some particular values
 31 * (e.g., 1 and -1)?
 32 */
 33static inline isc_int32_t
 34#ifdef __GNUC__
 35__attribute__ ((unused))
 36#endif
 37isc_atomic_xadd(isc_int32_t *p, isc_int32_t val)
 38{
 39	isc_int32_t prev, swapped;
 40
 41	for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) {
 42		swapped = prev + val;
 43		__asm__ volatile(
 44			"mov ar.ccv=%2;;"
 45			"cmpxchg4.acq %0=%4,%3,ar.ccv"
 46			: "=r" (swapped), "=m" (*p)
 47			: "r" (prev), "r" (swapped), "m" (*p)
 48			: "memory");
 49		if (swapped == prev)
 50			break;
 51	}
 52
 53	return (prev);
 54}
 55
 56/*
 57 * This routine atomically stores the value 'val' in 'p'.
 58 */
 59static inline void
 60#ifdef __GNUC__
 61__attribute__ ((unused))
 62#endif
 63isc_atomic_store(isc_int32_t *p, isc_int32_t val)
 64{
 65	__asm__ volatile(
 66		"st4.rel %0=%1"
 67		: "=m" (*p)
 68		: "r" (val)
 69		: "memory"
 70		);
 71}
 72
 73/*
 74 * This routine atomically replaces the value in 'p' with 'val', if the
 75 * original value is equal to 'cmpval'.  The original value is returned in any
 76 * case.
 77 */
 78static inline isc_int32_t
 79#ifdef __GNUC__
 80__attribute__ ((unused))
 81#endif
 82isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val)
 83{
 84	isc_int32_t ret;
 85
 86	__asm__ volatile(
 87		"mov ar.ccv=%2;;"
 88		"cmpxchg4.acq %0=%4,%3,ar.ccv"
 89		: "=r" (ret), "=m" (*p)
 90		: "r" (cmpval), "r" (val), "m" (*p)
 91		: "memory");
 92
 93	return (ret);
 94}
 95#else /* !ISC_PLATFORM_USEGCCASM */
 96
 97#error "unsupported compiler.  disable atomic ops by --disable-atomic"
 98
 99#endif
100#endif /* ISC_ATOMIC_H */