svn commit: r241625 - head/usr.sbin/cron/cron

Bruce Evans brde at optusnet.com.au
Wed Oct 17 11:21:31 UTC 2012


On Wed, 17 Oct 2012, Xin Li wrote:

> On 10/16/12 5:44 PM, Maxim Sobolev wrote:
>> Author: sobomax Date: Wed Oct 17 00:44:34 2012 New Revision:
>> 241625 URL: http://svn.freebsd.org/changeset/base/241625
>>
>> Log: o Use nanosleep(2) to sleep exact amount of time till the next
>> second, not multiple of 1 second, which results in actual time to
>> drift back and forth every run within 1 second of the actual action
>> has been set for.
>>
>> Suggested by:   Ian Lepore
>>
>> o Schedule the first run in 1 second after starting up, not on the
>> boundary of the next minute, which results in the every_second
>> jobs not being run.
>
>>
>> for (;;) { -		seconds_to_wait = (int) (TargetTime -
>> time((time_t*)0)); +		gettimeofday(&ctime, NULL);
>
> Could you please replace this with clock_gettime(CLOCK_REALTIME_FAST)?
> This also gives us time in timespec, suitable for use with nanosleep,
> plus save some code for the subtract helper.

CLOCK_REALTIME_FAST_N_BROKEN should never be used.  It isn't even fast
on systems with fast timecounter hardware, since the syscall overhead 
dominates the time.  It is broken since times read by it are not ordered
relative to times read by CLOCK_REALTIME.

Using CLOCK_REALTIME would be good.  cron should also consider using
CLOCK_MONOTONIC.  cron is one of the few things that needs real time
instead of monotonic time for most things, but perhaps it should check
the monotonic time occasionally in case someone stepped the real time
crazily.  For checking things every second, monotonic time is probably
best, but most things in crontabs want real time.

nanosleep() is quite broken here, and use of CLOCK_REALTIME_BROKEN_OR_NOT
is incompatible with use of the broken nanosleep().  POSIX specifies that
nanosleep() sleeps in intervals measured by CLOCK_REALTIME, but in FreeBSD
it sleeps in intervals measured by CLOCK_MONOTONIC.  POSIX specifies
clock_nanosleep(), which can sleep in on any clock, and is probably what
is wanted (with CLOCK_MONOTONIC) in most cases, but FreeBSD doesn't
implement this.  FreeBSD does implement some other POSIX APIS that can
get timeouts on any clock.  Perhaps these can be used to implement
clock_nanosleep() in a library, but I'm not familiar with them.

sleep() uses nanosleep() so it sleeps on the same wrong clock as
nanosleep().  sleep() existed before clock ids were dreamed of, so this
is more broken for it than for nanosleep().  It originally had no option
except to sleep in real time, so POSIX had to specify that it keep
sleeping on the clock id for that time once clock ids for sleeping
became available.

Bruce


More information about the svn-src-head mailing list