On Sun, 23 Jun 2013, I wrote:

I thought of lots of variations, but couldn't find one that works perfectly.
One idea (that goes with the sign check on the low 32 bits) is to use a
misaligned add to memory to copy the 31st bit as a carry bit to the the
high word.  The value of the counter is supposed to be

  [unsigned value of low 32 bits] + [unsigned value of next 24 bits] << 31
  (high 8 bits not used)

at all times, with the 31st bit zero at most times so that the the carry
operation is rarely executed.  This format is only slightly confusing for
debugging (it basically has 2 31st bits, with the one in the low 32 bits
rarely used).  This format can be updated using something like:
....
The above doesn't work if it is preempted -- then it might add do the
carry operation more than once.  But it is easy to lock using cmpxchg or
disabling interrupts.  Disabling interrupts requires only small code:
...
Another idea is to use the high bits of the high word to encode state.
They can be set atomically enough using addl/andl/orl/xorl since they
are per-CPU.  I couldn't quite get this to work.  You could increment

Here is a combined version.  It uses the old shift trick instead of
disabling interrupts for locking.  The shift trick is not often used
since it doesn't work for SMP.  It works here since the counters are
per-CPU:

        addl    %1,%%fs:(%0)            # only small 32-bit increments supported
        jns     8f
        sar     $1,%%fs:7(%0)           # hi 8 bits are for lock; init to 0xfe
        jc      8f                      # already locked
        addl    $0x80,%%fs:3(%0)        # misaligned memory access
        movb    $0xfe,%%fs:7(%0)        # unlock
8: ;

Since the locked case is rarely executed and the code for it is only
inline for convenience, the shortest code should be preferred and that
is the simpler version that disables interrupts.  Unless the lock byte
can be exploited in the fetching and zeroing code.  I don't see how
it can be, since this type of locking only works for a single CPU.

Bruce
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to