Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Threading;
- using NUnit.Framework;
- namespace ConsoleApplication1
- {
- public static class ReaderWriterLockHelper
- {
- public struct ReaderLockHolder : IDisposable
- {
- private readonly ReaderWriterLockSlim _lock;
- internal ReaderLockHolder(ReaderWriterLockSlim @lock)
- {
- _lock = @lock;
- _lock.EnterReadLock();
- }
- void IDisposable.Dispose()
- {
- _lock.ExitReadLock();
- }
- }
- public struct WriterLockHolder : IDisposable
- {
- private readonly ReaderWriterLockSlim _lock;
- internal WriterLockHolder(ReaderWriterLockSlim @lock)
- {
- _lock = @lock;
- _lock.EnterWriteLock();
- }
- void IDisposable.Dispose()
- {
- _lock.ExitWriteLock();
- }
- }
- public static ReaderLockHolder LockRead(this ReaderWriterLockSlim @lock)
- {
- return new ReaderLockHolder(@lock);
- }
- public static WriterLockHolder LockWrite(this ReaderWriterLockSlim @lock)
- {
- return new WriterLockHolder(@lock);
- }
- }
- public struct AtomicInt
- {
- public AtomicInt(int value)
- {
- _value = value;
- }
- public void Store(int desired)
- {
- Exchange(desired);
- }
- public int Load()
- {
- Interlocked.MemoryBarrier();
- return _value;
- }
- public int Exchange(int desired)
- {
- return Interlocked.Exchange(ref _value, desired);
- }
- public bool CompareExchange(int expected, int desired)
- {
- return Interlocked.CompareExchange(ref _value, desired, expected) != expected;
- }
- public int FetchAdd(int arg)
- {
- return Interlocked.Add(ref _value, arg);
- }
- public int FetchSub(int arg)
- {
- return Interlocked.Add(ref _value, -arg);
- }
- private int _value;
- }
- public struct AtomicFlag
- {
- public void Clear()
- {
- _value.Store(0);
- }
- public bool TestAndSet()
- {
- return _value.Exchange(1) == 1;
- }
- private AtomicInt _value;
- }
- class Program
- {
- static AtomicFlag lck;
- static void f(object obj)
- {
- int n = (int)obj;
- for (int cnt = 0; cnt < 10; ++cnt)
- {
- while (lck.TestAndSet()) ;
- Console.Write("Output from thread ");
- Console.Write(n);
- Console.WriteLine(": {0}", cnt);
- lck.Clear();
- }
- }
- static void Main(string[] args)
- {
- if (args == null) throw new ArgumentNullException("args");
- List<Thread> v = new List<Thread>();
- for (int n = 0; n < 10; ++n)
- {
- v.Add(new Thread(f));
- }
- for (int n = 0; n < 10; ++n)
- {
- v[n].Start(n);
- }
- ReaderWriterLockSlim lck = new ReaderWriterLockSlim();
- using (lck.LockRead())
- {
- }
- }
- }
- [TestFixture]
- public class TestAtomicInt
- {
- [Test]
- public void TestAdd()
- {
- var atomic = new AtomicInt(10);
- Assert.AreEqual(30, atomic.FetchAdd(20));
- Assert.AreEqual(30, atomic.Load());
- }
- [Test]
- public void TestSub()
- {
- var atomic = new AtomicInt(10);
- Assert.AreEqual(-10, atomic.FetchSub(20));
- Assert.AreEqual(-10, atomic.Load());
- }
- [Test]
- public void TestExchange()
- {
- var atomic = new AtomicInt(10);
- Assert.AreEqual(10, atomic.Exchange(20));
- Assert.AreEqual(20, atomic.Load());
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement