]> rtime.felk.cvut.cz Git - canping.git/commitdiff
Added ability to store cumulative histograms (option -g)
authorMichal Sojka <sojkam1@fel.cvut.cz>
Sat, 13 Jun 2009 23:05:58 +0000 (01:05 +0200)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Sat, 13 Jun 2009 23:05:58 +0000 (01:05 +0200)
src/vca_canping.c

index 8de0af5b9a1fcf315ddb1bf4dbf1cc87c0782d40..ca4e5ac6b6bbd4c309724c44d80090a66a917a23 100644 (file)
@@ -101,12 +101,19 @@ int option_timeout = 4;
 int option_open_once = 0;
 int option_synch_start = 0;
 bool option_background = false;
+char *option_histogram = NULL;
 
 /* Lists */
 typedef struct threads {
        ul_list_head_t head;
 } threads_t;
 
+struct histogram {
+       unsigned *data;
+       unsigned allocated;
+       unsigned resolution;
+};
+
 typedef struct thread_data {
        pthread_t tid;
        long int canid;
@@ -118,6 +125,8 @@ typedef struct thread_data {
        int min, max;           /* min/max response times */
        int timeout;            /* number of timeouts */
 
+       struct histogram hist;
+
        ul_list_node_t node;
 } thread_data_t;
 
@@ -126,6 +135,44 @@ UL_LIST_CUST_DEC(thread_list, threads_t, thread_data_t, head, node);
 threads_t master_threads;
 threads_t slave_threads;
 
+int histogram_init(struct histogram *h,
+                  unsigned max_value,
+                  unsigned resolution)
+{
+       size_t mem;
+       h->allocated = max_value/resolution + 1;
+       h->resolution = resolution;
+       mem = h->allocated*sizeof(*h->data);
+       h->data = malloc(mem);
+       if (h->data) {
+               memset(h->data, 0, mem);
+               return 0;
+       } else
+               return -1;
+}
+
+void histogram_add(struct histogram *h, unsigned value)
+{
+       unsigned index = value / h->resolution;
+       if (index >= h->allocated)
+               index = h->allocated - 1;
+       h->data[index]++;
+}
+
+void histogram_fprint(struct histogram *h, FILE *f)
+{
+       unsigned long long sum = 0, cum;
+       unsigned i;
+       for (i = 0; i < h->allocated; i++)
+               sum += h->data[i];
+       cum = sum;
+       for (i = 0; i < h->allocated; i++) {
+               if (h->data[i] != 0)
+                       fprintf(f, "%d %lld\n", i*h->resolution, cum);
+               cum -= h->data[i];
+       }
+}
+
 /* Subtract the `struct timeval' values X and Y, storing the result in
    RESULT.  Return 1 if the difference is negative, otherwise 0.  */
      
@@ -218,6 +265,9 @@ void *master_thread(void *arg)
                perror("ioctl CANQUE_QUEUE_FLUSH");
                exit(EXIT_FLUSH_ERROR);
        }
+
+       if (option_histogram)
+               histogram_init(&td->hist, 1000*1000/*max [us]*/, 5/*resolution [us]*/);
        
        /* Prepare data structures for the select syscall. */
        FD_ZERO (&rdset);
@@ -298,6 +348,8 @@ void *master_thread(void *arg)
                                        (double)time*time  / td->count;
                                if (time > td->max) td->max = time;
                                if (time < td->min) td->min = time;
+                               if (option_histogram)
+                                       histogram_add(&td->hist, time);
                                total_count++;
                        } /* read */
                } 
@@ -322,6 +374,15 @@ void *master_thread(void *arg)
                vca_close_handle(vcah);
        }
 
+       if (option_histogram) {
+               FILE *f;
+               char buf[100];
+               snprintf(buf, sizeof(buf), "%s-%d.dat", option_histogram, ping_id);
+               f = fopen(buf, "w");
+               histogram_fprint(&td->hist, f);
+               fclose(f);
+       }
+
        sem_post(&finish_sem);
        return (void *)ret;
 }
@@ -513,6 +574,7 @@ void print_help(void)
               "  -b            go to background (fork) after initialization, prints child PID\n"
               "  -c count      how many messages each master sends\n"
               "  -d dev        device (e.g. /dev/can1)\n"
+              "  -g prefix     store cumulative histogram in file <prefix>-<id>.dat\n"
               "  -h            print this help\n"
               "  -i id         id of first master message\n"
               "  -l length     length of the messages (0..8)\n"
@@ -536,7 +598,7 @@ int parse_options(int argc, char *argv[])
        int c;
        
        opterr = 0;
-       while ((c = getopt (argc, argv, "bc:d:hi:l:m:os:t:vw:yrR:")) != -1)
+       while ((c = getopt (argc, argv, "bc:d:g:h:i:l:m:os:t:vw:yrR:")) != -1)
                switch (c)
                {
                case 'b':
@@ -548,6 +610,9 @@ int parse_options(int argc, char *argv[])
                case 'd':
                        option_device = optarg;
                        break;
+               case 'g':
+                       option_histogram = optarg;
+                       break;
                case 'h':
                        print_help();
                        exit(EXIT_OK);
@@ -740,17 +805,13 @@ int main(int argc, char *argv[])
                }
        }
 
-       fprintf(stderr, "Common\n");
        if (fork_ret == 0) {
                /* Child */
-               fprintf(stderr, "Child starting childs\n");
                if (option_masters) start_masters(option_masters, option_first_id);
                if (option_slaves) start_slaves(option_slaves, option_first_id);
                sem_post(child_ready);
-               fprintf(stderr, "Child ready\n");
        } else {
                /* Parent */
-               fflush(stderr);
                sem_wait(child_ready);
                printf("%d\n", fork_ret);
                exit(0);