Hey Ben,

Just noticed, when compiling with sparse, it issues the warnings like:

"""
lib/netdev-linux.c:76:1: warning: symbol 'counter_netdev_set_policing' was
not declared. Should it be static?
lib/netdev-linux.c:77:1: warning: symbol 'counter_netdev_arp_lookup' was
not declared. Should it be static?
lib/netdev-linux.c:78:1: warning: symbol 'counter_netdev_get_ifindex' was
not declared. Should it be static?
"""


On Mon, Aug 19, 2013 at 8:08 AM, Alex Wang <al...@nicira.com> wrote:

> This looks good to me,
>
> The only issue may be that some comments need to be changed:
>
> -/* Sorts coverage counters in descending order by count, within equal
> counts
> - * alphabetically by name. */
> +/* Sorts coverage counters in descending order by total count,
> + * within equal total counts alphabetically by name. */
>  static int
>  compare_coverage_counters(const void *a_, const void *b_)
>  {
> @@ -108,7 +108,7 @@ coverage_hash(void)
>      uint32_t hash = 0;
>      int n_groups, i;
>
> -    /* Sort coverage counters into groups with equal counts. */
> +    /* Sort coverage counters into groups with equal total counts. */
>      c = xmalloc(n_coverage_counters * sizeof *c);
>      ovs_mutex_lock(&coverage_mutex);
>      for (i = 0; i < n_coverage_counters; i++) {
>
>
> On Fri, Aug 16, 2013 at 3:47 PM, Ben Pfaff <b...@nicira.com> wrote:
>
>> This makes each of the coverage counters per-thread.  It abandons the
>> idea of trying to keep track of the number of hits in the "current" poll
>> loop, since there are many poll loops running, each in its own thread, as
>> well as the idea of numbering epochs for the same reason.  Instead, we
>> just keep track of overall totals for the process for each coverage
>> counter, accumulating per-thread counts into the global total each time
>> a thread's main loop passes through poll_block().
>>
>> Signed-off-by: Ben Pfaff <b...@nicira.com>
>> ---
>>  lib/coverage.c |   73
>> +++++++++++++++++++++++++++++++-------------------------
>>  lib/coverage.h |   41 ++++++++++++++++++++++---------
>>  2 files changed, 71 insertions(+), 43 deletions(-)
>>
>> diff --git a/lib/coverage.c b/lib/coverage.c
>> index f152474..ac5dd67 100644
>> --- a/lib/coverage.c
>> +++ b/lib/coverage.c
>> @@ -1,5 +1,5 @@
>>  /*
>> - * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
>> + * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
>>   *
>>   * Licensed under the Apache License, Version 2.0 (the "License");
>>   * you may not use this file except in compliance with the License.
>> @@ -35,7 +35,19 @@ extern struct coverage_counter *__stop_coverage[];
>>  #define coverage_counters __start_coverage
>>  #define n_coverage_counters  (__stop_coverage - __start_coverage)
>>  #else  /* !USE_LINKER_SECTIONS */
>> -#define COVERAGE_COUNTER(NAME) COVERAGE_DEFINE__(NAME);
>> +#define COVERAGE_COUNTER(COUNTER)                                       \
>> +        DECLARE_EXTERN_PER_THREAD_DATA(unsigned int,                    \
>> +                                       counter_##COUNTER);              \
>> +        DEFINE_EXTERN_PER_THREAD_DATA(counter_##COUNTER, 0);            \
>> +        static unsigned int COUNTER##_count(void)                       \
>> +        {                                                               \
>> +            unsigned int *countp = counter_##COUNTER##_get();           \
>> +            unsigned int count = *countp;                               \
>> +            *countp = 0;                                                \
>> +            return count;                                               \
>> +        }                                                               \
>> +        struct coverage_counter counter_##COUNTER                       \
>> +            = { #COUNTER, COUNTER##_count, 0 };
>>  #include "coverage.def"
>>  #undef COVERAGE_COUNTER
>>
>> @@ -47,7 +59,7 @@ struct coverage_counter *coverage_counters[] = {
>>  #define n_coverage_counters ARRAY_SIZE(coverage_counters)
>>  #endif  /* !USE_LINKER_SECTIONS */
>>
>> -static unsigned int epoch;
>> +static struct ovs_mutex coverage_mutex = OVS_MUTEX_INITIALIZER;
>>
>>  static void coverage_read(struct svec *);
>>
>> @@ -82,8 +94,8 @@ compare_coverage_counters(const void *a_, const void
>> *b_)
>>      const struct coverage_counter *const *bp = b_;
>>      const struct coverage_counter *a = *ap;
>>      const struct coverage_counter *b = *bp;
>> -    if (a->count != b->count) {
>> -        return a->count < b->count ? 1 : -1;
>> +    if (a->total != b->total) {
>> +        return a->total < b->total ? 1 : -1;
>>      } else {
>>          return strcmp(a->name, b->name);
>>      }
>> @@ -98,9 +110,11 @@ coverage_hash(void)
>>
>>      /* Sort coverage counters into groups with equal counts. */
>>      c = xmalloc(n_coverage_counters * sizeof *c);
>> +    ovs_mutex_lock(&coverage_mutex);
>>      for (i = 0; i < n_coverage_counters; i++) {
>>          c[i] = coverage_counters[i];
>>      }
>> +    ovs_mutex_unlock(&coverage_mutex);
>>      qsort(c, n_coverage_counters, sizeof *c, compare_coverage_counters);
>>
>>      /* Hash the names in each group along with the rank. */
>> @@ -108,13 +122,13 @@ coverage_hash(void)
>>      for (i = 0; i < n_coverage_counters; ) {
>>          int j;
>>
>> -        if (!c[i]->count) {
>> +        if (!c[i]->total) {
>>              break;
>>          }
>>          n_groups++;
>>          hash = hash_int(i, hash);
>>          for (j = i; j < n_coverage_counters; j++) {
>> -            if (c[j]->count != c[i]->count) {
>> +            if (c[j]->total != c[i]->total) {
>>                  break;
>>              }
>>              hash = hash_string(c[j]->name, hash);
>> @@ -170,7 +184,7 @@ coverage_log(void)
>>          uint32_t hash = coverage_hash();
>>          if (coverage_hit(hash)) {
>>              VLOG_INFO("Skipping details of duplicate event coverage for "
>> -                      "hash=%08"PRIx32" in epoch %u", hash, epoch);
>> +                      "hash=%08"PRIx32, hash);
>>          } else {
>>              struct svec lines;
>>              const char *line;
>> @@ -186,17 +200,11 @@ coverage_log(void)
>>      }
>>  }
>>
>> -static void
>> -coverage_read_counter(struct svec *lines, const struct coverage_counter
>> *c)
>> -{
>> -    svec_add_nocopy(lines, xasprintf("%-24s %5u / %9llu",
>> -                                     c->name, c->count, c->count +
>> c->total));
>> -}
>> -
>>  /* Adds coverage counter information to 'lines'. */
>>  static void
>>  coverage_read(struct svec *lines)
>>  {
>> +    unsigned long long int *totals;
>>      size_t n_never_hit;
>>      uint32_t hash;
>>      size_t i;
>> @@ -204,37 +212,38 @@ coverage_read(struct svec *lines)
>>      hash = coverage_hash();
>>
>>      n_never_hit = 0;
>> -    svec_add_nocopy(lines, xasprintf("Event coverage (epoch %u/entire
>> run), "
>> -                                     "hash=%08"PRIx32":", epoch, hash));
>> +    svec_add_nocopy(lines,
>> +                    xasprintf("Event coverage, hash=%08"PRIx32":",
>> hash));
>> +
>> +    totals = xmalloc(n_coverage_counters * sizeof *totals);
>> +    ovs_mutex_lock(&coverage_mutex);
>>      for (i = 0; i < n_coverage_counters; i++) {
>> -        struct coverage_counter *c = coverage_counters[i];
>> -        if (c->count) {
>> -            coverage_read_counter(lines, c);
>> -        }
>> +        totals[i] = coverage_counters[i]->total;
>>      }
>> +    ovs_mutex_unlock(&coverage_mutex);
>> +
>>      for (i = 0; i < n_coverage_counters; i++) {
>> -        struct coverage_counter *c = coverage_counters[i];
>> -        if (!c->count) {
>> -            if (c->total) {
>> -                coverage_read_counter(lines, c);
>> -            } else {
>> -                n_never_hit++;
>> -            }
>> +        if (totals[i]) {
>> +            svec_add_nocopy(lines, xasprintf("%-24s %9llu",
>> +                                             coverage_counters[i]->name,
>> +                                             totals[i]));
>> +        } else {
>> +            n_never_hit++;
>>          }
>>      }
>>      svec_add_nocopy(lines, xasprintf("%zu events never hit",
>> n_never_hit));
>> +    free(totals);
>>  }
>>
>> -/* Advances to the next epoch of coverage, resetting all the counters to
>> 0. */
>>  void
>>  coverage_clear(void)
>>  {
>>      size_t i;
>>
>> -    epoch++;
>> +    ovs_mutex_lock(&coverage_mutex);
>>      for (i = 0; i < n_coverage_counters; i++) {
>>          struct coverage_counter *c = coverage_counters[i];
>> -        c->total += c->count;
>> -        c->count = 0;
>> +        c->total += c->count();
>>      }
>> +    ovs_mutex_unlock(&coverage_mutex);
>>  }
>> diff --git a/lib/coverage.h b/lib/coverage.h
>> index 968c489..73b027a 100644
>> --- a/lib/coverage.h
>> +++ b/lib/coverage.h
>> @@ -1,5 +1,5 @@
>>  /*
>> - * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
>> + * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
>>   *
>>   * Licensed under the Apache License, Version 2.0 (the "License");
>>   * you may not use this file except in compliance with the License.
>> @@ -27,33 +27,54 @@
>>   * for traditional coverage instrumentation with e.g. "gcov", but it is
>> still
>>   * a useful debugging tool. */
>>
>> +#include "ovs-thread.h"
>>  #include "vlog.h"
>>
>>  /* A coverage counter. */
>>  struct coverage_counter {
>> -    const char *name;           /* Textual name. */
>> -    unsigned int count;         /* Count within the current epoch. */
>> -    unsigned long long int total; /* Total count over all epochs. */
>> +    const char *const name;            /* Textual name. */
>> +    unsigned int (*const count)(void); /* Gets, zeros this thread's
>> count. */
>> +    unsigned long long int total;      /* Total count. */
>>  };
>>
>>  /* Defines COUNTER.  There must be exactly one such definition at file
>> scope
>>   * within a program. */
>>  #if USE_LINKER_SECTIONS
>>  #define COVERAGE_DEFINE(COUNTER)                                        \
>> -        COVERAGE_DEFINE__(COUNTER);                                     \
>> +        DEFINE_STATIC_PER_THREAD_DATA(unsigned int,                     \
>> +                                      counter_##COUNTER, 0);            \
>> +        static unsigned int COUNTER##_count(void)                       \
>> +        {                                                               \
>> +            unsigned int *countp = counter_##COUNTER##_get();           \
>> +            unsigned int count = *countp;                               \
>> +            *countp = 0;                                                \
>> +            return count;                                               \
>> +        }                                                               \
>> +        static inline void COUNTER##_add(unsigned int n)                \
>> +        {                                                               \
>> +            *counter_##COUNTER##_get() += n;                            \
>> +        }                                                               \
>> +        struct coverage_counter counter_##COUNTER                       \
>> +            = { #COUNTER, COUNTER##_count, 0 };                         \
>>          extern struct coverage_counter *counter_ptr_##COUNTER;          \
>>          struct coverage_counter *counter_ptr_##COUNTER                  \
>>              __attribute__((section("coverage"))) = &counter_##COUNTER
>>  #else
>> -#define COVERAGE_DEFINE(MODULE) \
>> -        extern struct coverage_counter counter_##MODULE
>> +#define COVERAGE_DEFINE(COUNTER)                                        \
>> +        DECLARE_EXTERN_PER_THREAD_DATA(unsigned int,                    \
>> +                                       counter_##COUNTER);              \
>> +        static inline void COUNTER##_add(unsigned int n)                \
>> +        {                                                               \
>> +            *counter_##COUNTER##_get() += n;                            \
>> +        }                                                               \
>> +        extern struct coverage_counter counter_##COUNTER
>>  #endif
>>
>>  /* Adds 1 to COUNTER. */
>> -#define COVERAGE_INC(COUNTER) counter_##COUNTER.count++;
>> +#define COVERAGE_INC(COUNTER) COVERAGE_ADD(COUNTER, 1)
>>
>>  /* Adds AMOUNT to COUNTER. */
>> -#define COVERAGE_ADD(COUNTER, AMOUNT) counter_##COUNTER.count +=
>> (AMOUNT);
>> +#define COVERAGE_ADD(COUNTER, AMOUNT) COUNTER##_add(AMOUNT)
>>
>>  void coverage_init(void);
>>  void coverage_log(void);
>> @@ -61,7 +82,5 @@ void coverage_clear(void);
>>
>>  /* Implementation detail. */
>>  #define COVERAGE_DEFINE__(COUNTER)                              \
>> -        extern struct coverage_counter counter_##COUNTER;       \
>> -        struct coverage_counter counter_##COUNTER = { #COUNTER, 0, 0 }
>>
>>  #endif /* coverage.h */
>> --
>> 1.7.10.4
>>
>> _______________________________________________
>> dev mailing list
>> dev@openvswitch.org
>> http://openvswitch.org/mailman/listinfo/dev
>>
>
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to