On Tue, 15 Aug 2000 10:30:25 -0600 (MDT), Ronald G Minnich <[EMAIL PROTECTED]> wrote: >The idea is simple: tset is the fastest, but you only want to spin so >long. Then you want to drop into the kernel, and wait for someone to wake >you up. Agreed. >Here's a simple test-and-set function for the 386 (tested and works): > >int >tset(int *i, int lockval, int unlockval) >{ > int j = 0; > asm("movl 16(%ebp), %eax"); > asm("movl 8(%ebp),%ecx"); > asm("movl 12(%ebp),%edx"); > asm("cmpxchg %edx, (%ecx)"); > asm("jne failed"); > asm("movl %eax, -4(%ebp)"); > asm("jmp done"); > asm("failed: movl %eax, -4(%ebp)"); > asm("done:"); > return j; >} Actually, this isn't particularly good coding. It isn't SMP-safe. If you compile it with -fomit-frame-pointer or -fomit-leaf-frame-pointer, it won't work (and will corrupt some innocent, probably stack, memory). When the code is optimised, it works as much by accident as design. And the documentation for gcc indicates that sequences of asm statements can be re-ordered. Something like the following should be somewhat safer. It returns unlockval if the semaphore was not locked, otherwise it returns the current contents of the semaphore (which seems to be the same as your code). int tset(int *i, int lockval, int unlockval) { int j; __asm__("lock cmpxchg %2, (%3)" : "=a" (j) : "0" (unlockval), "r" (lockval), "r" (i) : "memory", "cc"); return j; } Peter To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message