numam-dpdk/lib/graph/graph_ops.c
Bruce Richardson 99a2dd955f lib: remove librte_ prefix from directory names
There is no reason for the DPDK libraries to all have 'librte_' prefix on
the directory names. This prefix makes the directory names longer and also
makes it awkward to add features referring to individual libraries in the
build - should the lib names be specified with or without the prefix.
Therefore, we can just remove the library prefix and use the library's
unique name as the directory name, i.e. 'eal' rather than 'librte_eal'

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
2021-04-21 14:04:09 +02:00

170 lines
3.4 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2020 Marvell International Ltd.
*/
#include <stdbool.h>
#include <string.h>
#include <rte_common.h>
#include <rte_errno.h>
#include "graph_private.h"
/* Check whether a node has next_node to itself */
static inline int
node_has_loop_edge(struct node *node)
{
rte_edge_t i;
char *name;
int rc = 0;
for (i = 0; i < node->nb_edges; i++) {
if (strncmp(node->name, node->next_nodes[i],
RTE_NODE_NAMESIZE) == 0) {
name = node->name;
rc = 1;
SET_ERR_JMP(EINVAL, fail, "Node %s has loop to self",
name);
}
}
fail:
return rc;
}
int
graph_node_has_loop_edge(struct graph *graph)
{
struct graph_node *graph_node;
STAILQ_FOREACH(graph_node, &graph->node_list, next)
if (node_has_loop_edge(graph_node->node))
return 1;
return 0;
}
rte_node_t
graph_src_nodes_count(struct graph *graph)
{
struct graph_node *graph_node;
rte_node_t rc = 0;
STAILQ_FOREACH(graph_node, &graph->node_list, next)
if (graph_node->node->flags & RTE_NODE_SOURCE_F)
rc++;
if (rc == 0)
SET_ERR_JMP(EINVAL, fail, "Graph needs at least a source node");
fail:
return rc;
}
/* Check whether a node has next_node to a source node */
int
graph_node_has_edge_to_src_node(struct graph *graph)
{
struct graph_node *graph_node;
struct node *node;
rte_edge_t i;
STAILQ_FOREACH(graph_node, &graph->node_list, next) {
for (i = 0; i < graph_node->node->nb_edges; i++) {
node = graph_node->adjacency_list[i]->node;
if (node->flags & RTE_NODE_SOURCE_F)
SET_ERR_JMP(
EEXIST, fail,
"Node %s points to the source node %s",
graph_node->node->name, node->name);
}
}
return 0;
fail:
return 1;
}
rte_node_t
graph_nodes_count(struct graph *graph)
{
struct graph_node *graph_node;
rte_node_t count = 0;
STAILQ_FOREACH(graph_node, &graph->node_list, next)
count++;
return count;
}
void
graph_mark_nodes_as_not_visited(struct graph *graph)
{
struct graph_node *graph_node;
STAILQ_FOREACH(graph_node, &graph->node_list, next)
graph_node->visited = false;
}
int
graph_bfs(struct graph *graph, struct graph_node *start)
{
struct graph_node **queue, *v, *tmp;
uint16_t head = 0, tail = 0;
rte_edge_t i;
size_t sz;
sz = sizeof(struct graph_node *) * graph_nodes_count(graph);
queue = malloc(sz);
if (queue == NULL)
SET_ERR_JMP(ENOMEM, fail, "Failed to alloc BFS queue of %zu",
sz);
/* BFS algorithm */
queue[tail++] = start;
start->visited = true;
while (head != tail) {
v = queue[head++];
for (i = 0; i < v->node->nb_edges; i++) {
tmp = v->adjacency_list[i];
if (tmp->visited == false) {
queue[tail++] = tmp;
tmp->visited = true;
}
}
}
free(queue);
return 0;
fail:
return -rte_errno;
}
/* Check whether a node has connected path or parent node */
int
graph_has_isolated_node(struct graph *graph)
{
struct graph_node *graph_node;
graph_mark_nodes_as_not_visited(graph);
STAILQ_FOREACH(graph_node, &graph->node_list, next) {
if (graph_node->node->flags & RTE_NODE_SOURCE_F) {
if (graph_node->node->nb_edges == 0)
SET_ERR_JMP(EINVAL, fail,
"%s node needs minimum one edge",
graph_node->node->name);
if (graph_bfs(graph, graph_node))
goto fail;
}
}
STAILQ_FOREACH(graph_node, &graph->node_list, next)
if (graph_node->visited == false)
SET_ERR_JMP(EINVAL, fail, "Found isolated node %s",
graph_node->node->name);
return 0;
fail:
return 1;
}