Exemple #1
3
        public static void RunSpinLockTest0_Enter(int threadsCount, bool enableThreadIDs)
        {
            // threads array
            Task[] threads = new Task[threadsCount];
            //spinlock object
            SpinLock slock = new SpinLock(enableThreadIDs);
            // succeeded threads counter
            int succeeded = 0;
            // Semaphore used to make sure that there is no other threads in the critical section
            SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);

            for (int i = 0; i < threadsCount; i++)
            {
                threads[i] = Task.Run(delegate ()
                {
                    bool lockTaken = false;
                    try
                    {
                        slock.Enter(ref lockTaken);
                        //use semaphore to make sure that no other thread inside the critical section
                        if (!semaphore.Wait(0))
                        {
                            // This mean that there is another thread in the critical section
                            return;
                        }
                        succeeded++;
                        if (slock.IsThreadOwnerTrackingEnabled && !slock.IsHeldByCurrentThread)
                        {
                            // lock is obtained successfully
                            succeeded--;
                        }
                    }
                    catch
                    {
                        // decrement the count in case of exception
                        succeeded--;
                    }
                    finally
                    {
                        semaphore.Release();
                        if (lockTaken)
                        {
                            slock.Exit();
                        }
                    }
                });
            }
            // wait all threads
            for (int i = 0; i < threadsCount; i++)
            {
                threads[i].Wait();
            }
            // count must be equal to the threads count
            Assert.Equal(threadsCount, succeeded);
        }
Exemple #2
0
        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();
            }
        }
        /// <summary>
        /// 获取新的连接出去的客户端
        /// </summary>
        /// <returns></returns>
        internal ClientSocketManager Slice()
        {
            ClientSocketManager returnSocket = null;

            m_LockSliceSocket.Enter();
            {
                if (m_IsNeedSlice == true)
                {
                    m_IsNeedSlice = false;
                    returnSocket  = m_ClientSocketManager;
                }
            }
            m_LockSliceSocket.Exit();

            return(returnSocket);
        }
Exemple #4
0
        public void SemanticCorrectnessTest()
        {
            _sl = new SpinLock(false);

            var taken  = false;
            var 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");
        }
Exemple #5
0
            public static void Test()
            {
                lock (_lock) {
                }

                bool lockTaken = false;

                try {
                    _spinLock.Enter(ref lockTaken);
                } finally {
                    if (lockTaken)
                    {
                        _spinLock.Exit();
                    }
                }
            }
Exemple #6
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));
                }
            }
        }
Exemple #7
0
        public int Next()
        {
            bool lockTaken = false;

            try
            {
                _spinLock.Enter(ref lockTaken);
                return(_random.Next());
            }
            finally
            {
                if (lockTaken)
                {
                    _spinLock.Exit();
                }
            }
        }
        public void DoLocked(Action action)
        {
            var lockTaken = false;

            try
            {
                spinLock.Enter(ref lockTaken);
                action();
            }
            finally
            {
                if (lockTaken)
                {
                    spinLock.Exit();
                }
            }
        }
 public override void Open()
 {
     EnterLocked(ref OpenLock, "Open");
     try
     {
         if (IsOpen)
         {
             throw new Exception("Result listener is already open");
         }
         IsOpen = true;
         base.Open();
     }
     finally
     {
         OpenLock.Exit(false);
     }
 }
Exemple #10
0
            public void Atom_Enter()
            {
                double d_org = 2.2d;
                double d_new = 1.1d;
                double d_old;

                d_old = Interlocked.Exchange(ref d_org, d_new);
                SpinLock spinL = new SpinLock();
                bool     r     = true;

                spinL.Enter(ref r);
                spinL.Exit();

                SpinWait spin = new SpinWait();

                spin.SpinOnce();
            }
Exemple #11
0
 /// <summary>Acquires the lock and safely releases on dispose</summary>
 public static Scope Lock(this SpinLock sl)
 {
     return(Scope.Create(
                () =>
     {
         bool got_lock = false;
         sl.Enter(ref got_lock);
         return got_lock;
     },
                gl =>
     {
         if (gl)
         {
             sl.Exit();
         }
     }));
 }
