Re: kqueue periodic timer confusion

2012-07-19 Thread Andriy Gapon
on 19/07/2012 18:11 Davide Italiano said the following:
> On Thu, Jul 19, 2012 at 5:06 PM, Paul Albrecht  wrote:
>> On Fri, 2012-07-13 at 07:22 -0500, Davide Italiano wrote:
>>> On Thu, Jul 12, 2012 at 5:25 PM, John Baldwin  wrote:
 On Thursday, July 12, 2012 11:08:47 am Davide Italiano wrote:
> On Thu, Jul 12, 2012 at 4:26 PM, John Baldwin  wrote:
>> On Thursday, July 12, 2012 9:57:16 am Ian Lepore wrote:
>>> On Thu, 2012-07-12 at 08:34 -0400, John Baldwin wrote:
 On Wednesday, July 11, 2012 5:00:47 pm Ian Lepore wrote:
> On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
>> Hi,
>>
>> Sorry about this repost but I'm confused about the responses I 
>> received
>> in my last post so I'm looking for some clarification.
>>
>> Specifically, I though I could use the kqueue timer as essentially a
>> "drop in" replacement for linuxfd_create/read, but was surprised that
>> the accuracy of the kqueue timer is much less than what I need for my
>> application.
>>
>> So my confusion at this point is whether this is consider to be a 
>> bug or
>> "feature"?
>>
>> Here's some test code if you want to verify the problem:
>>
>> #include 
>> #include 
>> #include 
>> #include 
>> #include 
>> #include 
>> #include 
>> #include 
>>
>> int
>> main(void)
>> {
>> int i,msec;
>> int kq,nev;
>> struct kevent inqueue;
>> struct kevent outqueue;
>> struct timeval start,end;
>>
>> if ((kq = kqueue()) == -1) {
>> fprintf(stderr, "kqueue error!? errno = %s",
 strerror(errno));
>> exit(EXIT_FAILURE);
>> }
>> EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 20, 
>> 0);
>>
>> gettimeofday(&start, 0);
>> for (i = 0; i < 50; i++) {
>> if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, 
>> NULL)) ==
 -1) {
>> fprintf(stderr, "kevent error!? errno = %s",
 strerror(errno));
>> exit(EXIT_FAILURE);
>> } else if (outqueue.flags & EV_ERROR) {
>> fprintf(stderr, "EV_ERROR: %s\n",
 strerror(outqueue.data));
>> exit(EXIT_FAILURE);
>> }
>> }
>> gettimeofday(&end, 0);
>>
>> msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 +
 end.tv_usec - start.tv_usec) / 1000) - 1000);
>>
>> printf("msec = %d\n", msec);
>>
>> close(kq);
>> return EXIT_SUCCESS;
>> }
>>
>>
>
> What you are seeing is "just the way FreeBSD currently works."
>
> Sleeping (in most all of its various forms, and I've just looked at 
> the
> kevent code to verify this is true there) is handled by converting the
> amount of time to sleep (usually specified in a timeval or timespec
> struct) to a count of timer ticks, using an internal routine called
> tvtohz() in kern/kern_time.c.  That routine rounds up by one tick to
> account for the current tick.  Whether that's a good idea or not (it
> probably was once, and probably not anymore) it's how things currently
> work, and could explain the fairly consistant +1ms you're seeing.

 This is all true, but mostly irrelevant for his case.  EVFILT_TIMER
 installs a periodic callout that executes KNOTE() and then resets 
 itself (via
 callout_reset()) each time it runs.  This should generally be closer to
 regulary spaced intervals than something that does:

>>>
>>> In what way is it irrelevant?  That is, what did I miss?  It appears to
>>> me that the next callout is scheduled by calling timertoticks() passing
>>> a count of milliseconds, that count is converted to a struct timeval and
>>> passed to tvtohz() which is where the +1 adjustment happens.  If you ask
>>> for 20ms and each tick is 1ms, then you'd get regular spacing of 21ms.
>>> There is some time, likely a small number of microseconds, that you've
>>> consumed of the current tick, and that's what the +1 in tvtohz() is
>>> supposed to account for according to the comments.
>>>
>>> The tvtohz() routine both rounds up in the usual way (value+tick-1)/tick
>>> and then adds one tick on top of that.  That seems not quite right to
>>> me, except that it is a way to g'tee that you don't return early, and
>>>

Re: kqueue periodic timer confusion

2012-07-19 Thread Davide Italiano
On Thu, Jul 19, 2012 at 5:06 PM, Paul Albrecht  wrote:
> On Fri, 2012-07-13 at 07:22 -0500, Davide Italiano wrote:
>> On Thu, Jul 12, 2012 at 5:25 PM, John Baldwin  wrote:
>> > On Thursday, July 12, 2012 11:08:47 am Davide Italiano wrote:
>> >> On Thu, Jul 12, 2012 at 4:26 PM, John Baldwin  wrote:
>> >> > On Thursday, July 12, 2012 9:57:16 am Ian Lepore wrote:
>> >> >> On Thu, 2012-07-12 at 08:34 -0400, John Baldwin wrote:
>> >> >> > On Wednesday, July 11, 2012 5:00:47 pm Ian Lepore wrote:
>> >> >> > > On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
>> >> >> > > > Hi,
>> >> >> > > >
>> >> >> > > > Sorry about this repost but I'm confused about the responses I 
>> >> >> > > > received
>> >> >> > > > in my last post so I'm looking for some clarification.
>> >> >> > > >
>> >> >> > > > Specifically, I though I could use the kqueue timer as 
>> >> >> > > > essentially a
>> >> >> > > > "drop in" replacement for linuxfd_create/read, but was surprised 
>> >> >> > > > that
>> >> >> > > > the accuracy of the kqueue timer is much less than what I need 
>> >> >> > > > for my
>> >> >> > > > application.
>> >> >> > > >
>> >> >> > > > So my confusion at this point is whether this is consider to be 
>> >> >> > > > a bug or
>> >> >> > > > "feature"?
>> >> >> > > >
>> >> >> > > > Here's some test code if you want to verify the problem:
>> >> >> > > >
>> >> >> > > > #include 
>> >> >> > > > #include 
>> >> >> > > > #include 
>> >> >> > > > #include 
>> >> >> > > > #include 
>> >> >> > > > #include 
>> >> >> > > > #include 
>> >> >> > > > #include 
>> >> >> > > >
>> >> >> > > > int
>> >> >> > > > main(void)
>> >> >> > > > {
>> >> >> > > > int i,msec;
>> >> >> > > > int kq,nev;
>> >> >> > > > struct kevent inqueue;
>> >> >> > > > struct kevent outqueue;
>> >> >> > > > struct timeval start,end;
>> >> >> > > >
>> >> >> > > > if ((kq = kqueue()) == -1) {
>> >> >> > > > fprintf(stderr, "kqueue error!? errno = %s",
>> >> >> > strerror(errno));
>> >> >> > > > exit(EXIT_FAILURE);
>> >> >> > > > }
>> >> >> > > > EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 
>> >> >> > > > 20, 0);
>> >> >> > > >
>> >> >> > > > gettimeofday(&start, 0);
>> >> >> > > > for (i = 0; i < 50; i++) {
>> >> >> > > > if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, 
>> >> >> > > > NULL)) ==
>> >> >> > -1) {
>> >> >> > > > fprintf(stderr, "kevent error!? errno = 
>> >> >> > > > %s",
>> >> >> > strerror(errno));
>> >> >> > > > exit(EXIT_FAILURE);
>> >> >> > > > } else if (outqueue.flags & EV_ERROR) {
>> >> >> > > > fprintf(stderr, "EV_ERROR: %s\n",
>> >> >> > strerror(outqueue.data));
>> >> >> > > > exit(EXIT_FAILURE);
>> >> >> > > > }
>> >> >> > > > }
>> >> >> > > > gettimeofday(&end, 0);
>> >> >> > > >
>> >> >> > > > msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 
>> >> >> > > > +
>> >> >> > end.tv_usec - start.tv_usec) / 1000) - 1000);
>> >> >> > > >
>> >> >> > > > printf("msec = %d\n", msec);
>> >> >> > > >
>> >> >> > > > close(kq);
>> >> >> > > > return EXIT_SUCCESS;
>> >> >> > > > }
>> >> >> > > >
>> >> >> > > >
>> >> >> > >
>> >> >> > > What you are seeing is "just the way FreeBSD currently works."
>> >> >> > >
>> >> >> > > Sleeping (in most all of its various forms, and I've just looked 
>> >> >> > > at the
>> >> >> > > kevent code to verify this is true there) is handled by converting 
>> >> >> > > the
>> >> >> > > amount of time to sleep (usually specified in a timeval or timespec
>> >> >> > > struct) to a count of timer ticks, using an internal routine called
>> >> >> > > tvtohz() in kern/kern_time.c.  That routine rounds up by one tick 
>> >> >> > > to
>> >> >> > > account for the current tick.  Whether that's a good idea or not 
>> >> >> > > (it
>> >> >> > > probably was once, and probably not anymore) it's how things 
>> >> >> > > currently
>> >> >> > > work, and could explain the fairly consistant +1ms you're seeing.
>> >> >> >
>> >> >> > This is all true, but mostly irrelevant for his case.  EVFILT_TIMER
>> >> >> > installs a periodic callout that executes KNOTE() and then resets 
>> >> >> > itself (via
>> >> >> > callout_reset()) each time it runs.  This should generally be closer 
>> >> >> > to
>> >> >> > regulary spaced intervals than something that does:
>> >> >> >
>> >> >>
>> >> >> In what way is it irrelevant?  That is, what did I miss?  It appears to
>> >> >> me that the next callout is scheduled by calling timertoticks() passing
>> >> >> a count of milliseconds, that count is converted to a struct timeval 
>> >> >> and
>> >> >> passed to tvtohz() which is where the +1 adjustment happens.  If you 
>> >> >> ask
>> >> >> for 20ms and each tick is 1ms, then you'd get regular spacing of 21ms.
>> >> >> There is some ti

