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); }
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(); } }
public Pool(int capacity, Func <T> builder) { var buffer = new T[capacity]; for (var i = 0; i < buffer.Length; i++) { buffer[i] = builder(); } _buffer = buffer; _index = 0; _lock = new SpinLock(Debugger.IsAttached); }
/// <summary> /// MutuallyExclusivePrimitive constructor /// </summary> /// <param name="mainGateOpened">True - MainGate opened, BackgroundGate closed, False - MainGate closed, BackgroundGate opened</param> public MutuallyExclusivePrimitive(bool mainGateOpened) { _mainGate = new MutuallyExclusiveGate(this, false, mainGateOpened); _backgroundGate = new MutuallyExclusiveGate(this, true, !mainGateOpened); #if DEBUG _lock = new SpinLock(true); #else _lock = new SpinLock(false); #endif _combinedState = mainGateOpened ? MainGateBit : BackgroundGateBit | AllowBackgroundBit; _isDisposed = false; }
public FrontMenu() { InitializeComponent(); VersionStat.Text = "v " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); // I want to begin the database prompt as the application launches but allow the window to fully render // To do this I am spawning a thread to go perform the database checking work. cuteThread = new System.Threading.Thread(doTheThing); cuteThread.IsBackground = true; cuteThread.Start(); usrLock = new SpinLock(); }
public SearchWindow() { InitializeComponent(); FocusManager.SetFocusedElement(this, UsrInptTxtBox); Keyboard.Focus(UsrInptTxtBox); cuteThread = new System.Threading.Thread(doStuff); cuteThread.IsBackground = true; cuteThread.Start(); usrLock = new SpinLock(); }
public void RecursionExceptionTest() { Assert.Throws <LockRecursionException>(() => { _sl = new SpinLock(true); var taken = false; var taken2 = false; _sl.Enter(ref taken); Assert.IsTrue(taken, "#1"); _sl.Enter(ref taken2); }); }
public static void MSSpinLock() { var ss2 = new SpinLock(); var number = 0; Parallel.For(0, 100000, (i) => { bool lockTaken = false; ss2.Enter(ref lockTaken); number++; ss2.Exit(); }); }
public QueuedObject(T obj) { if (obj == null) { throw new ArgumentNullException(nameof(obj)); } Object = obj; _buyers = new ConcurrentQueue <IReadOnlyBuyer>(); _readyForService = new List <IReadOnlyBuyer>(); Object.Availabled += OnObjectAvailabled; _spinLock = new SpinLock(); }
/// <summary> /// Create a memory cache with a specific capacity, timeout and clock implementation. /// </summary> /// <param name="capacity">Capacity for this instance.</param> /// <param name="timeout">Entry timeout.</param> /// <param name="clock">System clock implementation.</param> public MemoryCache(long capacity, int timeout, ISystemClock clock) { this.m_disposed = false; this.m_timeout = timeout; this.m_clock = clock; this.m_data = new Dictionary <TKey, CacheEntry <TValue> >(); this.m_dataLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); this.m_lastScan = DateTimeOffset.MinValue; this.m_deletionQueue = new List <TKey>(); this.m_deletionLock = new SpinLock(); this.m_capacity = capacity; this.m_size = 0L; }
public int GetBalance() { var tasks = new List <Task>(); SpinLock s1 = new SpinLock(); for (int i = 0; i < 10; i++) { tasks.Add(Task.Factory.StartNew(() => { for (int j = 0; j < 1000; j++) { var lockTaken = false; try { s1.Enter(ref lockTaken); this.Deposit(100); } finally { if (lockTaken) { s1.Exit(); } } } })); tasks.Add(Task.Factory.StartNew(() => { for (int j = 0; j < 1000; j++) { var lockTaken = false; try { s1.Enter(ref lockTaken); this.Withdraw(100); } finally { if (lockTaken) { s1.Exit(); } } } })); } Task.WaitAll(tasks.ToArray()); return(this.Balance); }
public static void TestMethod2() { /* * 在实际的编程中需要注意的是:不要将SpinLock声明为只读字段, * 如果声明为只读字段,会导致每次调用都会返回一个SpinLock新副本, * 在多线程下,每个方法都会成功获得锁,而受到保护的临界区不会按照预期进行串行化。 * */ SpinLock sl = new SpinLock(); CookTasks = new Task[Particpants]; Thread.Sleep(4000); Stopwatch swTask1 = new Stopwatch(); swTask1.Start(); for (var taskIndex = 0; taskIndex < Particpants; taskIndex++) { CookTasks[taskIndex] = Task.Factory.StartNew((num) => { Parallel.For(1, 200000, (i) => { var str = "append message " + i; bool lockTaken = false; try { sl.Enter(ref lockTaken); AppendStrMonitorLock.Append(str); } finally { if (lockTaken) { sl.Exit(); } } }); }, taskIndex); } /*ContinueWhenAll 提供一组任务完成后 延续方法*/ var finalTask = Task.Factory.ContinueWhenAll(CookTasks, (tasks) => { /*等待任务完成*/ Task.WaitAll(CookTasks); swTask1.Stop(); Console.WriteLine($"采用SpinLock操作,字符串长度:{AppendStrMonitorLock.Length},耗时:{swTask1.ElapsedMilliseconds}"); /*释放资源*/ }); Console.ReadLine(); }
public void RunBenchmark() { int x = 0; const int iteration = 10000000; Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < iteration; ++i) { ++x; } Console.WriteLine("{0:N0}", sw.ElapsedMilliseconds); sw.Restart(); for (int i = 0; i < iteration; ++i) { DoNothing(); x++; DoNothing(); } Console.WriteLine(sw.ElapsedMilliseconds); SpinLock sl = new SpinLock(false); sw.Restart(); for (int i = 0; i < iteration; ++i) { bool taken = false; sl.Enter(ref taken); x++; sl.Exit(); } Console.WriteLine(sw.ElapsedMilliseconds); using (SimpleWaitLock simpleWaitLock = new SimpleWaitLock()) { sw.Restart(); for (int i = 0; i < iteration; ++i) { simpleWaitLock.Enter(); x++; simpleWaitLock.Leave(); } Console.WriteLine(sw.ElapsedMilliseconds); } }
public static void DoLocked(this SpinLock lck, Action action) { Helper.Enter(ref lck); //if fails, throws exception, not locked, all good try { action(); lck.Exit(); } catch { lck.Exit(); throw; } }
static void Main(string[] args) { var tasks = new List <Task>(); var ba = new BankAccount(); SpinLock sl = new SpinLock(); for (int i = 0; i < 10; i++) { tasks.Add(Task.Factory.StartNew(() => { for (int j = 0; j < 1000; j++) { bool lockTaken = false; try { sl.Enter(ref lockTaken); ba.Deposit(100); } finally { sl.Exit(); } } })); tasks.Add(Task.Factory.StartNew(() => { for (int j = 0; j < 1000; j++) { bool lockTaken = false; try { sl.Enter(ref lockTaken); ba.Withdraw(100); } finally { sl.Exit(); } } })); } Task.WaitAll(tasks.ToArray()); Console.WriteLine($"The current balance is {ba.Balance}"); LockRecursionTest(5); }
private bool print(Printer printer, FileInfo file, SpinLock pLock) { // if (!lock.haveLock) return false; if (!pLock.IsHeldByCurrentThread) { return(false); } // print file to printer.Queue using printer.Ticket (and presumably printer.Dialog) // In other words, THIS is where the actual printing code probably goes // Print was sent to the printer. It's out of our hands (for now). return(true); }
public MyConcurrentPool(int defaultCapacity = 0, bool preallocate = false) { m_lock = new SpinLock(); m_instances = new Stack <T>(defaultCapacity); if (preallocate) { m_instancesCreated = defaultCapacity; for (int i = 0; i < defaultCapacity; i++) { m_instances.Push(new T()); } } }
public DepotProcessor(SteamClient client, CallbackManager manager) { UpdateScript = Path.Combine(Application.Path, "files", "update.sh"); UpdateScriptLock = new SpinLock(); DepotLocks = new Dictionary <uint, byte>(); CDNClient = new CDNClient(client); FileDownloader.SetCDNClient(CDNClient); manager.Subscribe <SteamClient.ServerListCallback>(OnServerList); CDNServers = new List <string>(); }
public AsyncEntryBlockUC Enter() { using (SpinLock.Enter()) { if (LockStatus == Status.Opened) { LockStatus = Status.Locked; return(new AsyncEntryBlockUC(ExclusiveEntry)); } AccessItem access; Queue.Enqueue(access = AccessItem.NewTCS()); return(new AsyncEntryBlockUC(null, access.TCS)); } }
internal Bucket(int bufferLength, int numberOfBuffers, int poolId) { #if NET_4_6 || NET_STANDARD_2_0 _lock = new SpinLock(); #else _lock = new Object(); #endif _buffers = new T[numberOfBuffers][]; _bufferLength = bufferLength; #if NETSTACK_BUFFERS_LOG _poolId = poolId; #endif }
/// <summary> /// Add explicit support points for any small floating polygons. /// These can be used at toolpathing time to ensure support for /// such areas, which otherwise might be lost (or insufficiently /// supported) by the standard techniques to detect support regions. /// </summary> public void AddMinZTipSupportPoints(double tipDiamThresh = 2.0, int nExtraLayers = 0) { List <Vector3d> tips = new List <Vector3d>(); SpinLock tiplock = new SpinLock(); int N = Slices.Count; gParallel.ForEach(Interval1i.FromToInclusive(1, N - 1), (li) => { PlanarSlice slice = Slices[li]; PlanarSlice prev = Slices[li - 1]; foreach (GeneralPolygon2d poly in slice.InputSolids) { AxisAlignedBox2d bounds = poly.Bounds; if (bounds.MaxDim > tipDiamThresh) { continue; } Vector2d c = bounds.Center; bool contained = false; foreach (var poly2 in prev.InputSolids) { if (poly2.Contains(c)) { contained = true; break; } } if (contained) { continue; } bool entered = false; tiplock.Enter(ref entered); tips.Add(new Vector3d(c.x, c.y, li)); tiplock.Exit(); } }); foreach (var tip in tips) { int layer_i = (int)tip.z; int add_to = Math.Min(N - 1, layer_i + nExtraLayers); for (int i = layer_i; i < add_to; ++i) { Slices[i].InputSupportPoints.Add(tip.xy); } } }
static void Main(string[] args) { var tasks = new List <Task>(); var ba = new BankAccount(); SpinLock sl = new SpinLock(); for (int i = 0; i < 10; i++) { tasks.Add(Task.Factory.StartNew(() => { for (int j = 0; j < 100; j++) { var lockTaken = false; try { sl.Enter(ref lockTaken); ba.Deposit(100); } finally { if (lockTaken) { sl.Exit(); } } } })); tasks.Add(Task.Factory.StartNew(() => { for (int j = 0; j < 100; j++) { var lockTaken = false; try { sl.Enter(ref lockTaken); ba.Withdraw(100); } finally { if (lockTaken) { sl.Exit(); } } } })); } Task.WaitAll(tasks.ToArray()); Console.WriteLine(ba.Balance); Console.ReadKey(); }
/// <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); }
// Demonstrates: // SpinLock constructor(false) -- thread ownership not tracked static void SpinLockSample3() { // Create SpinLock that does not track ownership/threadIDs SpinLock sl = new SpinLock(false); // Used to synchronize with the Task below ManualResetEventSlim mres = new ManualResetEventSlim(false); // We will verify that the Task below runs on a separate thread Console.WriteLine("main thread id = {0}", Thread.CurrentThread.ManagedThreadId); // Now enter the SpinLock. Ordinarily, you would not want to spend so // much time holding a SpinLock, but we do it here for the purpose of // demonstrating that a non-ownership-tracking SpinLock can be exited // by a different thread than that which was used to enter it. bool lockTaken = false; sl.Enter(ref lockTaken); // Create a separate Task from which to Exit() the SpinLock Task worker = Task.Factory.StartNew(() => { Console.WriteLine("worker task thread id = {0} (should be different than main thread id)", Thread.CurrentThread.ManagedThreadId); // Now exit the SpinLock try { sl.Exit(); Console.WriteLine("worker task: successfully exited SpinLock, as expected"); } catch (Exception e) { Console.WriteLine("worker task: unexpected failure in exiting SpinLock: {0}", e.Message); } // Notify main thread to continue mres.Set(); }); // Do this instead of worker.Wait(), because worker.Wait() could inline the worker Task, // causing it to be run on the same thread. The purpose of this example is to show that // a different thread can exit the SpinLock created (without thread tracking) on your thread. mres.Wait(); // now Wait() on worker and clean up worker.Wait(); mres.Dispose(); }
public static void Go() { int x = 0; const int iterations = 1000000; Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { x++; } Console.WriteLine("Incrementing x: {0:N0}", sw.ElapsedMilliseconds); sw.Restart(); for (int i = 0; i < iterations; i++) { M(); x++; M(); } Console.WriteLine("Incrementing x in M: {0:N0}", sw.ElapsedMilliseconds); SimpleSpinLock ssl = new SimpleSpinLock(); sw.Restart(); for (int i = 0; i < iterations; i++) { ssl.Enter(); x++; ssl.Leave(); } Console.WriteLine("Incrementing x in SimpleSpinLock:{0:N0}", sw.ElapsedMilliseconds); SpinLock sl = new SpinLock(false); sw.Restart(); for (int i = 0; i < iterations; i++) { bool taken = false; sl.Enter(ref taken); x++; sl.Exit(false); } Console.WriteLine("Incrementing x in SpinLock: {0:N0}", sw.ElapsedMilliseconds); using (SimpleWaitLock swl = new SimpleWaitLock()) { sw.Restart(); for (int i = 0; i < iterations; i++) { swl.Enter(); x++; swl.Leave(); } Console.WriteLine("Incrementing x in SimpleWaitLock: {0:N0}", sw.ElapsedMilliseconds); } Console.ReadLine(); }
public void DebuggerProxy_FrameworkTypes_SpinLock() { var obj = new SpinLock(); var str = CSharpObjectFormatter.Instance.FormatObject(obj, s_inline); Assert.Equal("SpinLock(IsHeld = false) { IsHeld=false, IsHeldByCurrentThread=false, OwnerThreadID=0 }", str); str = CSharpObjectFormatter.Instance.FormatObject(obj, s_memberList); AssertMembers(str, "SpinLock(IsHeld = false)", "IsHeld: false", "IsHeldByCurrentThread: false", "OwnerThreadID: 0" ); }
public static void Enter(ref SpinLock lck) { bool amIn = false; for (int i = 0; i < 10; i++) { lck.Enter(ref amIn); if (amIn) { return; } Thread.Sleep(10); } throw new IntegrityViolation("Could not enter spinlock after 100 ms"); }
/// <summary> /// Initializes a new instance of the <see cref="ArrayPool{T}" /> class. /// </summary> /// <param name="bufferLength"> Length of the buffer. </param> /// <param name="numberOfBuffers"> (Optional) Number of buffers. </param> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown when one or more arguments are outside /// the required range. /// </exception> public ArrayPool(int bufferLength, int numberOfBuffers = 10) { if (bufferLength <= 0) { throw new ArgumentOutOfRangeException(nameof(bufferLength)); } if (numberOfBuffers <= 0) { throw new ArgumentOutOfRangeException(nameof(numberOfBuffers)); } _bufferLength = bufferLength; _lock = new SpinLock(Debugger.IsAttached); _buffers = new T[numberOfBuffers][]; }
public void IsHeldByCurrentThreadTest() { var lockTaken = false; _sl.Enter(ref lockTaken); Assert.IsTrue(lockTaken, "#1"); Assert.IsTrue(_sl.IsHeldByCurrentThread, "#2"); lockTaken = false; _sl = new SpinLock(true); _sl.Enter(ref lockTaken); Assert.IsTrue(lockTaken, "#3"); Assert.IsTrue(_sl.IsHeldByCurrentThread, "#4"); }
public void DebuggerProxy_FrameworkTypes_SpinLock() { var obj = new SpinLock(); var str = s_formatter.FormatObject(obj, SingleLineOptions); Assert.Equal("SpinLock(IsHeld = false) { IsHeld=false, IsHeldByCurrentThread=false, OwnerThreadID=0 }", str); str = s_formatter.FormatObject(obj, SeparateLinesOptions); AssertMembers(str, "SpinLock(IsHeld = false)", "IsHeld: false", "IsHeldByCurrentThread: false", "OwnerThreadID: 0" ); }
/// <summary> /// Initializes a new instance of the <see cref="ServerBase{T, TServerClient}" /> class. /// </summary> /// <param name="listenerCount"> (Optional) The listener count. </param> private protected ServerBase(byte listenerCount = 1) { _listenerCount = listenerCount; _dataReceivedCallbacks = new Dictionary <uint, ServerClientEventEntry <TServerClient> >(INITIAL_QUEUE_SIZE); _clients = new Dictionary <T, TServerClient>(INITIAL_CLIENT_QUEUE_SIZE); _clientsLock = new SpinLock(Debugger.IsAttached); _dataReceivedCallbacksLock = new SpinLock(Debugger.IsAttached); _packetID = 1; _clientDataReceived = new Event <ClientCommandDataReceivedHandler <TServerClient> >(); _bigDataHandler = new BigDataHandler(); }
public AsyncEntryBlockUC TryEnter(int milliseconds) { AccessItem access; using (SpinLock.Enter()) { if (LockStatus == Status.Opened) { LockStatus = Status.Locked; return(new AsyncEntryBlockUC(ExclusiveEntry)); } Queue.Enqueue(access = AccessItem.NewTimeLimitedTCS(milliseconds)); } return(new AsyncEntryBlockUC(null, access.TCS)); }
/// <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); } }
/// <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 }
/// <summary> /// Initializes a new instance of the <see cref="NetworkDevicePacketBuffer"/> class. /// </summary> /// <param name="networkDevice">The network device.</param> public NetworkDevicePacketBuffer(INetworkDevice networkDevice) { this.networkDevice = networkDevice; maxTransmitQueue = 100; // TODO: Lookup system default maxReceiveQueue = 100; // TODO: Lookup system default transmitLock = new SpinLock(); receiveLock = new SpinLock(); countTransmitPackets = 0; countReceivePackets = 0; discardedTransmitPackets = 0; discardedReceivePackets = 0; }
/// <summary>Initializes an instance of the SpinLockClass class.</summary> /// <param name="enableThreadOwnerTracking"> /// Controls whether the SpinLockClass should track /// thread-ownership fo the lock. /// </param> public SpinLockClass(bool enableThreadOwnerTracking) { _spinLock = new SpinLock(enableThreadOwnerTracking); }
internal SpinLockContext(SpinLock spinLock) { _spinLock = spinLock; _spinLock.Acquire(); _disposed = false; }
public LockedRegion(SpinLock myLock) { this.myLock = myLock; }
/// <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)); } } }
// // Constructors. // public StReadUpgradeWriteLock(StLockRecursionPolicy policy, int sc) { slock = new SpinLock(SPIN_LOCK_SPINS); rdQueue = new WaitNodeQueue(); wrQueue = new WaitNodeQueue(); upQueue = new WaitNodeQueue(); rdCounts = new ReaderCounterTable(); // writer = upgrader = UNOWNED; isReentrant = (policy == StLockRecursionPolicy.SupportsRecursion); spinCount = Platform.IsMultiProcessor ? sc : 0; }
public static void RunSpinLockTestExceptions() { SpinLock slock = new SpinLock(); bool isTaken = true; Assert.Throws<ArgumentException>(() => slock.Enter(ref isTaken)); // Failure Case: Enter didn't throw AE when isTaken is true slock = new SpinLock(false); Assert.Throws<InvalidOperationException>(() => { bool iHeld = slock.IsHeldByCurrentThread; }); // Failure Case: IsHeldByCurrentThread didn't throw IOE when the thread tracking is disabled }
public SpinLockWrapper (bool enableTracking) { Lock = new SpinLock (enableTracking); }
static TimerList() { // // Create the objects. // _lock = new SpinLock(TIMER_LIST_LOCK_SPINS); timerListHead = new RawTimer(null); limitTimer = new RawTimer(null); parker = new StParker(1); // // Initialize the limit timer as unlinked. // limitTimer.next = limitTimer; // // Initialize the timer list as empty. // timerListHead.next = timerListHead.prev = timerListHead; // // Set the start base time e set the *delay* sentinel. // baseTime = Environment.TickCount; timerListHead.delay = Int32.MaxValue; // // Create and start the timer thread. // new Thread(TimerThread).Start(); }
private SpinLock _spinLock; // NOTE: must *not* be readonly due to SpinLock being a mutable struct /// <summary>Initializes an instance of the SpinLockClass class.</summary> public SpinLockClass() { _spinLock = new SpinLock(); }
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); } }
/// <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")); } } }
/// <summary> /// Creates a FairResourceLock, specifying a spin count. /// </summary> /// <param name="spinCount"> /// The number of times to spin before going to sleep. /// </param> public FairResourceLock(int spinCount) { _value = 0; _lock = new SpinLock(); _spinCount = Environment.ProcessorCount != 1 ? spinCount : 0; _waitersListHead = (WaitBlock*)Marshal.AllocHGlobal(WaitBlock.SizeOf); _waitersListHead->Flink = _waitersListHead; _waitersListHead->Blink = _waitersListHead; _waitersListHead->Flags = 0; _firstSharedWaiter = _waitersListHead; #if !DEFER_EVENT_CREATION _wakeEvent = this.CreateWakeEvent(); #endif }
/// <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 }
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> /// 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> /// Initializes a new instance of the <see cref="NetworkDevicePacketBuffer"/> class. /// </summary> /// <param name="networkDevice">The network device.</param> /// <param name="maxTransmitQueue">The max transmit queue.</param> /// <param name="maxReceiveQueue">The max receive queue.</param> public NetworkDevicePacketBuffer(INetworkDevice networkDevice, uint maxTransmitQueue, uint maxReceiveQueue) { this.networkDevice = networkDevice; this.maxReceiveQueue = maxReceiveQueue; this.maxTransmitQueue = maxTransmitQueue; transmitLock = new SpinLock(); receiveLock = new SpinLock(); countTransmitPackets = 0; countReceivePackets = 0; discardedTransmitPackets = 0; discardedReceivePackets = 0; }