Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 02 Jan 2002 15:29:20 -0800 (PST)
From:      John Baldwin <jhb@FreeBSD.org>
To:        Matthew Dillon <dillon@apollo.backplane.com>
Cc:        arch@FreeBSD.ORG, Bernd Walter <ticso@cicely8.cicely.de>, Mike Smith <msmith@FreeBSD.ORG>, Bruce Evans <bde@zeta.org.au>, Michal Mertl <mime@traveller.cz>, Peter Jeremy <peter.jeremy@alcatel.com.au>
Subject:   Re: When to use atomic_ functions? (was: 64 bit counters)
Message-ID:  <XFMail.020102152920.jhb@FreeBSD.org>
In-Reply-To: <200201022323.g02NNjt60197@apollo.backplane.com>

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

On 02-Jan-02 Matthew Dillon wrote:
> 
>:This depends on how it is implemented.  Obviously
>:      int counter[NCPUS];
>:will be just as expensive as performing atomic operations, but no-one
>:in their right mind would do that.  One approach is to aggregate all
>:the per-CPU counters into a single region of KVM and arrange for that
>:KVM to be mapped to different physical memory for each CPU.  (Solaris
>:does or did this).  This means that the code to update the counter
>:doesn't need to know whether a counter is per-CPU or not.
>:
>:The code to read the counters _does_ need to know that the counters
>:are per-CPU and have to sum all the individual counters - which is
>:more expensive than a straight read, but is normally far less frequent.
>:
>:Peter
> 
>     Something like galloc()/gfree().
> 
>     offset = galloc(bytes);   /* allocate space in all cpu's per-cpu struct*/
>     gfree(offset, bytes);     /* return previously reserved space */
> 
>     And then macros to read and write it.
> 
>     global_int(offset)                /* returns address of global int @
offset */
>     global_quad(offset)               /* returns address of global int @
offset */
> 
>     e.g.
> 
>     ++*global_quad(ifc->counter_off);
> 
>     Which GCC ought to be able to optimize fairly easily.
> 
>     This isn't a recommendation, just one way we could do it.

Look at PCPU_GET/PCPU_SET.  Note that since an interrupt can preempt you and
push you off onto another CPU, you have to use a critical section while
updating per-CPU variables.  If desired, some kind of free area could be stuck
in struct pcpu (or more likely, struct pcpu would hold a pointer to the area)
that could be galloc/gfree'd or some such.

-- 

John Baldwin <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




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