diff options
author | Bill Fischofer <bill.fischofer@linaro.org> | 2015-11-17 18:16:38 -0600 |
---|---|---|
committer | Maxim Uvarov <maxim.uvarov@linaro.org> | 2015-11-24 16:45:08 +0300 |
commit | 98e272e7b836938b60125ed43f69255c7d474e71 (patch) | |
tree | 42b0dd53f8d4e707feeb98df6166ed8207ad2c41 /platform/linux-generic/odp_sorted_list.c | |
parent | e1eeca3bb3e45d5194a07b41078b7562ce7ff526 (diff) |
linux-generic: tm: implement traffic manager
Signed-off-by: Barry Spinney <spinney@ezchip.com>
Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'platform/linux-generic/odp_sorted_list.c')
-rw-r--r-- | platform/linux-generic/odp_sorted_list.c | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/platform/linux-generic/odp_sorted_list.c b/platform/linux-generic/odp_sorted_list.c new file mode 100644 index 000000000..221754ddb --- /dev/null +++ b/platform/linux-generic/odp_sorted_list.c @@ -0,0 +1,271 @@ +/* Copyright 2015 EZchip Semiconductor Ltd. All Rights Reserved. + * + * Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> +#include <string.h> +#include <malloc.h> +#include <stdio.h> +#include <odp.h> +#include <odp_debug_internal.h> +#include <odp_sorted_list_internal.h> + +typedef struct sorted_list_item_s sorted_list_item_t; + +struct sorted_list_item_s { + sorted_list_item_t *next_item; + uint64_t sort_key; + uint64_t user_data; +}; + +typedef struct { + sorted_list_item_t *first_item; + uint32_t sorted_list_len; + uint32_t pad; +} sorted_list_desc_t; + +typedef struct { + sorted_list_desc_t descs[0]; +} sorted_list_descs_t; + +typedef struct { + uint64_t total_inserts; + uint64_t total_deletes; + uint64_t total_removes; + uint32_t max_sorted_lists; + uint32_t next_list_idx; + sorted_list_descs_t *list_descs; +} sorted_pool_t; + +_odp_int_sorted_pool_t _odp_sorted_pool_create(uint32_t max_sorted_lists) +{ + sorted_list_descs_t *list_descs; + sorted_pool_t *pool; + uint32_t malloc_len; + + pool = malloc(sizeof(sorted_pool_t)); + memset(pool, 0, sizeof(sorted_pool_t)); + pool->max_sorted_lists = max_sorted_lists; + pool->next_list_idx = 1; + + malloc_len = max_sorted_lists * sizeof(sorted_list_desc_t); + list_descs = malloc(malloc_len); + memset(list_descs, 0, malloc_len); + pool->list_descs = list_descs; + return (_odp_int_sorted_pool_t)pool; +} + +_odp_int_sorted_list_t +_odp_sorted_list_create(_odp_int_sorted_pool_t sorted_pool, + uint32_t max_entries ODP_UNUSED) +{ + sorted_pool_t *pool; + uint32_t list_idx; + + pool = (sorted_pool_t *)sorted_pool; + list_idx = pool->next_list_idx++; + return (_odp_int_sorted_list_t)list_idx; +} + +int _odp_sorted_list_insert(_odp_int_sorted_pool_t sorted_pool, + _odp_int_sorted_list_t sorted_list, + uint64_t sort_key, + uint64_t user_data) +{ + sorted_list_desc_t *list_desc; + sorted_list_item_t *new_list_item, *list_item, *prev_list_item; + sorted_pool_t *pool; + uint32_t list_idx; + + pool = (sorted_pool_t *)sorted_pool; + list_idx = (uint32_t)sorted_list; + if ((pool->next_list_idx <= list_idx) || + (pool->max_sorted_lists <= list_idx)) + return -1; + + list_desc = &pool->list_descs->descs[list_idx]; + new_list_item = malloc(sizeof(sorted_list_item_t)); + memset(new_list_item, 0, sizeof(sorted_list_item_t)); + new_list_item->next_item = NULL; + new_list_item->sort_key = sort_key; + new_list_item->user_data = user_data; + + /* Now insert the new_list_item according to the sort_key (lowest + * value first). + */ + list_item = list_desc->first_item; + prev_list_item = NULL; + while ((list_item) && (list_item->sort_key <= sort_key)) { + prev_list_item = list_item; + list_item = list_item->next_item; + } + + new_list_item->next_item = list_item; + if (!prev_list_item) + list_desc->first_item = new_list_item; + else + prev_list_item->next_item = new_list_item; + + list_desc->sorted_list_len++; + pool->total_inserts++; + return 0; +} + +int _odp_sorted_list_find(_odp_int_sorted_pool_t sorted_pool, + _odp_int_sorted_list_t sorted_list, + uint64_t user_data, + uint64_t *sort_key_ptr) +{ + sorted_list_desc_t *list_desc; + sorted_list_item_t *list_item; + sorted_pool_t *pool; + uint32_t list_idx; + + pool = (sorted_pool_t *)sorted_pool; + list_idx = (uint32_t)sorted_list; + if ((pool->next_list_idx <= list_idx) || + (pool->max_sorted_lists <= list_idx)) + return -1; + + list_desc = &pool->list_descs->descs[list_idx]; + + /* Now search the sorted linked list - as described by list_desc - + * until an entry is found whose user_data field matches the supplied + * user_data or the end of the list is reached. + */ + list_item = list_desc->first_item; + while (list_item) { + if (list_item->user_data == user_data) { + if (sort_key_ptr) + *sort_key_ptr = list_item->sort_key; + + return 1; + } + + list_item = list_item->next_item; + } + + return 0; +} + +int _odp_sorted_list_delete(_odp_int_sorted_pool_t sorted_pool, + _odp_int_sorted_list_t sorted_list, + uint64_t user_data) +{ + sorted_list_desc_t *list_desc; + sorted_list_item_t *next_list_item, *list_item, *prev_list_item; + sorted_pool_t *pool; + uint32_t list_idx; + + pool = (sorted_pool_t *)sorted_pool; + list_idx = (uint32_t)sorted_list; + if ((pool->next_list_idx <= list_idx) || + (pool->max_sorted_lists <= list_idx)) + return -1; + + list_desc = &pool->list_descs->descs[list_idx]; + + /* Now search the sorted linked list - as described by list_desc - + * until an entry is found whose user_data field matches the supplied + * user_data or the end of the list is reached. + */ + list_item = list_desc->first_item; + prev_list_item = NULL; + while (list_item) { + next_list_item = list_item->next_item; + + if (list_item->user_data == user_data) { + if (!prev_list_item) + list_desc->first_item = next_list_item; + else + prev_list_item->next_item = next_list_item; + + list_desc->sorted_list_len--; + free(list_item); + pool->total_deletes++; + return 0; + } + + prev_list_item = list_item; + list_item = next_list_item; + } + + return -1; +} + +int _odp_sorted_list_remove(_odp_int_sorted_pool_t sorted_pool, + _odp_int_sorted_list_t sorted_list, + uint64_t *sort_key_ptr, + uint64_t *user_data_ptr) +{ + sorted_list_desc_t *list_desc; + sorted_list_item_t *list_item; + sorted_pool_t *pool; + uint32_t list_idx; + + pool = (sorted_pool_t *)sorted_pool; + list_idx = (uint32_t)sorted_list; + if ((pool->next_list_idx <= list_idx) || + (pool->max_sorted_lists <= list_idx)) + return -1; + + list_desc = &pool->list_descs->descs[list_idx]; + if ((list_desc->sorted_list_len == 0) || + (!list_desc->first_item)) + return -1; + + list_item = list_desc->first_item; + list_desc->first_item = list_item->next_item; + list_desc->sorted_list_len--; + + if (sort_key_ptr) + *sort_key_ptr = list_item->sort_key; + + if (user_data_ptr) + *user_data_ptr = list_item->user_data; + + free(list_item); + pool->total_removes++; + return 1; +} + +void _odp_sorted_list_stats_print(_odp_int_sorted_pool_t sorted_pool) +{ + sorted_pool_t *pool; + + pool = (sorted_pool_t *)sorted_pool; + ODP_DBG("sorted_pool=0x%lX\n", sorted_pool); + ODP_DBG(" max_sorted_lists=%u next_list_idx=%u\n", + pool->max_sorted_lists, pool->next_list_idx); + ODP_DBG(" total_inserts=%lu total_deletes=%lu total_removes=%lu\n", + pool->total_inserts, pool->total_deletes, pool->total_removes); +} + +void _odp_sorted_pool_destroy(_odp_int_sorted_pool_t sorted_pool) +{ + sorted_list_descs_t *list_descs; + sorted_list_desc_t *list_desc; + sorted_list_item_t *list_item, *next_list_item; + sorted_pool_t *pool; + uint32_t list_idx; + + pool = (sorted_pool_t *)sorted_pool; + list_descs = pool->list_descs; + + for (list_idx = 0; list_idx < pool->next_list_idx; list_idx++) { + list_desc = &list_descs->descs[list_idx]; + list_item = list_desc->first_item; + while (list_item) { + next_list_item = list_item->next_item; + free(list_item); + list_item = next_list_item; + } + } + + free(list_descs); + free(pool); +} |