+#define HIST_MAX_US 1000000
+#define HIST_RES_US 10
+
+struct histogram {
+ unsigned cnt[(HIST_MAX_US+1)/HIST_RES_US];
+ unsigned max;
+};
+
+/* static void hist_init(struct histogram *h) */
+/* { */
+/* memset(h, 0, sizeof(*h)); */
+/* } */
+
+static void hist_add(struct histogram *h, int us)
+{
+ assert(us > 0);
+ if (us > HIST_MAX_US)
+ us = HIST_MAX_US;
+ __sync_fetch_and_add(&h->cnt[us/HIST_RES_US], 1);
+
+ unsigned max;
+ do {
+ max = h->max;
+ } while (us > max && ! __sync_bool_compare_and_swap(&h->max, max, us));
+
+}
+
+static unsigned hist_get_percentile(struct histogram *h, unsigned p)
+{
+ uint64_t sum = 0, psum;
+ int i;
+ for (i=0; i<(HIST_MAX_US+1)/HIST_RES_US; i++)
+ sum += h->cnt[i];
+
+ psum = sum * p / 100;
+ sum = 0;
+ for (i=0; i<(HIST_MAX_US+1)/HIST_RES_US; i++) {
+ sum += h->cnt[i];
+ if (sum >= psum)
+ break;
+ }
+ return i*HIST_RES_US;
+}
+