From: Jerin Jacob <jer...@marvell.com>

Adding rte_node_register() API implementation includes allocating
memory for node object, check for duplicate node name and
add the allocated node to STAILQ node_list for future use.

Signed-off-by: Jerin Jacob <jer...@marvell.com>
Signed-off-by: Kiran Kumar K <kirankum...@marvell.com>
Signed-off-by: Pavan Nikhilesh <pbhagavat...@marvell.com>
---
 lib/librte_graph/Makefile              |   1 +
 lib/librte_graph/graph.c               |  18 +++-
 lib/librte_graph/graph_private.h       |  75 ++++++++++++++++
 lib/librte_graph/meson.build           |   2 +-
 lib/librte_graph/node.c                | 115 +++++++++++++++++++++++++
 lib/librte_graph/rte_graph_version.map |   4 +
 6 files changed, 213 insertions(+), 2 deletions(-)
 create mode 100644 lib/librte_graph/graph_private.h
 create mode 100644 lib/librte_graph/node.c

diff --git a/lib/librte_graph/Makefile b/lib/librte_graph/Makefile
index 26fe514f3..933d0ee49 100644
--- a/lib/librte_graph/Makefile
+++ b/lib/librte_graph/Makefile
@@ -14,6 +14,7 @@ LDLIBS += -lrte_eal
 EXPORT_MAP := rte_graph_version.map
 
 # all source are stored in SRCS-y
+SRCS-$(CONFIG_RTE_LIBRTE_GRAPH) += node.c
 SRCS-$(CONFIG_RTE_LIBRTE_GRAPH) += graph.c
 
 # install header files
diff --git a/lib/librte_graph/graph.c b/lib/librte_graph/graph.c
index a55bf443a..a9c124896 100644
--- a/lib/librte_graph/graph.c
+++ b/lib/librte_graph/graph.c
@@ -2,4 +2,20 @@
  * Copyright(C) 2020 Marvell International Ltd.
  */
 
-#include "rte_graph.h"
+#include <rte_spinlock.h>
+
+#include "graph_private.h"
+
+static rte_spinlock_t graph_lock = RTE_SPINLOCK_INITIALIZER;
+
+void
+graph_spinlock_lock(void)
+{
+       rte_spinlock_lock(&graph_lock);
+}
+
+void
+graph_spinlock_unlock(void)
+{
+       rte_spinlock_unlock(&graph_lock);
+}
diff --git a/lib/librte_graph/graph_private.h b/lib/librte_graph/graph_private.h
new file mode 100644
index 000000000..8b9ff5292
--- /dev/null
+++ b/lib/librte_graph/graph_private.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_GRAPH_PRIVATE_H_
+#define _RTE_GRAPH_PRIVATE_H_
+
+#include <inttypes.h>
+#include <sys/queue.h>
+
+#include <rte_common.h>
+#include <rte_eal.h>
+
+#include "rte_graph.h"
+
+/**
+ * @internal
+ *
+ * Structure that holds node internal data.
+ */
+struct node {
+       STAILQ_ENTRY(node) next;      /**< Next node in the list. */
+       char name[RTE_NODE_NAMESIZE]; /**< Name of the node. */
+       uint64_t flags;               /**< Node configuration flag. */
+       rte_node_process_t process;   /**< Node process function. */
+       rte_node_init_t init;         /**< Node init function. */
+       rte_node_fini_t fini;         /**< Node fini function. */
+       rte_node_t id;                /**< Allocated identifier for the node. */
+       rte_node_t parent_id;         /**< Parent node identifier. */
+       rte_edge_t nb_edges;          /**< Number of edges from this node. */
+       char next_nodes[][RTE_NODE_NAMESIZE]; /**< Names of next nodes. */
+};
+
+/* Node functions */
+STAILQ_HEAD(node_head, node);
+
+/**
+ * @internal
+ *
+ * Get the head of the node list.
+ *
+ * @return
+ *   Pointer to the node head.
+ */
+struct node_head *node_list_head_get(void);
+
+/**
+ * @internal
+ *
+ * Get node pointer from node name.
+ *
+ * @param name
+ *   Pointer to character string containing the node name.
+ *
+ * @return
+ *   Pointer to the node.
+ */
+struct node *node_from_name(const char *name);
+
+/* Lock functions */
+/**
+ * @internal
+ *
+ * Take a lock on the graph internal spin lock.
+ */
+void graph_spinlock_lock(void);
+
+/**
+ * @internal
+ *
+ * Release a lock on the graph internal spin lock.
+ */
+void graph_spinlock_unlock(void);
+
+#endif /* _RTE_GRAPH_PRIVATE_H_ */
diff --git a/lib/librte_graph/meson.build b/lib/librte_graph/meson.build
index 455cf2ba5..5754ac23b 100644
--- a/lib/librte_graph/meson.build
+++ b/lib/librte_graph/meson.build
@@ -4,7 +4,7 @@
 
 name = 'graph'
 
