util: make time formatting a bit smarter

Instead of outputting "5h 55s 50ms 3us" we'll now output "5h
55.050003s". Also, while outputting the accuracy is configurable.

Basically we now try use "dot notation" for all time values > 1min. For
>= 1s we use 's' as unit, otherwise for >= 1ms we use 'ms' as unit, and
finally 'us'.

This should give reasonably values in most cases.
This commit is contained in:
Lennart Poettering
2013-04-04 02:56:56 +02:00
parent 911963f1a2
commit 2fa4092c28
18 changed files with 146 additions and 47 deletions
+1 -1
View File
@@ -1097,7 +1097,7 @@ int generic_print_property(const char *name, DBusMessageIter *iter, bool all) {
} else if (strstr(name, "USec")) {
char timespan[FORMAT_TIMESPAN_MAX];
printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u));
printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u, 0));
} else
printf("%s=%llu\n", name, (unsigned long long) u);
+1 -1
View File
@@ -82,7 +82,7 @@ int label_init(const char *prefix) {
l = after_mallinfo.uordblks > before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0;
log_debug("Successfully loaded SELinux database in %s, size on heap is %iK.",
format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp),
format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0),
(l+1023)/1024);
}
#endif
+58 -9
View File
@@ -225,7 +225,7 @@ char *format_timestamp_relative(char *buf, size_t l, usec_t t) {
return buf;
}
char *format_timespan(char *buf, size_t l, usec_t t) {
char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) {
static const struct {
const char *suffix;
usec_t usec;
@@ -243,6 +243,7 @@ char *format_timespan(char *buf, size_t l, usec_t t) {
unsigned i;
char *p = buf;
bool something = false;
assert(buf);
assert(l > 0);
@@ -250,17 +251,23 @@ char *format_timespan(char *buf, size_t l, usec_t t) {
if (t == (usec_t) -1)
return NULL;
if (t == 0) {
snprintf(p, l, "0");
p[l-1] = 0;
return p;
}
/* The result of this function can be parsed with parse_sec */
for (i = 0; i < ELEMENTSOF(table); i++) {
int k;
size_t n;
bool done = false;
usec_t a, b;
if (t == 0 || t < accuracy) {
if (!something) {
snprintf(p, l, "0");
p[l-1] = 0;
return p;
}
break;
}
if (t < table[i].usec)
continue;
@@ -268,13 +275,55 @@ char *format_timespan(char *buf, size_t l, usec_t t) {
if (l <= 1)
break;
k = snprintf(p, l, "%s%llu%s", p > buf ? " " : "", (unsigned long long) (t / table[i].usec), table[i].suffix);
a = t / table[i].usec;
b = t % table[i].usec;
/* Let's see if we should shows this in dot notation */
if (t < USEC_PER_MINUTE && b > 0) {
usec_t cc;
int j;
j = 0;
for (cc = table[i].usec; cc > 1; cc /= 10)
j++;
for (cc = accuracy; cc > 1; cc /= 10) {
b /= 10;
j--;
}
if (j > 0) {
k = snprintf(p, l,
"%s%llu.%0*llu%s",
p > buf ? " " : "",
(unsigned long long) a,
j,
(unsigned long long) b,
table[i].suffix);
t = 0;
done = true;
}
}
/* No? Then let's show it normally */
if (!done) {
k = snprintf(p, l,
"%s%llu%s",
p > buf ? " " : "",
(unsigned long long) a,
table[i].suffix);
t = b;
}
n = MIN((size_t) k, l);
l -= n;
p += n;
t %= table[i].usec;
something = true;
}
*p = 0;
+1 -1
View File
@@ -74,7 +74,7 @@ struct timeval *timeval_store(struct timeval *tv, usec_t u);
char *format_timestamp(char *buf, size_t l, usec_t t);
char *format_timestamp_relative(char *buf, size_t l, usec_t t);
char *format_timespan(char *buf, size_t l, usec_t t);
char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy);
void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t);
void dual_timestamp_deserialize(const char *value, dual_timestamp *t);
+1 -1
View File
@@ -60,7 +60,7 @@ static int update_timeout(void) {
}
watchdog_timeout = (usec_t) sec * USEC_PER_SEC;
log_info("Set hardware watchdog to %s.", format_timespan(buf, sizeof(buf), watchdog_timeout));
log_info("Set hardware watchdog to %s.", format_timespan(buf, sizeof(buf), watchdog_timeout, 0));
flags = WDIOS_ENABLECARD;
r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags);