aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/odp_sorted_list.c
diff options
context:
space:
mode:
authorBill Fischofer <bill.fischofer@linaro.org>2015-11-17 18:16:38 -0600
committerMaxim Uvarov <maxim.uvarov@linaro.org>2015-11-24 16:45:08 +0300
commit98e272e7b836938b60125ed43f69255c7d474e71 (patch)
tree42b0dd53f8d4e707feeb98df6166ed8207ad2c41 /platform/linux-generic/odp_sorted_list.c
parente1eeca3bb3e45d5194a07b41078b7562ce7ff526 (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.c271
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);
+}