Merge pull request #3481 from alexrp/master
authorAlex Rønne Petersen <alex@alexrp.com>
Tue, 30 Aug 2016 22:23:43 +0000 (00:23 +0200)
committerGitHub <noreply@github.com>
Tue, 30 Aug 2016 22:23:43 +0000 (00:23 +0200)
Even more profiler fixes/improvements

14 files changed:
mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestChannel.cs
mcs/class/corlib/Test/System/DelegateTest.cs
mono/metadata/domain.c
mono/metadata/icall.c
mono/mini/mini-llvm.c
mono/sgen/sgen-marksweep.c
mono/unit-tests/test-conc-hashtable.c
mono/utils/atomic.h
mono/utils/mono-compiler.h
mono/utils/mono-membar.h
mono/utils/mono-threads-posix.c
mono/utils/mono-threads-windows.c
mono/utils/mono-threads.c
mono/utils/mono-threads.h

index 77995b55137a7127af793c38a406ebe1bb7fe3d3..4e4d73f9fb186fe974c15de0cfd45fdfa692f4eb 100644 (file)
@@ -126,6 +126,7 @@ namespace System.ServiceModel.Channels
                        }
 
                        web_request.Timeout = (int) timeout.TotalMilliseconds;
+                       web_request.KeepAlive = httpbe.KeepAliveEnabled;
 
                        // There is no SOAP Action/To header when AddressingVersion is None.
                        if (message.Version.Envelope.Equals (EnvelopeVersion.Soap11) ||
index e1d95dc93f00f563a4a7415708b3714d5a107a4f..ba664353ab9e0056492a1ae525057969609af25e 100644 (file)
@@ -1445,6 +1445,18 @@ namespace MonoTests.System
                        var del = Delegate.Remove (del1, del2);
                }
 
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void CreateDelegateThrowsAnArgumentExceptionWhenCalledWithAnOpenGeneric()
+               {
+                       var m = GetType().GetMethod("AnyGenericMethod");
+                       Delegate.CreateDelegate(typeof(Action), this, m);
+               }
+
+               public void AnyGenericMethod<T>()
+               {
+               }
+
                static bool Int32D2 (int x, int y)
                {
                        return (x & y) == y; 
index 0ceac2d500a98698255e82d3f9cff616c21dc88e..54e4115771d8a8d52a48e752fec201f173d2aefd 100644 (file)
@@ -525,6 +525,7 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
 #endif
 
 #ifndef HOST_WIN32
+       mono_w32handle_init ();
        wapi_init ();
 #endif
 
index 44ac525412d0fc974f43fdd2df2f0055b0ee5364..e1af074c4b459028a909b6e5e75165829ebe74a6 100644 (file)
@@ -6212,6 +6212,7 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
        MonoObject *delegate;
        gpointer func;
        MonoMethod *method = info->method;
+       MonoMethodSignature *sig = mono_method_signature(method);
 
        mono_class_init_checked (delegate_class, &error);
        if (mono_error_set_pending_exception (&error))
@@ -6236,6 +6237,13 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
                }
        }
 
+       if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
+               if (!method->is_inflated) {
+                       mono_set_pending_exception(mono_get_exception_argument("method", " Cannot bind to the target method because its signature differs from that of the delegate type"));
+                       return NULL;
+               }
+       }
+
        delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
        if (mono_error_set_pending_exception (&error))
                return NULL;
index d2ae0a74c372d5d486ade5b7f780bb903374dd4b..3ca1bca04c16a83087b5b01bf5c6eba63f020576 100644 (file)
@@ -5375,6 +5375,17 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
                        break;
                }
+
+/*
+ * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
+ * hack is necessary (for now).
+ */
+#ifdef TARGET_ARM64
+#define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
+#else
+#define ARM64_ATOMIC_FENCE_FIX
+#endif
+
                case OP_ATOMIC_EXCHANGE_I4:
                case OP_ATOMIC_EXCHANGE_I8: {
                        LLVMValueRef args [2];
@@ -5390,7 +5401,9 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
                        args [1] = convert (ctx, rhs, t);
 
+                       ARM64_ATOMIC_FENCE_FIX;
                        values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
+                       ARM64_ATOMIC_FENCE_FIX;
                        break;
                }
                case OP_ATOMIC_ADD_I4:
@@ -5407,7 +5420,9 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
 
                        args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
                        args [1] = convert (ctx, rhs, t);
+                       ARM64_ATOMIC_FENCE_FIX;
                        values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
+                       ARM64_ATOMIC_FENCE_FIX;
                        break;
                }
                case OP_ATOMIC_CAS_I4:
@@ -5425,7 +5440,9 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        args [1] = convert (ctx, values [ins->sreg3], t);
                        /* new value */
                        args [2] = convert (ctx, values [ins->sreg2], t);
+                       ARM64_ATOMIC_FENCE_FIX;
                        val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
+                       ARM64_ATOMIC_FENCE_FIX;
                        /* cmpxchg returns a pair */
                        values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
                        break;
@@ -5466,7 +5483,9 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
 
                        addr = convert (ctx, addr, LLVMPointerType (t, 0));
 
+                       ARM64_ATOMIC_FENCE_FIX;
                        values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
+                       ARM64_ATOMIC_FENCE_FIX;
 
                        if (sext)
                                values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
@@ -5514,7 +5533,9 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
                        value = convert (ctx, values [ins->sreg1], t);
 
+                       ARM64_ATOMIC_FENCE_FIX;
                        emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
+                       ARM64_ATOMIC_FENCE_FIX;
                        break;
                }
                case OP_RELAXED_NOP: {
index aa5ef1a44a93ace9fe040a3089e3bcffbf19f93e..a215c44502c12b226359ff45fddafe511f569374 100644 (file)
@@ -1138,10 +1138,7 @@ major_get_and_reset_num_major_objects_marked (void)
 
 /* gcc 4.2.1 from xcode4 crashes on sgen_card_table_get_card_address () when this is enabled */
 #if defined(PLATFORM_MACOSX)
-#define GCC_VERSION (__GNUC__ * 10000 \
-                               + __GNUC_MINOR__ * 100 \
-                               + __GNUC_PATCHLEVEL__)
-#if GCC_VERSION <= 40300
+#if MONO_GNUC_VERSION <= 40300
 #undef PREFETCH_CARDS
 #endif
 #endif
index 32d859c50d56cee18c92a9518db37a9c762a0597..abb24d9825f3ff143e20fa0cf73009455c72f1d8 100644 (file)
@@ -11,6 +11,7 @@
 #include "utils/mono-threads.h"
 #include "utils/mono-conc-hashtable.h"
 #include "utils/checked-build.h"
+#include "utils/w32handle.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -335,6 +336,9 @@ main (void)
        memset (&ticallbacks, 0, sizeof (ticallbacks));
        ticallbacks.thread_state_init = thread_state_init;
        mono_threads_runtime_init (&ticallbacks);
+#ifndef HOST_WIN32
+       mono_w32handle_init ();
+#endif
 
        mono_thread_info_attach ((gpointer)&cb);
 
index 4f5f010afd31bd61551347f754fe9f31639b0bae..dca6170a1a1e72cfe2f03cc77a5ce9a2895e1d6d 100755 (executable)
@@ -14,6 +14,7 @@
 
 #include "config.h"
 #include <glib.h>
+#include <mono/utils/mono-membar.h>
 
 /*
 The current Nexus 7 arm-v7a fails with:
@@ -29,7 +30,6 @@ Apple targets have historically being problematic, xcode 4.6 would miscompile th
 #define WIN32_LEAN_AND_MEAN
 #endif
 #include <windows.h>
-#include <mono/utils/mono-membar.h>
 
 /* mingw is missing InterlockedCompareExchange64 () from winbase.h */
 #if HAVE_DECL_INTERLOCKEDCOMPAREEXCHANGE64==0
@@ -180,30 +180,63 @@ static inline void InterlockedWrite16(volatile gint16 *dst, gint16 val)
 /* Prefer GCC atomic ops if the target supports it (see configure.ac). */
 #elif defined(USE_GCC_ATOMIC_OPS)
 
