Date: Tue, 18 Mar 1997 04:46:47 -0500 (EST) From: Peter Dufault <dufault@hda.com> To: plm@xs4all.nl (Peter Mutsaers) Cc: freebsd-questions@FreeBSD.ORG Subject: Re: test and set instruction: how? Message-ID: <199703180946.EAA21402@hda.hda.com> In-Reply-To: <199703172327.AAA01251@plm.xs4all.nl> from Peter Mutsaers at "Mar 18, 97 00:27:27 am"
next in thread | previous in thread | raw e-mail | index | archive | help
> Is there a (portable ?) way for a test-and-set instruction under
> FreeBSD?
(...)
Compare and exchange is present on 486s and Pentiums. Early 486s
have a different op code that collides with other instructions;
Pentiums support 64 bit flavors. Here is what I've been using.
It will compile with CAS_TEST.
/* cas: Compare-and-swap using the 486 and Pentium "cmpxchg"
* instruction.
*
* Atomically change what "ptr" points to to "n" if it is "o"
* and return success.
*/
#if defined(CAS_TEST)
typedef unsigned long castype;
extern int cas(volatile castype *, const castype, const castype);
#else
#include "cas.h"
#endif
#if defined(CAS_DEBUG)
#include <stdio.h>
#endif
int
cas(volatile castype *ptr, const castype o, const castype n)
{
volatile int result = 0;
#if defined(CAS_DEBUG)
fprintf(stderr, "cas %p %08lx %08lx %08lx, ", ptr, *ptr, o, n);
#endif
__asm __volatile(
"cmpxchg%L3 %3,%1; jne 0f; inc%L0 %0; 0:"
: "=m"(result)
: "m"(*ptr), "a"(o), "r"(n)
);
#if defined(CAS_DEBUG)
fprintf(stderr, "%s %08lx\n", result ? "OK " : "Fail", *ptr);
#endif
return result;
}
#if defined(CAS_TEST)
#include <stdio.h>
int main(int argc, char *av[])
{
while (1)
{
volatile castype c;
castype o, n;
int result;
printf("c old new > ");
if (scanf("%ld %ld %ld", &c, &o, &n) != 3)
break;
result = cas(&c, o, n);
printf("%d; %ld %ld %ld\n", result, c, o, n);
}
return 0;
}
#endif /* CAS_TEST */
--
Peter Dufault (dufault@hda.com) Realtime Machine Control and Simulation
HD Associates, Inc. Voice: 508 433 6936
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199703180946.EAA21402>