Re: kqueue periodic timer confusion

2012-07-19 Thread Paul Albrecht
On Fri, 2012-07-13 at 07:22 -0500, Davide Italiano wrote:
> On Thu, Jul 12, 2012 at 5:25 PM, John Baldwin  wrote:
> > On Thursday, July 12, 2012 11:08:47 am Davide Italiano wrote:
> >> On Thu, Jul 12, 2012 at 4:26 PM, John Baldwin  wrote:
> >> > On Thursday, July 12, 2012 9:57:16 am Ian Lepore wrote:
> >> >> On Thu, 2012-07-12 at 08:34 -0400, John Baldwin wrote:
> >> >> > On Wednesday, July 11, 2012 5:00:47 pm Ian Lepore wrote:
> >> >> > > On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
> >> >> > > > Hi,
> >> >> > > >
> >> >> > > > Sorry about this repost but I'm confused about the responses I 
> >> >> > > > received
> >> >> > > > in my last post so I'm looking for some clarification.
> >> >> > > >
> >> >> > > > Specifically, I though I could use the kqueue timer as 
> >> >> > > > essentially a
> >> >> > > > "drop in" replacement for linuxfd_create/read, but was surprised 
> >> >> > > > that
> >> >> > > > the accuracy of the kqueue timer is much less than what I need 
> >> >> > > > for my
> >> >> > > > application.
> >> >> > > >
> >> >> > > > So my confusion at this point is whether this is consider to be a 
> >> >> > > > bug or
> >> >> > > > "feature"?
> >> >> > > >
> >> >> > > > Here's some test code if you want to verify the problem:
> >> >> > > >
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > >
> >> >> > > > int
> >> >> > > > main(void)
> >> >> > > > {
> >> >> > > > int i,msec;
> >> >> > > > int kq,nev;
> >> >> > > > struct kevent inqueue;
> >> >> > > > struct kevent outqueue;
> >> >> > > > struct timeval start,end;
> >> >> > > >
> >> >> > > > if ((kq = kqueue()) == -1) {
> >> >> > > > fprintf(stderr, "kqueue error!? errno = %s",
> >> >> > strerror(errno));
> >> >> > > > exit(EXIT_FAILURE);
> >> >> > > > }
> >> >> > > > EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 
> >> >> > > > 20, 0);
> >> >> > > >
> >> >> > > > gettimeofday(&start, 0);
> >> >> > > > for (i = 0; i < 50; i++) {
> >> >> > > > if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, 
> >> >> > > > NULL)) ==
> >> >> > -1) {
> >> >> > > > fprintf(stderr, "kevent error!? errno = 
> >> >> > > > %s",
> >> >> > strerror(errno));
> >> >> > > > exit(EXIT_FAILURE);
> >> >> > > > } else if (outqueue.flags & EV_ERROR) {
> >> >> > > > fprintf(stderr, "EV_ERROR: %s\n",
> >> >> > strerror(outqueue.data));
> >> >> > > > exit(EXIT_FAILURE);
> >> >> > > > }
> >> >> > > > }
> >> >> > > > gettimeofday(&end, 0);
> >> >> > > >
> >> >> > > > msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 +
> >> >> > end.tv_usec - start.tv_usec) / 1000) - 1000);
> >> >> > > >
> >> >> > > > printf("msec = %d\n", msec);
> >> >> > > >
> >> >> > > > close(kq);
> >> >> > > > return EXIT_SUCCESS;
> >> >> > > > }
> >> >> > > >
> >> >> > > >
> >> >> > >
> >> >> > > What you are seeing is "just the way FreeBSD currently works."
> >> >> > >
> >> >> > > Sleeping (in most all of its various forms, and I've just looked at 
> >> >> > > the
> >> >> > > kevent code to verify this is true there) is handled by converting 
> >> >> > > the
> >> >> > > amount of time to sleep (usually specified in a timeval or timespec
> >> >> > > struct) to a count of timer ticks, using an internal routine called
> >> >> > > tvtohz() in kern/kern_time.c.  That routine rounds up by one tick to
> >> >> > > account for the current tick.  Whether that's a good idea or not (it
> >> >> > > probably was once, and probably not anymore) it's how things 
> >> >> > > currently
> >> >> > > work, and could explain the fairly consistant +1ms you're seeing.
> >> >> >
> >> >> > This is all true, but mostly irrelevant for his case.  EVFILT_TIMER
> >> >> > installs a periodic callout that executes KNOTE() and then resets 
> >> >> > itself (via
> >> >> > callout_reset()) each time it runs.  This should generally be closer 
> >> >> > to
> >> >> > regulary spaced intervals than something that does:
> >> >> >
> >> >>
> >> >> In what way is it irrelevant?  That is, what did I miss?  It appears to
> >> >> me that the next callout is scheduled by calling timertoticks() passing
> >> >> a count of milliseconds, that count is converted to a struct timeval and
> >> >> passed to tvtohz() which is where the +1 adjustment happens.  If you ask
> >> >> for 20ms and each tick is 1ms, then you'd get regular spacing of 21ms.
> >> >> There is some time, likely a small number of microseconds, that you've
> >> >> consumed of the current tick, and that's what the +1 in tvtohz() is
> >> >> supposed to account for according to the comments.
> >> >>
> >> >> The tvtohz() routine bot

Re: kqueue periodic timer confusion

2012-07-13 Thread John Baldwin
On Friday, July 13, 2012 8:22:13 am Davide Italiano wrote:
> On Thu, Jul 12, 2012 at 5:25 PM, John Baldwin  wrote:
> > On Thursday, July 12, 2012 11:08:47 am Davide Italiano wrote:
> >> On Thu, Jul 12, 2012 at 4:26 PM, John Baldwin  wrote:
> >> > On Thursday, July 12, 2012 9:57:16 am Ian Lepore wrote:
> >> >> On Thu, 2012-07-12 at 08:34 -0400, John Baldwin wrote:
> >> >> > On Wednesday, July 11, 2012 5:00:47 pm Ian Lepore wrote:
> >> >> > > On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
> >> >> > > > Hi,
> >> >> > > >
> >> >> > > > Sorry about this repost but I'm confused about the responses I 
received
> >> >> > > > in my last post so I'm looking for some clarification.
> >> >> > > >
> >> >> > > > Specifically, I though I could use the kqueue timer as 
essentially a
> >> >> > > > "drop in" replacement for linuxfd_create/read, but was surprised 
that
> >> >> > > > the accuracy of the kqueue timer is much less than what I need 
for my
> >> >> > > > application.
> >> >> > > >
> >> >> > > > So my confusion at this point is whether this is consider to be 
a bug or
> >> >> > > > "feature"?
> >> >> > > >
> >> >> > > > Here's some test code if you want to verify the problem:
> >> >> > > >
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > > #include 
> >> >> > > >
> >> >> > > > int
> >> >> > > > main(void)
> >> >> > > > {
> >> >> > > > int i,msec;
> >> >> > > > int kq,nev;
> >> >> > > > struct kevent inqueue;
> >> >> > > > struct kevent outqueue;
> >> >> > > > struct timeval start,end;
> >> >> > > >
> >> >> > > > if ((kq = kqueue()) == -1) {
> >> >> > > > fprintf(stderr, "kqueue error!? errno = %s",
> >> >> > strerror(errno));
> >> >> > > > exit(EXIT_FAILURE);
> >> >> > > > }
> >> >> > > > EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 
20, 0);
> >> >> > > >
> >> >> > > > gettimeofday(&start, 0);
> >> >> > > > for (i = 0; i < 50; i++) {
> >> >> > > > if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, 
NULL)) ==
> >> >> > -1) {
> >> >> > > > fprintf(stderr, "kevent error!? errno = 
%s",
> >> >> > strerror(errno));
> >> >> > > > exit(EXIT_FAILURE);
> >> >> > > > } else if (outqueue.flags & EV_ERROR) {
> >> >> > > > fprintf(stderr, "EV_ERROR: %s\n",
> >> >> > strerror(outqueue.data));
> >> >> > > > exit(EXIT_FAILURE);
> >> >> > > > }
> >> >> > > > }
> >> >> > > > gettimeofday(&end, 0);
> >> >> > > >
> >> >> > > > msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 
+
> >> >> > end.tv_usec - start.tv_usec) / 1000) - 1000);
> >> >> > > >
> >> >> > > > printf("msec = %d\n", msec);
> >> >> > > >
> >> >> > > > close(kq);
> >> >> > > > return EXIT_SUCCESS;
> >> >> > > > }
> >> >> > > >
> >> >> > > >
> >> >> > >
> >> >> > > What you are seeing is "just the way FreeBSD currently works."
> >> >> > >
> >> >> > > Sleeping (in most all of its various forms, and I've just looked 
at the
> >> >> > > kevent code to verify this is true there) is handled by converting 
the
> >> >> > > amount of time to sleep (usually specified in a timeval or 
timespec
> >> >> > > struct) to a count of timer ticks, using an internal routine 
called
> >> >> > > tvtohz() in kern/kern_time.c.  That routine rounds up by one tick 
to
> >> >> > > account for the current tick.  Whether that's a good idea or not 
(it
> >> >> > > probably was once, and probably not anymore) it's how things 
currently
> >> >> > > work, and could explain the fairly consistant +1ms you're seeing.
> >> >> >
> >> >> > This is all true, but mostly irrelevant for his case.  EVFILT_TIMER
> >> >> > installs a periodic callout that executes KNOTE() and then resets 
itself (via
> >> >> > callout_reset()) each time it runs.  This should generally be closer 
to
> >> >> > regulary spaced intervals than something that does:
> >> >> >
> >> >>
> >> >> In what way is it irrelevant?  That is, what did I miss?  It appears 
to
> >> >> me that the next callout is scheduled by calling timertoticks() 
passing
> >> >> a count of milliseconds, that count is converted to a struct timeval 
and
> >> >> passed to tvtohz() which is where the +1 adjustment happens.  If you 
ask
> >> >> for 20ms and each tick is 1ms, then you'd get regular spacing of 21ms.
> >> >> There is some time, likely a small number of microseconds, that you've
> >> >> consumed of the current tick, and that's what the +1 in tvtohz() is
> >> >> supposed to account for according to the comments.
> >> >>
> >> >> The tvtohz() routine both rounds up in the usual way 
(value+tick-1)/tick
> >> >> and then adds one tick on top of that.  That seems not quite right to
> >> >> me, except that it is 

Re: kqueue periodic timer confusion

2012-07-13 Thread Davide Italiano
On Thu, Jul 12, 2012 at 5:25 PM, John Baldwin  wrote:
> On Thursday, July 12, 2012 11:08:47 am Davide Italiano wrote:
>> On Thu, Jul 12, 2012 at 4:26 PM, John Baldwin  wrote:
>> > On Thursday, July 12, 2012 9:57:16 am Ian Lepore wrote:
>> >> On Thu, 2012-07-12 at 08:34 -0400, John Baldwin wrote:
>> >> > On Wednesday, July 11, 2012 5:00:47 pm Ian Lepore wrote:
>> >> > > On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
>> >> > > > Hi,
>> >> > > >
>> >> > > > Sorry about this repost but I'm confused about the responses I 
>> >> > > > received
>> >> > > > in my last post so I'm looking for some clarification.
>> >> > > >
>> >> > > > Specifically, I though I could use the kqueue timer as essentially a
>> >> > > > "drop in" replacement for linuxfd_create/read, but was surprised 
>> >> > > > that
>> >> > > > the accuracy of the kqueue timer is much less than what I need for 
>> >> > > > my
>> >> > > > application.
>> >> > > >
>> >> > > > So my confusion at this point is whether this is consider to be a 
>> >> > > > bug or
>> >> > > > "feature"?
>> >> > > >
>> >> > > > Here's some test code if you want to verify the problem:
>> >> > > >
>> >> > > > #include 
>> >> > > > #include 
>> >> > > > #include 
>> >> > > > #include 
>> >> > > > #include 
>> >> > > > #include 
>> >> > > > #include 
>> >> > > > #include 
>> >> > > >
>> >> > > > int
>> >> > > > main(void)
>> >> > > > {
>> >> > > > int i,msec;
>> >> > > > int kq,nev;
>> >> > > > struct kevent inqueue;
>> >> > > > struct kevent outqueue;
>> >> > > > struct timeval start,end;
>> >> > > >
>> >> > > > if ((kq = kqueue()) == -1) {
>> >> > > > fprintf(stderr, "kqueue error!? errno = %s",
>> >> > strerror(errno));
>> >> > > > exit(EXIT_FAILURE);
>> >> > > > }
>> >> > > > EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 
>> >> > > > 20, 0);
>> >> > > >
>> >> > > > gettimeofday(&start, 0);
>> >> > > > for (i = 0; i < 50; i++) {
>> >> > > > if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, 
>> >> > > > NULL)) ==
>> >> > -1) {
>> >> > > > fprintf(stderr, "kevent error!? errno = %s",
>> >> > strerror(errno));
>> >> > > > exit(EXIT_FAILURE);
>> >> > > > } else if (outqueue.flags & EV_ERROR) {
>> >> > > > fprintf(stderr, "EV_ERROR: %s\n",
>> >> > strerror(outqueue.data));
>> >> > > > exit(EXIT_FAILURE);
>> >> > > > }
>> >> > > > }
>> >> > > > gettimeofday(&end, 0);
>> >> > > >
>> >> > > > msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 +
>> >> > end.tv_usec - start.tv_usec) / 1000) - 1000);
>> >> > > >
>> >> > > > printf("msec = %d\n", msec);
>> >> > > >
>> >> > > > close(kq);
>> >> > > > return EXIT_SUCCESS;
>> >> > > > }
>> >> > > >
>> >> > > >
>> >> > >
>> >> > > What you are seeing is "just the way FreeBSD currently works."
>> >> > >
>> >> > > Sleeping (in most all of its various forms, and I've just looked at 
>> >> > > the
>> >> > > kevent code to verify this is true there) is handled by converting the
>> >> > > amount of time to sleep (usually specified in a timeval or timespec
>> >> > > struct) to a count of timer ticks, using an internal routine called
>> >> > > tvtohz() in kern/kern_time.c.  That routine rounds up by one tick to
>> >> > > account for the current tick.  Whether that's a good idea or not (it
>> >> > > probably was once, and probably not anymore) it's how things currently
>> >> > > work, and could explain the fairly consistant +1ms you're seeing.
>> >> >
>> >> > This is all true, but mostly irrelevant for his case.  EVFILT_TIMER
>> >> > installs a periodic callout that executes KNOTE() and then resets 
>> >> > itself (via
>> >> > callout_reset()) each time it runs.  This should generally be closer to
>> >> > regulary spaced intervals than something that does:
>> >> >
>> >>
>> >> In what way is it irrelevant?  That is, what did I miss?  It appears to
>> >> me that the next callout is scheduled by calling timertoticks() passing
>> >> a count of milliseconds, that count is converted to a struct timeval and
>> >> passed to tvtohz() which is where the +1 adjustment happens.  If you ask
>> >> for 20ms and each tick is 1ms, then you'd get regular spacing of 21ms.
>> >> There is some time, likely a small number of microseconds, that you've
>> >> consumed of the current tick, and that's what the +1 in tvtohz() is
>> >> supposed to account for according to the comments.
>> >>
>> >> The tvtohz() routine both rounds up in the usual way (value+tick-1)/tick
>> >> and then adds one tick on top of that.  That seems not quite right to
>> >> me, except that it is a way to g'tee that you don't return early, and
>> >> that is the one promise made by sleep routines on any OS; those magical
>> >> "at least" words always appear in the docs.
>> >>
>> >> 

Re: kqueue periodic timer confusion

