X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=libust%2Ftracectl.c;h=2f9215e65b29adc0df6095ce72c206425304c559;hb=1eba9d6b2081a1e75e7f711ac02023dde773bef1;hp=39756a55fec0e72602479593fce153408fc950d5;hpb=c95b244d5c6c391ea6a5deb400ac57ba38e837ba;p=ust.git diff --git a/libust/tracectl.c b/libust/tracectl.c index 39756a5..2f9215e 100644 --- a/libust/tracectl.c +++ b/libust/tracectl.c @@ -15,10 +15,16 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/* This file contains the implementation of the UST listener thread, which + * receives trace control commands. It also coordinates the initialization of + * libust. + */ + #define _GNU_SOURCE #include #include #include +#include #include #include #include @@ -48,6 +54,8 @@ */ s64 pidunique = -1LL; +extern struct chan_info_struct chan_infos[]; + struct list_head blocked_consumers = LIST_HEAD_INIT(blocked_consumers); static struct ustcomm_app ustcomm_app; @@ -456,18 +464,18 @@ static int do_cmd_get_subbuf_size(const char *recvbuf, struct ustcomm_source *sr return retval; } -static unsigned int poweroftwo(unsigned int x) -{ - unsigned int power2 = 1; - unsigned int hardcoded = 2147483648u; /* FIX max 2^31 */ - - if (x < 2) - return 2; +/* Return the power of two which is equal or higher to v */ - while (power2 < x && power2 < hardcoded) - power2 *= 2; - - return power2; +static unsigned int pow2_higher_or_eq(unsigned int v) +{ + int hb = fls(v); + int hbm1 = hb-1; + int retval = 1<<(hb-1); + + if(v-retval == 0) + return retval; + else + return retval<<1; } static int do_cmd_set_subbuf_size(const char *recvbuf, struct ustcomm_source *src) @@ -491,9 +499,10 @@ static int do_cmd_set_subbuf_size(const char *recvbuf, struct ustcomm_source *sr goto end; } - power = poweroftwo(size); + power = pow2_higher_or_eq(size); + power = max_t(unsigned int, 2u, power); if (power != size) - WARN("using the next 2^n = %u\n", power); + WARN("using the next power of two for buffer size = %u\n", power); ltt_lock_traces(); trace = _ltt_trace_find_setup(trace_name); @@ -1030,17 +1039,38 @@ static pthread_t listener_thread; void create_listener(void) { int result; + sigset_t sig_all_blocked; + sigset_t orig_parent_mask; if(have_listener) { WARN("not creating listener because we already had one"); return; } + /* A new thread created by pthread_create inherits the signal mask + * from the parent. To avoid any signal being received by the + * listener thread, we block all signals temporarily in the parent, + * while we create the listener thread. + */ + + sigfillset(&sig_all_blocked); + + result = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_parent_mask); + if(result) { + PERROR("pthread_sigmask: %s", strerror(result)); + } + result = pthread_create(&listener_thread, NULL, listener_main, NULL); if(result == -1) { PERROR("pthread_create"); } + /* Restore original signal mask in parent */ + result = pthread_sigmask(SIG_SETMASK, &orig_parent_mask, NULL); + if(result) { + PERROR("pthread_sigmask: %s", strerror(result)); + } + have_listener = 1; } @@ -1091,6 +1121,11 @@ static void __attribute__((constructor)) init() { int result; char* autoprobe_val = NULL; + char* subbuffer_size_val = NULL; + char* subbuffer_count_val = NULL; + unsigned int subbuffer_size; + unsigned int subbuffer_count; + unsigned int power; /* Assign the pidunique, to be able to differentiate the processes with same * pid, (before and after an exec). @@ -1174,6 +1209,23 @@ static void __attribute__((constructor)) init() } } + subbuffer_size_val = getenv("UST_SUBBUF_SIZE"); + if(subbuffer_size_val) { + sscanf(subbuffer_size_val, "%u", &subbuffer_size); + power = pow2_higher_or_eq(subbuffer_size); + if(power != subbuffer_size) + WARN("using the next power of two for buffer size = %u\n", power); + chan_infos[LTT_CHANNEL_UST].def_subbufsize = power; + } + + subbuffer_count_val = getenv("UST_SUBBUF_NUM"); + if(subbuffer_count_val) { + sscanf(subbuffer_count_val, "%u", &subbuffer_count); + if(subbuffer_count < 2) + subbuffer_count = 2; + chan_infos[LTT_CHANNEL_UST].def_subbufcount = subbuffer_count; + } + if(getenv("UST_TRACE")) { char trace_name[] = "auto"; char trace_type[] = "ustrelay"; @@ -1240,7 +1292,6 @@ static void __attribute__((constructor)) init() inform_consumer_daemon(trace_name); } - return; /* should decrementally destroy stuff if error */