Exemple #12
0
        static void Bar(SampleClass m)
        {
            bool lockTaken = false;

            try
            {
                _spinLock.Enter(ref lockTaken);
                _queue.Enqueue(m);
            }
            finally
            {
                if (lockTaken)
                {
                    _spinLock.Exit(false);
                }
            }
        }
Exemple #13
0
        private void InvokeLockedInternal(Action action)
        {
            bool lockTaken = false;

            try
            {
                _lock.Enter(ref lockTaken);
                action();
            }
            finally
            {
                if (lockTaken)
                {
                    _lock.Exit();
                }
            }
        }
Exemple #14
0
        static void Main(string[] args)
        {
            // create the bank account instance
            BankAccount account = new BankAccount();

            // create the spinlock
            SpinLock spinlock = new SpinLock();

            // create an array of tasks
            Task[] tasks = new Task[10];

            for (int i = 0; i < 10; i++)
            {
                // create a new task
                tasks[i] = new Task(() => {
                    // enter a loop for 1000 balance updates
                    for (int j = 0; j < 1000; j++)
                    {
                        bool lockAcquired = false;
                        try {
                            spinlock.Enter(ref lockAcquired);
                            // update the balance
                            account.Balance = account.Balance + 1;
                        } finally {
                            if (lockAcquired)
                            {
                                spinlock.Exit();
                            }
                        }
                    }
                });
                // start the new task
                tasks[i].Start();
            }

            // wait for all of the tasks to complete
            Task.WaitAll(tasks);

            // write out the counter value
            Console.WriteLine("Expected value {0}, Balance: {1}",
                              10000, account.Balance);

            // wait for input before exiting
            Console.WriteLine("Press enter to finish");
            Console.ReadLine();
        }
Exemple #15
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);
        }
            public bool Execute(Time tripStart, int modeIndex, float expansionFactor, Activity activity)
            {
                var modes = Parent.Modes;

                if (StartTime <= tripStart && tripStart < EndTime)
                {
                    bool taken = false;
                    WriteLock.Enter(ref taken);
                    GetPurposeCount(activity)[modeIndex] += expansionFactor;
                    if (taken)
                    {
                        WriteLock.Exit(true);
                    }
                    return(true);
                }
                return(false);
            }
        public static void SafeWork(this SpinLock spinLock, Action action)
        {
            bool lockTaken = false;

            try
            {
                spinLock.Enter(ref lockTaken);
                action();
            }
            finally
            {
                if (lockTaken)
                {
                    spinLock.Exit();
                }
            }
        }
Exemple #18
0
        private static void DoWork()
        {
            SpinLock spinLock  = new SpinLock();
            bool     isGetLock = false; //是否已获得了锁

            try
            {
                spinLock.Enter(ref isGetLock);
            }
            finally
            {
                if (isGetLock)
                {
                    spinLock.Exit();
                }
            }
        }
            public void Add(decimal value)
            {
                bool acquiredLock = false;

                try
                {
                    _lock.Enter(ref acquiredLock);
                    _total += value;
                }
                finally
                {
                    if (acquiredLock)
                    {
                        _lock.Exit();
                    }
                }
            }
Exemple #20
0
            /// <summary>Gets the builder's task with appropriate synchronization.</summary>
            internal Task <int> GetTaskSafe()
            {
                bool lockTaken = false;

                try
                {
                    BuilderTaskLock.Enter(ref lockTaken);
                    return(Builder.Task);
                }
                finally
                {
                    if (lockTaken)
                    {
                        BuilderTaskLock.Exit(useMemoryBarrier: false);
                    }
                }
            }
        static void Main(string[] args)
        {
            bool Locked = false;

            try
            {
                MySpinLock.Enter(ref Locked);
                //Work that requires lock would be done here
            }
            finally
            {
                if (Locked)
                {
                    MySpinLock.Exit();
                }
            }
        }
