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