diff options
| author | Goran Mekić <meka@tilda.center> | 2026-06-17 10:35:07 +0000 |
|---|---|---|
| committer | Christos Margiolis <christos@FreeBSD.org> | 2026-06-17 10:50:39 +0000 |
| commit | fe13f70b95a762e19c38d1152eac6312d8578f84 (patch) | |
| tree | cd0902c0f3950b1293e56a04f9016433d0676b9f | |
| parent | 47ae0a869c7db693ffb1ac058d63dcb79c4e68a8 (diff) | |
sound: Include more information in kevent returned from the kernel
Reviewed by: christos
Differential Revision: https://reviews.freebsd.org/D57362
| -rw-r--r-- | share/man/man4/pcm.4 | 78 | ||||
| -rw-r--r-- | sys/dev/sound/pcm/dsp.c | 14 |
2 files changed, 89 insertions, 3 deletions
diff --git a/share/man/man4/pcm.4 b/share/man/man4/pcm.4 index 181b2120c2e6..cda27d734b74 100644 --- a/share/man/man4/pcm.4 +++ b/share/man/man4/pcm.4 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 21, 2026 +.Dd June 17, 2026 .Dt SOUND 4 .Os .Sh NAME @@ -529,6 +529,82 @@ See for a complete list of the supported .Fn ioctl functions. +.Ss kqueue Support +The +.Va kevent +structure's fields are defined as follows: +.Bl -tag -width "Fa filter" +.It Fa ident +The file descriptor for the device. +.It Fa filter +The kernel filter used to process the event. +This is either +.Dv EVFILT_READ +for recording or +.Dv EVFILT_WRITE +for playback. +.It Fa data +The number of bytes available to be read or written. +.It Fa ext +.Bl -bullet -compact +.It +.Va ext[0] +For devices that use +.Xr mmap 2 , +it contains the +.Va count_info.ptr +field reported by +.Va SNDCTL_DSP_GETIPTR +for recording or +.Va SNDCTL_DSP_GETOPTR +for playback, whereas for devices that do not use +.Xr mmap 2 , +it contains the +.Va oss_count_t.fifo_samples +field reported by +.Va SNDCTL_DSP_CURRENT_IPTR +for recording or +.Va SNDCTL_DSP_CURRENT_OPTR +for playback. +.It +.Va ext[1] +contains the +.Va audio_errinfo.rec_overruns +field for recording events, or the +.Va audio_errinfo.play_underruns +field for playback events, as reported by +.Va SNDCTL_DSP_GETERROR . +.Pp +This allows a single +.Va kevent +to report that data is ready, how many bytes can be read or written, the +current buffer position, and the current error count. +This is especially useful for scenarios that use +.Xr mmap 2 , +because without +.Xr kqueue 2 +the typical processing loop consists of: +.Bl -bullet -compact +.It +Calculating the wait time and calling +.Xr clock_nanosleep 2 . +.It +Calling +.Xr ioctl 2 +for +.Va SNDCTL_DSP_GETIPTR +or +.Va SNDCTL_DSP_GETOPTR +to get the pointer into the memory-mapped buffer where new data starts. +.It +Calling +.Xr ioctl 2 +for +.Va SNDCTL_DSP_GETERROR +to get over/underruns and handle them. +.El +.El +.El .Sh FILES The .Nm diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index 1fa665b6b6cf..7f05da62a173 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -3020,10 +3020,20 @@ dsp_kqevent(struct knote *kn, long hint) } kn->kn_data = 0; if (chn_polltrigger(ch)) { - if (kn->kn_filter == EVFILT_READ) + if (kn->kn_filter == EVFILT_READ) { kn->kn_data = sndbuf_getready(ch->bufsoft); - else + if (ch->flags & CHN_F_MMAP) + kn->kn_kevent.ext[0] = sndbuf_getfreeptr(ch->bufsoft); + else + kn->kn_kevent.ext[0] = sndbuf_getready(ch->bufsoft) / ch->bufsoft->align; + } else { kn->kn_data = sndbuf_getfree(ch->bufsoft); + if (ch->flags & CHN_F_MMAP) + kn->kn_kevent.ext[0] = sndbuf_getreadyptr(ch->bufsoft); + else + kn->kn_kevent.ext[0] = sndbuf_getready(ch->bufsoft) / ch->bufsoft->align; + } + kn->kn_kevent.ext[1] = ch->xruns; } return (kn->kn_data > 0); |
