int odp_pool_term_global(void) { int i; pool_entry_t *pool; int ret = 0; int rc = 0; for (i = 0; i < ODP_CONFIG_POOLS; i++) { pool = get_pool_entry(i); POOL_LOCK(&pool->s.lock); if (pool->s.pool_shm != ODP_SHM_INVALID) { ODP_ERR("Not destroyed pool: %s\n", pool->s.name); rc = -1; } POOL_UNLOCK(&pool->s.lock); } ret = odp_shm_free(odp_shm_lookup(SHM_DEFAULT_NAME)); if (ret < 0) { ODP_ERR("shm free failed for %s", SHM_DEFAULT_NAME); rc = -1; } return rc; }
int odp_pool_destroy(odp_pool_t pool_hdl) { uint32_t pool_id = pool_handle_to_index(pool_hdl); pool_entry_t *pool = get_pool_entry(pool_id); int i; if (pool == NULL) return -1; POOL_LOCK(&pool->s.lock); /* Call fails if pool is not allocated or predefined*/ if (pool->s.pool_shm == ODP_SHM_INVALID || pool->s.flags.predefined) { POOL_UNLOCK(&pool->s.lock); return -1; } /* Make sure local caches are empty */ for (i = 0; i < ODP_THREAD_COUNT_MAX; i++) flush_cache(&pool->s.local_cache[i], &pool->s); /* Call fails if pool has allocated buffers */ if (odp_atomic_load_u32(&pool->s.bufcount) < pool->s.buf_num) { POOL_UNLOCK(&pool->s.lock); return -1; } odp_shm_free(pool->s.pool_shm); pool->s.pool_shm = ODP_SHM_INVALID; POOL_UNLOCK(&pool->s.lock); return 0; }
int odp_queue_term_global(void) { int ret = 0; int rc = 0; queue_entry_t *queue; int i; for (i = 0; i < ODP_CONFIG_QUEUES; i++) { queue = &queue_tbl->queue[i]; LOCK(queue); if (LOAD_S32(queue->s.status) != QUEUE_STATUS_FREE) { ODP_ERR("Not destroyed queue: %s\n", queue->s.name); rc = -1; } UNLOCK(queue); } ret = odp_shm_free(odp_shm_lookup("odp_queues")); if (ret < 0) { ODP_ERR("shm free failed for odp_queues"); rc = -1; } return rc; }
static int test_term(void) { char pool_name[ODP_POOL_NAME_LEN]; odp_pool_t pool; int i; int ret = 0; if (gbl_args->pktio_tx != gbl_args->pktio_rx) { if (odp_pktio_stop(gbl_args->pktio_tx)) { LOG_ERR("Failed to stop pktio_tx\n"); return -1; } if (odp_pktio_close(gbl_args->pktio_tx)) { LOG_ERR("Failed to close pktio_tx\n"); ret = -1; } } empty_inq(gbl_args->pktio_rx); if (odp_pktio_stop(gbl_args->pktio_rx)) { LOG_ERR("Failed to stop pktio_rx\n"); return -1; } if (odp_pktio_close(gbl_args->pktio_rx) != 0) { LOG_ERR("Failed to close pktio_rx\n"); ret = -1; } for (i = 0; i < gbl_args->args.num_ifaces; ++i) { snprintf(pool_name, sizeof(pool_name), "pkt_pool_%s", gbl_args->args.ifaces[i]); pool = odp_pool_lookup(pool_name); if (pool == ODP_POOL_INVALID) continue; if (odp_pool_destroy(pool) != 0) { LOG_ERR("Failed to destroy pool %s\n", pool_name); ret = -1; } } if (odp_pool_destroy(transmit_pkt_pool) != 0) { LOG_ERR("Failed to destroy transmit pool\n"); ret = -1; } free(gbl_args->args.if_str); if (odp_shm_free(odp_shm_lookup("test_globals")) != 0) { LOG_ERR("Failed to free test_globals\n"); ret = -1; } return ret; }
int odp_schedule_term_global(void) { int ret = 0; int rc = 0; int i, j; for (i = 0; i < ODP_CONFIG_SCHED_PRIOS; i++) { for (j = 0; j < QUEUES_PER_PRIO; j++) { 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"); } else 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("Pool destroy fail.\n"); rc = -1; } ret = odp_shm_free(sched->shm); if (ret < 0) { ODP_ERR("Shm free failed for odp_scheduler"); rc = -1; } return rc; }
int odp_thread_term_global(void) { int ret; ret = odp_shm_free(odp_shm_lookup("odp_thread_globals")); if (ret < 0) ODP_ERR("shm free failed for odp_thread_globals"); return ret; }
int ofp_shared_memory_free_raw(const char *name) { odp_shm_t shm_h; shm_h = odp_shm_lookup(name); if (shm_h == ODP_SHM_INVALID) return -1; odp_shm_free(shm_h); return 0; }
void *ofp_shared_memory_lookup_raw(const char *name) { odp_shm_t shm_h; void *shm; shm_h = odp_shm_lookup(name); if (shm_h == ODP_SHM_INVALID) return NULL; shm = odp_shm_addr(shm_h); if (shm == NULL) { odp_shm_free(shm_h); return NULL; } return shm; }
void *ofp_shared_memory_alloc(const char *name, uint64_t size) { odp_shm_t shm_h; void *shm; shm_h = odp_shm_reserve(name, size, ODP_CACHE_LINE_SIZE, 0); if (shm_h == ODP_SHM_INVALID) return NULL; shm = odp_shm_addr(shm_h); if (shm == NULL) { odp_shm_free(shm_h); return NULL; } return shm; }
static void *allocate_shared_memory(const char *name, uint64_t size) { odp_shm_t shm_h; void *shm; shm_h = odp_shm_reserve(name, size, ODP_CACHE_LINE_SIZE, OFP_SHM_SINGLE_VA); if (shm_h == ODP_SHM_INVALID) return NULL; shm = odp_shm_addr(shm_h); if (shm == NULL) { odp_shm_free(shm_h); return NULL; } return shm; }
int odph_linear_table_destroy(odph_table_t table) { int ret; odph_linear_table_imp *linear_tbl = NULL; if (table != NULL) { linear_tbl = (odph_linear_table_imp *)table; /* check magicword, make sure the memory is used by a table */ if (linear_tbl->magicword != ODPH_LINEAR_TABLE_MAGIC_WORD) return ODPH_FAIL; ret = odp_shm_free(odp_shm_lookup(linear_tbl->name)); if (ret != 0) { ODPH_DBG("free fail\n"); return ret; } return ODPH_SUCCESS; } return ODPH_FAIL; }
int odp_pktio_term_global(void) { pktio_entry_t *pktio_entry; int ret = 0; int id; int pktio_if; for (pktio_if = 0; pktio_if_ops[pktio_if]; ++pktio_if) if (pktio_if_ops[pktio_if]->term) if (pktio_if_ops[pktio_if]->term()) ODP_ERR("failed to terminate pktio type %d", pktio_if); for (id = 1; id <= ODP_CONFIG_PKTIO_ENTRIES; ++id) { pktio_entry = &pktio_tbl->entries[id - 1]; odp_queue_destroy(pktio_entry->s.outq_default); } ret = odp_shm_free(odp_shm_lookup("odp_pktio_entries")); if (ret < 0) ODP_ERR("shm free failed for odp_pktio_entries"); return ret; }
/** * Test main function */ int main(int argc, char *argv[]) { odph_linux_pthread_t thread_tbl[MAX_WORKERS]; int num_workers; odp_queue_t queue; uint64_t tick, ns; odp_queue_param_t param; odp_pool_param_t params; odp_timer_pool_param_t tparams; odp_timer_pool_info_t tpinfo; odp_cpumask_t cpumask; char cpumaskstr[ODP_CPUMASK_STR_SIZE]; odp_shm_t shm = ODP_SHM_INVALID; test_globals_t *gbls = NULL; int err = 0; printf("\nODP timer example starts\n"); if (odp_init_global(NULL, NULL)) { err = 1; printf("ODP global init failed.\n"); goto err_global; } /* Init this thread. */ if (odp_init_local(ODP_THREAD_CONTROL)) { err = 1; printf("ODP local init failed.\n"); goto err_local; } printf("\n"); printf("ODP system info\n"); printf("---------------\n"); printf("ODP API version: %s\n", odp_version_api_str()); printf("CPU model: %s\n", odp_cpu_model_str()); printf("CPU freq (hz): %"PRIu64"\n", odp_cpu_hz_max()); printf("Cache line size: %i\n", odp_sys_cache_line_size()); printf("Max CPU count: %i\n", odp_cpu_count()); printf("\n"); /* Reserve memory for test_globals_t from shared mem */ shm = odp_shm_reserve("shm_test_globals", sizeof(test_globals_t), ODP_CACHE_LINE_SIZE, 0); if (ODP_SHM_INVALID == shm) { err = 1; EXAMPLE_ERR("Error: shared mem reserve failed.\n"); goto err; } gbls = odp_shm_addr(shm); if (NULL == gbls) { err = 1; EXAMPLE_ERR("Error: shared mem alloc failed.\n"); goto err; } memset(gbls, 0, sizeof(test_globals_t)); gbls->pool = ODP_POOL_INVALID; gbls->tp = ODP_TIMER_POOL_INVALID; parse_args(argc, argv, &gbls->args); memset(thread_tbl, 0, sizeof(thread_tbl)); /* Default to system CPU count unless user specified */ num_workers = MAX_WORKERS; if (gbls->args.cpu_count) num_workers = gbls->args.cpu_count; /* Get default worker cpumask */ num_workers = odp_cpumask_default_worker(&cpumask, num_workers); (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr)); printf("num worker threads: %i\n", num_workers); printf("first CPU: %i\n", odp_cpumask_first(&cpumask)); printf("cpu mask: %s\n", cpumaskstr); printf("resolution: %i usec\n", gbls->args.resolution_us); printf("min timeout: %i usec\n", gbls->args.min_us); printf("max timeout: %i usec\n", gbls->args.max_us); printf("period: %i usec\n", gbls->args.period_us); printf("timeouts: %i\n", gbls->args.tmo_count); /* * Create pool for timeouts */ odp_pool_param_init(¶ms); params.tmo.num = NUM_TMOS; params.type = ODP_POOL_TIMEOUT; gbls->pool = odp_pool_create("msg_pool", ¶ms); if (gbls->pool == ODP_POOL_INVALID) { err = 1; EXAMPLE_ERR("Pool create failed.\n"); goto err; } tparams.res_ns = gbls->args.resolution_us * ODP_TIME_USEC_IN_NS; tparams.min_tmo = gbls->args.min_us * ODP_TIME_USEC_IN_NS; tparams.max_tmo = gbls->args.max_us * ODP_TIME_USEC_IN_NS; tparams.num_timers = num_workers; /* One timer per worker */ tparams.priv = 0; /* Shared */ tparams.clk_src = ODP_CLOCK_CPU; gbls->tp = odp_timer_pool_create("timer_pool", &tparams); if (gbls->tp == ODP_TIMER_POOL_INVALID) { err = 1; EXAMPLE_ERR("Timer pool create failed.\n"); goto err; } odp_timer_pool_start(); odp_shm_print_all(); (void)odp_timer_pool_info(gbls->tp, &tpinfo); printf("Timer pool\n"); printf("----------\n"); printf(" name: %s\n", tpinfo.name); printf(" resolution: %"PRIu64" ns\n", tpinfo.param.res_ns); printf(" min tmo: %"PRIu64" ticks\n", tpinfo.param.min_tmo); printf(" max tmo: %"PRIu64" ticks\n", tpinfo.param.max_tmo); printf("\n"); /* * Create a queue for timer test */ odp_queue_param_init(¶m); param.type = ODP_QUEUE_TYPE_SCHED; param.sched.prio = ODP_SCHED_PRIO_DEFAULT; param.sched.sync = ODP_SCHED_SYNC_PARALLEL; param.sched.group = ODP_SCHED_GROUP_ALL; queue = odp_queue_create("timer_queue", ¶m); if (queue == ODP_QUEUE_INVALID) { err = 1; EXAMPLE_ERR("Timer queue create failed.\n"); goto err; } printf("CPU freq %"PRIu64" Hz\n", odp_cpu_hz_max()); printf("Timer ticks vs nanoseconds:\n"); ns = 0; tick = odp_timer_ns_to_tick(gbls->tp, ns); printf(" %12" PRIu64 " ns -> %12" PRIu64 " ticks\n", ns, tick); printf(" %12" PRIu64 " ticks -> %12" PRIu64 " ns\n", tick, odp_timer_tick_to_ns(gbls->tp, tick)); for (ns = 1; ns <= 100 * ODP_TIME_SEC_IN_NS; ns *= 10) { tick = odp_timer_ns_to_tick(gbls->tp, ns); printf(" %12" PRIu64 " ns -> %12" PRIu64 " ticks\n", ns, tick); printf(" %12" PRIu64 " ticks -> %12" PRIu64 " ns\n", tick, odp_timer_tick_to_ns(gbls->tp, tick)); } printf("\n"); gbls->num_workers = num_workers; /* Initialize number of timeouts to receive */ odp_atomic_init_u32(&gbls->remain, gbls->args.tmo_count * num_workers); /* Barrier to sync test case execution */ odp_barrier_init(&gbls->test_barrier, num_workers); /* Create and launch worker threads */ odph_linux_pthread_create(thread_tbl, &cpumask, run_thread, gbls, ODP_THREAD_WORKER); /* Wait for worker threads to exit */ odph_linux_pthread_join(thread_tbl, num_workers); /* free resources */ if (odp_queue_destroy(queue)) err = 1; err: if (gbls != NULL && gbls->tp != ODP_TIMER_POOL_INVALID) odp_timer_pool_destroy(gbls->tp); if (gbls != NULL && gbls->pool != ODP_TIMER_POOL_INVALID) if (odp_pool_destroy(gbls->pool)) err = 1; if (shm != ODP_SHM_INVALID) if (odp_shm_free(shm)) err = 1; if (odp_term_local()) err = 1; err_local: if (odp_term_global()) err = 1; err_global: if (err) { printf("Err: ODP timer test failed\n\n"); return -1; } printf("ODP timer test complete\n\n"); return 0; }