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>