On Wed, 17 Jan 2001, Garrett Wollman wrote:

> <<On Tue, 16 Jan 2001 19:10:10 -0800, Alfred Perlstein <[EMAIL PROTECTED]> said:
> 
> > Just wondering, can't you use 'LOCK addl' and then use 'LOCK addc'?
> > add longword, add longword with carry?  I know it would be pretty
> > ugly, but it should work, no?
> 
> The two bus cycles are independent, so there is a race condition.
> 
> OTOH, it's a fairly *unlikely* race condition, and the worst thing
> that can happen is statistics that are obviously off by four billion.
> (The race only occurs when there is a carry out of the low-order
> longword, which is to say, once in every 2**32 operations.)

If they are obviously off by precisely four billion, then they can be
corrected :-).

I have thought of using special overflow handling methods to reduce the
cost of keeping statistics.  E.g.:

---
uint32_t counter[2];

        /* Low-level code increments only the lower 32 bits of counters. */
        atomic_add_32(&counter[0]), 1);

        /*
         * Counter daemon adjusts counters before they get anywhere near
         * overflowing.  It must run often enough to prevent overflow
         * (not very often).  This also make the race in the adjustment
         * code harmless.
         */
        KASSERT(counter[0] < 0xC0000000, "counter got near overflowing");
        if (counter[0] & 0x80000000) {
                atomic_subtract_32(&counter[0], 0x80000000);
                ++counter[1];
        }

        /*
         * Clients must use code like the following to convert counters
         * to values.  More locking is required to load counter[0] and
         * counter[1] atomically, but this is not a new problem (e.g.,
         * atomicity is mostly accidental for accesses via kmem).
         */
        counter_value = ((uint64_t)counter[1] << 31) | counter[0];
---

Bruce



To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to