aboutsummaryrefslogtreecommitdiff
path: root/helper
diff options
context:
space:
mode:
Diffstat (limited to 'helper')
-rw-r--r--helper/Makefile.am18
-rw-r--r--helper/cli.c4
-rw-r--r--helper/cuckootable.c776
-rw-r--r--helper/hashtable.c356
-rw-r--r--helper/include/odp/helper/debug.h (renamed from helper/include/odp/helper/odph_debug.h)0
-rw-r--r--helper/include/odp/helper/odph_api.h9
-rw-r--r--helper/include/odp/helper/odph_cuckootable.h146
-rw-r--r--helper/include/odp/helper/odph_hashtable.h111
-rw-r--r--helper/include/odp/helper/odph_iplookuptable.h125
-rw-r--r--helper/include/odp/helper/odph_lineartable.h101
-rw-r--r--helper/include/odp/helper/stress.h238
-rw-r--r--helper/include/odp/helper/string.h62
-rw-r--r--helper/include/odp/helper/table.h244
-rw-r--r--helper/include/odp/helper/threads.h45
-rw-r--r--helper/include/odph_list_internal.h88
-rw-r--r--helper/iplookuptable.c990
-rw-r--r--helper/ipsec.c2
-rw-r--r--helper/lineartable.c216
-rw-r--r--helper/linux/thread.c2
-rw-r--r--helper/m4/configure.m44
-rw-r--r--helper/m4/libcli.m44
-rw-r--r--helper/test/.gitignore4
-rw-r--r--helper/test/Makefile.am10
-rw-r--r--helper/test/cli.c15
-rw-r--r--helper/test/cuckootable.c577
-rw-r--r--helper/test/iplookuptable.c170
-rw-r--r--helper/test/odpthreads.c39
-rw-r--r--helper/test/stress.c118
-rw-r--r--helper/test/table.c130
-rw-r--r--helper/threads.c85
30 files changed, 587 insertions, 4102 deletions
diff --git a/helper/Makefile.am b/helper/Makefile.am
index 54d4fbf66..5dd078596 100644
--- a/helper/Makefile.am
+++ b/helper/Makefile.am
@@ -20,7 +20,7 @@ helperinclude_HEADERS = \
include/odp/helper/autoheader_external.h\
include/odp/helper/deprecated.h\
include/odp/helper/chksum.h\
- include/odp/helper/odph_debug.h \
+ include/odp/helper/debug.h \
include/odp/helper/eth.h\
include/odp/helper/gtp.h\
include/odp/helper/icmp.h\
@@ -29,14 +29,11 @@ helperinclude_HEADERS = \
include/odp/helper/ipsec.h\
include/odp/helper/macros.h\
include/odp/helper/odph_api.h\
- include/odp/helper/odph_cuckootable.h\
- include/odp/helper/odph_hashtable.h\
- include/odp/helper/odph_iplookuptable.h\
- include/odp/helper/odph_lineartable.h\
include/odp/helper/sctp.h \
+ include/odp/helper/stress.h\
+ include/odp/helper/string.h\
include/odp/helper/strong_types.h\
include/odp/helper/tcp.h\
- include/odp/helper/table.h\
include/odp/helper/threads.h \
include/odp/helper/udp.h \
include/odp/helper/version.h
@@ -56,17 +53,10 @@ helperinclude_HEADERS += \
include/odp/helper/cli.h
endif
-noinst_HEADERS = \
- include/odph_list_internal.h
-
__LIB__libodphelper_la_SOURCES = \
eth.c \
ip.c \
chksum.c \
- hashtable.c \
- lineartable.c \
- cuckootable.c \
- iplookuptable.c \
ipsec.c \
threads.c \
version.c
@@ -86,7 +76,7 @@ __LIB__libodphelper_la_LIBADD += $(LIBCLI_LIBS)
lib_LTLIBRARIES = $(LIB)/libodphelper.la
-CHECK_GLOBALS_REGEX = " (odph_|_deprecated_odph_)"
+CHECK_GLOBALS_REGEX = " (odph_|_deprecated_odph_|__odr_asan)"
TESTS_ENVIRONMENT = \
LIBTOOL="$(LIBTOOL)" \
diff --git a/helper/cli.c b/helper/cli.c
index 4ce4bf62e..dc6491f6b 100644
--- a/helper/cli.c
+++ b/helper/cli.c
@@ -153,13 +153,13 @@ int odph_cli_register_command(const char *name, odph_cli_user_cmd_func_t func,
cmd->fn = func;
- if (strlen(name) >= MAX_NAME_LEN - 1) {
+ if (strlen(name) >= MAX_NAME_LEN) {
ODPH_ERR("Error: command name too long\n");
goto error;
}
strcpy(cmd->name, name);
- if (strlen(help) >= MAX_HELP_LEN - 1) {
+ if (strlen(help) >= MAX_HELP_LEN) {
ODPH_ERR("Error: command help too long\n");
goto error;
}
diff --git a/helper/cuckootable.c b/helper/cuckootable.c
deleted file mode 100644
index 85f715b3c..000000000
--- a/helper/cuckootable.c
+++ /dev/null
@@ -1,776 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2016-2018 Linaro Limited
- */
-
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <stdint.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include <odp/helper/odph_cuckootable.h>
-#include <odp/helper/odph_debug.h>
-#include <odp_api.h>
-
-/* More efficient access to a map of single ullong */
-#define ULLONG_FOR_EACH_1(IDX, MAP) \
- for (; MAP && (((IDX) = __builtin_ctzll(MAP)), true); \
- MAP = (MAP & (MAP - 1)))
-
-/** @magic word, write to the first byte of the memory block
- * to indicate this block is used by a cuckoo hash table
- */
-#define ODPH_CUCKOO_TABLE_MAGIC_WORD 0xDFDFFDFD
-
-/** Number of items per bucket. */
-#define HASH_BUCKET_ENTRIES 4
-
-#define NULL_SIGNATURE 0
-#define KEY_ALIGNMENT 16
-
-/** Maximum size of hash table that can be created. */
-#define HASH_ENTRIES_MAX 1048576
-
-/** @internal signature struct
- * Structure storing both primary and secondary hashes
- */
-struct cuckoo_table_signatures {
- union {
- struct {
- uint32_t current;
- uint32_t alt;
- };
- uint64_t sig;
- };
-};
-
-/** @internal kay-value struct
- * Structure that stores key-value pair
- */
-struct cuckoo_table_key_value {
- uint8_t *key;
- uint8_t *value;
-};
-
-/** @internal bucket structure
- * Put the elements with different keys but a same signature
- * into a bucket, and each bucket has at most HASH_BUCKET_ENTRIES
- * elements.
- */
-struct ODP_ALIGNED_CACHE cuckoo_table_bucket {
- struct cuckoo_table_signatures signatures[HASH_BUCKET_ENTRIES];
- /* Includes dummy key index that always contains index 0 */
- odp_buffer_t key_buf[HASH_BUCKET_ENTRIES + 1];
- uint8_t flag[HASH_BUCKET_ENTRIES];
-};
-
-/* More efficient access to a map of single ullong */
-#define ULLONG_FOR_EACH_1(IDX, MAP) \
- for (; MAP && (((IDX) = __builtin_ctzll(MAP)), true); \
- MAP = (MAP & (MAP - 1)))
-
-/** A hash table structure. */
-typedef struct ODP_ALIGNED_CACHE {
- /**< for check */
- uint32_t magicword;
- /**< Name of the hash. */
- char name[ODPH_TABLE_NAME_LEN];
- /**< Total table entries. */
- uint32_t entries;
- /**< Number of buckets in table. */
- uint32_t num_buckets;
- /**< Length of hash key. */
- uint32_t key_len;
- /**< Length of value. */
- uint32_t value_len;
- /**< Bitmask for getting bucket index from hash signature. */
- uint32_t bucket_bitmask;
- /**< Queue that stores all free key-value slots*/
- odp_queue_t free_slots;
- /** Table with buckets storing all the hash values and key indexes
- to the key table*/
- struct cuckoo_table_bucket *buckets;
-} odph_cuckoo_table_impl;
-
-/**
- * Aligns input parameter to the next power of 2
- *
- * @param x
- * The integer value to algin
- *
- * @return
- * Input parameter aligned to the next power of 2
- */
-static inline uint32_t
-align32pow2(uint32_t x)
-{
- x--;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
-
- return x + 1;
-}
-
-odph_table_t
-odph_cuckoo_table_lookup(const char *name)
-{
- odph_cuckoo_table_impl *tbl = NULL;
- odp_shm_t shm;
-
- if (name == NULL || strlen(name) >= ODPH_TABLE_NAME_LEN)
- return NULL;
-
- shm = odp_shm_lookup(name);
- if (shm != ODP_SHM_INVALID)
- tbl = (odph_cuckoo_table_impl *)odp_shm_addr(shm);
- if (!tbl || tbl->magicword != ODPH_CUCKOO_TABLE_MAGIC_WORD)
- return NULL;
-
- if (strcmp(tbl->name, name))
- return NULL;
-
- return (odph_table_t)tbl;
-}
-
-odph_table_t
-odph_cuckoo_table_create(
- const char *name, uint32_t capacity, uint32_t key_size,
- uint32_t value_size)
-{
- odph_cuckoo_table_impl *tbl;
- odp_shm_t shm_tbl;
-
- odp_pool_t pool;
- odp_pool_param_t param;
-
- odp_queue_t queue;
- odp_queue_param_t qparam;
- odp_queue_capability_t qcapa;
- odp_pool_capability_t pcapa;
-
- char pool_name[ODPH_TABLE_NAME_LEN + 3],
- queue_name[ODPH_TABLE_NAME_LEN + 3];
- unsigned i;
- uint32_t impl_size, kv_entry_size,
- bucket_num, bucket_size;
-
- if (odp_queue_capability(&qcapa)) {
- ODPH_DBG("queue capa failed\n");
- return NULL;
- }
-
- if (qcapa.plain.max_size && qcapa.plain.max_size < capacity) {
- ODPH_DBG("queue max_size too small\n");
- return NULL;
- }
-
- if (odp_pool_capability(&pcapa)) {
- ODPH_DBG("pool capa failed\n");
- return NULL;
- }
-
- if (pcapa.buf.max_num && pcapa.buf.max_num < capacity) {
- ODPH_DBG("pool max_num too small\n");
- return NULL;
- }
-
- /* Check for valid parameters */
- if (
- (capacity > HASH_ENTRIES_MAX) ||
- (capacity < HASH_BUCKET_ENTRIES) ||
- (key_size == 0) ||
- (strlen(name) == 0)) {
- ODPH_DBG("invalid parameters\n");
- return NULL;
- }
-
- /* Guarantee there's no existing */
- tbl = (odph_cuckoo_table_impl *)(void *)odph_cuckoo_table_lookup(name);
- if (tbl != NULL) {
- ODPH_DBG("cuckoo hash table %s already exists\n", name);
- return NULL;
- }
-
- /* Calculate the sizes of different parts of cuckoo hash table */
- impl_size = sizeof(odph_cuckoo_table_impl);
- kv_entry_size = sizeof(struct cuckoo_table_key_value)
- + key_size + value_size;
-
- bucket_num = align32pow2(capacity) / HASH_BUCKET_ENTRIES;
- bucket_size = bucket_num * sizeof(struct cuckoo_table_bucket);
-
- shm_tbl = odp_shm_reserve(name, impl_size + bucket_size,
- ODP_CACHE_LINE_SIZE, 0);
-
- if (shm_tbl == ODP_SHM_INVALID) {
- ODPH_DBG(
- "shm allocation failed for odph_cuckoo_table_impl %s\n",
- name);
- return NULL;
- }
-
- tbl = (odph_cuckoo_table_impl *)odp_shm_addr(shm_tbl);
- memset(tbl, 0, impl_size + bucket_size);
-
- /* header of this mem block is the table impl struct,
- * then the bucket pool.
- */
- tbl->buckets = (void *)((char *)tbl + impl_size);
-
- /* initialize key-value buffer pool */
- snprintf(pool_name, sizeof(pool_name), "kv_%s", name);
- pool = odp_pool_lookup(pool_name);
-
- if (pool != ODP_POOL_INVALID)
- if (odp_pool_destroy(pool)) {
- odp_shm_free(shm_tbl);
- ODPH_DBG("failed to destroy pre-existing pool\n");
- return NULL;
- }
-
- odp_pool_param_init(&param);
- param.type = ODP_POOL_BUFFER;
- param.buf.size = kv_entry_size;
- if (pcapa.buf.max_align >= ODP_CACHE_LINE_SIZE)
- param.buf.align = ODP_CACHE_LINE_SIZE;
- param.buf.num = capacity;
-
- pool = odp_pool_create(pool_name, &param);
-
- if (pool == ODP_POOL_INVALID) {
- ODPH_DBG("failed to create key-value pool\n");
- odp_shm_free(shm_tbl);
- return NULL;
- }
-
- /* initialize free_slots queue */
- odp_queue_param_init(&qparam);
- qparam.type = ODP_QUEUE_TYPE_PLAIN;
- qparam.size = capacity;
-
- snprintf(queue_name, sizeof(queue_name), "fs_%s", name);
- queue = odp_queue_create(queue_name, &qparam);
- if (queue == ODP_QUEUE_INVALID) {
- ODPH_DBG("failed to create free_slots queue\n");
- (void)odp_pool_destroy(pool);
- odp_shm_free(shm_tbl);
- return NULL;
- }
-
- /* Setup hash context */
- snprintf(tbl->name, sizeof(tbl->name), "%s", name);
- tbl->magicword = ODPH_CUCKOO_TABLE_MAGIC_WORD;
- tbl->entries = capacity;
- tbl->key_len = key_size;
- tbl->value_len = value_size;
- tbl->num_buckets = bucket_num;
- tbl->bucket_bitmask = bucket_num - 1;
- tbl->free_slots = queue;
-
- /* generate all free buffers, and put into queue */
- for (i = 0; i < capacity; i++) {
- odp_event_t ev = odp_buffer_to_event(
- odp_buffer_alloc(pool));
- if (ev == ODP_EVENT_INVALID) {
- ODPH_DBG("failed to generate free slots\n");
- odph_cuckoo_table_destroy((odph_table_t)tbl);
- return NULL;
- }
-
- if (odp_queue_enq(queue, ev) < 0) {
- ODPH_DBG("failed to enqueue free slots\n");
- odph_cuckoo_table_destroy((odph_table_t)tbl);
- return NULL;
- }
- }
-
- return (odph_table_t)tbl;
-}
-
-int
-odph_cuckoo_table_destroy(odph_table_t tbl)
-{
- int ret;
- odph_cuckoo_table_impl *impl = NULL;
- char pool_name[ODPH_TABLE_NAME_LEN + 3];
- odp_event_t ev;
- odp_shm_t shm;
- odp_pool_t pool;
- uint32_t i, j;
-
- if (tbl == NULL)
- return -1;
-
- impl = (odph_cuckoo_table_impl *)(void *)tbl;
-
- /* check magic word */
- if (impl->magicword != ODPH_CUCKOO_TABLE_MAGIC_WORD) {
- ODPH_DBG("wrong magicword for cuckoo table\n");
- return -1;
- }
-
- /* free all used buffers*/
- for (i = 0; i < impl->num_buckets; i++) {
- for (j = 0; j < HASH_BUCKET_ENTRIES; j++) {
- if (impl->buckets[i].signatures[j].current
- != NULL_SIGNATURE)
- odp_buffer_free(impl->buckets[i].key_buf[j]);
- }
- }
-
- /* free all free buffers */
- while ((ev = odp_queue_deq(impl->free_slots))
- != ODP_EVENT_INVALID) {
- odp_buffer_free(odp_buffer_from_event(ev));
- }
-
- /* destroy free_slots queue */
- ret = odp_queue_destroy(impl->free_slots);
- if (ret < 0)
- ODPH_DBG("failed to destroy free_slots queue\n");
-
- /* destroy key-value pool */
- snprintf(pool_name, sizeof(pool_name), "kv_%s", impl->name);
- pool = odp_pool_lookup(pool_name);
- if (pool == ODP_POOL_INVALID) {
- ODPH_DBG("invalid pool\n");
- return -1;
- }
-
- ret = odp_pool_destroy(pool);
- if (ret != 0) {
- ODPH_DBG("failed to destroy key-value buffer pool\n");
- return -1;
- }
-
- /* free impl */
- shm = odp_shm_lookup(impl->name);
- if (shm == ODP_SHM_INVALID) {
- ODPH_DBG("unable look up shm\n");
- return -1;
- }
-
- return odp_shm_free(shm);
-}
-
-static uint32_t hash(const odph_cuckoo_table_impl *h, const void *key)
-{
- /* calc hash result by key */
- return odp_hash_crc32c(key, h->key_len, 0);
-}
-
-/* Calc the secondary hash value from the primary hash value of a given key */
-static inline uint32_t
-hash_secondary(const uint32_t primary_hash)
-{
- static const unsigned all_bits_shift = 12;
- static const unsigned alt_bits_xor = 0x5bd1e995;
-
- uint32_t tag = primary_hash >> all_bits_shift;
-
- return (primary_hash ^ ((tag + 1) * alt_bits_xor));
-}
-
-/* Search for an entry that can be pushed to its alternative location */
-static inline int
-make_space_bucket(
- const odph_cuckoo_table_impl *impl,
- struct cuckoo_table_bucket *bkt)
-{
- unsigned i, j;
- int ret;
- uint32_t next_bucket_idx;
- struct cuckoo_table_bucket *next_bkt[HASH_BUCKET_ENTRIES];
-
- /*
- * Push existing item (search for bucket with space in
- * alternative locations) to its alternative location
- */
- for (i = 0; i < HASH_BUCKET_ENTRIES; i++) {
- /* Search for space in alternative locations */
- next_bucket_idx = bkt->signatures[i].alt & impl->bucket_bitmask;
- next_bkt[i] = &impl->buckets[next_bucket_idx];
- for (j = 0; j < HASH_BUCKET_ENTRIES; j++) {
- if (next_bkt[i]->signatures[j].sig == NULL_SIGNATURE)
- break;
- }
-
- if (j != HASH_BUCKET_ENTRIES)
- break;
- }
-
- /* Alternative location has spare room (end of recursive function) */
- if (i != HASH_BUCKET_ENTRIES) {
- next_bkt[i]->signatures[j].alt = bkt->signatures[i].current;
- next_bkt[i]->signatures[j].current = bkt->signatures[i].alt;
- next_bkt[i]->key_buf[j] = bkt->key_buf[i];
- return i;
- }
-
- /* Pick entry that has not been pushed yet */
- for (i = 0; i < HASH_BUCKET_ENTRIES; i++)
- if (bkt->flag[i] == 0)
- break;
-
- /* All entries have been pushed, so entry cannot be added */
- if (i == HASH_BUCKET_ENTRIES)
- return -ENOSPC;
-
- /* Set flag to indicate that this entry is going to be pushed */
- bkt->flag[i] = 1;
- /* Need room in alternative bucket to insert the pushed entry */
- ret = make_space_bucket(impl, next_bkt[i]);
- /*
- * After recursive function.
- * Clear flags and insert the pushed entry
- * in its alternative location if successful,
- * or return error
- */
- bkt->flag[i] = 0;
- if (ret >= 0) {
- next_bkt[i]->signatures[ret].alt = bkt->signatures[i].current;
- next_bkt[i]->signatures[ret].current = bkt->signatures[i].alt;
- next_bkt[i]->key_buf[ret] = bkt->key_buf[i];
- return i;
- }
-
- return ret;
-}
-
-static inline int32_t
-cuckoo_table_add_key_with_hash(
- const odph_cuckoo_table_impl *h, const void *key,
- uint32_t sig, void *data)
-{
- uint32_t alt_hash;
- uint32_t prim_bucket_idx, sec_bucket_idx;
- unsigned i;
- struct cuckoo_table_bucket *prim_bkt, *sec_bkt;
- struct cuckoo_table_key_value *new_kv, *kv;
-
- odp_buffer_t new_buf;
- int ret;
-
- prim_bucket_idx = sig & h->bucket_bitmask;
- prim_bkt = &h->buckets[prim_bucket_idx];
- __builtin_prefetch((const void *)(uintptr_t)prim_bkt, 0, 3);
-
- alt_hash = hash_secondary(sig);
- sec_bucket_idx = alt_hash & h->bucket_bitmask;
- sec_bkt = &h->buckets[sec_bucket_idx];
- __builtin_prefetch((const void *)(uintptr_t)sec_bkt, 0, 3);
-
- /* Get a new slot for storing the new key */
- new_buf = odp_buffer_from_event(odp_queue_deq(h->free_slots));
- if (new_buf == ODP_BUFFER_INVALID)
- return -ENOSPC;
-
- /* Check if key is already inserted in primary location */
- for (i = 0; i < HASH_BUCKET_ENTRIES; i++) {
- if (
- prim_bkt->signatures[i].current == sig &&
- prim_bkt->signatures[i].alt == alt_hash) {
- kv = (struct cuckoo_table_key_value *)odp_buffer_addr(
- prim_bkt->key_buf[i]);
- if (memcmp(key, kv->key, h->key_len) == 0) {
- odp_queue_enq(
- h->free_slots,
- odp_buffer_to_event(new_buf));
- /* Update data */
- if (kv->value != NULL)
- memcpy(kv->value, data, h->value_len);
-
- /* Return bucket index */
- return prim_bucket_idx;
- }
- }
- }
-
- /* Check if key is already inserted in secondary location */
- for (i = 0; i < HASH_BUCKET_ENTRIES; i++) {
- if (
- sec_bkt->signatures[i].alt == sig &&
- sec_bkt->signatures[i].current == alt_hash) {
- kv = (struct cuckoo_table_key_value *)odp_buffer_addr(
- sec_bkt->key_buf[i]);
- if (memcmp(key, kv->key, h->key_len) == 0) {
- odp_queue_enq(
- h->free_slots,
- odp_buffer_to_event(new_buf));
- /* Update data */
- if (kv->value != NULL)
- memcpy(kv->value, data, h->value_len);
-
- /* Return bucket index */
- return sec_bucket_idx;
- }
- }
- }
-
- new_kv = (struct cuckoo_table_key_value *)odp_buffer_addr(new_buf);
- __builtin_prefetch((const void *)(uintptr_t)new_kv, 0, 3);
-
- /* Copy key and value.
- * key-value mem block : struct cuckoo_table_key_value
- * + key (key_len) + value (value_len)
- */
- new_kv->key = (uint8_t *)new_kv
- + sizeof(struct cuckoo_table_key_value);
- memcpy(new_kv->key, key, h->key_len);
-
- if (h->value_len > 0) {
- new_kv->value = new_kv->key + h->key_len;
- memcpy(new_kv->value, data, h->value_len);
- } else {
- new_kv->value = NULL;
- }
-
- /* Insert new entry is there is room in the primary bucket */
- for (i = 0; i < HASH_BUCKET_ENTRIES; i++) {
- /* Check if slot is available */
- if (odp_likely(prim_bkt->signatures[i].sig == NULL_SIGNATURE)) {
- prim_bkt->signatures[i].current = sig;
- prim_bkt->signatures[i].alt = alt_hash;
- prim_bkt->key_buf[i] = new_buf;
- return prim_bucket_idx;
- }
- }
-
- /* Primary bucket is full, so we need to make space for new entry */
- ret = make_space_bucket(h, prim_bkt);
-
- /*
- * After recursive function.
- * Insert the new entry in the position of the pushed entry
- * if successful or return error and
- * store the new slot back in the pool
- */
- if (ret >= 0) {
- prim_bkt->signatures[ret].current = sig;
- prim_bkt->signatures[ret].alt = alt_hash;
- prim_bkt->key_buf[ret] = new_buf;
- return prim_bucket_idx;
- }
-
- /* Error in addition, store new slot back in the free_slots */
- odp_queue_enq(h->free_slots, odp_buffer_to_event(new_buf));
- return ret;
-}
-
-int
-odph_cuckoo_table_put_value(odph_table_t tbl, void *key, void *value)
-{
- odph_cuckoo_table_impl *impl;
- int ret;
-
- if ((tbl == NULL) || (key == NULL))
- return -EINVAL;
-
- impl = (odph_cuckoo_table_impl *)(void *)tbl;
- ret = cuckoo_table_add_key_with_hash(
- impl, key, hash(impl, key), value);
-
- if (ret < 0)
- return -1;
-
- return 0;
-}
-
-static inline int32_t
-cuckoo_table_lookup_with_hash(
- const odph_cuckoo_table_impl *h, const void *key,
- uint32_t sig, void **data_ptr)
-{
- uint32_t bucket_idx;
- uint32_t alt_hash;
- unsigned i;
- struct cuckoo_table_bucket *bkt;
- struct cuckoo_table_key_value *kv;
-
- bucket_idx = sig & h->bucket_bitmask;
- bkt = &h->buckets[bucket_idx];
-
- /* Check if key is in primary location */
- for (i = 0; i < HASH_BUCKET_ENTRIES; i++) {
- if (
- bkt->signatures[i].current == sig &&
- bkt->signatures[i].sig != NULL_SIGNATURE) {
- kv = (struct cuckoo_table_key_value *)odp_buffer_addr(
- bkt->key_buf[i]);
- if (memcmp(key, kv->key, h->key_len) == 0) {
- if (data_ptr != NULL)
- *data_ptr = kv->value;
- /*
- * Return index where key is stored,
- * subtracting the first dummy index
- */
- return bucket_idx;
- }
- }
- }
-
- /* Calculate secondary hash */
- alt_hash = hash_secondary(sig);
- bucket_idx = alt_hash & h->bucket_bitmask;
- bkt = &h->buckets[bucket_idx];
-
- /* Check if key is in secondary location */
- for (i = 0; i < HASH_BUCKET_ENTRIES; i++) {
- if (
- bkt->signatures[i].current == alt_hash &&
- bkt->signatures[i].alt == sig) {
- kv = (struct cuckoo_table_key_value *)odp_buffer_addr(
- bkt->key_buf[i]);
- if (memcmp(key, kv->key, h->key_len) == 0) {
- if (data_ptr != NULL)
- *data_ptr = kv->value;
- /*
- * Return index where key is stored,
- * subtracting the first dummy index
- */
- return bucket_idx;
- }
- }
- }
-
- return -ENOENT;
-}
-
-int odph_cuckoo_table_get_value(odph_table_t tbl, void *key,
- void *buffer, uint32_t buffer_size ODP_UNUSED)
-{
- odph_cuckoo_table_impl *impl = (odph_cuckoo_table_impl *)(void *)tbl;
- void *tmp = NULL;
- int ret;
-
- if ((tbl == NULL) || (key == NULL))
- return -EINVAL;
-
- ret = cuckoo_table_lookup_with_hash(impl, key, hash(impl, key), &tmp);
-
- if (ret < 0)
- return -1;
-
- if (impl->value_len > 0)
- memcpy(buffer, tmp, impl->value_len);
-
- return 0;
-}
-
-static inline int32_t
-cuckoo_table_del_key_with_hash(
- const odph_cuckoo_table_impl *h,
- const void *key, uint32_t sig)
-{
- uint32_t bucket_idx;
- uint32_t alt_hash;
- unsigned i;
- struct cuckoo_table_bucket *bkt;
- struct cuckoo_table_key_value *kv;
-
- bucket_idx = sig & h->bucket_bitmask;
- bkt = &h->buckets[bucket_idx];
-
- /* Check if key is in primary location */
- for (i = 0; i < HASH_BUCKET_ENTRIES; i++) {
- if (
- bkt->signatures[i].current == sig &&
- bkt->signatures[i].sig != NULL_SIGNATURE) {
- kv = (struct cuckoo_table_key_value *)odp_buffer_addr(
- bkt->key_buf[i]);
- if (memcmp(key, kv->key, h->key_len) == 0) {
- bkt->signatures[i].sig = NULL_SIGNATURE;
- odp_queue_enq(
- h->free_slots,
- odp_buffer_to_event(
- bkt->key_buf[i]));
- return bucket_idx;
- }
- }
- }
-
- /* Calculate secondary hash */
- alt_hash = hash_secondary(sig);
- bucket_idx = alt_hash & h->bucket_bitmask;
- bkt = &h->buckets[bucket_idx];
-
- /* Check if key is in secondary location */
- for (i = 0; i < HASH_BUCKET_ENTRIES; i++) {
- if (
- bkt->signatures[i].current == alt_hash &&
- bkt->signatures[i].sig != NULL_SIGNATURE) {
- kv = (struct cuckoo_table_key_value *)odp_buffer_addr(
- bkt->key_buf[i]);
- if (memcmp(key, kv->key, h->key_len) == 0) {
- bkt->signatures[i].sig = NULL_SIGNATURE;
- odp_queue_enq(
- h->free_slots,
- odp_buffer_to_event(
- bkt->key_buf[i]));
- return bucket_idx;
- }
- }
- }
-
- return -ENOENT;
-}
-
-int
-odph_cuckoo_table_remove_value(odph_table_t tbl, void *key)
-{
- odph_cuckoo_table_impl *impl = (void *)tbl;
- int ret;
-
- if ((tbl == NULL) || (key == NULL))
- return -EINVAL;
-
- ret = cuckoo_table_del_key_with_hash(impl, key, hash(impl, key));
- if (ret < 0)
- return -1;
-
- return 0;
-}
-
-odph_table_ops_t odph_cuckoo_table_ops = {
- odph_cuckoo_table_create,
- odph_cuckoo_table_lookup,
- odph_cuckoo_table_destroy,
- odph_cuckoo_table_put_value,
- odph_cuckoo_table_get_value,
- odph_cuckoo_table_remove_value
-};
diff --git a/helper/hashtable.c b/helper/hashtable.c
deleted file mode 100644
index 28c23a58c..000000000
--- a/helper/hashtable.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Linaro Limited
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <malloc.h>
-
-#include <odp/helper/odph_hashtable.h>
-#include <odp/helper/odph_debug.h>
-#include "odph_list_internal.h"
-#include <odp_api.h>
-
-#define ODPH_SUCCESS 0
-#define ODPH_FAIL -1
-
-/** @magic word, write to the first byte of the memory block
- * to indicate this block is used by a hash table structure
- */
-#define ODPH_HASH_TABLE_MAGIC_WORD 0xABABBABA
-
-/** @support 64k buckets. Bucket is a list that composed of
- * elements with the same HASH-value but different keys
- */
-#define ODPH_MAX_BUCKET_NUM 0x10000
-
-/** @inner element structure of hash table
- * To resolve the hash conflict:
- * we put the elements with different keys but a same HASH-value
- * into a list
- */
-typedef struct odph_hash_node {
- /** list structure,for list opt */
- odph_list_object list_node;
- /** Flexible Array,memory will be alloced when table has been created
- * Its length is key_size + value_size,
- * suppose key_size = m; value_size = n;
- * its structure is like:
- * k_byte1 k_byte2...k_byten v_byte1...v_bytem
- */
- char content[];
-} odph_hash_node;
-
-typedef struct {
- uint32_t magicword; /**< for check */
- uint32_t key_size; /**< input param when create,in Bytes */
- uint32_t value_size; /**< input param when create,in Bytes */
- uint32_t init_cap; /**< input param when create,in Bytes */
- /** multi-process support,every list has one rw lock */
- odp_rwlock_t *lock_pool;
- /** table bucket pool,every hash value has one list head */
- odph_list_head *list_head_pool;
- /** number of the list head in list_head_pool */
- uint32_t head_num;
- /** table element pool */
- odph_hash_node *hash_node_pool;
- /** number of element in the hash_node_pool */
- uint32_t hash_node_num;
- char rsv[7]; /**< Reserved,for alignment */
- char name[ODPH_TABLE_NAME_LEN]; /**< table name */
-} odph_hash_table_imp;
-
-odph_table_t odph_hash_table_create(const char *name, uint32_t capacity,
- uint32_t key_size,
- uint32_t value_size)
-{
- int i;
- uint32_t node_num;
- odph_hash_table_imp *tbl;
- odp_shm_t shmem;
- uint32_t node_mem;
-
- if (strlen(name) >= ODPH_TABLE_NAME_LEN || capacity < 1 ||
- capacity >= 0x1000 || key_size == 0 || value_size == 0) {
- ODPH_DBG("create para input error!\n");
- return NULL;
- }
- if (odp_shm_lookup(name) != ODP_SHM_INVALID) {
- ODPH_DBG("name already exist\n");
- return NULL;
- }
- shmem = odp_shm_reserve(name, capacity << 20, 64, 0);
- if (shmem == ODP_SHM_INVALID) {
- ODPH_DBG("shm reserve fail\n");
- return NULL;
- }
- tbl = (odph_hash_table_imp *)odp_shm_addr(shmem);
-
- /* clean this block of memory */
- memset(tbl, 0, capacity << 20);
-
- tbl->init_cap = capacity << 20;
- strncpy(tbl->name, name, ODPH_TABLE_NAME_LEN - 1);
- tbl->key_size = key_size;
- tbl->value_size = value_size;
-
- /* header of this mem block is the table control struct,
- * then the lock pool, then the list header pool
- * the last part is the element node pool
- */
-
- tbl->lock_pool = (odp_rwlock_t *)(void *)((char *)tbl
- + sizeof(odph_hash_table_imp));
- tbl->list_head_pool = (odph_list_head *)(void *)((char *)tbl->lock_pool
- + ODPH_MAX_BUCKET_NUM * sizeof(odp_rwlock_t));
-
- node_mem = tbl->init_cap - sizeof(odph_hash_table_imp)
- - ODPH_MAX_BUCKET_NUM * sizeof(odph_list_head)
- - ODPH_MAX_BUCKET_NUM * sizeof(odp_rwlock_t);
-
- node_num = node_mem / (sizeof(odph_hash_node) + key_size + value_size);
- tbl->hash_node_num = node_num;
- tbl->hash_node_pool =
- (odph_hash_node *)(void *)((char *)tbl->list_head_pool
- + ODPH_MAX_BUCKET_NUM * sizeof(odph_list_head));
-
- /* init every list head and rw lock */
- for (i = 0; i < ODPH_MAX_BUCKET_NUM; i++) {
- ODPH_INIT_LIST_HEAD(&tbl->list_head_pool[i]);
- odp_rwlock_init((odp_rwlock_t *)&tbl->lock_pool[i]);
- }
-
- tbl->magicword = ODPH_HASH_TABLE_MAGIC_WORD;
- return (odph_table_t)tbl;
-}
-
-int odph_hash_table_destroy(odph_table_t table)
-{
- int ret;
-
- if (table != NULL) {
- odph_hash_table_imp *hash_tbl;
-
- hash_tbl = (odph_hash_table_imp *)(void *)table;
- if (hash_tbl->magicword != ODPH_HASH_TABLE_MAGIC_WORD)
- return ODPH_FAIL;
-
- ret = odp_shm_free(odp_shm_lookup(hash_tbl->name));
- if (ret != 0) {
- ODPH_DBG("free fail\n");
- return ret;
- }
- /* clean head */
- return ODPH_SUCCESS;
- }
- return ODPH_FAIL;
-}
-
-odph_table_t odph_hash_table_lookup(const char *name)
-{
- odph_hash_table_imp *hash_tbl = NULL;
- odp_shm_t shm;
-
- if (name == NULL || strlen(name) >= ODPH_TABLE_NAME_LEN)
- return NULL;
-
- shm = odp_shm_lookup(name);
- if (shm != ODP_SHM_INVALID)
- hash_tbl = (odph_hash_table_imp *)odp_shm_addr(shm);
- if (hash_tbl != NULL && strcmp(hash_tbl->name, name) == 0)
- return (odph_table_t)hash_tbl;
- return NULL;
-}
-
-/**
- * Calculate has value by the input key and key_size
- * This hash algorithm is the most simple one, so we choose it as an DEMO
- * User can use any other algorithm, like CRC...
- */
-static uint16_t odp_key_hash(void *key, uint32_t key_size)
-{
- register uint32_t hash = 0;
- uint32_t idx = (key_size == 0 ? 1 : key_size);
- uint32_t ch;
-
- while (idx != 0) {
- ch = (uint32_t)(*(char *)key);
- hash = hash * 131 + ch;
- idx--;
- }
- return (uint16_t)(hash & 0x0000FFFF);
-}
-
-/**
- * Get an available node from pool
- */
-static odph_hash_node *hashnode_take(odph_table_t table)
-{
- odph_hash_table_imp *tbl;
- uint32_t idx;
- odph_hash_node *node;
-
- tbl = (odph_hash_table_imp *)(void *)table;
- for (idx = 0; idx < tbl->hash_node_num; idx++) {
- /** notice: memory of one hash_node is
- * not only sizeof(odph_hash_node)
- * should add the size of Flexible Array
- */
- node = (odph_hash_node *)(void *)((char *)tbl->hash_node_pool
- + idx * (sizeof(odph_hash_node)
- + tbl->key_size
- + tbl->value_size));
- if (node->list_node.next == NULL &&
- node->list_node.prev == NULL) {
- ODPH_INIT_LIST_HEAD(&node->list_node);
- return node;
- }
- }
- return NULL;
-}
-
-/**
- * Release an node to the pool
- */
-static void hashnode_give(odph_table_t table, odph_hash_node *node)
-{
- odph_hash_table_imp *tbl;
-
- if (node == NULL)
- return;
-
- tbl = (odph_hash_table_imp *)(void *)table;
-
- odph_list_del(&node->list_node);
- memset(node, 0,
- (sizeof(odph_hash_node) + tbl->key_size + tbl->value_size));
-}
-
-/* should make sure the input table exists and is available */
-int odph_hash_put_value(odph_table_t table, void *key, void *value)
-{
- odph_hash_table_imp *tbl;
- uint16_t hash = 0;
- odph_hash_node *node = NULL;
- char *tmp = NULL;
-
- if (table == NULL || key == NULL || value == NULL)
- return ODPH_FAIL;
-
- tbl = (odph_hash_table_imp *)(void *)table;
- /* hash value is just the index of the list head in pool */
- hash = odp_key_hash(key, tbl->key_size);
-
- odp_rwlock_write_lock(&tbl->lock_pool[hash]);
- /* First, check if the key already exist */
- ODPH_LIST_FOR_EACH(node, &tbl->list_head_pool[hash], odph_hash_node,
- list_node)
- {
- if (memcmp(node->content, key, tbl->key_size) == 0) {
- /* copy value content to hash node*/
- tmp = (void *)((char *)node->content + tbl->key_size);
- memcpy(tmp, value, tbl->value_size);
- odp_rwlock_write_unlock(&tbl->lock_pool[hash]);
- return ODPH_SUCCESS;
- }
- }
-
- /*if the key is a new one, get a new hash node form the pool */
- node = hashnode_take(table);
- if (node == NULL) {
- odp_rwlock_write_unlock(&tbl->lock_pool[hash]);
- return ODPH_FAIL;
- }
-
- /* copy both key and value content to the hash node */
- memcpy(node->content, key, tbl->key_size);
- tmp = (void *)((char *)node->content + tbl->key_size);
- memcpy(tmp, value, tbl->value_size);
-
- /* add the node to list */
- odph_list_add(&node->list_node, &tbl->list_head_pool[hash]);
-
- odp_rwlock_write_unlock(&tbl->lock_pool[hash]);
- return ODPH_SUCCESS;
-}
-
-/* should make sure the input table exists and is available */
-int odph_hash_get_value(odph_table_t table, void *key, void *buffer,
- uint32_t buffer_size)
-{
- odph_hash_table_imp *tbl;
- uint16_t hash = 0;
- odph_hash_node *node;
- char *tmp = NULL;
-
- tbl = (odph_hash_table_imp *)(void *)table;
-
- if (table == NULL || key == NULL || buffer == NULL ||
- buffer_size < tbl->value_size)
- return ODPH_FAIL;
-
- /* hash value is just the index of the list head in pool */
- hash = odp_key_hash(key, tbl->key_size);
-
- odp_rwlock_read_lock(&tbl->lock_pool[hash]);
-
- ODPH_LIST_FOR_EACH(node, &tbl->list_head_pool[hash],
- odph_hash_node, list_node)
- {
- /* in case of hash conflict, compare the whole key */
- if (memcmp(node->content, key, tbl->key_size) == 0) {
- /* find the target */
- tmp = (void *)((char *)node->content + tbl->key_size);
- memcpy(buffer, tmp, tbl->value_size);
-
- odp_rwlock_read_unlock(&tbl->lock_pool[hash]);
-
- return ODPH_SUCCESS;
- }
- }
-
- odp_rwlock_read_unlock(&tbl->lock_pool[hash]);
-
- return ODPH_FAIL;
-}
-
-/* should make sure the input table exists and is available */
-int odph_hash_remove_value(odph_table_t table, void *key)
-{
- odph_hash_table_imp *tbl;
- uint16_t hash = 0;
- odph_hash_node *node;
-
- if (table == NULL || key == NULL)
- return ODPH_FAIL;
-
- tbl = (odph_hash_table_imp *)(void *)table;
-
- /* hash value is just the index of the list head in pool */
- hash = odp_key_hash(key, tbl->key_size);
-
- odp_rwlock_write_lock(&tbl->lock_pool[hash]);
-
- ODPH_LIST_FOR_EACH(node, &tbl->list_head_pool[hash], odph_hash_node,
- list_node)
- {
- if (memcmp(node->content, key, tbl->key_size) == 0) {
- hashnode_give(table, node);
- odp_rwlock_write_unlock(&tbl->lock_pool[hash]);
- return ODPH_SUCCESS;
- }
- }
-
- odp_rwlock_write_unlock(&tbl->lock_pool[hash]);
-
- return ODPH_SUCCESS;
-}
-
-odph_table_ops_t odph_hash_table_ops = {
- odph_hash_table_create,
- odph_hash_table_lookup,
- odph_hash_table_destroy,
- odph_hash_put_value,
- odph_hash_get_value,
- odph_hash_remove_value};
-
diff --git a/helper/include/odp/helper/odph_debug.h b/helper/include/odp/helper/debug.h
index 41b425ab2..41b425ab2 100644
--- a/helper/include/odp/helper/odph_debug.h
+++ b/helper/include/odp/helper/debug.h
diff --git a/helper/include/odp/helper/odph_api.h b/helper/include/odp/helper/odph_api.h
index 94d43a61b..2541efa89 100644
--- a/helper/include/odp/helper/odph_api.h
+++ b/helper/include/odp/helper/odph_api.h
@@ -18,23 +18,20 @@ extern "C" {
#include <odp/helper/autoheader_external.h>
-#include <odp/helper/odph_debug.h>
#include <odp/helper/chksum.h>
-#include <odp/helper/odph_cuckootable.h>
+#include <odp/helper/debug.h>
#include <odp/helper/eth.h>
#include <odp/helper/gtp.h>
-#include <odp/helper/odph_hashtable.h>
#include <odp/helper/icmp.h>
#include <odp/helper/igmp.h>
#include <odp/helper/ip.h>
#include <odp/helper/ipsec.h>
#include <odp/helper/macros.h>
-#include <odp/helper/odph_lineartable.h>
-#include <odp/helper/odph_iplookuptable.h>
+#include <odp/helper/stress.h>
#include <odp/helper/sctp.h>
+#include <odp/helper/string.h>
#include <odp/helper/strong_types.h>
#include <odp/helper/tcp.h>
-#include <odp/helper/table.h>
#include <odp/helper/threads.h>
#include <odp/helper/udp.h>
#include <odp/helper/version.h>
diff --git a/helper/include/odp/helper/odph_cuckootable.h b/helper/include/odp/helper/odph_cuckootable.h
deleted file mode 100644
index 1c87a3d42..000000000
--- a/helper/include/odp/helper/odph_cuckootable.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2016-2018 Linaro Limited
- */
-
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ODPH_CUCKOO_TABLE_H_
-#define ODPH_CUCKOO_TABLE_H_
-
-#include <odp/helper/table.h>
-
-/**
- * @file
- *
- * ODP Cuckoo Hash Table
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @defgroup odph_cuckootable ODPH CUCKOO TABLE
- * Cuckoo table
- *
- * @{
- */
-
-/**
- * Create a cuckoo table
- *
- * @param name Name of the cuckoo table to be created
- * @param capacity Number of elements table may store
- * @param key_size Size of the key for each element
- * @param value_size Size of the value stored for each element
- *
- * @return Handle of created cuckoo table
- * @retval NULL Create failed
- */
-odph_table_t odph_cuckoo_table_create(
- const char *name,
- uint32_t capacity,
- uint32_t key_size,
- uint32_t value_size);
-
-/**
- * Lookup a cuckoo table by name
- *
- * @param name Name of the table to be located
- *
- * @return Handle of the located cuckoo table
- * @retval NULL No table matching supplied name found
- */
-odph_table_t odph_cuckoo_table_lookup(const char *name);
-
-/**
- * Destroy a cuckoo table
- *
- * @param table Handle of the cuckoo table to be destroyed
- *
- * @retval 0 Success
- * @retval < 0 Failure
- */
-int odph_cuckoo_table_destroy(odph_table_t table);
-
-/**
- * Insert a key/value pair into a cuckoo table
- *
- * @param table Table into which value is to be stored
- * @param key Address of an odph_table_t to be used as key
- * @param value Value to be associated with specified key
- *
- * @retval >= 0 Success
- * @retval < 0 Failure
- */
-int odph_cuckoo_table_put_value(odph_table_t table, void *key, void *value);
-
-/**
- * Retrieve a value from a cuckoo table
- *
- * @param table Table from which value is to be retrieved
- * @param key Address of an odph_table_t to be used as key
- * @param[out] buffer Address of buffer to receive resulting value
- * @param buffer_size Size of supplied buffer
- *
- * @retval 0 Success
- * @retval 1 Success
- * @retval < 0 Failure
- */
-int odph_cuckoo_table_get_value(odph_table_t table,
- void *key, void *buffer,
- uint32_t buffer_size);
-
-/**
- * Remove a value from a cuckoo table
- *
- * @param table Table from which value is to be removed
- * @param key Address of odph_table_t to be used as key
- *
- * @retval >= 0 Success
- * @retval < 0 Failure
- */
-int odph_cuckoo_table_remove_value(odph_table_t table, void *key);
-
-extern odph_table_ops_t odph_cuckoo_table_ops; /**< @internal */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ODPH_CUCKOO_TABLE_H_ */
diff --git a/helper/include/odp/helper/odph_hashtable.h b/helper/include/odp/helper/odph_hashtable.h
deleted file mode 100644
index b2dd21920..000000000
--- a/helper/include/odp/helper/odph_hashtable.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Linaro Limited
- */
-
-/**
- * @file
- *
- * ODP Hash Table
- */
-
-#ifndef ODPH_HASH_TABLE_H_
-#define ODPH_HASH_TABLE_H_
-
-#include <odp/helper/table.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @defgroup odph_hash_table ODPH HASH TABLE
- * Hash table
- *
- * @{
- */
-
-/**
- * Create a hash table
- *
- * @param name Name of the hash table to be created.
- * @param capacity Number of elements table may store
- * @param key_size Size of the key for each element
- * @param value_size Size of the value stored for each element
- *
- * @return Handle of created hash table
- * @retval NULL Create failed
- */
-odph_table_t odph_hash_table_create(const char *name,
- uint32_t capacity,
- uint32_t key_size,
- uint32_t value_size);
-
-/**
- * Lookup a hash table by name
- *
- * @param name Name of the table to be located
- *
- * @return Handle of the located hash table
- * @return NULL No table matching supplied name found
- */
-odph_table_t odph_hash_table_lookup(const char *name);
-
-/**
- * Destroy a hash table
- *
- * @param table Handle of the hash table to be destroyed
- *
- * @retval 0 Success
- * @retval < 0 Failure
- */
-int odph_hash_table_destroy(odph_table_t table);
-
-/**
- * Insert a key/value pair into a hash table
- *
- * @param table Table into which value is to be stored
- * @param key Address of an odph_table_t to be used as key
- * @param value Value to be associated with specified key
- *
- * @retval >= 0 Success
- * @retval < 0 Failure
- */
-int odph_hash_put_value(odph_table_t table, void *key, void *value);
-
-/**
- * Retrieve a value from a hash table
- *
- * @param table Table from which value is to be retrieved
- * @param key Address of an odph_table_t to be used as key
- * @param[out] buffer Address of buffer to receive resulting value
- * @param buffer_size Size of supplied buffer
- *
- * @retval 0 Success
- * @retval 1 Success
- * @retval < 0 Failure
- */
-int odph_hash_get_value(odph_table_t table, void *key, void *buffer,
- uint32_t buffer_size);
-
-/**
- * Remove a value from a hash table
- *
- * @param table Table from which value is to be removed
- * @param key Address of odph_table_t to be used as key
- *
- * @retval >= 0 Success
- * @retval < 0 Failure
- */
-int odph_hash_remove_value(odph_table_t table, void *key);
-
-extern odph_table_ops_t odph_hash_table_ops; /**< @internal */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/helper/include/odp/helper/odph_iplookuptable.h b/helper/include/odp/helper/odph_iplookuptable.h
deleted file mode 100644
index 41235ecc6..000000000
--- a/helper/include/odp/helper/odph_iplookuptable.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2016-2018 Linaro Limited
- */
-
-/**
- * @file
- *
- * ODP IP Lookup Table
- */
-
-#ifndef ODPH_IPLOOKUP_TABLE_H_
-#define ODPH_IPLOOKUP_TABLE_H_
-
-#include <odp/helper/table.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @defgroup odph_iplookuptable ODPH IP LOOKUP TABLE
- * IP lookup table
- *
- * @details
- * This is an implementation of the IP lookup table. The key of this table is
- * IPv4 address (32 bits), and the value can be defined by user. This table uses
- * the 16,8,8 ip lookup (longest prefix matching) algorithm.
- *
- * @{
- */
-
-/**
- * IP Lookup Prefix
- */
-typedef struct {
- uint32_t ip; /**< IPv4 address */
- uint8_t cidr; /**< CIDR value for prefix matching */
-} odph_iplookup_prefix_t;
-
-/**
- * Create an IP lookup table
- *
- * @param name Name of the table to be created
- * @param ODP_IGNORED_1 Unused
- * @param ODP_IGNORED_2 Unused
- * @param value_size Byte size of each entry in the table
- *
- * @return Handle of the created ip lookup table
- * @retval NULL If table create failed
- */
-odph_table_t odph_iplookup_table_create(const char *name,
- uint32_t ODP_IGNORED_1,
- uint32_t ODP_IGNORED_2,
- uint32_t value_size);
-
-/**
- * Lookup an IP lookup table by name
- *
- * @param name Name of the table to be located
- *
- * @return Handle of the located ip lookup table
- * @retval NULL No table matching supplied name found
- */
-odph_table_t odph_iplookup_table_lookup(const char *name);
-
-/**
- * Destroy an IP lookup table
- *
- * @param table Handle of the ip lookup table to be destroyed
- *
- * @retval 0 Success
- * @retval < 0 Failure
- */
-int odph_iplookup_table_destroy(odph_table_t table);
-
-/**
- * Insert a key/value pair into an ip lookup table
- *
- * @param table Table into which value is to be stored
- * @param key Address of an odph_iplookup_prefix_t to be used as key
- * @param value Value to be associated with specified key
- *
- * @retval >= 0 Success
- * @retval < 0 Failure
- */
-int odph_iplookup_table_put_value(odph_table_t table, void *key, void *value);
-
-/**
- * Retrieve a value from an iplookup table
- *
- * @param table Table from which value is to be retrieved
- * @param key Address of an odph_iplookup_prefix_t to be used as key
- * @param[out] buffer Address of buffer to receive resulting value
- * @param buffer_size Size of supplied buffer
- *
- * @retval 0 Success
- * @retval 1 Success
- * @retval < 0 Failure
- */
-int odph_iplookup_table_get_value(odph_table_t table, void *key,
- void *buffer, uint32_t buffer_size);
-
-/**
- * Remove a value from an iplookup table
- *
- * @param table Table from which value is to be removed
- * @param key Address of odph_iplookup_prefix_t to be used as key
- *
- * @retval >= 0 Success
- * @retval < 0 Failure
- *
- */
-int odph_iplookup_table_remove_value(odph_table_t table, void *key);
-
-extern odph_table_ops_t odph_iplookup_table_ops; /**< @internal */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ODPH_IPLOOKUP_TABLE_H_ */
diff --git a/helper/include/odp/helper/odph_lineartable.h b/helper/include/odp/helper/odph_lineartable.h
deleted file mode 100644
index dc61113a5..000000000
--- a/helper/include/odp/helper/odph_lineartable.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Linaro Limited
- */
-
-/**
- * @file
- *
- * ODP Linear Table
- */
-
-#ifndef ODPH_LINEAR_TABLE_H_
-#define ODPH_LINEAR_TABLE_H_
-
-#include <stdint.h>
-#include <odp/helper/table.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @defgroup odph_lineartable ODPH LINEAR TABLE
- * Linear table
- *
- * @{
- */
-
-/**
- * Create a linear table
- *
- * @param name Name of the linear table to be created
- * @param capacity Number of elements table may store
- * @param ODP_IGNORED Ignored parameter
- * @param value_size Size of the value stored for each element
- *
- * @return Handle of created linear table
- * @return NULL Create failed
- */
-odph_table_t odph_linear_table_create(const char *name,
- uint32_t capacity,
- uint32_t ODP_IGNORED,
- uint32_t value_size);
-
-/**
- * Lookup a linear table
- *
- * @param name Name of the table to be located
- *
- * @return Handle of the located linear table
- * @retval NULL No table matching supplied name found
- */
-odph_table_t odph_linear_table_lookup(const char *name);
-
-/**
- * Destroy a linear table
- *
- * @param table Handle of linear table to be destroyed
- *
- * @retval 0 Success
- * @retval < 0 Failure
- */
-int odph_linear_table_destroy(odph_table_t table);
-
-/**
- * Insert a value into a linear table
- *
- * @param table Table into which value is to be stored
- * @param key Index value used as key
- * @param value Value to be assoceiated with specified key index
- *
- * @retval >= 0 Success
- * @retval < 0 Failure
- */
-int odph_linear_put_value(odph_table_t table, void *key, void *value);
-
-/**
- * Retrieve a value from a linear table
- *
- * @param table Table from which value is to be retrieved
- * @param key Index value used as key
- * @param[out] buffer Address of buffer to receive resulting value
- * @param buffer_size Size of supplied buffer
- *
- * @retval 0 Success
- * @retval 1 Success
- * @retval < 0 Failure
- */
-int odph_linear_get_value(odph_table_t table, void *key, void *buffer,
- uint32_t buffer_size);
-
-extern odph_table_ops_t odph_linear_table_ops; /**< @internal */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/helper/include/odp/helper/stress.h b/helper/include/odp/helper/stress.h
new file mode 100644
index 000000000..cfdc41033
--- /dev/null
+++ b/helper/include/odp/helper/stress.h
@@ -0,0 +1,238 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2024 Nokia
+ */
+
+/**
+ * @file
+ *
+ * ODP helper stress
+ */
+
+#ifndef ODPH_STRESS_H_
+#define ODPH_STRESS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup odph_stress ODPH STRESS
+ * Dummy CPU stress functions
+ *
+ * These functions may be used in test applications to create dummy CPU load. Functions are not
+ * highly optimized, as they try to utilize various parts of CPU instruction set (load/store,
+ * branch, integer/float arithmetics, vector, etc. instructions).
+ *
+ * @{
+ */
+
+/**
+ * Returns 'value' raised to the power of 2
+ *
+ * @param value Base value
+ *
+ * @return The value raised to the power of 2
+ */
+static inline uint32_t odph_stress_pow2_u32(uint32_t value)
+{
+ uint64_t v = (uint64_t)value;
+ uint64_t res = v * v;
+
+ if (odp_unlikely(res > UINT32_MAX))
+ return UINT32_MAX;
+
+ return (uint32_t)res;
+}
+
+/**
+ * Returns base 2 logarithm of 'value'
+ *
+ * @param value The value for which the logarithm is being calculated
+ *
+ * @return Base 2 logarithm of 'value'
+ */
+static inline uint32_t odph_stress_log2_u32(uint32_t value)
+{
+ uint32_t ret = 0;
+
+ while ((value >>= 1) != 0)
+ ret++;
+
+ return ret;
+}
+
+/**
+ * Calculates square root of a 32-bit unsigned integer value
+ *
+ * @param value The value for which the square root is being calculated
+ *
+ * @return Square root of the value
+ */
+static inline uint32_t odph_stress_sqrt_u32(uint32_t value)
+{
+ uint64_t x;
+ uint64_t pow = 1;
+
+ if (odp_unlikely(value == 0 || value == 1))
+ return value;
+
+ if (value & 0xffff0000) {
+ if (value & 0xff000000) {
+ if (value & 0xf0000000) {
+ x = 16384;
+ if (value & 0xe0000000)
+ x = 23170;
+ if (value & 0xc0000000)
+ x = 32768;
+ if (value & 0x80000000)
+ x = 46340;
+ } else {
+ /* value & 0x0f000000 */
+ x = 4096;
+ if (value & 0x0e000000)
+ x = 5792;
+ if (value & 0x0c000000)
+ x = 8192;
+ if (value & 0x08000000)
+ x = 11585;
+ }
+ } else {
+ if (value & 0x00f00000) {
+ x = 1024;
+ if (value & 0x00e00000)
+ x = 1448;
+ if (value & 0x00c00000)
+ x = 2048;
+ if (value & 0x00800000)
+ x = 2896;
+ } else {
+ /* value & 0x000f0000 */
+ x = 256;
+ if (value & 0x000e0000)
+ x = 362;
+ if (value & 0x000c0000)
+ x = 512;
+ if (value & 0x00080000)
+ x = 724;
+ }
+ }
+ } else {
+ /* value & 0xffff */
+ x = 1;
+
+ if (value >= 16384) {
+ x = 128;
+ if (value >= 25600)
+ x = 160;
+ if (value >= 36864)
+ x = 192;
+ if (value >= 50176)
+ x = 224;
+ } else {
+ if (value >= 1024)
+ x = 32;
+ if (value >= 4096)
+ x = 64;
+ if (value >= 9216)
+ x = 96;
+ }
+ }
+
+ while (pow <= value) {
+ x++;
+ pow = x * x;
+ }
+
+ return (uint32_t)(x - 1);
+}
+
+/**
+ * Calculates square root of a floating point value
+ *
+ * @param value The value for which the square root is being calculated
+ *
+ * @return Square root of the value
+ */
+static inline float odph_stress_sqrt_f32(float value)
+{
+ double x;
+ double pow = 1;
+
+ if (odp_unlikely(value == 0 || value == 1))
+ return value;
+
+ if (value >= 65536) {
+ if (value >= 16777215) {
+ if (value >= 268435456) {
+ x = 16384;
+ if (value >= 536870912)
+ x = 23170;
+ if (value >= 1073741824)
+ x = 32768;
+ if (value >= 2147483648)
+ x = 46340;
+ } else {
+ x = 4096;
+ if (value >= 33554432)
+ x = 5792;
+ if (value >= 67108864)
+ x = 8192;
+ if (value >= 134217728)
+ x = 11585;
+ }
+ } else {
+ if (value >= 1048576) {
+ x = 1024;
+ if (value >= 2097152)
+ x = 1448;
+ if (value >= 4194304)
+ x = 2048;
+ if (value >= 8388608)
+ x = 2896;
+ } else {
+ x = 256;
+ if (value >= 131072)
+ x = 362;
+ if (value >= 262144)
+ x = 512;
+ if (value >= 524288)
+ x = 724;
+ }
+ }
+ } else {
+ x = 1;
+
+ if (value >= 16384) {
+ x = 128;
+ if (value >= 25600)
+ x = 160;
+ if (value >= 36864)
+ x = 192;
+ if (value >= 50176)
+ x = 224;
+ } else {
+ if (value >= 1024)
+ x = 32;
+ if (value >= 4096)
+ x = 64;
+ if (value >= 9216)
+ x = 96;
+ }
+ }
+
+ while (pow <= value) {
+ x = x + 1;
+ pow = x * x;
+ }
+
+ return (float)(x - 1);
+}
+
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/helper/include/odp/helper/string.h b/helper/include/odp/helper/string.h
new file mode 100644
index 000000000..da2d61a6b
--- /dev/null
+++ b/helper/include/odp/helper/string.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2024 Nokia
+ */
+
+/**
+ * @file
+ *
+ * ODP string helper
+ */
+
+#ifndef ODPH_STRING_H_
+#define ODPH_STRING_H_
+
+#include <odp/api/hints.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup odph_string ODPH STRING
+ * String helper
+ *
+ * @{
+ */
+
+/**
+ * Copy a string
+ *
+ * Like strncpy(), but additionally ensures that the destination string is null
+ * terminated, unless sz is zero in which case returns dst without doing
+ * anything else.
+ *
+ * @param[out] dst Pointer to destination string.
+ * @param src Pointer to source string.
+ * @param sz Destination size.
+ * @return Pointer to destination string.
+ */
+#ifdef __cplusplus
+ODP_UNUSED static char *odph_strcpy(char *dst, const char *src, size_t sz)
+#else
+ODP_UNUSED static char *odph_strcpy(char *restrict dst, const char *restrict src, size_t sz)
+#endif
+{
+ if (!sz)
+ return dst;
+
+ strncpy(dst, src, sz - 1);
+ dst[sz - 1] = 0;
+ return dst;
+}
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/helper/include/odp/helper/table.h b/helper/include/odp/helper/table.h
deleted file mode 100644
index 6a24e742b..000000000
--- a/helper/include/odp/helper/table.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Linaro Limited
- */
-
-/**
- * @file
- *
- * ODP table
- */
-
-#ifndef ODPH_TABLE_H_
-#define ODPH_TABLE_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @defgroup odph_tables ODPH TABLES
- * Table interface
- *
- * @details
- * TCAM(Ternary Content Addressable Memory) is used widely in packet
- * forwarding to speedup the table lookup.
- *
- * This file contains a simple interface for creating and using the table.
- * Table here means a collection of related data held in a structured
- * format.
- * Some examples for table are ARP Table, Routing Table, etc.The table
- * contains many entries, each consist of key and associated data
- * (called key/value pair or rule/action pair in some paper.).
- * Enclosed are some classical table examples, used publicly
- * in data plane packet processing:
- *
- * <H3>Use Case: ARP table</H3>
- * Once a route has been identified for an IP packet (so the output
- * interface and the IP address of the next hop station are known),
- * the MAC address of the next hop station is needed in order to
- * send this packet onto the next leg of the journey
- * towards its destination (as identified by its destination IP address).
- * The MAC address of the next hop station becomes the destination
- * MAC address of the outgoing Ethernet frame.
- * <ol>
- * <li>Key: The pair of (Output interface, Next Hop IP address)
- * <li>Associated Data: MAC address of the next hop station
- * <li>Algorithm: Hash
- * </ol>
- *
- * <H3>Use Case: Routing Table</H3>
- * When each router receives a packet, it searches its routing table
- * to find the best match between the destination IP address of
- * the packet and one of the network addresses in the routing table.
- * <ol>
- * <li>Key: destination IP address
- * <li>Associated Data: The pair of (Output interface, Next Hop IP address)
- * <li>Algorithm: LPM(Longest Prefix Match)
- * </ol>
- *
- * <H3>Use Case: Flow Classification</H3>
- * The flow classification is executed at least once for each
- * input packet.This operation maps each incoming packet against
- * one of the known traffic
- * flows in the flow database that typically contains millions of flows.
- * <ol>
- * <li>Key:n-tuple of packet fields that uniquely identify a traffic flow.
- * <li>Associated data:
- * actions and action meta-data describing what processing to be
- * applied for the packets of the current flow, such as whether
- * encryption/decryption is required on this packet, what kind of cipher
- * algorithm should be chosen.
- * <li>Algorithm: Hash
- * </ol>
- *
- * All these different types of lookup tables have the common operations:
- * create a table, destroy a table, add (key,associated data),
- * delete key and look up the associated data via the key.
- * Usually these operations are software based, but also can be
- * hardware accelerated such as using TCAM to implement ARP table
- * or Routing Table.
- * And specific alogithm can be used for specific lookup table.
- *
- * notes: key/value and key/associated data mean the same thing
- * in this file unless otherwise mentioned.
- *
- * @{
- */
-
-#include <stdint.h>
-
-/**
- * @def ODPH_TABLE_NAME_LEN
- * Max length of table name
- */
-#define ODPH_TABLE_NAME_LEN 32
-
-#include <odp/helper/strong_types.h>
-/** @internal ODPH table handle @return */
-typedef ODPH_HANDLE_T(odph_table_t);
-
-/**
-* create a table
-* Generally, tables only support key-value pair both with fixed size
-*
-* @param name
-* name of this table, max ODPH_TABLE_NAME_LEN - 1
-* May be specified as NULL for anonymous table
-* @param capacity
-* Max memory usage this table use, in MBytes
-* @param key_size
-* fixed size of the 'key' in bytes.
-* @param value_size
-* fixed size of the 'value' in bytes.
-* @return
-* Handle to table instance or NULL if failed
-* @note
-*/
-typedef odph_table_t (*odph_table_create)(const char *name,
- uint32_t capacity,
- uint32_t key_size,
- uint32_t value_size);
-
-/**
- * Find a table by name
- *
- * @param name Name of the table
- *
- * @return Handle of found table
- * @retval NULL table could not be found
- *
- * @note This routine cannot be used to look up an anonymous
- * table (one created with no name).
- * This API supports Multiprocess
- */
-typedef odph_table_t (*odph_table_lookup)(const char *name);
-
-/**
- * Destroy a table previously created by odph_table_create()
- *
- * @param table Handle of the table to be destroyed
- *
- * @retval 0 Success
- * @retval -1 Failure
- *
- * @note This routine destroys a previously created pool
- * also should free any memory allocated at creation
- *
- */
-typedef int (*odph_table_destroy)(odph_table_t table);
-
-/**
- * Add (key,associated data) pair into the specific table.
- * When no associated data is currently associated with key,
- * then the (key,assocatied data) association is created.
- * When key is already associated with data0, then association (key, data0)
- * will be removed and association (key, associated data) is created.
- *
- * @param table Handle of the table that the element be added
- *
- * @param key address of 'key' in key-value pair.
- * User should make sure the address and 'key_size'
- * bytes after are accessible
- * @param value address of 'value' in key-value pair
- * User should make sure the address and 'value_size'
- * bytes after are accessible
- * @retval 0 Success
- * @retval -1 Failure
- * @note Add a same key again with a new value, the older one will
- * be covered.
- */
-typedef int (*odph_table_put_value)(odph_table_t table, void *key,
- void *value);
-
-/**
- * Lookup the associated data via specific key.
- * When no value is currently associated with key, then this operation
- * restuns <0 to indicate the lookup miss.
- * When key is associated with value,
- * then this operation returns value.
- * The (key,value) association won't change.
- *
- * @param table Handle of the table that the element be added
- *
- * @param key address of 'key' in key-value pair
- * User should make sure the address and key_size bytes after
- * are accessible
- *
- * @param buffer output The buffer address to the 'value'
- * After successfully found, the content of 'value' will be
- * copied to this address
- * User should make sure the address and value_size bytes
- * after are accessible
- * @param buffer_size size of the buffer
- * should be equal or bigger than value_size
- * @retval 0 Success
- * @retval -1 Failure
- *
- * @note
- */
-typedef int (*odph_table_get_value)(odph_table_t table, void *key,
- void *buffer,
- uint32_t buffer_size);
-/**
- * Delete the association specified by key
- * When no data is currently associated with key, this operation
- * has no effect. When key is already associated data ad0,
- * then (key,ad0) pair is deleted.
- *
- * @param table Handle of the table that the element will be removed from
- *
- * @param key address of 'key' in key-value pair
- * User should make sure the address and key_size bytes after
- * are accessible
- *
- * @retval 0 Success
- * @retval -1 Failure
- *
- * @note
- */
-typedef int (*odph_table_remove_value)(odph_table_t table, void *key);
-
-/**
- * Table interface set. Defining the table operations.
- */
-typedef struct odph_table_ops_t {
- odph_table_create f_create; /**< Table Create */
- odph_table_lookup f_lookup; /**< Table Lookup */
- odph_table_destroy f_des; /**< Table Destroy */
- /** add (key,associated data) pair into the specific table */
- odph_table_put_value f_put;
- /** lookup the associated data via specific key */
- odph_table_get_value f_get;
- /** delete the association specified by key */
- odph_table_remove_value f_remove;
-} odph_table_ops_t;
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/helper/include/odp/helper/threads.h b/helper/include/odp/helper/threads.h
index c18a46e8a..ca420e80a 100644
--- a/helper/include/odp/helper/threads.h
+++ b/helper/include/odp/helper/threads.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2013-2018 Linaro Limited
- * Copyright (c) 2019-2021 Nokia
+ * Copyright (c) 2019-2024 Nokia
*/
@@ -191,6 +191,20 @@ typedef struct {
} odph_thread_common_param_t;
+/** Thread join result */
+typedef struct {
+ /** Exit caused by signal */
+ odp_bool_t is_sig;
+
+ /**
+ * Exit status of the joined thread/process
+ *
+ * If 'is_sig' is true, then this is the signal number that caused
+ * process exit. Otherwise status of the exited thread/process.
+ */
+ int ret;
+} odph_thread_join_result_t;
+
/**
* Initialize thread params
*
@@ -236,7 +250,8 @@ void odph_thread_common_param_init(odph_thread_common_param_t *param);
* thread goes to the smallest CPU number of the mask, etc.
*
* Launched threads may be waited for exit with odph_thread_join(), or with
- * direct Linux system calls.
+ * direct Linux system calls. If odph_thread_join() is used, the output thread
+ * table elements must not be modified during the life time of the threads.
*
* @param[out] thread Thread table for output
* @param param Common parameters for all threads to be created
@@ -261,10 +276,14 @@ int odph_thread_create(odph_thread_t thread[],
* A function call may be used to wait any number of launched threads to exit.
* A particular thread may be waited only once.
*
+ * Threads are joined in the order they are in 'thread' table. Returns on the
+ * first non-zero exit status or other failure.
+ *
* @param thread Table of threads to exit
* @param num Number of threads to exit
*
- * @return Number of threads exited
+ * @return Number of threads successfully joined with zero exit status
+ * (0 ... num)
* @retval -1 On failure
*
* @see odph_thread_create()
@@ -272,6 +291,26 @@ int odph_thread_create(odph_thread_t thread[],
int odph_thread_join(odph_thread_t thread[], int num);
/**
+ * Wait previously launched threads to exit
+ *
+ * Similar to odph_thread_join() but outputs results of joined threads and
+ * stops only if the actual join operation fails for some thread. Threads are
+ * joined in the order they are in 'thread' table. Returns number of threads
+ * successfully joined and writes respective exit statuses into the 'res'
+ * table.
+ *
+ * @param thread Table of threads to exit
+ * @param[out] res Table for result output
+ * @param num Number of threads to exit and results to output
+ *
+ * @return Number of threads successfully joined (0 ... num)
+ * @retval -1 On failure
+ *
+ * @see odph_thread_create()
+ */
+int odph_thread_join_result(odph_thread_t thread[], odph_thread_join_result_t res[], int num);
+
+/**
* Set CPU affinity of the current odp thread
*
* CPU affinity determines the CPU core on which the thread is
diff --git a/helper/include/odph_list_internal.h b/helper/include/odph_list_internal.h
deleted file mode 100644
index d90b07ebc..000000000
--- a/helper/include/odph_list_internal.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Linaro Limited
- */
-
-/**
- * @file
- *
- * ODP list
- * a simple implementation of Doubly linked list
- */
-
-#ifndef ODPH_LIST_INTER_H_
-#define ODPH_LIST_INTER_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** @cond _ODP_HIDE_FROM_DOXYGEN_ */
-
-typedef struct odph_list_object {
- struct odph_list_object *next;
-
- struct odph_list_object *prev;
-} odph_list_object;
-
-typedef odph_list_object odph_list_head;
-
-static inline void ODPH_INIT_LIST_HEAD(odph_list_object *list)
-{
- list->next = list;
- list->prev = list;
-}
-
-static inline void __odph_list_add(odph_list_object *new,
- odph_list_object *prev,
- odph_list_object *next)
-{
- next->prev = new;
- new->next = next;
- new->prev = prev;
- prev->next = new;
-}
-
-static inline void odph_list_add(odph_list_object *new, odph_list_object *head)
-{
- __odph_list_add(new, head, head->next);
-}
-
-static inline void odph_list_add_tail(struct odph_list_object *new,
- odph_list_object *head)
-{
- __odph_list_add(new, head->prev, head);
-}
-
-static inline void __odph_list_del(struct odph_list_object *prev,
- odph_list_object *next)
-{
- next->prev = prev;
- prev->next = next;
-}
-
-static inline void odph_list_del(struct odph_list_object *entry)
-{
- __odph_list_del(entry->prev, entry->next);
- ODPH_INIT_LIST_HEAD(entry);
-}
-
-static inline int odph_list_empty(const struct odph_list_object *head)
-{
- return head->next == head;
-}
-
-#define container_of(ptr, type, list_node) \
- ((type *)(void *)((char *)ptr - offsetof(type, list_node)))
-
-#define ODPH_LIST_FOR_EACH(pos, list_head, type, list_node) \
- for (pos = container_of((list_head)->next, type, list_node); \
- &pos->list_node != (list_head); \
- pos = container_of(pos->list_node.next, type, list_node))
-
-/** @endcond */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/helper/iplookuptable.c b/helper/iplookuptable.c
deleted file mode 100644
index 31273a0a5..000000000
--- a/helper/iplookuptable.c
+++ /dev/null
@@ -1,990 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2016-2018 Linaro Limited
- */
-
-#include <string.h>
-#include <stdint.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include <odp/helper/odph_iplookuptable.h>
-#include <odp/helper/odph_debug.h>
-#include "odph_list_internal.h"
-#include <odp_api.h>
-
-/** @magic word, write to the first byte of the memory block
- * to indicate this block is used by a ip lookup table
- */
-#define ODPH_IP_LOOKUP_TABLE_MAGIC_WORD 0xCFCFFCFC
-
-/* The length(bit) of the IPv4 address */
-#define IP_LENGTH 32
-
-/* The number of L1 entries */
-#define ENTRY_NUM_L1 (1 << 16)
-/* The size of one L2\L3 subtree */
-#define ENTRY_NUM_SUBTREE (1 << 8)
-
-#define WHICH_CHILD(ip, cidr) ((ip >> (IP_LENGTH - cidr)) & 0x00000001)
-
-/** @internal entry struct
- * Structure store an entry of the ip prefix table.
- * Because of the leaf pushing, each entry of the table must have
- * either a child entry, or a nexthop info.
- * If child == 0 and index != ODP_BUFFER_INVALID, this entry has
- * a nexthop info, index indicates the buffer that stores the
- * nexthop value, and ptr points to the address of the buffer.
- * If child == 1, this entry has a subtree, index indicates
- * the buffer that stores the subtree, and ptr points to the
- * address of the buffer.
- */
-typedef struct {
- union {
- odp_buffer_t nexthop;
- void *ptr;
- };
- union {
- uint8_t u8;
- struct {
-#if ODP_BYTE_ORDER == ODP_BIG_ENDIAN
- uint8_t child : 1;
- uint8_t cidr : 7;
-#else
- uint8_t cidr : 7;
- uint8_t child : 1;
-#endif
- };
- };
-} prefix_entry_t;
-
-#define ENTRY_SIZE (sizeof(prefix_entry_t) + sizeof(odp_buffer_t))
-#define ENTRY_BUFF_ARR(x) ((odp_buffer_t *)(void *)((char *)x \
- + sizeof(prefix_entry_t) * ENTRY_NUM_SUBTREE))
-
-/** @internal trie node struct
- * In this IP lookup algorithm, we use a
- * binary tire to detect the overlap prefix.
- */
-typedef struct trie_node {
- /* tree structure */
- struct trie_node *parent;
- struct trie_node *left;
- struct trie_node *right;
- /* IP prefix length */
- uint8_t cidr;
- /* Nexthop buffer index */
- odp_buffer_t nexthop;
- /* Buffer that stores this node */
- odp_buffer_t buffer;
-} trie_node_t;
-
-/** Number of L2\L3 entries(subtrees) per cache cube. */
-#define CACHE_NUM_SUBTREE (4 * 1024)
-/** Number of trie nodes per cache cube. */
-#define CACHE_NUM_TRIE (4 * 1024)
-
-/** @typedef cache_type_t
- * Cache node type
- */
-typedef enum {
- CACHE_TYPE_SUBTREE = 0,
- CACHE_TYPE_TRIE
-} cache_type_t;
-
-/** A IP lookup table structure. */
-typedef struct ODP_ALIGNED_CACHE {
- /**< for check */
- uint32_t magicword;
- /** Name of the hash. */
- char name[ODPH_TABLE_NAME_LEN];
- /** Total L1 entries. */
- prefix_entry_t *l1e;
- /** Root node of the binary trie */
- trie_node_t *trie;
- /** Length of value. */
- uint32_t nexthop_len;
- /** Queues of free slots (caches)
- * There are two queues:
- * - free_slots[CACHE_TYPE_SUBTREE] is used for L2 and
- * L3 entries (subtrees). Each entry stores an 8-bit
- * subtree.
- * - free_slots[CACHE_TYPE_TRIE] is used for the binary
- * trie. Each entry contains a trie node.
- */
- odp_queue_t free_slots[2];
- /** The number of pool used by each queue. */
- uint32_t cache_count[2];
-} odph_iplookup_table_impl;
-
-/***********************************************************
- ***************** Cache management ********************
- ***********************************************************/
-
-/** Destroy all caches */
-static void
-cache_destroy(odph_iplookup_table_impl *impl)
-{
- odp_queue_t queue;
- odp_event_t ev;
- uint32_t i = 0, count = 0;
- char pool_name[ODPH_TABLE_NAME_LEN + 8];
-
- /* free all buffers in the queue */
- for (; i < 2; i++) {
- queue = impl->free_slots[i];
- if (queue == ODP_QUEUE_INVALID)
- continue;
-
- while ((ev = odp_queue_deq(queue))
- != ODP_EVENT_INVALID) {
- odp_buffer_free(odp_buffer_from_event(ev));
- }
- odp_queue_destroy(queue);
- }
-
- /* destroy all cache pools */
- for (i = 0; i < 2; i++) {
- for (count = 0; count < impl->cache_count[i]; count++) {
- sprintf(
- pool_name, "%s_%d_%d",
- impl->name, i, count);
- (void)odp_pool_destroy(odp_pool_lookup(pool_name));
- }
- }
-}
-
-/** According to the type of cache, set the value of
- * a buffer to the initial value.
- */
-static void
-cache_init_buffer(odp_buffer_t buffer, cache_type_t type, uint32_t size)
-{
- int i = 0;
- void *addr = odp_buffer_addr(buffer);
-
- memset(addr, 0, size);
- if (type == CACHE_TYPE_SUBTREE) {
- prefix_entry_t *entry = (prefix_entry_t *)addr;
-
- for (i = 0; i < ENTRY_NUM_SUBTREE; i++, entry++)
- entry->nexthop = ODP_BUFFER_INVALID;
- } else if (type == CACHE_TYPE_TRIE) {
- trie_node_t *node = (trie_node_t *)addr;
-
- node->buffer = buffer;
- node->nexthop = ODP_BUFFER_INVALID;
- }
-}
-
-/** Create a new buffer pool, and insert its buffer into the queue. */
-static int
-cache_alloc_new_pool(
- odph_iplookup_table_impl *tbl, cache_type_t type)
-{
- odp_pool_t pool;
- odp_pool_param_t param;
- odp_pool_capability_t pool_capa;
- odp_queue_t queue = tbl->free_slots[type];
-
- odp_buffer_t buffer;
- char pool_name[ODPH_TABLE_NAME_LEN + 8];
- uint32_t size = 0, num = 0;
-
- if (odp_pool_capability(&pool_capa)) {
- ODPH_ERR("pool capa failed\n");
- return -1;
- }
-
- if (pool_capa.buf.max_num) {
- if (pool_capa.buf.max_num < CACHE_NUM_TRIE ||
- pool_capa.buf.max_num < CACHE_NUM_SUBTREE) {
- ODPH_ERR("pool size too small\n");
- return -1;
- }
- }
-
- if (pool_capa.buf.max_size) {
- if (pool_capa.buf.max_size < ENTRY_SIZE * ENTRY_NUM_SUBTREE ||
- pool_capa.buf.max_size < sizeof(trie_node_t)) {
- ODPH_ERR("buffer size too small\n");
- return -1;
- }
- }
-
- /* Create new pool (new free buffers). */
- odp_pool_param_init(&param);
- param.type = ODP_POOL_BUFFER;
- if (pool_capa.buf.max_align >= ODP_CACHE_LINE_SIZE)
- param.buf.align = ODP_CACHE_LINE_SIZE;
- if (type == CACHE_TYPE_SUBTREE) {
- num = CACHE_NUM_SUBTREE;
- size = ENTRY_SIZE * ENTRY_NUM_SUBTREE;
- } else if (type == CACHE_TYPE_TRIE) {
- num = CACHE_NUM_TRIE;
- size = sizeof(trie_node_t);
- } else {
- ODPH_DBG("wrong cache_type_t.\n");
- return -1;
- }
- param.buf.size = size;
- param.buf.num = num;
-
- sprintf(
- pool_name, "%s_%d_%d",
- tbl->name, type, tbl->cache_count[type]);
- pool = odp_pool_create(pool_name, &param);
- if (pool == ODP_POOL_INVALID) {
- ODPH_DBG("failed to create a new pool.\n");
- return -1;
- }
-
- /* insert new free buffers into queue */
- while ((buffer = odp_buffer_alloc(pool))
- != ODP_BUFFER_INVALID) {
- cache_init_buffer(buffer, type, size);
- if (odp_queue_enq(queue, odp_buffer_to_event(buffer))) {
- ODPH_DBG("queue enqueue failed\n");
- odp_buffer_free(buffer);
- break;
- }
- }
-
- tbl->cache_count[type]++;
- return 0;
-}
-
-/** Get a new buffer from a cache list. If there is no
- * available buffer, allocate a new pool.
- */
-static odp_buffer_t
-cache_get_buffer(odph_iplookup_table_impl *tbl, cache_type_t type)
-{
- odp_buffer_t buffer = ODP_BUFFER_INVALID;
- odp_queue_t queue = tbl->free_slots[type];
-
- /* get free buffer from queue */
- buffer = odp_buffer_from_event(
- odp_queue_deq(queue));
-
- /* If there is no free buffer available, allocate new pool */
- if (buffer == ODP_BUFFER_INVALID) {
- cache_alloc_new_pool(tbl, type);
- buffer = odp_buffer_from_event(odp_queue_deq(queue));
- }
-
- return buffer;
-}
-
-/***********************************************************
- ****************** Binary trie ********************
- ***********************************************************/
-
-/* Initialize the root node of the trie */
-static int
-trie_init(odph_iplookup_table_impl *tbl)
-{
- trie_node_t *root = NULL;
- odp_buffer_t buffer = cache_get_buffer(tbl, CACHE_TYPE_TRIE);
-
- if (buffer != ODP_BUFFER_INVALID) {
- root = (trie_node_t *)odp_buffer_addr(buffer);
- root->cidr = 0;
- tbl->trie = root;
- return 0;
- }
-
- return -1;
-}
-
-/* Destroy the whole trie (recursively) */
-static void
-trie_destroy(odph_iplookup_table_impl *tbl, trie_node_t *trie)
-{
- if (trie->left != NULL)
- trie_destroy(tbl, trie->left);
- if (trie->right != NULL)
- trie_destroy(tbl, trie->right);
-
- /* destroy this node */
- odp_queue_enq(
- tbl->free_slots[CACHE_TYPE_TRIE],
- odp_buffer_to_event(trie->buffer));
-}
-
-/* Insert a new prefix node into the trie
- * If the node is already existed, update its nexthop info,
- * Return 0 and set nexthop pointer to INVALID.
- * If the node is not exitsed, create this target node and
- * all nodes along the path from root to the target node.
- * Then return 0 and set nexthop pointer points to the
- * new buffer.
- * Return -1 for error.
- */
-static int
-trie_insert_node(
- odph_iplookup_table_impl *tbl, trie_node_t *root,
- uint32_t ip, uint8_t cidr, odp_buffer_t nexthop)
-{
- uint8_t level = 0, child;
- odp_buffer_t buf;
- trie_node_t *node = root, *prev = root;
-
- /* create/update all nodes along the path
- * from root to the new node. */
- for (level = 1; level <= cidr; level++) {
- child = WHICH_CHILD(ip, level);
-
- node = child == 0 ? prev->left : prev->right;
- /* If the child node doesn't exit, create it. */
- if (node == NULL) {
- buf = cache_get_buffer(tbl, CACHE_TYPE_TRIE);
- if (buf == ODP_BUFFER_INVALID)
- return -1;
-
- node = (trie_node_t *)odp_buffer_addr(buf);
- node->cidr = level;
- node->parent = prev;
-
- if (child == 0)
- prev->left = node;
- else
- prev->right = node;
- }
- prev = node;
- }
-
- /* The final one is the target. */
- node->nexthop = nexthop;
- return 0;
-}
-
-/* Delete a node */
-static int
-trie_delete_node(
- odph_iplookup_table_impl *tbl,
- trie_node_t *root, uint32_t ip, uint8_t cidr)
-{
- if (root == NULL)
- return -1;
-
- /* The default prefix (root node) cannot be deleted. */
- if (cidr == 0)
- return -1;
-
- trie_node_t *node = root, *prev = NULL;
- uint8_t level = 1, child = 0;
- odp_buffer_t tmp;
-
- /* Find the target node. */
- for (level = 1; level <= cidr; level++) {
- child = WHICH_CHILD(ip, level);
- node = (child == 0) ? node->left : node->right;
- if (node == NULL) {
- ODPH_DBG("Trie node is not existed\n");
- return -1;
- }
- }
-
- node->nexthop = ODP_BUFFER_INVALID;
-
- /* Delete all redundant nodes along the path. */
- for (level = cidr; level > 0; level--) {
- if (
- node->left != NULL || node->right != NULL ||
- node->nexthop != ODP_BUFFER_INVALID)
- break;
-
- child = WHICH_CHILD(ip, level);
- prev = node->parent;
-
- /* free trie node */
- tmp = node->buffer;
- cache_init_buffer(
- tmp, CACHE_TYPE_TRIE, sizeof(trie_node_t));
- odp_queue_enq(
- tbl->free_slots[CACHE_TYPE_TRIE],
- odp_buffer_to_event(tmp));
-
- if (child == 0)
- prev->left = NULL;
- else
- prev->right = NULL;
- node = prev;
- }
- return 0;
-}
-
-/* Detect the longest overlapping prefix. */
-static int
-trie_detect_overlap(
- trie_node_t *trie, uint32_t ip, uint8_t cidr,
- uint8_t leaf_push, uint8_t *over_cidr,
- odp_buffer_t *over_nexthop)
-{
- uint8_t child = 0;
- uint32_t level, limit = cidr > leaf_push ? leaf_push + 1 : cidr;
- trie_node_t *node = trie, *longest = trie;
-
- for (level = 1; level < limit; level++) {
- child = WHICH_CHILD(ip, level);
- node = (child == 0) ? node->left : node->right;
- if (node->nexthop != ODP_BUFFER_INVALID)
- longest = node;
- }
-
- *over_cidr = longest->cidr;
- *over_nexthop = longest->nexthop;
- return 0;
-}
-
-/***********************************************************
- *************** IP prefix lookup table ****************
- ***********************************************************/
-
-odph_table_t
-odph_iplookup_table_lookup(const char *name)
-{
- odph_iplookup_table_impl *tbl = NULL;
- odp_shm_t shm;
-
- if (name == NULL || strlen(name) >= ODPH_TABLE_NAME_LEN)
- return NULL;
-
- shm = odp_shm_lookup(name);
- if (shm != ODP_SHM_INVALID)
- tbl = (odph_iplookup_table_impl *)odp_shm_addr(shm);
-
- if (
- tbl != NULL &&
- tbl->magicword == ODPH_IP_LOOKUP_TABLE_MAGIC_WORD &&
- strcmp(tbl->name, name) == 0)
- return (odph_table_t)tbl;
-
- return NULL;
-}
-
-odph_table_t odph_iplookup_table_create(const char *name,
- uint32_t p1 ODP_UNUSED,
- uint32_t p2 ODP_UNUSED,
- uint32_t value_size)
-{
- odph_iplookup_table_impl *tbl;
- odp_shm_t shm_tbl;
- odp_queue_t queue;
- odp_queue_param_t qparam;
- odp_queue_capability_t queue_capa;
- unsigned i;
- uint32_t impl_size, l1_size, queue_size;
- char queue_name[ODPH_TABLE_NAME_LEN + 2];
-
- if (odp_queue_capability(&queue_capa)) {
- ODPH_ERR("queue capa failed\n");
- return NULL;
- }
-
- if (queue_capa.plain.max_size) {
- if (queue_capa.plain.max_size < CACHE_NUM_TRIE ||
- queue_capa.plain.max_size < CACHE_NUM_SUBTREE) {
- ODPH_ERR("queue size too small\n");
- return NULL;
- }
- }
-
- queue_size = CACHE_NUM_TRIE;
- if (CACHE_NUM_SUBTREE > CACHE_NUM_TRIE)
- queue_size = CACHE_NUM_SUBTREE;
-
- /* Check for valid parameters */
- if (strlen(name) == 0) {
- ODPH_DBG("invalid parameters\n");
- return NULL;
- }
-
- /* Guarantee there's no existing */
- tbl = (void *)odph_iplookup_table_lookup(name);
- if (tbl != NULL) {
- ODPH_DBG("IP prefix table %s already exists\n", name);
- return NULL;
- }
-
- /* Calculate the sizes of different parts of IP prefix table */
- impl_size = sizeof(odph_iplookup_table_impl);
- l1_size = ENTRY_SIZE * ENTRY_NUM_L1;
-
- shm_tbl = odp_shm_reserve(name, impl_size + l1_size, ODP_CACHE_LINE_SIZE, 0);
-
- if (shm_tbl == ODP_SHM_INVALID) {
- ODPH_DBG(
- "shm allocation failed for odph_iplookup_table_impl %s\n",
- name);
- return NULL;
- }
-
- tbl = (odph_iplookup_table_impl *)odp_shm_addr(shm_tbl);
- memset(tbl, 0, impl_size + l1_size);
-
- /* header of this mem block is the table impl struct,
- * then the l1 entries array.
- */
- tbl->l1e = (prefix_entry_t *)(void *)((char *)tbl + impl_size);
- for (i = 0; i < ENTRY_NUM_L1; i++)
- tbl->l1e[i].nexthop = ODP_BUFFER_INVALID;
-
- /* Setup table context. */
- snprintf(tbl->name, sizeof(tbl->name), "%s", name);
- tbl->magicword = ODPH_IP_LOOKUP_TABLE_MAGIC_WORD;
- tbl->nexthop_len = value_size;
-
- /* Initialize cache */
- for (i = 0; i < 2; i++) {
- tbl->cache_count[i] = 0;
-
- odp_queue_param_init(&qparam);
- qparam.type = ODP_QUEUE_TYPE_PLAIN;
- qparam.size = queue_size;
- sprintf(queue_name, "%s_%d", name, i);
- queue = odp_queue_create(queue_name, &qparam);
- if (queue == ODP_QUEUE_INVALID) {
- ODPH_DBG("failed to create queue");
- cache_destroy(tbl);
- return NULL;
- }
- tbl->free_slots[i] = queue;
- cache_alloc_new_pool(tbl, i);
- }
-
- /* Initialize tire */
- if (trie_init(tbl) < 0) {
- odp_shm_free(shm_tbl);
- return NULL;
- }
-
- return (odph_table_t)tbl;
-}
-
-int
-odph_iplookup_table_destroy(odph_table_t tbl)
-{
- int i, j;
- odph_iplookup_table_impl *impl = NULL;
- prefix_entry_t *subtree = NULL;
- odp_buffer_t *buff1 = NULL, *buff2 = NULL;
-
- if (tbl == NULL)
- return -1;
-
- impl = (odph_iplookup_table_impl *)(void *)tbl;
-
- /* check magic word */
- if (impl->magicword != ODPH_IP_LOOKUP_TABLE_MAGIC_WORD) {
- ODPH_DBG("wrong magicword for IP prefix table\n");
- return -1;
- }
-
- /* destroy trie */
- trie_destroy(impl, impl->trie);
-
- /* free all L2 and L3 entries */
- buff1 = ENTRY_BUFF_ARR(impl->l1e);
- for (i = 0; i < ENTRY_NUM_L1; i++) {
- if ((impl->l1e[i]).child == 0)
- continue;
-
- subtree = (prefix_entry_t *)impl->l1e[i].ptr;
- buff2 = ENTRY_BUFF_ARR(subtree);
- /* destroy all l3 subtrees of this l2 subtree */
- for (j = 0; j < ENTRY_NUM_SUBTREE; j++) {
- if (subtree[j].child == 0)
- continue;
- odp_queue_enq(
- impl->free_slots[CACHE_TYPE_TRIE],
- odp_buffer_to_event(buff2[j]));
- }
- /* destroy this l2 subtree */
- odp_queue_enq(
- impl->free_slots[CACHE_TYPE_TRIE],
- odp_buffer_to_event(buff1[i]));
- }
-
- /* destroy all cache */
- cache_destroy(impl);
-
- /* free impl */
- odp_shm_free(odp_shm_lookup(impl->name));
- return 0;
-}
-
-/* Insert the prefix into level x
- * Return:
- * -1 error
- * 0 the table is unmodified
- * 1 the table is modified
- */
-static int
-prefix_insert_into_lx(
- odph_iplookup_table_impl *tbl, prefix_entry_t *entry,
- uint8_t cidr, odp_buffer_t nexthop, uint8_t level)
-{
- int ret = 0;
- uint32_t i = 0, limit = (1 << (level - cidr));
- prefix_entry_t *e = entry, *ne = NULL;
-
- for (i = 0; i < limit; i++, e++) {
- if (e->cidr > cidr)
- continue;
-
- if (e->child == 1) {
- e->cidr = cidr;
- /* push to next level */
- ne = (prefix_entry_t *)e->ptr;
- ret = prefix_insert_into_lx(
- tbl, ne, cidr, nexthop, cidr + 8);
- if (ret == -1)
- return -1;
- if (ret == 0)
- return ret;
- } else {
- e->child = 0;
- e->cidr = cidr;
- e->nexthop = nexthop;
- ret = 1;
- }
- }
- return ret;
-}
-
-static int
-prefix_insert_iter(
- odph_iplookup_table_impl *tbl, prefix_entry_t *entry,
- odp_buffer_t *buff, uint32_t ip, uint8_t cidr,
- odp_buffer_t nexthop, uint8_t level, uint8_t depth)
-{
- uint8_t state = 0;
- prefix_entry_t *ne = NULL;
- odp_buffer_t *nbuff = NULL;
-
- /* If child subtree is existed, get it. */
- if (entry->child) {
- ne = (prefix_entry_t *)entry->ptr;
- nbuff = ENTRY_BUFF_ARR(ne);
- } else {
- /* If the child is not existed, create a new subtree. */
- odp_buffer_t buf, push = entry->nexthop;
-
- buf = cache_get_buffer(tbl, CACHE_TYPE_SUBTREE);
- if (buf == ODP_BUFFER_INVALID) {
- ODPH_DBG("failed to get subtree buffer from cache.\n");
- return -1;
- }
- ne = (prefix_entry_t *)odp_buffer_addr(buf);
- nbuff = ENTRY_BUFF_ARR(ne);
-
- entry->child = 1;
- entry->ptr = ne;
- *buff = buf;
-
- /* If this entry contains a nexthop and a small cidr,
- * push it to the next level.
- */
- if (entry->cidr > 0)
- (void)prefix_insert_into_lx(tbl, ne, entry->cidr,
- push, entry->cidr + 8);
- }
-
- ne += (ip >> 24);
- nbuff += (ip >> 24);
- if (cidr <= 8) {
- state = prefix_insert_into_lx(
- tbl, ne, cidr + depth * 8, nexthop, level);
- } else {
- state = prefix_insert_iter(
- tbl, ne, nbuff, ip << 8, cidr - 8,
- nexthop, level + 8, depth + 1);
- }
-
- return state;
-}
-
-int
-odph_iplookup_table_put_value(odph_table_t tbl, void *key, void *value)
-{
- odph_iplookup_table_impl *impl = (void *)tbl;
- odph_iplookup_prefix_t *prefix = (odph_iplookup_prefix_t *)key;
- prefix_entry_t *l1e = NULL;
- odp_buffer_t nexthop;
- int ret = 0;
-
- if ((tbl == NULL) || (key == NULL) || (value == NULL))
- return -1;
-
- nexthop = *((odp_buffer_t *)value);
-
- if (prefix->cidr == 0 || prefix->cidr > 32)
- return -1;
-
- prefix->ip = prefix->ip & (0xffffffff << (IP_LENGTH - prefix->cidr));
-
- /* insert into trie */
- ret = trie_insert_node(
- impl, impl->trie,
- prefix->ip, prefix->cidr, nexthop);
-
- if (ret < 0) {
- ODPH_DBG("failed to insert into trie\n");
- return -1;
- }
-
- /* get L1 entry */
- l1e = &impl->l1e[prefix->ip >> 16];
- odp_buffer_t *buff = ENTRY_BUFF_ARR(impl->l1e) + (prefix->ip >> 16);
-
- if (prefix->cidr <= 16) {
- ret = prefix_insert_into_lx(
- impl, l1e, prefix->cidr, nexthop, 16);
- } else {
- ret = prefix_insert_iter(
- impl, l1e, buff,
- ((prefix->ip) << 16), prefix->cidr - 16,
- nexthop, 24, 2);
- }
-
- return ret;
-}
-
-int odph_iplookup_table_get_value(odph_table_t tbl, void *key,
- void *buffer ODP_UNUSED,
- uint32_t buffer_size ODP_UNUSED)
-{
- odph_iplookup_table_impl *impl = (void *)tbl;
- uint32_t ip;
- prefix_entry_t *entry;
- odp_buffer_t *buff = (odp_buffer_t *)buffer;
-
- if ((tbl == NULL) || (key == NULL) || (buffer == NULL))
- return -EINVAL;
-
- ip = *((uint32_t *)key);
- entry = &impl->l1e[ip >> 16];
-
- if (entry == NULL) {
- ODPH_DBG("failed to get L1 entry.\n");
- return -1;
- }
-
- ip <<= 16;
- while (entry->child) {
- entry = (prefix_entry_t *)entry->ptr;
- entry += ip >> 24;
- ip <<= 8;
- }
-
- /* copy data */
- if (entry->nexthop == ODP_BUFFER_INVALID) {
- /* ONLY match the default prefix */
- printf("only match the default prefix\n");
- *buff = ODP_BUFFER_INVALID;
- } else {
- *buff = entry->nexthop;
- }
-
- return 0;
-}
-
-static int
-prefix_delete_lx(
- odph_iplookup_table_impl *tbl, prefix_entry_t *l1e,
- odp_buffer_t *buff, uint8_t cidr, uint8_t over_cidr,
- odp_buffer_t over_nexthop, uint8_t level)
-{
- uint8_t ret, flag = 1;
- prefix_entry_t *e = l1e;
- odp_buffer_t *b = buff;
- uint32_t i = 0, limit = 1 << (level - cidr);
-
- for (i = 0; i < limit; i++, e++, b++) {
- if (e->child == 1) {
- if (e->cidr > cidr) {
- flag = 0;
- continue;
- }
-
- prefix_entry_t *ne = (prefix_entry_t *)e->ptr;
- odp_buffer_t *nbuff = ENTRY_BUFF_ARR(ne);
-
- e->cidr = over_cidr;
- ret = prefix_delete_lx(
- tbl, ne, nbuff, cidr, over_cidr,
- over_nexthop, cidr + 8);
-
- /* If ret == 1, the next 2^8 entries equal to
- * (over_cidr, over_nexthop). In this case, we
- * should not push the (over_cidr, over_nexthop)
- * to the next level. In fact, we should recycle
- * the next 2^8 entries.
- */
- if (ret) {
- /* destroy subtree */
- cache_init_buffer(
- *b, CACHE_TYPE_SUBTREE,
- ENTRY_SIZE * ENTRY_NUM_SUBTREE);
- odp_queue_enq(
- tbl->free_slots[CACHE_TYPE_SUBTREE],
- odp_buffer_to_event(*b));
- e->child = 0;
- e->nexthop = over_nexthop;
- } else {
- flag = 0;
- }
- } else {
- if (e->cidr > cidr) {
- flag = 0;
- continue;
- } else {
- e->cidr = over_cidr;
- e->nexthop = over_nexthop;
- }
- }
- }
- return flag;
-}
-
-/* Check if the entry can be recycled.
- * An entry can be recycled duo to two reasons:
- * - all children of the entry are the same,
- * - all children of the entry have a cidr smaller than the level
- * bottom bound.
- */
-static uint8_t
-can_recycle(prefix_entry_t *e, uint32_t level)
-{
- uint8_t recycle = 1;
- int i = 1;
- prefix_entry_t *ne = (prefix_entry_t *)e->ptr;
-
- if (ne->child)
- return 0;
-
- uint8_t cidr = ne->cidr;
- odp_buffer_t index = ne->nexthop;
-
- if (cidr > level)
- return 0;
-
- ne++;
- for (; i < 256; i++, ne++) {
- if (
- ne->child != 0 || ne->cidr != cidr ||
- ne->nexthop != index) {
- recycle = 0;
- break;
- }
- }
- return recycle;
-}
-
-static uint8_t
-prefix_delete_iter(
- odph_iplookup_table_impl *tbl, prefix_entry_t *e,
- odp_buffer_t *buff, uint32_t ip, uint8_t cidr,
- uint8_t level, uint8_t depth)
-{
- uint8_t ret = 0, over_cidr;
- odp_buffer_t over_nexthop;
-
- trie_detect_overlap(
- tbl->trie, ip, cidr + 8 * depth, level,
- &over_cidr, &over_nexthop);
- if (cidr > 8) {
- prefix_entry_t *ne =
- (prefix_entry_t *)e->ptr;
- odp_buffer_t *nbuff = ENTRY_BUFF_ARR(ne);
-
- ne += ((uint32_t)(ip << level) >> 24);
- nbuff += ((uint32_t)(ip << level) >> 24);
- ret = prefix_delete_iter(
- tbl, ne, nbuff, ip, cidr - 8,
- level + 8, depth + 1);
-
- if (ret && can_recycle(e, level)) {
- /* destroy subtree */
- cache_init_buffer(
- *buff, CACHE_TYPE_SUBTREE,
- ENTRY_SIZE * ENTRY_NUM_SUBTREE);
- odp_queue_enq(
- tbl->free_slots[CACHE_TYPE_SUBTREE],
- odp_buffer_to_event(*buff));
- e->child = 0;
- e->nexthop = over_nexthop;
- e->cidr = over_cidr;
- return 1;
- }
- return 0;
- }
-
- ret = prefix_delete_lx(
- tbl, e, buff, cidr + 8 * depth,
- over_cidr, over_nexthop, level);
- return ret;
-}
-
-int
-odph_iplookup_table_remove_value(odph_table_t tbl, void *key)
-{
- odph_iplookup_table_impl *impl = (void *)tbl;
- odph_iplookup_prefix_t *prefix = (odph_iplookup_prefix_t *)key;
- uint32_t ip;
- uint8_t cidr;
-
- if ((tbl == NULL) || (key == NULL))
- return -EINVAL;
-
- ip = prefix->ip;
- cidr = prefix->cidr;
-
- if (cidr == 0 || cidr > 32)
- return -EINVAL;
-
- prefix_entry_t *entry = &impl->l1e[ip >> 16];
- odp_buffer_t *buff = ENTRY_BUFF_ARR(impl->l1e) + (ip >> 16);
- uint8_t over_cidr, ret;
- odp_buffer_t over_nexthop;
-
- trie_detect_overlap(
- impl->trie, ip, cidr, 16, &over_cidr, &over_nexthop);
-
- if (cidr <= 16) {
- prefix_delete_lx(
- impl, entry, buff, cidr, over_cidr, over_nexthop, 16);
- } else {
- prefix_entry_t *ne = (prefix_entry_t *)entry->ptr;
- odp_buffer_t *nbuff = ENTRY_BUFF_ARR(ne);
-
- ne += ((uint32_t)(ip << 16) >> 24);
- nbuff += ((uint32_t)(ip << 16) >> 24);
- ret = prefix_delete_iter(impl, ne, nbuff, ip, cidr - 16, 24, 2);
-
- if (ret && can_recycle(entry, 16)) {
- /* destroy subtree */
- cache_init_buffer(
- *buff, CACHE_TYPE_SUBTREE,
- sizeof(prefix_entry_t) * ENTRY_NUM_SUBTREE);
- odp_queue_enq(
- impl->free_slots[CACHE_TYPE_SUBTREE],
- odp_buffer_to_event(*buff));
- entry->child = 0;
- entry->cidr = over_cidr;
- entry->nexthop = over_nexthop;
- }
- }
-
- return trie_delete_node(impl, impl->trie, ip, cidr);
-}
-
-odph_table_ops_t odph_iplookup_table_ops = {
- odph_iplookup_table_create,
- odph_iplookup_table_lookup,
- odph_iplookup_table_destroy,
- odph_iplookup_table_put_value,
- odph_iplookup_table_get_value,
- odph_iplookup_table_remove_value
-};
diff --git a/helper/ipsec.c b/helper/ipsec.c
index bb7d5d0eb..1589d33bd 100644
--- a/helper/ipsec.c
+++ b/helper/ipsec.c
@@ -4,8 +4,8 @@
* Copyright (c) 2021 Nokia
*/
+#include <odp/helper/debug.h>
#include <odp/helper/ipsec.h>
-#include <odp/helper/odph_debug.h>
uint32_t odph_ipsec_auth_icv_len_default(odp_auth_alg_t auth_alg)
{
diff --git a/helper/lineartable.c b/helper/lineartable.c
deleted file mode 100644
index 290a90c02..000000000
--- a/helper/lineartable.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Linaro Limited
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <malloc.h>
-
-#include <odp/helper/odph_lineartable.h>
-#include <odp/helper/odph_debug.h>
-#include <odp_api.h>
-
-#define ODPH_SUCCESS 0
-#define ODPH_FAIL -1
-
-/** @magic word, write to the first byte of the memory block
- * to indicate this block is used by a linear table structure
- */
-#define ODPH_LINEAR_TABLE_MAGIC_WORD 0xEFEFFEFE
-
-/** @internal table struct
- * For linear table, value is orgnized as a big array,
- * and key is the index of this array, so we just need to record the
- * content of value, and make sure the key won't overflow
- */
-typedef struct {
- uint32_t magicword; /**< for check */
- uint32_t init_cap; /**< input param of capacity */
- /** given the capacity, calculate out the max supported nodes number */
- uint32_t node_sum;
- /** size of a lineartable element,including the rwlock in the head */
- uint32_t value_size;
- void *value_array; /**< value pool in array format */
- char name[ODPH_TABLE_NAME_LEN]; /**< name of the table */
-} odph_linear_table_imp;
-
-/** Note: for linear table, key must be an number, its size is fixed 4.
- * So, we ignore the input key_size here
- */
-
-odph_table_t odph_linear_table_create(const char *name, uint32_t capacity,
- uint32_t un ODP_UNUSED,
- uint32_t value_size)
-{
- uint32_t idx;
- uint32_t node_num;
- odp_shm_t shmem;
- odph_linear_table_imp *tbl;
-
- if (strlen(name) >= ODPH_TABLE_NAME_LEN || capacity < 1 ||
- capacity >= 0x1000 || value_size == 0) {
- printf("create para input error or less than !");
- return NULL;
- }
- /* check name conflict in shm*/
- if (odp_shm_lookup(name) != ODP_SHM_INVALID) {
- ODPH_DBG("name already exist\n");
- return NULL;
- }
-
- /* alloc memory from shm */
- shmem = odp_shm_reserve(name, capacity << 20, 64, 0);
- if (shmem == ODP_SHM_INVALID) {
- ODPH_DBG("shm reserve fail\n");
- return NULL;
- }
- tbl = (odph_linear_table_imp *)odp_shm_addr(shmem);
-
- /* clean this block of memory */
- memset(tbl, 0, capacity << 20);
-
- tbl->init_cap = capacity < 20;
-
- strncpy(tbl->name, name, ODPH_TABLE_NAME_LEN - 1);
-
- /* for linear table, the key is just the index, without conflict
- * so we just need to record the value content
- * there is a rwlock in the head of every node
- */
-
- tbl->value_size = value_size + sizeof(odp_rwlock_t);
-
- node_num = tbl->init_cap / tbl->value_size;
- tbl->node_sum = node_num;
-
- tbl->value_array = (void *)((char *)tbl
- + sizeof(odph_linear_table_imp));
-
- /* initialize rwlock*/
- for (idx = 0; idx < tbl->node_sum; idx++) {
- odp_rwlock_t *lock;
-
- lock = (odp_rwlock_t *)(void *)((char *)tbl->value_array
- + idx * tbl->value_size);
- odp_rwlock_init(lock);
- }
-
- tbl->magicword = ODPH_LINEAR_TABLE_MAGIC_WORD;
-
- return (odph_table_t)(tbl);
-}
-
-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 *)(void *)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;
-}
-
-odph_table_t odph_linear_table_lookup(const char *name)
-{
- odph_linear_table_imp *tbl = NULL;
- odp_shm_t shm;
-
- if (name == NULL || strlen(name) >= ODPH_TABLE_NAME_LEN)
- return NULL;
-
- shm = odp_shm_lookup(name);
- if (shm != ODP_SHM_INVALID)
- tbl = (odph_linear_table_imp *)odp_shm_addr(shm);
-
- /* check magicword to make sure the memory block is used by a table */
- if (tbl != NULL &&
- tbl->magicword == ODPH_LINEAR_TABLE_MAGIC_WORD &&
- strcmp(tbl->name, name) == 0)
- return (odph_table_t)tbl;
-
- return NULL;
-}
-
-/* should make sure the input table exists and is available */
-static int odph_lineartable_put_value(odph_table_t table,
- void *key, void *value)
-{
- odph_linear_table_imp *tbl;
- uint32_t ikey = 0;
- void *entry = NULL;
- odp_rwlock_t *lock = NULL;
-
- if (table == NULL || key == NULL || value == NULL)
- return ODPH_FAIL;
-
- tbl = (odph_linear_table_imp *)(void *)table;
- ikey = *(uint32_t *)key;
- if (ikey >= tbl->node_sum)
- return ODPH_FAIL;
-
- entry = (void *)((char *)tbl->value_array + ikey * tbl->value_size);
- lock = (odp_rwlock_t *)entry;
- entry = (char *)entry + sizeof(odp_rwlock_t);
-
- odp_rwlock_write_lock(lock);
-
- memcpy(entry, value, tbl->value_size - sizeof(odp_rwlock_t));
-
- odp_rwlock_write_unlock(lock);
-
- return ODPH_SUCCESS;
-}
-
-/* should make sure the input table exists and is available */
-static int odph_lineartable_get_value(odph_table_t table,
- void *key, void *buffer,
- uint32_t buffer_size ODP_UNUSED)
-{
- odph_linear_table_imp *tbl;
- uint32_t ikey = 0;
- void *entry = NULL;
- odp_rwlock_t *lock = NULL;
-
- if (table == NULL || key == NULL || buffer == NULL)
- return ODPH_FAIL;
-
- tbl = (odph_linear_table_imp *)(void *)table;
- ikey = *(uint32_t *)key;
- if (ikey >= tbl->node_sum)
- return ODPH_FAIL;
-
- entry = (void *)((char *)tbl->value_array + ikey * tbl->value_size);
- lock = (odp_rwlock_t *)entry;
- entry = (char *)entry + sizeof(odp_rwlock_t);
-
- odp_rwlock_read_lock(lock);
-
- memcpy(buffer, entry, tbl->value_size - sizeof(odp_rwlock_t));
-
- odp_rwlock_read_unlock(lock);
-
- return ODPH_SUCCESS;
-}
-
-odph_table_ops_t odph_linear_table_ops = {
- odph_linear_table_create,
- odph_linear_table_lookup,
- odph_linear_table_destroy,
- odph_lineartable_put_value,
- odph_lineartable_get_value,
- NULL,
- };
-
diff --git a/helper/linux/thread.c b/helper/linux/thread.c
index d5b016833..ec2847a88 100644
--- a/helper/linux/thread.c
+++ b/helper/linux/thread.c
@@ -18,9 +18,9 @@
#include <stdbool.h>
#include <odp_api.h>
+#include <odp/helper/debug.h>
#include <odp/helper/linux/pthread.h>
#include <odp/helper/linux/process.h>
-#include <odp/helper/odph_debug.h>
static void *_odph_run_start_routine(void *arg)
{
diff --git a/helper/m4/configure.m4 b/helper/m4/configure.m4
index 2e1076172..04768f25e 100644
--- a/helper/m4/configure.m4
+++ b/helper/m4/configure.m4
@@ -1,3 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (c) 2016 Linaro Limited
+#
+
##########################################################################
# Include m4 files
##########################################################################
diff --git a/helper/m4/libcli.m4 b/helper/m4/libcli.m4
index 6748cbb41..7edaf3a5d 100644
--- a/helper/m4/libcli.m4
+++ b/helper/m4/libcli.m4
@@ -1,3 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (c) 2021 Nokia
+#
+
##########################################################################
# Set optional libcli path
##########################################################################
diff --git a/helper/test/.gitignore b/helper/test/.gitignore
index 3db451f68..6fb54ea3b 100644
--- a/helper/test/.gitignore
+++ b/helper/test/.gitignore
@@ -2,13 +2,11 @@
*.log
chksum
cli
-cuckootable
-iplookuptable
macros
odpthreads
parse
process
-table
+stress
thread
pthread
version
diff --git a/helper/test/Makefile.am b/helper/test/Makefile.am
index 9cf48d7d9..07986761c 100644
--- a/helper/test/Makefile.am
+++ b/helper/test/Makefile.am
@@ -3,11 +3,9 @@ include $(top_srcdir)/test/Makefile.inc
EXECUTABLES = version \
debug \
chksum \
- cuckootable \
macros \
- parse\
- table \
- iplookuptable
+ parse \
+ stress
#These are platform specific extensions that are not portable
#They are a convenience to app writers who have chosen to
@@ -39,12 +37,10 @@ test_PROGRAMS = $(EXECUTABLES) $(COMPILE_ONLY)
dist_check_SCRIPTS = odpthreads_as_processes odpthreads_as_pthreads
chksum_SOURCES = chksum.c
-cuckootable_SOURCES = cuckootable.c
macros_SOURCES = macros.c
odpthreads_SOURCES = odpthreads.c
parse_SOURCES = parse.c
-table_SOURCES = table.c
-iplookuptable_SOURCES = iplookuptable.c
+stress_SOURCES = stress.c
version_SOURCES = version.c
debug_SOURCES = debug.c
diff --git a/helper/test/cli.c b/helper/test/cli.c
index 08e750153..f7f072fef 100644
--- a/helper/test/cli.c
+++ b/helper/test/cli.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2021 Nokia
+ * Copyright (c) 2021-2024 Nokia
*/
#include <odp_api.h>
@@ -9,7 +9,7 @@ static int cli_server(void *arg ODP_UNUSED)
{
if (odph_cli_run()) {
ODPH_ERR("odph_cli_run() failed.\n");
- exit(EXIT_FAILURE);
+ return -1;
}
return 0;
@@ -55,6 +55,7 @@ int main(int argc, char *argv[])
odph_thread_common_param_t thr_common;
odph_thread_param_t thr_param;
odph_thread_t thr_server;
+ odph_thread_join_result_t res;
if (odp_cpumask_default_control(&cpumask, 1) != 1) {
ODPH_ERR("Failed to get default CPU mask.\n");
@@ -86,8 +87,14 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
- if (odph_thread_join(&thr_server, 1) != 1) {
- ODPH_ERR("Failed to join server thread.\n");
+ if (odph_thread_join_result(&thr_server, &res, 1) != 1) {
+ ODPH_ERR("Error: failed to join server thread.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (res.is_sig || res.ret != 0) {
+ ODPH_ERR("Error: worker thread failure%s: %d.\n", res.is_sig ? " (signaled)" : "",
+ res.ret);
exit(EXIT_FAILURE);
}
diff --git a/helper/test/cuckootable.c b/helper/test/cuckootable.c
deleted file mode 100644
index d17f79562..000000000
--- a/helper/test/cuckootable.c
+++ /dev/null
@@ -1,577 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2016-2018 Linaro Limited
- */
-
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include <odp_api.h>
-#include <odp/helper/odph_api.h>
-
-/*******************************************************************************
- * Hash function performance test configuration section.
- *
- * The five arrays below control what tests are performed. Every combination
- * from the array entries is tested.
- */
-/******************************************************************************/
-
-/* 5-tuple key type */
-struct flow_key {
- uint32_t ip_src;
- uint32_t ip_dst;
- uint16_t port_src;
- uint16_t port_dst;
- uint8_t proto;
-} __packed;
-
-/*
- * Print out result of unit test hash operation.
- */
-static void print_key_info(
- const char *msg, const struct flow_key *key)
-{
- const uint8_t *p = (const uint8_t *)key;
- unsigned i;
-
- printf("%s key:0x", msg);
- for (i = 0; i < sizeof(struct flow_key); i++)
- printf("%02X", p[i]);
- printf("\n");
-}
-
-static double get_time_diff(struct timeval *start, struct timeval *end)
-{
- int sec = end->tv_sec - start->tv_sec;
- int usec = end->tv_usec - start->tv_usec;
-
- if (usec < 0) {
- sec--;
- usec += 1000000;
- }
- double diff = sec + (double)usec / 1000000;
-
- return diff;
-}
-
-/** Create IPv4 address */
-#define IPv4(a, b, c, d) ((uint32_t)(((a) & 0xff) << 24) | \
- (((b) & 0xff) << 16) | \
- (((c) & 0xff) << 8) | \
- ((d) & 0xff))
-
-/* Keys used by unit test functions */
-static struct flow_key keys[5] = { {
- .ip_src = IPv4(0x03, 0x02, 0x01, 0x00),
- .ip_dst = IPv4(0x07, 0x06, 0x05, 0x04),
- .port_src = 0x0908,
- .port_dst = 0x0b0a,
- .proto = 0x0c,
-}, {
- .ip_src = IPv4(0x13, 0x12, 0x11, 0x10),
- .ip_dst = IPv4(0x17, 0x16, 0x15, 0x14),
- .port_src = 0x1918,
- .port_dst = 0x1b1a,
- .proto = 0x1c,
-}, {
- .ip_src = IPv4(0x23, 0x22, 0x21, 0x20),
- .ip_dst = IPv4(0x27, 0x26, 0x25, 0x24),
- .port_src = 0x2928,
- .port_dst = 0x2b2a,
- .proto = 0x2c,
-}, {
- .ip_src = IPv4(0x33, 0x32, 0x31, 0x30),
- .ip_dst = IPv4(0x37, 0x36, 0x35, 0x34),
- .port_src = 0x3938,
- .port_dst = 0x3b3a,
- .proto = 0x3c,
-}, {
- .ip_src = IPv4(0x43, 0x42, 0x41, 0x40),
- .ip_dst = IPv4(0x47, 0x46, 0x45, 0x44),
- .port_src = 0x4948,
- .port_dst = 0x4b4a,
- .proto = 0x4c,
-} };
-
-/*
- * Basic sequence of operations for a single key:
- * - put
- * - get (hit)
- * - remove
- * - get (miss)
- */
-static int test_put_remove(void)
-{
- odph_table_t table;
- odph_table_ops_t *ops;
-
- ops = &odph_cuckoo_table_ops;
-
- /* test with standard put/get/remove functions */
- int ret;
-
- table = ops->f_create("put_remove", 10, sizeof(struct flow_key), 0);
- if (table == NULL) {
- printf("cuckoo hash table creation failed\n");
- return -1;
- }
-
- ret = odph_cuckoo_table_put_value(table, &keys[0], NULL);
- print_key_info("Add", &keys[0]);
- if (ret < 0) {
- printf("failed to add key\n");
- odph_cuckoo_table_destroy(table);
- return -1;
- }
-
- ret = odph_cuckoo_table_get_value(table, &keys[0], NULL, 0);
- print_key_info("Lkp", &keys[0]);
- if (ret < 0) {
- printf("failed to find key\n");
- odph_cuckoo_table_destroy(table);
- return -1;
- }
-
- ret = odph_cuckoo_table_remove_value(table, &keys[0]);
- print_key_info("Del", &keys[0]);
- if (ret < 0) {
- printf("failed to delete key\n");
- odph_cuckoo_table_destroy(table);
- return -1;
- }
-
- ret = odph_cuckoo_table_get_value(table, &keys[0], NULL, 0);
- print_key_info("Lkp", &keys[0]);
- if (ret >= 0) {
- printf("error: found key after deleting!\n");
- odph_cuckoo_table_destroy(table);
- return -1;
- }
-
- odph_cuckoo_table_destroy(table);
- return 0;
-}
-
-/*
- * Sequence of operations for a single key:
- * key type : struct flow_key
- * value type: uint8_t
- * - remove: miss
- * - put
- * - get: hit
- * - put: update
- * - get: hit (updated data)
- * - remove: hit
- * - remove: miss
- */
-static int test_put_update_remove(void)
-{
- odph_table_t table;
- int ret;
- uint8_t val1 = 1, val2 = 2, val = 0;
-
- table = odph_cuckoo_table_create(
- "put_update_remove",
- 10, sizeof(struct flow_key), sizeof(uint8_t));
- if (table == NULL) {
- printf("failed to create table\n");
- return -1;
- }
-
- ret = odph_cuckoo_table_remove_value(table, &keys[0]);
- print_key_info("Del", &keys[0]);
- if (ret >= 0) {
- printf("error: found non-existent key\n");
- odph_cuckoo_table_destroy(table);
- return -1;
- }
-
- ret = odph_cuckoo_table_put_value(table, &keys[0], &val1);
- print_key_info("Add", &keys[0]);
- if (ret < 0) {
- printf("failed to add key\n");
- odph_cuckoo_table_destroy(table);
- return -1;
- }
-
- ret = odph_cuckoo_table_get_value(
- table, &keys[0], &val, sizeof(uint8_t));
- print_key_info("Lkp", &keys[0]);
- if (ret < 0) {
- printf("failed to find key\n");
- odph_cuckoo_table_destroy(table);
- return -1;
- }
-
- ret = odph_cuckoo_table_put_value(table, &keys[0], &val2);
- if (ret < 0) {
- printf("failed to re-add key\n");
- odph_cuckoo_table_destroy(table);
- return -1;
- }
-
- ret = odph_cuckoo_table_get_value(
- table, &keys[0], &val, sizeof(uint8_t));
- print_key_info("Lkp", &keys[0]);
- if (ret < 0) {
- printf("failed to find key\n");
- odph_cuckoo_table_destroy(table);
- return -1;
- }
-
- ret = odph_cuckoo_table_remove_value(table, &keys[0]);
- print_key_info("Del", &keys[0]);
- if (ret < 0) {
- printf("failed to delete key\n");
- odph_cuckoo_table_destroy(table);
- return -1;
- }
-
- ret = odph_cuckoo_table_remove_value(table, &keys[0]);
- print_key_info("Del", &keys[0]);
- if (ret >= 0) {
- printf("error: deleted already deleted key\n");
- odph_cuckoo_table_destroy(table);
- return -1;
- }
-
- odph_cuckoo_table_destroy(table);
- return 0;
-}
-
-/*
- * Sequence of operations for find existing hash table
- *
- * - create table
- * - find existing table: hit
- * - find non-existing table: miss
- *
- */
-static int test_table_lookup(void)
-{
- odph_table_t table, result;
-
- /* Create cuckoo hash table. */
- table = odph_cuckoo_table_create("table_lookup", 10, 4, 0);
- if (table == NULL) {
- printf("failed to create table\n");
- return -1;
- }
-
- /* Try to find existing hash table */
- result = odph_cuckoo_table_lookup("table_lookup");
- if (result != table) {
- printf("error: could not find existing table\n");
- odph_cuckoo_table_destroy(table);
- return -1;
- }
-
- /* Try to find non-existing hash table */
- result = odph_cuckoo_table_lookup("non_existing");
- if (result != NULL) {
- printf("error: found table that shouldn't exist.\n");
- odph_cuckoo_table_destroy(table);
- return -1;
- }
-
- /* Cleanup. */
- odph_cuckoo_table_destroy(table);
- return 0;
-}
-
-/*
- * Sequence of operations for 5 keys
- * - put keys
- * - get keys: hit
- * - remove keys : hit
- * - get keys: miss
- */
-static int test_five_keys(void)
-{
- odph_table_t table;
- unsigned i;
- int ret;
-
- table = odph_cuckoo_table_create(
- "five_keys", 10, sizeof(struct flow_key), 0);
- if (table == NULL) {
- printf("failed to create table\n");
- return -1;
- }
-
- /* put */
- for (i = 0; i < 5; i++) {
- ret = odph_cuckoo_table_put_value(table, &keys[i], NULL);
- print_key_info("Add", &keys[i]);
- if (ret < 0) {
- printf("failed to add key %d\n", i);
- odph_cuckoo_table_destroy(table);
- return -1;
- }
- }
-
- /* get */
- for (i = 0; i < 5; i++) {
- ret = odph_cuckoo_table_get_value(table, &keys[i], NULL, 0);
- print_key_info("Lkp", &keys[i]);
- if (ret < 0) {
- printf("failed to find key %d\n", i);
- odph_cuckoo_table_destroy(table);
- return -1;
- }
- }
-
- /* remove */
- for (i = 0; i < 5; i++) {
- ret = odph_cuckoo_table_remove_value(table, &keys[i]);
- print_key_info("Del", &keys[i]);
- if (ret < 0) {
- printf("failed to delete key %d\n", i);
- odph_cuckoo_table_destroy(table);
- return -1;
- }
- }
-
- /* get */
- for (i = 0; i < 5; i++) {
- ret = odph_cuckoo_table_get_value(table, &keys[i], NULL, 0);
- print_key_info("Lkp", &keys[i]);
- if (ret >= 0) {
- printf("found non-existing key %d\n", i);
- odph_cuckoo_table_destroy(table);
- return -1;
- }
- }
-
- odph_cuckoo_table_destroy(table);
- return 0;
-}
-
-#define BUCKET_ENTRIES 4
-#define HASH_ENTRIES_MAX 1048576
-/*
- * Do tests for cuchoo table creation with bad parameters.
- */
-static int test_creation_with_bad_parameters(void)
-{
- odph_table_t table;
-
- table = odph_cuckoo_table_create(
- "bad_param_0", HASH_ENTRIES_MAX + 1, 4, 0);
- if (table != NULL) {
- odph_cuckoo_table_destroy(table);
- printf("Impossible creating table successfully with entries in parameter exceeded\n");
- return -1;
- }
-
- table = odph_cuckoo_table_create(
- "bad_param_1", BUCKET_ENTRIES - 1, 4, 0);
- if (table != NULL) {
- odph_cuckoo_table_destroy(table);
- printf("Impossible creating hash successfully if entries less than bucket_entries in parameter\n");
- return -1;
- }
-
- table = odph_cuckoo_table_create("bad_param_2", 10, 0, 0);
- if (table != NULL) {
- odph_cuckoo_table_destroy(table);
- printf("Impossible creating hash successfully if key_len in parameter is zero\n");
- return -1;
- }
-
- printf("# Test successful. No more errors expected\n");
-
- return 0;
-}
-
-#define PERFORMANCE_CAPACITY 4000
-
-/*
- * Test the performance of cuckoo hash table.
- * table capacity : 1,000,000
- * key size : 4 bytes
- * value size : 0
- * Insert at most number random keys into the table. If one
- * insertion is failed, the rest insertions will be cancelled.
- * The table utilization of the report will show actual number
- * of items inserted.
- * Then search all inserted items.
- */
-static int test_performance(int number)
-{
- odph_table_t table;
-
- /* generate random keys */
- uint8_t *key_space = NULL;
- const void **key_ptr = NULL;
- unsigned key_len = 4, j;
- unsigned elem_num = (number > PERFORMANCE_CAPACITY) ?
- PERFORMANCE_CAPACITY : number;
- unsigned key_num = key_len * elem_num;
-
- key_space = (uint8_t *)malloc(key_num);
- if (key_space == NULL)
- return -ENOENT;
-
- key_ptr = (const void **)malloc(sizeof(void *) * elem_num);
- if (key_ptr == NULL) {
- free(key_space);
- return -ENOENT;
- }
-
- for (j = 0; j < key_num; j++) {
- key_space[j] = rand() % 255;
- if (j % key_len == 0)
- key_ptr[j / key_len] = &key_space[j];
- }
-
- unsigned num;
- int ret = 0;
- struct timeval start, end;
- double add_time = 0;
-
- fflush(stdout);
- table = odph_cuckoo_table_create(
- "performance_test", PERFORMANCE_CAPACITY, key_len, 0);
- if (table == NULL) {
- printf("cuckoo table creation failed\n");
- free(key_ptr);
- free(key_space);
- return -ENOENT;
- }
-
- /* insert (put) */
- gettimeofday(&start, 0);
- for (j = 0; j < elem_num; j++) {
- ret = odph_cuckoo_table_put_value(
- table, &key_space[j * key_len], NULL);
- if (ret < 0)
- break;
- }
- gettimeofday(&end, 0);
- num = j;
- add_time = get_time_diff(&start, &end);
- printf(
- "add %u/%u (%.2f) items, time = %.9lfs\n",
- num, PERFORMANCE_CAPACITY,
- (double)num / PERFORMANCE_CAPACITY, add_time);
-
- /* search (get) */
- gettimeofday(&start, 0);
- for (j = 0; j < num; j++) {
- ret = odph_cuckoo_table_get_value(
- table, &key_space[j * key_len], NULL, 0);
-
- if (ret < 0)
- printf("lookup error\n");
- }
- gettimeofday(&end, 0);
- printf(
- "lookup %u items, time = %.9lfs\n",
- num, get_time_diff(&start, &end));
-
- odph_cuckoo_table_destroy(table);
- free(key_ptr);
- free(key_space);
- return ret;
-}
-
-/*
- * Do all unit and performance tests.
- */
-static int
-test_cuckoo_hash_table(void)
-{
- if (test_put_remove() < 0)
- return -1;
- if (test_table_lookup() < 0)
- return -1;
- if (test_put_update_remove() < 0)
- return -1;
- if (test_five_keys() < 0)
- return -1;
- if (test_creation_with_bad_parameters() < 0)
- return -1;
- if (test_performance(950000) < 0)
- return -1;
-
- return 0;
-}
-
-int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
-{
- odp_instance_t instance;
- int ret = 0;
-
- ret = odp_init_global(&instance, NULL, NULL);
- if (ret != 0) {
- fprintf(stderr, "Error: ODP global init failed.\n");
- exit(EXIT_FAILURE);
- }
-
- ret = odp_init_local(instance, ODP_THREAD_WORKER);
- if (ret != 0) {
- fprintf(stderr, "Error: ODP local init failed.\n");
- exit(EXIT_FAILURE);
- }
-
- srand(time(0));
- ret = test_cuckoo_hash_table();
-
- if (ret < 0)
- printf("cuckoo hash table test fail!!\n");
- else
- printf("All Tests pass!!\n");
-
- if (odp_term_local()) {
- fprintf(stderr, "Error: ODP local term failed.\n");
- exit(EXIT_FAILURE);
- }
-
- if (odp_term_global(instance)) {
- fprintf(stderr, "Error: ODP global term failed.\n");
- exit(EXIT_FAILURE);
- }
-
- return ret;
-}
diff --git a/helper/test/iplookuptable.c b/helper/test/iplookuptable.c
deleted file mode 100644
index 669d334dd..000000000
--- a/helper/test/iplookuptable.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2016-2018 Linaro Limited
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include <odp_api.h>
-#include <odp/helper/odph_api.h>
-
-static void print_prefix_info(
- const char *msg, uint32_t ip, uint8_t cidr)
-{
- int i = 0;
- uint8_t *ptr = (uint8_t *)(&ip);
-
- printf("%s IP prefix: ", msg);
- for (i = 3; i >= 0; i--) {
- if (i != 3)
- printf(".");
- printf("%d", ptr[i]);
- }
- printf("/%d\n", cidr);
-}
-
-/*
- * Basic sequence of operations for a single key:
- * - put short prefix
- * - put long prefix
- * - get (hit long prefix)
- * - remove long prefix
- * - get (hit short prefix)
- */
-static int test_ip_lookup_table(void)
-{
- odph_iplookup_prefix_t prefix1, prefix2;
- odph_table_t table;
- int ret;
- uint64_t value1 = 1, value2 = 2, result = 0;
- uint32_t lkp_ip = 0;
-
- table = odph_iplookup_table_create(
- "prefix_test", 0, 0, sizeof(uint32_t));
- if (table == NULL) {
- printf("IP prefix lookup table creation failed\n");
- return -1;
- }
-
- ret = odph_ipv4_addr_parse(&prefix1.ip, "192.168.0.0");
- if (ret < 0) {
- printf("Failed to get IP addr from str\n");
- odph_iplookup_table_destroy(table);
- return -1;
- }
- prefix1.cidr = 11;
-
- ret = odph_ipv4_addr_parse(&prefix2.ip, "192.168.0.0");
- if (ret < 0) {
- printf("Failed to get IP addr from str\n");
- odph_iplookup_table_destroy(table);
- return -1;
- }
- prefix2.cidr = 24;
-
- ret = odph_ipv4_addr_parse(&lkp_ip, "192.168.0.1");
- if (ret < 0) {
- printf("Failed to get IP addr from str\n");
- odph_iplookup_table_destroy(table);
- return -1;
- }
-
- /* test with standard put/get/remove functions */
- ret = odph_iplookup_table_put_value(table, &prefix1, &value1);
- print_prefix_info("Add", prefix1.ip, prefix1.cidr);
- if (ret < 0) {
- printf("Failed to add ip prefix\n");
- odph_iplookup_table_destroy(table);
- return -1;
- }
-
- ret = odph_iplookup_table_get_value(table, &lkp_ip, &result, 0);
- print_prefix_info("Lkp", lkp_ip, 32);
- if (ret < 0 || result != 1) {
- printf("Failed to find longest prefix\n");
- odph_iplookup_table_destroy(table);
- return -1;
- }
-
- /* add a longer prefix */
- ret = odph_iplookup_table_put_value(table, &prefix2, &value2);
- print_prefix_info("Add", prefix2.ip, prefix2.cidr);
- if (ret < 0) {
- printf("Failed to add ip prefix\n");
- odph_iplookup_table_destroy(table);
- return -1;
- }
-
- ret = odph_iplookup_table_get_value(table, &lkp_ip, &result, 0);
- print_prefix_info("Lkp", lkp_ip, 32);
- if (ret < 0 || result != 2) {
- printf("Failed to find longest prefix\n");
- odph_iplookup_table_destroy(table);
- return -1;
- }
-
- ret = odph_iplookup_table_remove_value(table, &prefix2);
- print_prefix_info("Del", prefix2.ip, prefix2.cidr);
- if (ret < 0) {
- printf("Failed to delete ip prefix\n");
- odph_iplookup_table_destroy(table);
- return -1;
- }
-
- ret = odph_iplookup_table_get_value(table, &lkp_ip, &result, 0);
- print_prefix_info("Lkp", lkp_ip, 32);
- if (ret < 0 || result != 1) {
- printf("Error: found result ater deleting\n");
- odph_iplookup_table_destroy(table);
- return -1;
- }
-
- ret = odph_iplookup_table_remove_value(table, &prefix1);
- print_prefix_info("Del", prefix1.ip, prefix1.cidr);
- if (ret < 0) {
- printf("Failed to delete prefix\n");
- odph_iplookup_table_destroy(table);
- return -1;
- }
-
- odph_iplookup_table_destroy(table);
- return 0;
-}
-
-int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
-{
- odp_instance_t instance;
- int ret = 0;
-
- ret = odp_init_global(&instance, NULL, NULL);
- if (ret != 0) {
- fprintf(stderr, "Error: ODP global init failed.\n");
- exit(EXIT_FAILURE);
- }
-
- ret = odp_init_local(instance, ODP_THREAD_WORKER);
- if (ret != 0) {
- fprintf(stderr, "Error: ODP local init failed.\n");
- exit(EXIT_FAILURE);
- }
-
- if (test_ip_lookup_table() < 0)
- printf("Test failed\n");
- else
- printf("All tests passed\n");
-
- if (odp_term_local()) {
- fprintf(stderr, "Error: ODP local term failed.\n");
- exit(EXIT_FAILURE);
- }
-
- if (odp_term_global(instance)) {
- fprintf(stderr, "Error: ODP global term failed.\n");
- exit(EXIT_FAILURE);
- }
-
- return ret;
-}
diff --git a/helper/test/odpthreads.c b/helper/test/odpthreads.c
index bf623569b..158b1d3c3 100644
--- a/helper/test/odpthreads.c
+++ b/helper/test/odpthreads.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2016-2018 Linaro Limited
- * Copyright (c) 2021 Nokia
+ * Copyright (c) 2021-2024 Nokia
*/
/*
@@ -73,7 +73,6 @@ int main(int argc, char *argv[])
odp_init_t init_param;
int num_workers;
int cpu, affinity;
- int ret;
char cpumaskstr[ODP_CPUMASK_STR_SIZE];
struct rlimit rlimit;
pthread_attr_t attr;
@@ -161,11 +160,25 @@ int main(int argc, char *argv[])
thr_param.arg = NULL;
thr_param.thr_type = ODP_THREAD_WORKER;
- odph_thread_create(thread_tbl, &thr_common, &thr_param, num_workers);
+ if (odph_thread_create(thread_tbl, &thr_common, &thr_param, num_workers) != num_workers) {
+ ODPH_ERR("Error: failed to create worker threads.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ odph_thread_join_result_t res[num_workers];
- ret = odph_thread_join(thread_tbl, num_workers);
- if (ret < 0)
+ if (odph_thread_join_result(thread_tbl, res, num_workers) != num_workers) {
+ ODPH_ERR("Error: failed to join worker threads.\n");
exit(EXIT_FAILURE);
+ }
+
+ for (int i = 0; i < num_workers; i++) {
+ if (res[i].is_sig || res[i].ret != 0) {
+ ODPH_ERR("Error: worker thread failure%s: %d.\n", res[i].is_sig ?
+ " (signaled)" : "", res[i].ret);
+ exit(EXIT_FAILURE);
+ }
+ }
/* Test threads with non-default stack size and sync timeout. */
@@ -195,11 +208,23 @@ int main(int argc, char *argv[])
printf("use sync timeout: %" PRIu64 "\n", thr_common.sync_timeout);
printf("\n");
- if (odph_thread_create(thread_tbl, &thr_common, &thr_param, num_workers) != num_workers)
+ if (odph_thread_create(thread_tbl, &thr_common, &thr_param, num_workers) != num_workers) {
+ ODPH_ERR("Error: failed to create worker threads.\n");
exit(EXIT_FAILURE);
+ }
- if (odph_thread_join(thread_tbl, num_workers) != num_workers)
+ if (odph_thread_join_result(thread_tbl, res, num_workers) != num_workers) {
+ ODPH_ERR("Error: failed to join worker threads.\n");
exit(EXIT_FAILURE);
+ }
+
+ for (int i = 0; i < num_workers; i++) {
+ if (res[i].is_sig || res[i].ret != 0) {
+ ODPH_ERR("Error: worker thread failure%s: %d.\n", res[i].is_sig ?
+ " (signaled)" : "", res[i].ret);
+ exit(EXIT_FAILURE);
+ }
+ }
return 0;
}
diff --git a/helper/test/stress.c b/helper/test/stress.c
new file mode 100644
index 000000000..e66a0447d
--- /dev/null
+++ b/helper/test/stress.c
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Nokia
+ */
+
+#include <odp_api.h>
+#include <odp/helper/odph_api.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static int test_pow2(void)
+{
+ uint32_t in[] = {0, 1, 2, 3, 4, 0xff, 0x100, 0xfffe, 0xffff, 0x10000};
+ uint32_t out[] = {0, 1, 4, 9, 16, 0xfe01, 0x10000, 0xfffc0004, 0xfffe0001, 0xffffffff};
+ uint32_t num = ODPH_ARRAY_SIZE(out);
+ int ret = 0;
+
+ printf(" odph_stress_pow2_u32() ... ");
+
+ for (uint32_t i = 0; i < num; i++)
+ if (odph_stress_pow2_u32(in[i]) != out[i])
+ ret++;
+
+ if (ret)
+ printf("%i tests failed\n", ret);
+ else
+ printf("passed\n");
+
+ return ret;
+}
+
+static int test_log2(void)
+{
+ uint32_t in[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 15, 16, 255, 256, 257, 512, 513, 1023, 1024};
+ uint32_t out[] = {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 4, 7, 8, 8, 9, 9, 9, 10};
+ uint32_t num = ODPH_ARRAY_SIZE(out);
+ int ret = 0;
+
+ printf(" odph_stress_log2_u32() ... ");
+
+ for (uint32_t i = 0; i < num; i++)
+ if (odph_stress_log2_u32(in[i]) != out[i])
+ ret++;
+
+ if (ret)
+ printf("%i tests failed\n", ret);
+ else
+ printf("passed\n");
+
+ return ret;
+}
+
+static int test_sqrt_u32(void)
+{
+ uint32_t in[] = {0, 1, 2, 3, 4, 7, 8, 9, 100, 1500, 2900, 4096, 6213, 8191, 16384, 100000,
+ 1000000, 4036587, 0x42c1d80, 0x8000000, 0x1fffffff, 0x2faf0800,
+ 0xffffffff};
+ uint32_t out[] = {0, 1, 1, 1, 2, 2, 2, 3, 10, 38, 53, 64, 78, 90, 128, 316, 1000, 2009,
+ 8366, 11585, 23170, 28284, 65535};
+ uint32_t num = ODPH_ARRAY_SIZE(out);
+ int ret = 0;
+
+ printf(" odph_stress_sqrt_u32() ... ");
+
+ for (uint32_t i = 0; i < num; i++)
+ if (odph_stress_sqrt_u32(in[i]) != out[i])
+ ret++;
+
+ if (ret)
+ printf("%i tests failed\n", ret);
+ else
+ printf("passed\n");
+
+ return ret;
+}
+
+/*
+ * 32-bit floating point can represent integers between 0 and 16777216 exactly, and integers
+ * between 16777216 and 33554432 in multiples of 2, etc.
+ */
+static int test_sqrt_f32(void)
+{
+ float in[] = {0, 1, 2, 3, 4, 7, 8, 9, 100, 1500, 2900, 4096, 6213, 8191, 16384, 100000,
+ 1000000, 4036587, 16777216, 33554432, 134217728, 3000000000, 4294967296};
+ float out[] = {0, 1, 1, 1, 2, 2, 2, 3, 10, 38, 53, 64, 78, 90, 128, 316, 1000, 2009, 4096,
+ 5792, 11585, 54772, 65536};
+ uint32_t num = ODPH_ARRAY_SIZE(out);
+ int ret = 0;
+
+ printf(" odph_stress_sqrt_f32() ... ");
+
+ for (uint32_t i = 0; i < num; i++)
+ if (odph_stress_sqrt_f32(in[i]) != out[i])
+ ret++;
+
+ if (ret)
+ printf("%i tests failed\n", ret);
+ else
+ printf("passed\n");
+
+ return ret;
+}
+
+int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
+{
+ int ret = 0;
+
+ printf("Running helper algorithm tests:\n");
+
+ ret += test_pow2();
+ ret += test_log2();
+ ret += test_sqrt_u32();
+ ret += test_sqrt_f32();
+
+ printf("\n");
+
+ return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/helper/test/table.c b/helper/test/table.c
deleted file mode 100644
index fb17e8a37..000000000
--- a/helper/test/table.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Linaro Limited
- */
-
-#include <odp_api.h>
-#include <odp/helper/odph_api.h>
-
-/**
- * Address Resolution Protocol (ARP)
- * Description: Once a route has been identified for an IP packet (so the
- * output interface and the IP address of the next hop station are known),
- * the MAC address of the next hop station is needed in order to send this
- * packet onto the next leg of the journey towards its destination
- * (as identified by its destination IP address). The MAC address of the next
- * hop station becomes the destination MAC address of the outgoing
- * Ethernet frame.
- * Hash table name: ARP table
- * Number of keys: Thousands
- * Key format: The pair of (Output interface, Next Hop IP address),
- * which is typically 5 bytes for IPv4 and 17 bytes for IPv6.
- * value (data): MAC address of the next hop station (6 bytes).
- */
-
-int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
-{
- odp_instance_t instance;
- int ret = 0;
- odph_table_t table;
- odph_table_t tmp_tbl;
- odph_table_ops_t *test_ops;
- char tmp[32];
- char ip_addr1[] = "12345678";
- char ip_addr2[] = "11223344";
- char ip_addr3[] = "55667788";
- char mac_addr1[] = "0A1122334401";
- char mac_addr2[] = "0A1122334402";
- char mac_addr3[] = "0B4433221101";
- char mac_addr4[] = "0B4433221102";
-
- ret = odp_init_global(&instance, NULL, NULL);
- if (ret != 0) {
- ODPH_ERR("odp_shm_init_global fail\n");
- exit(EXIT_FAILURE);
- }
- ret = odp_init_local(instance, ODP_THREAD_WORKER);
- if (ret != 0) {
- ODPH_ERR("odp_shm_init_local fail\n");
- exit(EXIT_FAILURE);
- }
-
- printf("test hash table:\n");
- test_ops = &odph_hash_table_ops;
-
- table = test_ops->f_create("test", 2, 4, 16);
- if (table == NULL) {
- printf("table create fail\n");
- return -1;
- }
- ret += test_ops->f_put(table, &ip_addr1, mac_addr1);
-
- ret += test_ops->f_put(table, &ip_addr2, mac_addr2);
-
- ret += test_ops->f_put(table, &ip_addr3, mac_addr3);
-
- if (ret != 0) {
- printf("put value fail\n");
- return -1;
- }
-
- ret = test_ops->f_get(table, &ip_addr1, &tmp, 32);
- if (ret != 0) {
- printf("get value fail\n");
- return -1;
- }
- printf("\t1 get '123' tmp = %s,\n", tmp);
-
- ret = test_ops->f_put(table, &ip_addr1, mac_addr4);
- if (ret != 0) {
- printf("repeat put value fail\n");
- return -1;
- }
-
- ret = test_ops->f_get(table, &ip_addr1, &tmp, 32);
- if (ret != 0 || strcmp(tmp, mac_addr4) != 0) {
- printf("get value fail\n");
- return -1;
- }
-
- printf("\t2 repeat get '123' value = %s\n", tmp);
-
- ret = test_ops->f_remove(table, &ip_addr1);
- if (ret != 0) {
- printf("remove value fail\n");
- return -1;
- }
- ret = test_ops->f_get(table, &ip_addr1, tmp, 32);
- if (ret == 0) {
- printf("remove value fail actually\n");
- return -1;
- }
- printf("\t3 remove success!\n");
-
- tmp_tbl = test_ops->f_lookup("test");
- if (tmp_tbl != table) {
- printf("lookup table fail!!!\n");
- return -1;
- }
- printf("\t4 lookup table success!\n");
-
- ret = test_ops->f_des(table);
- if (ret != 0) {
- printf("destroy table fail!!!\n");
- exit(EXIT_FAILURE);
- }
- printf("\t5 destroy table success!\n");
-
- printf("all test finished success!!\n");
-
- if (odp_term_local()) {
- ODPH_ERR("Error: ODP local term failed.\n");
- exit(EXIT_FAILURE);
- }
-
- if (odp_term_global(instance)) {
- ODPH_ERR("Error: ODP global term failed.\n");
- exit(EXIT_FAILURE);
- }
-
- return 0;
-}
diff --git a/helper/threads.c b/helper/threads.c
index 72003d0f4..5063725b2 100644
--- a/helper/threads.c
+++ b/helper/threads.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2013-2018 Linaro Limited
- * Copyright (c) 2019-2022 Nokia
+ * Copyright (c) 2019-2024 Nokia
*/
#ifndef _GNU_SOURCE
@@ -21,8 +21,8 @@
#include <inttypes.h>
#include <odp_api.h>
+#include <odp/helper/debug.h>
#include <odp/helper/threads.h>
-#include <odp/helper/odph_debug.h>
#define FAILED_CPU -1
@@ -144,10 +144,10 @@ static int create_process(odph_thread_t *thread, int cpu, uint64_t stack_size)
/*
* Wait single process to exit
*/
-static int wait_process(odph_thread_t *thread)
+static int wait_process(odph_thread_t *thread, odph_thread_join_result_t *res)
{
pid_t pid;
- int status = 0;
+ int status = 0, estatus;
pid = waitpid(thread->proc.pid, &status, 0);
@@ -157,19 +157,27 @@ static int wait_process(odph_thread_t *thread)
}
/* Examine the child process' termination status */
- if (WIFEXITED(status) &&
- WEXITSTATUS(status) != EXIT_SUCCESS) {
- ODPH_ERR("Child exit status:%d (pid:%d)\n",
- WEXITSTATUS(status), (int)pid);
- return -1;
- }
-
- if (WIFSIGNALED(status)) {
+ if (WIFEXITED(status)) {
+ estatus = WEXITSTATUS(status);
+
+ if (res != NULL) {
+ res->is_sig = false;
+ res->ret = estatus;
+ } else if (estatus != EXIT_SUCCESS) {
+ ODPH_ERR("Child exit status:%d (pid:%d)\n", estatus, (int)pid);
+ return -1;
+ }
+ } else {
int signo = WTERMSIG(status);
- ODPH_ERR("Child term signo:%d - %s (pid:%d)\n",
- signo, strsignal(signo), (int)pid);
- return -1;
+ if (res != NULL) {
+ res->is_sig = true;
+ res->ret = signo;
+ } else {
+ ODPH_ERR("Child term signo:%d - %s (pid:%d)\n", signo, strsignal(signo),
+ (int)pid);
+ return -1;
+ }
}
return 0;
@@ -229,7 +237,7 @@ static int create_pthread(odph_thread_t *thread, int cpu, uint64_t stack_size)
/*
* Wait single pthread to exit
*/
-static int wait_pthread(odph_thread_t *thread)
+static int wait_pthread(odph_thread_t *thread, odph_thread_join_result_t *res)
{
int ret;
void *thread_ret = NULL;
@@ -243,9 +251,11 @@ static int wait_pthread(odph_thread_t *thread)
return -1;
}
- if (thread_ret) {
- ODPH_ERR("Bad exit status cpu #%i %p\n",
- thread->cpu, thread_ret);
+ if (res != NULL) {
+ res->is_sig = false;
+ res->ret = (int)(intptr_t)thread_ret;
+ } else if (thread_ret) {
+ ODPH_ERR("Bad exit status cpu #%i %p\n", thread->cpu, thread_ret);
return -1;
}
@@ -254,7 +264,9 @@ static int wait_pthread(odph_thread_t *thread)
if (ret) {
ODPH_ERR("pthread_attr_destroy failed (%i) from cpu #%i\n",
ret, thread->cpu);
- return -1;
+
+ if (res == NULL)
+ return -1;
}
return 0;
@@ -380,7 +392,7 @@ int odph_thread_create(odph_thread_t thread[],
return i;
}
-int odph_thread_join(odph_thread_t thread[], int num)
+static int join_threads(odph_thread_t thread[], odph_thread_join_result_t res[], int num)
{
odph_thread_start_args_t *start_args;
int i;
@@ -389,15 +401,15 @@ int odph_thread_join(odph_thread_t thread[], int num)
start_args = &thread[i].start_args;
if (start_args->status != STARTED) {
- ODPH_DBG("Thread (i:%i) not started.\n", i);
+ ODPH_ERR("Thread (i:%i) not started.\n", i);
break;
}
if (thread[i].start_args.mem_model == ODP_MEM_MODEL_THREAD) {
- if (wait_pthread(&thread[i]))
+ if (wait_pthread(&thread[i], res != NULL ? &res[i] : NULL))
break;
} else {
- if (wait_process(&thread[i]))
+ if (wait_process(&thread[i], res != NULL ? &res[i] : NULL))
break;
}
@@ -407,6 +419,31 @@ int odph_thread_join(odph_thread_t thread[], int num)
return i;
}
+int odph_thread_join(odph_thread_t thread[], int num)
+{
+ if (thread == NULL) {
+ ODPH_ERR("Bad thread table pointer\n");
+ return -1;
+ }
+
+ return join_threads(thread, NULL, num);
+}
+
+int odph_thread_join_result(odph_thread_t thread[], odph_thread_join_result_t res[], int num)
+{
+ if (thread == NULL) {
+ ODPH_ERR("Bad thread table pointer\n");
+ return -1;
+ }
+
+ if (res == NULL) {
+ ODPH_ERR("Bad result table pointer\n");
+ return -1;
+ }
+
+ return join_threads(thread, res, num);
+}
+
/* man gettid() notes:
* Glibc does not provide a wrapper for this system call;
*/