Re: current_time in main loop



On 16 Jan 2000, Owen Taylor wrote:

> Hi Tim,
> 
> I've had a chance to look at this now, and I'd agree that we need to
> refetch the time at the end of the poll(). It tends to actually work
> OK for a lot of things now, because usually we'll go around to the
> next iteration immediately, and the timeout will be dispatched without
> further waiting; but the intervals get rather screwed up, because the
> time for the next iterations is _after_ all the other dispatches in
> the same batch get fired, so the next timout is potentially delayed
> under load. 
> 
> The tests you did with BEAST tend to be empirical confirmation that
> the change helps.

i'm not so sure about that "test case" anymore actually, i.e. i'm
not sure i actually encountered behaviour changes due to the current_time
refetch, cause i'm having a hard time to reliably reproduce both cases.

> But I'm less sure we should refetch the time after each dispatch.
> Firt, lets consider a real world example:
> 
>  0ms:  timers start
>  30ms: timer 1 fires, expiration = 60ms
>  40ms: timer 2 fires, expiration = 70ms
>  60ms: timer 1 fires, expiration = 90ms
>  70ms: timer 2 fires, expiration = 100ms
> 
> If we refetch only after the poll, then we have:
> 
>  0ms:  timers start
>  30ms: timer 1 fires, expiration = 60ms
>  40ms: timer 2 fires, expiration = 60ms
>  60ms: timer 1 fires, expiration = 90ms
>  70ms: timer 2 fires, expiration = 90ms
> 
> Not too much to choose between here - either way, we
> get the right intervals, though with the first, there
> is some chance of slippage, since the delay of the
> second timer is permeanent, even if the first timer
> removed.

i agree that we shouldn't really refetch the current time for each
dispatch, less for performance reasons, but because we can do more
accurate dispatching for e.g. g_timeout_dispatch() when passing the
time value when dispatching (checking) started.
dispatch handlers that need a really accurate current time can do
g_get_current_time() on their own; and should do so 1) to compensate
time spent in other dispatch handlers, 2) because very few sources
actually need a current time value.

> So, for pure performance, I'm not really sure what 
> difference it makes. I suppose we need a mainloop
> torture test, and do some testing.
> 
> But there are a couple of, I think, good reasons to 
> not update the current time after the dispatch:
> 
>  - It doesn't fit into the "theory" of the main loop, which
>    is that after the poll, we effectively take a "snapshot"
>    of the current state by calling check on each source, then dispatch
>    them. This means, for instance, that even if we do get
>    a newer current time, then we can't decide to dispatch another
>    timeout based on it. The reason we do things this way
>    is to get a consistent view of the priorities of the sources.
> 
>  - If we don't know whether we need to refetch it, then why don't we
>    save the 1.6us and not do so. Syscalls are cheap on most OS's, but
>    getting the time of day can be a fairly involved process. (On
>    intel, it involves blocking interrupts, obtaining a lock in the
>    kernel, etc.)

yeah, so i suggest we basically apply:

--- gmain.c.orig        Sun Jan 16 03:38:38 2000
+++ gmain.c     Fri Jan 21 20:04:52 2000
@@ -707,7 +707,7 @@
                gboolean dispatch)
 {
   GHook *hook;
-  GTimeVal current_time  ={ 0, 0 };
+  GTimeVal current_time  = { 0, 0 };
   gint n_ready = 0;
   gint current_priority = 0;
   gint timeout;
@@ -810,6 +810,9 @@

   g_main_poll (timeout, n_ready > 0, current_priority);

+  if (timeout != 0)
+    g_get_current_time (&current_time);
+
   /* Check to see what sources need to be dispatched */

   n_ready = 0;


and to make things a bit clearer on the API side, do
s/current_time/check_time/ for the dispatch handlers.

> (And, as I noted, we only want to refetch the time if we poll()
>  with a non-zero timeout.)

that's what the patch currently does, i'm not sure we wouldn't want
to refetch it in either case to "compensate" time spent in the different
prepare() handlers (which may need to make time consuming system calls),
but then i don't have a good example at hand where this would make a
major difference.

> 
> Regards,
>                                         Owen
> 

---
ciaoTJ



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]