⛏️ index : haiku.git

/*
 * Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org.
 * Distributed under the terms of the MIT License.
 */
#ifndef _KERNEL_ARCH_X86_32_ATOMIC_H
#define _KERNEL_ARCH_X86_32_ATOMIC_H


static inline void
memory_read_barrier_inline(void)
{
	asm volatile("lock; addl $0, (%%esp)" : : : "memory");
}


static inline void
memory_write_barrier_inline(void)
{
	asm volatile("lock; addl $0, (%%esp)" : : : "memory");
}


static inline void
memory_full_barrier_inline(void)
{
	asm volatile("lock; addl $0, (%%esp)" : : : "memory");
}


#define memory_read_barrier		memory_read_barrier_inline
#define memory_write_barrier	memory_write_barrier_inline
#define memory_full_barrier		memory_full_barrier_inline


#if __GNUC__ < 4


static inline void
atomic_set_inline(int32* value, int32 newValue)
{
	memory_write_barrier();
	*(volatile int32*)value = newValue;
}


static inline int32
atomic_get_and_set_inline(int32* value, int32 newValue)
{
	asm volatile("xchgl %0, (%1)"
		: "+r" (newValue)
		: "r" (value)
		: "memory");
	return newValue;
}


static inline int32
atomic_test_and_set_inline(int32* value, int32 newValue, int32 testAgainst)
{
	asm volatile("lock; cmpxchgl %2, (%3)"
		: "=a" (newValue)
		: "0" (testAgainst), "r" (newValue), "r" (value)
		: "memory");
	return newValue;
}


static inline int32
atomic_add_inline(int32* value, int32 newValue)
{
	asm volatile("lock; xaddl %0, (%1)"
		: "+r" (newValue)
		: "r" (value)
		: "memory");
	return newValue;
}


static inline int32
atomic_get_inline(int32* value)
{
	int32 newValue = *(volatile int32*)value;
	memory_read_barrier();
	return newValue;
}


#define atomic_set				atomic_set_inline
#define atomic_get_and_set		atomic_get_and_set_inline
#define atomic_test_and_set		atomic_test_and_set_inline
#define atomic_add				atomic_add_inline
#define atomic_get				atomic_get_inline


#endif	// dark ages


#endif	// _KERNEL_ARCH_X86_32_ATOMIC_H