+/*
+ * As of this comment (August 2016), all current Clang versions get atomic
+ * intrinsics on ARM64 wrong. All GCC versions prior to 5.3.0 do, too. The bug
+ * is the same: The compiler developers thought that the acq + rel barriers
+ * that ARM64 load/store instructions can impose are sufficient to provide
+ * sequential consistency semantics. This is not the case:
+ *
+ *     http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/229588.html
+ *
+ * We work around this bug by inserting full barriers around each atomic
+ * intrinsic if we detect that we're built with a buggy compiler.
+ */
+
+#if defined (HOST_ARM64) && (defined (__clang__) || MONO_GNUC_VERSION < 50300)
+#define WRAP_ATOMIC_INTRINSIC(INTRIN) \
+       ({ \
+               mono_memory_barrier (); \
+               __typeof__ (INTRIN) atomic_ret__ = (INTRIN); \
+               mono_memory_barrier (); \
+               atomic_ret__; \
+       })
+
+#define gcc_sync_val_compare_and_swap(a, b, c) WRAP_ATOMIC_INTRINSIC (__sync_val_compare_and_swap (a, b, c))
+#define gcc_sync_add_and_fetch(a, b) WRAP_ATOMIC_INTRINSIC (__sync_add_and_fetch (a, b))
+#define gcc_sync_sub_and_fetch(a, b) WRAP_ATOMIC_INTRINSIC (__sync_sub_and_fetch (a, b))
+#define gcc_sync_fetch_and_add(a, b) WRAP_ATOMIC_INTRINSIC (__sync_fetch_and_add (a, b))
+#else
+#define gcc_sync_val_compare_and_swap(a, b, c) __sync_val_compare_and_swap (a, b, c)
+#define gcc_sync_add_and_fetch(a, b) __sync_add_and_fetch (a, b)
+#define gcc_sync_sub_and_fetch(a, b) __sync_sub_and_fetch (a, b)
+#define gcc_sync_fetch_and_add(a, b) __sync_fetch_and_add (a, b)
+#endif
+
 static inline gint32 InterlockedCompareExchange(volatile gint32 *dest,
                                                gint32 exch, gint32 comp)
 {
-       return __sync_val_compare_and_swap (dest, comp, exch);
+       return gcc_sync_val_compare_and_swap (dest, comp, exch);
 }
 
 static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp)
 {
-       return __sync_val_compare_and_swap (dest, comp, exch);
+       return gcc_sync_val_compare_and_swap (dest, comp, exch);
 }
 
 static inline gint32 InterlockedAdd(volatile gint32 *dest, gint32 add)
 {
-       return __sync_add_and_fetch (dest, add);
+       return gcc_sync_add_and_fetch (dest, add);
 }
 
 static inline gint32 InterlockedIncrement(volatile gint32 *val)
 {
-       return __sync_add_and_fetch (val, 1);
+       return gcc_sync_add_and_fetch (val, 1);
 }
 
 static inline gint32 InterlockedDecrement(volatile gint32 *val)
 {
-       return __sync_sub_and_fetch (val, 1);
+       return gcc_sync_sub_and_fetch (val, 1);
 }
 
 static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val)
@@ -211,7 +244,7 @@ static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val)
        gint32 old_val;
        do {
                old_val = *val;
-       } while (__sync_val_compare_and_swap (val, old_val, new_val) != old_val);
+       } while (gcc_sync_val_compare_and_swap (val, old_val, new_val) != old_val);
        return old_val;
 }
 
@@ -221,30 +254,30 @@ static inline gpointer InterlockedExchangePointer(volatile gpointer *val,
        gpointer old_val;
        do {
                old_val = *val;
-       } while (__sync_val_compare_and_swap (val, old_val, new_val) != old_val);
+       } while (gcc_sync_val_compare_and_swap (val, old_val, new_val) != old_val);
        return old_val;
 }
 
 static inline gint32 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
 {
-       return __sync_fetch_and_add (val, add);
+       return gcc_sync_fetch_and_add (val, add);
 }
 
 static inline gint8 InterlockedRead8(volatile gint8 *src)
 {
        /* Kind of a hack, but GCC doesn't give us anything better, and it's
         * certainly not as bad as using a CAS loop. */
-       return __sync_fetch_and_add (src, 0);
+       return gcc_sync_fetch_and_add (src, 0);
 }
 
 static inline gint16 InterlockedRead16(volatile gint16 *src)
 {
-       return __sync_fetch_and_add (src, 0);
+       return gcc_sync_fetch_and_add (src, 0);
 }
 
 static inline gint32 InterlockedRead(volatile gint32 *src)
 {
-       return __sync_fetch_and_add (src, 0);
+       return gcc_sync_fetch_and_add (src, 0);
 }
 
 static inline void InterlockedWrite8(volatile gint8 *dst, gint8 val)
@@ -253,7 +286,7 @@ static inline void InterlockedWrite8(volatile gint8 *dst, gint8 val)
        gint8 old_val;
        do {
                old_val = *dst;
-       } while (__sync_val_compare_and_swap (dst, old_val, val) != old_val);
+       } while (gcc_sync_val_compare_and_swap (dst, old_val, val) != old_val);
 }
 
 static inline void InterlockedWrite16(volatile gint16 *dst, gint16 val)
