Added clean up for pending schedule commands and queue destroys. Added error detection of non empty queues and pre-scheduled events.
Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com> --- platform/linux-generic/odp_schedule.c | 82 ++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 21 deletions(-) diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c index 59e40c7..7fe42d7 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -46,6 +46,7 @@ typedef struct { pri_mask_t pri_mask[ODP_CONFIG_SCHED_PRIOS]; odp_spinlock_t mask_lock; odp_pool_t pool; + odp_shm_t shm; uint32_t pri_count[ODP_CONFIG_SCHED_PRIOS][QUEUES_PER_PRIO]; } sched_t; @@ -86,6 +87,20 @@ static sched_t *sched; /* Thread local scheduler context */ static __thread sched_local_t sched_local; +static void sched_local_init(void) +{ + int i; + + memset(&sched_local, 0, sizeof(sched_local_t)); + + sched_local.pri_queue = ODP_QUEUE_INVALID; + sched_local.cmd_ev = ODP_EVENT_INVALID; + sched_local.qe = NULL; + + for (i = 0; i < MAX_DEQ; i++) + sched_local.buf_hdr[i] = NULL; +} + int odp_schedule_init_global(void) { odp_shm_t shm; @@ -121,6 +136,7 @@ int odp_schedule_init_global(void) } sched->pool = pool; + sched->shm = shm; odp_spinlock_init(&sched->mask_lock); for (i = 0; i < ODP_CONFIG_SCHED_PRIOS; i++) { @@ -160,21 +176,52 @@ int odp_schedule_term_global(void) for (i = 0; i < ODP_CONFIG_SCHED_PRIOS; i++) { for (j = 0; j < QUEUES_PER_PRIO; j++) { - if (odp_queue_destroy(sched->pri_queue[i][j])) { - ODP_ERR("Sched term: Queue destroy fail.\n"); + odp_queue_t pri_q; + odp_event_t ev; + + pri_q = sched->pri_queue[i][j]; + + while ((ev = odp_queue_deq(pri_q)) != + ODP_EVENT_INVALID) { + odp_buffer_t buf; + sched_cmd_t *sched_cmd; + + buf = odp_buffer_from_event(ev); + sched_cmd = odp_buffer_addr(buf); + + if (sched_cmd->cmd == SCHED_CMD_DEQUEUE) { + queue_entry_t *qe; + odp_buffer_hdr_t *buf_hdr[1]; + int num; + + qe = sched_cmd->qe; + num = queue_deq_multi(qe, buf_hdr, 1); + + if (num < 0) + queue_destroy_finalize(qe); + + if (num > 0) + ODP_ERR("Queue not empty\n"); + } + + odp_buffer_free(buf); + } + + if (odp_queue_destroy(pri_q)) { + ODP_ERR("Pri queue destroy fail.\n"); rc = -1; } } } if (odp_pool_destroy(sched->pool) != 0) { - ODP_ERR("Sched term: Pool destroy fail.\n"); + ODP_ERR("Pool destroy fail.\n"); rc = -1; } - ret = odp_shm_free(odp_shm_lookup("odp_scheduler")); + ret = odp_shm_free(sched->shm); if (ret < 0) { - ODP_ERR("Sched term: shm free failed for odp_scheduler"); + ODP_ERR("Shm free failed for odp_scheduler"); rc = -1; } @@ -183,27 +230,20 @@ int odp_schedule_term_global(void) int odp_schedule_init_local(void) { - int i; - - memset(&sched_local, 0, sizeof(sched_local_t)); - - sched_local.pri_queue = ODP_QUEUE_INVALID; - sched_local.cmd_ev = ODP_EVENT_INVALID; - - for (i = 0; i < MAX_DEQ; i++) - sched_local.buf_hdr[i] = NULL; - - sched_local.qe = NULL; - sched_local.num = 0; - sched_local.index = 0; - sched_local.pause = 0; - + sched_local_init(); return 0; } int odp_schedule_term_local(void) { - memset(&sched_local, 0, sizeof(sched_local_t)); + if (sched_local.num) { + ODP_ERR("Locally pre-scheduled events exist.\n"); + return -1; + } + + odp_schedule_release_atomic(); + + sched_local_init(); return 0; } -- 2.3.3 _______________________________________________ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp