Lockless uidinfo.
Bruce Evans
brde at optusnet.com.au
Sat Aug 18 21:53:57 PDT 2007
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
More information about the freebsd-arch
mailing list