Fix: syscall event rule: emission sites not compared in is_equal
[lttng-tools.git] / src / bin / lttng-relayd / sessiond-trace-chunks.cpp
index 7201daed1ef74bb27c9c3d7b51464c659dc2e217..9d793c9bcf79315e722447fcb3c205f785a60c54 100644 (file)
@@ -14,6 +14,7 @@
 #include <common/macros.hpp>
 #include <common/string-utils/format.hpp>
 #include <common/trace-chunk-registry.hpp>
+#include <common/urcu.hpp>
 
 #include <inttypes.h>
 #include <stdio.h>
@@ -112,10 +113,9 @@ static void trace_chunk_registry_ht_element_release(struct urcu_ref *ref)
        DBG("Destroying trace chunk registry associated to sessiond {%s}", uuid_str);
        if (element->sessiond_trace_chunk_registry) {
                /* Unpublish. */
-               rcu_read_lock();
+               lttng::urcu::read_lock_guard read_lock;
                cds_lfht_del(element->sessiond_trace_chunk_registry->ht, &element->ht_node);
-               rcu_read_unlock();
-               element->sessiond_trace_chunk_registry = NULL;
+               element->sessiond_trace_chunk_registry = nullptr;
        }
 
        lttng_trace_chunk_registry_destroy(element->trace_chunk_registry);
