Date: Wed, 16 Aug 2000 14:53:19 +1000 From: Peter Jeremy <peter.jeremy@alcatel.com.au> To: rminnich@lanl.gov Cc: freebsd-hackers@freebsd.org Subject: Re: IPC, shared memory, syncronization AND threads... Message-ID: <00Aug16.145324est.115207@border.alcanet.com.au>
next in thread | raw e-mail | index | archive | help
On Tue, 15 Aug 2000 10:30:25 -0600 (MDT), Ronald G Minnich <rminnich@lanl.gov> 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 majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?00Aug16.145324est.115207>