*/
#include "sessiond-trace-chunks.hpp"
-#include <urcu.h>
-#include <urcu/rculfhash.h>
-#include <urcu/ref.h>
-#include <common/macros.hpp>
-#include <common/hashtable/hashtable.hpp>
-#include <common/hashtable/utils.hpp>
-#include <common/trace-chunk-registry.hpp>
+
#include <common/defaults.hpp>
#include <common/error.hpp>
+#include <common/hashtable/hashtable.hpp>
+#include <common/hashtable/utils.hpp>
+#include <common/macros.hpp>
#include <common/string-utils/format.hpp>
-#include <stdio.h>
+#include <common/trace-chunk-registry.hpp>
+#include <common/urcu.hpp>
+
#include <inttypes.h>
+#include <stdio.h>
+#include <urcu.h>
+#include <urcu/rculfhash.h>
+#include <urcu/ref.h>
/*
* Lifetime of trace chunks within the relay daemon.
struct cds_lfht *ht;
};
+namespace {
struct trace_chunk_registry_ht_key {
lttng_uuid sessiond_uuid;
};
struct lttng_trace_chunk_registry *trace_chunk_registry;
struct sessiond_trace_chunk_registry *sessiond_trace_chunk_registry;
};
+} /* namespace */
-static
-unsigned long trace_chunk_registry_ht_key_hash(
- const struct trace_chunk_registry_ht_key *key)
+static unsigned long trace_chunk_registry_ht_key_hash(const struct trace_chunk_registry_ht_key *key)
{
- uint64_t uuid_h1 = ((uint64_t *) key->sessiond_uuid)[0];
- uint64_t uuid_h2 = ((uint64_t *) key->sessiond_uuid)[1];
+ const uint64_t uuid_h1 = *reinterpret_cast<const uint64_t *>(&key->sessiond_uuid[0]);
+ const uint64_t uuid_h2 = *reinterpret_cast<const uint64_t *>(&key->sessiond_uuid[1]);
- return hash_key_u64(&uuid_h1, lttng_ht_seed) ^
- hash_key_u64(&uuid_h2, lttng_ht_seed);
+ return hash_key_u64(&uuid_h1, lttng_ht_seed) ^ hash_key_u64(&uuid_h2, lttng_ht_seed);
}
/* cds_lfht match function */
-static
-int trace_chunk_registry_ht_key_match(struct cds_lfht_node *node,
- const void *_key)
+static int trace_chunk_registry_ht_key_match(struct cds_lfht_node *node, const void *_key)
{
- const struct trace_chunk_registry_ht_key *key =
- (struct trace_chunk_registry_ht_key *) _key;
+ const struct trace_chunk_registry_ht_key *key = (struct trace_chunk_registry_ht_key *) _key;
struct trace_chunk_registry_ht_element *registry;
- registry = container_of(node, typeof(*registry), ht_node);
- return lttng_uuid_is_equal(key->sessiond_uuid,
- registry->key.sessiond_uuid);
+ registry = lttng::utils::container_of(node, &trace_chunk_registry_ht_element::ht_node);
+ return key->sessiond_uuid == registry->key.sessiond_uuid;
}
-static
-void trace_chunk_registry_ht_element_free(struct rcu_head *node)
+static void trace_chunk_registry_ht_element_free(struct rcu_head *node)
{
struct trace_chunk_registry_ht_element *element =
- container_of(node, typeof(*element), rcu_node);
+ lttng::utils::container_of(node, &trace_chunk_registry_ht_element::rcu_node);
free(element);
}
-static
-void trace_chunk_registry_ht_element_release(struct urcu_ref *ref)
+static void trace_chunk_registry_ht_element_release(struct urcu_ref *ref)
{
struct trace_chunk_registry_ht_element *element =
- container_of(ref, typeof(*element), ref);
+ lttng::utils::container_of(ref, &trace_chunk_registry_ht_element::ref);
char uuid_str[LTTNG_UUID_STR_LEN];
lttng_uuid_to_str(element->key.sessiond_uuid, uuid_str);
- DBG("Destroying trace chunk registry associated to sessiond {%s}",
- uuid_str);
+ DBG("Destroying trace chunk registry associated to sessiond {%s}", uuid_str);
if (element->sessiond_trace_chunk_registry) {
/* Unpublish. */
- rcu_read_lock();
- cds_lfht_del(element->sessiond_trace_chunk_registry->ht,
- &element->ht_node);
- rcu_read_unlock();
- element->sessiond_trace_chunk_registry = NULL;
+ lttng::urcu::read_lock_guard read_lock;
+ cds_lfht_del(element->sessiond_trace_chunk_registry->ht, &element->ht_node);
+ element->sessiond_trace_chunk_registry = nullptr;
}
lttng_trace_chunk_registry_destroy(element->trace_chunk_registry);
call_rcu(&element->rcu_node, trace_chunk_registry_ht_element_free);
}
-static
-bool trace_chunk_registry_ht_element_get(
- struct trace_chunk_registry_ht_element *element)
+static bool trace_chunk_registry_ht_element_get(struct trace_chunk_registry_ht_element *element)
{
return urcu_ref_get_unless_zero(&element->ref);
}
-static
-void trace_chunk_registry_ht_element_put(
- struct trace_chunk_registry_ht_element *element)
+static void trace_chunk_registry_ht_element_put(struct trace_chunk_registry_ht_element *element)
{
if (!element) {
return;
}
/* Acquires a reference to the returned element on behalf of the caller. */
-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)
+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,
&iter);
node = cds_lfht_iter_get_node(&iter);
if (node) {
- element = container_of(node, typeof(*element), ht_node);
+ element =
+ lttng::utils::container_of(node, &trace_chunk_registry_ht_element::ht_node);
/*
* Only consider the look-up as successful if a reference
* could be acquired.
*/
if (!trace_chunk_registry_ht_element_get(element)) {
- element = NULL;
+ element = nullptr;
}
}
- rcu_read_unlock();
return element;
}
-static
-int trace_chunk_registry_ht_element_create(
- struct sessiond_trace_chunk_registry *sessiond_registry,
- const struct trace_chunk_registry_ht_key *key)
+static int
+trace_chunk_registry_ht_element_create(struct sessiond_trace_chunk_registry *sessiond_registry,
+ const struct trace_chunk_registry_ht_key *key)
{
int ret = 0;
struct trace_chunk_registry_ht_element *new_element;
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;
+ {
+ /*
+ * Keep the rcu read lock is held accross all attempts
+ * purely for efficiency reasons.
+ */
+ 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,
+ 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 = container_of(published_node,
- typeof(*published_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;
+ 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);
+ ERR("Failed to create trace chunk registry for session daemon {%s}", uuid_str);
}
lttng_trace_chunk_registry_destroy(trace_chunk_registry);
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>();
+ zmalloc<sessiond_trace_chunk_registry>();
if (!sessiond_registry) {
goto end;
}
- sessiond_registry->ht = cds_lfht_new(DEFAULT_HT_SIZE,
- 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
+ sessiond_registry->ht = cds_lfht_new(
+ DEFAULT_HT_SIZE, 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, nullptr);
if (!sessiond_registry->ht) {
goto error;
}
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)
+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);
}
int sessiond_trace_chunk_registry_session_created(
- struct sessiond_trace_chunk_registry *sessiond_registry,
- const lttng_uuid sessiond_uuid)
+ struct sessiond_trace_chunk_registry *sessiond_registry, const lttng_uuid& sessiond_uuid)
{
int ret = 0;
struct trace_chunk_registry_ht_key key;
struct trace_chunk_registry_ht_element *element;
- lttng_uuid_copy(key.sessiond_uuid, sessiond_uuid);
+ key.sessiond_uuid = sessiond_uuid;
element = trace_chunk_registry_ht_element_find(sessiond_registry, &key);
if (element) {
char uuid_str[LTTNG_UUID_STR_LEN];
lttng_uuid_to_str(sessiond_uuid, uuid_str);
- DBG("Acquired reference to trace chunk registry of sessiond {%s}",
- uuid_str);
+ DBG("Acquired reference to trace chunk registry of sessiond {%s}", uuid_str);
goto end;
} else {
- ret = trace_chunk_registry_ht_element_create(
- sessiond_registry, &key);
+ ret = trace_chunk_registry_ht_element_create(sessiond_registry, &key);
}
end:
return ret;
}
int sessiond_trace_chunk_registry_session_destroyed(
- struct sessiond_trace_chunk_registry *sessiond_registry,
- const lttng_uuid sessiond_uuid)
+ struct sessiond_trace_chunk_registry *sessiond_registry, const lttng_uuid& sessiond_uuid)
{
int ret = 0;
struct trace_chunk_registry_ht_key key;
char uuid_str[LTTNG_UUID_STR_LEN];
lttng_uuid_to_str(sessiond_uuid, uuid_str);
- lttng_uuid_copy(key.sessiond_uuid, sessiond_uuid);
+ key.sessiond_uuid = sessiond_uuid;
element = trace_chunk_registry_ht_element_find(sessiond_registry, &key);
if (element) {
- DBG("Releasing reference to trace chunk registry of sessiond {%s}",
- uuid_str);
+ DBG("Releasing reference to trace chunk registry of sessiond {%s}", uuid_str);
/*
* Release the reference held by the session and the reference
* acquired through the "find" operation.
trace_chunk_registry_ht_element_put(element);
trace_chunk_registry_ht_element_put(element);
} else {
- ERR("Failed to find trace chunk registry of sessiond {%s}",
- uuid_str);
+ ERR("Failed to find trace chunk registry of sessiond {%s}", uuid_str);
ret = -1;
}
return ret;
}
-struct lttng_trace_chunk *sessiond_trace_chunk_registry_publish_chunk(
- struct sessiond_trace_chunk_registry *sessiond_registry,
- const lttng_uuid sessiond_uuid, uint64_t session_id,
- struct lttng_trace_chunk *new_chunk)
+struct lttng_trace_chunk *
+sessiond_trace_chunk_registry_publish_chunk(struct sessiond_trace_chunk_registry *sessiond_registry,
+ const lttng_uuid& sessiond_uuid,
+ uint64_t session_id,
+ struct lttng_trace_chunk *new_chunk)
{
enum lttng_trace_chunk_status status;
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);
- lttng_uuid_copy(key.sessiond_uuid, sessiond_uuid);
+ key.sessiond_uuid = sessiond_uuid;
status = lttng_trace_chunk_get_id(new_chunk, &chunk_id);
if (status == LTTNG_TRACE_CHUNK_STATUS_OK) {
int ret;
- ret = snprintf(chunk_id_str, sizeof(chunk_id_str), "%" PRIu64,
- chunk_id);
+ ret = snprintf(chunk_id_str, sizeof(chunk_id_str), "%" PRIu64, chunk_id);
if (ret < 0) {
lttng_strncpy(chunk_id_str, "-1", sizeof(chunk_id_str));
WARN("Failed to format trace chunk id");
}
DBG("Attempting to publish trace chunk: sessiond {%s}, session_id = "
- "%" PRIu64 ", chunk_id = %s",
- uuid_str, session_id,
- is_anonymous_chunk ? "anonymous" : chunk_id_str);
+ "%" PRIu64 ", chunk_id = %s",
+ uuid_str,
+ session_id,
+ is_anonymous_chunk ? "anonymous" : chunk_id_str);
element = trace_chunk_registry_ht_element_find(sessiond_registry, &key);
if (!element) {
goto end;
}
- published_chunk = lttng_trace_chunk_registry_publish_chunk(
- element->trace_chunk_registry, session_id, new_chunk,
- &trace_chunk_already_published);
+ published_chunk = lttng_trace_chunk_registry_publish_chunk(element->trace_chunk_registry,
+ session_id,
+ new_chunk,
+ &trace_chunk_already_published);
/*
* When the trace chunk is first published, two references to the
* published chunks exist. One is taken by the registry while the other
return published_chunk;
}
-struct lttng_trace_chunk *
-sessiond_trace_chunk_registry_get_anonymous_chunk(
- struct sessiond_trace_chunk_registry *sessiond_registry,
- const lttng_uuid sessiond_uuid,
- uint64_t session_id)
+struct lttng_trace_chunk *sessiond_trace_chunk_registry_get_anonymous_chunk(
+ struct sessiond_trace_chunk_registry *sessiond_registry,
+ 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];
lttng_uuid_to_str(sessiond_uuid, uuid_str);
- lttng_uuid_copy(key.sessiond_uuid, sessiond_uuid);
+ key.sessiond_uuid = sessiond_uuid;
element = trace_chunk_registry_ht_element_find(sessiond_registry, &key);
if (!element) {
- ERR("Failed to find trace chunk registry of sessiond {%s}",
- uuid_str);
+ ERR("Failed to find trace chunk registry of sessiond {%s}", uuid_str);
goto end;
}
- chunk = lttng_trace_chunk_registry_find_anonymous_chunk(
- element->trace_chunk_registry,
- session_id);
+ chunk = lttng_trace_chunk_registry_find_anonymous_chunk(element->trace_chunk_registry,
+ session_id);
trace_chunk_registry_ht_element_put(element);
end:
return chunk;
}
struct lttng_trace_chunk *
-sessiond_trace_chunk_registry_get_chunk(
- struct sessiond_trace_chunk_registry *sessiond_registry,
- const lttng_uuid sessiond_uuid,
- uint64_t session_id, uint64_t chunk_id)
+sessiond_trace_chunk_registry_get_chunk(struct sessiond_trace_chunk_registry *sessiond_registry,
+ const lttng_uuid& sessiond_uuid,
+ 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];
lttng_uuid_to_str(sessiond_uuid, uuid_str);
- lttng_uuid_copy(key.sessiond_uuid, sessiond_uuid);
+ key.sessiond_uuid = sessiond_uuid;
element = trace_chunk_registry_ht_element_find(sessiond_registry, &key);
if (!element) {
- ERR("Failed to find trace chunk registry of sessiond {%s}",
- uuid_str);
+ ERR("Failed to find trace chunk registry of sessiond {%s}", uuid_str);
goto end;
}
chunk = lttng_trace_chunk_registry_find_chunk(
- element->trace_chunk_registry,
- session_id, chunk_id);
+ element->trace_chunk_registry, session_id, chunk_id);
trace_chunk_registry_ht_element_put(element);
end:
return chunk;
}
int sessiond_trace_chunk_registry_chunk_exists(
- struct sessiond_trace_chunk_registry *sessiond_registry,
- const lttng_uuid sessiond_uuid,
- uint64_t session_id, uint64_t chunk_id, bool *chunk_exists)
+ struct sessiond_trace_chunk_registry *sessiond_registry,
+ const lttng_uuid& sessiond_uuid,
+ uint64_t session_id,
+ uint64_t chunk_id,
+ bool *chunk_exists)
{
int ret;
struct trace_chunk_registry_ht_element *element;
struct trace_chunk_registry_ht_key key;
- lttng_uuid_copy(key.sessiond_uuid, sessiond_uuid);
+ key.sessiond_uuid = sessiond_uuid;
element = trace_chunk_registry_ht_element_find(sessiond_registry, &key);
if (!element) {
char uuid_str[LTTNG_UUID_STR_LEN];
* connection/registry. This would indicate a protocol
* (or internal) error.
*/
- ERR("Failed to find trace chunk registry of sessiond {%s}",
- uuid_str);
+ ERR("Failed to find trace chunk registry of sessiond {%s}", uuid_str);
ret = -1;
goto end;
}
ret = lttng_trace_chunk_registry_chunk_exists(
- element->trace_chunk_registry,
- session_id, chunk_id, chunk_exists);
+ element->trace_chunk_registry, session_id, chunk_id, chunk_exists);
trace_chunk_registry_ht_element_put(element);
end:
return ret;