shithub: riscv

Download patch

ref: fc88896fc1f7a1849e8f4e8c372b1e06ea836384
parent: f4550c4d6ae277a5ee96fac110fdd306b3e3ac40
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri Jan 10 09:51:29 EST 2014

mixfs: make mixbuffer addition atomic

serialize mixing with spinlock to make the addition
on the mixbuffer samples atomic.

--- a/sys/src/cmd/audio/mixfs/mixfs.c
+++ b/sys/src/cmd/audio/mixfs/mixfs.c
@@ -23,6 +23,7 @@
 
 ulong	mixrp;
 int	mixbuf[NBUF][NCHAN];
+Lock	mixlock;
 Stream	streams[16];
 
 int
@@ -163,26 +164,38 @@
 
 	p = (uchar*)r->ifcall.data;
 	n = r->ifcall.count;
-	m = n/(NCHAN*2);
+	r->ofcall.count = n;
+	n /= (NCHAN*2);
 
 	srv = r->srv;
 	srvrelease(srv);
 	s = r->fid->aux;
 	qlock(s);
-	if(s->run == 0){
-		s->wp = mixrp;
-		s->run = 1;
-	}
-	for(i=0; i<m; i++){
-		while((long)(s->wp - mixrp) >= NBUF-1){
+	while(n > 0){
+		if(s->run == 0){
+			s->wp = mixrp;
 			s->run = 1;
+		}
+		m = NBUF-1 - (long)(s->wp - mixrp);
+		if(m <= 0){
+			s->run = 1;
 			rsleep(s);
+			continue;
 		}
-		for(j=0; j<NCHAN; j++){
-			mixbuf[s->wp % NBUF][j] += s16(p);
-			p += 2;
+		if(m > n)
+			m = n;
+
+		lock(&mixlock);
+		for(i=0; i<m; i++){
+			for(j=0; j<NCHAN; j++){
+				mixbuf[s->wp % NBUF][j] += s16(p);
+				p += 2;
+			}
+			s->wp++;
 		}
-		s->wp++;
+		unlock(&mixlock);
+
+		n -= m;
 	}
 	if((long)(s->wp - mixrp) >= NDELAY){
 		s->run = 1;
@@ -189,7 +202,6 @@
 		rsleep(s);
 	}
 	qunlock(s);
-	r->ofcall.count = n;
 	respond(r, nil);
 	srvacquire(srv);
 }
--