Subject: VAX atomic test-and-set?
To: None <port-vax@NetBSD.ORG>
From: Tom I Helbekkmo <tih@Hamartun.Priv.NO>
List: port-vax
Date: 02/04/1998 11:21:41
Hi, folks!

I've got a bad cold, and am staying home today (heck, we're more or
less snowed in anyway) -- but I can't stay in bed all day, so I have
to do a little bit of hacking in between, so...

I needed an atomic test-and-set for the VAX, and I believe I've got it
right with the following -- but I don't have sufficient documentation
handy to be absolutely certain.  If any of you experienced VAX folks
could take a quick look at this and tell me whether my assumptions
about BBSSI hold, I'd be grateful!

static int tas(int *lock) {
  asm("movl 4(ap), r0");
  asm("bbssi $0, (r0), 1f");
  asm("clrl r0");
  asm("1: ret");
}

void acquire_lock(int *lock) {
  while (tas(lock))
    sleep(1);
}

void acquire_lock_urgent(int *lock) {
  while (tas(lock))
    ;
}

void release_lock(int *lock) {
  *lock = 0;
}

While I'm asking, how can I make this secure against GCC optimization?
The damn thing inlines my assembly code at optimization levels above
-O2, which breaks this stuff completely.  For various reasons, it
would be a Good Thing if it were possible to keep the assembly code in
a C source file, as I've done here.

Of course, in the supplied sample code above, I ought to inline
everything manually anyway, but the actual application is different.
What I'm really doing is getting the object-relational database system
PostgreSQL to work under NetBSD/vax.  I've got it running nicely, and
if I can get them to slip my modifications in quickly, then PostgreSQL
version 6.3, due for release 1 March, will support us.  I just need to
know for certain that I've got the locking right.  (I already know
that 6.3 will work on NetBSD/sparc, and assume /i386 is OK as well.)

(Interested parties can check out <http://www.postgresql.org>.  The
daily snapshots of 6.3 beta are in <ftp://ftp.postgresql.org/pub/>.)

-tih
-- 
Popularity is the hallmark of mediocrity.  --Niles Crane, "Frasier"