atomic_dec_and_test() in FreeBSD?
John Baldwin
jhb at FreeBSD.org
Fri Apr 4 11:45:56 PST 2003
On 04-Apr-2003 Garrett Rooney wrote:
> John Baldwin wrote:
>
>>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);
>>
>>
>>
>
> I believe Craig is looking for a user space solution, not kernel space.
Argh, I couldn't remember. Well, one could always use a mutex to
protect the count I suppose. One must be using some sort of threads
library for this to even make sense in userland.
--
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