-sources = files('graph.c')
+sources = files('node.c', 'graph.c')
 headers = files('rte_graph.h')
 allow_experimental_apis = true
 
diff --git a/lib/librte_graph/node.c b/lib/librte_graph/node.c
new file mode 100644
index 000000000..7999ca6ed
--- /dev/null
+++ b/lib/librte_graph/node.c
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <rte_common.h>
+#include <rte_debug.h>
+#include <rte_eal.h>
+#include <rte_errno.h>
+#include <rte_string_fns.h>
+
+#include "graph_private.h"
+
+static struct node_head node_list = STAILQ_HEAD_INITIALIZER(node_list);
+static rte_node_t node_id;
+
+#define NODE_ID_CHECK(id) ID_CHECK(id, node_id)
+
+/* Private functions */
+struct node_head *
+node_list_head_get(void)
+{
+       return &node_list;
+}
+
+struct node *
+node_from_name(const char *name)
+{
+       struct node *node;
+
+       STAILQ_FOREACH(node, &node_list, next)
+               if (strncmp(node->name, name, RTE_NODE_NAMESIZE) == 0)
+                       return node;
+
+       return NULL;
+}
+
+static bool
+node_has_duplicate_entry(const char *name)
+{
+       struct node *node;
+
+       /* Is duplicate name registered */
+       STAILQ_FOREACH(node, &node_list, next) {
+               if (strncmp(node->name, name, RTE_NODE_NAMESIZE) == 0) {
+                       rte_errno = EEXIST;
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/* Public functions */
+rte_node_t
+__rte_node_register(const struct rte_node_register *reg)
+{
+       struct node *node;
+       rte_edge_t i;
+       size_t sz;
+
+       graph_spinlock_lock();
+
+       /* Check sanity */
+       if (reg == NULL || reg->process == NULL) {
+               rte_errno = EINVAL;
+               goto fail;
+       }
+
+       /* Check for duplicate name */
+       if (node_has_duplicate_entry(reg->name))
+               goto fail;
+
+       sz = sizeof(struct node) + (reg->nb_edges * RTE_NODE_NAMESIZE);
+       node = calloc(1, sz);
+       if (node == NULL) {
+               rte_errno = ENOMEM;
+               goto fail;
+       }
+
+       /* Initialize the node */
+       if (rte_strscpy(node->name, reg->name, RTE_NODE_NAMESIZE) < 0) {
+               rte_errno = E2BIG;
+               goto free;
+       }
+       node->flags = reg->flags;
+       node->process = reg->process;
+       node->init = reg->init;
+       node->fini = reg->fini;
+       node->nb_edges = reg->nb_edges;
+       node->parent_id = reg->parent_id;
+       for (i = 0; i < reg->nb_edges; i++) {
+               if (rte_strscpy(node->next_nodes[i], reg->next_nodes[i],
+                               RTE_NODE_NAMESIZE) < 0) {
+                       rte_errno = E2BIG;
+                       goto free;
+               }
+       }
+
+       node->id = node_id++;
+
+       /* Add the node at tail */
+       STAILQ_INSERT_TAIL(&node_list, node, next);
+       graph_spinlock_unlock();
+
+       return node->id;
+free:
+       free(node);
+fail:
+       graph_spinlock_unlock();
+       return RTE_NODE_ID_INVALID;
+}
+
diff --git a/lib/librte_graph/rte_graph_version.map 
b/lib/librte_graph/rte_graph_version.map
index 55ef35df5..0884c09f1 100644
--- a/lib/librte_graph/rte_graph_version.map
+++ b/lib/librte_graph/rte_graph_version.map
@@ -1,3 +1,7 @@
 EXPERIMENTAL {
+       global:
 
+       __rte_node_register;
+
+       local: *;
 };
-- 
2.25.1

Reply via email to