Exemple #22
0
            private void SetPrintedError()
            {
                bool gotLock = false;

                try
                {
                    printedErrLock.Enter(ref gotLock);
                    printedErr = true;
                }
                finally
                {
                    if (gotLock)
                    {
                        printedErrLock.Exit();
                    }
                }
            }
Exemple #23
0
        public static void DoLock(this SpinLock locker, Action action, int maximumRetryCount = 4096)
        {
            var retryCount = 0;
            var acquired   = false;

            while (!acquired)
            {
                locker.Enter(ref acquired);
                if (++retryCount > maximumRetryCount)
                {
                    throw new InvalidOperationException("lock timeout");
                }
            }

            action();
            locker.Exit();
        }
Exemple #24
0
            public int AddBytes(int count)
            {
                bool lockTaken = false;

                try
                {
                    _thisLock.Enter(ref lockTaken);
                    return(_bytesLeft -= count);
                }
                finally
                {
                    if (lockTaken)
                    {
                        _thisLock.Exit(false);
                    }
                }
            }
Exemple #25
0
        /// <summary>
        /// 空转锁,等待锁的线程并不放弃cpu,而是空转。
        /// </summary>
        /// <param name="action"></param>
        public void Spinlock(Action action)
        {
            bool lockTaken = false;

            try
            {
                spinLock.Enter(ref lockTaken);
                action();
            }
            finally
            {
                if (lockTaken)
                {
                    spinLock.Exit();
                }
            }
        }
        /// <summary>
        /// Locks are made for each correlation id. We don't want to lock threads that handle
        /// a client that is not disconnected
        /// </summary>
        public static object GetLock(string correlationId)
        {
            bool lockTacken = false;

            try
            {
                gate.Enter(ref lockTacken);
                return(_locks.GetOrAdd(correlationId, _ => new object()));
            }
            finally
            {
                if (lockTacken)
                {
                    gate.Exit();
                }
            }
        }
Exemple #27
0
        private void SetDaysOff()
        {
            Parallel.For(0, _populationSize, (i) =>
            {
                Individual individual = new Individual
                {
                    Dna = new IAllel[_totalNumberOfDoctors, DateTime.DaysInMonth(_date.Year, _date.Month)]
                };

                for (int j = 0; j < _totalNumberOfDoctors; j++)
                {
                    int index   = j;
                    var daysOff = _daysOff.FindAll(d => d.UserId == _doctorIds[index]).Select(d => d.Date.Day).ToList();

                    if (daysOff.Count == 0)
                    {
                        continue;
                    }
                    else
                    {
                        for (int k = 0; k < DateTime.DaysInMonth(_date.Year, _date.Month); k++)
                        {
                            if (daysOff.Contains(k + 1))
                            {
                                individual.Dna[j, k] = Allel.DayOff;
                            }
                        }
                    }
                }

                bool lockTaken = false;

                try
                {
                    _spinLock.Enter(ref lockTaken);
                    _individuals.Add(individual);
                }
                finally
                {
                    if (lockTaken)
                    {
                        _spinLock.Exit();
                    }
                }
            });
        }
Exemple #28
0
        private static void ThreadProc(object state)
        {
            bool lockTaken = false;

            Console.WriteLine($"Thread{Thread.CurrentThread.ManagedThreadId} 等候取得 SpinLock 擁有權 Enter");
            spinLock.Enter(ref lockTaken);

            Console.WriteLine($"Thread{Thread.CurrentThread.ManagedThreadId} @ 已經取得 SpinLock 擁有權");

            Console.WriteLine($"模擬 Thread{Thread.CurrentThread.ManagedThreadId} 執行專屬獨享的1秒時間的工作");
            Thread.Sleep(1000);


            Console.WriteLine($"Thread{Thread.CurrentThread.ManagedThreadId} 準備要釋放 SpinLock 擁有權");
            spinLock.Exit();
            Console.WriteLine($"Thread{Thread.CurrentThread.ManagedThreadId} # 已經要釋放 SpinLock 擁有權 Exit");
        }