2012-07-12 Thread Paul Albrecht
On Thu, 2012-07-12 at 10:40 -0500, Ian Lepore wrote:
> On Thu, 2012-07-12 at 17:08 +0200, Davide Italiano wrote:
> > On Thu, Jul 12, 2012 at 4:26 PM, John Baldwin  wrote:
> > > On Thursday, July 12, 2012 9:57:16 am Ian Lepore wrote:
> > >> On Thu, 2012-07-12 at 08:34 -0400, John Baldwin wrote:
> > >> > On Wednesday, July 11, 2012 5:00:47 pm Ian Lepore wrote:
> > >> > > On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
> > >> > > > Hi,
> > >> > > >
> > >> > > > Sorry about this repost but I'm confused about the responses I 
> > >> > > > received
> > >> > > > in my last post so I'm looking for some clarification.
> > >> > > >
> > >> > > > Specifically, I though I could use the kqueue timer as essentially 
> > >> > > > a
> > >> > > > "drop in" replacement for linuxfd_create/read, but was surprised 
> > >> > > > that
> > >> > > > the accuracy of the kqueue timer is much less than what I need for 
> > >> > > > my
> > >> > > > application.
> > >> > > >
> > >> > > > So my confusion at this point is whether this is consider to be a 
> > >> > > > bug or
> > >> > > > "feature"?
> > >> > > >
> > >> > > > Here's some test code if you want to verify the problem:
> > >> > > >
> > >> > > > #include 
> > >> > > > #include 
> > >> > > > #include 
> > >> > > > #include 
> > >> > > > #include 
> > >> > > > #include 
> > >> > > > #include 
> > >> > > > #include 
> > >> > > >
> > >> > > > int
> > >> > > > main(void)
> > >> > > > {
> > >> > > > int i,msec;
> > >> > > > int kq,nev;
> > >> > > > struct kevent inqueue;
> > >> > > > struct kevent outqueue;
> > >> > > > struct timeval start,end;
> > >> > > >
> > >> > > > if ((kq = kqueue()) == -1) {
> > >> > > > fprintf(stderr, "kqueue error!? errno = %s",
> > >> > strerror(errno));
> > >> > > > exit(EXIT_FAILURE);
> > >> > > > }
> > >> > > > EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 
> > >> > > > 20, 0);
> > >> > > >
> > >> > > > gettimeofday(&start, 0);
> > >> > > > for (i = 0; i < 50; i++) {
> > >> > > > if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, 
> > >> > > > NULL)) ==
> > >> > -1) {
> > >> > > > fprintf(stderr, "kevent error!? errno = 
> > >> > > > %s",
> > >> > strerror(errno));
> > >> > > > exit(EXIT_FAILURE);
> > >> > > > } else if (outqueue.flags & EV_ERROR) {
> > >> > > > fprintf(stderr, "EV_ERROR: %s\n",
> > >> > strerror(outqueue.data));
> > >> > > > exit(EXIT_FAILURE);
> > >> > > > }
> > >> > > > }
> > >> > > > gettimeofday(&end, 0);
> > >> > > >
> > >> > > > msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 +
> > >> > end.tv_usec - start.tv_usec) / 1000) - 1000);
> > >> > > >
> > >> > > > printf("msec = %d\n", msec);
> > >> > > >
> > >> > > > close(kq);
> > >> > > > return EXIT_SUCCESS;
> > >> > > > }
> > >> > > >
> > >> > > >
> > >> > >
> > >> > > What you are seeing is "just the way FreeBSD currently works."
> > >> > >
> > >> > > Sleeping (in most all of its various forms, and I've just looked at 
> > >> > > the
> > >> > > kevent code to verify this is true there) is handled by converting 
> > >> > > the
> > >> > > amount of time to sleep (usually specified in a timeval or timespec
> > >> > > struct) to a count of timer ticks, using an internal routine called
> > >> > > tvtohz() in kern/kern_time.c.  That routine rounds up by one tick to
> > >> > > account for the current tick.  Whether that's a good idea or not (it
> > >> > > probably was once, and probably not anymore) it's how things 
> > >> > > currently
> > >> > > work, and could explain the fairly consistant +1ms you're seeing.
> > >> >
> > >> > This is all true, but mostly irrelevant for his case.  EVFILT_TIMER
> > >> > installs a periodic callout that executes KNOTE() and then resets 
> > >> > itself (via
> > >> > callout_reset()) each time it runs.  This should generally be closer to
> > >> > regulary spaced intervals than something that does:
> > >> >
> > >>
> > >> In what way is it irrelevant?  That is, what did I miss?  It appears to
> > >> me that the next callout is scheduled by calling timertoticks() passing
> > >> a count of milliseconds, that count is converted to a struct timeval and
> > >> passed to tvtohz() which is where the +1 adjustment happens.  If you ask
> > >> for 20ms and each tick is 1ms, then you'd get regular spacing of 21ms.
> > >> There is some time, likely a small number of microseconds, that you've
> > >> consumed of the current tick, and that's what the +1 in tvtohz() is
> > >> supposed to account for according to the comments.
> > >>
> > >> The tvtohz() routine both rounds up in the usual way (value+tick-1)/tick
> > >> and then adds one tick on top of that.  That seems not quite right to
> > >> me, except that it is a way to g'tee that you don't ret

Re: kqueue periodic timer confusion

2012-07-12 Thread Paul Albrecht
On Thu, 2012-07-12 at 09:26 -0500, John Baldwin wrote:
> On Thursday, July 12, 2012 9:57:16 am Ian Lepore wrote:
> > On Thu, 2012-07-12 at 08:34 -0400, John Baldwin wrote:
> > > On Wednesday, July 11, 2012 5:00:47 pm Ian Lepore wrote:
> > > > On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
> > > > > Hi,
> > > > > 
> > > > > Sorry about this repost but I'm confused about the responses I 
> > > > > received
> > > > > in my last post so I'm looking for some clarification.
> > > > > 
> > > > > Specifically, I though I could use the kqueue timer as essentially a
> > > > > "drop in" replacement for linuxfd_create/read, but was surprised that
> > > > > the accuracy of the kqueue timer is much less than what I need for my
> > > > > application.
> > > > > 
> > > > > So my confusion at this point is whether this is consider to be a bug 
> > > > > or
> > > > > "feature"?
> > > > > 
> > > > > Here's some test code if you want to verify the problem:
> > > > > 
> > > > > #include 
> > > > > #include 
> > > > > #include 
> > > > > #include 
> > > > > #include 
> > > > > #include 
> > > > > #include 
> > > > > #include 
> > > > > 
> > > > > int
> > > > > main(void)
> > > > > {
> > > > > int i,msec;
> > > > > int kq,nev;
> > > > > struct kevent inqueue;
> > > > > struct kevent outqueue;
> > > > > struct timeval start,end;
> > > > > 
> > > > > if ((kq = kqueue()) == -1) {
> > > > > fprintf(stderr, "kqueue error!? errno = %s", 
> > > strerror(errno));
> > > > > exit(EXIT_FAILURE);
> > > > > }
> > > > > EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 20, 
> > > > > 0);
> > > > > 
> > > > > gettimeofday(&start, 0);
> > > > > for (i = 0; i < 50; i++) {
> > > > > if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, 
> > > > > NULL)) == 
> > > -1) {
> > > > > fprintf(stderr, "kevent error!? errno = %s", 
> > > strerror(errno));
> > > > > exit(EXIT_FAILURE);
> > > > > } else if (outqueue.flags & EV_ERROR) {
> > > > > fprintf(stderr, "EV_ERROR: %s\n", 
> > > strerror(outqueue.data));
> > > > > exit(EXIT_FAILURE);
> > > > > }
> > > > > }
> > > > > gettimeofday(&end, 0);
> > > > > 
> > > > > msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 + 
> > > end.tv_usec - start.tv_usec) / 1000) - 1000);
> > > > > 
> > > > > printf("msec = %d\n", msec);
> > > > > 
> > > > > close(kq);
> > > > > return EXIT_SUCCESS;
> > > > > }
> > > > > 
> > > > > 
> > > > 
> > > > What you are seeing is "just the way FreeBSD currently works."  
> > > > 
> > > > Sleeping (in most all of its various forms, and I've just looked at the
> > > > kevent code to verify this is true there) is handled by converting the
> > > > amount of time to sleep (usually specified in a timeval or timespec
> > > > struct) to a count of timer ticks, using an internal routine called
> > > > tvtohz() in kern/kern_time.c.  That routine rounds up by one tick to
> > > > account for the current tick.  Whether that's a good idea or not (it
> > > > probably was once, and probably not anymore) it's how things currently
> > > > work, and could explain the fairly consistant +1ms you're seeing.
> > > 
> > > This is all true, but mostly irrelevant for his case.  EVFILT_TIMER
> > > installs a periodic callout that executes KNOTE() and then resets itself 
> > > (via 
> > > callout_reset()) each time it runs.  This should generally be closer to
> > > regulary spaced intervals than something that does:
> > > 
> > 
> > In what way is it irrelevant?  That is, what did I miss?  It appears to
> > me that the next callout is scheduled by calling timertoticks() passing
> > a count of milliseconds, that count is converted to a struct timeval and
> > passed to tvtohz() which is where the +1 adjustment happens.  If you ask
> > for 20ms and each tick is 1ms, then you'd get regular spacing of 21ms.
> > There is some time, likely a small number of microseconds, that you've
> > consumed of the current tick, and that's what the +1 in tvtohz() is
> > supposed to account for according to the comments.
> > 
> > The tvtohz() routine both rounds up in the usual way (value+tick-1)/tick
> > and then adds one tick on top of that.  That seems not quite right to
> > me, except that it is a way to g'tee that you don't return early, and
> > that is the one promise made by sleep routines on any OS; those magical
> > "at least" words always appear in the docs.
> > 
> > Actually what I'm missing (that I know of) is how the scheduler works.
> > Maybe the +1 adjustment to account for the fraction of the current tick
> > you've already consumed is the right thing to do, even when that
> > fraction is 1uS or less of a 1mS tick.  That would depend on scheduler
> > behavior that I know nothing about.
> 
> Oh.  M

