From: Vlad Brezae Date: Thu, 29 Sep 2016 11:30:15 +0000 (+0300) Subject: [sgen] Add worker index to the binary protocol entries X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=33e80a5291986e98251198c13086f91fcc2a40e2 [sgen] Add worker index to the binary protocol entries --- diff --git a/mono/sgen/sgen-protocol.c b/mono/sgen/sgen-protocol.c index a399aa088da..66e80d97e55 100644 --- a/mono/sgen/sgen-protocol.c +++ b/mono/sgen/sgen-protocol.c @@ -340,30 +340,37 @@ static void protocol_entry (unsigned char type, gpointer data, int size) { int index; + gboolean include_worker_index = type != PROTOCOL_ID (binary_protocol_header); + int entry_size = size + 1 + (include_worker_index ? 1 : 0); // type + worker_index + size BinaryProtocolBuffer *buffer; if (binary_protocol_file == invalid_file_value) return; - if (sgen_thread_pool_is_thread_pool_thread (mono_native_thread_id_get ())) - type |= 0x80; - lock_recursive (); retry: buffer = binary_protocol_get_buffer (size + 1); retry_same_buffer: index = buffer->index; - if (index + 1 + size > BINARY_PROTOCOL_BUFFER_SIZE) + if (index + entry_size > BINARY_PROTOCOL_BUFFER_SIZE) goto retry; - if (InterlockedCompareExchange (&buffer->index, index + 1 + size, index) != index) + if (InterlockedCompareExchange (&buffer->index, index + entry_size, index) != index) goto retry_same_buffer; /* FIXME: if we're interrupted at this point, we have a buffer entry that contains random data. */ buffer->buffer [index++] = type; + /* We should never change the header format */ + if (include_worker_index) { + /* + * If the thread is not a worker thread we insert 0, which is interpreted + * as gc thread. Worker indexes are 1 based. + */ + buffer->buffer [index++] = (unsigned char) sgen_thread_pool_is_thread_pool_thread (mono_native_thread_id_get ()); + } memcpy (buffer->buffer + index, data, size); index += size; diff --git a/mono/sgen/sgen-protocol.h b/mono/sgen/sgen-protocol.h index db873fe8890..b0892f4478f 100644 --- a/mono/sgen/sgen-protocol.h +++ b/mono/sgen/sgen-protocol.h @@ -21,7 +21,7 @@ * should be able to handle all the previous versions, while an old grepper will * be able to tell if it cannot handle the format. */ -#define PROTOCOL_HEADER_VERSION 1 +#define PROTOCOL_HEADER_VERSION 2 /* Special indices returned by MATCH_INDEX. */ #define BINARY_PROTOCOL_NO_MATCH (-1) diff --git a/mono/sgen/sgen-thread-pool.c b/mono/sgen/sgen-thread-pool.c index 62ad3ec480b..533d70a4076 100644 --- a/mono/sgen/sgen-thread-pool.c +++ b/mono/sgen/sgen-thread-pool.c @@ -268,17 +268,18 @@ sgen_thread_pool_wait_for_all_jobs (void) mono_os_mutex_unlock (&lock); } -gboolean +/* Return 0 if is not a thread pool thread or the thread number otherwise */ +int sgen_thread_pool_is_thread_pool_thread (MonoNativeThreadId some_thread) { int i; for (i = 0; i < threads_num; i++) { if (some_thread == threads [i]) - return TRUE; + return i + 1; } - return FALSE; + return 0; } #endif diff --git a/mono/sgen/sgen-thread-pool.h b/mono/sgen/sgen-thread-pool.h index 99bf7f6711f..e0835669a3c 100644 --- a/mono/sgen/sgen-thread-pool.h +++ b/mono/sgen/sgen-thread-pool.h @@ -41,6 +41,6 @@ void sgen_thread_pool_idle_wait (void); void sgen_thread_pool_wait_for_all_jobs (void); -gboolean sgen_thread_pool_is_thread_pool_thread (MonoNativeThreadId thread); +int sgen_thread_pool_is_thread_pool_thread (MonoNativeThreadId thread); #endif diff --git a/tools/sgen/sgen-grep-binprot.c b/tools/sgen/sgen-grep-binprot.c index ef7b07f6400..322f47a72ad 100644 --- a/tools/sgen/sgen-grep-binprot.c +++ b/tools/sgen/sgen-grep-binprot.c @@ -18,6 +18,8 @@ #include "sgen-entry-stream.h" #include "sgen-grep-binprot.h" +static int file_version = 0; + #ifdef BINPROT_HAS_HEADER #define PACKED_SUFFIX p #else @@ -57,13 +59,23 @@ typedef int64_t mword; #define MAX_ENTRY_SIZE (1 << 10) static int -read_entry (EntryStream *stream, void *data) +read_entry (EntryStream *stream, void *data, unsigned char *windex) { unsigned char type; ssize_t size; if (read_stream (stream, &type, 1) <= 0) return SGEN_PROTOCOL_EOF; + + if (windex) { + if (file_version >= 2) { + if (read_stream (stream, windex, 1) <= 0) + return SGEN_PROTOCOL_EOF; + } else { + *windex = !!(WORKER (type)); + } + } + switch (TYPE (type)) { #define BEGIN_PROTOCOL_ENTRY0(method) \ @@ -172,8 +184,6 @@ is_always_match (int type) } } -#define WORKER_PREFIX(t) (WORKER ((t)) ? "w" : " ") - enum { NO_COLOR = -1 }; typedef struct { @@ -238,10 +248,13 @@ index_color (int index, int num_nums, int *match_indices) } static void -print_entry (int type, void *data, int num_nums, int *match_indices, gboolean color_output) +print_entry (int type, void *data, int num_nums, int *match_indices, gboolean color_output, unsigned char worker_index) { const char *always_prefix = is_always_match (type) ? " " : ""; - printf ("%s%s ", WORKER_PREFIX (type), always_prefix); + if (worker_index) + printf ("w%-2d%s ", worker_index, always_prefix); + else + printf (" %s ", always_prefix); switch (TYPE (type)) { @@ -566,7 +579,7 @@ sgen_binary_protocol_read_header (EntryStream *stream) { #ifdef BINPROT_HAS_HEADER char data [MAX_ENTRY_SIZE]; - int type = read_entry (stream, data); + int type = read_entry (stream, data, NULL); if (type == SGEN_PROTOCOL_EOF) return FALSE; if (type == PROTOCOL_ID (binary_protocol_header)) { @@ -576,6 +589,7 @@ sgen_binary_protocol_read_header (EntryStream *stream) fprintf (stderr, "The file contains a newer version %d. We support up to %d. Please update.\n", str->version, PROTOCOL_HEADER_VERSION); exit (1); } + file_version = str->version; return TRUE; } } @@ -600,6 +614,7 @@ GREP_ENTRIES_FUNCTION_NAME (EntryStream *stream, int num_nums, long nums [], int gboolean dump_all, gboolean pause_times, gboolean color_output, unsigned long long first_entry_to_consider) { int type; + unsigned char worker_index; void *data = g_malloc0 (MAX_ENTRY_SIZE); int i; gboolean pause_times_stopped = FALSE; @@ -612,7 +627,7 @@ GREP_ENTRIES_FUNCTION_NAME (EntryStream *stream, int num_nums, long nums [], int return FALSE; entry_index = 0; - while ((type = read_entry (stream, data)) != SGEN_PROTOCOL_EOF) { + while ((type = read_entry (stream, data, &worker_index)) != SGEN_PROTOCOL_EOF) { if (entry_index < first_entry_to_consider) goto next_entry; if (pause_times) { @@ -667,7 +682,7 @@ GREP_ENTRIES_FUNCTION_NAME (EntryStream *stream, int num_nums, long nums [], int if (dump_all) printf (match ? "* " : " "); if (match || dump_all) - print_entry (type, data, num_nums, match_indices, color_output); + print_entry (type, data, num_nums, match_indices, color_output, worker_index); } next_entry: ++entry_index;