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>