Add "key" to callback registration
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 15 Dec 2023 19:17:00 +0000 (14:17 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 15 Dec 2023 19:17:16 +0000 (14:17 -0500)
This is in preparation to support the state-dump feature.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/side/trace.h
src/side.c
src/tracer.c

index 5df637fb1634c6558c55169fef32b62e36f93e74..22d88c7b801c6ba1545ba25483fe388655747613 100644 (file)
@@ -81,6 +81,13 @@ void side_call(const struct side_event_state *state,
 void side_call_variadic(const struct side_event_state *state,
        const struct side_arg_vec *side_arg_vec,
        const struct side_arg_dynamic_struct *var_struct);
+void side_call_key(const struct side_event_state *state,
+       const struct side_arg_vec *side_arg_vec,
+       void *key);
+void side_call_variadic_key(const struct side_event_state *state,
+       const struct side_arg_vec *side_arg_vec,
+       const struct side_arg_dynamic_struct *var_struct,
+       void *key);
 
 struct side_events_register_handle *side_events_register(struct side_event_description **events,
                uint32_t nr_events);
@@ -102,16 +109,16 @@ typedef void (*side_tracer_callback_variadic_func)(const struct side_event_descr
 
 int side_tracer_callback_register(struct side_event_description *desc,
                side_tracer_callback_func call,
-               void *priv);
+               void *priv, void *key);
 int side_tracer_callback_variadic_register(struct side_event_description *desc,
                side_tracer_callback_variadic_func call_variadic,
-               void *priv);
+               void *priv, void *key);
 int side_tracer_callback_unregister(struct side_event_description *desc,
                side_tracer_callback_func call,
-               void *priv);
+               void *priv, void *key);
 int side_tracer_callback_variadic_unregister(struct side_event_description *desc,
                side_tracer_callback_variadic_func call_variadic,
-               void *priv);
+               void *priv, void *key);
 
 enum side_tracer_notification {
        SIDE_TRACER_NOTIFICATION_INSERT_EVENTS,
index b781712a0bbcf1e1f188d5a2c69a6c8b1d853d45..67f57bea2cfb381ff50e09ee77322b02b89fce18 100644 (file)
@@ -49,6 +49,7 @@ struct side_callback {
                        void *priv);
        } u;
        void *priv;
+       void *key;
 };
 
 static struct side_rcu_gp_state rcu_gp;
@@ -76,7 +77,7 @@ static DEFINE_SIDE_LIST_HEAD(side_tracer_list);
  */
 const char side_empty_callback[sizeof(struct side_callback)];
 
-void side_call(const struct side_event_state *event_state, const struct side_arg_vec *side_arg_vec)
+void side_call_key(const struct side_event_state *event_state, const struct side_arg_vec *side_arg_vec, void *key)
 {
        struct side_rcu_read_state rcu_read_state;
        const struct side_event_state_0 *es0;
@@ -96,14 +97,24 @@ void side_call(const struct side_event_state *event_state, const struct side_arg
                // TODO: call kernel write.
        }
        side_rcu_read_begin(&rcu_gp, &rcu_read_state);
-       for (side_cb = side_rcu_dereference(es0->callbacks); side_cb->u.call != NULL; side_cb++)
+       for (side_cb = side_rcu_dereference(es0->callbacks); side_cb->u.call != NULL; side_cb++) {
+               /* A NULL key is always a match. */
+               if (key && side_cb->key && side_cb->key != key)
+                       continue;
                side_cb->u.call(es0->desc, side_arg_vec, side_cb->priv);
+       }
        side_rcu_read_end(&rcu_gp, &rcu_read_state);
 }
 
-void side_call_variadic(const struct side_event_state *event_state,
+void side_call(const struct side_event_state *event_state, const struct side_arg_vec *side_arg_vec)
+{
+       side_call_key(event_state, side_arg_vec, NULL);
+}
+
+void side_call_variadic_key(const struct side_event_state *event_state,
        const struct side_arg_vec *side_arg_vec,
-       const struct side_arg_dynamic_struct *var_struct)
+       const struct side_arg_dynamic_struct *var_struct,
+       void *key)
 {
        struct side_rcu_read_state rcu_read_state;
        const struct side_event_state_0 *es0;
@@ -123,15 +134,26 @@ void side_call_variadic(const struct side_event_state *event_state,
                // TODO: call kernel write.
        }
        side_rcu_read_begin(&rcu_gp, &rcu_read_state);
-       for (side_cb = side_rcu_dereference(es0->callbacks); side_cb->u.call_variadic != NULL; side_cb++)
+       for (side_cb = side_rcu_dereference(es0->callbacks); side_cb->u.call_variadic != NULL; side_cb++) {
+               /* A NULL key is always a match. */
+               if (key && side_cb->key && side_cb->key != key)
+                       continue;
                side_cb->u.call_variadic(es0->desc, side_arg_vec, var_struct, side_cb->priv);
+       }
        side_rcu_read_end(&rcu_gp, &rcu_read_state);
 }
 
