void sessiond_notify_ready(void)
{
/*
- * The _return variant is used since the implied memory barriers are
- * required.
+ * This memory barrier is paired with the one performed by
+ * the client thread after it has seen that 'lttng_sessiond_ready' is 0.
+ *
+ * The purpose of these memory barriers is to ensure that all
+ * initialization operations of the various threads that call this
+ * function to signal that they are ready are commited/published
+ * before the client thread can see the 'lttng_sessiond_ready' counter
+ * reach 0.
+ *
+ * Note that this could be a 'write' memory barrier, but a full barrier
+ * is used in case the code using this utility changes. The performance
+ * implications of this choice are minimal since this is a slow path.
*/
- (void) uatomic_sub_return(<tng_sessiond_ready, 1);
+ cmm_smp_mb();
+ uatomic_sub(<tng_sessiond_ready, 1);
}
static
if (ret > 0 || (ret < 0 && errno != EINTR)) {
goto exit;
}
- cmm_smp_rmb();
}
+ /*
+ * This barrier is paired with the one in sessiond_notify_ready() to
+ * ensure that loads accessing data initialized by the other threads,
+ * on which this thread was waiting, are not performed before this point.
+ *
+ * Note that this could be a 'read' memory barrier, but a full barrier
+ * is used in case the code changes. The performance implications of
+ * this choice are minimal since this is a slow path.
+ */
+ cmm_smp_mb();
/* This testpoint is after we signal readiness to the parent. */
if (testpoint(sessiond_thread_manage_clients)) {
goto exit_set_signal_handler;
}
+ /*
+ * Init config from environment variables.
+ * Command line option override env configuration per-doc. Do env first.
+ */
+ sessiond_config_apply_env_config(&config);
+
/*
* Parse arguments and load the daemon configuration file.
*
goto exit_options;
}
- /* Init config from environment variables. */
- sessiond_config_apply_env_config(&config);
-
/*
* Resolve all paths received as arguments, configuration option, or
* through environment variable as absolute paths. This is necessary