atomic_dec_and_test() in FreeBSD?
John Baldwin
jhb at FreeBSD.org
Fri Apr 4 11:34:20 PST 2003
On 04-Apr-2003 Craig Rodrigues wrote:
> On Wed, Mar 26, 2003 at 12:13:21PM -0500, John Baldwin wrote:
>> > I am the port maintainer of the Apache Portable Runtime (apr) library.
>> > apr has some atomic functions. For FreeBSD, this is what is defined:
>> >
>> > /**
>> > * decrement the atomic variable by 1
>> > * @param mem pointer to the atomic value
>> > * @return zero if the value is zero, otherwise non-zero
>> > */
>> > int apr_atomic_dec(volatile apr_atomic_t *mem);
>> >
>> > [snip]
>> >
>> >#define apr_atomic_dec(mem) atomic_subtract_int(mem,1)
>> >
>> >
>> > This is obviously quite wrong.
>> >
>> > So are you saying that I should replace this with:
>> >
>> > int apr_atomic_dec(volatile apr_atomic_t *mem);
>> >
>> > int apr_atomic_dec(volatile apr_atomic_t *mem){
>> > apr_atomic_t x
>> > do {
>> > x = *mem;
>> > } while (atomic_cmpset_int(mem, x, x - 1) == 0);
>> > if (x == 1)
>> > /* foo just dropped to zero */
>> >
>> >
>> > ???????
>> > }
>> >
>> > Can you give more guidance?
>>
>> You could do this:
>>
>> apr_atomic_t x;
>>
>> do {
>> x = *mem;
>> } while (atomic_cmpset_int(mem, x, x - 1) == 0);
>> return (x - 1)
>
>
>
> This macro exists on -CURRENT, but I can't seem to find it
> on FreeBSD 4.7. What is the equivalent solution on that platform?
4.7 doesn't have a real good equivalent. However, on 4.7 you can
probably just do:
s = splhigh();
x--;
zero = x == 0;
splx(s);
if (x == 0)
/* refcount is zero */
In fact, depending on what you do in the zero case, you probably
would need to do:
s = splhigh();
if (--x == 0)
/* refcount is zero, call free(), etc. */
splx(s);
--
John Baldwin <jhb at FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve!" - http://www.FreeBSD.org/
More information about the freebsd-smp
mailing list