Re: kqueue periodic timer confusion

2012-07-12 Thread Ian Lepore
On Thu, 2012-07-12 at 17:08 +0200, Davide Italiano wrote:
> On Thu, Jul 12, 2012 at 4:26 PM, John Baldwin  wrote:
> > On Thursday, July 12, 2012 9:57:16 am Ian Lepore wrote:
> >> On Thu, 2012-07-12 at 08:34 -0400, John Baldwin wrote:
> >> > On Wednesday, July 11, 2012 5:00:47 pm Ian Lepore wrote:
> >> > > On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
> >> > > > Hi,
> >> > > >
> >> > > > Sorry about this repost but I'm confused about the responses I 
> >> > > > received
> >> > > > in my last post so I'm looking for some clarification.
> >> > > >
> >> > > > Specifically, I though I could use the kqueue timer as essentially a
> >> > > > "drop in" replacement for linuxfd_create/read, but was surprised that
> >> > > > the accuracy of the kqueue timer is much less than what I need for my
> >> > > > application.
> >> > > >
> >> > > > So my confusion at this point is whether this is consider to be a 
> >> > > > bug or
> >> > > > "feature"?
> >> > > >
> >> > > > Here's some test code if you want to verify the problem:
> >> > > >
> >> > > > #include 
> >> > > > #include 
> >> > > > #include 
> >> > > > #include 
> >> > > > #include 
> >> > > > #include 
> >> > > > #include 
> >> > > > #include 
> >> > > >
> >> > > > int
> >> > > > main(void)
> >> > > > {
> >> > > > int i,msec;
> >> > > > int kq,nev;
> >> > > > struct kevent inqueue;
> >> > > > struct kevent outqueue;
> >> > > > struct timeval start,end;
> >> > > >
> >> > > > if ((kq = kqueue()) == -1) {
> >> > > > fprintf(stderr, "kqueue error!? errno = %s",
> >> > strerror(errno));
> >> > > > exit(EXIT_FAILURE);
> >> > > > }
> >> > > > EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 20, 
> >> > > > 0);
> >> > > >
> >> > > > gettimeofday(&start, 0);
> >> > > > for (i = 0; i < 50; i++) {
> >> > > > if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, 
> >> > > > NULL)) ==
> >> > -1) {
> >> > > > fprintf(stderr, "kevent error!? errno = %s",
> >> > strerror(errno));
> >> > > > exit(EXIT_FAILURE);
> >> > > > } else if (outqueue.flags & EV_ERROR) {
> >> > > > fprintf(stderr, "EV_ERROR: %s\n",
> >> > strerror(outqueue.data));
> >> > > > exit(EXIT_FAILURE);
> >> > > > }
> >> > > > }
> >> > > > gettimeofday(&end, 0);
> >> > > >
> >> > > > msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 +
> >> > end.tv_usec - start.tv_usec) / 1000) - 1000);
> >> > > >
> >> > > > printf("msec = %d\n", msec);
> >> > > >
> >> > > > close(kq);
> >> > > > return EXIT_SUCCESS;
> >> > > > }
> >> > > >
> >> > > >
> >> > >
> >> > > What you are seeing is "just the way FreeBSD currently works."
> >> > >
> >> > > Sleeping (in most all of its various forms, and I've just looked at the
> >> > > kevent code to verify this is true there) is handled by converting the
> >> > > amount of time to sleep (usually specified in a timeval or timespec
> >> > > struct) to a count of timer ticks, using an internal routine called
> >> > > tvtohz() in kern/kern_time.c.  That routine rounds up by one tick to
> >> > > account for the current tick.  Whether that's a good idea or not (it
> >> > > probably was once, and probably not anymore) it's how things currently
> >> > > work, and could explain the fairly consistant +1ms you're seeing.
> >> >
> >> > This is all true, but mostly irrelevant for his case.  EVFILT_TIMER
> >> > installs a periodic callout that executes KNOTE() and then resets itself 
> >> > (via
> >> > callout_reset()) each time it runs.  This should generally be closer to
> >> > regulary spaced intervals than something that does:
> >> >
> >>
> >> In what way is it irrelevant?  That is, what did I miss?  It appears to
> >> me that the next callout is scheduled by calling timertoticks() passing
> >> a count of milliseconds, that count is converted to a struct timeval and
> >> passed to tvtohz() which is where the +1 adjustment happens.  If you ask
> >> for 20ms and each tick is 1ms, then you'd get regular spacing of 21ms.
> >> There is some time, likely a small number of microseconds, that you've
> >> consumed of the current tick, and that's what the +1 in tvtohz() is
> >> supposed to account for according to the comments.
> >>
> >> The tvtohz() routine both rounds up in the usual way (value+tick-1)/tick
> >> and then adds one tick on top of that.  That seems not quite right to
> >> me, except that it is a way to g'tee that you don't return early, and
> >> that is the one promise made by sleep routines on any OS; those magical
> >> "at least" words always appear in the docs.
> >>
> >> Actually what I'm missing (that I know of) is how the scheduler works.
> >> Maybe the +1 adjustment to account for the fraction of the current tick
> >> you've already consumed is the right thing to do, eve

Re: kqueue periodic timer confusion

2012-07-12 Thread John Baldwin
On Thursday, July 12, 2012 11:08:47 am Davide Italiano wrote:
> On Thu, Jul 12, 2012 at 4:26 PM, John Baldwin  wrote:
> > On Thursday, July 12, 2012 9:57:16 am Ian Lepore wrote:
> >> On Thu, 2012-07-12 at 08:34 -0400, John Baldwin wrote:
> >> > On Wednesday, July 11, 2012 5:00:47 pm Ian Lepore wrote:
> >> > > On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
> >> > > > Hi,
> >> > > >
> >> > > > Sorry about this repost but I'm confused about the responses I 
> >> > > > received
> >> > > > in my last post so I'm looking for some clarification.
> >> > > >
> >> > > > Specifically, I though I could use the kqueue timer as essentially a
> >> > > > "drop in" replacement for linuxfd_create/read, but was surprised that
> >> > > > the accuracy of the kqueue timer is much less than what I need for my
> >> > > > application.
> >> > > >
> >> > > > So my confusion at this point is whether this is consider to be a 
> >> > > > bug or
> >> > > > "feature"?
> >> > > >
> >> > > > Here's some test code if you want to verify the problem:
> >> > > >
> >> > > > #include 
> >> > > > #include 
> >> > > > #include 
> >> > > > #include 
> >> > > > #include 
> >> > > > #include 
> >> > > > #include 
> >> > > > #include 
> >> > > >
> >> > > > int
> >> > > > main(void)
> >> > > > {
> >> > > > int i,msec;
> >> > > > int kq,nev;
> >> > > > struct kevent inqueue;
> >> > > > struct kevent outqueue;
> >> > > > struct timeval start,end;
> >> > > >
> >> > > > if ((kq = kqueue()) == -1) {
> >> > > > fprintf(stderr, "kqueue error!? errno = %s",
> >> > strerror(errno));
> >> > > > exit(EXIT_FAILURE);
> >> > > > }
> >> > > > EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 20, 
> >> > > > 0);
> >> > > >
> >> > > > gettimeofday(&start, 0);
> >> > > > for (i = 0; i < 50; i++) {
> >> > > > if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, 
> >> > > > NULL)) ==
> >> > -1) {
> >> > > > fprintf(stderr, "kevent error!? errno = %s",
> >> > strerror(errno));
> >> > > > exit(EXIT_FAILURE);
> >> > > > } else if (outqueue.flags & EV_ERROR) {
> >> > > > fprintf(stderr, "EV_ERROR: %s\n",
> >> > strerror(outqueue.data));
> >> > > > exit(EXIT_FAILURE);
> >> > > > }
> >> > > > }
> >> > > > gettimeofday(&end, 0);
> >> > > >
> >> > > > msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 +
> >> > end.tv_usec - start.tv_usec) / 1000) - 1000);
> >> > > >
> >> > > > printf("msec = %d\n", msec);
> >> > > >
> >> > > > close(kq);
> >> > > > return EXIT_SUCCESS;
> >> > > > }
> >> > > >
> >> > > >
> >> > >
> >> > > What you are seeing is "just the way FreeBSD currently works."
> >> > >
> >> > > Sleeping (in most all of its various forms, and I've just looked at the
> >> > > kevent code to verify this is true there) is handled by converting the
> >> > > amount of time to sleep (usually specified in a timeval or timespec
> >> > > struct) to a count of timer ticks, using an internal routine called
> >> > > tvtohz() in kern/kern_time.c.  That routine rounds up by one tick to
> >> > > account for the current tick.  Whether that's a good idea or not (it
> >> > > probably was once, and probably not anymore) it's how things currently
> >> > > work, and could explain the fairly consistant +1ms you're seeing.
> >> >
> >> > This is all true, but mostly irrelevant for his case.  EVFILT_TIMER
> >> > installs a periodic callout that executes KNOTE() and then resets itself 
> >> > (via
> >> > callout_reset()) each time it runs.  This should generally be closer to
> >> > regulary spaced intervals than something that does:
> >> >
> >>
> >> In what way is it irrelevant?  That is, what did I miss?  It appears to
> >> me that the next callout is scheduled by calling timertoticks() passing
> >> a count of milliseconds, that count is converted to a struct timeval and
> >> passed to tvtohz() which is where the +1 adjustment happens.  If you ask
> >> for 20ms and each tick is 1ms, then you'd get regular spacing of 21ms.
> >> There is some time, likely a small number of microseconds, that you've
> >> consumed of the current tick, and that's what the +1 in tvtohz() is
> >> supposed to account for according to the comments.
> >>
> >> The tvtohz() routine both rounds up in the usual way (value+tick-1)/tick
> >> and then adds one tick on top of that.  That seems not quite right to
> >> me, except that it is a way to g'tee that you don't return early, and
> >> that is the one promise made by sleep routines on any OS; those magical
> >> "at least" words always appear in the docs.
> >>
> >> Actually what I'm missing (that I know of) is how the scheduler works.
> >> Maybe the +1 adjustment to account for the fraction of the current tick
> >> you've already consumed is the right thing to do,

