TryEnter() public method

public TryEnter ( TimeSpan timeout, bool &lockTaken ) : void
timeout TimeSpan
lockTaken bool
return void
		public void SemanticCorrectnessTest ()
		{
			sl = new SpinLock (false);

			bool taken = false;
			bool taken2 = false;

			sl.Enter (ref taken);
			Assert.IsTrue (taken, "#1");
			sl.TryEnter (ref taken2);
			Assert.IsFalse (taken2, "#2");
			sl.Exit ();

			sl.TryEnter (ref taken2);
			Assert.IsTrue (taken2, "#3");
		}
Esempio n. 2
0
            public IThreadPoolWorkItem TrySteal(ref bool missedSteal)
            {
                while (true)
                {
                    if (CanSteal)
                    {
                        bool taken = false;
                        try
                        {
                            m_foreignLock.TryEnter(ref taken);
                            if (taken)
                            {
                                // Increment head, and ensure read of tail doesn't move before it (fence).
                                int head = m_headIndex;
                                Interlocked.Exchange(ref m_headIndex, head + 1);

                                if (head < m_tailIndex)
                                {
                                    int idx = head & m_mask;
                                    IThreadPoolWorkItem obj = Volatile.Read(ref m_array[idx]);

                                    // Check for nulls in the array.
                                    if (obj == null)
                                    {
                                        continue;
                                    }

                                    m_array[idx] = null;
                                    return(obj);
                                }
                                else
                                {
                                    // Failed, restore head.
                                    m_headIndex = head;
                                }
                            }
                        }
                        finally
                        {
                            if (taken)
                            {
                                m_foreignLock.Exit(useMemoryBarrier: false);
                            }
                        }

                        missedSteal = true;
                    }

                    return(null);
                }
            }
