On Mon, Oct 15, 2012 at 08:21:50AM +0000, Maxim Sobolev 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.

Do I read the code correctly and the cron deamon will wake up every
second now even if @every_second is not used at all?

>   
>   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;

-- 
Pawel Jakub Dawidek                       http://www.wheelsystems.com
FreeBSD committer                         http://www.FreeBSD.org
Am I Evil? Yes, I Am!                     http://tupytaj.pl

Attachment: pgpKrkTH835bv.pgp
Description: PGP signature

Reply via email to