ref: 08cdfaedb4d05f28fc75bade6a1c0a309c8df9a8
parent: e373badb4eb3c4844a5e2259f278220e501e4336
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Nov 5 12:06:49 EST 2023
atomic: return a boolean from the cas variants while it's sometimes useful to know the old value in the atomic location, it's harder to implement on some cpu architectures like arm.
--- a/atomic-amd64.s
+++ b/atomic-amd64.s
@@ -34,6 +34,8 @@
MOVL c+8(FP), AX
MOVL v+16(FP), BX
LOCK; CMPXCHGL BX, (RARG)
+ SETEQ AX
+ MOVBLZX AX, AX
RET
TEXT acasv+0(SB),1,$0
@@ -41,8 +43,11 @@
MOVQ c+8(FP), AX
MOVQ v+16(FP), BX
LOCK; CMPXCHGQ BX, (RARG)
+ SETEQ AX
+ MOVBLZX AX, AX
RET
/* barriers (do we want to distinguish types?) */
TEXT coherence+0(SB),1,$0
MFENCE
+ RET
--- a/atomic.h
+++ b/atomic.h
@@ -10,8 +10,8 @@
vlong aincv(vlong*, vlong);
void* aincp(void**, void*);
-long acasl(long*, long, long);
-vlong acasv(vlong*, vlong, vlong);
-void* acasp(void**, void*, void*);
+int acasl(long*, long, long);
+int acasv(vlong*, vlong, vlong);
+int acasp(void**, void*, void*);
-void coherence(void);
\ No newline at end of file
+void coherence(void);
--- a/blk.c
+++ b/blk.c
@@ -29,7 +29,7 @@
while(1){
ov = agetl(&b->flag);
nv = ov | f;
- if(acasl(&b->flag, ov, nv) == ov)
+ if(acasl(&b->flag, ov, nv))
break;
}
}
@@ -42,7 +42,7 @@
while(1){
ov = agetl(&b->flag);
nv = ov & ~f;
- if(acasl(&b->flag, ov, nv) == ov)
+ if(acasl(&b->flag, ov, nv))
break;
}
}
--- a/fs.c
+++ b/fs.c
@@ -149,7 +149,7 @@
long v;
v = agetl(&c->count);
- if(v == 0 || acasl(&c->count, v, v-1) != v)
+ if(v == 0 || !acasl(&c->count, v, v-1))
semacquire(&c->count, 1);
lock(&c->rl);
a = *c->rp;
@@ -166,7 +166,7 @@
long v;
v = agetl(&c->avail);
- if(v == 0 || acasl(&c->avail, v, v-1) != v)
+ if(v == 0 || !acasl(&c->avail, v, v-1))
semacquire(&c->avail, 1);
lock(&c->wl);
*c->wp = m;