Advertisement
zhangsongcui

ReaderWriterLock

Nov 30th, 2013
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.18 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4.  
  5. using NUnit.Framework;
  6.  
  7. namespace ConsoleApplication1
  8. {
  9.     public static class ReaderWriterLockHelper
  10.     {
  11.         public struct ReaderLockHolder : IDisposable
  12.         {
  13.             private readonly ReaderWriterLockSlim _lock;
  14.  
  15.             internal ReaderLockHolder(ReaderWriterLockSlim @lock)
  16.             {
  17.                 _lock = @lock;
  18.                 _lock.EnterReadLock();
  19.             }
  20.  
  21.             void IDisposable.Dispose()
  22.             {
  23.                 _lock.ExitReadLock();
  24.             }
  25.         }
  26.  
  27.         public struct WriterLockHolder : IDisposable
  28.         {
  29.             private readonly ReaderWriterLockSlim _lock;
  30.  
  31.             internal WriterLockHolder(ReaderWriterLockSlim @lock)
  32.             {
  33.                 _lock = @lock;
  34.                 _lock.EnterWriteLock();
  35.             }
  36.  
  37.             void IDisposable.Dispose()
  38.             {
  39.                 _lock.ExitWriteLock();
  40.             }
  41.         }
  42.  
  43.         public static ReaderLockHolder LockRead(this ReaderWriterLockSlim @lock)
  44.         {
  45.             return new ReaderLockHolder(@lock);
  46.         }
  47.  
  48.         public static WriterLockHolder LockWrite(this ReaderWriterLockSlim @lock)
  49.         {
  50.             return new WriterLockHolder(@lock);
  51.         }
  52.     }
  53.  
  54.     public struct AtomicInt
  55.     {
  56.         public AtomicInt(int value)
  57.         {
  58.             _value = value;
  59.         }
  60.  
  61.         public void Store(int desired)
  62.         {
  63.             Exchange(desired);
  64.         }
  65.  
  66.         public int Load()
  67.         {
  68.             Interlocked.MemoryBarrier();
  69.             return _value;
  70.         }
  71.  
  72.         public int Exchange(int desired)
  73.         {
  74.             return Interlocked.Exchange(ref _value, desired);
  75.         }
  76.  
  77.         public bool CompareExchange(int expected, int desired)
  78.         {
  79.             return Interlocked.CompareExchange(ref _value, desired, expected) != expected;
  80.         }
  81.  
  82.         public int FetchAdd(int arg)
  83.         {
  84.             return Interlocked.Add(ref _value, arg);
  85.         }
  86.  
  87.         public int FetchSub(int arg)
  88.         {
  89.             return Interlocked.Add(ref _value, -arg);
  90.         }
  91.  
  92.         private int _value;
  93.     }
  94.  
  95.     public struct AtomicFlag
  96.     {
  97.         public void Clear()
  98.         {
  99.             _value.Store(0);
  100.         }
  101.  
  102.         public bool TestAndSet()
  103.         {
  104.             return _value.Exchange(1) == 1;
  105.         }
  106.  
  107.         private AtomicInt _value;
  108.     }
  109.  
  110.     class Program
  111.     {
  112.         static AtomicFlag lck;
  113.  
  114.         static void f(object obj)
  115.         {
  116.             int n = (int)obj;
  117.             for (int cnt = 0; cnt < 10; ++cnt)
  118.             {
  119.                 while (lck.TestAndSet()) ;
  120.                 Console.Write("Output from thread ");
  121.                 Console.Write(n);
  122.                 Console.WriteLine(": {0}", cnt);
  123.                 lck.Clear();
  124.             }
  125.         }
  126.  
  127.         static void Main(string[] args)
  128.         {
  129.             if (args == null) throw new ArgumentNullException("args");
  130.             List<Thread> v = new List<Thread>();
  131.             for (int n = 0; n < 10; ++n)
  132.             {
  133.                 v.Add(new Thread(f));
  134.             }
  135.             for (int n = 0; n < 10; ++n)
  136.             {
  137.                 v[n].Start(n);
  138.             }
  139.  
  140.             ReaderWriterLockSlim lck = new ReaderWriterLockSlim();
  141.  
  142.             using (lck.LockRead())
  143.             {
  144.                
  145.             }
  146.         }
  147.     }
  148.  
  149.     [TestFixture]
  150.     public class TestAtomicInt
  151.     {
  152.         [Test]
  153.         public void TestAdd()
  154.         {
  155.             var atomic = new AtomicInt(10);
  156.             Assert.AreEqual(30, atomic.FetchAdd(20));
  157.             Assert.AreEqual(30, atomic.Load());
  158.         }
  159.  
  160.         [Test]
  161.         public void TestSub()
  162.         {
  163.             var atomic = new AtomicInt(10);
  164.             Assert.AreEqual(-10, atomic.FetchSub(20));
  165.             Assert.AreEqual(-10, atomic.Load());
  166.         }
  167.  
  168.         [Test]
  169.         public void TestExchange()
  170.         {
  171.             var atomic = new AtomicInt(10);
  172.             Assert.AreEqual(10, atomic.Exchange(20));
  173.             Assert.AreEqual(20, atomic.Load());
  174.         }
  175.     }
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement