Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F173949176
D60127.id188000.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D60127.id188000.diff
View Options
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -138,9 +138,7 @@
d = devclass_get_softc(pcm_devclass, i);
if (!PCM_REGISTERED(d))
continue;
- PCM_LOCK(d);
- PCM_WAIT(d);
- PCM_ACQUIRE(d);
+ PCM_ACQUIRE_QUICK(d);
CHN_FOREACH(c, d, channels.pcm) {
CHN_LOCK(c);
chn_setvolume_matrix(c, SND_VOL_C_PCM, SND_CHN_T_VOL_0DB, db);
@@ -148,8 +146,7 @@
chn_vpc_reset(c, SND_VOL_C_PCM, 1);
CHN_UNLOCK(c);
}
- PCM_RELEASE(d);
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
}
bus_topo_unlock();
}
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -266,9 +266,8 @@
PCM_GIANT_ENTER(d);
+ PCM_ACQUIRE_QUICK(d);
PCM_LOCK(d);
- PCM_WAIT(d);
- PCM_ACQUIRE(d);
rdch = priv->rdch;
wrch = priv->wrch;
@@ -278,76 +277,71 @@
if (wrch != NULL)
CHN_REMOVE(d, wrch, channels.pcm.opened);
- if (rdch != NULL || wrch != NULL) {
- PCM_UNLOCK(d);
- if (rdch != NULL) {
- /*
- * The channel itself need not be locked because:
- * a) Adding a channel to a syncgroup happens only
- * in dsp_ioctl(), which cannot run concurrently
- * to dsp_close().
- * b) The syncmember pointer (sm) is protected by
- * the global syncgroup list lock.
- * c) A channel can't just disappear, invalidating
- * pointers, unless it's closed/dereferenced
- * first.
- */
- PCM_SG_LOCK();
- sg_ids = chn_syncdestroy(rdch);
- PCM_SG_UNLOCK();
- if (sg_ids != 0)
- free_unr(pcmsg_unrhdr, sg_ids);
+ PCM_UNLOCK(d);
- /*
- * Go through the channel abort/flush path for both
- * primary and virtual channels to ensure that, in the
- * case of vchans, the stream is always properly
- * stopped, and the primary channels do not keep being
- * interrupted even if all vchans are gone.
- */
+ if (rdch != NULL) {
+ /*
+ * The channel itself need not be locked because:
+ * a) Adding a channel to a syncgroup happens only in
+ * dsp_ioctl(), which cannot run concurrently to
+ * dsp_close().
+ * b) The syncmember pointer (sm) is protected by the global
+ * syncgroup list lock.
+ * c) A channel can't just disappear, invalidating pointers,
+ * unless it's closed/dereferenced first.
+ */
+ PCM_SG_LOCK();
+ sg_ids = chn_syncdestroy(rdch);
+ PCM_SG_UNLOCK();
+ if (sg_ids != 0)
+ free_unr(pcmsg_unrhdr, sg_ids);
+
+ /*
+ * Go through the channel abort/flush path for both primary and
+ * virtual channels to ensure that, in the case of vchans, the
+ * stream is always properly stopped, and the primary channels
+ * do not keep being interrupted even if all vchans are gone.
+ */
+ CHN_LOCK(rdch);
+ chn_abort(rdch); /* won't sleep */
+ rdch->flags &= ~(CHN_F_RUNNING | CHN_F_MMAP |
+ CHN_F_DEAD | CHN_F_EXCLUSIVE | CHN_F_NBIO);
+ chn_reset(rdch, 0, 0);
+ chn_release(rdch);
+ if (rdch->flags & CHN_F_VIRTUAL) {
+ parent = rdch->parentchannel;
+ CHN_LOCK(parent);
CHN_LOCK(rdch);
- chn_abort(rdch); /* won't sleep */
- rdch->flags &= ~(CHN_F_RUNNING | CHN_F_MMAP |
- CHN_F_DEAD | CHN_F_EXCLUSIVE | CHN_F_NBIO);
- chn_reset(rdch, 0, 0);
- chn_release(rdch);
- if (rdch->flags & CHN_F_VIRTUAL) {
- parent = rdch->parentchannel;
- CHN_LOCK(parent);
- CHN_LOCK(rdch);
- vchan_destroy(rdch);
- CHN_UNLOCK(parent);
- }
+ vchan_destroy(rdch);
+ CHN_UNLOCK(parent);
}
- if (wrch != NULL) {
- /*
- * Please see block above.
- */
- PCM_SG_LOCK();
- sg_ids = chn_syncdestroy(wrch);
- PCM_SG_UNLOCK();
- if (sg_ids != 0)
- free_unr(pcmsg_unrhdr, sg_ids);
+ }
+ if (wrch != NULL) {
+ /*
+ * Please see block above.
+ */
+ PCM_SG_LOCK();
+ sg_ids = chn_syncdestroy(wrch);
+ PCM_SG_UNLOCK();
+ if (sg_ids != 0)
+ free_unr(pcmsg_unrhdr, sg_ids);
+ CHN_LOCK(wrch);
+ chn_flush(wrch); /* may sleep */
+ wrch->flags &= ~(CHN_F_RUNNING | CHN_F_MMAP |
+ CHN_F_DEAD | CHN_F_EXCLUSIVE | CHN_F_NBIO);
+ chn_reset(wrch, 0, 0);
+ chn_release(wrch);
+ if (wrch->flags & CHN_F_VIRTUAL) {
+ parent = wrch->parentchannel;
+ CHN_LOCK(parent);
CHN_LOCK(wrch);
- chn_flush(wrch); /* may sleep */
- wrch->flags &= ~(CHN_F_RUNNING | CHN_F_MMAP |
- CHN_F_DEAD | CHN_F_EXCLUSIVE | CHN_F_NBIO);
- chn_reset(wrch, 0, 0);
- chn_release(wrch);
- if (wrch->flags & CHN_F_VIRTUAL) {
- parent = wrch->parentchannel;
- CHN_LOCK(parent);
- CHN_LOCK(wrch);
- vchan_destroy(wrch);
- CHN_UNLOCK(parent);
- }
+ vchan_destroy(wrch);
+ CHN_UNLOCK(parent);
}
- PCM_LOCK(d);
}
- PCM_RELEASE(d);
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
PCM_GIANT_LEAVE(d);
skip:
@@ -384,8 +378,8 @@
PCM_GIANT_ENTER(d);
/* Lock snddev so nobody else can monkey with it. */
+ PCM_ACQUIRE_QUICK(d);
PCM_LOCK(d);
- PCM_WAIT(d);
error = 0;
if (!DSP_F_VALID(flags))
@@ -424,20 +418,14 @@
error = ENOTSUP;
}
}
+ PCM_UNLOCK(d);
+
if (error != 0) {
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
PCM_GIANT_EXIT(d);
return (error);
}
- /*
- * That is just enough. Acquire and unlock pcm lock so
- * the other will just have to wait until we finish doing
- * everything.
- */
- PCM_ACQUIRE(d);
- PCM_UNLOCK(d);
-
if (DSP_F_WRITE(flags)) {
error = dsp_chn_alloc(d, &priv->wrch, PCMDIR_PLAY, flags, td);
if (error != 0) {
diff --git a/sys/dev/sound/pcm/feeder_eq.c b/sys/dev/sound/pcm/feeder_eq.c
--- a/sys/dev/sound/pcm/feeder_eq.c
+++ b/sys/dev/sound/pcm/feeder_eq.c
@@ -445,14 +445,11 @@
if (!PCM_REGISTERED(d))
return (ENODEV);
- PCM_LOCK(d);
- PCM_WAIT(d);
+ PCM_ACQUIRE_QUICK(d);
if (d->flags & SD_F_EQ)
val = 1;
else
val = 0;
- PCM_ACQUIRE(d);
- PCM_UNLOCK(d);
oval = val;
err = sysctl_handle_int(oidp, &val, 0, req);
@@ -463,17 +460,12 @@
return (EINVAL);
}
- PCM_LOCK(d);
-
if (val == 1)
d->flags |= SD_F_EQ;
else
d->flags &= ~SD_F_EQ;
-
- PCM_RELEASE(d);
- PCM_UNLOCK(d);
- } else
- PCM_RELEASE_QUICK(d);
+ }
+ PCM_RELEASE_QUICK(d);
return (err);
}
@@ -491,15 +483,12 @@
if (!PCM_REGISTERED(d))
return (ENODEV);
- PCM_LOCK(d);
- PCM_WAIT(d);
+ PCM_ACQUIRE_QUICK(d);
val = d->eqpreamp;
bzero(buf, sizeof(buf));
(void)snprintf(buf, sizeof(buf), "%c%d.%ddB",
FEEDEQ_PREAMP_SIGNMARK(val), FEEDEQ_PREAMP_IPART(val),
FEEDEQ_PREAMP_FPART(val));
- PCM_ACQUIRE(d);
- PCM_UNLOCK(d);
oval = val;
err = sysctl_handle_string(oidp, buf, sizeof(buf), req);
@@ -511,8 +500,6 @@
return (EINVAL);
}
- PCM_LOCK(d);
-
if (val != oval) {
if (val < FEEDEQ_PREAMP_MIN)
val = FEEDEQ_PREAMP_MIN;
@@ -521,6 +508,7 @@
d->eqpreamp = val;
+ PCM_LOCK(d);
CHN_FOREACH(c, d, channels.pcm.busy) {
CHN_LOCK(c);
f = feeder_find(c, FEEDER_EQ);
@@ -528,12 +516,10 @@
(void)FEEDER_SET(f, FEEDEQ_PREAMP, val);
CHN_UNLOCK(c);
}
+ PCM_UNLOCK(d);
}
-
- PCM_RELEASE(d);
- PCM_UNLOCK(d);
- } else
- PCM_RELEASE_QUICK(d);
+ }
+ PCM_RELEASE_QUICK(d);
return (err);
}
diff --git a/sys/dev/sound/pcm/feeder_rate.c b/sys/dev/sound/pcm/feeder_rate.c
--- a/sys/dev/sound/pcm/feeder_rate.c
+++ b/sys/dev/sound/pcm/feeder_rate.c
@@ -249,9 +249,7 @@
d = devclass_get_softc(pcm_devclass, i);
if (!PCM_REGISTERED(d))
continue;
- PCM_LOCK(d);
- PCM_WAIT(d);
- PCM_ACQUIRE(d);
+ PCM_ACQUIRE_QUICK(d);
CHN_FOREACH(c, d, channels.pcm) {
CHN_LOCK(c);
f = feeder_find(c, FEEDER_RATE);
@@ -262,8 +260,7 @@
(void)FEEDER_SET(f, FEEDRATE_QUALITY, val);
CHN_UNLOCK(c);
}
- PCM_RELEASE(d);
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
}
bus_topo_unlock();
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -132,17 +132,16 @@
struct pcm_channel *ch;
int err = 0;
+ PCM_ACQUIRE_QUICK(d);
PCM_LOCK(d);
- PCM_WAIT(d);
- PCM_ACQUIRE(d);
ch = chn_init(d, NULL, cls, dir, devinfo);
if (!ch) {
device_printf(d->dev, "chn_init(%s, %d, %p) failed\n",
cls->name, dir, devinfo);
err = ENODEV;
}
- PCM_RELEASE(d);
PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
return (err);
}
@@ -282,11 +281,8 @@
if (!PCM_REGISTERED(d))
return (ENODEV);
- PCM_LOCK(d);
- PCM_WAIT(d);
+ PCM_ACQUIRE_QUICK(d);
val = (d->flags & SD_F_BITPERFECT) ? 1 : 0;
- PCM_ACQUIRE(d);
- PCM_UNLOCK(d);
err = sysctl_handle_int(oidp, &val, 0, req);
@@ -296,15 +292,10 @@
return (EINVAL);
}
- PCM_LOCK(d);
-
d->flags &= ~SD_F_BITPERFECT;
d->flags |= (val != 0) ? SD_F_BITPERFECT : 0;
-
- PCM_RELEASE(d);
- PCM_UNLOCK(d);
- } else
- PCM_RELEASE_QUICK(d);
+ }
+ PCM_RELEASE_QUICK(d);
return (err);
}
@@ -460,12 +451,9 @@
return (0);
}
- PCM_LOCK(d);
- PCM_WAIT(d);
-
+ PCM_ACQUIRE_QUICK(d);
d->flags &= ~SD_F_REGISTERED;
-
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
pcm_shutdownchans(d);
@@ -476,10 +464,7 @@
*/
dsp_destroy_dev(dev);
- PCM_LOCK(d);
- PCM_WAIT(d);
- PCM_ACQUIRE(d);
- PCM_UNLOCK(d);
+ PCM_ACQUIRE_QUICK(d);
pcm_killchans(d);
diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c
--- a/sys/dev/sound/pcm/vchan.c
+++ b/sys/dev/sound/pcm/vchan.c
@@ -260,35 +260,31 @@
}
bus_topo_unlock();
- PCM_LOCK(d);
- PCM_WAIT(d);
+ PCM_ACQUIRE_QUICK(d);
switch (VCHAN_SYSCTL_DIR(oidp->oid_arg1)) {
case VCHAN_PLAY:
/* Exit if we do not support this direction. */
if (d->playcount < 1) {
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
return (ENODEV);
}
flag = SD_F_PVCHANS;
break;
case VCHAN_REC:
if (d->reccount < 1) {
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
return (ENODEV);
}
flag = SD_F_RVCHANS;
break;
default:
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
return (EINVAL);
}
enabled = (d->flags & flag) != 0;
- PCM_ACQUIRE(d);
- PCM_UNLOCK(d);
-
err = sysctl_handle_int(oidp, &enabled, 0, req);
if (err != 0 || req->newptr == NULL) {
PCM_RELEASE_QUICK(d);
@@ -322,13 +318,12 @@
}
bus_topo_unlock();
- PCM_LOCK(d);
- PCM_WAIT(d);
+ PCM_ACQUIRE_QUICK(d);
switch (VCHAN_SYSCTL_DIR(oidp->oid_arg1)) {
case VCHAN_PLAY:
if ((d->flags & SD_F_PVCHANS) == 0) {
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
return (ENODEV);
}
direction = PCMDIR_PLAY;
@@ -336,20 +331,17 @@
break;
case VCHAN_REC:
if ((d->flags & SD_F_RVCHANS) == 0) {
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
return (ENODEV);
}
direction = PCMDIR_REC;
vchanmode = &d->rvchanmode;
break;
default:
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
return (EINVAL);
}
- PCM_ACQUIRE(d);
- PCM_UNLOCK(d);
-
if (*vchanmode & CHN_F_VCHAN_PASSTHROUGH)
strlcpy(dtype, "passthrough", sizeof(dtype));
else if (*vchanmode & CHN_F_VCHAN_ADAPTIVE)
@@ -416,13 +408,12 @@
}
bus_topo_unlock();
- PCM_LOCK(d);
- PCM_WAIT(d);
+ PCM_ACQUIRE_QUICK(d);
switch (VCHAN_SYSCTL_DIR(oidp->oid_arg1)) {
case VCHAN_PLAY:
if ((d->flags & SD_F_PVCHANS) == 0) {
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
return (ENODEV);
}
direction = PCMDIR_PLAY;
@@ -430,20 +421,17 @@
break;
case VCHAN_REC:
if ((d->flags & SD_F_RVCHANS) == 0) {
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
return (ENODEV);
}
direction = PCMDIR_REC;
vchanrate = &d->rvchanrate;
break;
default:
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
return (EINVAL);
}
- PCM_ACQUIRE(d);
- PCM_UNLOCK(d);
-
newspd = *vchanrate;
ret = sysctl_handle_int(oidp, &newspd, 0, req);
@@ -512,13 +500,12 @@
}
bus_topo_unlock();
- PCM_LOCK(d);
- PCM_WAIT(d);
+ PCM_ACQUIRE_QUICK(d);
switch (VCHAN_SYSCTL_DIR(oidp->oid_arg1)) {
case VCHAN_PLAY:
if ((d->flags & SD_F_PVCHANS) == 0) {
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
return (ENODEV);
}
direction = PCMDIR_PLAY;
@@ -526,20 +513,17 @@
break;
case VCHAN_REC:
if ((d->flags & SD_F_RVCHANS) == 0) {
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
return (ENODEV);
}
direction = PCMDIR_REC;
vchanformat = &d->rvchanformat;
break;
default:
- PCM_UNLOCK(d);
+ PCM_RELEASE_QUICK(d);
return (EINVAL);
}
- PCM_ACQUIRE(d);
- PCM_UNLOCK(d);
-
bzero(fmtstr, sizeof(fmtstr));
if (snd_afmt2str(*vchanformat, fmtstr, sizeof(fmtstr)) != *vchanformat)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Sep 30, 2:14 PM (17 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39949523
Default Alt Text
D60127.id188000.diff (12 KB)
Attached To
Mode
D60127: sound: Do not take PCM_LOCK just to busy the device
Attached
Detach File
Event Timeline
Log In to Comment