Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Oct 2012 15:45:37 -0700
From:      Adrian Chadd <adrian@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: r241576 - in head/usr.sbin/cron: cron crontab lib
Message-ID:  <CAJ-VmomRx_n6LoXeQCPAX-KzVYqPcjhZt1J0MX89FiEEojPePw@mail.gmail.com>
In-Reply-To: <201210150821.q9F8Lobc047576@svn.freebsd.org>
References:  <201210150821.q9F8Lobc047576@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Why not sleep for the amonut of time needed before the next event?



adrian


On 15 October 2012 01:21, Maxim Sobolev <sobomax@freebsd.org> wrote:
> Author: sobomax
> Date: Mon Oct 15 08:21:49 2012
> New Revision: 241576
> URL: http://svn.freebsd.org/changeset/base/241576
>
> Log:
>   Add per-second scheduling into the cron(8). Right now it's
>   only available via the new @every_second shortcut. ENOTIME to
>   implement crontab(5) format extensions to allow more flexible
>   scheduling.
>
>   In order to address some concerns expressed by Terry Lambert
>   while discussing the topic few years ago, about per-second cron
>   possibly causing some bad effects on /etc/crontab by stat()ing
>   it every second instead of every minute now (i.e. atime update),
>   only check that database needs to be reloaded on every 60-th
>   loop run. This should be close enough to the current behaviour.
>
>   Add "@every_minute" shortcut while I am here.
>
>   MFC after:    1 month
>
> Modified:
>   head/usr.sbin/cron/cron/cron.c
>   head/usr.sbin/cron/cron/cron.h
>   head/usr.sbin/cron/crontab/crontab.5
>   head/usr.sbin/cron/lib/entry.c
>
> Modified: head/usr.sbin/cron/cron/cron.c
> ==============================================================================
> --- head/usr.sbin/cron/cron/cron.c      Mon Oct 15 07:57:55 2012        (r241575)
> +++ head/usr.sbin/cron/cron/cron.c      Mon Oct 15 08:21:49 2012        (r241576)
> @@ -98,6 +98,7 @@ main(argc, argv)
>         char    *argv[];
>  {
>         cron_db database;
> +       int runnum;
>
>         ProgramName = argv[0];
>
> @@ -149,21 +150,24 @@ main(argc, argv)
>         load_database(&database);
>         run_reboot_jobs(&database);
>         cron_sync();
> +       runnum = 0;
>         while (TRUE) {
>  # if DEBUGGING
>             /* if (!(DebugFlags & DTEST)) */
>  # endif /*DEBUGGING*/
>                         cron_sleep(&database);
>
> -               load_database(&database);
> +               if (runnum % 60 == 0)
> +                       load_database(&database);
>
>                 /* do this iteration
>                  */
>                 cron_tick(&database);
>
> -               /* sleep 1 minute
> +               /* sleep 1 second
>                  */
> -               TargetTime += 60;
> +               TargetTime += 1;
> +               runnum += 1;
>         }
>  }
>
> @@ -194,22 +198,23 @@ cron_tick(db)
>         static time_t   diff = 0, /* time difference in seconds from the last offset change */
>                 difflimit = 0; /* end point for the time zone correction */
>         struct tm       otztm; /* time in the old time zone */
> -       int             otzminute, otzhour, otzdom, otzmonth, otzdow;
> +       int             otzsecond, otzminute, otzhour, otzdom, otzmonth, otzdow;
>         register struct tm      *tm = localtime(&TargetTime);
> -       register int            minute, hour, dom, month, dow;
> +       register int            second, minute, hour, dom, month, dow;
>         register user           *u;
>         register entry          *e;
>
>         /* make 0-based values out of these so we can use them as indicies
>          */
> +       second = tm->tm_sec -FIRST_SECOND;
>         minute = tm->tm_min -FIRST_MINUTE;
>         hour = tm->tm_hour -FIRST_HOUR;
>         dom = tm->tm_mday -FIRST_DOM;
>         month = tm->tm_mon +1 /* 0..11 -> 1..12 */ -FIRST_MONTH;
>         dow = tm->tm_wday -FIRST_DOW;
>
> -       Debug(DSCH, ("[%d] tick(%d,%d,%d,%d,%d)\n",
> -               getpid(), minute, hour, dom, month, dow))
> +       Debug(DSCH, ("[%d] tick(%d,%d,%d,%d,%d,%d)\n",
> +               getpid(), second, minute, hour, dom, month, dow))
>
>         if (dst_enabled && last_time != 0
>         && TargetTime > last_time /* exclude stepping back */
> @@ -262,6 +267,7 @@ cron_tick(db)
>
>                         /* make 0-based values out of these so we can use them as indicies
>                          */
> +                       otzsecond = otztm.tm_sec -FIRST_SECOND;
>                         otzminute = otztm.tm_min -FIRST_MINUTE;
>                         otzhour = otztm.tm_hour -FIRST_HOUR;
>                         otzdom = otztm.tm_mday -FIRST_DOM;
> @@ -283,7 +289,8 @@ cron_tick(db)
>                                           e->uid, e->gid, e->cmd))
>
>                         if ( diff != 0 && (e->flags & (RUN_AT|NOT_UNTIL)) ) {
> -                               if (bit_test(e->minute, otzminute)
> +                               if (bit_test(e->second, otzsecond)
> +                                && bit_test(e->minute, otzminute)
>                                  && bit_test(e->hour, otzhour)
>                                  && bit_test(e->month, otzmonth)
>                                  && ( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR))
> @@ -302,7 +309,8 @@ cron_tick(db)
>                                         continue;
>                         }
>
> -                       if (bit_test(e->minute, minute)
> +                       if (bit_test(e->second, second)
> +                        && bit_test(e->minute, minute)
>                          && bit_test(e->hour, hour)
>                          && bit_test(e->month, month)
>                          && ( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR))
>
> Modified: head/usr.sbin/cron/cron/cron.h
> ==============================================================================
> --- head/usr.sbin/cron/cron/cron.h      Mon Oct 15 07:57:55 2012        (r241575)
> +++ head/usr.sbin/cron/cron/cron.h      Mon Oct 15 08:21:49 2012        (r241576)
> @@ -124,6 +124,10 @@
>                          LineNumber = ln; \
>                         }
>
> +#define        FIRST_SECOND    0
> +#define        LAST_SECOND     59
> +#define        SECOND_COUNT    (LAST_SECOND - FIRST_SECOND + 1)
> +
>  #define        FIRST_MINUTE    0
>  #define        LAST_MINUTE     59
>  #define        MINUTE_COUNT    (LAST_MINUTE - FIRST_MINUTE + 1)
> @@ -165,6 +169,7 @@ typedef     struct _entry {
>  #endif
>         char            **envp;
>         char            *cmd;
> +       bitstr_t        bit_decl(second, SECOND_COUNT);
>         bitstr_t        bit_decl(minute, MINUTE_COUNT);
>         bitstr_t        bit_decl(hour,   HOUR_COUNT);
>         bitstr_t        bit_decl(dom,    DOM_COUNT);
>
> Modified: head/usr.sbin/cron/crontab/crontab.5
> ==============================================================================
> --- head/usr.sbin/cron/crontab/crontab.5        Mon Oct 15 07:57:55 2012        (r241575)
> +++ head/usr.sbin/cron/crontab/crontab.5        Mon Oct 15 08:21:49 2012        (r241576)
> @@ -232,6 +232,8 @@ string              meaning
>  @daily         Run once a day, "0 0 * * *".
>  @midnight      (same as @daily)
>  @hourly                Run once an hour, "0 * * * *".
> +@every_minute  Run once a minute, "*/1 * * * *".
> +@every_second  Run once a second.
>  .Ed
>  .Sh EXAMPLE CRON FILE
>  .Bd -literal
>
> Modified: head/usr.sbin/cron/lib/entry.c
> ==============================================================================
> --- head/usr.sbin/cron/lib/entry.c      Mon Oct 15 07:57:55 2012        (r241575)
> +++ head/usr.sbin/cron/lib/entry.c      Mon Oct 15 08:21:49 2012        (r241576)
> @@ -151,6 +151,7 @@ load_entry(file, error_func, pw, envp)
>                         e->flags |= WHEN_REBOOT;
>                 } else if (!strcmp("yearly", cmd) || !strcmp("annually", cmd)){
>                         Debug(DPARS, ("load_entry()...yearly shortcut\n"))
> +                       bit_set(e->second, 0);
>                         bit_set(e->minute, 0);
>                         bit_set(e->hour, 0);
>                         bit_set(e->dom, 0);
> @@ -159,6 +160,7 @@ load_entry(file, error_func, pw, envp)
>                         e->flags |= DOW_STAR;
>                 } else if (!strcmp("monthly", cmd)) {
>                         Debug(DPARS, ("load_entry()...monthly shortcut\n"))
> +                       bit_set(e->second, 0);
>                         bit_set(e->minute, 0);
>                         bit_set(e->hour, 0);
>                         bit_set(e->dom, 0);
> @@ -167,6 +169,7 @@ load_entry(file, error_func, pw, envp)
>                         e->flags |= DOW_STAR;
>                 } else if (!strcmp("weekly", cmd)) {
>                         Debug(DPARS, ("load_entry()...weekly shortcut\n"))
> +                       bit_set(e->second, 0);
>                         bit_set(e->minute, 0);
>                         bit_set(e->hour, 0);
>                         bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
> @@ -175,6 +178,7 @@ load_entry(file, error_func, pw, envp)
>                         bit_set(e->dow, 0);
>                 } else if (!strcmp("daily", cmd) || !strcmp("midnight", cmd)) {
>                         Debug(DPARS, ("load_entry()...daily shortcut\n"))
> +                       bit_set(e->second, 0);
>                         bit_set(e->minute, 0);
>                         bit_set(e->hour, 0);
>                         bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
> @@ -182,11 +186,28 @@ load_entry(file, error_func, pw, envp)
>                         bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1));
>                 } else if (!strcmp("hourly", cmd)) {
>                         Debug(DPARS, ("load_entry()...hourly shortcut\n"))
> +                       bit_set(e->second, 0);
>                         bit_set(e->minute, 0);
>                         bit_nset(e->hour, 0, (LAST_HOUR-FIRST_HOUR+1));
>                         bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
>                         bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1));
>                         bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1));
> +               } else if (!strcmp("every_minute", cmd)) {
> +                       Debug(DPARS, ("load_entry()...every_minute shortcut\n"))
> +                       bit_set(e->second, 0);
> +                       bit_nset(e->minute, 0, (LAST_MINUTE-FIRST_MINUTE+1));
> +                       bit_nset(e->hour, 0, (LAST_HOUR-FIRST_HOUR+1));
> +                       bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
> +                       bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1));
> +                       bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1));
> +               } else if (!strcmp("every_second", cmd)) {
> +                       Debug(DPARS, ("load_entry()...every_second shortcut\n"))
> +                       bit_nset(e->second, 0, (LAST_SECOND-FIRST_SECOND+1));
> +                       bit_nset(e->minute, 0, (LAST_MINUTE-FIRST_MINUTE+1));
> +                       bit_nset(e->hour, 0, (LAST_HOUR-FIRST_HOUR+1));
> +                       bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
> +                       bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1));
> +                       bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1));
>                 } else {
>                         ecode = e_timespec;
>                         goto eof;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-VmomRx_n6LoXeQCPAX-KzVYqPcjhZt1J0MX89FiEEojPePw>