From mboxrd@z Thu Jan 1 00:00:00 1970 Message-Id: <200007101240.IAA27005@cse.psu.edu> To: 9fans@cse.psu.edu Subject: Re: [9fans] Kernel question: i386 test-and-set problem From: "Russ Cox" Date: Mon, 10 Jul 2000 08:40:20 -0400 MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Topicbox-Message-UUID: d6b13404-eac8-11e9-9e20-41e7f4b1d025 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