Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Jan 2001 21:03:45 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
Cc:        Alfred Perlstein <bright@wintelcom.net>, current@FreeBSD.ORG
Subject:   Re: Atomic breakage?
Message-ID:  <Pine.BSF.4.21.0101181957230.1115-100000@besplex.bde.org>
In-Reply-To: <200101171614.LAA18224@khavrinen.lcs.mit.edu>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 17 Jan 2001, Garrett Wollman wrote:

> <<On Tue, 16 Jan 2001 19:10:10 -0800, Alfred Perlstein <bright@wintelcom.net> 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 majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0101181957230.1115-100000>