<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Thu May 23 07:38:56 GMT 2013 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='302'>
<header><title>Fix &quot;after&quot;&apos;s Sensitivity To Adjustments Of System Clock</title><author address="mailto:alexandre.ferrieux@gmail.com">Alexandre Ferrieux</author><author address="mailto:kennykb@acm.org">Kevin Kenny</author><status type='project' state='draft' tclversion="8.7" vote='prior'>$Revision: 1.3 $</status><history></history><created day='13' month='dec' year='2006' /><keyword>Tcl {time changes}</keyword></header>
<abstract>Currently, <emph style="bold">after</emph> tasks can be drastically delayed or sped up simply by adjusting the system clock. This is due to the implementation&apos;s use of an <emph style="italic">absolute</emph> target date based on the system clock. The idea of this TIP is to use another timebase for this purpose: the count of ticks from boot, which is not affected by system time adjustments.</abstract>
<body><section title="Background">
<para>The basis of the implementation of <emph style="bold">after</emph> is, on each call to <emph style="bold">vwait</emph>, to compute the <emph style="italic">timeout</emph> argument to select() by difference between the stored target date of the earliest event and the current system date (<emph style="italic">gettimeofday()</emph>). This is perfect while the system date ticks regularly. But if, say, the clock is set back by 5 minutes, then an after handler scheduled 1 second ago which was just about to fire, will have 5 minutes yet to wait before its (unmodified) target date is reached. So, if this handler was part of a 1-Hz periodic task, there will be a huge gap of 5:01 between two ticks at that point. If some other component is expecting some kind of regularity, even with a conservative timeout of 10 times the expected period, it <emph style="italic">will</emph> time out, decide the periodic task is dead, and possibly take drastic action.</para>
</section>
<section title="Proposed Change">
<para>This TIP proposes to use other timebases instead of gettimeofday() in the vwait/after code: <emph style="bold">times()</emph> in unix, <emph style="bold">GetTickCount()</emph> in Windows. These clocks suffer <emph style="italic">no</emph> sysadmin tinkering.</para>
</section>
<section title="Potential Break Of Compatibility">
<para>It has been objected that <emph style="italic">some</emph> applications today may be using <emph style="bold">after</emph> with an <emph style="italic">absolute</emph> spirit; IOW such apps are supposed to <emph style="italic">rely</emph> on the fact that the after handler will fire when the system clock equals the target date computed once for all when <emph style="bold">after</emph> was called. A prototype example would be a crontab-like task, which would itself compute the offset by difference between the target date and the current <emph style="bold">clock seconds</emph>.</para>
<subsection title="Arguments For Breaking It Anyway">
<enumerate><item.e index='1'><para>This <emph style="italic">absolute</emph> interpretation is far from being natural, because <emph style="bold">after</emph>&apos;s argument is an <emph style="italic">offset</emph>.</para></item.e><item.e index='2'><para>This technique is not usable for a longer range than 25 days (MAXINT milliseconds), so not applicable e.g. for a personal schedule.</para></item.e><item.e index='3'><para>The <emph style="bold">overwhelming</emph> majority of uses of <emph style="bold">after</emph> takes the <emph style="italic">relative</emph> interpretation (periodic tasks, timeouts) and <emph style="italic">cannot</emph> work correctly today.</para></item.e><item.e index='4'><para>If this TIP were implemented incompatibly (i.e. without a specific flag to <emph style="bold">after</emph>), those <emph style="italic">absolute-minded</emph> apps could simply be adapted <emph style="italic">and</emph> improved in both robustness and range by using a periodic task which polls <emph style="bold">clock seconds</emph>.</para></item.e><item.e index='5'><para>There is little evidence that the total number of <emph style="italic">absolute-minded</emph> apps exceeds <emph style="bold">one</emph> (see discussion on <url ref="news:comp.lang.tcl"/> &quot;[after] fooled by shifting date&quot;)</para></item.e></enumerate>
</subsection>
</section>
<section title="Syntax For Not Breaking It If Deemed Useful">
<para>Of course, if this supposed singleton is in fact many, or has enough weight to preclude an improvement of the rest of Tcl timers, we can do:</para>
<quote><emph style="bold">after -robust</emph> <emph style="italic">millisecs</emph></quote>
<para>or any other colorful option name. But in this case there is a high risk that: <emph style="italic">either</emph> <emph style="bold">after -robust</emph> becomes the dominant use, thus cluttering the code in many places, <emph style="italic">or</emph> people remain largely unaware of the problem, stick to the default <emph style="bold">after</emph>, and space shuttles fall by dozens.</para>
</section>
<section title="Escalation To The TCT">
<para>I&apos;ll leave it to the TCT to arbitrate, and decide whether <emph style="italic">fixing</emph> a widely used core primitive can outweigh breaking a rare and clumsy use.</para>
</section>
<section title="Reference Implementation">
<para>I have not yet written a reference implementation; I assume somebody with a more fluent practice of the core will do so more efficiently. However, gentle arm twisting, etc.</para>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
<section title="Comments">
<para>The <emph style="italic">times</emph> function in Unix is <emph style="italic">not</emph> an appropriate time base. It reports the user and system time (CPU time, in other words) of the currently executing process and its children. As far as I have been able to determine, Unix assumes that the system time reported by <emph style="italic">gettimeofday</emph> is the sole time base for absolute timing; if multiple timers are required in a single process, <emph style="italic">gettimeofday</emph> appears to be the only reference that is available.</para>
</section>
</body></TIP>
