[lttng-dev] [Patch LTTng-tools v2 4/5] Dump a global type only once per session
Geneviève Bastien
gbastien+lttng at versatic.net
Tue Feb 11 16:40:51 EST 2014
Global type declarations can be used more than once in a single tracepoint,
or many tracepoints can use it. It must be statedumped only once in a given
session.
Signed-off-by: Geneviève Bastien <gbastien+lttng at versatic.net>
---
src/bin/lttng-sessiond/ust-metadata.c | 46 +++++++++++++++++++++++
src/bin/lttng-sessiond/ust-registry.c | 69 +++++++++++++++++++++++++++++++++++
src/bin/lttng-sessiond/ust-registry.h | 15 ++++++++
3 files changed, 130 insertions(+)
diff --git a/src/bin/lttng-sessiond/ust-metadata.c b/src/bin/lttng-sessiond/ust-metadata.c
index 743901a..dc144e1 100644
--- a/src/bin/lttng-sessiond/ust-metadata.c
+++ b/src/bin/lttng-sessiond/ust-metadata.c
@@ -322,6 +322,40 @@ int _lttng_one_global_type_statedump(struct ust_registry_session *session,
const struct ustctl_global_type_decl *global_type_decl)
{
int ret = 0, i;
+ struct ust_registry_global_type_decl *global_type;
+ struct cds_lfht_node *nodep;
+ struct lttng_ht_iter iter;
+ struct lttng_ht_node_str *node;
+
+ /* Check if the global type was already dumped */
+ global_type = zmalloc(sizeof(*global_type));
+ if (!global_type) {
+ PERROR("zmalloc ust registry global type");
+ return -ENOMEM;
+ }
+ global_type->category = global_type_decl->mtype;
+ switch (global_type_decl->mtype) {
+ case ustctl_mtype_enum:
+ strncpy(global_type->name, global_type_decl->u.ctf_enum.name, LTTNG_UST_SYM_NAME_LEN);
+ global_type->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ rcu_read_lock();
+ cds_lfht_lookup(session->global_types_ht->ht, session->global_types_ht->hash_fct((void *) global_type, lttng_ht_seed),
+ session->global_types_ht->match_fct, global_type, &iter.iter);
+ node = lttng_ht_iter_get_node_str(&iter);
+ if (node != NULL) {
+ DBG("global type %s already in metadata", global_type->name);
+ rcu_read_unlock();
+ free(global_type);
+ return ret;
+ }
+ cds_lfht_node_init(&global_type->node.node);
+ rcu_read_unlock();
+
switch (global_type_decl->mtype) {
case ustctl_mtype_enum:
@@ -371,6 +405,17 @@ int _lttng_one_global_type_statedump(struct ust_registry_session *session,
return -EINVAL;
}
+ /* Flag this global type as dumped */
+ /*
+ * This is an add unique with a custom match function for global types.
+ * The node are matched using the category and global type name.
+ */
+ rcu_read_lock();
+ nodep = cds_lfht_add_unique(session->global_types_ht->ht, session->global_types_ht->hash_fct(global_type, lttng_ht_seed),
+ session->global_types_ht->match_fct, global_type, &global_type->node.node);
+ assert(nodep == &global_type->node.node);
+ rcu_read_unlock();
+
return ret;
}
@@ -388,6 +433,7 @@ int _lttng_global_type_decl_statedump(struct ust_registry_session *session,
const struct ustctl_global_type_decl *global_type_decl = &event->global_type_decl[i];
ret = _lttng_one_global_type_statedump(session, global_type_decl);
+ DBG("_lttng_global_type_decl_statedump %d", ret);
if (ret)
return ret;
}
diff --git a/src/bin/lttng-sessiond/ust-registry.c b/src/bin/lttng-sessiond/ust-registry.c
index 281ea7c..80df17a 100644
--- a/src/bin/lttng-sessiond/ust-registry.c
+++ b/src/bin/lttng-sessiond/ust-registry.c
@@ -73,6 +73,49 @@ static unsigned long ht_hash_event(void *_key, unsigned long seed)
}
/*
+ * Hash table match function for global type declarations in the session.
+ */
+static int ht_match_global_type(struct cds_lfht_node *node, const void *_key)
+{
+ struct ust_registry_global_type_decl *global_type;
+ const struct ust_registry_global_type_decl *key;
+
+ assert(node);
+ assert(_key);
+
+ global_type = caa_container_of(node, struct ust_registry_global_type_decl, node.node);
+ assert(global_type);
+ key = _key;
+
+ /* It has to be a perfect match. */
+ if (global_type->category != key->category) {
+ goto no_match;
+ }
+ if (strncmp(global_type->name, key->name, strlen(global_type->name) != 0)) {
+ goto no_match;
+ }
+
+ /* Match */
+ return 1;
+
+no_match:
+ return 0;
+}
+
+static unsigned long ht_hash_global_type(void *_key, unsigned long seed)
+{
+ uint64_t xored_key;
+ struct ust_registry_global_type_decl *key = _key;
+
+ assert(key);
+
+ xored_key = (uint64_t) (hash_key_ulong((void *)key->category, seed) ^
+ hash_key_str(key->name, seed));
+
+ return hash_key_u64(&xored_key, seed);
+}
+
+/*
* Return negative value on error, 0 if OK.
*
* TODO: we could add stricter verification of more types to catch
@@ -570,6 +613,16 @@ int ust_registry_session_init(struct ust_registry_session **sessionp,
session->uint64_t_alignment = uint64_t_alignment;
session->long_alignment = long_alignment;
session->byte_order = byte_order;
+ session->global_types_ht = 0;
+ session->global_types_ht = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
+ if (!session->global_types_ht) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ /* Set custom match function. */
+ session->global_types_ht->match_fct = ht_match_global_type;
+ session->global_types_ht->hash_fct = ht_hash_global_type;
session->channels = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
if (!session->channels) {
@@ -610,6 +663,7 @@ void ust_registry_session_destroy(struct ust_registry_session *reg)
int ret;
struct lttng_ht_iter iter;
struct ust_registry_channel *chan;
+ struct ust_registry_global_type_decl *global_type;
assert(reg);
@@ -632,4 +686,19 @@ void ust_registry_session_destroy(struct ust_registry_session *reg)
}
free(reg->metadata);
+
+ /* Destroy the global type hash table */
+ if (reg->global_types_ht) {
+ rcu_read_lock();
+ /* Destroy all global types associated with this registry. */
+ cds_lfht_for_each_entry(reg->global_types_ht->ht, &iter.iter, global_type,
+ node.node) {
+ /* Delete the node from the ht and free it. */
+ ret = lttng_ht_del(reg->global_types_ht, &iter);
+ assert(!ret);
+ free(global_type);
+ }
+ rcu_read_unlock();
+ ht_cleanup_push(reg->global_types_ht);
+ }
}
diff --git a/src/bin/lttng-sessiond/ust-registry.h b/src/bin/lttng-sessiond/ust-registry.h
index 8b41c2a..29bc120 100644
--- a/src/bin/lttng-sessiond/ust-registry.h
+++ b/src/bin/lttng-sessiond/ust-registry.h
@@ -31,6 +31,16 @@
struct ust_app;
+struct ust_registry_global_type_decl {
+ uint32_t category;
+ char name[LTTNG_UST_SYM_NAME_LEN];
+ /*
+ * Node in the ust-session hash table. The global type name and
+ * category is used to initialize the node and for the match function.
+ */
+ struct lttng_ht_node_u64 node;
+};
+
struct ust_registry_session {
/*
* With multiple writers and readers, use this lock to access the registry.
@@ -75,6 +85,11 @@ struct ust_registry_session {
* deletes its sessions.
*/
unsigned int metadata_closed;
+ /*
+ * Hash table containing global type declarations already dumped into the
+ * metadata. MUST be accessed with a RCU read side lock acquired.
+ */
+ struct lttng_ht *global_types_ht;
};
struct ust_registry_channel {
--
1.8.5.4
More information about the lttng-dev
mailing list