9fans archive / 2000 / 07 / 150 prev next
From: Russ Cox <rsc@pla...>
Subject: Kernel question: i386 test-and-set problem
Date: Mon, 10 Jul 2000 08:40:20 -0400
The weird thing is that it looks as though this function only exchanged %eax
and (%ebx) by XCHG instruction which is NOT atomic. The C source looks
satisfied with it (I have no opportunity to try it, because I am not running
It looks atomic to me. The Intel 386 instruction set
manual says
XCHG exchanges two operands. The operands can be in either
order. If a memory operand is involved, BUS LOCK is
asserted for the duration of the exchange, regardless of the
presence or absence of the LOCK prefix or of the value of
the IOPL.
As for cas, ...
By further searching, I found (in /sys/src/libthread/386cas.s ... or
something) a routine called cas(). This routine uses the proper 386 atomic
instruction CMPXCHG.
Well, what's going on? I'd expect all those C functions to call cas()
instead of tas(). Mys second question is why cas() is not the only tas()
(test-end-set) within the 386 part of the kernel. My last question is why
the cas() is outside the kernel tree.
The main problem with cas() is that it's not on the 386.
It is on the Pentium, and if memory serves, is on the 486.
Libthread is a user-level thread library and not part of
the kernel. The lack of cas() for any othe architecture
suggests that it was written but never used, probably
for exactly the reason above. I poked around in the
past and can't find any calls to it, ever.
You'll also note that 386xadd.s does not actually use
the XADD instruction, for the same reason. Since we
only need increment and decrement, we use
INC and DEC instructions with a LOCK prefix, since
that will work on a 386 (which lacks XADD as well).
The choice of locking primitive is fairly arbitrary,
and tas got chosen a long time ago. Since we don't
play funny games with lock-free data structures, the
absence of cas or cas2 is not felt. You could have cas
instead, but it'd be clumsy to implement on a 386
(and maybe on the early Sparcs?).
Russ