summaryrefslogtreecommitdiff
path: root/lib/hook.h
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2020-01-20 11:12:26 +0100
committerDavid Lamparter <equinox@diac24.net>2020-04-01 06:53:26 +0200
commit8d0a2918e8c517731b4b71a4d9f40693938e6385 (patch)
tree77fc7c2adacab1eff61f20d7e5a73fc740b4adba /lib/hook.h
parent1c4086281f72fd8b6fdf824a6edfaebe1871e383 (diff)
lib/hook: use static hook entry when possible
hook_register() invocations generally are in some initialization function and not looped over or similar. We can use a static struct hookent variable for the hook list entry in 99.999% of cases, so let's do that and not malloc() memory. Signed-off-by: David Lamparter <equinox@diac24.net>
Diffstat (limited to 'lib/hook.h')
-rw-r--r--lib/hook.h28
1 files changed, 21 insertions, 7 deletions
diff --git a/lib/hook.h b/lib/hook.h
index f7fb7b8a5c..3823cebe6a 100644
--- a/lib/hook.h
+++ b/lib/hook.h
@@ -114,7 +114,9 @@ struct hookent {
struct hookent *next;
void *hookfn; /* actually a function pointer */
void *hookarg;
- bool has_arg;
+ bool has_arg : 1;
+ bool ent_on_heap : 1;
+ bool ent_used : 1;
int priority;
struct frrmod_runtime *module;
const char *fnname;
@@ -133,21 +135,33 @@ struct hook {
* always use hook_register(), which uses the static inline helper from
* DECLARE_HOOK in order to get type safety
*/
-extern void _hook_register(struct hook *hook, void *funcptr, void *arg,
- bool has_arg, struct frrmod_runtime *module,
+extern void _hook_register(struct hook *hook, struct hookent *stackent,
+ void *funcptr, void *arg, bool has_arg,
+ struct frrmod_runtime *module,
const char *funcname, int priority);
+
+/* most hook_register calls are not in a loop or similar and can use a
+ * statically allocated "struct hookent" from the data segment
+ */
+#define _hook_reg_svar(hook, funcptr, arg, has_arg, module, funcname, prio) \
+ do { \
+ static struct hookent stack_hookent = { .ent_on_heap = 0, }; \
+ _hook_register(hook, &stack_hookent, funcptr, arg, has_arg, \
+ module, funcname, prio); \
+ } while (0)
+
#define hook_register(hookname, func) \
- _hook_register(&_hook_##hookname, _hook_typecheck_##hookname(func), \
+ _hook_reg_svar(&_hook_##hookname, _hook_typecheck_##hookname(func), \
NULL, false, THIS_MODULE, #func, HOOK_DEFAULT_PRIORITY)
#define hook_register_arg(hookname, func, arg) \
- _hook_register(&_hook_##hookname, \
+ _hook_reg_svar(&_hook_##hookname, \
_hook_typecheck_arg_##hookname(func), arg, true, \
THIS_MODULE, #func, HOOK_DEFAULT_PRIORITY)
#define hook_register_prio(hookname, prio, func) \
- _hook_register(&_hook_##hookname, _hook_typecheck_##hookname(func), \
+ _hook_reg_svar(&_hook_##hookname, _hook_typecheck_##hookname(func), \
NULL, false, THIS_MODULE, #func, prio)
#define hook_register_arg_prio(hookname, prio, func, arg) \
- _hook_register(&_hook_##hookname, \
+ _hook_reg_svar(&_hook_##hookname, \
_hook_typecheck_arg_##hookname(func), arg, true, \
THIS_MODULE, #func, prio)