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>