X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=liblttng-ust%2Flttng-events.c;h=0c508af7bc9a263f3a4f1dd39ed5e535b906d234;hb=a44d07dac81c3444b6da551db9fb774a7402a9ef;hp=0c684df2f3f6759d9930c2317926dce2853ae7a9;hpb=d871c65bcb2e94c69e0a46e7e0dcd2dae2fce7af;p=deliverable%2Flttng-ust.git diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c index 0c684df2..0c508af7 100644 --- a/liblttng-ust/lttng-events.c +++ b/liblttng-ust/lttng-events.c @@ -560,6 +560,23 @@ end: return ret; } +static inline +struct cds_hlist_head *borrow_hash_table_bucket( + struct cds_hlist_head *hash_table, + unsigned int hash_table_size, + const struct lttng_event_desc *desc) +{ + const char *event_name; + size_t name_len; + uint32_t hash; + + event_name = desc->name; + name_len = strlen(event_name); + + hash = jhash(event_name, name_len, 0); + return &hash_table[hash & (hash_table_size - 1)]; +} + /* * Supports event creation while tracing session is active. */ @@ -567,18 +584,15 @@ static int lttng_event_create(const struct lttng_event_desc *desc, struct lttng_channel *chan) { - const char *event_name = desc->name; struct lttng_event *event; struct lttng_session *session = chan->session; struct cds_hlist_head *head; int ret = 0; - size_t name_len = strlen(event_name); - uint32_t hash; int notify_socket, loglevel; const char *uri; - hash = jhash(event_name, name_len, 0); - head = &chan->session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; + head = borrow_hash_table_bucket(chan->session->events_ht.table, + LTTNG_UST_EVENT_HT_SIZE, desc); notify_socket = lttng_get_notify_socket(session->owner); if (notify_socket < 0) { @@ -624,7 +638,7 @@ int lttng_event_create(const struct lttng_event_desc *desc, session, session->objd, chan->objd, - event_name, + desc->name, loglevel, desc->signature, desc->nr_fields, @@ -785,22 +799,16 @@ void lttng_create_event_if_missing(struct lttng_event_enabler *event_enabler) bool found = false; struct cds_hlist_head *head; struct cds_hlist_node *node; - const char *event_name; - size_t name_len; - uint32_t hash; desc = probe_desc->event_desc[i]; if (!lttng_desc_match_enabler(desc, lttng_event_enabler_as_enabler(event_enabler))) continue; - event_name = desc->name; - name_len = strlen(event_name); - /* - * Check if already created. - */ - hash = jhash(event_name, name_len, 0); - head = &session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; + head = borrow_hash_table_bucket( + session->events_ht.table, + LTTNG_UST_EVENT_HT_SIZE, desc); + cds_hlist_for_each_entry(event, node, head, hlist) { if (event->desc == desc && event->chan == event_enabler->chan) { @@ -825,54 +833,106 @@ void lttng_create_event_if_missing(struct lttng_event_enabler *event_enabler) } } -/* - * Iterate over all the UST sessions to unregister and destroy all probes from - * the probe provider descriptor received as argument. Must me called with the - * ust_lock held. - */ -void lttng_probe_provider_unregister_events(struct lttng_probe_desc *provider_desc) +static +void probe_provider_event_for_each(struct lttng_probe_desc *provider_desc, + void (*event_func)(struct lttng_session *session, struct lttng_event *event)) { struct cds_hlist_node *node, *tmp_node; struct cds_list_head *sessionsp; - struct lttng_session *session; - struct cds_hlist_head *head; - struct lttng_event *event; - unsigned int i, j; + unsigned int i; /* Get handle on list of sessions. */ sessionsp = _lttng_get_sessions(); /* - * Iterate over all events in the probe provider descriptions and sessions - * to queue the unregistration of the events. + * Iterate over all events in the probe provider descriptions and + * sessions to queue the unregistration of the events. */ for (i = 0; i < provider_desc->nr_events; i++) { const struct lttng_event_desc *event_desc; - const char *event_name; - size_t name_len; - uint32_t hash; + struct lttng_session *session; + struct cds_hlist_head *head; + struct lttng_event *event; event_desc = provider_desc->event_desc[i]; - event_name = event_desc->name; - name_len = strlen(event_name); - hash = jhash(event_name, name_len, 0); - /* Iterate over all session to find the current event description. */ + /* + * Iterate over all session to find the current event + * description. + */ cds_list_for_each_entry(session, sessionsp, node) { /* - * Get the list of events in the hashtable bucket and iterate to - * find the event matching this descriptor. + * Get the list of events in the hashtable bucket and + * iterate to find the event matching this descriptor. */ - head = &session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; - cds_hlist_for_each_entry(event, node, head, hlist) { + head = borrow_hash_table_bucket( + session->events_ht.table, + LTTNG_UST_EVENT_HT_SIZE, event_desc); + + cds_hlist_for_each_entry_safe(event, node, tmp_node, head, hlist) { if (event_desc == event->desc) { - /* Queue the unregistration of this event. */ - _lttng_event_unregister(event); + event_func(session, event); break; } } } } +} + +static +void _unregister_event(struct lttng_session *session, + struct lttng_event *event) +{ + _lttng_event_unregister(event); +} + +static +void _event_enum_destroy(struct lttng_session *session, + struct lttng_event *event) +{ + unsigned int i; + + /* Destroy enums of the current event. */ + for (i = 0; i < event->desc->nr_fields; i++) { + const struct lttng_enum_desc *enum_desc; + const struct lttng_event_field *field; + struct lttng_enum *curr_enum; + + field = &(event->desc->fields[i]); + switch (field->type.atype) { + case atype_enum: + enum_desc = field->type.u.legacy.basic.enumeration.desc; + break; + case atype_enum_nestable: + enum_desc = field->type.u.enum_nestable.desc; + break; + default: + continue; + } + + curr_enum = lttng_ust_enum_get_from_desc(session, enum_desc); + if (curr_enum) { + _lttng_enum_destroy(curr_enum); + } + } + + /* Destroy event. */ + _lttng_event_destroy(event); +} + +/* + * Iterate over all the UST sessions to unregister and destroy all probes from + * the probe provider descriptor received as argument. Must me called with the + * ust_lock held. + */ +void lttng_probe_provider_unregister_events( + struct lttng_probe_desc *provider_desc) +{ + /* + * Iterate over all events in the probe provider descriptions and sessions + * to queue the unregistration of the events. + */ + probe_provider_event_for_each(provider_desc, _unregister_event); /* Wait for grace period. */ synchronize_trace(); @@ -883,56 +943,7 @@ void lttng_probe_provider_unregister_events(struct lttng_probe_desc *provider_de * It is now safe to destroy the events and remove them from the event list * and hashtables. */ - for (i = 0; i < provider_desc->nr_events; i++) { - const struct lttng_event_desc *event_desc; - const char *event_name; - size_t name_len; - uint32_t hash; - - event_desc = provider_desc->event_desc[i]; - event_name = event_desc->name; - name_len = strlen(event_name); - hash = jhash(event_name, name_len, 0); - - /* Iterate over all sessions to find the current event description. */ - cds_list_for_each_entry(session, sessionsp, node) { - /* - * Get the list of events in the hashtable bucket and iterate to - * find the event matching this descriptor. - */ - head = &session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)]; - cds_hlist_for_each_entry_safe(event, node, tmp_node, head, hlist) { - if (event_desc == event->desc) { - /* Destroy enums of the current event. */ - for (j = 0; j < event->desc->nr_fields; j++) { - const struct lttng_enum_desc *enum_desc; - const struct lttng_event_field *field; - struct lttng_enum *curr_enum; - - field = &(event->desc->fields[j]); - switch (field->type.atype) { - case atype_enum: - enum_desc = field->type.u.legacy.basic.enumeration.desc; - break; - case atype_enum_nestable: - enum_desc = field->type.u.enum_nestable.desc; - break; - default: - continue; - } - curr_enum = lttng_ust_enum_get_from_desc(session, enum_desc); - if (curr_enum) { - _lttng_enum_destroy(curr_enum); - } - } - - /* Destroy event. */ - _lttng_event_destroy(event); - break; - } - } - } - } + probe_provider_event_for_each(provider_desc, _event_enum_destroy); } /* @@ -977,7 +988,10 @@ int lttng_event_enabler_ref_events(struct lttng_event_enabler *event_enabler) /* * Link filter bytecodes if not linked yet. */ - lttng_event_enabler_link_bytecode(event, event_enabler); + lttng_enabler_link_bytecode(event->desc, + &session->ctx, + &event->bytecode_runtime_head, + lttng_event_enabler_as_enabler(event_enabler)); /* TODO: merge event context. */ }