Exemple #29
0
        private void UpdateWithSpinLock(Data d, int i)
        {
            bool lockTaken = false;

            try
            {
                _spinlock.Enter(ref lockTaken);
                _queue.Enqueue(d);
            }
            finally
            {
                if (lockTaken)
                {
                    _spinlock.Exit(false);
                }
            }
        }
Exemple #30
0
        /// <summary>
        /// Sends messages to targets.
        /// </summary>
        protected override void Process()
        {
            bool processed;

            do
            {
                ForceProcessing = false;

                bool lockTaken = false;
                try {
                    firstItemLock.Enter(ref lockTaken);

                    T item;
                    if (!Store.TryPeek(out item))
                    {
                        break;
                    }

                    if (!targets.HasCurrentItem)
                    {
                        targets.SetCurrentItem(item);
                    }

                    if (reservedForTargetBlock != null)
                    {
                        break;
                    }

                    processed = targets.OfferItemToTargets();
                    if (processed)
                    {
                        Outgoing.TryTake(out item);
                        DecreaseCounts(item);
                        FirstItemChanged();
                    }
                } finally {
                    if (lockTaken)
                    {
                        firstItemLock.Exit();
                    }
                }
            } while (processed);

            IsProcessing.Value = false;

            // to guard against race condition
            if (ForceProcessing && reservedForTargetBlock == null)
            {
                EnsureProcessing();
            }

            VerifyCompleteness();
        }
Exemple #31
0
        public void EnterExclusive(T id)
        {
            bool taken = false;

            _spinLock.Enter(ref taken);
            try
            {
                if (ExclusiveLockTakenBy(id))
                {
                    throw new InvalidOperationException("Recursion is not allowed");
                }

                if (SharedLockTakenBy(id))
                {
                    throw new InvalidOperationException("Cannot take shared lock after the exclusive was already taken.");
                }

                for (;;)
                {
                    if (_flags.CanTakeExclusive())
                    {
                        // from now on all others that try to enter this lock will have to wait
                        _flags.SetExclusiveFlag();
                        break;
                    }

                    // at any point in time other thread can take the upgradeable lock
                    // so it is better to perform the check here, while within the spinlock
                    if (UpgradeableLockTakenBy(id))
                    {
                        // only the upgradeable lock (with this id) is taken, it is safe
                        // to upgrade it
                        _flags.SetExclusiveFlag();
                        break;
                    }

                    // lock is taken, we have to wait
                    SpinWait();
                }
            }
            finally
            {
                _spinLock.Exit();
            }

            // we are protected here, id for exit can be set.
            _exclusiveOwnerId = id;
        }
Exemple #32
0
 /// <summary>
 /// 显示教师列表
 /// </summary>
 /// <param name="me"></param>
 public static void DisplayTeacherList(this UserCore me)
 {
     if (UserRepository.TeacherLibrary.Count > 0)
     {
         var  sLock   = new SpinLock();
         bool isWhite = true;
         WriteLine($"{"Name",-10}{"Account",-10}{"UserType",-10}{"Sex",-7}{"Age",-5}{"CreatedTime",-20}{"Since",-7}");
         Parallel.For(0, UserRepository.TeacherLibrary.Count, index =>
         {
             bool hasLock = false;
             sLock.Enter(ref hasLock);
             if (hasLock)
             {
                 try
                 {
                     ConsoleColor bg = isWhite ? ConsoleColor.White : ConsoleColor.Black;
                     ConsoleColor fg = isWhite ? ConsoleColor.Black : ConsoleColor.White;
                     PrintColorMsg($"{UserRepository.TeacherLibrary[index].Name,-10}",
                                   bg, ConsoleColor.DarkYellow);
                     PrintColorMsg($"{UserRepository.TeacherLibrary[index].Account,-10}" +
                                   $"{UserRepository.TeacherLibrary[index].UserType,-10}" +
                                   $"{UserRepository.TeacherLibrary[index].Sex,-7}" +
                                   $"{UserRepository.TeacherLibrary[index].Age,-5}" +
                                   $"{UserRepository.TeacherLibrary[index].CreatedTime,-20}" +
                                   $"{UserRepository.TeacherLibrary[index].YearsOfProfessional,-7}",
                                   bg, fg);
                     WriteLine();
                     isWhite = !isWhite;
                 }
                 finally
                 {
                     sLock.Exit();
                 }
             }
             else
             {
                 WriteLine("获取锁超时");
             }
         });
     }
     else
     {
         DisplayTheInformationOfErrorCode(ErrorCode.NoDisplayableInformation);
     }
 }
