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>