atomic_dec_and_test() in FreeBSD?
John Baldwin
jhb at FreeBSD.org
Wed Mar 26 17:13:26 PST 2003
On 26-Mar-2003 Craig Rodrigues wrote:
> On Mon, Mar 24, 2003 at 11:48:10AM -0500, John Baldwin wrote:
>> > http://kernelnewbies.org/documents/kdoc/kernel-api/r287.html
>>
>> If you strictly need decrement and test, you can use a while loop
>> with atomic_cmpset(), e.g.
>>
>> do {
>> x = foo;
>> } while (atomic_cmpset_int(&foo, x, x - 1) == 0);
>> if (x == 1)
>> /* foo just dropped to zero */
>>
>> What task are you trying to accomplish though?
>
>
> 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)
--
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