]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: remove pure attribute from functions that modify memory
authorIgor Ryzhov <iryzhov@nfware.com>
Fri, 18 Jun 2021 10:06:13 +0000 (13:06 +0300)
committermergify-bot <noreply@mergify.io>
Sat, 19 Jun 2021 12:56:37 +0000 (12:56 +0000)
Almost all functions currently marked with pure attribute acquire a
route_node lock. By marking them pure we allow compiler to optimize the
code and not call them when it already knows the return value. This is
completely incorrect.

Only two of eleven functions can be marked as pure. And they still won't
be optimized because they are never called from the same function twice.
Let's remove the ext_pure macro completely to reduce the chance of
repeating this mistake in the future.

Fixes #8866, #8809, #8595, #6992.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
(cherry picked from commit 4f08c715db6893ff439d0a39bf4506cd26256d13)

lib/compiler.h
lib/table.h

index e430925e69723a10c3c2e362bfdad38b0cf93d06..2de042662517156ef4ba13a104e1ca86da5998e8 100644 (file)
@@ -108,15 +108,6 @@ extern "C" {
 #define assume(x)
 #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 */
 #define macro_inline   static inline __attribute__((unused))
 #define macro_pure     static inline __attribute__((unused, pure))
index 7a69c1664f4a24319151f1e0f3a77ff5100a4006..cbcb6a389c0aff0502eae706cc1b6b382f87fc69 100644 (file)
@@ -197,29 +197,25 @@ static inline void route_table_set_info(struct route_table *table, void *d)
        table->info = d;
 }
 
-/* ext_pure => extern __attribute__((pure))
- *   does not modify memory (but depends on mem), allows compiler to optimize
- */
-
 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_top(struct route_table *table);
+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 *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_lookup(struct route_table *table,
+                                           union prefixconstptr pu);
+extern struct route_node *route_node_lookup_maynull(struct route_table *table,
+                                                   union prefixconstptr pu);
+extern struct route_node *route_node_match(struct route_table *table,
+                                          union prefixconstptr pu);
+extern struct route_node *route_node_match_ipv4(struct route_table *table,
+                                               const struct in_addr *addr);
+extern struct route_node *route_node_match_ipv6(struct route_table *table,
+                                               const struct in6_addr *addr);
+
+extern unsigned long route_table_count(struct route_table *table);
 
 extern struct route_node *route_node_create(route_table_delegate_t *delegate,
                                            struct route_table *table);
@@ -228,10 +224,10 @@ extern void route_node_destroy(route_table_delegate_t *delegate,
                               struct route_table *table,
                               struct route_node *node);
 
-ext_pure struct route_node *route_table_get_next(struct route_table *table,
-                                                union prefixconstptr pu);
-ext_pure int route_table_prefix_iter_cmp(const struct prefix *p1,
-                                        const struct prefix *p2);
+extern struct route_node *route_table_get_next(struct route_table *table,
+                                              union prefixconstptr pu);
+extern int route_table_prefix_iter_cmp(const struct prefix *p1,
+                                      const struct prefix *p2);
 
 /*
  * Iterator functions.