code: plan9front

Download patch

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);