Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 17 Oct 2012 11:58:21 +0400
From:      Andrey Zonov <zont@FreeBSD.org>
To:        Maxim Sobolev <sobomax@FreeBSD.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r241625 - head/usr.sbin/cron/cron
Message-ID:  <507E651D.2060809@FreeBSD.org>
In-Reply-To: <201210170044.q9H0iZHo055977@svn.freebsd.org>
References:  <201210170044.q9H0iZHo055977@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--------------enig31F401DC21F5684E424370A8
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 10/17/12 4:44 AM, Maxim Sobolev wrote:
> Author: sobomax
> Date: Wed Oct 17 00:44:34 2012
> New Revision: 241625
> URL: http://svn.freebsd.org/changeset/base/241625
>=20
> 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.
>  =20
>   Suggested by:   Ian Lepore
>  =20
>   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.
>=20
> Modified:
>   head/usr.sbin/cron/cron/cron.c
>=20
> Modified: head/usr.sbin/cron/cron/cron.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/usr.sbin/cron/cron/cron.c	Wed Oct 17 00:33:10 2012	(r241624)
> +++ head/usr.sbin/cron/cron/cron.c	Wed Oct 17 00:44:34 2012	(r241625)
> @@ -341,37 +341,73 @@ cron_tick(db)
>   */
>  static void
>  cron_sync() {
> +#if 0
>   	register struct tm	*tm;
> +#endif
> =20
> -	TargetTime =3D time((time_t*)0);
> +	TargetTime =3D time((time_t*)0) + 1;
> +#if 0
>  	tm =3D localtime(&TargetTime);
>  	TargetTime +=3D (60 - tm->tm_sec);
> +#endif
>  }
> =20
> +static int

This should be type of time_t.

> +timeval_subtract(struct timespec *result, struct timeval *x, struct ti=
meval *y)
> +{
> +	int nsec;

And this should be suseconds_t.

> +
> +	/* Perform the carry for the later subtraction by updating y. */
> +	if (x->tv_usec < y->tv_usec) {
> +		nsec =3D (y->tv_usec - x->tv_usec) / 1000000 + 1;
> +		y->tv_usec -=3D 1000000 * nsec;
> +		y->tv_sec +=3D nsec;
> +	}
> +	if (x->tv_usec - y->tv_usec > 1000000) {
> +		nsec =3D (x->tv_usec - y->tv_usec) / 1000000;
> +		y->tv_usec +=3D 1000000 * nsec;
> +		y->tv_sec -=3D nsec;
> +	}
> +    =20
> +	/* tv_nsec is certainly positive. */
> +	result->tv_sec =3D x->tv_sec - y->tv_sec;
> +	result->tv_nsec =3D (x->tv_usec - y->tv_usec) * 1000;
> +    =20
> +	/* Return difference in seconds */
> +	return (x->tv_sec - y->tv_sec);
> +}

May be it's better to use timersub() and TIMEVAL_TO_TIMESPEC()?

> =20
>  static void
>  cron_sleep(db)
>  	cron_db	*db;
>  {
> -	int	seconds_to_wait =3D 0;
> +	int seconds_to_wait;
> +	int rval;
> +	struct timeval ctime, ttime;
> +	struct timespec stime, remtime;
> =20
>  	/*
>  	 * Loop until we reach the top of the next minute, sleep when possibl=
e.
>  	 */
> =20
>  	for (;;) {
> -		seconds_to_wait =3D (int) (TargetTime - time((time_t*)0));
> +		gettimeofday(&ctime, NULL);
> +		ttime.tv_sec =3D TargetTime;
> +		ttime.tv_usec =3D 0;
> +		timeval_subtract(&stime, &ttime, &ctime);
> =20
>  		/*
>  		 * If the seconds_to_wait value is insane, jump the cron
>  		 */
> =20
> -		if (seconds_to_wait < -600 || seconds_to_wait > 600) {
> +		if (stime.tv_sec < -600 || stime.tv_sec > 600) {
>  			cron_clean(db);
>  			cron_sync();
>  			continue;
>  		}
> =20
> +		seconds_to_wait =3D (stime.tv_nsec > 0) ? stime.tv_sec + 1 : stime.t=
v_sec;
> +
>  		Debug(DSCH, ("[%d] TargetTime=3D%ld, sec-to-wait=3D%d\n",
>  			getpid(), (long)TargetTime, seconds_to_wait))
> =20
> @@ -380,13 +416,19 @@ cron_sleep(db)
>  		 * to run, break
>  		 */
> =20
> -		if (seconds_to_wait <=3D 0)
> +		if (stime.tv_sec < 0)
>  			break;
>  		if (job_runqueue() =3D=3D 0) {
>  			Debug(DSCH, ("[%d] sleeping for %d seconds\n",
>  				getpid(), seconds_to_wait))
> =20
> -			sleep(seconds_to_wait);
> +			for (;;) {
> +				rval =3D nanosleep(&stime, &remtime);
> +				if (rval =3D=3D 0 || errno !=3D EINTR)
> +					break;
> +				stime.tv_sec =3D remtime.tv_sec;
> +				stime.tv_nsec =3D remtime.tv_nsec;
> +			}
>  		}
>  	}
>  }
>=20


--=20
Andrey Zonov


--------------enig31F401DC21F5684E424370A8
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.18 (Darwin)
Comment: GPGTools - http://gpgtools.org

iQEcBAEBAgAGBQJQfmUhAAoJEBWLemxX/CvTiXkH/jqGbd/nVeCJw4h2yKvXhL8y
4SMPIWJ+mHwtgPm4uhYNJ0MrZzVpmt1VwOzgyCz1SKPVvLDFP5KF2RJDs2hQFJn7
uMTaazdK6zOirNWjXj2YsFSERz/LdvxEF4aOPOqe6qQYtlZE7L8cF7rMCWPgPhm0
RFFVqX7eUS3yJOMfSG/hInnyt0RSPXnhw3i3531mnQKJloq3G36sr9McS11IYsaC
YhUn4h+/HIDeHi9UN2Nl4n1Obmm9zOiSyiZcn+8w/4wAsv7O7qsxqyq1Y0SLDQlL
2IuQ8GR1qCc/lfT9oQjLHH04u5hwmpcogyImojRXh/XZDXSpirIVG6mKmfoC+5A=
=SufR
-----END PGP SIGNATURE-----

--------------enig31F401DC21F5684E424370A8--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?507E651D.2060809>