On 05.11.15 13:20, huanggaoyang wrote:
Signed-off-by: huanggaoyang <huanggaoya...@huawei.com> --- helper/lineartable.c | 210 ++++++++++++++++++++++++++++++++++++++++++++++ helper/odph_lineartable.h | 41 +++++++++ 2 files changed, 251 insertions(+) create mode 100644 helper/lineartable.c create mode 100644 helper/odph_lineartable.h diff --git a/helper/lineartable.c b/helper/lineartable.c new file mode 100644 index 0000000..7809a52 --- /dev/null +++ b/helper/lineartable.c @@ -0,0 +1,210 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdio.h> +#include <string.h> +#include <malloc.h> + +#include "odph_lineartable.h" +#include "odph_debug.h" +#include <odp.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, caculate 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 ODP_IGNORED, uint32_t value_size) +{ + int 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 confict in shm*/ + tbl = (odph_linear_table_imp *)odp_shm_addr(odp_shm_lookup(name)); + if (tbl != NULL) { + ODPH_DBG("name already exist\n"); + return NULL; + } + + /* alloc memory from shm */ + shmem = odp_shm_reserve(name, capacity << 20, 64, ODP_SHM_SW_ONLY); + 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); + + /* for linear table, the key is just the index, without confict + * 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 = (odp_rwlock_t *)((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 *)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) +{ + int idx; + odph_linear_table_imp *tbl; + + if (name == NULL || strlen(name) >= ODPH_TABLE_NAME_LEN) + return NULL; + + tbl = (odph_linear_table_imp *)odp_shm_addr(odp_shm_lookup(name)); + + /* 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 */ +int odph_lineartable_put_value(odph_table_t table, void *key, void *value) +{ + odph_linear_table_imp *tbl = (odph_linear_table_imp *)table; + uint32_t ikey = 0; + void *entry = NULL; + odp_rwlock_t *lock = NULL; + + if (table == NULL || key == NULL || value == NULL) + return ODPH_FAIL; + + 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 */ +int odph_lineartable_get_value(odph_table_t table, void *key, void *buffer, + uint32_t buffer_size) +{ + odph_linear_table_imp *tbl = (odph_linear_table_imp *)table; + uint32_t ikey = 0; + void *entry = NULL; + odp_rwlock_t *lock = NULL; + + if (table == NULL || key == NULL || buffer == NULL) + return ODPH_FAIL; + + 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/odph_lineartable.h b/helper/odph_lineartable.h new file mode 100644 index 0000000..a53c68b --- /dev/null +++ b/helper/odph_lineartable.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP Linear Table + */ + +#ifndef ODPH_LINEAR_TABLE_H_ +#define ODPH_LINEAR_TABLE_H_ + +#include <stdint.h> +#include <odp/plat/strong_types.h>
platform dependent inclusion. Maxim, it's already in master branch and should be fixed.
+#include <odp/helper/table.h> + +#ifdef __cplusplus +extern "C" { +#endif + +odph_table_t odph_linear_table_create(const char *name, + uint32_t capacity, + uint32_t ODP_IGNORED, + uint32_t value_size); +odph_table_t odph_linear_table_lookup(const char *name); +int odph_linear_table_destroy(odph_table_t table); +int odph_linear_put_value(odph_table_t table, void *key, void *value); +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; + +#ifdef __cplusplus +} +#endif + +#endif +
-- Regards, Ivan Khoronzhuk _______________________________________________ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp