sasatom.h
Go to the documentation of this file.
/*
* Copyright (c) 1995-2014 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation, Steven Munroe - initial API and implementation
*/
#ifndef _SASATOMIC_H
#define _SASATOMIC_H
#include <sched.h> // for sched_yield
#define GCC_VERSION \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
typedef unsigned int sas_spin_lock_t;
typedef void* sas_lock_ptr_t;
#if defined(__powerpc64__) || defined (__powerpc__)
#include "sasatom_powerpc.h"
#elif defined(__x86_64__)
#include "sasatom_x86_64.h"
#elif defined(__i386__)
#include "sasatom_i386.h"
#else
#include "sasatom_generic.h"
#endif
#define sas_write_barrier() __arch_sas_write_barrier()
#define sas_read_barrier() __arch_sas_read_barrier()
#define sas_full_barrier() __arch_sas_full_barrier()
#define sas_code_barrier() __asm ("" ::: "memory")
static inline void *
sas_fetch_and_add_ptr(void **pointer, long int delta)
{
return __arch_fetch_and_add_ptr(pointer, delta);
}
static inline long int
sas_fetch_and_add(long *pointer, long int delta)
{
return __arch_fetch_and_add(pointer, delta);
}
static inline long int
sas_fetch_and_and(unsigned int *pointer, int delta)
{
#if GCC_VERSION >= 40700
return __atomic_fetch_and(pointer, delta, __ATOMIC_ACQ_REL);
#else
return __sync_fetch_and_and(pointer, delta);
#endif
}
static inline long int
sas_fetch_and_and_long(unsigned long *pointer, long int delta)
{
#if GCC_VERSION >= 40700
return __atomic_fetch_and(pointer, delta, __ATOMIC_ACQ_REL);
#else
return __sync_fetch_and_and(pointer, delta);
#endif
}
static inline long int
sas_fetch_and_or(unsigned int *pointer, int delta)
{
#if GCC_VERSION >= 40700
return __atomic_fetch_or(pointer, delta, __ATOMIC_ACQ_REL);
#else
return __sync_fetch_and_or(pointer, delta);
#endif
}
static inline long int
sas_fetch_and_or_long(unsigned long *pointer, long int delta)
{
#if GCC_VERSION >= 40700
return __atomic_fetch_or(pointer, delta, __ATOMIC_ACQ_REL);
#else
return __sync_fetch_and_or(pointer, delta);
#endif
}
static inline int
sas_compare_and_swap (volatile long int *p, long int oldval, long int newval)
{
return __arch_compare_and_swap(p, oldval, newval);
}
static inline long int
sas_atomic_swap (long int *p, long int replace)
{
return __arch_atomic_swap(p, replace);
}
static inline void
sas_atomic_inc(long int *p)
{
__arch_atomic_inc(p);
}
static inline void
sas_atomic_dec(long int *p)
{
__arch_atomic_dec(p);
}
static inline void
sas_spin_lock_init (volatile sas_spin_lock_t *lock)
{
sas_read_barrier();
*lock = 0;
}
static inline void
sas_spin_lock (volatile sas_spin_lock_t *lock)
{
__arch_sas_spin_lock(lock);
}
static inline int
sas_spin_trylock (volatile sas_spin_lock_t *lock)
{
return __arch_sas_spin_trylock(lock);
}
static inline void
sas_spin_unlock (volatile sas_spin_lock_t *lock)
{
sas_read_barrier();
*lock = 0;
}
static inline void
sas_lock_ptr_init (volatile sas_lock_ptr_t *lock)
{
sas_read_barrier();
*lock = NULL;
}
static inline void*
sas_lock_ptr (volatile sas_lock_ptr_t *lock)
{
int rc;
long unlocked, locked;
do {
unlocked = (long)(*lock) & -2L;
locked = unlocked | 1;
rc = sas_compare_and_swap ((long int *)lock, unlocked, locked);
} while (!rc);
sas_write_barrier();
return (void*)unlocked;
}
static inline void
sas_set_unlocked_ptr (volatile sas_lock_ptr_t *lock, sas_lock_ptr_t newptr)
{
int rc;
do {
long unlocked= (long)(*lock) & -2L;
long newlocked= (long)newptr | 1;
rc = sas_compare_and_swap ((long int *)lock, unlocked, newlocked);
} while (!rc);
sas_write_barrier();
}
static inline void
sas_set_locked_ptr (volatile sas_lock_ptr_t *lock, sas_lock_ptr_t newptr)
{
int rc;
do {
long locked= (long)(*lock) | 1;
long newlocked= (long)newptr | 1;
rc = sas_compare_and_swap ((long int *)lock, locked, newlocked);
} while (!rc);
}
static inline int
sas_trylock_ptr (volatile sas_lock_ptr_t *lock)
{
int rc;
{
long unlocked= (long)(*lock) & -2L;
long locked= unlocked | 1;
rc = sas_compare_and_swap ((long int *)lock, unlocked, locked);
}
sas_write_barrier();
return !rc;
}
static inline void
sas_unlock_ptr (volatile sas_lock_ptr_t *lock)
{
int rc;
sas_read_barrier();
do {
long unlocked= (long)(*lock) & -2L;
long locked= unlocked | 1;
rc = sas_compare_and_swap ((long int *)lock, locked, unlocked);
} while (!rc);
}
static inline void
sas_spin_lock_with_yield (volatile sas_spin_lock_t *lock)
{
int rc;
if (sas_spin_trylock(lock) == 0)
return;
if (sas_spin_trylock(lock) == 0)
return;
if (sas_spin_trylock(lock) == 0)
return;
if (sas_spin_trylock(lock) == 0)
return;
do
{
sched_yield();
rc = sas_spin_trylock(lock);
}
while (rc);
}
static inline void
sas_lock_ptr_with_yield (volatile sas_lock_ptr_t *lock)
{
int rc;
if (sas_trylock_ptr(lock) == 0)
return;
if (sas_trylock_ptr(lock) == 0)
return;
if (sas_trylock_ptr(lock) == 0)
return;
if (sas_trylock_ptr(lock) == 0)
return;
do
{
sched_yield();
rc = sas_trylock_ptr(lock);
}
while (rc);
return;
}
#if 1
static inline long
sas_atomic_inc_long (volatile long *value)
{
long result;
long delta = 1;
#if GCC_VERSION >= 40700
result = __atomic_fetch_add(value, delta, __ATOMIC_ACQUIRE);
#else
result = __sync_fetch_and_add(value, delta);
#endif
return result;
}
static inline long
sas_atomic_dec_long (volatile long *value)
{
long result;
long delta = -1;
#if GCC_VERSION >= 40700
result = __atomic_fetch_add(value, delta, __ATOMIC_ACQUIRE);
#else
result = __sync_fetch_and_add(value, delta);
#endif
return result;
}
#endif
#endif /*_SASATOMIC_H */
sas_fetch_and_add_ptr
static void * sas_fetch_and_add_ptr(void **pointer, long int delta)
Definition: sasatom.h:77
sas_atomic_dec_long
static long sas_atomic_dec_long(volatile long *value)
Definition: sasatom.h:427
sas_fetch_and_add
static long int sas_fetch_and_add(long *pointer, long int delta)
Definition: sasatom.h:91
sas_spin_lock
static void sas_spin_lock(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:229
sas_trylock_ptr
static int sas_trylock_ptr(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:322
sas_spin_unlock
static void sas_spin_unlock(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:251
sas_fetch_and_or
static long int sas_fetch_and_or(unsigned int *pointer, int delta)
Definition: sasatom.h:141
sas_fetch_and_and_long
static long int sas_fetch_and_and_long(unsigned long *pointer, long int delta)
Definition: sasatom.h:123
sas_lock_ptr_t
void * sas_lock_ptr_t
Definition: sasatom.h:36
sas_spin_lock_t
unsigned int sas_spin_lock_t
Definition: sasatom.h:34
sas_compare_and_swap
static int sas_compare_and_swap(volatile long int *p, long int oldval, long int newval)
Definition: sasatom.h:176
sas_read_barrier
#define sas_read_barrier()
Definition: sasatom.h:56
sas_set_locked_ptr
static void sas_set_locked_ptr(volatile sas_lock_ptr_t *lock, sas_lock_ptr_t newptr)
Definition: sasatom.h:307
sas_spin_lock_with_yield
static void sas_spin_lock_with_yield(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:356
sas_lock_ptr_init
static void sas_lock_ptr_init(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:262
sas_unlock_ptr
static void sas_unlock_ptr(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:339
sas_atomic_swap
static long int sas_atomic_swap(long int *p, long int replace)
Definition: sasatom.h:188
sas_atomic_dec
static void sas_atomic_dec(long int *p)
Definition: sasatom.h:206
sas_spin_trylock
static int sas_spin_trylock(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:242
sas_atomic_inc
static void sas_atomic_inc(long int *p)
Definition: sasatom.h:197
sas_set_unlocked_ptr
static void sas_set_unlocked_ptr(volatile sas_lock_ptr_t *lock, sas_lock_ptr_t newptr)
Definition: sasatom.h:291
sas_lock_ptr_with_yield
static void sas_lock_ptr_with_yield(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:382
sas_fetch_and_or_long
static long int sas_fetch_and_or_long(unsigned long *pointer, long int delta)
Definition: sasatom.h:159
sas_spin_lock_init
static void sas_spin_lock_init(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:216
sas_lock_ptr
static void * sas_lock_ptr(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:272
sas_fetch_and_and
static long int sas_fetch_and_and(unsigned int *pointer, int delta)
Definition: sasatom.h:105
sas_atomic_inc_long
static long sas_atomic_inc_long(volatile long *value)
Definition: sasatom.h:409
sas_write_barrier
#define sas_write_barrier()
Definition: sasatom.h:51