X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=libust%2Ftracectl.c;h=463edb6b492897546a84cf3161c07c680a12eb10;hb=e005efaa25bb1c65019e147e5290733cf5e0c82d;hp=b058cb3ce19d0d317790ddbf03103164508d1eb4;hpb=e625e9191bcb16522072aa34301cc517392f85ba;p=ust.git diff --git a/libust/tracectl.c b/libust/tracectl.c index b058cb3..463edb6 100644 --- a/libust/tracectl.c +++ b/libust/tracectl.c @@ -558,14 +558,30 @@ static void listener_cleanup(void *ptr) pthread_mutex_unlock(&listen_sock_mutex); } -static void force_subbuf_switch() +static int force_subbuf_switch(const char *trace_name) { - struct ust_buffer *buf; + struct ust_trace *trace; + int i, j, retval = 0; + + ltt_lock_traces(); + trace = _ltt_trace_find(trace_name); + if (!trace) { + retval = -ENODATA; + DBG("Cannot find trace. It was likely destroyed by the user."); + goto unlock_traces; + } - cds_list_for_each_entry(buf, &open_buffers_list, - open_buffers_list) { - ltt_force_switch(buf, FORCE_FLUSH); + for (i = 0; i < trace->nr_channels; i++) { + for (j = 0; j < trace->channels[i].n_cpus; j++) { + ltt_force_switch(trace->channels[i].buf[j], + FORCE_FLUSH); + } } + +unlock_traces: + ltt_unlock_traces(); + + return retval; } /* Simple commands are those which need only respond with a return value. */ @@ -585,12 +601,6 @@ static int process_simple_client_cmd(int command, char *recv_buf) return setenv("UST_DAEMON_SOCKET", sock_msg->field, 1); } - case FORCE_SUBBUF_SWITCH: - /* FIXME: return codes? */ - force_subbuf_switch(); - - break; - default: return -EINVAL; } @@ -716,6 +726,15 @@ static int process_trace_cmd(int command, char *trace_name) return result; } return 0; + case FORCE_SUBBUF_SWITCH: + DBG("force switch"); + + result = force_subbuf_switch(trace_name); + if (result < 0) { + ERR("force_subbuf_switch failed"); + return result; + } + return 0; } return 0; @@ -957,7 +976,7 @@ static void process_client_cmd(struct ustcomm_header *recv_header, print_markers(fp); fclose(fp); - reply_header->size = size; + reply_header->size = size + 1; /* Include final \0 */ result = ustcomm_send(sock, reply_header, ptr); @@ -983,7 +1002,7 @@ static void process_client_cmd(struct ustcomm_header *recv_header, print_trace_events(fp); fclose(fp); - reply_header->size = size; + reply_header->size = size + 1; /* Include final \0 */ result = ustcomm_send(sock, reply_header, ptr); @@ -1048,6 +1067,7 @@ static void process_client_cmd(struct ustcomm_header *recv_header, case START_TRACE: case STOP_TRACE: case DESTROY_TRACE: + case FORCE_SUBBUF_SWITCH: { struct ustcomm_single_field *trace_inf = (struct ustcomm_single_field *)recv_buf; @@ -1697,6 +1717,7 @@ void ust_before_fork(ust_fork_info_t *fork_info) * Hold listen_sock_mutex to protect from listen_sock teardown. */ pthread_mutex_lock(&listen_sock_mutex); + rcu_bp_before_fork(); } /* Don't call this function directly in a traced program */ @@ -1717,24 +1738,20 @@ static void ust_after_fork_common(ust_fork_info_t *fork_info) void ust_after_fork_parent(ust_fork_info_t *fork_info) { + rcu_bp_after_fork_parent(); /* Release mutexes and reenable signals */ ust_after_fork_common(fork_info); } void ust_after_fork_child(ust_fork_info_t *fork_info) { - /* First sanitize the child */ + /* Release urcu mutexes */ + rcu_bp_after_fork_child(); + + /* Sanitize the child */ ust_fork(); /* Then release mutexes and reenable signals */ ust_after_fork_common(fork_info); - - /* - * Make sure we clean up the urcu-bp thread list in the child by running - * the garbage collection before any pthread_create can be called. - * Failure to do so could lead to a deadlock caused by reuse of a thread - * ID before urcu-bp garbage collection is performed. - */ - synchronize_rcu(); }