[corlib] Import System.Threading.Monitor
authorLudovic Henry <ludovic@xamarin.com>
Wed, 20 Apr 2016 17:19:02 +0000 (19:19 +0200)
committerLudovic Henry <ludovic@xamarin.com>
Wed, 4 May 2016 20:13:10 +0000 (16:13 -0400)
mcs/class/corlib/System.Threading/Monitor.cs
mcs/class/corlib/Test/System.Threading/MonitorTest.cs
mcs/class/corlib/corlib.dll.sources
mcs/class/referencesource/mscorlib/system/threading/monitor.cs
mono/metadata/icall-def.h
mono/metadata/marshal.c
mono/metadata/monitor.c
mono/metadata/monitor.h
mono/mini/method-to-ir.c

index b76c35d2d88324116507e97faef0a68db4969c08..9ec94ff97f9985ce8764e276fc3cae5cfe8dd964 100644 (file)
@@ -37,151 +37,51 @@ using System.Runtime.InteropServices;
 
 namespace System.Threading
 {
-       [ComVisible (true)]
-       public static class Monitor
+       public static partial class Monitor
        {
-               // Grabs the mutex on object 'obj', with a maximum
-               // wait time 'ms' but doesn't block - if it can't get
-               // the lock it returns false, true if it can
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static bool Monitor_try_enter(object obj, int ms);
+               extern static bool Monitor_test_synchronised(object obj);
 
-               // Enter/Exit are implemented directly as icalls for performance reasons
-
-               // Acquires the mutex on object 'obj'
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static void Enter(object obj);
-
-               // Releases the mutex on object 'obj'
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static void Exit(object obj);
-
-               // Signals one of potentially many objects waiting on
-               // object 'obj'
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static void Monitor_pulse(object obj);
+               extern static void Monitor_pulse(object obj);
 
-               // Checks whether object 'obj' is currently synchronised
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static bool Monitor_test_synchronised(object obj);
-
-               public static void Pulse(object obj) {
-                       if(obj==null) {
-                               throw new ArgumentNullException("obj");
-                       }
-                       if(Monitor_test_synchronised(obj)==false) {
+               static void ObjPulse(Object obj)
+               {
+                       if (!Monitor_test_synchronised (obj))
                                throw new SynchronizationLockException("Object is not synchronized");
-                       }
 
-                       Monitor_pulse(obj);
+                       Monitor_pulse (obj);
                }
 
-               // Signals all of potentially many objects waiting on
-               // object 'obj'
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static void Monitor_pulse_all(object obj);
-
-               public static void PulseAll(object obj) {
-                       if(obj==null) {
-                               throw new ArgumentNullException("obj");
-                       }
-                       if(Monitor_test_synchronised(obj)==false) {
-                               throw new SynchronizationLockException("Object is not synchronized");
-                       }
-
-                       Monitor_pulse_all(obj);
-               }
+               extern static void Monitor_pulse_all(object obj);
 
-               public static bool TryEnter (object obj)
+               static void ObjPulseAll(Object obj)
                {
-                       return TryEnter (obj, 0);
-               }
-
-               public static bool TryEnter (object obj, int millisecondsTimeout)
-               {
-                       if (obj == null)
-                               throw new ArgumentNullException ("obj");
-
-                       if (millisecondsTimeout == Timeout.Infinite) {
-                               Enter (obj);
-                               return true;
-                       }
-
-                       if (millisecondsTimeout < 0)
-                               throw new ArgumentException ("negative value for millisecondsTimeout", "millisecondsTimeout");
-                       
-                       return Monitor_try_enter (obj, millisecondsTimeout);
-               }
+                       if (!Monitor_test_synchronised (obj))
+                               throw new SynchronizationLockException("Object is not synchronized");
 
-               public static bool TryEnter (object obj, TimeSpan timeout)
-               {
-                       long ms = (long) timeout.TotalMilliseconds;
-                       if (ms < Timeout.Infinite || ms > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("timeout", "timeout out of range");
-                       
-                       return TryEnter (obj, (int) ms);
+                       Monitor_pulse_all (obj);
                }
 
-               // Waits for a signal on object 'obj' with maximum
-               // wait time 'ms'. Returns true if the object was
-               // signalled, false if it timed out
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static bool Monitor_wait(object obj, int ms);
-
-               public static bool Wait (object obj)
-               {
-                       return Wait (obj, Timeout.Infinite);
-               }
+               extern static bool Monitor_wait(object obj, int ms);
 
-               public static bool Wait (object obj, int millisecondsTimeout)
+               static bool ObjWait(bool exitContext, int millisecondsTimeout, Object obj)
                {
-                       if (obj == null)
-                               throw new ArgumentNullException ("obj");
-
-                       if (millisecondsTimeout < Timeout.Infinite)
-                               throw new ArgumentOutOfRangeException ("millisecondsTimeout", "timeout out of range");
-
+                       if (millisecondsTimeout < 0 && millisecondsTimeout != (int) Timeout.Infinite)
+                               throw new ArgumentOutOfRangeException ("millisecondsTimeout");
                        if (!Monitor_test_synchronised (obj))
                                throw new SynchronizationLockException ("Object is not synchronized");
 
-                       return Monitor_wait (obj, millisecondsTimeout);
-               }
-
-               public static bool Wait (object obj, TimeSpan timeout)
-               {
-                       long ms = (long) timeout.TotalMilliseconds;
-                       if (ms < Timeout.Infinite || ms > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("timeout", "timeout out of range");
-
-                       return Wait (obj, (int) ms);
-               }
-
-               public static bool Wait(object obj, int millisecondsTimeout, bool exitContext) {
                        try {
 #if !DISABLE_REMOTING
                                if (exitContext)
                                        SynchronizationAttribute.ExitContext ();
 #endif
-                               return Wait (obj, millisecondsTimeout);
-                       }
-                       finally {
-#if !DISABLE_REMOTING
-                               if (exitContext)
-                                       SynchronizationAttribute.EnterContext ();
-#endif
-                       }
-               }
 
-               public static bool Wait(object obj, TimeSpan timeout, bool exitContext) {
-                       try {
-#if !DISABLE_REMOTING
-                               if (exitContext)
-                                       SynchronizationAttribute.ExitContext ();
-#endif
-                               return Wait (obj, timeout);
-                       }
-                       finally {
+                               return Monitor_wait (obj, millisecondsTimeout);
+                       } finally {
 #if !DISABLE_REMOTING
                                if (exitContext)
                                        SynchronizationAttribute.EnterContext ();
@@ -192,50 +92,27 @@ 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);
-
-               // Can't make this an icall since it has the same name as the other Enter method
-               [MethodImpl(MethodImplOptions.AggressiveInlining)]
-               public static void Enter (object obj, ref bool lockTaken)
+               static void ReliableEnterTimeout(Object obj, int timeout, ref bool lockTaken)
                {
-                       enter_with_atomic_var (obj, ref lockTaken);
-               }
+                       if (obj == null)
+                               throw new ArgumentNullException ("obj");
+                       if (timeout < 0 && timeout != (int) Timeout.Infinite)
+                               throw new ArgumentOutOfRangeException ("millisecondsTimeout");
 
-               public static void TryEnter (object obj, ref bool lockTaken)
-               {
-                       TryEnter (obj, 0, ref lockTaken);
+                       try_enter_with_atomic_var (obj, timeout, ref lockTaken);
                }
 
-               public static void TryEnter (object obj, TimeSpan timeout, ref bool lockTaken)
+               static void ReliableEnter(Object obj, ref bool lockTaken)
                {
-                       long ms = (long) timeout.TotalMilliseconds;
-                       if (ms < Timeout.Infinite || ms > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("timeout", "timeout out of range");
-                       TryEnter (obj, (int)ms, ref lockTaken);
+                       ReliableEnterTimeout (obj, (int) Timeout.Infinite, ref lockTaken);
                }
 
-               public static void TryEnter (object obj, int millisecondsTimeout, ref bool lockTaken)
-               {
-                       if (obj == null)
-                               throw new ArgumentNullException ("obj");
-                       if (lockTaken)
-                               throw new ArgumentException ("lockTaken");
-
-                       if (millisecondsTimeout < 0 && millisecondsTimeout != Timeout.Infinite)
-                               throw new ArgumentException ("negative value for millisecondsTimeout", "millisecondsTimeout");
-
-                       try_enter_with_atomic_var (obj, millisecondsTimeout, ref lockTaken);
-               }               
-
-
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                extern static bool Monitor_test_owner (object obj);
 
-               public
-               static bool IsEntered (object obj)
+               static bool IsEnteredNative(Object obj)
                {
-                       return Monitor_test_owner(obj);
+                       return Monitor_test_owner (obj);
                }
        }
 }
index 1c4ae9408a0e936dcb9053181c91ca59f4ac5a29..158a9afc9424f0cb0b67358b8d588c4269273a0b 100644 (file)
@@ -144,7 +144,7 @@ namespace MonoTests.System.Threading {
                }
 
                [Test]
-               [ExpectedException (typeof (ArgumentException))]
+               [ExpectedException (typeof (ArgumentOutOfRangeException))]
                public void TryEnter_Int_Negative ()
                {
                        object o = new object ();
index d1202a94e80eccaa411fd34a533e27d8925a0ae1..76f25a22e35de24c0879a6f022c921f3828eda03 100644 (file)
@@ -1556,6 +1556,7 @@ ReferenceSources/SecurityContext.cs
 ../referencesource/mscorlib/system/threading/lockrecursionexception.cs
 ../referencesource/mscorlib/system/threading/manualresetevent.cs
 ../referencesource/mscorlib/system/threading/ManualResetEventSlim.cs
+../referencesource/mscorlib/system/threading/monitor.cs
 ../referencesource/mscorlib/system/threading/parameterizedthreadstart.cs
 ../referencesource/mscorlib/system/threading/semaphorefullexception.cs
 ../referencesource/mscorlib/system/threading/SemaphoreSlim.cs
index 9232230801d229d6917bcf3c9a72c48b9c5ed8a0..2bb82ed520e13f8c22650469c3ad1c723be7cfe2 100644 (file)
@@ -31,7 +31,7 @@ namespace System.Threading {
 
     [HostProtection(Synchronization=true, ExternalThreading=true)]
     [System.Runtime.InteropServices.ComVisible(true)]
-    public static class Monitor 
+    public static partial class Monitor
     {
         /*=========================================================================
         ** Obtain the monitor lock of obj. Will block if another thread holds the lock
@@ -66,11 +66,12 @@ namespace System.Threading {
             throw new ArgumentException(Environment.GetResourceString("Argument_MustBeFalse"), "lockTaken");
         }
 
+#if !MONO
         [System.Security.SecuritySafeCritical]
         [ResourceExposure(ResourceScope.None)]
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         private static extern void ReliableEnter(Object obj, ref bool lockTaken);
-
+#endif
 
 
         /*=========================================================================
@@ -160,10 +161,12 @@ namespace System.Threading {
             ReliableEnterTimeout(obj, MillisecondsTimeoutFromTimeSpan(timeout), ref lockTaken);
         }
 
+#if !MONO
         [System.Security.SecuritySafeCritical]
         [ResourceExposure(ResourceScope.None)]
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         private static extern void ReliableEnterTimeout(Object obj, int timeout, ref bool lockTaken);
+#endif
 
         [System.Security.SecuritySafeCritical]
         public static bool IsEntered(object obj)
@@ -174,10 +177,12 @@ namespace System.Threading {
             return IsEnteredNative(obj);
         }
 
+#if !MONO
         [System.Security.SecurityCritical]
         [ResourceExposure(ResourceScope.None)]
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         private static extern bool IsEnteredNative(Object obj);
+#endif
 
         /*========================================================================
     ** Waits for notification from the object (via a Pulse/PulseAll). 
@@ -190,10 +195,12 @@ namespace System.Threading {
     **
         ** Exceptions: ArgumentNullException if object is null.
     ========================================================================*/
+#if !MONO
         [System.Security.SecurityCritical]  // auto-generated
         [ResourceExposure(ResourceScope.None)]
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         private static extern bool ObjWait(bool exitContext, int millisecondsTimeout, Object obj);
+#endif
 
         [System.Security.SecuritySafeCritical]  // auto-generated
         public static bool Wait(Object obj, int millisecondsTimeout, bool exitContext)
@@ -228,10 +235,12 @@ namespace System.Threading {
         * Exceptions: SynchronizationLockException if this method is not called inside
         * a synchronized block of code.
         ========================================================================*/
+#if !MONO
         [System.Security.SecurityCritical]  // auto-generated
         [ResourceExposure(ResourceScope.None)]
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         private static extern void ObjPulse(Object obj);
+#endif
 
         [System.Security.SecuritySafeCritical]  // auto-generated
         public static void Pulse(Object obj)
@@ -247,10 +256,12 @@ namespace System.Threading {
         /*========================================================================
         ** Sends a notification to all waiting objects. 
         ========================================================================*/
+#if !MONO
         [System.Security.SecurityCritical]  // auto-generated
         [ResourceExposure(ResourceScope.None)]
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         private static extern void ObjPulseAll(Object obj);
+#endif
 
         [System.Security.SecuritySafeCritical]  // auto-generated
         public static void PulseAll(Object obj)
index 9c345a269cde4a0e5a36d7b234a9450695c4a004..35dffcb03c6e3d7a44a4073f3eba4212fbc1e51d 100644 (file)
@@ -873,9 +873,7 @@ ICALL(MONIT_2, "Monitor_pulse", ves_icall_System_Threading_Monitor_Monitor_pulse
 ICALL(MONIT_3, "Monitor_pulse_all", ves_icall_System_Threading_Monitor_Monitor_pulse_all)
 ICALL(MONIT_4, "Monitor_test_owner", ves_icall_System_Threading_Monitor_Monitor_test_owner)
 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 13ef2b4c486a68e9b8ca8be2303d851b22aebcf2..4d5bdd4af3587527c16884a8a9d9da324cd846db 100644 (file)
@@ -9202,7 +9202,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
        if (!enter_method) {
                MonoMethodDesc *desc;
 
-               desc = mono_method_desc_new ("Monitor:enter_with_atomic_var(object,bool&)", FALSE);
+               desc = mono_method_desc_new ("Monitor:Enter(object,bool&)", FALSE);
                enter_method = mono_method_desc_search_in_class (desc, mono_defaults.monitor_class);
                g_assert (enter_method);
                mono_method_desc_free (desc);
index 45c13be4e0f780ed511c327c5c9925ff97626e36..1b94b2345ff5019e55638df5e34feeb331353f03 100644 (file)
@@ -1076,25 +1076,6 @@ mono_monitor_threads_sync_members_offset (int *status_offset, int *nest_offset)
        *nest_offset = ENCODE_OFF_SIZE (MONO_STRUCT_OFFSET (MonoThreadsSync, nest), sizeof (ts.nest));
 }
 
-gboolean 
-ves_icall_System_Threading_Monitor_Monitor_try_enter (MonoObject *obj, guint32 ms)
-{
-       gint32 res;
-
-       do {
-               res = mono_monitor_try_enter_internal (obj, ms, TRUE);
-               if (res == -1) {
-                       MonoException *exc = mono_thread_interruption_checkpoint ();
-                       if (exc) {
-                               mono_set_pending_exception (exc);
-                               return FALSE;
-                       }
-               }
-       } while (res == -1);
-       
-       return res == 1;
-}
-
 void
 ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (MonoObject *obj, guint32 ms, char *lockTaken)
 {
index f8e89936ba93067e658532d75e2e05e042321e0b..f43e08caece432d1aba4a7bedd81d8e063138ff1 100644 (file)
@@ -115,7 +115,6 @@ void mono_monitor_threads_sync_members_offset (int *status_offset, int *nest_off
 #define MONO_THREADS_SYNC_MEMBER_OFFSET(o)     ((o)>>8)
 #define MONO_THREADS_SYNC_MEMBER_SIZE(o)       ((o)&0xff)
 
-extern gboolean ves_icall_System_Threading_Monitor_Monitor_try_enter(MonoObject *obj, guint32 ms);
 extern gboolean ves_icall_System_Threading_Monitor_Monitor_test_owner(MonoObject *obj);
 extern gboolean ves_icall_System_Threading_Monitor_Monitor_test_synchronised(MonoObject *obj);
 extern void ves_icall_System_Threading_Monitor_Monitor_pulse(MonoObject *obj);
index b677b3ad6adee8e3fa01ce0af5e0cc0e64fb7254..0a2708f3b45dac6810ba15bdc1a5f3a940671e4c 100644 (file)
@@ -6110,12 +6110,7 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
                        return NULL;
        } else if (cmethod->klass == mono_defaults.monitor_class) {
                gboolean is_enter = FALSE;
-               gboolean is_v4 = FALSE;
 
-               if (!strcmp (cmethod->name, "enter_with_atomic_var") && mono_method_signature (cmethod)->param_count == 2) {
-                       is_enter = TRUE;
-                       is_v4 = TRUE;
-               }
                if (!strcmp (cmethod->name, "Enter") && mono_method_signature (cmethod)->param_count == 1)
                        is_enter = TRUE;
 
@@ -6128,10 +6123,10 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
 
                        NEW_BBLOCK (cfg, end_bb);
 
-                       ins = mono_emit_jit_icall (cfg, is_v4 ? (gpointer)mono_monitor_enter_v4_fast : (gpointer)mono_monitor_enter_fast, args);
+                       ins = mono_emit_jit_icall (cfg, (gpointer)mono_monitor_enter_fast, args);
                        MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ICOMPARE_IMM, -1, ins->dreg, 0);
                        MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBNE_UN, end_bb);
-                       ins = mono_emit_jit_icall (cfg, is_v4 ? (gpointer)mono_monitor_enter_v4 : (gpointer)mono_monitor_enter, args);
+                       ins = mono_emit_jit_icall (cfg, (gpointer)mono_monitor_enter, args);
                        MONO_START_BB (cfg, end_bb);
                        return ins;
                }