libbb: introduce and use xgettimeofday(), do not truncate 64-bit time_t in shells

function                                             old     new   delta
xgettimeofday                                          -      11     +11
get_local_var_value                                  280     281      +1
svlogd_main                                         1323    1322      -1
change_epoch                                          67      66      -1
timestamp_and_log                                    461     458      -3
hwclock_main                                         301     298      -3
fmt_time_bernstein_25                                135     132      -3
step_time                                            331     326      -5
script_main                                         1207    1202      -5
machtime                                              34      28      -6
curtime                                               61      54      -7
ts_main                                              423     415      -8
nmeter_main                                          761     751     -10
gettime1900d                                          67      46     -21
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/12 up/down: 12/-73)           Total: -61 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2020-12-30 23:48:01 +01:00
parent 89a55972fd
commit 3c13da3dab
16 changed files with 46 additions and 34 deletions

View File

@ -657,6 +657,7 @@ void parse_datestr(const char *date_str, struct tm *ptm) FAST_FUNC;
time_t validate_tm_time(const char *date_str, struct tm *ptm) FAST_FUNC; time_t validate_tm_time(const char *date_str, struct tm *ptm) FAST_FUNC;
char *strftime_HHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC; char *strftime_HHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC;
char *strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC; char *strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC;
void xgettimeofday(struct timeval *tv) FAST_FUNC;
void xsettimeofday(const struct timeval *tv) FAST_FUNC; void xsettimeofday(const struct timeval *tv) FAST_FUNC;

View File

@ -291,19 +291,19 @@ unsigned FAST_FUNC monotonic_sec(void)
unsigned long long FAST_FUNC monotonic_ns(void) unsigned long long FAST_FUNC monotonic_ns(void)
{ {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); xgettimeofday(&tv);
return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000; return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000;
} }
unsigned long long FAST_FUNC monotonic_us(void) unsigned long long FAST_FUNC monotonic_us(void)
{ {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); xgettimeofday(&tv);
return tv.tv_sec * 1000000ULL + tv.tv_usec; return tv.tv_sec * 1000000ULL + tv.tv_usec;
} }
unsigned long long FAST_FUNC monotonic_ms(void) unsigned long long FAST_FUNC monotonic_ms(void)
{ {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); xgettimeofday(&tv);
return tv.tv_sec * 1000ULL + tv.tv_usec / 1000; return tv.tv_sec * 1000ULL + tv.tv_usec / 1000;
} }
unsigned FAST_FUNC monotonic_sec(void) unsigned FAST_FUNC monotonic_sec(void)

View File

@ -720,3 +720,14 @@ void FAST_FUNC xsettimeofday(const struct timeval *tv)
if (settimeofday(tv, NULL)) if (settimeofday(tv, NULL))
bb_simple_perror_msg_and_die("settimeofday"); bb_simple_perror_msg_and_die("settimeofday");
} }
void FAST_FUNC xgettimeofday(struct timeval *tv)
{
#if 0
if (gettimeofday(tv, NULL))
bb_simple_perror_msg_and_die("gettimeofday");
#else
/* Never fails on Linux */
gettimeofday(tv, NULL);
#endif
}

View File

