[sgen] Add worker index to the binary protocol entries
authorVlad Brezae <brezaevlad@gmail.com>
Thu, 29 Sep 2016 11:30:15 +0000 (14:30 +0300)
committerVlad Brezae <brezaevlad@gmail.com>
Thu, 19 Jan 2017 22:45:16 +0000 (00:45 +0200)
mono/sgen/sgen-protocol.c
mono/sgen/sgen-protocol.h
mono/sgen/sgen-thread-pool.c
mono/sgen/sgen-thread-pool.h
tools/sgen/sgen-grep-binprot.c

index a399aa088da2fbe59635d443d777a79200698986..66e80d97e55483c544d38ed56214085926010149 100644 (file)
@@ -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;
 
index db873fe8890b83ff8fe5e30a6aff86ad9ee813e6..b0892f4478fd09effd1ee58ce2c7e2db5bbe3e9b 100644 (file)
@@ -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)
index 62ad3ec480bccc06d4c0a51b2360230075dc2af2..533d70a407669c1895f9559367f209cda73636a4 100644 (file)
@@ -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
index 99bf7f6711f5b9dcb2f0e6822c7c5b1135f55dfd..e0835669a3c28201e047059b2893c6cee8bf0599 100644 (file)
@@ -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
index ef7b07f6400399ae4139455fd1a510c4012e7d02..322f47a72ad518931ebcd2e8b1a8ae56807fba78 100644 (file)
@@ -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;