The branch main has been updated by christos: URL: https://cgit.FreeBSD.org/src/commit/?id=fe13f70b95a762e19c38d1152eac6312d8578f84
commit fe13f70b95a762e19c38d1152eac6312d8578f84 Author: Goran Mekić <[email protected]> AuthorDate: 2026-06-17 10:35:07 +0000 Commit: Christos Margiolis <[email protected]> CommitDate: 2026-06-17 10:50:39 +0000 sound: Include more information in kevent returned from the kernel Reviewed by: christos Differential Revision: https://reviews.freebsd.org/D57362 --- share/man/man4/pcm.4 | 78 ++++++++++++++++++++++++++++++++++++++++++++++++- 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);