@ -47,13 +47,13 @@ int ts_main(int argc UNUSED_PARAM, char **argv)
#define date_buf bb_common_bufsiz1 #define date_buf bb_common_bufsiz1
setup_common_bufsiz(); setup_common_bufsiz();
gettimeofday(&base, NULL); xgettimeofday(&base);
while ((line = xmalloc_fgets(stdin)) != NULL) { while ((line = xmalloc_fgets(stdin)) != NULL) {
struct timeval ts; struct timeval ts;
struct tm tm_time; struct tm tm_time;
gettimeofday(&ts, NULL); xgettimeofday(&ts);
if (opt) { if (opt) {
/* -i and/or -s */ /* -i and/or -s */
struct timeval ts1 = ts1; struct timeval ts1 = ts1;

View File

@ -1701,7 +1701,7 @@ static uint32_t machtime(void)
{ {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); xgettimeofday(&tv);
return htonl((uint32_t)(tv.tv_sec + 2208988800U)); return htonl((uint32_t)(tv.tv_sec + 2208988800U));
} }
/* ARGSUSED */ /* ARGSUSED */

View File

@ -560,7 +560,7 @@ static double
gettime1900d(void) gettime1900d(void)
{ {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); /* never fails */ xgettimeofday(&tv);
G.cur_time = tv.tv_sec + (1.0e-6 * tv.tv_usec) + OFFSET_1900_1970; G.cur_time = tv.tv_sec + (1.0e-6 * tv.tv_usec) + OFFSET_1900_1970;
return G.cur_time; return G.cur_time;
} }
@ -1144,7 +1144,7 @@ step_time(double offset)
char buf[sizeof("yyyy-mm-dd hh:mm:ss") + /*paranoia:*/ 4]; char buf[sizeof("yyyy-mm-dd hh:mm:ss") + /*paranoia:*/ 4];
time_t tval; time_t tval;
gettimeofday(&tvc, NULL); /* never fails */ xgettimeofday(&tvc);
dtime = tvc.tv_sec + (1.0e-6 * tvc.tv_usec) + offset; dtime = tvc.tv_sec + (1.0e-6 * tvc.tv_usec) + offset;
d_to_tv(dtime, &tvn); d_to_tv(dtime, &tvn);
xsettimeofday(&tvn); xsettimeofday(&tvn);

View File

@ -505,7 +505,7 @@ send_probe(int seq, int ttl)
struct outdata6_t *pkt = (void *) outdata; struct outdata6_t *pkt = (void *) outdata;
pkt->ident6 = ident; pkt->ident6 = ident;
pkt->seq6 = htonl(seq); pkt->seq6 = htonl(seq);
/*gettimeofday(&pkt->tv, &tz);*/ /*xgettimeofday(&pkt->tv);*/
icp = outicmp6; icp = outicmp6;
} else } else
#endif #endif

View File

@ -952,11 +952,11 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
reset_outbuf(); reset_outbuf();
if (G.delta >= 0) { if (G.delta >= 0) {
gettimeofday(&G.tv, NULL); xgettimeofday(&G.tv);
usleep(G.delta > 1000000 ? 1000000 : G.delta - G.tv.tv_usec % G.deltanz); usleep(G.delta > 1000000 ? 1000000 : G.delta - G.tv.tv_usec % G.deltanz);
} }
gettimeofday(&G.start, NULL); xgettimeofday(&G.start);
G.tv = G.start; G.tv = G.start;
while (1) { while (1) {
collect_info(first); collect_info(first);
@ -971,7 +971,7 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
if (G.delta >= 0) { if (G.delta >= 0) {
int rem; int rem;
// can be commented out, will sacrifice sleep time precision a bit // can be commented out, will sacrifice sleep time precision a bit
gettimeofday(&G.tv, NULL); xgettimeofday(&G.tv);
if (need_seconds) if (need_seconds)
rem = G.delta - ((ullong)G.tv.tv_sec*1000000 + G.tv.tv_usec) % G.deltanz; rem = G.delta - ((ullong)G.tv.tv_sec*1000000 + G.tv.tv_usec) % G.deltanz;
else else
@ -983,7 +983,7 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
} }
usleep(rem); usleep(rem);
} }
gettimeofday(&G.tv, NULL); xgettimeofday(&G.tv);
} }
/*return 0;*/ /*return 0;*/

View File

@ -62,12 +62,12 @@ static void gettimeofday_ns(struct timespec *ts)
&& sizeof(((struct timeval*)ts)->tv_usec) == sizeof(ts->tv_nsec) && sizeof(((struct timeval*)ts)->tv_usec) == sizeof(ts->tv_nsec)
) { ) {
/* Cheat */ /* Cheat */
gettimeofday((void*)ts, NULL); xgettimeofday((void*)ts);
ts->tv_nsec *= 1000; ts->tv_nsec *= 1000;
} else { } else {
/* For example, musl has "incompatible" layouts */ /* For example, musl has "incompatible" layouts */
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); xgettimeofday(&tv);
ts->tv_sec = tv.tv_sec; ts->tv_sec = tv.tv_sec;
ts->tv_nsec = tv.tv_usec * 1000; ts->tv_nsec = tv.tv_usec * 1000;
} }

View File

@ -351,7 +351,7 @@ static void fmt_time_human_30nul(char *s, char dt_delim)
struct tm *ptm; struct tm *ptm;
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); xgettimeofday(&tv);
ptm = gmtime_r(&tv.tv_sec, &tm); ptm = gmtime_r(&tv.tv_sec, &tm);
/* ^^^ using gmtime_r() instead of gmtime() to not use static data */ /* ^^^ using gmtime_r() instead of gmtime() to not use static data */
sprintf(s, "%04u-%02u-%02u%c%02u:%02u:%02u.%06u000", sprintf(s, "%04u-%02u-%02u%c%02u:%02u:%02u.%06u000",
@ -376,7 +376,7 @@ static void fmt_time_bernstein_25(char *s)
struct timeval tv; struct timeval tv;
unsigned sec_hi; unsigned sec_hi;
gettimeofday(&tv, NULL); xgettimeofday(&tv);
sec_hi = (0x400000000000000aULL + tv.tv_sec) >> 32; sec_hi = (0x400000000000000aULL + tv.tv_sec) >> 32;
tv.tv_sec = (time_t)(0x400000000000000aULL) + tv.tv_sec; tv.tv_sec = (time_t)(0x400000000000000aULL) + tv.tv_sec;
tv.tv_usec *= 1000; tv.tv_usec *= 1000;

View File

@ -11371,10 +11371,10 @@ static void FAST_FUNC
change_epoch(struct var *vepoch, const char *fmt) change_epoch(struct var *vepoch, const char *fmt)
{ {
struct timeval tv; struct timeval tv;
char buffer[sizeof("%lu.nnnnnn") + sizeof(long)*3]; char buffer[sizeof("%llu.nnnnnn") + sizeof(long long)*3];
gettimeofday(&tv, NULL); xgettimeofday(&tv);
sprintf(buffer, fmt, (unsigned long)tv.tv_sec, (unsigned)tv.tv_usec); sprintf(buffer, fmt, (unsigned long long)tv.tv_sec, (unsigned)tv.tv_usec);
setvar(vepoch->var_text, buffer, VNOFUNC); setvar(vepoch->var_text, buffer, VNOFUNC);
vepoch->flags &= ~VNOFUNC; vepoch->flags &= ~VNOFUNC;
} }
@ -11382,13 +11382,13 @@ change_epoch(struct var *vepoch, const char *fmt)
static void FAST_FUNC static void FAST_FUNC
change_seconds(const char *value UNUSED_PARAM) change_seconds(const char *value UNUSED_PARAM)
{ {
change_epoch(&vepochs, "%lu"); change_epoch(&vepochs, "%llu");
} }
static void FAST_FUNC static void FAST_FUNC
change_realtime(const char *value UNUSED_PARAM) change_realtime(const char *value UNUSED_PARAM)
{ {
change_epoch(&vepochr, "%lu.%06u"); change_epoch(&vepochr, "%llu.%06u");
} }
#endif #endif

View File

@ -1027,7 +1027,7 @@ struct globals {
struct sigaction sa; struct sigaction sa;
char optstring_buf[sizeof("eixcs")]; char optstring_buf[sizeof("eixcs")];
#if BASH_EPOCH_VARS #if BASH_EPOCH_VARS
char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3]; char epoch_buf[sizeof("%llu.nnnnnn") + sizeof(long long)*3];
#endif #endif
#if ENABLE_FEATURE_EDITING #if ENABLE_FEATURE_EDITING
char user_input_buf[CONFIG_FEATURE_EDITING_MAX_LEN]; char user_input_buf[CONFIG_FEATURE_EDITING_MAX_LEN];
@ -2277,13 +2277,13 @@ static const char* FAST_FUNC get_local_var_value(const char *name)
{ {
const char *fmt = NULL; const char *fmt = NULL;
if (strcmp(name, "EPOCHSECONDS") == 0) if (strcmp(name, "EPOCHSECONDS") == 0)
fmt = "%lu"; fmt = "%llu";
else if (strcmp(name, "EPOCHREALTIME") == 0) else if (strcmp(name, "EPOCHREALTIME") == 0)
fmt = "%lu.%06u"; fmt = "%llu.%06u";
if (fmt) { if (fmt) {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); xgettimeofday(&tv);
sprintf(G.epoch_buf, fmt, (unsigned long)tv.tv_sec, sprintf(G.epoch_buf, fmt, (unsigned long long)tv.tv_sec,
(unsigned)tv.tv_usec); (unsigned)tv.tv_usec);
return G.epoch_buf; return G.epoch_buf;
} }

View File

@ -842,7 +842,7 @@ static void timestamp_and_log(int pri, char *msg, int len)
#if ENABLE_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS #if ENABLE_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS
if (!timestamp) { if (!timestamp) {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); xgettimeofday(&tv);
now = tv.tv_sec; now = tv.tv_sec;
timestamp = ctime(&now) + 4; /* skip day of week */ timestamp = ctime(&now) + 4; /* skip day of week */
/* overwrite year by milliseconds, zero terminate */ /* overwrite year by milliseconds, zero terminate */

View File

@ -79,7 +79,7 @@ static time_t read_rtc(const char **pp_rtcname, struct timeval *sys_tv, int utc)
int before = tm_time.tm_sec; int before = tm_time.tm_sec;
while (1) { while (1) {
rtc_read_tm(&tm_time, fd); rtc_read_tm(&tm_time, fd);
gettimeofday(sys_tv, NULL); xgettimeofday(sys_tv);
if (before != (int)tm_time.tm_sec) if (before != (int)tm_time.tm_sec)
break; break;
} }
@ -205,7 +205,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
int rtc; int rtc;
rtc = rtc_xopen(pp_rtcname, O_WRONLY); rtc = rtc_xopen(pp_rtcname, O_WRONLY);
gettimeofday(&tv, NULL); xgettimeofday(&tv);
/* Prepare tm_time */ /* Prepare tm_time */
if (sizeof(time_t) == sizeof(tv.tv_sec)) { if (sizeof(time_t) == sizeof(tv.tv_sec)) {
if (utc) if (utc)
@ -253,7 +253,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
unsigned rem_usec; unsigned rem_usec;
time_t t; time_t t;
gettimeofday(&tv, NULL); xgettimeofday(&tv);
t = tv.tv_sec; t = tv.tv_sec;
rem_usec = 1000000 - tv.tv_usec; rem_usec = 1000000 - tv.tv_usec;
@ -274,7 +274,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
} }
/* gmtime/localtime took some time, re-get cur time */ /* gmtime/localtime took some time, re-get cur time */
gettimeofday(&tv, NULL); xgettimeofday(&tv);
if (tv.tv_sec < t /* we are still in old second */ if (tv.tv_sec < t /* we are still in old second */
|| (tv.tv_sec == t && tv.tv_usec < adj) /* not too far into next second */ || (tv.tv_sec == t && tv.tv_usec < adj) /* not too far into next second */

View File

@ -963,7 +963,7 @@ static void load_firmware(const char *firmware, const char *sysfs_path)
static char *curtime(void) static char *curtime(void)
{ {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); xgettimeofday(&tv);
sprintf( sprintf(
strftime_HHMMSS(G.timestr, sizeof(G.timestr), &tv.tv_sec), strftime_HHMMSS(G.timestr, sizeof(G.timestr), &tv.tv_sec),
".%06u", ".%06u",

View File

@ -172,7 +172,7 @@ int script_main(int argc UNUSED_PARAM, char **argv)
struct timeval tv; struct timeval tv;
double newtime; double newtime;
gettimeofday(&tv, NULL); xgettimeofday(&tv);
newtime = tv.tv_sec + (double) tv.tv_usec / 1000000; newtime = tv.tv_sec + (double) tv.tv_usec / 1000000;
fprintf(timing_fp, "%f %u\n", newtime - oldtime, count); fprintf(timing_fp, "%f %u\n", newtime - oldtime, count);
oldtime = newtime; oldtime = newtime;