@@ -261,7 +294,7 @@ static inline void InterlockedWrite16(volatile gint16 *dst, gint16 val)
        gint16 old_val;
        do {
                old_val = *dst;
-       } while (__sync_val_compare_and_swap (dst, old_val, val) != old_val);
+       } while (gcc_sync_val_compare_and_swap (dst, old_val, val) != old_val);
 }
 
 static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
@@ -270,7 +303,7 @@ static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
        gint32 old_val;
        do {
                old_val = *dst;
-       } while (__sync_val_compare_and_swap (dst, old_val, val) != old_val);
+       } while (gcc_sync_val_compare_and_swap (dst, old_val, val) != old_val);
 }
 
 #if defined (TARGET_OSX) || defined (__arm__) || (defined (__mips__) && !defined (__mips64)) || (defined (__powerpc__) && !defined (__powerpc64__)) || (defined (__sparc__) && !defined (__arch64__))
@@ -281,33 +314,33 @@ static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
 
 static inline gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
 {
-       return __sync_val_compare_and_swap (dest, comp, exch);
+       return gcc_sync_val_compare_and_swap (dest, comp, exch);
 }
 
 static inline gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add)
 {
-       return __sync_add_and_fetch (dest, add);
+       return gcc_sync_add_and_fetch (dest, add);
 }
 
 static inline gint64 InterlockedIncrement64(volatile gint64 *val)
 {
-       return __sync_add_and_fetch (val, 1);
+       return gcc_sync_add_and_fetch (val, 1);
 }
 
 static inline gint64 InterlockedDecrement64(volatile gint64 *val)
 {
-       return __sync_sub_and_fetch (val, 1);
+       return gcc_sync_sub_and_fetch (val, 1);
 }
 
 static inline gint64 InterlockedExchangeAdd64(volatile gint64 *val, gint64 add)
 {
-       return __sync_fetch_and_add (val, add);
+       return gcc_sync_fetch_and_add (val, add);
 }
 
 static inline gint64 InterlockedRead64(volatile gint64 *src)
 {
        /* Kind of a hack, but GCC doesn't give us anything better. */
-       return __sync_fetch_and_add (src, 0);
+       return gcc_sync_fetch_and_add (src, 0);
 }
 
 #else
@@ -393,122 +426,6 @@ static inline void InterlockedWrite64(volatile gint64 *dst, gint64 val)
        InterlockedExchange64 (dst, val);
 }
 
-#elif defined(__ia64__)
-
-#ifdef __INTEL_COMPILER
-#include <ia64intrin.h>
-#endif
-
-static inline gint32 InterlockedCompareExchange(gint32 volatile *dest,
-                                               gint32 exch, gint32 comp)
-{
-       gint32 old;
-       guint64 real_comp;
-
-#ifdef __INTEL_COMPILER
-       old = _InterlockedCompareExchange (dest, exch, comp);
-#else
-       /* cmpxchg4 zero extends the value read from memory */
-       real_comp = (guint64)(guint32)comp;
-       asm volatile ("mov ar.ccv = %2 ;;\n\t"
-                                 "cmpxchg4.acq %0 = [%1], %3, ar.ccv\n\t"
-                                 : "=r" (old) : "r" (dest), "r" (real_comp), "r" (exch));
-#endif
-
-       return(old);
-}
-
-static inline gpointer InterlockedCompareExchangePointer(gpointer volatile *dest,
-                                               gpointer exch, gpointer comp)
-{
-       gpointer old;
-
-#ifdef __INTEL_COMPILER
-       old = _InterlockedCompareExchangePointer (dest, exch, comp);
-#else
-       asm volatile ("mov ar.ccv = %2 ;;\n\t"
-                                 "cmpxchg8.acq %0 = [%1], %3, ar.ccv\n\t"
-                                 : "=r" (old) : "r" (dest), "r" (comp), "r" (exch));
-#endif
-
-       return(old);
-}
-
-static inline gint32 InterlockedIncrement(gint32 volatile *val)
-{
-#ifdef __INTEL_COMPILER
-       return _InterlockedIncrement (val);
-#else
-       gint32 old;
-
-       do {
-               old = *val;
-       } while (InterlockedCompareExchange (val, old + 1, old) != old);
-
-       return old + 1;
-#endif
-}
-
-static inline gint32 InterlockedDecrement(gint32 volatile *val)
-{
-#ifdef __INTEL_COMPILER
-       return _InterlockedDecrement (val);
-#else
-       gint32 old;
-
-       do {
-               old = *val;
-       } while (InterlockedCompareExchange (val, old - 1, old) != old);
-
-       return old - 1;
-#endif
-}
-
-static inline gint32 InterlockedExchange(gint32 volatile *dest, gint32 new_val)
-{
-#ifdef __INTEL_COMPILER
-       return _InterlockedExchange (dest, new_val);
-#else
-       gint32 res;
-
-       do {
-               res = *dest;
-       } while (InterlockedCompareExchange (dest, new_val, res) != res);
-
-       return res;
-#endif
-}
-
-static inline gpointer InterlockedExchangePointer(gpointer volatile *dest, gpointer new_val)
-{
-#ifdef __INTEL_COMPILER
-       return (gpointer)_InterlockedExchange64 ((gint64*)dest, (gint64)new_val);
-#else
-       gpointer res;
-
-       do {
-               res = *dest;
-       } while (InterlockedCompareExchangePointer (dest, new_val, res) != res);
-
-       return res;
-#endif
-}
-
-static inline gint32 InterlockedExchangeAdd(gint32 volatile *val, gint32 add)
-{
-       gint32 old;
-
-#ifdef __INTEL_COMPILER
-       old = _InterlockedExchangeAdd (val, add);
-#else
-       do {
-               old = *val;
-       } while (InterlockedCompareExchange (val, old + add, old) != old);
-
-       return old;
-#endif
-}
-
 #else
 
 #define WAPI_NO_ATOMIC_ASM
