forked from Mirror/frr
lib/table: remove nonsensical const, add pure
Passing the struct route_table *ptr as const doesn't really help; if anything it semantically would imply that the returned route_node is const too since constness should propagate (but it doesn't in C.) The right thing to do here - which actually helps the compiler optimize the code too - is to tag functions with __attribute__((pure)). The compiler does this automatically if it has the function body (and the body of all called functions) available. That should cover most "static inline" functions in headers, as well as functions in the same file. However, this doesn't work (at least without LTO) for extern functions. Hence, add "ext_pure" for this case. (Built-in "extern" to make lines shorter.) Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
parent
0734f93b8e
commit
3b18b6c03d
|
@ -76,6 +76,15 @@ extern "C" {
|
||||||
#define _DEPRECATED(x) deprecated
|
#define _DEPRECATED(x) deprecated
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* pure = function does not modify memory & return value is the same if
|
||||||
|
* memory hasn't changed (=> allows compiler to optimize)
|
||||||
|
*
|
||||||
|
* Mostly autodetected by the compiler if function body is available (i.e.
|
||||||
|
* static inline functions in headers). Since that implies it should only be
|
||||||
|
* used in headers for non-inline functions, the "extern" is included here.
|
||||||
|
*/
|
||||||
|
#define ext_pure extern __attribute__((pure))
|
||||||
|
|
||||||
/* for helper functions defined inside macros */
|
/* for helper functions defined inside macros */
|
||||||
#define macro_inline static inline __attribute__((unused))
|
#define macro_inline static inline __attribute__((unused))
|
||||||
#define macro_pure static inline __attribute__((unused, pure))
|
#define macro_pure static inline __attribute__((unused, pure))
|
||||||
|
|
18
lib/table.c
18
lib/table.c
|
@ -191,7 +191,7 @@ static void set_link(struct route_node *node, struct route_node *new)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find matched prefix. */
|
/* Find matched prefix. */
|
||||||
struct route_node *route_node_match(const struct route_table *table,
|
struct route_node *route_node_match(struct route_table *table,
|
||||||
union prefixconstptr pu)
|
union prefixconstptr pu)
|
||||||
{
|
{
|
||||||
const struct prefix *p = pu.p;
|
const struct prefix *p = pu.p;
|
||||||
|
@ -221,7 +221,7 @@ struct route_node *route_node_match(const struct route_table *table,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct route_node *route_node_match_ipv4(const struct route_table *table,
|
struct route_node *route_node_match_ipv4(struct route_table *table,
|
||||||
const struct in_addr *addr)
|
const struct in_addr *addr)
|
||||||
{
|
{
|
||||||
struct prefix_ipv4 p;
|
struct prefix_ipv4 p;
|
||||||
|
@ -234,7 +234,7 @@ struct route_node *route_node_match_ipv4(const struct route_table *table,
|
||||||
return route_node_match(table, (struct prefix *)&p);
|
return route_node_match(table, (struct prefix *)&p);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct route_node *route_node_match_ipv6(const struct route_table *table,
|
struct route_node *route_node_match_ipv6(struct route_table *table,
|
||||||
const struct in6_addr *addr)
|
const struct in6_addr *addr)
|
||||||
{
|
{
|
||||||
struct prefix_ipv6 p;
|
struct prefix_ipv6 p;
|
||||||
|
@ -248,7 +248,7 @@ struct route_node *route_node_match_ipv6(const struct route_table *table,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup same prefix node. Return NULL when we can't find route. */
|
/* Lookup same prefix node. Return NULL when we can't find route. */
|
||||||
struct route_node *route_node_lookup(const struct route_table *table,
|
struct route_node *route_node_lookup(struct route_table *table,
|
||||||
union prefixconstptr pu)
|
union prefixconstptr pu)
|
||||||
{
|
{
|
||||||
struct route_node rn, *node;
|
struct route_node rn, *node;
|
||||||
|
@ -260,7 +260,7 @@ struct route_node *route_node_lookup(const struct route_table *table,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup same prefix node. Return NULL when we can't find route. */
|
/* Lookup same prefix node. Return NULL when we can't find route. */
|
||||||
struct route_node *route_node_lookup_maynull(const struct route_table *table,
|
struct route_node *route_node_lookup_maynull(struct route_table *table,
|
||||||
union prefixconstptr pu)
|
union prefixconstptr pu)
|
||||||
{
|
{
|
||||||
struct route_node rn, *node;
|
struct route_node rn, *node;
|
||||||
|
@ -272,7 +272,7 @@ struct route_node *route_node_lookup_maynull(const struct route_table *table,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add node to routing table. */
|
/* Add node to routing table. */
|
||||||
struct route_node *route_node_get(struct route_table *const table,
|
struct route_node *route_node_get(struct route_table *table,
|
||||||
union prefixconstptr pu)
|
union prefixconstptr pu)
|
||||||
{
|
{
|
||||||
struct route_node search;
|
struct route_node search;
|
||||||
|
@ -471,7 +471,7 @@ struct route_node *route_next_until(struct route_node *node,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long route_table_count(const struct route_table *table)
|
unsigned long route_table_count(struct route_table *table)
|
||||||
{
|
{
|
||||||
return table->count;
|
return table->count;
|
||||||
}
|
}
|
||||||
|
@ -606,7 +606,7 @@ static struct route_node *route_get_subtree_next(struct route_node *node)
|
||||||
* @see route_table_get_next
|
* @see route_table_get_next
|
||||||
*/
|
*/
|
||||||
static struct route_node *
|
static struct route_node *
|
||||||
route_table_get_next_internal(const struct route_table *table,
|
route_table_get_next_internal(struct route_table *table,
|
||||||
const struct prefix *p)
|
const struct prefix *p)
|
||||||
{
|
{
|
||||||
struct route_node *node, *tmp_node;
|
struct route_node *node, *tmp_node;
|
||||||
|
@ -707,7 +707,7 @@ route_table_get_next_internal(const struct route_table *table,
|
||||||
* Find the node that occurs after the given prefix in order of
|
* Find the node that occurs after the given prefix in order of
|
||||||
* iteration.
|
* iteration.
|
||||||
*/
|
*/
|
||||||
struct route_node *route_table_get_next(const struct route_table *table,
|
struct route_node *route_table_get_next(struct route_table *table,
|
||||||
union prefixconstptr pu)
|
union prefixconstptr pu)
|
||||||
{
|
{
|
||||||
const struct prefix *p = pu.p;
|
const struct prefix *p = pu.p;
|
||||||
|
|
49
lib/table.h
49
lib/table.h
|
@ -198,26 +198,29 @@ static inline void route_table_set_info(struct route_table *table, void *d)
|
||||||
table->info = d;
|
table->info = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void route_table_finish(struct route_table *table);
|
/* ext_pure => extern __attribute__((pure))
|
||||||
extern struct route_node *route_top(struct route_table *table);
|
* does not modify memory (but depends on mem), allows compiler to optimize
|
||||||
extern struct route_node *route_next(struct route_node *node);
|
*/
|
||||||
extern struct route_node *route_next_until(struct route_node *node,
|
|
||||||
const struct route_node *limit);
|
|
||||||
extern struct route_node *route_node_get(struct route_table *const table,
|
|
||||||
union prefixconstptr pu);
|
|
||||||
extern struct route_node *route_node_lookup(const struct route_table *table,
|
|
||||||
union prefixconstptr pu);
|
|
||||||
extern struct route_node *
|
|
||||||
route_node_lookup_maynull(const struct route_table *table,
|
|
||||||
union prefixconstptr pu);
|
|
||||||
extern struct route_node *route_node_match(const struct route_table *table,
|
|
||||||
union prefixconstptr pu);
|
|
||||||
extern struct route_node *route_node_match_ipv4(const struct route_table *table,
|
|
||||||
const struct in_addr *addr);
|
|
||||||
extern struct route_node *route_node_match_ipv6(const struct route_table *table,
|
|
||||||
const struct in6_addr *addr);
|
|
||||||
|
|
||||||
extern unsigned long route_table_count(const struct route_table *table);
|
extern void route_table_finish(struct route_table *table);
|
||||||
|
ext_pure struct route_node *route_top(struct route_table *table);
|
||||||
|
ext_pure struct route_node *route_next(struct route_node *node);
|
||||||
|
ext_pure struct route_node *route_next_until(struct route_node *node,
|
||||||
|
const struct route_node *limit);
|
||||||
|
extern struct route_node *route_node_get(struct route_table *table,
|
||||||
|
union prefixconstptr pu);
|
||||||
|
ext_pure struct route_node *route_node_lookup(struct route_table *table,
|
||||||
|
union prefixconstptr pu);
|
||||||
|
ext_pure struct route_node *route_node_lookup_maynull(struct route_table *table,
|
||||||
|
union prefixconstptr pu);
|
||||||
|
ext_pure struct route_node *route_node_match(struct route_table *table,
|
||||||
|
union prefixconstptr pu);
|
||||||
|
ext_pure struct route_node *route_node_match_ipv4(struct route_table *table,
|
||||||
|
const struct in_addr *addr);
|
||||||
|
ext_pure struct route_node *route_node_match_ipv6(struct route_table *table,
|
||||||
|
const struct in6_addr *addr);
|
||||||
|
|
||||||
|
ext_pure unsigned long route_table_count(struct route_table *table);
|
||||||
|
|
||||||
extern struct route_node *route_node_create(route_table_delegate_t *delegate,
|
extern struct route_node *route_node_create(route_table_delegate_t *delegate,
|
||||||
struct route_table *table);
|
struct route_table *table);
|
||||||
|
@ -226,10 +229,10 @@ extern void route_node_destroy(route_table_delegate_t *delegate,
|
||||||
struct route_table *table,
|
struct route_table *table,
|
||||||
struct route_node *node);
|
struct route_node *node);
|
||||||
|
|
||||||
extern struct route_node *route_table_get_next(const struct route_table *table,
|
ext_pure struct route_node *route_table_get_next(struct route_table *table,
|
||||||
union prefixconstptr pu);
|
union prefixconstptr pu);
|
||||||
extern int route_table_prefix_iter_cmp(const struct prefix *p1,
|
ext_pure int route_table_prefix_iter_cmp(const struct prefix *p1,
|
||||||
const struct prefix *p2);
|
const struct prefix *p2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iterator functions.
|
* Iterator functions.
|
||||||
|
|
Loading…
Reference in a new issue