X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=libust%2Ftracectl.c;h=7a5cf9562282ce7fe90cc3d5e4c405d3bf44b8c6;hb=f51d84eac11907346fa02e33da358aad171ac80a;hp=74ad4ea6be59a309ab8a4634ae7af15d48725d2b;hpb=8649cd59b1c15b8d4097cf63f733e8007d76ad13;p=ust.git diff --git a/libust/tracectl.c b/libust/tracectl.c index 74ad4ea..7a5cf95 100644 --- a/libust/tracectl.c +++ b/libust/tracectl.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -456,18 +457,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 = 2147483648; /* FIX max 2^31 */ - - if (x < 2) - return 2; - - while (power2 < x && power2 < hardcoded) - power2 *= 2; +/* Return the power of two which is equal or higher to v */ - 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 +492,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 +1032,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; }