index 2b3b86e2ef2e305dd8de427b6eb4902b999283de..d03ba8051aa565a53319b35aad89cecae2b9f450 100644 (file)
@@ -303,5 +303,9 @@ typedef SSIZE_T ssize_t;
 #define MONO_COLD
 #endif
 
+#if defined (__GNUC__) && defined (__GNUC_MINOR__) && defined (__GNUC_PATCHLEVEL__)
+#define MONO_GNUC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#endif
+
 #endif /* __UTILS_MONO_COMPILER_H__*/
 
index 60f6164dc4511921906c9076701ea86db707f50e..b59ffff85f93b28573c3089420381f8eeef6b484 100644 (file)
@@ -56,21 +56,6 @@ static inline void mono_memory_read_barrier (void)
        mono_memory_barrier ();
 }
 
-static inline void mono_memory_write_barrier (void)
-{
-       mono_memory_barrier ();
-}
-#elif defined(__ia64__)
-static inline void mono_memory_barrier (void)
-{
-       __asm__ __volatile__ ("mf" : : : "memory");
-}
-
-static inline void mono_memory_read_barrier (void)
-{
-       mono_memory_barrier ();
-}
-
 static inline void mono_memory_write_barrier (void)
 {
        mono_memory_barrier ();
index 60f5585e1823dbb35454d0a5197cc0886d02efc0..c92f7bb316f814400e151a10f59a798ca5a74697 100644 (file)
@@ -228,17 +228,6 @@ mono_threads_platform_create_thread (MonoThreadStart start_routine, gpointer arg
        return start_info.handle;
 }
 
-/*
- * mono_threads_platform_resume_created:
- *
- *   Resume a newly created thread created using CREATE_SUSPENDED.
- */
-void
-mono_threads_platform_resume_created (MonoThreadInfo *info, MonoNativeThreadId tid)
-{
-       mono_coop_sem_post (&info->create_suspended_sem);
-}
-
 gboolean
 mono_threads_platform_yield (void)
 {
index f66e6936b6dc1df123ab5060db34eb65a74ef86f..97f75f0db1e5544155933bf8846256723c9f8b36 100644 (file)
@@ -154,7 +154,6 @@ typedef struct {
        gint32 priority;
        MonoCoopSem registered;
        gboolean suspend;
-       HANDLE suspend_event;
        HANDLE handle;
 } ThreadStartInfo;
 
@@ -166,22 +165,28 @@ inner_start_thread (LPVOID arg)
        LPTHREAD_START_ROUTINE start_func = start_info->start_routine;
        DWORD result;
        gboolean suspend = start_info->suspend;
-       HANDLE suspend_event = start_info->suspend_event;
        MonoThreadInfo *info;
+       int res;
 
        info = mono_thread_info_attach (&result);
        info->runtime_thread = TRUE;
-       info->create_suspended = suspend;
 
        start_info->handle = info->handle;
 
        mono_threads_platform_set_priority(info, start_info->priority);
 
+       if (suspend) {
+               info->create_suspended = TRUE;
+               mono_coop_sem_init (&info->create_suspended_sem, 0);
+       }
+
        mono_coop_sem_post (&(start_info->registered));
 
        if (suspend) {
-               WaitForSingleObject (suspend_event, INFINITE); /* caller will suspend the thread before setting the event. */
-               CloseHandle (suspend_event);
+               res = mono_coop_sem_wait (&info->create_suspended_sem, MONO_SEM_FLAGS_NONE);
+               g_assert (res != -1);
+
+               mono_coop_sem_destroy (&info->create_suspended_sem);
        }
 
        result = start_func (t_arg);
@@ -207,11 +212,6 @@ mono_threads_platform_create_thread (MonoThreadStart start_routine, gpointer arg
        start_info.suspend = creation_flags & CREATE_SUSPENDED;
        start_info.priority = tp->priority;
        creation_flags &= ~CREATE_SUSPENDED;
-       if (start_info.suspend) {
-               start_info.suspend_event = CreateEvent (NULL, TRUE, FALSE, NULL);
-               if (!start_info.suspend_event)
-                       return NULL;
-       }
 
        result = CreateThread (NULL, tp->stack_size, inner_start_thread, &start_info, creation_flags, &thread_id);
        if (result) {
@@ -221,13 +221,6 @@ mono_threads_platform_create_thread (MonoThreadStart start_routine, gpointer arg
                /* A new handle has been opened when attaching
                 * the thread, so we don't need this one */
                CloseHandle (result);
-
-               if (start_info.suspend) {
-                       g_assert (SuspendThread (start_info.handle) != (DWORD)-1);
-                       SetEvent (start_info.suspend_event);
-               }
-       } else if (start_info.suspend) {
-               CloseHandle (start_info.suspend_event);
        }
        if (out_tid)
                *out_tid = thread_id;
@@ -254,17 +247,6 @@ mono_native_thread_create (MonoNativeThreadId *tid, gpointer func, gpointer arg)
        return CreateThread (NULL, 0, (func), (arg), 0, (tid)) != NULL;
 }
 
-void
-mono_threads_platform_resume_created (MonoThreadInfo *info, MonoNativeThreadId tid)
-{
-       HANDLE handle;
-
-       handle = OpenThread (THREAD_ALL_ACCESS, TRUE, tid);
-       g_assert (handle);
-       ResumeThread (handle);
-       CloseHandle (handle);
-}
-
 #if HAVE_DECL___READFSDWORD==0
 static MONO_ALWAYS_INLINE unsigned long long
 __readfsdword (unsigned long offset)
index 980522621b264ca3709ab733d6e76928853a1fb4..12c95c7861bda5eb2bb8f92d3efce2e72dac577d 100644 (file)
@@ -770,7 +770,7 @@ mono_thread_info_core_resume (MonoThreadInfo *info)
                MonoNativeThreadId tid = mono_thread_info_get_tid (info);
                /* Have to special case this, as the normal suspend/resume pair are racy, they don't work if he resume is received before the suspend */
                info->create_suspended = FALSE;
-               mono_threads_platform_resume_created (info, tid);
+               mono_coop_sem_post (&info->create_suspended_sem);
                return TRUE;
        }
 
index 4611892ceb7de8bde1c362b78fae9735c19a2092..a59430e855cf2b374f77fd96db6022890b693862 100644 (file)
@@ -536,7 +536,6 @@ gboolean mono_threads_suspend_needs_abort_syscall (void);
 void mono_threads_platform_register (THREAD_INFO_TYPE *info);
 void mono_threads_platform_unregister (THREAD_INFO_TYPE *info);
 HANDLE mono_threads_platform_create_thread (MonoThreadStart start, gpointer arg, MonoThreadParm *, MonoNativeThreadId *out_tid);
-void mono_threads_platform_resume_created (THREAD_INFO_TYPE *info, MonoNativeThreadId tid);
 void mono_threads_platform_get_stack_bounds (guint8 **staddr, size_t *stsize);
 gboolean mono_threads_platform_yield (void);
 void mono_threads_platform_exit (int exit_code);