Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 04 Apr 2003 14:45:50 -0500 (EST)
From:      John Baldwin <jhb@FreeBSD.org>
To:        Garrett Rooney <rooneg@electricjellyfish.net>
Cc:        freebsd-smp@FreeBSD.org
Subject:   Re: atomic_dec_and_test() in FreeBSD?
Message-ID:  <XFMail.20030404144550.jhb@FreeBSD.org>
In-Reply-To: <3E8DDF5A.5040005@electricjellyfish.net>

next in thread | previous in thread | raw e-mail | index | archive | help

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@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.20030404144550.jhb>