/* Copyright (c) 2009-2011 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * x86 atomics and locking functions. */

#ifndef ROS_KERN_ARCH_ATOMIC_H
#define ROS_KERN_ARCH_ATOMIC_H

#include <ros/common.h>
#include <ros/arch/membar.h>
#include <arch/x86.h>
#include <arch/arch.h>

static inline void atomic_andb(volatile uint8_t *number, uint8_t mask);
static inline void atomic_orb(volatile uint8_t *number, uint8_t mask);

/* Inlined functions declared above */
static inline void atomic_init(atomic_t *number, long val)
{
	asm volatile("mov %1,%0" : "=m"(*number) : "r"(val));
}

static inline long atomic_read(atomic_t *number)
{
	long val;
	asm volatile("mov %1,%0" : "=r"(val) : "m"(*number));
	return val;
}

static inline void atomic_set(atomic_t *number, long val)
{
	asm volatile("mov %1,%0" : "=m"(*number) : "r"(val));
}

static inline void atomic_add(atomic_t *number, long val)
{
	__sync_fetch_and_add(number, val);
}

static inline void atomic_inc(atomic_t *number)
{
	__sync_fetch_and_add(number, 1);
}

static inline void atomic_dec(atomic_t *number)
{
	__sync_fetch_and_sub(number, 1);
}

static inline long atomic_fetch_and_add(atomic_t *number, long val)
{
	return (long)__sync_fetch_and_add(number, val);
}

static inline void atomic_and(atomic_t *number, long mask)
{
	__sync_fetch_and_and(number, mask);
}

static inline void atomic_or(atomic_t *number, long mask)
{
	__sync_fetch_and_or(number, mask);
}

static inline long atomic_swap(atomic_t *addr, long val)
{
	/* This poorly named function does an xchg */
	return (long)__sync_lock_test_and_set(addr, val);
}

static inline bool atomic_cas(atomic_t *addr, long exp_val, long new_val)
{
	return __sync_bool_compare_and_swap(addr, exp_val, new_val);
}

static inline bool atomic_cas_ptr(void **addr, void *exp_val, void *new_val)
{
	return __sync_bool_compare_and_swap(addr, exp_val, new_val);
}

static inline bool atomic_cas_u32(uint32_t *addr, uint32_t exp_val,
                                  uint32_t new_val)
{
	return __sync_bool_compare_and_swap(addr, exp_val, new_val);
}

/* Adds val to number, so long as number was not zero.  Returns TRUE if the
 * operation succeeded (added, not zero), returns FALSE if number is zero. */
static inline bool atomic_add_not_zero(atomic_t *number, long val)
{
	long old_num, new_num;
	do {
		old_num = atomic_read(number);
		if (!old_num)
			return FALSE;
		new_num = old_num + val;
	} while (!atomic_cas(number, old_num, new_num));
	return TRUE;
}

/* Subtracts val from number, returning True if the new value is 0. */
static inline bool atomic_sub_and_test(atomic_t *number, long val)
{
	bool b;
	asm volatile("lock sub %2,%1; setz %0" : "=q"(b), "=m"(*number)
	                                       : "r"(val), "m"(*number)
	                                       : "cc" );
	return b;
}

static inline void atomic_andb(volatile uint8_t *number, uint8_t mask)
{
	__sync_fetch_and_and(number, mask);
}

static inline void atomic_orb(volatile uint8_t *number, uint8_t mask)
{
	__sync_fetch_and_or(number, mask);
}

static inline bool spin_locked(spinlock_t *lock)
{
	// the lock status is the lowest byte of the lock
	return lock->rlock & 0xff;
}

static inline void __spin_lock_raw(volatile uint32_t *rlock)
{
	uint8_t dicks = 0;
	asm volatile(
			"1:                       "
			"	cmpb $0, %0;          "
			"	je 2f;                "
			"	pause;                "
			"	jmp 1b;               "
			"2:                       " 
			"	movb $1, %1;          "
			"	xchgb %1, %0;         "
			"	cmpb $0, %1;          "
			"	jne 1b;               "
	        : : "m"(*rlock), "r"(dicks) : "cc");
	cmb();	/* need cmb(), the CPU mb() was handled by the xchg */
}

static inline void __spin_lock(spinlock_t *lock)
{
	__spin_lock_raw(&lock->rlock);
}

static inline bool __spin_trylock(spinlock_t *lock)
{
	/* since this is an or, we're not going to clobber the top bytes (if that
	 * matters) */
	return !__sync_fetch_and_or(&lock->rlock, 1);
}

static inline void __spin_unlock(spinlock_t *lock)
{
	/* Need to prevent the compiler from reordering older stores. */
	wmb();
	rwmb();	/* x86 makes both of these a cmb() */
	lock->rlock = 0;
}

static inline void __spinlock_init(spinlock_t *lock)
{
	lock->rlock = 0;
}

#endif /* ROS_KERN_ARCH_ATOMIC_H */
