summaryrefslogtreecommitdiff
path: root/sys/src/cmd/cwfs
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-08-07 01:32:11 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2013-08-07 01:32:11 +0200
commit3663ffeefacb34fc131b3ca8995783ce8dc1bd83 (patch)
tree402b39e9999ec02679480c1978f905e07ecad25e /sys/src/cmd/cwfs
parent2c8f291db2f04b4f87c01fcd3344c8d2fb1f8e89 (diff)
cwfs: use atomic compare and swap to avoid semacquire() syscalls in new queue implementation
Diffstat (limited to 'sys/src/cmd/cwfs')
-rw-r--r--sys/src/cmd/cwfs/sub.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/sys/src/cmd/cwfs/sub.c b/sys/src/cmd/cwfs/sub.c
index 656ad19b9..3f33310fa 100644
--- a/sys/src/cmd/cwfs/sub.c
+++ b/sys/src/cmd/cwfs/sub.c
@@ -917,12 +917,17 @@ hexdump(void *a, int n)
fprint(2, "%s\n", s1);
}
+extern int cas(long *p, long ov, long nv);
+
void*
fs_recv(Queue *q, int)
{
void *a;
+ long v;
- semacquire(&q->count, 1);
+ v = q->count;
+ if(v == 0 || cas(&q->count, v, v-1) == 0)
+ semacquire(&q->count, 1);
lock(&q->rl);
a = *q->rp;
if(++q->rp >= &q->args[q->size])
@@ -935,7 +940,11 @@ fs_recv(Queue *q, int)
void
fs_send(Queue *q, void *a)
{
- semacquire(&q->avail, 1);
+ long v;
+
+ v = q->avail;
+ if(v == 0 || cas(&q->avail, v, v-1) == 0)
+ semacquire(&q->avail, 1);
lock(&q->wl);
*q->wp = a;
if(++q->wp >= &q->args[q->size])