/* (C) Matthew Kirkwood <matthew@hairy.beasts.org> */

/* Atomic dec: return 1 unless counter decremented to zero. */
/* Taken from 2.4.18's linux/include/asm-i386/atomic.h */
static int __down(int *counter)
{
	unsigned char c;

	__asm__ __volatile__(
		"lock; decl %0; sete %1"
		:"=m" (*counter), "=qm" (c)
		:"m" (*counter) : "memory");
	return c == 0;
}

/* Atomic inc: return 1 unless counter incremented from 0 to 1. */
static __inline__ int __up(int *c)
{
	int r = 0;

	/* This actually tests if result >= 1. --RR */
	__asm__ __volatile__ (
	"	lock; incl %1\n"
	"	jg 1f\n"
	"	incl %0\n"
	"1:\n"
		: "=q"(r), "=m"(*c) : "0"(r)
	);
	return r;
}

/* Commit the write, so it happens before we send the semaphore to
   anyone else */
static __inline__ void __commit(void)
{
	/* Probably overkill, but some non-Intel clones support
           out-of-order stores, according to 2.5.5-pre1's
           linux/include/asm-i386/system.h */
	__asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory");
}
