On Tue, Apr 25, 2017 at 4:27 PM, Brian Brooks <[email protected]> wrote:
> In order to robustly drain all queues when the benchmark has > ended, we enqueue a special event on every queue and invoke > the scheduler until all such events have been received. > > Signed-off-by: Ola Liljedahl <[email protected]> > Reviewed-by: Brian Brooks <[email protected]> > Reviewed-by: Honnappa Nagarahalli <[email protected]> > Reviewed-and-tested-by: Bill Fischofer <[email protected]> > --- > > v2: > - Call odp_schedule() after draining to ensure ODP_EVENT_INVALID is > returned > and thus any scheduler context is released > - Abort if failure to allocate or enqueue cool_down event > - Use only one cool_down event, reuse for all queues > > test/common_plat/performance/odp_sched_latency.c | 59 > ++++++++++++++++++------ > 1 file changed, 46 insertions(+), 13 deletions(-) > > diff --git a/test/common_plat/performance/odp_sched_latency.c > b/test/common_plat/performance/odp_sched_latency.c > index 2b28cd7b..b4018687 100644 > --- a/test/common_plat/performance/odp_sched_latency.c > +++ b/test/common_plat/performance/odp_sched_latency.c > @@ -57,9 +57,10 @@ ODP_STATIC_ASSERT(LO_PRIO_QUEUES <= MAX_QUEUES, "Too > many LO priority queues"); > > /** Test event types */ > typedef enum { > - WARM_UP, /**< Warm up event */ > - TRAFFIC, /**< Event used only as traffic load */ > - SAMPLE /**< Event used to measure latency */ > + WARM_UP, /**< Warm up event */ > + COOL_DOWN,/**< Last event on queue */ > + TRAFFIC, /**< Event used only as traffic load */ > + SAMPLE /**< Event used to measure latency */ > } event_type_t; > > /** Test event */ > @@ -112,20 +113,52 @@ typedef struct { > /** > * Clear all scheduled queues. > * > - * Retry to be sure that all buffers have been scheduled. > + * Use special cool_down event to guarantee that queue is drained. > */ > -static void clear_sched_queues(void) > +static void clear_sched_queues(test_globals_t *globals) > { > odp_event_t ev; > + odp_buffer_t buf; > + test_event_t *event; > + int i, j; > + odp_queue_t fromq; > > - while (1) { > - ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT); > + /* Allocate the cool_down event. */ > + buf = odp_buffer_alloc(globals->pool); > + if (buf == ODP_BUFFER_INVALID) > + LOG_ABORT("Buffer alloc failed.\n"); > > - if (ev == ODP_EVENT_INVALID) > - break; > + event = odp_buffer_addr(buf); > + event->type = COOL_DOWN; > + ev = odp_buffer_to_event(buf); > > - odp_event_free(ev); > + for (i = 0; i < NUM_PRIOS; i++) { > + for (j = 0; j < globals->args.prio[i].queues; j++) { > + /* Enqueue cool_down event on each queue. */ > + if (odp_queue_enq(globals->queue[i][j], ev)) > + LOG_ABORT("Queue enqueue failed.\n"); > + > + /* Invoke scheduler until cool_down event has been > + * received. */ > + while (1) { > + ev = odp_schedule(NULL, ODP_SCHED_WAIT); > + buf = odp_buffer_from_event(ev); > + event = odp_buffer_addr(buf); > + if (event->type == COOL_DOWN) > + break; > + odp_event_free(ev); > + } > + } > } > + > + /* Free the cool_down event. */ > + odp_event_free(ev); > + > + /* Call odp_schedule() to trigger a release of any scheduler > context. */ > + ev = odp_schedule(&fromq, ODP_SCHED_NO_WAIT); > + if (ev != ODP_EVENT_INVALID) > + LOG_ABORT("Queue %" PRIu64 " not empty.\n", > + odp_queue_to_u64(fromq)); > } > > /** > @@ -394,10 +427,10 @@ static int test_schedule(int thr, test_globals_t > *globals) > > odp_barrier_wait(&globals->barrier); > > - clear_sched_queues(); > - > - if (thr == MAIN_THREAD) > + if (thr == MAIN_THREAD) { > + clear_sched_queues(globals); > print_results(globals); > + } > > return 0; > } > -- > 2.12.2 > >