@@ -142,11 +142,11 @@ static struct trace_chunk_registry_ht_element *
 trace_chunk_registry_ht_element_find(struct sessiond_trace_chunk_registry *sessiond_registry,
                                     const struct trace_chunk_registry_ht_key *key)
 {
-       struct trace_chunk_registry_ht_element *element = NULL;
+       struct trace_chunk_registry_ht_element *element = nullptr;
        struct cds_lfht_node *node;
        struct cds_lfht_iter iter;
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
        cds_lfht_lookup(sessiond_registry->ht,
                        trace_chunk_registry_ht_key_hash(key),
                        trace_chunk_registry_ht_key_match,
@@ -161,10 +161,9 @@ trace_chunk_registry_ht_element_find(struct sessiond_trace_chunk_registry *sessi
                 * could be acquired.
                 */
                if (!trace_chunk_registry_ht_element_get(element)) {
-                       element = NULL;
+                       element = nullptr;
                }
        }
-       rcu_read_unlock();
        return element;
 }
 
@@ -195,49 +194,54 @@ trace_chunk_registry_ht_element_create(struct sessiond_trace_chunk_registry *ses
        urcu_ref_init(&new_element->ref);
        cds_lfht_node_init(&new_element->ht_node);
        new_element->trace_chunk_registry = trace_chunk_registry;
-       trace_chunk_registry = NULL;
+       trace_chunk_registry = nullptr;
 
        /* Attempt to publish the new element. */
-       rcu_read_lock();
-       while (1) {
-               struct cds_lfht_node *published_node;
-               struct trace_chunk_registry_ht_element *published_element;
-
-               published_node =
-                       cds_lfht_add_unique(sessiond_registry->ht,
-                                           trace_chunk_registry_ht_key_hash(&new_element->key),
-                                           trace_chunk_registry_ht_key_match,
-                                           &new_element->key,
-                                           &new_element->ht_node);
-               if (published_node == &new_element->ht_node) {
-                       /* New element published successfully. */
-                       DBG("Created trace chunk registry for sessiond {%s}", uuid_str);
-                       new_element->sessiond_trace_chunk_registry = sessiond_registry;
-                       break;
-               }
-
+       {
                /*
-                * An equivalent element was published during the creation of
-                * this element. Attempt to acquire a reference to the one that
-                * was already published and release the reference to the copy
-                * we created if successful.
+                * Keep the rcu read lock is held accross all attempts
+                * purely for efficiency reasons.
                 */
-               published_element = lttng::utils::container_of(
-                       published_node, &trace_chunk_registry_ht_element::ht_node);
-               if (trace_chunk_registry_ht_element_get(published_element)) {
-                       DBG("Acquired reference to trace chunk registry of sessiond {%s}",
-                           uuid_str);
-                       trace_chunk_registry_ht_element_put(new_element);
-                       new_element = NULL;
-                       break;
+               lttng::urcu::read_lock_guard read_lock;
+               while (true) {
+                       struct cds_lfht_node *published_node;
+                       struct trace_chunk_registry_ht_element *published_element;
+
+                       published_node = cds_lfht_add_unique(
+                               sessiond_registry->ht,
+                               trace_chunk_registry_ht_key_hash(&new_element->key),
+                               trace_chunk_registry_ht_key_match,
+                               &new_element->key,
+                               &new_element->ht_node);
+                       if (published_node == &new_element->ht_node) {
+                               /* New element published successfully. */
+                               DBG("Created trace chunk registry for sessiond {%s}", uuid_str);
+                               new_element->sessiond_trace_chunk_registry = sessiond_registry;
+                               break;
+                       }
+
+                       /*
+                        * An equivalent element was published during the creation of
+                        * this element. Attempt to acquire a reference to the one that
+                        * was already published and release the reference to the copy
+                        * we created if successful.
+                        */
+                       published_element = lttng::utils::container_of(
+                               published_node, &trace_chunk_registry_ht_element::ht_node);
+                       if (trace_chunk_registry_ht_element_get(published_element)) {
+                               DBG("Acquired reference to trace chunk registry of sessiond {%s}",
+                                   uuid_str);
+                               trace_chunk_registry_ht_element_put(new_element);
+                               new_element = nullptr;
+                               break;
+                       }
+                       /*
+                        * A reference to the previously published element could not
+                        * be acquired. Hence, retry to publish our copy of the
+                        * element.
+                        */
                }
-               /*
-                * A reference to the previously published element could not
-                * be acquired. Hence, retry to publish our copy of the
-                * element.
-                */
        }
-       rcu_read_unlock();
 end:
        if (ret < 0) {
                ERR("Failed to create trace chunk registry for session daemon {%s}", uuid_str);
@@ -246,7 +250,7 @@ end:
        return ret;
 }
 
-struct sessiond_trace_chunk_registry *sessiond_trace_chunk_registry_create(void)
+struct sessiond_trace_chunk_registry *sessiond_trace_chunk_registry_create()
 {
        struct sessiond_trace_chunk_registry *sessiond_registry =
                zmalloc<sessiond_trace_chunk_registry>();
@@ -256,7 +260,7 @@ struct sessiond_trace_chunk_registry *sessiond_trace_chunk_registry_create(void)
        }
 
        sessiond_registry->ht = cds_lfht_new(
-               DEFAULT_HT_SIZE, 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
+               DEFAULT_HT_SIZE, 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, nullptr);
        if (!sessiond_registry->ht) {
                goto error;
        }
@@ -265,12 +269,12 @@ end:
        return sessiond_registry;
 error:
        sessiond_trace_chunk_registry_destroy(sessiond_registry);
-       return NULL;
+       return nullptr;
 }
 
 void sessiond_trace_chunk_registry_destroy(struct sessiond_trace_chunk_registry *sessiond_registry)
 {
-       int ret = cds_lfht_destroy(sessiond_registry->ht, NULL);
+       int ret = cds_lfht_destroy(sessiond_registry->ht, nullptr);
 
        LTTNG_ASSERT(!ret);
        free(sessiond_registry);
@@ -336,10 +340,10 @@ sessiond_trace_chunk_registry_publish_chunk(struct sessiond_trace_chunk_registry
        uint64_t chunk_id;
        bool is_anonymous_chunk;
        struct trace_chunk_registry_ht_key key;
-       struct trace_chunk_registry_ht_element *element = NULL;
+       struct trace_chunk_registry_ht_element *element = nullptr;
        char uuid_str[LTTNG_UUID_STR_LEN];
        char chunk_id_str[MAX_INT_DEC_LEN(typeof(chunk_id))] = "-1";
-       struct lttng_trace_chunk *published_chunk = NULL;
+       struct lttng_trace_chunk *published_chunk = nullptr;
        bool trace_chunk_already_published;
 
        lttng_uuid_to_str(sessiond_uuid, uuid_str);
@@ -409,7 +413,7 @@ struct lttng_trace_chunk *sessiond_trace_chunk_registry_get_anonymous_chunk(
        const lttng_uuid& sessiond_uuid,
        uint64_t session_id)
 {
-       struct lttng_trace_chunk *chunk = NULL;
+       struct lttng_trace_chunk *chunk = nullptr;
        struct trace_chunk_registry_ht_element *element;
        struct trace_chunk_registry_ht_key key;
        char uuid_str[LTTNG_UUID_STR_LEN];
@@ -436,7 +440,7 @@ sessiond_trace_chunk_registry_get_chunk(struct sessiond_trace_chunk_registry *se
                                        uint64_t session_id,
                                        uint64_t chunk_id)
 {
-       struct lttng_trace_chunk *chunk = NULL;
+       struct lttng_trace_chunk *chunk = nullptr;
        struct trace_chunk_registry_ht_element *element;
        struct trace_chunk_registry_ht_key key;
        char uuid_str[LTTNG_UUID_STR_LEN];
This page took 0.027011 seconds and 4 git commands to generate.