Esempio n. 3
0
        /// <summary>
        /// Test TryEnter invalid cases
        /// </summary>
        /// <returns>True if succeeded, false otherwise</returns>
        private static void RunSpinLockTest3_TryEnter(bool enableThreadIDs)
        {
            Exception exception = null;
            SpinLock slock = new SpinLock(enableThreadIDs);
            bool lockTaken = false;

            #region Recursive lock
            if (enableThreadIDs) // only valid if thread IDs are on
            {
                // Test recursive locks
                slock.Enter(ref lockTaken);
                try
                {
                    if (lockTaken)
                    {
                        bool dummy = false;
                        // reacquire the lock
                        slock.Enter(ref dummy);
                    }
                }
                catch (Exception ex)
                {
                    // LockRecursionException must be thrown
                    exception = ex;
                }
                if (lockTaken)
                {
                    slock.Exit();
                    if (exception == null || exception.GetType() != typeof(LockRecursionException))
                    {
                        Assert.True(false, string.Format("SpinLock.TryEnter() failed, recursive locks without exception"));
                    }
                    if (slock.IsHeldByCurrentThread)
                    {
                        Assert.True(false, string.Format("SpinLock.TryEnter() failed, IsHeld is true after calling Exit"));
                    }
                }
                else
                {
                    Assert.True(false, string.Format("LockRecursionException was not thrown?"));
                }
            }
            #endregion

            #region timeout > int.max
            // Test invalid argument handling, too long timeout
            exception = null;
            try
            {
                lockTaken = false;
                slock.TryEnter(TimeSpan.MaxValue, ref lockTaken);
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            if (exception == null || exception.GetType() != typeof(ArgumentOutOfRangeException))
            {
                Assert.True(false, string.Format(@"SpinLock.TryEnter() failed, timeout.Totalmilliseconds > int.maxValue
                 without throwing ArgumentOutOfRangeException " + exception));
            }
            #endregion

            #region Timeout > int.max
            // Test invalid argument handling, timeout < -1
            exception = null;
            try
            {
                lockTaken = false;
                slock.TryEnter(-2, ref lockTaken);
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            if (exception == null || exception.GetType() != typeof(ArgumentOutOfRangeException))
            {
                Assert.True(false, string.Format(@"SpinLock.TryEnter() failed, timeout < -1
                 without throwing ArgumentOutOfRangeException"));
            }
            #endregion
        }
Esempio n. 4
0
        /// <summary>
        /// Test SpinLock.TryEnter(Timespan) by generating random timespan milliseconds
        /// </summary>
        /// <param name="threadsCount">Number of threads that call enter/exit</param>
        /// <returns>True if succeeded, false otherwise</returns>
        private static void RunSpinLockTest2_TryEnter(int threadsCount, bool enableThreadIDs)
        {
            for (int j = 0; j < 2; j++)
            {
                bool useMemoryBarrier = j == 0;
                Task[] threads = new Task[threadsCount];
                SpinLock slock = new SpinLock(enableThreadIDs);
                int succeeded = 0;
                int failed = 0;

                // Run threads
                for (int i = 0; i < threadsCount; i++)
                {
                    threads[i] = new Task(delegate (object x)
                    {
                        // Generate random timespan
                        bool lockTaken = false;
                        TimeSpan time = TimeSpan.FromMilliseconds(20);
                        slock.TryEnter(time, ref lockTaken);
                        if (lockTaken)
                        {
                            // add some delay in the critical section
                            Task.WaitAll(Task.Delay(15));
                            Interlocked.Increment(ref succeeded);
                            slock.Exit(useMemoryBarrier);
                        }
                        else
                        {
                            // Failed to get the lock within the timeout
                            Interlocked.Increment(ref failed);
                        }
                    }, i);
                    threads[i].Start(TaskScheduler.Default);
                }
                // Wait all threads
                for (int i = 0; i < threadsCount; i++)
                {
                    threads[i].Wait();
                }
                // succeeded + failed must be equal to the threads count.
                if (succeeded + failed != threadsCount)
                {
                    Assert.True(false, string.Format("SpinLock.TryEnter() failed, actual count: " + (succeeded + failed) +
                        " expected :" + threadsCount));
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Test SpinLock.TryEnter() by launching n threads, each one calls TryEnter, the succeeded threads increment
        /// a counter variable and failed threads increment failed variable, count + failed must be equal to n
        /// </summary>
        /// <param name="threadsCount">Number of threads that call enter/exit</param>
        /// <returns>True if succeeded, false otherwise</returns>
        private static void RunSpinLockTest1_TryEnter(int threadsCount, bool enableThreadIDs)
        {
            for (int j = 0; j < 2; j++)
            {
                bool useMemoryBarrier = j == 0;
                Task[] threads = new Task[threadsCount];
                SpinLock slock = new SpinLock(enableThreadIDs);
                int succeeded = 0;
                int failed = 0;


                // Run threads
                for (int i = 0; i < threadsCount; i++)
                {
                    threads[i] = Task.Run(delegate ()
                    {
                        bool lockTaken = false;
                        slock.TryEnter(ref lockTaken);
                        if (lockTaken)
                        {
                            // Increment succeeded counter 
                            Interlocked.Increment(ref succeeded);
                            slock.Exit(useMemoryBarrier);
                        }
                        else
                        {
                            // Increment failed counter
                            Interlocked.Increment(ref failed);
                        }
                    });
                }
                // Wait all threads
                for (int i = 0; i < threadsCount; i++)
                {
                    threads[i].Wait();
                }
                // succeeded + failed must be equal to the threads count.
                if (succeeded + failed != threadsCount)
                {
                    Assert.True(false, string.Format("SpinLock.TryEnter() failed, actual count: " + (succeeded + failed) +
                        " expected :" + threadsCount));
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Test TryEnter invalid cases
        /// </summary>
        /// <returns>True if succeeded, false otherwise</returns>
        private static bool RunSpinLockTest3_TryEnter(bool enableThreadIDs)
        {
            TestHarness.TestLog("SpinLock.TryEnter(invalid cases)");
            Exception exception = null;
            SpinLock slock = new SpinLock(enableThreadIDs);
            bool lockTaken = false;
            #region Recursive lock
            if (enableThreadIDs) // only valid if thread IDs are on
            {

                // Test recursive locks
                slock.Enter(ref lockTaken);
                try
                {
                    if (lockTaken)
                    {

                        bool dummy = false;
                        // reacquire the lock
                        slock.Enter(ref dummy);
                    }
                }
                catch (Exception ex)
                {
                    // LockRecursionException must be thrown
                    exception = ex;
                }
                if (lockTaken)
                {
                    slock.Exit();
                    //TODO: uncomment after finishing type forwarding in clr integration
                    if (exception == null /*|| exception.GetType() != typeof(LockRecursionException)*/)
                    {
                        TestHarness.TestLog("SpinLock.TryEnter() failed, recursive locks without exception");
                        return false;
                    }
                    if (slock.IsHeldByCurrentThread)
                    {
                        TestHarness.TestLog("SpinLock.TryEnter() failed, IsHeld is true after calling Exit");
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            #endregion
            #region timeout > int.max
            // Test invalid argument handling, too long timeout
            exception = null;
            try
            {
                lockTaken = false;
                slock.TryEnter(TimeSpan.MaxValue, ref lockTaken);

            }
            catch (Exception ex)
            {
                exception = ex;
            }
            if (exception == null || exception.GetType() != typeof(ArgumentOutOfRangeException))
            {
                TestHarness.TestLog(@"SpinLock.TryEnter() failed, timeout.Totalmilliseconds > int.maxValue
                 without throwing ArgumentOutOfRangeException " + exception);
                return false;
            }
            #endregion

            #region Timeout > int.max
            // Test invalid argument handling, timeout < -1
            exception = null;
            try
            {
                lockTaken = false;
                slock.TryEnter(-2, ref lockTaken);
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            if (exception == null || exception.GetType() != typeof(ArgumentOutOfRangeException))
            {
                TestHarness.TestLog(@"SpinLock.TryEnter() failed, timeout < -1
                 without throwing ArgumentOutOfRangeException");
                return false;
            }
            #endregion

            TestHarness.TestLog("SpinLock.TryEnter() passed.");
            return true;
        }
Esempio n. 7
0
        /// <summary>
        /// Test SpinLock.TryEnter(Timespan) by generating random timespan milliseconds
        /// </summary>
        /// <param name="threadsCount">Number of threads that call enter/exit</param>
        /// <returns>True if succeeded, false otherwise</returns>
        private static bool RunSpinLockTest2_TryEnter(int threadsCount, bool enableThreadIDs)
        {
            TestHarness.TestLog("SpinLock.TryEnter(" + threadsCount + " threads)");

            Thread[] threads = new Thread[threadsCount];
            SpinLock slock = new SpinLock(enableThreadIDs);
            int succeeded = 0;
            int failed = 0;

            // Run threads
            for (int i = 0; i < threadsCount; i++)
            {
                threads[i] = new Thread(delegate(object x)
                {
                    // Generate random timespan
                    Random rand = new Random(33);
                    bool lockTaken = false;
                    TimeSpan time = TimeSpan.FromMilliseconds(rand.Next(-1, 20));
                    slock.TryEnter(time, ref lockTaken);
                    if (lockTaken)
                    {
                        // add some delay in the critical section
                        Thread.Sleep(15);
                        Interlocked.Increment(ref succeeded);
                        slock.Exit();
                    }
                    else
                    {
                        // Failed to get the lock within the timeout
                        Interlocked.Increment(ref failed);
                    }
                });
                threads[i].Start(i);
            }
            // Wait all threads
            for (int i = 0; i < threadsCount; i++)
            {
                threads[i].Join();
            }
            // succeeded + failed must be equal to the threads count.
            if (succeeded + failed != threadsCount)
            {
                TestHarness.TestLog("SpinLock.TryEnter() failed, actual count: " + (succeeded + failed) +
                    " expected :" + threadsCount);
                return false;
            }
            TestHarness.TestLog("SpinLock.TryEnter() passed.");
            return true;
        }
Esempio n. 8
0
        /// <summary>
        /// Test SpinLock.TryEnter() by launching n threads, each one calls TryEnter, the succeeded threads increment
        /// a counter variable and failed threads increment failed variable, count + failed must be equal to n
        /// </summary>
        /// <param name="threadsCount">Number of threads that call enter/exit</param>
        /// <returns>True if succeeded, false otherwise</returns>
        private static bool RunSpinLockTest1_TryEnter(int threadsCount, bool enableThreadIDs)
        {
            TestHarness.TestLog("SpinLock.TryEnter(" + threadsCount + " threads)");

            Thread[] threads = new Thread[threadsCount];
            SpinLock slock = new SpinLock(enableThreadIDs);
            int succeeded = 0;
            int failed = 0;


            // Run threads
            for (int i = 0; i < threadsCount; i++)
            {
                threads[i] = new Thread(delegate()
                {
                    bool lockTaken = false;
                    slock.TryEnter(ref lockTaken);
                    if (lockTaken)
                    {
                        // Increment succeeded counter 
                        Interlocked.Increment(ref succeeded);
                        slock.Exit();
                    }
                    else
                    {
                        // Increment failed counter
                        Interlocked.Increment(ref failed);
                    }
                });
                threads[i].Start();
            }
            // Wait all threads
            for (int i = 0; i < threadsCount; i++)
            {
                threads[i].Join();
            }
            // succeeded + failed must be equal to the threads count.
            if (succeeded + failed != threadsCount)
            {
                TestHarness.TestLog("SpinLock.TryEnter() failed, actual count: " + (succeeded + failed) +
                    " expected :" + threadsCount);
                return false;
            }
            TestHarness.TestLog("SpinLock.TryEnter() passed.");
            return true;
        }
Esempio n. 9
-1
        public static void EnterExit()
        {
            var sl = new SpinLock();
            Assert.True(sl.IsThreadOwnerTrackingEnabled);

            for (int i = 0; i < 4; i++)
            {
                Assert.False(sl.IsHeld);
                Assert.False(sl.IsHeldByCurrentThread);

                bool lockTaken = false;
                if (i % 2 == 0)
                    sl.Enter(ref lockTaken);
                else
                    sl.TryEnter(ref lockTaken);
                Assert.True(lockTaken);
                Assert.True(sl.IsHeld);
                Assert.True(sl.IsHeldByCurrentThread);
                Task.Factory.StartNew(() =>
                {
                    Assert.True(sl.IsHeld);
                    Assert.False(sl.IsHeldByCurrentThread);
                }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default).GetAwaiter().GetResult();
                sl.Exit();
            }
        }