Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Oct 2003 19:21:46 +0900
From:      Seigo Tanimura <tanimura@tanimura.dyndns.org>
To:        arch@FreeBSD.org
Cc:        Seigo Tanimura <tanimura@tanimura.dyndns.org>
Subject:   Re: Who should set the priority of a select(2)ing thread being waken up?
Message-ID:  <200310221021.h9MALkUM023905@urban>
In-Reply-To: <200310220319.h9M3JGI1005225@urban>
References:  <200310220319.h9M3JGI1005225@urban>

next in thread | previous in thread | raw e-mail | index | archive | help
--Multipart_Wed_Oct_22_19:21:46_2003-1
Content-Type: text/plain; charset=US-ASCII

On Wed, 22 Oct 2003 12:19:16 +0900,
  Seigo Tanimura <tanimura@tanimura.dyndns.org> said:

tanimura> In good old days, only a socket and a pipe were the major file
tanimura> descriptors being select(2)ed.  As select(2) was just a socket
tanimura> operation, it was sufficient to set the priority of select(2)ing
tanimura> process to PSOCK(*1), I suppose.

tanimura> Nowadays, quite a few drivers support select(2) as well, including
tanimura> sound, usb, scsi controllers, and so on.  I am not convinced whether a
tanimura> process should select(2) those devices at PSOCK as we do for a socket.

tanimura> Suppose that a process select(2)s for a pcm device and a socket at
tanimura> once.  If the process is waken up by the pcm driver at PSOCK, another
tanimura> process at a better priority may preempt the first one, which can
tanimura> result in dropping some pcm data.

tanimura> Maybe it would be better if the caller of selwakeup() could determine
tanimura> the priority of a process or a thread.  That would let us raise the
tanimura> priority to PRIBIO if pcm data was ready, while the priority would
tanimura> stay at PSOCK if the socket was ready.


tanimura> (*1) I broke that in 5-CURRENT when I modified select(2) and poll(2)
tanimura> to use a conditional variable.

The attached patch implements selwakeuppri(), which lets you set the
priority of a thread being waken up.  Also in the patch is a small
test code to use selwakeuppri() in pcm(4).


Comments are welcome, thanks in advance.

-- 
Seigo Tanimura <tanimura@tanimura.dyndns.org> <tanimura@FreeBSD.org>

--Multipart_Wed_Oct_22_19:21:46_2003-1
Content-Type: text/x-patch; type=patch; charset=US-ASCII
Content-Disposition: attachment; filename="selwakeuppri.diff"
Content-Transfer-Encoding: 7bit

diff -urN --exclude-from=/home/urban/tanimura/selwakeuppri.exclude.txt freebsd/sys/dev/sound/pcm/channel.c handoffpri/dev/sound/pcm/channel.c
--- freebsd/sys/dev/sound/pcm/channel.c	Fri Oct 17 14:53:58 2003
+++ handoffpri/dev/sound/pcm/channel.c	Wed Oct 22 18:34:09 2003
@@ -116,7 +116,7 @@
 
 	CHN_LOCKASSERT(c);
 	if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c))
-		selwakeup(sndbuf_getsel(bs));
+		selwakeuppri(sndbuf_getsel(bs), PRIBIO);
 	wakeup(bs);
 }
 
diff -urN --exclude-from=/home/urban/tanimura/selwakeuppri.exclude.txt freebsd/sys/kern/sys_generic.c handoffpri/kern/sys_generic.c
--- freebsd/sys/kern/sys_generic.c	Fri Oct 17 14:54:25 2003
+++ handoffpri/kern/sys_generic.c	Wed Oct 22 18:34:09 2003
@@ -82,6 +82,7 @@
 		    size_t, off_t, int);
 static int	dofilewrite(struct thread *, struct file *, int,
 		    const void *, size_t, off_t, int);
+static void	doselwakeup(struct selinfo *, int);
 
 /*
  * Read system call.
@@ -1162,12 +1163,30 @@
 	mtx_unlock(&sellock);
 }
 
+/* Wake up a selecting thread. */
+void
+selwakeup(sip)
+	struct selinfo *sip;
+{
+	doselwakeup(sip, -1);
+}
+
+/* Wake up a selecting thread, and set its priority. */
+void
+selwakeuppri(sip, pri)
+	struct selinfo *sip;
+	int pri;
+{
+	doselwakeup(sip, pri);
+}
+
 /*
  * Do a wakeup when a selectable event occurs.
  */
-void
-selwakeup(sip)
+static void
+doselwakeup(sip, pri)
 	struct selinfo *sip;
+	int pri;
 {
 	struct thread *td;
 
@@ -1188,6 +1207,8 @@
 	if (td->td_wchan == &selwait) {
 		cv_waitq_remove(td);
 		TD_CLR_SLEEPING(td);
+		if (pri >= PRI_MIN && pri <= PRI_MAX)
+			td->td_priority = pri;
 		setrunnable(td);
 	} else
 		td->td_flags &= ~TDF_SELECT;
diff -urN --exclude-from=/home/urban/tanimura/selwakeuppri.exclude.txt freebsd/sys/sys/selinfo.h handoffpri/sys/selinfo.h
--- freebsd/sys/sys/selinfo.h	Fri May  2 11:05:02 2003
+++ handoffpri/sys/selinfo.h	Wed Oct 22 18:34:09 2003
@@ -58,6 +58,7 @@
 void	clear_selinfo_list(struct thread *td);
 void	selrecord(struct thread *selector, struct selinfo *sip);
 void	selwakeup(struct selinfo *sip);
+void	selwakeuppri(struct selinfo *sip, int pri);
 #endif
 
 #endif /* !_SYS_SELINFO_H_ */

--Multipart_Wed_Oct_22_19:21:46_2003-1--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310221021.h9MALkUM023905>