ref: 79e9c9534592bc4948f4a0299f413d7cfa45479c
parent: 35b8a692679495606c09e3f023ddee744a8852b9
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Dec 4 11:35:04 EST 2022
audio/mixfs: fix locking for /dev/audio loopback Add "Lock rplock" as a barrier for /dev/audio loopback readers. Readers can execute concurrently (no need to acquire mixlock), we just have to make sure lbbuf[] data is written *before* mixrp is updated by audioproc().
--- a/sys/src/cmd/audio/mixfs/mixfs.c
+++ b/sys/src/cmd/audio/mixfs/mixfs.c
@@ -23,9 +23,12 @@
};
ulong mixrp;
-int mixbuf[NBUF][NCHAN];
+Lock rplock;
int lbbuf[NBUF][NCHAN];
+
+int mixbuf[NBUF][NCHAN];
Lock mixlock;
+
Stream streams[16];
int
@@ -89,6 +92,7 @@
{
static uchar buf[NBUF*NCHAN*2];
int sweep, fd, i, j, n, m, v;
+ ulong rp;
Stream *s;
uchar *p;
@@ -144,16 +148,23 @@
}
p = buf;
+ rp = mixrp;
for(i=0; i<m; i++){
for(j=0; j<NCHAN; j++){
- v = clip16(mixbuf[mixrp % NBUF][j]);
- lbbuf[mixrp % NBUF][j] = v;
- mixbuf[mixrp % NBUF][j] = 0;
+ v = clip16(mixbuf[rp % NBUF][j]);
+ lbbuf[rp % NBUF][j] = v;
+ mixbuf[rp % NBUF][j] = 0;
*p++ = v & 0xFF;
*p++ = v >> 8;
}
- mixrp++;
+ rp++;
}
+
+ /* barrier */
+ lock(&rplock);
+ mixrp = rp;
+ unlock(&rplock);
+
write(fd, buf, p - buf);
}
}
@@ -182,6 +193,7 @@
s->run = 1;
}
m = NBUF-1 - (long)(s->wp - mixrp);
+
if(m <= 0){
s->run = 1;
rsleep(s);
@@ -190,7 +202,6 @@
if(m > n)
m = n;
- lock(&mixlock);
for(i=0; i<m; i++){
for(j=0; j<NCHAN; j++){
v = lbbuf[s->wp % NBUF][j];
@@ -199,7 +210,6 @@
}
s->wp++;
}
- unlock(&mixlock);
n -= m;
}
@@ -231,6 +241,7 @@
s->run = 1;
}
m = NBUF-1 - (long)(s->wp - mixrp);
+
if(m <= 0){
s->run = 1;
rsleep(s);