Re: kqueue periodic timer confusion

2012-07-12 Thread Davide Italiano
On Thu, Jul 12, 2012 at 4:26 PM, John Baldwin  wrote:
> On Thursday, July 12, 2012 9:57:16 am Ian Lepore wrote:
>> On Thu, 2012-07-12 at 08:34 -0400, John Baldwin wrote:
>> > On Wednesday, July 11, 2012 5:00:47 pm Ian Lepore wrote:
>> > > On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
>> > > > Hi,
>> > > >
>> > > > Sorry about this repost but I'm confused about the responses I received
>> > > > in my last post so I'm looking for some clarification.
>> > > >
>> > > > Specifically, I though I could use the kqueue timer as essentially a
>> > > > "drop in" replacement for linuxfd_create/read, but was surprised that
>> > > > the accuracy of the kqueue timer is much less than what I need for my
>> > > > application.
>> > > >
>> > > > So my confusion at this point is whether this is consider to be a bug 
>> > > > or
>> > > > "feature"?
>> > > >
>> > > > Here's some test code if you want to verify the problem:
>> > > >
>> > > > #include 
>> > > > #include 
>> > > > #include 
>> > > > #include 
>> > > > #include 
>> > > > #include 
>> > > > #include 
>> > > > #include 
>> > > >
>> > > > int
>> > > > main(void)
>> > > > {
>> > > > int i,msec;
>> > > > int kq,nev;
>> > > > struct kevent inqueue;
>> > > > struct kevent outqueue;
>> > > > struct timeval start,end;
>> > > >
>> > > > if ((kq = kqueue()) == -1) {
>> > > > fprintf(stderr, "kqueue error!? errno = %s",
>> > strerror(errno));
>> > > > exit(EXIT_FAILURE);
>> > > > }
>> > > > EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 20, 
>> > > > 0);
>> > > >
>> > > > gettimeofday(&start, 0);
>> > > > for (i = 0; i < 50; i++) {
>> > > > if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, 
>> > > > NULL)) ==
>> > -1) {
>> > > > fprintf(stderr, "kevent error!? errno = %s",
>> > strerror(errno));
>> > > > exit(EXIT_FAILURE);
>> > > > } else if (outqueue.flags & EV_ERROR) {
>> > > > fprintf(stderr, "EV_ERROR: %s\n",
>> > strerror(outqueue.data));
>> > > > exit(EXIT_FAILURE);
>> > > > }
>> > > > }
>> > > > gettimeofday(&end, 0);
>> > > >
>> > > > msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 +
>> > end.tv_usec - start.tv_usec) / 1000) - 1000);
>> > > >
>> > > > printf("msec = %d\n", msec);
>> > > >
>> > > > close(kq);
>> > > > return EXIT_SUCCESS;
>> > > > }
>> > > >
>> > > >
>> > >
>> > > What you are seeing is "just the way FreeBSD currently works."
>> > >
>> > > Sleeping (in most all of its various forms, and I've just looked at the
>> > > kevent code to verify this is true there) is handled by converting the
>> > > amount of time to sleep (usually specified in a timeval or timespec
>> > > struct) to a count of timer ticks, using an internal routine called
>> > > tvtohz() in kern/kern_time.c.  That routine rounds up by one tick to
>> > > account for the current tick.  Whether that's a good idea or not (it
>> > > probably was once, and probably not anymore) it's how things currently
>> > > work, and could explain the fairly consistant +1ms you're seeing.
>> >
>> > This is all true, but mostly irrelevant for his case.  EVFILT_TIMER
>> > installs a periodic callout that executes KNOTE() and then resets itself 
>> > (via
>> > callout_reset()) each time it runs.  This should generally be closer to
>> > regulary spaced intervals than something that does:
>> >
>>
>> In what way is it irrelevant?  That is, what did I miss?  It appears to
>> me that the next callout is scheduled by calling timertoticks() passing
>> a count of milliseconds, that count is converted to a struct timeval and
>> passed to tvtohz() which is where the +1 adjustment happens.  If you ask
>> for 20ms and each tick is 1ms, then you'd get regular spacing of 21ms.
>> There is some time, likely a small number of microseconds, that you've
>> consumed of the current tick, and that's what the +1 in tvtohz() is
>> supposed to account for according to the comments.
>>
>> The tvtohz() routine both rounds up in the usual way (value+tick-1)/tick
>> and then adds one tick on top of that.  That seems not quite right to
>> me, except that it is a way to g'tee that you don't return early, and
>> that is the one promise made by sleep routines on any OS; those magical
>> "at least" words always appear in the docs.
>>
>> Actually what I'm missing (that I know of) is how the scheduler works.
>> Maybe the +1 adjustment to account for the fraction of the current tick
>> you've already consumed is the right thing to do, even when that
>> fraction is 1uS or less of a 1mS tick.  That would depend on scheduler
>> behavior that I know nothing about.
>
> Oh.  My bad, sorry.  You are correct.  It is a bug to use +1 in this
> case.  That is, the +1 makes sense when you are computing a one-time delta
> for thing

Re: kqueue periodic timer confusion

