[runtime] Add a separate icall for Monitor.Enter(obj,&bool).
authorZoltan Varga <vargaz@gmail.com>
Mon, 3 Aug 2015 22:35:42 +0000 (18:35 -0400)
committerZoltan Varga <vargaz@gmail.com>
Mon, 3 Aug 2015 22:35:42 +0000 (18:35 -0400)
mcs/class/corlib/System.Threading/Monitor.cs
mono/metadata/icall-def.h
mono/metadata/monitor.c

index 026f46c3797430f24db8ba3911b8a03bd84749fd..5f00b0a1488576cb5dd1989ff4725207e9505b2b 100644 (file)
@@ -192,9 +192,12 @@ namespace System.Threading
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                extern static void try_enter_with_atomic_var (object obj, int millisecondsTimeout, ref bool lockTaken);
 
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               extern static void enter_with_atomic_var (object obj, ref bool lockTaken);
+
                public static void Enter (object obj, ref bool lockTaken)
                {
-                       TryEnter (obj, Timeout.Infinite, ref lockTaken);
+                       enter_with_atomic_var (obj, ref lockTaken);
                }
 
                public static void TryEnter (object obj, ref bool lockTaken)
index 3187a6b3876e2c4d0e04660f282cc095727b1b90..860dbd80785311dba2723d6009560d9ec0e8b640 100644 (file)
@@ -871,6 +871,7 @@ ICALL(MONIT_4, "Monitor_test_owner", ves_icall_System_Threading_Monitor_Monitor_
 ICALL(MONIT_5, "Monitor_test_synchronised", ves_icall_System_Threading_Monitor_Monitor_test_synchronised)
 ICALL(MONIT_6, "Monitor_try_enter", ves_icall_System_Threading_Monitor_Monitor_try_enter)
 ICALL(MONIT_7, "Monitor_wait", ves_icall_System_Threading_Monitor_Monitor_wait)
+ICALL(MONIT_10, "enter_with_atomic_var", mono_monitor_enter_v4)
 ICALL(MONIT_9, "try_enter_with_atomic_var", ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var)
 
 ICALL_TYPE(MUTEX, "System.Threading.Mutex", MUTEX_1)
index 5ebc2a09b6907f53e02b793f2df37fda096f32ce..53899fd03da6d2f1f656c66b103aa5645ce84cc4 100644 (file)
@@ -907,6 +907,20 @@ ves_icall_System_Threading_Monitor_Monitor_try_enter (MonoObject *obj, guint32 m
 
 void
 ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (MonoObject *obj, guint32 ms, char *lockTaken)
+{
+       gint32 res;
+       do {
+               res = mono_monitor_try_enter_internal (obj, ms, TRUE);
+               /*This means we got interrupted during the wait and didn't got the monitor.*/
+               if (res == -1)
+                       mono_thread_interruption_checkpoint ();
+       } while (res == -1);
+       /*It's safe to do it from here since interruption would happen only on the wrapper.*/
+       *lockTaken = res == 1;
+}
+
+void
+mono_monitor_enter_v4 (MonoObject *obj, char *lock_taken)
 {
        /* FASTPATH */
 #ifdef HAVE_MOVING_COLLECTOR
@@ -914,7 +928,7 @@ ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (MonoObject
        gsize id = mono_thread_info_get_small_id ();
        guint32 new_status, old_status, tmp_status;
 
-       if (G_LIKELY (obj && ms == INFINITE && *lockTaken == 0)) {
+       if (G_LIKELY (obj && *lock_taken == 0)) {
                mon = obj->synchronisation;
 
                if (G_LIKELY (mon)) {
@@ -932,7 +946,7 @@ ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (MonoObject
                                        tmp_status = InterlockedCompareExchange ((gint32*)&mon->status, new_status, old_status);
                                        if (G_LIKELY (tmp_status == old_status)) {
                                                /* Success */
-                                               *lockTaken = 1;
+                                               *lock_taken = 1;
                                                g_assert (mon->nest == 1);
                                                return;
                                        }
@@ -942,20 +956,6 @@ ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (MonoObject
        }
 #endif
 
-       gint32 res;
-       do {
-               res = mono_monitor_try_enter_internal (obj, ms, TRUE);
-               /*This means we got interrupted during the wait and didn't got the monitor.*/
-               if (res == -1)
-                       mono_thread_interruption_checkpoint ();
-       } while (res == -1);
-       /*It's safe to do it from here since interruption would happen only on the wrapper.*/
-       *lockTaken = res == 1;
-}
-
-void
-mono_monitor_enter_v4 (MonoObject *obj, char *lock_taken)
-{
        if (*lock_taken == 1) {
                mono_set_pending_exception (mono_get_exception_argument ("lockTaken", "lockTaken is already true"));
                return;