]> rtime.felk.cvut.cz Git - frescor/fwp.git/commitdiff
fwp-timing: Added histogram and statistics
authorMichal Sojka <sojkam1@fel.cvut.cz>
Tue, 10 Nov 2009 12:31:06 +0000 (13:31 +0100)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Tue, 10 Nov 2009 12:31:06 +0000 (13:31 +0100)
fwp/tests/timing/fwp-timing.c

index a594ef373fd123bb97b9375f3ad960317e6eeba3..c0c1b5bb0087c10a48930a099ce656c3b2c86988 100644 (file)
 
 bool opt_verbose = false;
 
+#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;
+}
+
 struct stats {
-       
+       uint32_t sent;
+       uint32_t received;
+       uint32_t lost;
 } stats;
 
+struct histogram hist;
+
 void set_rt_prio(int priority)
 {
        int maxpri, minpri;
@@ -275,6 +323,14 @@ static inline double tsdiff2d(struct timespec *x,
        return ts2d(&r);
 }
 
+static inline int tsdiff2us(struct timespec *x,
+                             struct timespec *y)
+{
+       struct timespec r;
+       timespec_subtract(&r, x, y);
+       return r.tv_sec*1000000 + r.tv_nsec/1000;
+}
+
 struct msg {
        int cnt;
        struct timespec ts;
@@ -302,8 +358,13 @@ void *receiver(void *arg)
                ret = frsh_receive_sync(epdst, msg, rp->budget, &mlen, NULL);
                clock_gettime(CLOCK_MONOTONIC, &tsr);
                tss = msg->ts;
-               if (msg->cnt != last_cnt+1)
+               if (msg->cnt != last_cnt+1) {
                        printf("%3d: packet(s) lost!\n", rp->id);
+                       __sync_fetch_and_add(&stats.lost, msg->cnt - last_cnt+1);
+               } else {
+                       hist_add(&hist, tsdiff2us(&tsr, &tss));
+                       __sync_fetch_and_add(&stats.received, 1);
+               }
                if (opt_verbose)
                        printf("%3d: %10d: %10.3lf ms\n",
                               rp->id, msg->cnt, tsdiff2d(&tsr, &tss)*1000);
@@ -359,6 +420,7 @@ void *sender(void *arg)
                        ret = frsh_send_sync(epsrc, msg, p->budget);
                        clock_gettime(CLOCK_MONOTONIC, &next_period);
                }
+               __sync_fetch_and_add(&stats.sent, 1);
                next_period.tv_sec  += (p->period_ms/1000);
                next_period.tv_nsec += (p->period_ms%1000) * 1000000;
                if (next_period.tv_nsec >= 1000000000) {
@@ -375,6 +437,19 @@ void *sender(void *arg)
        return NULL;
 }
 
+void print_stat(bool full)
+{
+       printf("Sent: %5d  Received: %5d  Lost: %5d Max: %6.3f ms",
+              stats.sent, stats.received, stats.lost, hist.max/1000.0);
+       if (full) {
+               printf("  Max: %6.3f ms  90%%: %6.3f ms",
+                      hist_get_percentile(&hist, 100)/1000.0,
+                      hist_get_percentile(&hist, 90)/1000.0);
+       }
+       printf("\r");
+       fflush(stdout);
+}
+
 int main(int argc, char *argv[])
 {
        int ret;
@@ -411,8 +486,20 @@ int main(int argc, char *argv[])
                }
        } while(ret == 0);
 
+       while (!exit_flag) {
+               int v;
+               print_stat(false);
+               sem_getvalue(&finished, &v);
+               if (v == num)
+                       break;
+               usleep(100000);
+       }
+
        while (num--)
                sem_wait(&finished);
+
+       print_stat(true);
+       printf("\n");
        
        return 0;
 }