side_event_cond(_identifier) \
side_event_call_variadic(_identifier, SIDE_PARAM(_sav), SIDE_PARAM(_var), SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
-#define side_statedump_event_call(_identifier, _sav) \
- _side_event_call(side_statedump_call, _identifier, SIDE_PARAM(_sav))
+#define _side_statedump_event_call(_call, _identifier, _key, _sav) \
+ { \
+ const struct side_arg side_sav[] = { _sav }; \
+ const struct side_arg_vec side_arg_vec = { \
+ .sav = SIDE_PTR_INIT(side_sav), \
+ .len = SIDE_ARRAY_SIZE(side_sav), \
+ }; \
+ _call(&(side_event_state__##_identifier).parent, &side_arg_vec, _key); \
+ }
+
+#define side_statedump_event_call(_identifier, _key, _sav) \
+ _side_statedump_event_call(side_statedump_call, _identifier, _key, SIDE_PARAM(_sav))
+
+#define _side_statedump_event_call_variadic(_call, _identifier, _key, _sav, _var_fields, _attr...) \
+ { \
+ const struct side_arg side_sav[] = { _sav }; \
+ const struct side_arg_vec side_arg_vec = { \
+ .sav = side_ptr_init(side_sav), \
+ .len = side_array_size(side_sav), \
+ }; \
+ const struct side_arg_dynamic_field side_fields[] = { _var_fields }; \
+ const struct side_arg_dynamic_struct var_struct = { \
+ .fields = side_ptr_init(side_fields), \
+ .attr = side_ptr_init(_attr), \
+ .len = side_array_size(side_fields), \
+ .nr_attr = side_array_size(_attr), \
+ }; \
+ _call(&(side_event_state__##_identifier.parent), &side_arg_vec, &var_struct, _key); \
+ }
-#define side_statedump_event_call_variadic(_identifier, _sav, _var_fields, _attr...) \
- _side_event_call_variadic(side_statedump_call_variadic, _identifier, SIDE_PARAM(_sav), SIDE_PARAM(_var_fields), SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#define side_statedump_event_call_variadic(_identifier, _key, _sav, _var_fields, _attr...) \
+ _side_statedump_event_call_variadic(side_statedump_call_variadic, _identifier, _key, SIDE_PARAM(_sav), SIDE_PARAM(_var_fields), SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
#define _side_define_event(_linkage, _identifier, _provider, _event, _loglevel, _fields, _flags, _attr...) \
_linkage struct side_event_description __attribute__((section("side_event_description"))) \
* notification register/unregister APIs.
*/
void side_statedump_call(const struct side_event_state *state,
- const struct side_arg_vec *side_arg_vec);
+ const struct side_arg_vec *side_arg_vec,
+ void *statedump_request_key);
void side_statedump_call_variadic(const struct side_event_state *state,
- const struct side_arg_vec *side_arg_vec,
- const struct side_arg_dynamic_struct *var_struct);
+ const struct side_arg_vec *side_arg_vec,
+ const struct side_arg_dynamic_struct *var_struct,
+ void *statedump_request_key);
/*
* If side_statedump_request_notification_register is invoked from
* their statedump callbacks registered with the agent thread. This
* could result in deadlocks when pthread_atfork handler waits for
* agent thread quiescence.
+ *
+ * The statedump_request_key received by the statedump_cb is only
+ * valid until the statedump_cb returns.
*/
enum side_statedump_mode {
SIDE_STATEDUMP_MODE_POLLING,
struct side_statedump_request_handle *
side_statedump_request_notification_register(
const char *state_name,
- void (*statedump_cb)(void),
+ void (*statedump_cb)(void *statedump_request_key),
enum side_statedump_mode mode);
void side_statedump_request_notification_unregister(
struct side_statedump_request_handle *handle);
struct side_statedump_request_handle {
struct side_list_node node; /* Statedump request RCU list node. */
struct side_list_head notification_queue; /* Queue of struct side_statedump_notification */
- void (*cb)(void);
+ void (*cb)(void *statedump_request_key);
char *name;
enum side_statedump_mode mode;
};
*/
static DEFINE_SIDE_LIST_HEAD(side_statedump_list);
-/*
- * Callback filter key for state dump.
- */
-static __thread uint64_t filter_key = SIDE_KEY_MATCH_ALL;
-
/*
* The empty callback has a NULL function callback pointer, which stops
* iteration on the array of callbacks immediately.
_side_call(event_state, side_arg_vec, SIDE_KEY_MATCH_ALL);
}
-void side_statedump_call(const struct side_event_state *event_state, const struct side_arg_vec *side_arg_vec)
+void side_statedump_call(const struct side_event_state *event_state,
+ const struct side_arg_vec *side_arg_vec,
+ void *statedump_request_key)
{
- _side_call(event_state, side_arg_vec, filter_key);
+ _side_call(event_state, side_arg_vec, *(const uint64_t *) statedump_request_key);
}
static
}
void side_statedump_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)
+ const struct side_arg_vec *side_arg_vec,
+ const struct side_arg_dynamic_struct *var_struct,
+ void *statedump_request_key)
{
- _side_call_variadic(event_state, side_arg_vec, var_struct, filter_key);
+ _side_call_variadic(event_state, side_arg_vec, var_struct, *(const uint64_t *) statedump_request_key);
}
static
void side_statedump_run(struct side_statedump_request_handle *handle,
struct side_statedump_notification *notif)
{
- /* Invoke the state dump callback specifically for the tracer key. */
- filter_key = notif->key;
- side_statedump_event_call(side_statedump_begin,
+ side_statedump_event_call(side_statedump_begin, ¬if->key,
side_arg_list(side_arg_string(handle->name)));
- handle->cb();
- side_statedump_event_call(side_statedump_end,
+ /* Invoke the state dump callback specifically for the tracer key. */
+ handle->cb(¬if->key);
+ side_statedump_event_call(side_statedump_end, ¬if->key,
side_arg_list(side_arg_string(handle->name)));
- filter_key = SIDE_KEY_MATCH_ALL;
}
static
struct side_statedump_request_handle *
side_statedump_request_notification_register(const char *state_name,
- void (*statedump_cb)(void),
+ void (*statedump_cb)(void *statedump_request_key),
enum side_statedump_mode mode)
{
struct side_statedump_request_handle *handle;
return NULL;
if (!initialized)
side_init();
- /*
- * The statedump request notification should not be registered
- * from a notification callback.
- */
- assert(!filter_key);
handle = (struct side_statedump_request_handle *)
calloc(1, sizeof(struct side_statedump_request_handle));
if (!handle)
return;
if (!initialized)
side_init();
- assert(!filter_key);
if (handle->mode == SIDE_STATEDUMP_MODE_AGENT_THREAD)
pthread_mutex_lock(&side_agent_thread_lock);
static struct side_statedump_request_handle *statedump_request_handle;
static
-void statedump_cb(void)
+void statedump_cb(void *statedump_request_key)
{
size_t i;
side_event_cond(my_provider_event_dump1) {
for (i = 0; i < SIDE_ARRAY_SIZE(mystr); i++) {
side_statedump_event_call(my_provider_event_dump1,
+ statedump_request_key,
side_arg_list(side_arg_string(mystr[i])));
}
}
side_event_cond(my_provider_event_dump2) {
for (i = 0; i < SIDE_ARRAY_SIZE(myint); i++) {
side_statedump_event_call(my_provider_event_dump2,
+ statedump_request_key,
side_arg_list(side_arg_s32(myint[i])));
}
}