+void side_call_variadic(const struct side_event_state *event_state,
+       const struct side_arg_vec *side_arg_vec,
+       const struct side_arg_dynamic_struct *var_struct)
+{
+       side_call_variadic_key(event_state, side_arg_vec, var_struct, NULL);
+}
+
 static
 const struct side_callback *side_tracer_callback_lookup(
                const struct side_event_description *desc,
-               void *call, void *priv)
+               void *call, void *priv, void *key)
 {
        struct side_event_state *event_state = side_ptr_get(desc->state);
        const struct side_event_state_0 *es0;
@@ -141,7 +163,7 @@ const struct side_callback *side_tracer_callback_lookup(
                abort();
        es0 = side_container_of(event_state, const struct side_event_state_0, parent);
        for (cb = es0->callbacks; cb->u.call != NULL; cb++) {
-               if ((void *) cb->u.call == call && cb->priv == priv)
+               if ((void *) cb->u.call == call && cb->priv == priv && cb->key == key)
                        return cb;
        }
        return NULL;
@@ -149,7 +171,7 @@ const struct side_callback *side_tracer_callback_lookup(
 
 static
 int _side_tracer_callback_register(struct side_event_description *desc,
-               void *call, void *priv)
+               void *call, void *priv, void *key)
 {
        struct side_event_state *event_state;
        struct side_callback *old_cb, *new_cb;
@@ -174,7 +196,7 @@ int _side_tracer_callback_register(struct side_event_description *desc,
                goto unlock;
        }
        /* Reject duplicate (call, priv) tuples. */
-       if (side_tracer_callback_lookup(desc, call, priv)) {
+       if (side_tracer_callback_lookup(desc, call, priv, key)) {
                ret = SIDE_ERROR_EXIST;
                goto unlock;
        }
@@ -193,6 +215,7 @@ int _side_tracer_callback_register(struct side_event_description *desc,
                new_cb[old_nr_cb].u.call =
                        (side_tracer_callback_func) call;
        new_cb[old_nr_cb].priv = priv;
+       new_cb[old_nr_cb].key = key;
        /* High order bits are already zeroed. */
        side_rcu_assign_pointer(es0->callbacks, new_cb);
        side_rcu_wait_grace_period(&rcu_gp);
@@ -209,24 +232,24 @@ unlock:
 
 int side_tracer_callback_register(struct side_event_description *desc,
                side_tracer_callback_func call,
-               void *priv)
+               void *priv, void *key)
 {
        if (desc->flags & SIDE_EVENT_FLAG_VARIADIC)
                return SIDE_ERROR_INVAL;
-       return _side_tracer_callback_register(desc, (void *) call, priv);
+       return _side_tracer_callback_register(desc, (void *) call, priv, key);
 }
 
 int side_tracer_callback_variadic_register(struct side_event_description *desc,
                side_tracer_callback_variadic_func call_variadic,
-               void *priv)
+               void *priv, void *key)
 {
        if (!(desc->flags & SIDE_EVENT_FLAG_VARIADIC))
                return SIDE_ERROR_INVAL;
-       return _side_tracer_callback_register(desc, (void *) call_variadic, priv);
+       return _side_tracer_callback_register(desc, (void *) call_variadic, priv, key);
 }
 
 static int _side_tracer_callback_unregister(struct side_event_description *desc,
-               void *call, void *priv)
+               void *call, void *priv, void *key)
 {
        struct side_event_state *event_state;
        struct side_callback *old_cb, *new_cb;
@@ -247,7 +270,7 @@ static int _side_tracer_callback_unregister(struct side_event_description *desc,
        if (side_unlikely(event_state->version != 0))
                abort();
        es0 = side_container_of(event_state, struct side_event_state_0, parent);
-       cb_pos = side_tracer_callback_lookup(desc, call, priv);
+       cb_pos = side_tracer_callback_lookup(desc, call, priv, key);
        if (!cb_pos) {
                ret = SIDE_ERROR_NOENT;
                goto unlock;
@@ -283,20 +306,20 @@ unlock:
 
 int side_tracer_callback_unregister(struct side_event_description *desc,
                side_tracer_callback_func call,
-               void *priv)
+               void *priv, void *key)
 {
        if (desc->flags & SIDE_EVENT_FLAG_VARIADIC)
                return SIDE_ERROR_INVAL;
-       return _side_tracer_callback_unregister(desc, (void *) call, priv);
+       return _side_tracer_callback_unregister(desc, (void *) call, priv, key);
 }
 
 int side_tracer_callback_variadic_unregister(struct side_event_description *desc,
                side_tracer_callback_variadic_func call_variadic,
-               void *priv)
+               void *priv, void *key)
 {
        if (!(desc->flags & SIDE_EVENT_FLAG_VARIADIC))
                return SIDE_ERROR_INVAL;
-       return _side_tracer_callback_unregister(desc, (void *) call_variadic, priv);
+       return _side_tracer_callback_unregister(desc, (void *) call_variadic, priv, key);
 }
 
 struct side_events_register_handle *side_events_register(struct side_event_description **events, uint32_t nr_events)
index e4ccd86950ac0efbe36ffde2cf9768abb50a410e..427f9e66e35dfe706a725682701e25c657c661e8 100644 (file)
@@ -2120,21 +2120,21 @@ void tracer_event_notification(enum side_tracer_notification notif,
                                        event->nr_side_attr_type - _NR_SIDE_ATTR_TYPE);
                        }
                        if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
-                               ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL);
+                               ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL, NULL);
                                if (ret)
                                        abort();
                        } else {
-                               ret = side_tracer_callback_register(event, tracer_call, NULL);
+                               ret = side_tracer_callback_register(event, tracer_call, NULL, NULL);
                                if (ret)
                                        abort();
                        }
                } else {
                        if (event->flags & SIDE_EVENT_FLAG_VARIADIC) {
-                               ret = side_tracer_callback_variadic_unregister(event, tracer_call_variadic, NULL);
+                               ret = side_tracer_callback_variadic_unregister(event, tracer_call_variadic, NULL, NULL);
                                if (ret)
                                        abort();
                        } else {
-                               ret = side_tracer_callback_unregister(event, tracer_call, NULL);
+                               ret = side_tracer_callback_unregister(event, tracer_call, NULL, NULL);
                                if (ret)
                                        abort();
                        }
This page took 0.02702 seconds and 4 git commands to generate.