Added fairness check option. When enabled, event count per
queue is calculated and printed after test.

Signed-off-by: Petri Savolainen <[email protected]>
---
 test/performance/odp_scheduling.c | 103 +++++++++++++++++++++++++++++++++++---
 1 file changed, 96 insertions(+), 7 deletions(-)

diff --git a/test/performance/odp_scheduling.c 
b/test/performance/odp_scheduling.c
index ec913ae..c7a3049 100644
--- a/test/performance/odp_scheduling.c
+++ b/test/performance/odp_scheduling.c
@@ -37,6 +37,7 @@
 #define ALLOC_ROUNDS          (1024*1024)   /**< Alloc test rounds */
 #define MULTI_BUFS_MAX        4             /**< Buffer burst size */
 #define TEST_SEC              2             /**< Time test duration in sec */
+#define STATS_PER_LINE        8             /**< Stats per printed line */
 
 /** Dummy message */
 typedef struct {
@@ -51,15 +52,55 @@ typedef struct {
 typedef struct {
        int cpu_count;  /**< CPU count */
        int proc_mode;  /**< Process mode */
+       int fairness;   /**< Check fairness */
 } test_args_t;
 
+typedef struct {
+       uint64_t num_ev;
+
+       /* Round up the struct size to cache line size */
+       uint8_t pad[ODP_CACHE_LINE_SIZE - sizeof(uint64_t)];
+} queue_context_t ODP_ALIGNED_CACHE;
+
 /** Test global variables */
 typedef struct {
-       odp_barrier_t barrier;
-       odp_pool_t    pool;
-       odp_queue_t   queue[NUM_PRIOS][QUEUES_PER_PRIO];
+       odp_barrier_t    barrier;
+       odp_spinlock_t   lock;
+       odp_pool_t       pool;
+       int              first_thr;
+       test_args_t      args;
+       odp_queue_t      queue[NUM_PRIOS][QUEUES_PER_PRIO];
+       queue_context_t  queue_ctx[NUM_PRIOS][QUEUES_PER_PRIO];
 } test_globals_t;
 
+/* Prints and initializes queue statistics */
+static void print_stats(int prio, test_globals_t *globals)
+{
+       int i, j, k;
+
+       if (prio == ODP_SCHED_PRIO_HIGHEST)
+               i = 0;
+       else
+               i = 1;
+
+       printf("\nQueue fairness\n-----+--------\n");
+
+       for (j = 0; j < QUEUES_PER_PRIO;) {
+               printf("  %2i | ", j);
+
+               for (k = 0; k < STATS_PER_LINE - 1; k++) {
+                       printf(" %8" PRIu64,
+                              globals->queue_ctx[i][j].num_ev);
+                       globals->queue_ctx[i][j++].num_ev = 0;
+               }
+
+               printf(" %8" PRIu64 "\n", globals->queue_ctx[i][j].num_ev);
+               globals->queue_ctx[i][j++].num_ev = 0;
+       }
+
+       printf("\n");
+}
+
 /**
  * @internal Clear all scheduled queues. Retry to be sure that all
  * buffers have been scheduled.
@@ -452,6 +493,13 @@ static int test_schedule_multi(const char *str, int thr,
 
                tot += num;
 
+               if (globals->args.fairness) {
+                       queue_context_t *queue_ctx;
+
+                       queue_ctx = odp_queue_context(queue);
+                       queue_ctx->num_ev += num;
+               }
+
                /* Assume we can enqueue all events */
                if (odp_queue_enq_multi(queue, ev, num) != num) {
                        LOG_ERR("  [%i] Queue enqueue failed.\n", thr);
@@ -471,6 +519,13 @@ static int test_schedule_multi(const char *str, int thr,
 
                tot += num;
 
+               if (globals->args.fairness) {
+                       queue_context_t *queue_ctx;
+
+                       queue_ctx = odp_queue_context(queue);
+                       queue_ctx->num_ev += num;
+               }
+
                /* Assume we can enqueue all events */
                if (odp_queue_enq_multi(queue, ev, num) != num) {
                        LOG_ERR("  [%i] Queue enqueue failed.\n", thr);
@@ -494,6 +549,11 @@ static int test_schedule_multi(const char *str, int thr,
 
        printf("  [%i] %s enq+deq %6" PRIu64 " CPU cycles\n", thr, str, cycles);
 
+       odp_barrier_wait(&globals->barrier);
+
+       if (globals->args.fairness && globals->first_thr == thr)
+               print_stats(prio, globals);
+
        return 0;
 }
 
@@ -534,6 +594,16 @@ static void *run_thread(void *arg)
        odp_barrier_wait(barrier);
        odp_barrier_wait(barrier);
 
+       /* Select which thread is the first_thr */
+       while (globals->first_thr < 0) {
+               if (odp_spinlock_trylock(&globals->lock)) {
+                       globals->first_thr = thr;
+                       odp_spinlock_unlock(&globals->lock);
+               }
+       }
+
+       odp_barrier_wait(barrier);
+
        if (test_alloc_single(thr, globals))
                return NULL;
 
@@ -645,7 +715,8 @@ static void print_usage(void)
        printf("Options:\n");
        printf("  -c, --count <number>    CPU count\n");
        printf("  -h, --help              this help\n");
-       printf("  --proc                  process mode\n");
+       printf("  -p, --proc              process mode\n");
+       printf("  -f, --fair              collect fairness statistics\n");
        printf("\n\n");
 }
 
@@ -663,22 +734,28 @@ static void parse_args(int argc, char *argv[], 
test_args_t *args)
 
        static struct option longopts[] = {
                {"count", required_argument, NULL, 'c'},
+               {"proc", no_argument, NULL, 'p'},
+               {"fair", no_argument, NULL, 'f'},
                {"help", no_argument, NULL, 'h'},
-               {"proc", no_argument, NULL, 0},
                {NULL, 0, NULL, 0}
        };
 
        while (1) {
-               opt = getopt_long(argc, argv, "+c:h", longopts, &long_index);
+               opt = getopt_long(argc, argv, "+c:pfh",
+                                 longopts, &long_index);
 
                if (opt == -1)
                        break;  /* No more options */
 
                switch (opt) {
-               case 0:
+               case 'p':
                        args->proc_mode = 1;
                        break;
 
+               case 'f':
+                       args->fairness = 1;
+                       break;
+
                case 'c':
                        args->cpu_count = atoi(optarg);
                        break;
@@ -780,6 +857,7 @@ int main(int argc, char *argv[])
 
        globals = odp_shm_addr(shm);
        memset(globals, 0, sizeof(test_globals_t));
+       memcpy(&globals->args, &args, sizeof(test_args_t));
 
        /*
         * Create message pool
@@ -847,6 +925,14 @@ int main(int argc, char *argv[])
                        }
 
                        globals->queue[i][j] = queue;
+
+                       if (odp_queue_context_set(queue,
+                                                 &globals->queue_ctx[i][j],
+                                                 sizeof(queue_context_t))
+                                                 < 0) {
+                               LOG_ERR("Queue context set failed.\n");
+                               return -1;
+                       }
                }
        }
 
@@ -855,6 +941,9 @@ int main(int argc, char *argv[])
        /* Barrier to sync test case execution */
        odp_barrier_init(&globals->barrier, num_workers);
 
+       odp_spinlock_init(&globals->lock);
+       globals->first_thr = -1;
+
        memset(&thr_params, 0, sizeof(thr_params));
        thr_params.thr_type = ODP_THREAD_WORKER;
        thr_params.instance = instance;
-- 
2.8.1

_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to