Subject: Re: Moving to struct timespec in the kernel.
To: Jonathan Stone <jonathan@dsg.stanford.edu>
From: Matt Thomas <matt@3am-software.com>
List: tech-kern
Date: 02/22/2005 16:01:44
At 01:38 PM 2/22/2005, Jonathan Stone wrote:
>In message <20050222145841.GY388@canolog.ninthwonder.com>,
>Allen Briggs writes:
>
> >On Sat, Feb 19, 2005 at 01:45:04AM -0800, Matt Thomas wrote:
> >> Currently, the kernel uses struct timeval (time_t + microseconds)
> >> internally for the large majority.  However, POSIX created struct
> >> timespec (time_t + nanoseconds) and used it in clock_gettime(3), etc.
> >>
> >> I think it's time NetBSD moves to using struct timespec in the kernel.
> >
> >I agree.  I also like the addition of pselect(2) and your proposal
> >for pollts(2).
>
>"Me too". If I had had the time, I'd have done it a couple of years
>ago.  (Didn't it come up then?)

I've already implemented pollts and pselect (it took remarkably
little effort).  Since they were so easy, should I add them for
3.0?

>I'd add one caveat: can you leave select(2) as a syscall?

I could but i don't really think it's needed.

>We'll need an in-kernel select() for many emauls for legacy reasons,
>so in the typical case it's not that big a deal.  And that finesses
>the thorny issue about whether select(2) treats the timeout value as
>an pure input, or may modify it to return the remaining time.  (I know
>what our select(2) manpage says, but don't some emuls require the
>modify-timeval behaviour?)

I created pollcommon and selectcommon which do
the majority of the work.

For instance, sys_select is reduced to:

int
sys_select(struct lwp *l, void *v, register_t *retval)
{
         struct sys_select_args /* {
                 syscallarg(int)                 nd;
                 syscallarg(fd_set *)            in;
                 syscallarg(fd_set *)            ou;
                 syscallarg(fd_set *)            ex;
                 syscallarg(struct timeval *)    tv;
         } */ * const uap = v;
         struct timeval atv;
         struct timespec ats, *ts = NULL;
         int error;

         if (SCARG(uap, tv)) {
                 error = copyin(SCARG(uap, tv), (caddr_t)&atv,
                         sizeof(atv));
                 if (error)
                         return error;
                 ats.tv_sec = atv.tv_sec;
                 ats.tv_nsec = atv.atv_usec * 1000;
                 ts = &ats;
         }

         return selectcommon(l, retval, SCARG(uap, nd), SCARG(uap, in),
             SCARG(uap, ou), SCARG(uap, ex), ts, NULL);
}

Any emulation that needs its own select, can simply call selectcommon to do
the majority of the work.

-- 
Matt Thomas                     email: matt@3am-software.com
3am Software Foundry              www: http://3am-software.com/bio/matt/
Cupertino, CA              disclaimer: I avow all knowledge of this message.