1170431Spjd/*- 2170431Spjd * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3170431Spjd * All rights reserved. 4170431Spjd * 5170431Spjd * Redistribution and use in source and binary forms, with or without 6170431Spjd * modification, are permitted provided that the following conditions 7170431Spjd * are met: 8170431Spjd * 1. Redistributions of source code must retain the above copyright 9170431Spjd * notice, this list of conditions and the following disclaimer. 10170431Spjd * 2. Redistributions in binary form must reproduce the above copyright 11170431Spjd * notice, this list of conditions and the following disclaimer in the 12170431Spjd * documentation and/or other materials provided with the distribution. 13170431Spjd * 14170431Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15170431Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16170431Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17170431Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18170431Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19170431Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20170431Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21170431Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22170431Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23170431Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24170431Spjd * SUCH DAMAGE. 25170431Spjd * 26170431Spjd * $FreeBSD$ 27170431Spjd */ 28170431Spjd 29170431Spjd#ifndef _OPENSOLARIS_SYS_ATOMIC_H_ 30170431Spjd#define _OPENSOLARIS_SYS_ATOMIC_H_ 31170431Spjd 32170431Spjd#include <sys/types.h> 33170431Spjd#include <machine/atomic.h> 34170431Spjd 35179202Sjb#define casptr(_a, _b, _c) \ 36179202Sjb atomic_cmpset_ptr((volatile uintptr_t *)(_a), (uintptr_t)(_b), (uintptr_t) (_c)) 37179202Sjb#define cas32 atomic_cmpset_32 38179202Sjb 39218007Sjchandra#if !defined(__LP64__) && !defined(__mips_n32) 40170431Spjdextern void atomic_add_64(volatile uint64_t *target, int64_t delta); 41185029Spjdextern void atomic_dec_64(volatile uint64_t *target); 42218007Sjchandra#endif 43170431Spjd#ifndef __sparc64__ 44219089Spjdextern uint32_t atomic_cas_32(volatile uint32_t *target, uint32_t cmp, 45219089Spjd uint32_t newval); 46170431Spjdextern uint64_t atomic_cas_64(volatile uint64_t *target, uint64_t cmp, 47170431Spjd uint64_t newval); 48170431Spjd#endif 49170431Spjdextern uint64_t atomic_add_64_nv(volatile uint64_t *target, int64_t delta); 50170431Spjdextern uint8_t atomic_or_8_nv(volatile uint8_t *target, uint8_t value); 51170431Spjdextern void membar_producer(void); 52170431Spjd 53183154Simp#if defined(__sparc64__) || defined(__powerpc__) || defined(__arm__) || \ 54183154Simp defined(__mips__) 55170431Spjdextern void atomic_or_8(volatile uint8_t *target, uint8_t value); 56170431Spjd#else 57170431Spjdstatic __inline void 58170431Spjdatomic_or_8(volatile uint8_t *target, uint8_t value) 59170431Spjd{ 60170431Spjd atomic_set_8(target, value); 61170431Spjd} 62170431Spjd#endif 63170431Spjd 64170431Spjdstatic __inline uint32_t 65170431Spjdatomic_add_32_nv(volatile uint32_t *target, int32_t delta) 66170431Spjd{ 67170431Spjd return (atomic_fetchadd_32(target, delta) + delta); 68170431Spjd} 69170431Spjd 70170431Spjdstatic __inline u_int 71170431Spjdatomic_add_int_nv(volatile u_int *target, int delta) 72170431Spjd{ 73170431Spjd return (atomic_add_32_nv(target, delta)); 74170431Spjd} 75170431Spjd 76170431Spjdstatic __inline void 77170431Spjdatomic_dec_32(volatile uint32_t *target) 78170431Spjd{ 79170431Spjd atomic_subtract_32(target, 1); 80170431Spjd} 81170431Spjd 82170431Spjdstatic __inline uint32_t 83170431Spjdatomic_dec_32_nv(volatile uint32_t *target) 84170431Spjd{ 85170431Spjd return (atomic_fetchadd_32(target, -1) - 1); 86170431Spjd} 87170431Spjd 88218007Sjchandra#if defined(__LP64__) || defined(__mips_n32) 89170431Spjdstatic __inline void 90185029Spjdatomic_dec_64(volatile uint64_t *target) 91185029Spjd{ 92185029Spjd atomic_subtract_64(target, 1); 93185029Spjd} 94185029Spjd#endif 95185029Spjd 96185029Spjdstatic __inline void 97170431Spjdatomic_inc_32(volatile uint32_t *target) 98170431Spjd{ 99170431Spjd atomic_add_32(target, 1); 100170431Spjd} 101170431Spjd 102170431Spjdstatic __inline uint32_t 103170431Spjdatomic_inc_32_nv(volatile uint32_t *target) 104170431Spjd{ 105170431Spjd return (atomic_add_32_nv(target, 1)); 106170431Spjd} 107170431Spjd 108170431Spjdstatic __inline void 109170431Spjdatomic_inc_64(volatile uint64_t *target) 110170431Spjd{ 111170431Spjd atomic_add_64(target, 1); 112170431Spjd} 113170431Spjd 114170431Spjdstatic __inline uint64_t 115170431Spjdatomic_inc_64_nv(volatile uint64_t *target) 116170431Spjd{ 117170431Spjd return (atomic_add_64_nv(target, 1)); 118170431Spjd} 119170431Spjd 120219089Spjd#if !defined(COMPAT_32BIT) && defined(__LP64__) 121170431Spjdstatic __inline void * 122170431Spjdatomic_cas_ptr(volatile void *target, void *cmp, void *newval) 123170431Spjd{ 124219089Spjd return ((void *)atomic_cas_64((volatile uint64_t *)target, 125219089Spjd (uint64_t)cmp, (uint64_t)newval)); 126170431Spjd} 127219089Spjd#else 128219089Spjdstatic __inline void * 129219089Spjdatomic_cas_ptr(volatile void *target, void *cmp, void *newval) 130219089Spjd{ 131219089Spjd return ((void *)atomic_cas_32((volatile uint32_t *)target, 132219089Spjd (uint32_t)cmp, (uint32_t)newval)); 133219089Spjd} 134219089Spjd#endif /* !defined(COMPAT_32BIT) && defined(__LP64__) */ 135170431Spjd 136170431Spjd#endif /* !_OPENSOLARIS_SYS_ATOMIC_H_ */ 137