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(); } }
protected void GetOperationLock() { bool getLock = false; _operationLock.TryEnter(Constants.OperationTimeout, ref getLock); if (!getLock) { GlobalInfo.LogService.Print(LogLevel.Error, CommonConst.PlatformLogSession, "Operation Timeout"); throw new TestflowRuntimeException(ModuleErrorCode.OperationTimeout, GlobalInfo.I18N.GetStr("OperatoinTimeout")); } }
public bool TryEnterExit() { SpinLock spinLock = _spinLock; bool lockTaken = false; spinLock.TryEnter(0, ref lockTaken); spinLock.Exit(); return(lockTaken); }
public DisposableSpinLock(SpinLock thelock, bool tryLock) { this.mylock = thelock; if (tryLock) { mylock.TryEnter(ref isLocked); } else { mylock.Enter(ref isLocked); } }
public T 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; T obj = Volatile.Read(ref m_array[idx].Value); // Check for nulls in the array. if (obj == null) { continue; } m_array[idx].Value = null; return(obj); } else { // Failed, restore head. m_headIndex = head; } } } finally { if (taken) { m_foreignLock.Exit(useMemoryBarrier: false); } } missedSteal = true; } return(null); } }
/// <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); }
public void DoSth4() { var lockAcquired = false; mySpinLock.TryEnter(ref lockAcquired); try { } finally { if (lockAcquired) { Monitor.Exit(myLockObj); } } }
public void DoSth4() { var lockAcquired = false; try { mySpinLock.TryEnter(ref lockAcquired); } finally { if (lockAcquired) { mySpinLock.Exit(); } } }
/// <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)); } } }
public static void SpinLockTryEnterAlreadyAcquired() { while (true) { bool taken = false; var sl = new SpinLock(false); sl.Enter(ref taken); var sw = Stopwatch.StartNew(); for (int i = 0; i < 100_000_000; i++) { taken = false; sl.TryEnter(0, ref taken); } Console.WriteLine(sw.Elapsed); } }
/// <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 void TryEnterExit() { SpinLock spinLock = new SpinLock(); foreach (var iteration in Benchmark.Iterations) { using (iteration.StartMeasurement()) { for (int i = 0; i < Benchmark.InnerIterationCount; i++) { bool lockTaken = false; spinLock.TryEnter(0, ref lockTaken); spinLock.Exit(); } } } }
/// <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)); } } }
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); } }
/// <summary> /// 旋转锁SpinLock /// 特殊的业务逻辑让thread在用户模式下进行自选,欺骗cpu当前thread正在运行中。。。。 /// </summary> public void Fun3() { for (int i = 0; i < 100; i++) { try { bool f = false; spinLock.TryEnter(ref f); Console.WriteLine(num++); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { spinLock.Exit(); } } }
private void Elapsed(object sender, ElapsedEventArgs e) { _timer.Stop(); _timer.Interval = _interval; bool taken = false; _lock.TryEnter(ref taken); if (taken) { try { Process(); } finally { _lock.Exit(); } } }
private ScriptRunner GetScriptRunnerUnlikely(Key script) { var value = new Lazy <ScriptRunner>(() => { var runner = new ScriptRunner(_database, _configuration, EnableClr); script.GenerateScript(runner); runner.ScriptType = script.GetType().Name; return(runner); }); var lazy = _cache.GetOrAdd(script, value); if (value != lazy) { return(lazy.Value); } // we were the one who added it, need to check that we are there var count = Interlocked.Increment(ref _numberOfCachedScripts); if (count > _configuration.Patching.MaxNumberOfCachedScripts) { bool taken = false; try { _cleaning.TryEnter(ref taken); if (taken) { var numRemaining = CleanTheCache(); Interlocked.Add(ref _numberOfCachedScripts, -(count - numRemaining)); } } finally { if (taken) { _cleaning.Exit(); } } } return(lazy.Value); }
/// <summary> /// Get queue operation lock. Available when 'AutoLock' is false. TimeoutException will be raised when lock not acquired in specified timeout. /// </summary> /// <param name="timeout">Lock operation timeout in milliseconds. 0: no wait; -1: always wait until lock acquired.</param> public void Enter(int timeout = -1) { if (_autoLock == AutoLockValue) { return; } bool getLock = false; _queueLock.TryEnter(timeout, ref getLock); if (!getLock) { throw new TimeoutException(i18n.GetStr("RunTime.Timeout")); } Interlocked.Exchange(ref _mutexThreadId, Thread.CurrentThread.ManagedThreadId); }
/// <summary> /// 为SpinLock提供 能够await的 TryEnter /// </summary> /// <param name="spinLock"></param> /// <param name="timeoutInMillionseconds"></param> /// <returns></returns> public static async Task <bool> TryEnter(this SpinLock spinLock, int timeoutInMillionseconds) { bool hasLock = false; DateTime timeLocked = DateTime.Now; do { spinLock.TryEnter(ref hasLock); if (hasLock) { return(true); } if (timeoutInMillionseconds > 0) { await Task.Yield(); } } while ((DateTime.Now - timeLocked).Milliseconds < timeoutInMillionseconds); return(false); }
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); } }
private static T CreateRandom <T>(Func <byte[], T> converter) { bool lockTaken = false; try { _lock.TryEnter(ref lockTaken); if (!lockTaken) { throw new InvalidOperationException(); } rngCsp.GetBytes(_data); return(converter(_data)); } finally { if (lockTaken) { _lock.Exit(false); } } }
private static void PerformUsingPrimitive(Action <Action <Action> > perform) { var control = new SpinLock(false); perform((operation) => { var lockTaken = false; control.TryEnter(ref lockTaken); try { operation(); } finally { if (lockTaken) { control.Exit(); } } }); }
private void UpdateWithSpinTryEnter() { bool lockTaken = false; try { while (!lockTaken) { _numTryEnters++; _spinlock.TryEnter(ref lockTaken); if (lockTaken) { _numEnterSucceses++; } else { _numEnterFails++; } } Random rnd = new Random(1); int temp = bank.GetValue(); //odczytaj Thread.Sleep(rnd.Next(0, 50)); temp = howMuch + temp; //dodaj Thread.Sleep(rnd.Next(0, 50)); bank.Set(temp); //zapisz Console.WriteLine("{0}", temp); Console.WriteLine("Runnable id {3} Spinlock enters: {0} fails {1} successes {2}", _numTryEnters, _numEnterFails, _numEnterSucceses, Thread.CurrentThread.ManagedThreadId); } finally { if (lockTaken) { _spinlock.Exit(false); } } }
/// <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)); } } }
/// <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 }
private void TimerCallback(object state) { bool lockTaken = false; lLock.TryEnter(1000, ref lockTaken); if (!lockTaken) { _log.DebugFormat("设备 {0} 正在处理中 ...", device); return; } uint DeviceId = 0; try { var connectDevice = bioSdk.ConnectDevice(device.Ip, ref DeviceId); device.Enable = connectDevice ? 1 : 2; if (!connectDevice) { device.Enable = 2; return; } if (Clean_Log) { bioSdk.CleanLog(ref DeviceId); Clean_Log = false; return; } if (Clean_User) { bioSdk.RemoveAllUser(ref DeviceId); Clean_User = false; return; } if (Get_User_Size) { bioSdk.GetUserSize(ref DeviceId); Get_User_Size = false; return; } bioSdk.SynDateTime(ref DeviceId, DatabaseHelper.ParseDateTimeTo1970Sec(DateTime.Now.AddHours(8))); var geTasks = DatabaseHelper.GeTasks(device.Id); foreach (var geTask in geTasks) { if (geTask.RecordType == 1) { var cardIds = new List <string>(); cardIds.Add(geTask.CardID); var fingers = DatabaseHelper.GetFingers(geTask.CardSN); bool insert = bioSdk.InsertUser(ref DeviceId, geTask.CardSN, geTask.CardType, geTask.UserName, cardIds, fingers.Select(s => s.Data).ToList()); if (insert) { DatabaseHelper.UpdateTask(geTask.Id, 1, 2); } } if (geTask.RecordType == 3) { if (geTask.CardSN == null) { DatabaseHelper.DeleteTask(geTask.Id); continue; } bool remove = bioSdk.RemoveUser(ref DeviceId, geTask.CardSN); if (remove) { DatabaseHelper.DeleteTask(geTask.Id); } } } var bs2Events = bioSdk.ReadLog(ref DeviceId, lastRecordTime, 100); foreach (var bs2Event in bs2Events) { var userId = Enumerable.SequenceEqual(bs2Event.userID, emptyUserIds) ? "" : Encoding.UTF8.GetString(bioSdk.Empty(bs2Event.userID)); _log.InfoFormat("deviceID:{0} dateTime:{1} userID:{2} code:{3} ", bioSdk.parseIdToIp(bs2Event.deviceID), bs2Event.dateTime, userId, bs2Event.code); lastRecordTime = bs2Event.id; if (userId.Length > 0) { int type = parseRecordCodeType(bs2Event.code); DatabaseHelper.InsertRecord(device.Id, userId, bs2Event.dateTime, bs2Event.code, bs2Event.id, type); } //Thread.Sleep(500); } } catch (Exception e) { device.Enable = 2; _log.ErrorFormat("设备 {0} 通讯时发生异常", device.Ip); } finally { if (DeviceId > 0) { bioSdk.DisConnectDevice(ref DeviceId); } lLock.Exit(); } }
// Sends a message to the Arduino and returns its response private async Task <List <byte> > CommunicateRaw(DATACATEGORY cat, SUBCATEGORY subcat, ACTION action, object data = null, double timeoutLength = -1.0) { // Returns the raw response without validating it. // If there is no response or if some other kind of error occurs, it throws an ArduinoCommunicationException exception. bool gotLock = false; try { // Spin for up to 500 ms trying to enter into communication commLock.TryEnter(500, ref gotLock); if (!gotLock) // Don't enter the critical section if the lock wasn't acquired. { Console.WriteLine("Could not enter critical section. Lock is held by another thread. "); throw new ArduinoCommunicationException("Serial port is busy. Could not enter critical section."); } if (Port == null || !Port.IsOpen) { if (gotLock) { commLock.Exit(false); } throw new ArduinoCommunicationException("The serial port is null or not open."); } // The timeoutLength is the total time in milliseconds between just before the data is sent and right after the response is received. if (timeoutLength < 0.0) // If the user didn't specify a timeout length { // Use the recommended timeout length for the type of communication you're using timeoutLength = _GetTimeoutLength(cat, subcat, action, data); // Returns a placeholder value for now } bool noResponse = true; if (_ExpectedResponseCancellation.IsCancellationRequested) { _ExpectedResponseCancellation = new CancellationTokenSource(); Console.WriteLine("Made new cancellation token."); // Just for debugging } // try using the token.register thing? _ReceivedBytes.Clear(); // This should be ok b/c we have the commLock. But is One-Way communication data safe? _ReceivedTwoWayData.Clear(); SendData(cat, subcat, action, data); // Send the data try { // Wait until timeout or until response is received Task.Delay(TimeSpan.FromMilliseconds(timeoutLength), _ExpectedResponseCancellation.Token).Wait(); Console.WriteLine("---No longer waiting for a response!!!"); } catch (TaskCanceledException) { noResponse = false; Console.WriteLine("Canceled the delay for the response."); } catch (AggregateException ex) // Hmmm. There could be a legit bad exception that it lets through { AggregateException aggregateException = ex.Flatten(); foreach (var inner_ex in ex.InnerExceptions) { if (inner_ex is TaskCanceledException) { noResponse = false; } } if (noResponse) { throw ex; } } catch (Exception ex) { throw ex; } // These were both uncommented before: (2/24/2019) //_ExpectedResponseCancellation.Dispose(); //_ExpectedResponseCancellation = new CancellationTokenSource(); // Create new one for next time if (noResponse) { throw new ArduinoCommunicationException("No response."); } List <byte> resp_data_bytes = new List <byte>(); resp_data_bytes.AddRange(_ReceivedTwoWayData); _ReceivedTwoWayData.Clear(); Console.WriteLine("### CommunicateRaw. Received: {0}\n......Which is the same as: {1}", BytesToString(resp_data_bytes), BitConverter.ToString(resp_data_bytes.ToArray())); if (gotLock) { commLock.Exit(false); } return(resp_data_bytes); } catch (Exception e) { Console.WriteLine("In CommunicateRaw: Exception caught: " + e.Message); // Only give up the lock if you actually acquired it if (gotLock) { commLock.Exit(false); throw; } else { throw new ArduinoCommunicationException("Exception in CommunicateRaw. ", e); } } finally { // Only give up the lock if you actually acquired it //if (gotLock) commLock.Exit(); //throw new ArduinoCommunicationException("In CommunicateRaw in finally. You should never see this exception! "); //Console.WriteLine("In CommunicateRaw in finally. You should never see this! "); } }
private void VerifyIndex(FilterFileItem filterFileItem = null) { bool lockTaken = false; try { _spinLock.TryEnter(ref lockTaken); FilterFile filterFile = new FilterFile(); filterFile = (FilterFile)CurrentFile(); ObservableCollection <FilterFileItem> contentList = TabItems[SelectedIndex].ContentList; // filterFile.EnablePatternNotifications(false); ObservableCollection <FilterFileItem> contentItems = filterFile.ContentItems; List <FilterFileItem> sortedFilterItems = new List <FilterFileItem>(contentItems.OrderBy(x => x.Index)); SetStatus(string.Format("VerifyIndex: contentList count: {0} contentItems count: {1}", contentList.Count, contentItems.Count)); if (filterFileItem != null) { SetStatus(string.Format("VerifyIndex: filterFileItem index: {0} pattern: {1}", filterFileItem.Index, filterFileItem.Filterpattern)); } bool dupes = false; bool needsSorting = false; bool needsReIndexing = false; List <int> indexList = new List <int>(); for (int i = 0; i < sortedFilterItems.Count; i++) { int orderedFilterItemIndex = sortedFilterItems[i].Index; if (orderedFilterItemIndex != contentItems[i].Index) { // original index does not equal sorted index needsSorting = true; } if (!indexList.Contains(orderedFilterItemIndex)) { // add filter item to temp list for compare indexList.Add(orderedFilterItemIndex); } else { // item already exists in temp list based on filter index dupes = true; } if (i != orderedFilterItemIndex) { needsReIndexing = true; } } // does index need to be modified? if (!needsSorting && !dupes && !needsReIndexing) { // do nothing return; } else { filterFile.EnablePatternNotifications(false); // needs sorting or has dupes or needs reindexing if (filterFileItem != null && sortedFilterItems.Count(x => x.Index == filterFileItem.Index) > 1) { // new / modifed filteritem index remove and insert selected item in list at // lowest position in index of dupes sortedFilterItems.RemoveAt(sortedFilterItems.IndexOf(filterFileItem)); sortedFilterItems.Insert((int)(sortedFilterItems.IndexOf(sortedFilterItems.First(x => x.Index == filterFileItem.Index))), filterFileItem); } // sync contentList for (int i = 0; i < sortedFilterItems.Count; i++) { Debug.Print(string.Format("VerifyIndex:sync:sortedFilterItems index: {0} filterpattern: {1}", i, sortedFilterItems[i].Filterpattern)); Debug.Print(string.Format("VerifyIndex:sync:contentList index: {0} filterpattern: {1}", i, contentList[i].Filterpattern)); Debug.Print(string.Format("VerifyIndex:sync:contentItems index: {0} filterpattern: {1}", i, contentItems[i].Filterpattern)); contentList[i] = sortedFilterItems[i]; contentItems[i] = sortedFilterItems[i]; contentList[i].Index = i; contentItems[i].Index = i; } filterFile.EnablePatternNotifications(true); } } catch (LockRecursionException) { SetStatus("VerifyIndex:reentrant:skipping"); } catch (Exception ex) { SetStatus("VerifyIndex:exception:" + ex.ToString()); } finally { if (lockTaken) { _spinLock.Exit(); } } }
public AsyncEntryBlockUC TryEnter() { bool gotLock = false; _spinLock.TryEnter(ref gotLock); return gotLock ? new AsyncEntryBlockUC(EntryTypeUC.Exclusive, EntryCompletion) : AsyncEntryBlockUC.RefusedEntry; }
/// <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)); } } }
public IDisposable Enter() { _sLock.TryEnter(ref _lockTaken); return(this); }
static void Main(string[] args) { _tasks = new Task[_participants]; _barrier = new Barrier(_participants, (barrier) => { Console.WriteLine("Current phase: {0}", barrier.CurrentPhaseNumber); }); // You pass false for enableThreadOwnerTracking // because you want the best performance out of SpinLock var sl = new SpinLock(false); var sb = new StringBuilder(); for (int i = 0; i < _participants; i++) { _tasks[i] = Task.Factory.StartNew((num) => { var participantNumber = (int)num; for (int j = 0; j < 10; j++) { CreatePlanets(participantNumber); _barrier.SignalAndWait(); CreateStars(participantNumber); _barrier.SignalAndWait(); CheckCollisionsBetweenPlanets(participantNumber); _barrier.SignalAndWait(); CheckCollisionsBetweenStars(participantNumber); _barrier.SignalAndWait(); RenderCollisions(participantNumber); _barrier.SignalAndWait(); var logLine = String.Format( "Time: {0}, Phase: {1}, Participant: {2}, Phase completed OK\n", DateTime.Now.TimeOfDay, _barrier.CurrentPhaseNumber, participantNumber); bool lockTaken = false; try { sl.TryEnter(2000, ref lockTaken); if (!lockTaken) { // It was not possible to acquire the lock Console.WriteLine( "Lock timeout for participant: {0}", participantNumber); throw new TimeoutException( String.Format( "Participants are requiring more than {0} seconds " + "to acquire the lock at the Phase # {1}.", 2000, _barrier.CurrentPhaseNumber)); } // SpinLock acquired a lock // Critical section sb.Append(logLine); // End of critical section } finally { // You need to make sure that // you release the lock if (lockTaken) { // Gives up the lock if it actually acquired it // SpinLock doesn't // You want performance at the expense of fairness // Therefore, you pass false for useMemoryBarrier sl.Exit(false); } } } }, i); } var finalTask = Task.Factory.ContinueWhenAll(_tasks, (tasks) => { // Wait for all the tasks to ensure // the propagation of any exception occurred // in any of the _tasks Task.WaitAll(_tasks); Console.WriteLine( "All the phases were executed."); Console.WriteLine(sb); // Dispose the Barrier instance _barrier.Dispose(); }); // Wait for finalTask to finish finalTask.Wait(); Console.ReadLine(); }
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); } }
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); } }
public void SecondTakenParameterTest() { bool taken = true; sl.TryEnter(ref taken); }
/// <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 }