Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:michael_meeks:fastboot
util-linux
hwclock-adjust-and-hctosys.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File hwclock-adjust-and-hctosys.diff of Package util-linux
From: Kurt Garloff <garloff@suse.de> Subject: Allow to combine --adjust and --hctosys Reference: bnc441106 Waiting for a clock tick twice when calling --adjust and --hctosys is wasteful. Having to do it once is bad enough. This patch allows combining the two options. It does two additional things: The busy wait loop for set_hardware_clock_exact() is replaced by a version that does some usleep()ing to save CPU cycles. It's broken out in a separate function. It also uses the newly introduced usec granularity of set_system_clock() to avoid the up to 1s inaccuracy in --preadjust. [Patch 4/4] Index: util-linux-ng-2.14.1/hwclock/hwclock.c =================================================================== --- util-linux-ng-2.14.1.orig/hwclock/hwclock.c +++ util-linux-ng-2.14.1/hwclock/hwclock.c @@ -489,19 +489,13 @@ set_hardware_clock(const time_t newtime, err = ur->set_hardware_clock(&new_broken_time); } } +static int +set_system_clock(const bool hclock_valid, const time_t newtime, + const bool testing, const int usec); - -static void -set_hardware_clock_exact(const time_t sethwtime, - const struct timeval refsystime, - const bool universal, - const bool testing) { /*---------------------------------------------------------------------------- - Set the Hardware Clock to the time "sethwtime", in local time zone or UTC, - according to "universal". - Wait for a fraction of a second so that "sethwtime" is the value of the Hardware Clock as of system time "refsystime", which is in the past. For example, if "sethwtime" is 14:03:05 and "refsystime" is 12:10:04.5 and the current system time is 12:10:06.0: Wait .5 seconds (to make @@ -514,11 +508,16 @@ set_hardware_clock_exact(const time_t se This function ought to be able to accept set times as fractional times. Idea for future enhancement. -----------------------------------------------------------------------------*/ - +static time_t +time_busy_wait(const time_t sethwtime, + const struct timeval refsystime, + float delta) +{ time_t newhwtime; struct timeval beginsystime, nowsystime; + float towait; time_resync: gettimeofday(&beginsystime, NULL); newhwtime = sethwtime + (int) time_diff(beginsystime, refsystime) + 1; @@ -538,15 +537,35 @@ set_hardware_clock_exact(const time_t se gettimeofday(&nowsystime, NULL); tdiff = time_diff(nowsystime, beginsystime); if (tdiff < 0) goto time_resync; /* probably time was reset */ - } while (time_diff(nowsystime, refsystime) - 0.5 < newhwtime - sethwtime); + towait = newhwtime - sethwtime + delta - time_diff(nowsystime, refsystime); + if (towait > 0.08) { + usleep(1000000*(towait-0.08)); + towait = 0.08; + } + } while (towait > 0); + return newhwtime; +} +static void +set_hardware_clock_exact(const time_t sethwtime, + const struct timeval refsystime, + const bool universal, + const bool testing, + const bool hctosys) { +/*---------------------------------------------------------------------------- + Set the Hardware Clock to the time "sethwtime", in local time zone or UTC, + according to "universal". +-----------------------------------------------------------------------------*/ + + time_t newhwtime = time_busy_wait(sethwtime, refsystime, 0.5); + if (hctosys) + set_system_clock(TRUE, newhwtime, testing, 500000); set_hardware_clock(newhwtime, universal, testing); } - static void display_time(const bool hclock_valid, const time_t systime, const double sync_duration) { /*---------------------------------------------------------------------------- @@ -672,9 +691,9 @@ interpret_date_string(const char *date_o static int set_system_clock(const bool hclock_valid, const time_t newtime, - const bool testing) { + const bool testing, const int usec) { /*---------------------------------------------------------------------------- Set the System Clock to time 'newtime'. Also set the kernel time zone value to the value indicated by the @@ -700,9 +719,9 @@ set_system_clock(const bool hclock_valid int minuteswest; int rc; tv.tv_sec = newtime; - tv.tv_usec = 0; + tv.tv_usec = usec; broken = localtime(&newtime); #ifdef HAVE_TM_GMTOFF minuteswest = -broken->tm_gmtoff/60; /* GNU extension */ @@ -936,9 +955,10 @@ save_adjtime(const struct adjtime adjtim static void do_adjustment(struct adjtime *adjtime_p, const bool hclock_valid, const time_t hclocktime, const struct timeval read_time, - const bool universal, const bool testing) { + const bool universal, const bool testing, + const bool hctosys) { /*--------------------------------------------------------------------------- Do the adjustment requested, by 1) setting the Hardware Clock (if necessary), and 2) updating the last-adjusted time in the adjtime structure. @@ -991,9 +1011,9 @@ do_adjustment(struct adjtime *adjtime_p, &adjustment, &retro); if (adjustment > 0 || adjustment < -1) { set_hardware_clock_exact(hclocktime + adjustment, time_inc(read_time, -retro), - universal, testing); + universal, testing, hctosys); adjtime_p->last_adj_time = hclocktime + adjustment; adjtime_p->not_adjusted = 0; adjtime_p->dirty = TRUE; } else @@ -1047,8 +1067,9 @@ manipulate_clock(const bool show, const struct adjtime adjtime; /* Contents of the adjtime file, or what they should be. */ int rc; /* local return code */ bool no_auth; /* User lacks necessary authorization to access the clock */ + int usec = 0; no_auth = ur->get_permissions(); if (no_auth) return EX_NOPERM; @@ -1104,27 +1125,23 @@ manipulate_clock(const bool show, const adjtime.not_adjusted, hclocktime, &adjustment, &retro); hclocktime += adjustment; - /* We can safely ignore retro here as it's a positive value, - * thus by ignoring it we at worst set the time a bit more - * backwards than we would ideally, which is safe, as a subsequent - * exact setting will only cause a jump forward which is harmless. - * We could do: usleep((1-retro)*1000000); hclocktime += 1; */ + usec = 1000000*retro; } if (show) { display_time(hclock_valid, hclocktime, time_diff(read_time, startup_time)); } else if (set) { set_hardware_clock_exact(set_time, startup_time, - universal, testing); + universal, testing, FALSE); if (!noadjfile) adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime, time_diff(read_time, startup_time)); } else if (adjust) { do_adjustment(&adjtime, hclock_valid, hclocktime, - read_time, universal, testing); + read_time, universal, testing, hctosys); } else if (systohc) { struct timeval nowtime, reftime; /* We can only set_hardware_clock_exact to a whole seconds time, so we set it with reference to the most recent @@ -1134,14 +1151,14 @@ manipulate_clock(const bool show, const reftime.tv_sec = nowtime.tv_sec; reftime.tv_usec = 0; set_hardware_clock_exact((time_t) reftime.tv_sec, reftime, - universal, testing); + universal, testing, FALSE); if (!noadjfile) adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid, hclocktime, (double) read_time.tv_usec / 1E6); } else if (hctosys) { - rc = set_system_clock(hclock_valid, hclocktime, testing); + rc = set_system_clock(hclock_valid, hclocktime, testing, usec); if (rc) { printf(_("Unable to set system clock.\n")); return rc; } @@ -1479,9 +1496,9 @@ main(int argc, char **argv) { "You supplied %d.\n"), MYNAME, argc); } - if (show + set + systohc + hctosys + adjust + getepoch + setepoch > 1){ + if (show + set + systohc + hctosys + getepoch + setepoch > 1){ fprintf(stderr, _("You have specified multiple functions.\n" "You can only perform one function " "at a time.\n")); hwclock_exit(EX_USAGE); Index: util-linux-ng-2.14.1/hwclock/hwclock.8 =================================================================== --- util-linux-ng-2.14.1.orig/hwclock/hwclock.8 +++ util-linux-ng-2.14.1/hwclock/hwclock.8 @@ -199,21 +199,17 @@ from not using this option. This option ( .B \-s ). This option is often combined .B \-\-preadjust -and then followed by asynchronous calls with -.B \-\-adjust -and -.B \-\-hctosys +and then followed by an asynchronous call with +.B \-\-adjust \-\-hctosys .TP .B \-\-preadjust causes hwclock to use the drift information from adjfile when transferring the hwclock time to the system time. Unlike .B \-\-adjust -it will not update the adjfile nor change the hwclock. The calculation does -discard sub-second corrections and may result in a time that's up to 1s behind -the real value. +it will not update the adjfile nor change the hwclock. .TP .B \-\-rtc=filename overrides the default /dev file name, which is
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor