Date: Sun, 19 Aug 2007 14:53:53 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Pawel Jakub Dawidek <pjd@FreeBSD.org> Cc: freebsd-arch@FreeBSD.org Subject: Re: Lockless uidinfo. Message-ID: <20070819142214.O34036@delplex.bde.org> In-Reply-To: <20070818220756.GH6498@garage.freebsd.pl> References: <20070818120056.GA6498@garage.freebsd.pl> <20070818220756.GH6498@garage.freebsd.pl>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 19 Aug 2007, Pawel Jakub Dawidek wrote: > Two more things... > >> The patch below remove per-uidinfo locks: >> >> http://people.freebsd.org/~pjd/patches/uidinfo_lockless.patch > > We could upgrade from lock-free algorithm I used here to wait-free > algorithm, but we don't have atomic_fetchadd_long(). How hard will it be > to implement it? > > We could then change: > > do { > old = uip->ui_proccnt; > if (old + diff > max) > return (0); > } while (atomic_cmpset_long(&uip->ui_proccnt, old, old + diff) == 0); > > to something like this: > > if (atomic_fetchadd_long(&uip->ui_proccnt, diff) + diff > max) { > atomic_subtract_long(&uip->ui_proccnt, diff); > return (0); > } atomic_*long() shouldn't exist (and doesn't exist in my version) since longs should actually be long (twice as long as registers) and thus especially epensive to lock. long is just a bogus historical type for ui_proccnt (in case int is 16 bits, and the null set of old systems with 16-bit ints have non-old CPU resources for >= 65536 processes per user). There are several variables like this. This causes problems spelling atomic accesses to such variables. Sometimes on 64-bit machines, asking for a long (128 bits) is actually useful for the bogus reason that long has the wrong size (64 bits) and 64-bits is actually useful on 64-bit machines though not needed on 32-bit machines. >> I needed to change ui_sbsize from rlim_t (64bit) to long, because we >> don't have 64bit atomics on all archs, and because sbsize represents >> size in bytes, it can't go beyond 32bit on 32bit archs (PAE might be a >> bit of a problem). This problem is similar. rlim_t is 64 bits since 64 bits is needed for a few limits and 128 bits isn't needed yet, so the same type is used for all limits. This causes problems locking it even on 64-bit machines where longs have the wrong size (not 2*64), since although 64-bit machines have 64-bit atomics, there is no good way to spell the atomic accesses to an rlim_t. On 32-bit machines, there is no way at all to spell the atomic accesses to an rlim_t. Here the spelling problems prevent misuse of atomics on longs. Otherwise, the type for a size should be something like vm_size_t, and then the problem is the spelling of atomic accesses to vm_size_t's. This problem is handled for pointers by type-punning pointers to ints or longs in <machine/atomic.h>. (The amd64 atomic.h uses longs. It should use int64_t or register_t. It uses 8-bit DOS/Windowspeak "Operations on 32-bit double words" and "Operations on 64-bit quad words" in comments copied from the i386 version. On 64-bit machines, 32 bits is half a word, not a double word...) Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070819142214.O34036>