x86: Implement atomic[64]_dec_if_positive()
Add support for atomic_dec_if_positive(), and atomic64_dec_if_positive() for x86-64. atomic64_dec_if_positive() for x86-32 was already implemented in a previous patch. Signed-off-by: Luca Barbieri <luca@luca-barbieri.com> LKML-Reference: <1267183361-20775-2-git-send-email-luca@luca-barbieri.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
8f4f202b33
commit
d7f6de1e9c
|
@ -246,6 +246,29 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
|
||||||
|
|
||||||
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
|
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* atomic_dec_if_positive - decrement by 1 if old value positive
|
||||||
|
* @v: pointer of type atomic_t
|
||||||
|
*
|
||||||
|
* The function returns the old value of *v minus 1, even if
|
||||||
|
* the atomic variable, v, was not decremented.
|
||||||
|
*/
|
||||||
|
static inline int atomic_dec_if_positive(atomic_t *v)
|
||||||
|
{
|
||||||
|
int c, old, dec;
|
||||||
|
c = atomic_read(v);
|
||||||
|
for (;;) {
|
||||||
|
dec = c - 1;
|
||||||
|
if (unlikely(dec < 0))
|
||||||
|
break;
|
||||||
|
old = atomic_cmpxchg((v), c, dec);
|
||||||
|
if (likely(old == c))
|
||||||
|
break;
|
||||||
|
c = old;
|
||||||
|
}
|
||||||
|
return dec;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* atomic_inc_short - increment of a short integer
|
* atomic_inc_short - increment of a short integer
|
||||||
* @v: pointer to type int
|
* @v: pointer to type int
|
||||||
|
|
|
@ -221,4 +221,27 @@ static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
|
||||||
|
|
||||||
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
|
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* atomic64_dec_if_positive - decrement by 1 if old value positive
|
||||||
|
* @v: pointer of type atomic_t
|
||||||
|
*
|
||||||
|
* The function returns the old value of *v minus 1, even if
|
||||||
|
* the atomic variable, v, was not decremented.
|
||||||
|
*/
|
||||||
|
static inline long atomic64_dec_if_positive(atomic64_t *v)
|
||||||
|
{
|
||||||
|
long c, old, dec;
|
||||||
|
c = atomic64_read(v);
|
||||||
|
for (;;) {
|
||||||
|
dec = c - 1;
|
||||||
|
if (unlikely(dec < 0))
|
||||||
|
break;
|
||||||
|
old = atomic64_cmpxchg((v), c, dec);
|
||||||
|
if (likely(old == c))
|
||||||
|
break;
|
||||||
|
c = old;
|
||||||
|
}
|
||||||
|
return dec;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _ASM_X86_ATOMIC64_64_H */
|
#endif /* _ASM_X86_ATOMIC64_64_H */
|
||||||
|
|
|
@ -112,7 +112,7 @@ static __init int test_atomic64(void)
|
||||||
r += one;
|
r += one;
|
||||||
BUG_ON(v.counter != r);
|
BUG_ON(v.counter != r);
|
||||||
|
|
||||||
#if defined(CONFIG_X86_32) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(_ASM_GENERIC_ATOMIC64_H)
|
#if defined(CONFIG_X86) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(_ASM_GENERIC_ATOMIC64_H)
|
||||||
INIT(onestwos);
|
INIT(onestwos);
|
||||||
BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1));
|
BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1));
|
||||||
r -= one;
|
r -= one;
|
||||||
|
|
Loading…
Reference in New Issue