Skip site navigation (1)Skip section navigation (2)
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>