Exemple #33
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
        }
Exemple #34
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));
                }
            }
        }
Exemple #35
0
        public 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.
                Assert.Equal(threadsCount, succeeded + failed);
            }
        }
Exemple #36
0
        /// <summary>
        /// Test TryEnter invalid cases
        /// </summary>
        /// <returns>True if succeeded, false otherwise</returns>
        private static void RunSpinLockTest3_TryEnter(bool enableThreadIDs)
        {
            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);
                Assert.True(lockTaken);
                Assert.Throws<LockRecursionException>(() => { bool dummy = false; slock.Enter(ref dummy); });

                slock.Exit();
                Assert.False(slock.IsHeldByCurrentThread);
            }
            #endregion

            #region timeout > int.max
            // Test invalid argument handling, too long timeout
            Assert.Throws<ArgumentOutOfRangeException>(() => { bool lt = false; slock.TryEnter(TimeSpan.MaxValue, ref lt); });

            #endregion timeout > int.max

            #region Timeout > int.max
            // Test invalid argument handling, timeout < -1
            Assert.Throws<ArgumentOutOfRangeException>(() => { bool lt = false; slock.TryEnter(-2, ref lt); });

            #endregion Timeout > int.max
        }
Exemple #37
0
        /// <summary>
        /// Test Exit
        /// </summary>
        /// <returns>True if succeeded, false otherwise</returns>
        private static void RunSpinLockTest4_Exit(bool enableThreadIDs)
        {
            Exception exception = null;
            SpinLock slock = new SpinLock(enableThreadIDs);
            bool lockTaken = false;
            slock.Enter(ref lockTaken);
            slock.Exit();
            if (enableThreadIDs)
            {
                if (slock.IsHeldByCurrentThread)
                {
                    Assert.True(false, string.Format("SpinLock.Exit() failed, IsHeld is true after calling Exit"));
                }
            }
            else
            {
                if (slock.IsHeld)
                {
                    Assert.True(false, string.Format("SpinLock.Exit() failed, IsHeld is true after calling Exit"));
                }
            }

            for (int i = 0; i < 2; i++)
            {
                bool useBarrier = i == 0;
                // Calling Exit without owning the lock
                try
                {
                    slock.Exit(useBarrier);
                }
                catch (Exception ex)
                {
                    // SynchronizationLockException must be thrown
                    exception = ex;
                }
            }
            if (enableThreadIDs)
            {
                if (exception == null || exception.GetType() != typeof(SynchronizationLockException))
                {
                    Assert.True(false, string.Format(@"SpinLock.Exit() failed, calling Exit without owning the lock"));
                }
            }
        }
Exemple #38
0
 /// <summary>
 /// Test Exit
 /// </summary>
 /// <returns>True if succeeded, false otherwise</returns>
 private static void RunSpinLockTest4_Exit(bool enableThreadIDs)
 {
     SpinLock slock = new SpinLock(enableThreadIDs);
     bool lockTaken = false;
     slock.Enter(ref lockTaken);
     slock.Exit();
     if (enableThreadIDs)
     {
         Assert.False(slock.IsHeldByCurrentThread);
         Assert.Throws<SynchronizationLockException>(() => slock.Exit(true));
         Assert.Throws<SynchronizationLockException>(() => slock.Exit(false));
     }
     else
     {
         Assert.False(slock.IsHeld);
     }
 }
Exemple #39
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));
                }
            }
        }
Exemple #40
0
        public 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, CancellationToken.None, TaskCreationOptions.LongRunning);
                    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.
                Assert.Equal(threadsCount, succeeded + failed);
            }
        }