]> git.ozlabs.org Git - ccan/blobdiff - ccan/timer/benchmarks/expected-usage.c
timers: implementation of lazily-ordered timers.
[ccan] / ccan / timer / benchmarks / expected-usage.c
diff --git a/ccan/timer/benchmarks/expected-usage.c b/ccan/timer/benchmarks/expected-usage.c
new file mode 100644 (file)
index 0000000..9777856
--- /dev/null
@@ -0,0 +1,71 @@
+/* We expect a timer to rarely go off, so benchmark that case:
+ * Every 1ms a connection comes in, we set up a 30 second timer for it.
+ * After 8192ms we finish the connection (and thus delete the timer).
+ */
+#include <ccan/timer/timer.h>
+#include <ccan/opt/opt.h>
+#include <ccan/array_size/array_size.h>
+#include <stdio.h>
+
+#define PER_CONN_TIME 8192
+#define CONN_TIMEOUT_MS 30000
+
+int main(int argc, char *argv[])
+{
+       struct timespec start, curr;
+       struct timers timers;
+       struct list_head expired;
+       struct timer t[PER_CONN_TIME];
+       unsigned int i, num;
+       bool check = false;
+
+       opt_register_noarg("-c|--check", opt_set_bool, &check,
+                          "Check timer structure during progress");
+
+       opt_parse(&argc, argv, opt_log_stderr_exit);
+
+       num = argv[1] ? atoi(argv[1]) : (check ? 10000 : 1000000);
+
+       list_head_init(&expired);
+       curr = start = time_now();
+       timers_init(&timers, start);
+
+       for (i = 0; i < num; i++) {
+               curr = time_add(curr, time_from_msec(1));
+               if (check)
+                       timers_check(&timers, NULL);
+               timers_expire(&timers, curr, &expired);
+               if (check)
+                       timers_check(&timers, NULL);
+               assert(list_empty(&expired));
+
+               if (i >= PER_CONN_TIME) {
+                       timer_del(&timers, &t[i%PER_CONN_TIME]);
+                       if (check)
+                               timers_check(&timers, NULL);
+               }
+               timer_add(&timers, &t[i%PER_CONN_TIME],
+                         time_add(curr, time_from_msec(CONN_TIMEOUT_MS)));
+               if (check)
+                       timers_check(&timers, NULL);
+       }
+       if (num > PER_CONN_TIME) {
+               for (i = 0; i < PER_CONN_TIME; i++)
+                       timer_del(&timers, &t[i]);
+       }
+
+       curr = time_sub(time_now(), start);
+       if (check)
+               timers_check(&timers, NULL);
+       timers_cleanup(&timers);
+       opt_free_table();
+
+       for (i = 0; i < ARRAY_SIZE(timers.level); i++)
+               if (!timers.level[i])
+                       break;
+
+       printf("%u in %lu.%09lu (%u levels / %zu)\n",
+              num, (long)curr.tv_sec, curr.tv_nsec,
+              i, ARRAY_SIZE(timers.level));
+       return 0;
+}