/* * %CopyrightBegin% * * Copyright Ericsson AB 2010. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * %CopyrightEnd% */ /* * Description: The ethread atomic API * Author: Rickard Green */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define ETHR_INLINE_FUNC_NAME_(X) X ## __ #define ETHR_ATOMIC_IMPL__ #include "ethread.h" #include "ethr_internal.h" #ifndef ETHR_HAVE_NATIVE_ATOMICS ethr_atomic_protection_t ethr_atomic_protection__[1 << ETHR_ATOMIC_ADDR_BITS]; #endif int ethr_init_atomics(void) { #ifndef ETHR_HAVE_NATIVE_ATOMICS { int i; for (i = 0; i < (1 << ETHR_ATOMIC_ADDR_BITS); i++) { int res = ethr_spinlock_init(ðr_atomic_protection__[i].u.lck); if (res != 0) return res; } } #endif return 0; } /* * --- Pointer size atomics --------------------------------------------------- */ ethr_sint_t * ethr_atomic_addr(ethr_atomic_t *var) { ETHR_ASSERT(var); return ethr_atomic_addr__(var); } void ethr_atomic_init(ethr_atomic_t *var, ethr_sint_t i) { ETHR_ASSERT(var); ethr_atomic_init__(var, i); } void ethr_atomic_set(ethr_atomic_t *var, ethr_sint_t i) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); ethr_atomic_set__(var, i); } ethr_sint_t ethr_atomic_read(ethr_atomic_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic_read__(var); } ethr_sint_t ethr_atomic_add_read(ethr_atomic_t *var, ethr_sint_t incr) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic_add_read__(var, incr); } ethr_sint_t ethr_atomic_inc_read(ethr_atomic_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic_inc_read__(var); } ethr_sint_t ethr_atomic_dec_read(ethr_atomic_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic_dec_read__(var); } void ethr_atomic_add(ethr_atomic_t *var, ethr_sint_t incr) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); ethr_atomic_add__(var, incr); } void ethr_atomic_inc(ethr_atomic_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); ethr_atomic_inc__(var); } void ethr_atomic_dec(ethr_atomic_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); ethr_atomic_dec__(var); } ethr_sint_t ethr_atomic_read_band(ethr_atomic_t *var, ethr_sint_t mask) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic_read_band__(var, mask); } ethr_sint_t ethr_atomic_read_bor(ethr_atomic_t *var, ethr_sint_t mask) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic_read_bor__(var, mask); } ethr_sint_t ethr_atomic_xchg(ethr_atomic_t *var, ethr_sint_t new) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic_xchg__(var, new); } ethr_sint_t ethr_atomic_cmpxchg(ethr_atomic_t *var, ethr_sint_t new, ethr_sint_t expected) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic_cmpxchg__(var, new, expected); } ethr_sint_t ethr_atomic_read_acqb(ethr_atomic_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic_read_acqb__(var); } ethr_sint_t ethr_atomic_inc_read_acqb(ethr_atomic_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic_inc_read_acqb__(var); } void ethr_atomic_set_relb(ethr_atomic_t *var, ethr_sint_t i) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); ethr_atomic_set_relb__(var, i); } void ethr_atomic_dec_relb(ethr_atomic_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); ethr_atomic_dec_relb__(var); } ethr_sint_t ethr_atomic_dec_read_relb(ethr_atomic_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic_dec_read_relb__(var); } ethr_sint_t ethr_atomic_cmpxchg_acqb(ethr_atomic_t *var, ethr_sint_t new, ethr_sint_t exp) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic_cmpxchg_acqb__(var, new, exp); } ethr_sint_t ethr_atomic_cmpxchg_relb(ethr_atomic_t *var, ethr_sint_t new, ethr_sint_t exp) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic_cmpxchg_relb__(var, new, exp); } /* * --- 32-bit atomics --------------------------------------------------------- */ ethr_sint32_t * ethr_atomic32_addr(ethr_atomic32_t *var) { ETHR_ASSERT(var); return ethr_atomic32_addr__(var); } void ethr_atomic32_init(ethr_atomic32_t *var, ethr_sint32_t i) { ETHR_ASSERT(var); ethr_atomic32_init__(var, i); } void ethr_atomic32_set(ethr_atomic32_t *var, ethr_sint32_t i) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); ethr_atomic32_set__(var, i); } ethr_sint32_t ethr_atomic32_read(ethr_atomic32_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic32_read__(var); } ethr_sint32_t ethr_atomic32_add_read(ethr_atomic32_t *var, ethr_sint32_t incr) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic32_add_read__(var, incr); } ethr_sint32_t ethr_atomic32_inc_read(ethr_atomic32_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic32_inc_read__(var); } ethr_sint32_t ethr_atomic32_dec_read(ethr_atomic32_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic32_dec_read__(var); } void ethr_atomic32_add(ethr_atomic32_t *var, ethr_sint32_t incr) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); ethr_atomic32_add__(var, incr); } void ethr_atomic32_inc(ethr_atomic32_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); ethr_atomic32_inc__(var); } void ethr_atomic32_dec(ethr_atomic32_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); ethr_atomic32_dec__(var); } ethr_sint32_t ethr_atomic32_read_band(ethr_atomic32_t *var, ethr_sint32_t mask) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic32_read_band__(var, mask); } ethr_sint32_t ethr_atomic32_read_bor(ethr_atomic32_t *var, ethr_sint32_t mask) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic32_read_bor__(var, mask); } ethr_sint32_t ethr_atomic32_xchg(ethr_atomic32_t *var, ethr_sint32_t new) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic32_xchg__(var, new); } ethr_sint32_t ethr_atomic32_cmpxchg(ethr_atomic32_t *var, ethr_sint32_t new, ethr_sint32_t expected) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic32_cmpxchg__(var, new, expected); } ethr_sint32_t ethr_atomic32_read_acqb(ethr_atomic32_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic32_read_acqb__(var); } ethr_sint32_t ethr_atomic32_inc_read_acqb(ethr_atomic32_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic32_inc_read_acqb__(var); } void ethr_atomic32_set_relb(ethr_atomic32_t *var, ethr_sint32_t i) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); ethr_atomic32_set_relb__(var, i); } void ethr_atomic32_dec_relb(ethr_atomic32_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); ethr_atomic32_dec_relb__(var); } ethr_sint32_t ethr_atomic32_dec_read_relb(ethr_atomic32_t *var) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic32_dec_read_relb__(var); } ethr_sint32_t ethr_atomic32_cmpxchg_acqb(ethr_atomic32_t *var, ethr_sint32_t new, ethr_sint32_t exp) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic32_cmpxchg_acqb__(var, new, exp); } ethr_sint32_t ethr_atomic32_cmpxchg_relb(ethr_atomic32_t *var, ethr_sint32_t new, ethr_sint32_t exp) { ETHR_ASSERT(!ethr_not_inited__); ETHR_ASSERT(var); return ethr_atomic32_cmpxchg_relb__(var, new, exp); }