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

Reply via email to