2012-07-12 Thread John Baldwin
On Thursday, July 12, 2012 9:57:16 am Ian Lepore wrote:
> On Thu, 2012-07-12 at 08:34 -0400, John Baldwin wrote:
> > On Wednesday, July 11, 2012 5:00:47 pm Ian Lepore wrote:
> > > On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
> > > > Hi,
> > > > 
> > > > Sorry about this repost but I'm confused about the responses I received
> > > > in my last post so I'm looking for some clarification.
> > > > 
> > > > Specifically, I though I could use the kqueue timer as essentially a
> > > > "drop in" replacement for linuxfd_create/read, but was surprised that
> > > > the accuracy of the kqueue timer is much less than what I need for my
> > > > application.
> > > > 
> > > > So my confusion at this point is whether this is consider to be a bug or
> > > > "feature"?
> > > > 
> > > > Here's some test code if you want to verify the problem:
> > > > 
> > > > #include 
> > > > #include 
> > > > #include 
> > > > #include 
> > > > #include 
> > > > #include 
> > > > #include 
> > > > #include 
> > > > 
> > > > int
> > > > main(void)
> > > > {
> > > > int i,msec;
> > > > int kq,nev;
> > > > struct kevent inqueue;
> > > > struct kevent outqueue;
> > > > struct timeval start,end;
> > > > 
> > > > if ((kq = kqueue()) == -1) {
> > > > fprintf(stderr, "kqueue error!? errno = %s", 
> > strerror(errno));
> > > > exit(EXIT_FAILURE);
> > > > }
> > > > EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 20, 0);
> > > > 
> > > > gettimeofday(&start, 0);
> > > > for (i = 0; i < 50; i++) {
> > > > if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, NULL)) 
> > > > == 
> > -1) {
> > > > fprintf(stderr, "kevent error!? errno = %s", 
> > strerror(errno));
> > > > exit(EXIT_FAILURE);
> > > > } else if (outqueue.flags & EV_ERROR) {
> > > > fprintf(stderr, "EV_ERROR: %s\n", 
> > strerror(outqueue.data));
> > > > exit(EXIT_FAILURE);
> > > > }
> > > > }
> > > > gettimeofday(&end, 0);
> > > > 
> > > > msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 + 
> > end.tv_usec - start.tv_usec) / 1000) - 1000);
> > > > 
> > > > printf("msec = %d\n", msec);
> > > > 
> > > > close(kq);
> > > > return EXIT_SUCCESS;
> > > > }
> > > > 
> > > > 
> > > 
> > > What you are seeing is "just the way FreeBSD currently works."  
> > > 
> > > Sleeping (in most all of its various forms, and I've just looked at the
> > > kevent code to verify this is true there) is handled by converting the
> > > amount of time to sleep (usually specified in a timeval or timespec
> > > struct) to a count of timer ticks, using an internal routine called
> > > tvtohz() in kern/kern_time.c.  That routine rounds up by one tick to
> > > account for the current tick.  Whether that's a good idea or not (it
> > > probably was once, and probably not anymore) it's how things currently
> > > work, and could explain the fairly consistant +1ms you're seeing.
> > 
> > This is all true, but mostly irrelevant for his case.  EVFILT_TIMER
> > installs a periodic callout that executes KNOTE() and then resets itself 
> > (via 
> > callout_reset()) each time it runs.  This should generally be closer to
> > regulary spaced intervals than something that does:
> > 
> 
> In what way is it irrelevant?  That is, what did I miss?  It appears to
> me that the next callout is scheduled by calling timertoticks() passing
> a count of milliseconds, that count is converted to a struct timeval and
> passed to tvtohz() which is where the +1 adjustment happens.  If you ask
> for 20ms and each tick is 1ms, then you'd get regular spacing of 21ms.
> There is some time, likely a small number of microseconds, that you've
> consumed of the current tick, and that's what the +1 in tvtohz() is
> supposed to account for according to the comments.
> 
> The tvtohz() routine both rounds up in the usual way (value+tick-1)/tick
> and then adds one tick on top of that.  That seems not quite right to
> me, except that it is a way to g'tee that you don't return early, and
> that is the one promise made by sleep routines on any OS; those magical
> "at least" words always appear in the docs.
> 
> Actually what I'm missing (that I know of) is how the scheduler works.
> Maybe the +1 adjustment to account for the fraction of the current tick
> you've already consumed is the right thing to do, even when that
> fraction is 1uS or less of a 1mS tick.  That would depend on scheduler
> behavior that I know nothing about.

Oh.  My bad, sorry.  You are correct.  It is a bug to use +1 in this
case.  That is, the +1 makes sense when you are computing a one-time delta
for things like nanosleep().  It is incorrect when computing a periodic
delta such as for computing the interval for an itimer (setitimer) or
EVFILT_TIMER().

Hah, setitime

Re: kqueue periodic timer confusion

2012-07-12 Thread Ian Lepore
On Thu, 2012-07-12 at 08:34 -0400, John Baldwin wrote:
> On Wednesday, July 11, 2012 5:00:47 pm Ian Lepore wrote:
> > On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
> > > Hi,
> > > 
> > > Sorry about this repost but I'm confused about the responses I received
> > > in my last post so I'm looking for some clarification.
> > > 
> > > Specifically, I though I could use the kqueue timer as essentially a
> > > "drop in" replacement for linuxfd_create/read, but was surprised that
> > > the accuracy of the kqueue timer is much less than what I need for my
> > > application.
> > > 
> > > So my confusion at this point is whether this is consider to be a bug or
> > > "feature"?
> > > 
> > > Here's some test code if you want to verify the problem:
> > > 
> > > #include 
> > > #include 
> > > #include 
> > > #include 
> > > #include 
> > > #include 
> > > #include 
> > > #include 
> > > 
> > > int
> > > main(void)
> > > {
> > > int i,msec;
> > > int kq,nev;
> > > struct kevent inqueue;
> > > struct kevent outqueue;
> > > struct timeval start,end;
> > > 
> > > if ((kq = kqueue()) == -1) {
> > > fprintf(stderr, "kqueue error!? errno = %s", 
> strerror(errno));
> > > exit(EXIT_FAILURE);
> > > }
> > > EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 20, 0);
> > > 
> > > gettimeofday(&start, 0);
> > > for (i = 0; i < 50; i++) {
> > > if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, NULL)) 
> > > == 
> -1) {
> > > fprintf(stderr, "kevent error!? errno = %s", 
> strerror(errno));
> > > exit(EXIT_FAILURE);
> > > } else if (outqueue.flags & EV_ERROR) {
> > > fprintf(stderr, "EV_ERROR: %s\n", 
> strerror(outqueue.data));
> > > exit(EXIT_FAILURE);
> > > }
> > > }
> > > gettimeofday(&end, 0);
> > > 
> > > msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 + 
> end.tv_usec - start.tv_usec) / 1000) - 1000);
> > > 
> > > printf("msec = %d\n", msec);
> > > 
> > > close(kq);
> > > return EXIT_SUCCESS;
> > > }
> > > 
> > > 
> > 
> > What you are seeing is "just the way FreeBSD currently works."  
> > 
> > Sleeping (in most all of its various forms, and I've just looked at the
> > kevent code to verify this is true there) is handled by converting the
> > amount of time to sleep (usually specified in a timeval or timespec
> > struct) to a count of timer ticks, using an internal routine called
> > tvtohz() in kern/kern_time.c.  That routine rounds up by one tick to
> > account for the current tick.  Whether that's a good idea or not (it
> > probably was once, and probably not anymore) it's how things currently
> > work, and could explain the fairly consistant +1ms you're seeing.
> 
> This is all true, but mostly irrelevant for his case.  EVFILT_TIMER
> installs a periodic callout that executes KNOTE() and then resets itself (via 
> callout_reset()) each time it runs.  This should generally be closer to
> regulary spaced intervals than something that does:
> 

In what way is it irrelevant?  That is, what did I miss?  It appears to
me that the next callout is scheduled by calling timertoticks() passing
a count of milliseconds, that count is converted to a struct timeval and
passed to tvtohz() which is where the +1 adjustment happens.  If you ask
for 20ms and each tick is 1ms, then you'd get regular spacing of 21ms.
There is some time, likely a small number of microseconds, that you've
consumed of the current tick, and that's what the +1 in tvtohz() is
supposed to account for according to the comments.  

The tvtohz() routine both rounds up in the usual way (value+tick-1)/tick
and then adds one tick on top of that.  That seems not quite right to
me, except that it is a way to g'tee that you don't return early, and
that is the one promise made by sleep routines on any OS; those magical
"at least" words always appear in the docs.

Actually what I'm missing (that I know of) is how the scheduler works.
Maybe the +1 adjustment to account for the fraction of the current tick
you've already consumed is the right thing to do, even when that
fraction is 1uS or less of a 1mS tick.  That would depend on scheduler
behavior that I know nothing about.

-- Ian


___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"


Re: kqueue periodic timer confusion

2012-07-12 Thread John Baldwin
On Wednesday, July 11, 2012 5:00:47 pm Ian Lepore wrote:
> On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
> > Hi,
> > 
> > Sorry about this repost but I'm confused about the responses I received
> > in my last post so I'm looking for some clarification.
> > 
> > Specifically, I though I could use the kqueue timer as essentially a
> > "drop in" replacement for linuxfd_create/read, but was surprised that
> > the accuracy of the kqueue timer is much less than what I need for my
> > application.
> > 
> > So my confusion at this point is whether this is consider to be a bug or
> > "feature"?
> > 
> > Here's some test code if you want to verify the problem:
> > 
> > #include 
> > #include 
> > #include 
> > #include 
> > #include 
> > #include 
> > #include 
> > #include 
> > 
> > int
> > main(void)
> > {
> > int i,msec;
> > int kq,nev;
> > struct kevent inqueue;
> > struct kevent outqueue;
> > struct timeval start,end;
> > 
> > if ((kq = kqueue()) == -1) {
> > fprintf(stderr, "kqueue error!? errno = %s", 
strerror(errno));
> > exit(EXIT_FAILURE);
> > }
> > EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 20, 0);
> > 
> > gettimeofday(&start, 0);
> > for (i = 0; i < 50; i++) {
> > if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, NULL)) == 
-1) {
> > fprintf(stderr, "kevent error!? errno = %s", 
strerror(errno));
> > exit(EXIT_FAILURE);
> > } else if (outqueue.flags & EV_ERROR) {
> > fprintf(stderr, "EV_ERROR: %s\n", 
strerror(outqueue.data));
> > exit(EXIT_FAILURE);
> > }
> > }
> > gettimeofday(&end, 0);
> > 
> > msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 + 
end.tv_usec - start.tv_usec) / 1000) - 1000);
> > 
> > printf("msec = %d\n", msec);
> > 
> > close(kq);
> > return EXIT_SUCCESS;
> > }
> > 
> > 
> 
> What you are seeing is "just the way FreeBSD currently works."  
> 
> Sleeping (in most all of its various forms, and I've just looked at the
> kevent code to verify this is true there) is handled by converting the
> amount of time to sleep (usually specified in a timeval or timespec
> struct) to a count of timer ticks, using an internal routine called
> tvtohz() in kern/kern_time.c.  That routine rounds up by one tick to
> account for the current tick.  Whether that's a good idea or not (it
> probably was once, and probably not anymore) it's how things currently
> work, and could explain the fairly consistant +1ms you're seeing.

