hwclock: fix sizeof bug (used it on pointer, not array); make --systohc exact
function old new delta hwclock_main 329 428 +99 rtc_adjtime_is_utc 138 134 -4 edir 365 354 -11 read_rtc 39 23 -16 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/3 up/down: 99/-31) Total: 68 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
06667f21d6
commit
695fa51c80
@ -19,7 +19,7 @@ int FAST_FUNC rtc_adjtime_is_utc(void)
|
|||||||
FILE *f = fopen_for_read(ADJTIME_PATH);
|
FILE *f = fopen_for_read(ADJTIME_PATH);
|
||||||
|
|
||||||
if (f) {
|
if (f) {
|
||||||
RESERVE_CONFIG_BUFFER(buffer, 128);
|
char buffer[128];
|
||||||
|
|
||||||
while (fgets(buffer, sizeof(buffer), f)) {
|
while (fgets(buffer, sizeof(buffer), f)) {
|
||||||
int len = strlen(buffer);
|
int len = strlen(buffer);
|
||||||
@ -35,8 +35,6 @@ int FAST_FUNC rtc_adjtime_is_utc(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
RELEASE_CONFIG_BUFFER(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return utc;
|
return utc;
|
||||||
|
@ -191,8 +191,8 @@ static int cbq_print_opt(struct rtattr *opt)
|
|||||||
struct tc_cbq_wrropt *wrr = NULL;
|
struct tc_cbq_wrropt *wrr = NULL;
|
||||||
struct tc_cbq_fopt *fopt = NULL;
|
struct tc_cbq_fopt *fopt = NULL;
|
||||||
struct tc_cbq_ovl *ovl = NULL;
|
struct tc_cbq_ovl *ovl = NULL;
|
||||||
const char * const error = "CBQ: too short %s opt";
|
const char *const error = "CBQ: too short %s opt";
|
||||||
RESERVE_CONFIG_BUFFER(buf, 64);
|
char buf[64];
|
||||||
|
|
||||||
if (opt == NULL)
|
if (opt == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
@ -272,7 +272,6 @@ static int cbq_print_opt(struct rtattr *opt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
RELEASE_CONFIG_BUFFER(buf);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ static NOINLINE void edir(const char *directory_name)
|
|||||||
xchdir(directory_name);
|
xchdir(directory_name);
|
||||||
dir = xopendir(".");
|
dir = xopendir(".");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
RESERVE_CONFIG_BUFFER(buf, 256);
|
char buf[256];
|
||||||
char *tail;
|
char *tail;
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
@ -148,7 +148,6 @@ static NOINLINE void edir(const char *directory_name)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
xsetenv(d->d_name, buf);
|
xsetenv(d->d_name, buf);
|
||||||
RELEASE_CONFIG_BUFFER(buf);
|
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
if (fchdir(wdir) == -1)
|
if (fchdir(wdir) == -1)
|
||||||
|
@ -27,27 +27,12 @@ static time_t read_rtc(int utc)
|
|||||||
|
|
||||||
fd = rtc_xopen(&rtcname, O_RDONLY);
|
fd = rtc_xopen(&rtcname, O_RDONLY);
|
||||||
ret = rtc_read_time(fd, utc);
|
ret = rtc_read_time(fd, utc);
|
||||||
close(fd);
|
if (ENABLE_FEATURE_CLEAN_UP)
|
||||||
|
close(fd);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_rtc(time_t t, int utc)
|
|
||||||
{
|
|
||||||
struct tm tm;
|
|
||||||
int rtc = rtc_xopen(&rtcname, O_WRONLY);
|
|
||||||
|
|
||||||
if (utc)
|
|
||||||
gmtime_r(&t, &tm);
|
|
||||||
else
|
|
||||||
localtime_r(&t, &tm);
|
|
||||||
tm.tm_isdst = 0;
|
|
||||||
|
|
||||||
xioctl(rtc, RTC_SET_TIME, &tm);
|
|
||||||
|
|
||||||
close(rtc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void show_clock(int utc)
|
static void show_clock(int utc)
|
||||||
{
|
{
|
||||||
//struct tm *ptm;
|
//struct tm *ptm;
|
||||||
@ -58,10 +43,10 @@ static void show_clock(int utc)
|
|||||||
//ptm = localtime(&t); /* Sets 'tzname[]' */
|
//ptm = localtime(&t); /* Sets 'tzname[]' */
|
||||||
|
|
||||||
cp = ctime(&t);
|
cp = ctime(&t);
|
||||||
if (cp[0])
|
strchrnul(cp, '\n')[0] = '\0';
|
||||||
cp[strlen(cp) - 1] = '\0';
|
|
||||||
|
|
||||||
//printf("%s %.6f seconds %s\n", cp, 0.0, utc ? "" : (ptm->tm_isdst ? tzname[1] : tzname[0]));
|
//printf("%s 0.000000 seconds %s\n", cp, utc ? "" : (ptm->tm_isdst ? tzname[1] : tzname[0]));
|
||||||
|
/* 0.000000 stand for unimplemented difference between RTC and system clock */
|
||||||
printf("%s 0.000000 seconds\n", cp);
|
printf("%s 0.000000 seconds\n", cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,12 +66,73 @@ static void to_sys_clock(int utc)
|
|||||||
|
|
||||||
static void from_sys_clock(int utc)
|
static void from_sys_clock(int utc)
|
||||||
{
|
{
|
||||||
|
#define TWEAK_USEC 200
|
||||||
|
struct tm tm;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
unsigned adj = TWEAK_USEC;
|
||||||
|
int rtc = rtc_xopen(&rtcname, O_WRONLY);
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
/* Try to catch the moment when whole second is close */
|
||||||
//if (gettimeofday(&tv, NULL))
|
while (1) {
|
||||||
// bb_perror_msg_and_die("gettimeofday() failed");
|
unsigned rem_usec;
|
||||||
write_rtc(tv.tv_sec, utc);
|
time_t t;
|
||||||
|
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
|
||||||
|
rem_usec = 1000000 - tv.tv_usec;
|
||||||
|
if (rem_usec < 1024) {
|
||||||
|
/* Less than 1ms to next second. Good enough */
|
||||||
|
small_rem:
|
||||||
|
tv.tv_sec++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare tm */
|
||||||
|
t = tv.tv_sec;
|
||||||
|
if (utc)
|
||||||
|
gmtime_r(&t, &tm); /* may read /etc/xxx (it takes time) */
|
||||||
|
else
|
||||||
|
localtime_r(&t, &tm); /* same */
|
||||||
|
tm.tm_isdst = 0;
|
||||||
|
|
||||||
|
/* gmtime/localtime took some time, re-get cur time */
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
|
||||||
|
if (tv.tv_sec < t /* may happen if rem_usec was < 1024 */
|
||||||
|
|| (tv.tv_sec == t && tv.tv_usec < 1024)
|
||||||
|
) {
|
||||||
|
/* We are not too far into next second. Good. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
adj += 32; /* 2^(10-5) = 2^5 = 32 iterations max */
|
||||||
|
if (adj >= 1024) {
|
||||||
|
/* Give up trying to sync */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to sync up by sleeping */
|
||||||
|
rem_usec = 1000000 - tv.tv_usec;
|
||||||
|
if (rem_usec < 1024) {
|
||||||
|
goto small_rem; /* already close, don't sleep */
|
||||||
|
}
|
||||||
|
/* Need to sleep.
|
||||||
|
* Note that small adj on slow processors can make us
|
||||||
|
* to always overshoot tv.tv_usec < 1024 check on next
|
||||||
|
* iteration. That's why adj is increased on each iteration.
|
||||||
|
* This also allows it to be reused as a loop limiter.
|
||||||
|
*/
|
||||||
|
usleep(rem_usec - adj);
|
||||||
|
}
|
||||||
|
|
||||||
|
xioctl(rtc, RTC_SET_TIME, &tm);
|
||||||
|
|
||||||
|
/* Debug aid to find "good" TWEAK_USEC.
|
||||||
|
* Look for a value which makes tv_usec close to 999999 or 0.
|
||||||
|
* for 2.20GHz Intel Core 2: TWEAK_USEC ~= 200
|
||||||
|
*/
|
||||||
|
//bb_error_msg("tv.tv_usec:%d adj:%d", (int)tv.tv_usec, adj);
|
||||||
|
|
||||||
|
if (ENABLE_FEATURE_CLEAN_UP)
|
||||||
|
close(rtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HWCLOCK_OPT_LOCALTIME 0x01
|
#define HWCLOCK_OPT_LOCALTIME 0x01
|
||||||
|
Loading…
x
Reference in New Issue
Block a user