log_msg_va(evdev_libinput_context(device), priority, buf, args);
va_end(args);
- if (state == RATELIMIT_THRESHOLD)
+ if (state == RATELIMIT_THRESHOLD) {
+ struct human_time ht = to_human_time(ratelimit->interval);
evdev_log_msg(device,
priority,
- "WARNING: log rate limit exceeded (%d msgs per %dms). Discarding future messages.\n",
+ "WARNING: log rate limit exceeded (%d msgs per %d%s). "
+ "Discarding future messages.\n",
ratelimit->burst,
- us2ms(ratelimit->interval));
+ ht.value,
+ ht.unit);
+
+ }
}
#define evdev_log_debug(d_, ...) evdev_log_msg((d_), LIBINPUT_LOG_PRIORITY_DEBUG, __VA_ARGS__)
#include "config.h"
+#include <assert.h>
#include <time.h>
#include <stdint.h>
#include <unistd.h>
#include <linux/input.h>
+#include "util-macros.h"
+
static inline void
msleep(unsigned int ms)
{
return tv;
}
+
+struct human_time {
+ unsigned int value;
+ const char *unit;
+};
+
+/**
+ * Converts a time delta in µs to a human-readable time like "2h" or "4d"
+ */
+static inline struct human_time
+to_human_time(uint64_t us)
+{
+ struct human_time t;
+ struct c {
+ const char *unit;
+ unsigned int change_from_previous;
+ uint64_t limit;
+ } conversion[] = {
+ {"us", 1, 5000},
+ {"ms", 1000, 5000},
+ {"s", 1000, 120},
+ {"min", 60, 120},
+ {"h", 60, 48},
+ {"d", 24, ~0},
+ };
+ struct c *c;
+ uint64_t value = us;
+
+ ARRAY_FOR_EACH(conversion, c) {
+ value = value/c->change_from_previous;
+ if (value < c->limit) {
+ t.unit = c->unit;
+ t.value = value;
+ return t;
+ }
+ }
+
+ assert(!"We should never get here");
+}
}
END_TEST
+START_TEST(human_time)
+{
+ struct ht_tests {
+ uint64_t interval;
+ unsigned int value;
+ const char *unit;
+ } tests[] = {
+ { 0, 0, "us" },
+ { 123, 123, "us" },
+ { ms2us(5), 5, "ms" },
+ { ms2us(100), 100, "ms" },
+ { s2us(5), 5, "s" },
+ { s2us(100), 100, "s" },
+ { s2us(120), 2, "min" },
+ { 5 * s2us(60), 5, "min" },
+ { 120 * s2us(60), 2, "h" },
+ { 5 * 60 * s2us(60), 5, "h" },
+ { 48 * 60 * s2us(60), 2, "d" },
+ { 1000 * 24 * 60 * s2us(60), 1000, "d" },
+ { 0, 0, NULL },
+ };
+ for (int i = 0; tests[i].unit != NULL; i++) {
+ struct human_time ht;
+
+ ht = to_human_time(tests[i].interval);
+ ck_assert_int_eq(ht.value, tests[i].value);
+ ck_assert_str_eq(ht.unit, tests[i].unit);
+ }
+}
+END_TEST
+
struct atoi_test {
char *str;
bool success;
tcase_add_test(tc, strjoin_test);
tcase_add_test(tc, strstrip_test);
tcase_add_test(tc, time_conversion);
+ tcase_add_test(tc, human_time);
tcase_add_test(tc, list_test_insert);
tcase_add_test(tc, list_test_append);