This is all true, but mostly irrelevant for his case.  EVFILT_TIMER
installs a periodic callout that executes KNOTE() and then resets itself (via 
callout_reset()) each time it runs.  This should generally be closer to
regulary spaced intervals than something that does:

for (;;) {
usleep(20 * 1000);
}

Which should be subject to the problem you are describing.  It would be 
interesting to see if the callout routine itself is running at the right 
interval or if it is being delayed.  If the latter, then that should be fixed 
if at all possible.  You could investigate that by adding KTR traces to the
relevant callout routine (so recording the TSC timestamp each time the callout 
runs), and then parsing the ktrdump output to compute TSC deltas and examining 
that distribution to see if it is noisy or incorrect, etc.

-- 
John Baldwin
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"


Re: kqueue periodic timer confusion

2012-07-11 Thread Davide Italiano
On Wed, Jul 11, 2012 at 9:52 PM, Paul Albrecht  wrote:
>
> Hi,
>
> Sorry about this repost but I'm confused about the responses I received
> in my last post so I'm looking for some clarification.
>
> Specifically, I though I could use the kqueue timer as essentially a
> "drop in" replacement for linuxfd_create/read, but was surprised that
> the accuracy of the kqueue timer is much less than what I need for my
> application.
>
> So my confusion at this point is whether this is consider to be a bug or
> "feature"?
>
> Here's some test code if you want to verify the problem:
>
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
>
> int
> main(void)
> {
> int i,msec;
> int kq,nev;
> struct kevent inqueue;
> struct kevent outqueue;
> struct timeval start,end;
>
> if ((kq = kqueue()) == -1) {
> fprintf(stderr, "kqueue error!? errno = %s", strerror(errno));
> exit(EXIT_FAILURE);
> }
> EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 20, 0);
>
> gettimeofday(&start, 0);
> for (i = 0; i < 50; i++) {
> if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, NULL)) == 
> -1) {
> fprintf(stderr, "kevent error!? errno = %s", 
> strerror(errno));
> exit(EXIT_FAILURE);
> } else if (outqueue.flags & EV_ERROR) {
> fprintf(stderr, "EV_ERROR: %s\n", 
> strerror(outqueue.data));
> exit(EXIT_FAILURE);
> }
> }
> gettimeofday(&end, 0);
>
> msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 + 
> end.tv_usec - start.tv_usec) / 1000) - 1000);
>
> printf("msec = %d\n", msec);
>
> close(kq);
> return EXIT_SUCCESS;
> }
>
>
> --
> Paul Albrecht
>
> ___
> freebsd-hackers@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"

Hi.
As I told you before I'm currently working on this problem.
I wrote a testcase myself, you can find it here:
http://people.freebsd.org/~davide/kqueue/kevent_test.c
As part of my callout(9) rewriting work I've recently converted
kqueue(9) in order to exploit the precision allowed by the new backend
and exposed to consumers via the new interface
(callout_reset_bt_on()).
I ran my testcase and these are the results over 100 iterations:
http://people.freebsd.org/~davide/kqueue/kqueue_res.png
(red line-> old, green line -> new). It seems there's some
improvement, at least for now.

If you want to give it a try checkout the projects/calloutng branch
and apply the following patch
http://people.freebsd.org/~davide/kqueue/kqueue_calloutng.diff (still
in an early stage, if there are some issues, feel free to report
them).

Davide
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"


Re: kqueue periodic timer confusion

2012-07-11 Thread Ian Lepore
On Wed, 2012-07-11 at 14:52 -0500, Paul Albrecht wrote:
> Hi,
> 
> Sorry about this repost but I'm confused about the responses I received
> in my last post so I'm looking for some clarification.
> 
> Specifically, I though I could use the kqueue timer as essentially a
> "drop in" replacement for linuxfd_create/read, but was surprised that
> the accuracy of the kqueue timer is much less than what I need for my
> application.
> 
> So my confusion at this point is whether this is consider to be a bug or
> "feature"?
> 
> Here's some test code if you want to verify the problem:
> 
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
> 
> int
> main(void)
> {
> int i,msec;
> int kq,nev;
> struct kevent inqueue;
> struct kevent outqueue;
> struct timeval start,end;
> 
> if ((kq = kqueue()) == -1) {
> fprintf(stderr, "kqueue error!? errno = %s", strerror(errno));
> exit(EXIT_FAILURE);
> }
> EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 20, 0);
> 
> gettimeofday(&start, 0);
> for (i = 0; i < 50; i++) {
> if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, NULL)) == 
> -1) {
> fprintf(stderr, "kevent error!? errno = %s", 
> strerror(errno));
> exit(EXIT_FAILURE);
> } else if (outqueue.flags & EV_ERROR) {
> fprintf(stderr, "EV_ERROR: %s\n", 
> strerror(outqueue.data));
> exit(EXIT_FAILURE);
> }
> }
> gettimeofday(&end, 0);
> 
> msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 + 
> end.tv_usec - start.tv_usec) / 1000) - 1000);
> 
> printf("msec = %d\n", msec);
> 
> close(kq);
> return EXIT_SUCCESS;
> }
> 
> 

What you are seeing is "just the way FreeBSD currently works."  

Sleeping (in most all of its various forms, and I've just looked at the
kevent code to verify this is true there) is handled by converting the
amount of time to sleep (usually specified in a timeval or timespec
struct) to a count of timer ticks, using an internal routine called
tvtohz() in kern/kern_time.c.  That routine rounds up by one tick to
account for the current tick.  Whether that's a good idea or not (it
probably was once, and probably not anymore) it's how things currently
work, and could explain the fairly consistant +1ms you're seeing.

Another source of oversleeping is that the length of a tick in
microseconds is simplisticly calculated as 100 / hz on most
hardware, so for HZ=1000, tick=1000.  Unless the clock producing the
tick interrupts is running at a frequency exactly divisible by 1000,
that tick-length calculation has some rounding error in it, and it
results in systematic oversleeping.  On modern hardware with
high-frequency clocks it's typically less than 1%.  

The routines for sleeping in the kernel take a count of ticks for how
long to sleep, so when tvtohz() converts some number of microseconds to
the corresponding number of ticks, any rounding error in the value for
the length of a tick results in oversleeping by some small percentage of
the time you wanted to sleep.  Note that this rounding error in
calculating the length of a tick does not result in a systematic skew in
system timekeeping, because when each tick interrupt happens, the system
reads a clock counter register that may or may not be related to the
clock producing tick interrupts; the value in the register is full
precision without the rounding error you get when counting ticks.

It might be an interesting experiment to add kern.hz=1 to
your /boot/loader.conf and see how that affects your test.

-- Ian


___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"


kqueue periodic timer confusion

2012-07-11 Thread Paul Albrecht

Hi,

Sorry about this repost but I'm confused about the responses I received
in my last post so I'm looking for some clarification.

Specifically, I though I could use the kqueue timer as essentially a
"drop in" replacement for linuxfd_create/read, but was surprised that
the accuracy of the kqueue timer is much less than what I need for my
application.

So my confusion at this point is whether this is consider to be a bug or
"feature"?

Here's some test code if you want to verify the problem:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int
main(void)
{
int i,msec;
int kq,nev;
struct kevent inqueue;
struct kevent outqueue;
struct timeval start,end;

if ((kq = kqueue()) == -1) {
fprintf(stderr, "kqueue error!? errno = %s", strerror(errno));
exit(EXIT_FAILURE);
}
EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, 20, 0);

gettimeofday(&start, 0);
for (i = 0; i < 50; i++) {
if ((nev = kevent(kq, &inqueue, 1, &outqueue, 1, NULL)) == -1) {
fprintf(stderr, "kevent error!? errno = %s", 
strerror(errno));
exit(EXIT_FAILURE);
} else if (outqueue.flags & EV_ERROR) {
fprintf(stderr, "EV_ERROR: %s\n", 
strerror(outqueue.data));
exit(EXIT_FAILURE);
}
}
gettimeofday(&end, 0);

msec = ((end.tv_sec - start.tv_sec) * 1000) + (((100 + end.tv_usec 
- start.tv_usec) / 1000) - 1000);

printf("msec = %d\n", msec);

close(kq);
return EXIT_SUCCESS;
}


-- 
Paul Albrecht

___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"