Merge pull request #498 from Unroll-Me/master
[mono.git] / mono / metadata / sgen-os-posix.c
index 276923779f9e9b5b7034ab00f9936d860e96f0d8..b4f84d3899ae3689cbe781349b2533a53779a14b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * sgen-os-posix.c: Simple generational GC.
+ * sgen-os-posix.c: Posix support.
  *
  * Author:
  *     Paolo Molaro (lupus@ximian.com)
@@ -7,25 +7,20 @@
  *     Geoff Norton (gnorton@novell.com)
  *
  * Copyright 2010 Novell, Inc (http://www.novell.com)
+ * Copyright (C) 2012 Xamarin Inc
  *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License 2.0 as published by the Free Software Foundation;
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License 2.0 along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "config.h"
@@ -57,9 +52,7 @@ static void
 suspend_thread (SgenThreadInfo *info, void *context)
 {
        int stop_count;
-#ifdef USE_MONO_CTX
-       MonoContext monoctx;
-#else
+#ifndef USE_MONO_CTX
        gpointer regs [ARCH_NUM_REGS];
 #endif
        gpointer stack_start;
@@ -83,17 +76,16 @@ suspend_thread (SgenThreadInfo *info, void *context)
 
 #ifdef USE_MONO_CTX
                if (context) {
-                       mono_sigctx_to_monoctx (context, &monoctx);
-                       info->monoctx = &monoctx;
+                       mono_sigctx_to_monoctx (context, &info->ctx);
                } else {
-                       info->monoctx = NULL;
+                       memset (&info->ctx, 0, sizeof (MonoContext));
                }
 #else
                if (context) {
                        ARCH_COPY_SIGCTX_REGS (regs, context);
-                       info->stopped_regs = regs;
+                       memcpy (&info->regs, regs, sizeof (info->regs));
                } else {
-                       info->stopped_regs = NULL;
+                       memset (&info->regs, 0, sizeof (info->regs));
                }
 #endif
        } else {
@@ -102,9 +94,9 @@ suspend_thread (SgenThreadInfo *info, void *context)
 
        /* Notify the JIT */
        if (mono_gc_get_gc_callbacks ()->thread_suspend_func)
-               mono_gc_get_gc_callbacks ()->thread_suspend_func (info->runtime_data, context);
+               mono_gc_get_gc_callbacks ()->thread_suspend_func (info->runtime_data, context, NULL);
 
-       DEBUG (4, fprintf (gc_debug_file, "Posting suspend_ack_semaphore for suspend from %p %p\n", info, (gpointer)mono_native_thread_id_get ()));
+       SGEN_LOG (4, "Posting suspend_ack_semaphore for suspend from %p %p", info, (gpointer)mono_native_thread_id_get ());
 
        /*
        Block the restart signal. 
@@ -126,7 +118,7 @@ suspend_thread (SgenThreadInfo *info, void *context)
        /* Unblock the restart signal. */
        pthread_sigmask (SIG_UNBLOCK, &suspend_ack_signal_mask, NULL);
 
-       DEBUG (4, fprintf (gc_debug_file, "Posting suspend_ack_semaphore for resume from %p %p\n", info, (gpointer)mono_native_thread_id_get ()));
+       SGEN_LOG (4, "Posting suspend_ack_semaphore for resume from %p %p\n", info, (gpointer)mono_native_thread_id_get ());
        /* notify the waiting thread */
        MONO_SEM_POST (suspend_ack_semaphore_ptr);
 }
@@ -165,7 +157,7 @@ restart_handler (int sig)
        rely on pthread_self () and seatch over the thread list.
        */
        if (!info)
-               info = mono_thread_info_lookup (pthread_self ());
+               info = (SgenThreadInfo*)mono_thread_info_lookup (pthread_self ());
 
        /*
         * If a thread is dying there might be no thread info.  In
@@ -173,7 +165,7 @@ restart_handler (int sig)
         */
        if (info) {
                info->signal = restart_signal_num;
-               DEBUG (4, fprintf (gc_debug_file, "Restart handler in %p %p\n", info, (gpointer)mono_native_thread_id_get ()));
+               SGEN_LOG (4, "Restart handler in %p %p", info, (gpointer)mono_native_thread_id_get ());
        }
        errno = old_errno;
 }
@@ -198,7 +190,7 @@ sgen_wait_for_suspend_ack (int count)
        for (i = 0; i < count; ++i) {
                while ((result = MONO_SEM_WAIT (suspend_ack_semaphore_ptr)) != 0) {
                        if (errno != EINTR) {
-                               g_error ("sem_wait ()");
+                               g_error ("MONO_SEM_WAIT FAILED with %d errno %d (%s)", result, errno, strerror (errno));
                        }
                }
        }
@@ -225,6 +217,9 @@ sgen_thread_handshake (BOOL suspend)
 
        count = 0;
        FOREACH_THREAD_SAFE (info) {
+               if (info->joined_stw == suspend)
+                       continue;
+               info->joined_stw = suspend;
                if (mono_native_thread_id_equals (mono_thread_info_get_tid (info), me)) {
                        continue;
                }