}
/* Create thread to manage the client socket */
- ret = pthread_create(&health_thread, NULL,
+ ret = pthread_create(&health_thread, default_pthread_attr(),
thread_manage_health, (void *) NULL);
if (ret) {
errno = ret;
cmm_smp_mb(); /* Read ready before following operations */
/* Create thread to manage channels */
- ret = pthread_create(&channel_thread, NULL,
+ ret = pthread_create(&channel_thread, default_pthread_attr(),
consumer_thread_channel_poll,
(void *) ctx);
if (ret) {
}
/* Create thread to manage the polling/writing of trace metadata */
- ret = pthread_create(&metadata_thread, NULL,
+ ret = pthread_create(&metadata_thread, default_pthread_attr(),
consumer_thread_metadata_poll,
(void *) ctx);
if (ret) {
}
/* Create thread to manage the polling/writing of trace data */
- ret = pthread_create(&data_thread, NULL, consumer_thread_data_poll,
- (void *) ctx);
+ ret = pthread_create(&data_thread, default_pthread_attr(),
+ consumer_thread_data_poll, (void *) ctx);
if (ret) {
errno = ret;
PERROR("pthread_create");
}
/* Create the thread to manage the receive of fd */
- ret = pthread_create(&sessiond_thread, NULL,
+ ret = pthread_create(&sessiond_thread, default_pthread_attr(),
consumer_thread_sessiond_poll,
(void *) ctx);
if (ret) {
* Create the thread to manage the UST metadata periodic timer and
* live timer.
*/
- ret = pthread_create(&metadata_timer_thread, NULL,
+ ret = pthread_create(&metadata_timer_thread, default_pthread_attr(),
consumer_timer_thread, (void *) ctx);
if (ret) {
errno = ret;
}
/* Setup the dispatcher thread */
- ret = pthread_create(&live_dispatcher_thread, NULL,
+ ret = pthread_create(&live_dispatcher_thread, default_pthread_attr(),
thread_dispatcher, (void *) NULL);
if (ret) {
errno = ret;
}
/* Setup the worker thread */
- ret = pthread_create(&live_worker_thread, NULL,
+ ret = pthread_create(&live_worker_thread, default_pthread_attr(),
thread_worker, NULL);
if (ret) {
errno = ret;
}
/* Setup the listener thread */
- ret = pthread_create(&live_listener_thread, NULL,
+ ret = pthread_create(&live_listener_thread, default_pthread_attr(),
thread_listener, (void *) NULL);
if (ret) {
errno = ret;
}
}
-
/* Initialize thread health monitoring */
health_relayd = health_app_create(NR_HEALTH_RELAYD_TYPES);
if (!health_relayd) {
}
/* Create thread to manage the client socket */
- ret = pthread_create(&health_thread, NULL,
+ ret = pthread_create(&health_thread, default_pthread_attr(),
thread_manage_health, (void *) NULL);
if (ret) {
errno = ret;
}
/* Setup the dispatcher thread */
- ret = pthread_create(&dispatcher_thread, NULL,
+ ret = pthread_create(&dispatcher_thread, default_pthread_attr(),
relay_thread_dispatcher, (void *) NULL);
if (ret) {
errno = ret;
}
/* Setup the worker thread */
- ret = pthread_create(&worker_thread, NULL,
+ ret = pthread_create(&worker_thread, default_pthread_attr(),
relay_thread_worker, NULL);
if (ret) {
errno = ret;
}
/* Setup the listener thread */
- ret = pthread_create(&listener_thread, NULL,
+ ret = pthread_create(&listener_thread, default_pthread_attr(),
relay_thread_listener, (void *) NULL);
if (ret) {
errno = ret;
goto error_quit_pipe;
}
- ret = pthread_create(thread, NULL, thread_ht_cleanup, NULL);
+ ret = pthread_create(thread, default_pthread_attr(), thread_ht_cleanup,
+ NULL);
if (ret) {
errno = ret;
PERROR("pthread_create ht_cleanup");
goto error;
}
- ret = pthread_create(&consumer_data->thread, NULL, thread_manage_consumer,
- consumer_data);
+ ret = pthread_create(&consumer_data->thread, default_pthread_attr(),
+ thread_manage_consumer, consumer_data);
if (ret) {
errno = ret;
PERROR("pthread_create consumer");
load_info->path = opt_load_session_path;
/* Create health-check thread */
- ret = pthread_create(&health_thread, NULL,
+ ret = pthread_create(&health_thread, default_pthread_attr(),
thread_manage_health, (void *) NULL);
if (ret) {
errno = ret;
}
/* Create thread to manage the client socket */
- ret = pthread_create(&client_thread, NULL,
+ ret = pthread_create(&client_thread, default_pthread_attr(),
thread_manage_clients, (void *) NULL);
if (ret) {
errno = ret;
}
/* Create thread to dispatch registration */
- ret = pthread_create(&dispatch_thread, NULL,
+ ret = pthread_create(&dispatch_thread, default_pthread_attr(),
thread_dispatch_ust_registration, (void *) NULL);
if (ret) {
errno = ret;
}
/* Create thread to manage application registration. */
- ret = pthread_create(®_apps_thread, NULL,
+ ret = pthread_create(®_apps_thread, default_pthread_attr(),
thread_registration_apps, (void *) NULL);
if (ret) {
errno = ret;
}
/* Create thread to manage application socket */
- ret = pthread_create(&apps_thread, NULL,
+ ret = pthread_create(&apps_thread, default_pthread_attr(),
thread_manage_apps, (void *) NULL);
if (ret) {
errno = ret;
}
/* Create thread to manage application notify socket */
- ret = pthread_create(&apps_notify_thread, NULL,
+ ret = pthread_create(&apps_notify_thread, default_pthread_attr(),
ust_thread_manage_notify, (void *) NULL);
if (ret) {
errno = ret;
}
/* Create agent registration thread. */
- ret = pthread_create(&agent_reg_thread, NULL,
+ ret = pthread_create(&agent_reg_thread, default_pthread_attr(),
agent_thread_manage_registration, (void *) NULL);
if (ret) {
errno = ret;
/* Don't start this thread if kernel tracing is not requested nor root */
if (is_root && !opt_no_kernel) {
/* Create kernel thread to manage kernel event */
- ret = pthread_create(&kernel_thread, NULL,
+ ret = pthread_create(&kernel_thread, default_pthread_attr(),
thread_manage_kernel, (void *) NULL);
if (ret) {
errno = ret;
}
/* Create session loading thread. */
- ret = pthread_create(&load_session_thread, NULL, thread_load_session,
- load_info);
+ ret = pthread_create(&load_session_thread, default_pthread_attr(),
+ thread_load_session, load_info);
if (ret) {
errno = ret;
PERROR("pthread_create load_session_thread");
#define _LGPL_SOURCE
#include <stddef.h>
#include <unistd.h>
+#include <stdbool.h>
+#include <sys/resource.h>
+#include <pthread.h>
#include "defaults.h"
#include "macros.h"
#include "align.h"
+#include "error.h"
+
+static bool pthread_attr_init_done;
+static pthread_attr_t tattr;
+static pthread_mutex_t tattr_lock = PTHREAD_MUTEX_INITIALIZER;
LTTNG_HIDDEN
size_t default_get_channel_subbuf_size(void)
{
return max(DEFAULT_UST_UID_CHANNEL_SUBBUF_SIZE, PAGE_SIZE);
}
+
+LTTNG_HIDDEN
+pthread_attr_t *default_pthread_attr(void)
+{
+ int ret = 0;
+ size_t ptstacksize;
+ struct rlimit rlim;
+
+ pthread_mutex_lock(&tattr_lock);
+
+ /* Return cached value. */
+ if (pthread_attr_init_done) {
+ goto end;
+ }
+
+ /* Get system stack size limits. */
+ ret = getrlimit(RLIMIT_STACK, &rlim);
+ if (ret < 0) {
+ PERROR("getrlimit");
+ goto error;
+ }
+ DBG("Stack size limits: soft %lld, hard %lld bytes",
+ (long long) rlim.rlim_cur,
+ (long long) rlim.rlim_max);
+
+ /* Get pthread default thread stack size. */
+ ret = pthread_attr_getstacksize(&tattr, &ptstacksize);
+ if (ret < 0) {
+ PERROR("pthread_attr_getstacksize");
+ goto error;
+ }
+ DBG("Default pthread stack size is %zu bytes", ptstacksize);
+
+ /* Check if the default pthread stack size honors ulimits. */
+ if (ptstacksize < rlim.rlim_cur) {
+ DBG("Your libc doesn't honor stack size limits, setting thread stack size to soft limit (%lld bytes)",
+ (long long) rlim.rlim_cur);
+
+ /* Create pthread_attr_t struct with ulimit stack size. */
+ ret = pthread_attr_setstacksize(&tattr, rlim.rlim_cur);
+ if (ret < 0) {
+ PERROR("pthread_attr_setstacksize");
+ goto error;
+ }
+ }
+
+ /* Enable cached value. */
+ pthread_attr_init_done = true;
+end:
+ pthread_mutex_unlock(&tattr_lock);
+ return &tattr;
+error:
+ pthread_mutex_unlock(&tattr_lock);
+ WARN("Failed to initialize pthread attributes, using libc defaults.");
+ return NULL;
+}
LTTNG_HIDDEN
size_t default_get_ust_uid_channel_subbuf_size(void);
+/*
+ * Get the default pthread_attr to use on thread creation.
+ *
+ * Some libc, such as musl, don't honor the limit set for the stack size and use
+ * their own empirically chosen static value. This function checks if the
+ * current stack size is smaller than the stack size limit and if so returns a
+ * pthread_attr_t pointer where the thread stack size is set to the soft stack
+ * size limit.
+ */
+LTTNG_HIDDEN
+pthread_attr_t *default_pthread_attr(void);
+
#endif /* _DEFAULTS_H */