Esempio n. 1
0
        public async Task AllBareLock_ExceptionInRelease_ThrowsUnlockException()
        {
            // setup
            var locks = new List <IBareAsyncLock <string> >();
            var l     = new Mock <IBareAsyncLock <string> >(MockBehavior.Strict);

            l.As <IBareAsyncLock>().Setup(x => x.BarelyLockAsync(It.IsAny <CancellationToken>()))
            .ReturnsAsync(() =>
            {
                return("0");
            });
            l.Setup(x => x.BarelyUnlock()).Throws(new SynchronizationLockException());
            locks.Add(l.Object);
            var guard = await MultiSync.AllAsync(locks);

            // act and assert
            var exception = Should.Throw <UnlockException>(() => guard.Dispose());

            exception.PriorException.ShouldBeNull();
            exception.InnerExceptions
            .ToDictionary(kv => kv.Key, kv => kv.Value.GetType())
            .ShouldBe(new Dictionary <int, Type>
            {
                [0] = typeof(SynchronizationLockException)
            });
        }
Esempio n. 2
0
        public void AllBareLockTimeout_Timeout_NotAcquire(TimingMethod timingMethod, int sleepMs)
        {
            // setup
            var    locks      = new List <IBareLock>();
            object valueToken = null;

            {
                var l = new Mock <IBareLock>(MockBehavior.Strict);
                l.Setup(x => x.BarelyTryLock(1, out valueToken)).Returns(new TryLockTimeoutDelegate((int _, out object v) =>
                {
                    Thread.Sleep(sleepMs);
                    v = new object();
                    return(true);
                }));
                l.Setup(x => x.BarelyUnlock());
                locks.Add(l.Object);
            }
            {
                var l = new Mock <IBareLock>(MockBehavior.Strict);
                l.Setup(x => x.BarelyTryLock(out valueToken)).Returns(false);
                l.Setup(x => x.BarelyTryLock(0, out valueToken)).Returns(false);
                l.Setup(x => x.BarelyUnlock());
                locks.Add(l.Object);
            }
            locks.Add(new Mock <IBareLock>(MockBehavior.Strict).Object); // prevent infinite loop

            // act
            var guard = MultiSync.All(locks, 1, timingMethod);

            // assert
            guard.ShouldBeNull();
        }
Esempio n. 3
0
 public void UnorderedAcquisition()
 {
     using (var guard = MultiSync.All(new[] { lock1, lock2 }))
     {
         var list1 = guard.Value[0];
         var list2 = guard.Value[1];
         list1.AddRange(list2);
     }
 }
Esempio n. 4
0
        public async Task AllBareLock_Acquire(params int[][] initialLockStates)
        {
            // setup
            var remainingStates = initialLockStates.ToList();
            var locks           = new List <IBareAsyncLock>();
            var currentStates   = remainingStates.First().ToList();

            remainingStates.RemoveAt(0);
            int count = currentStates.Count;

            for (int i = 0; i < count; ++i)
            {
                int iCopy = i;
                var l     = new Mock <IBareAsyncLock>(MockBehavior.Strict);
                l.Setup(x => x.BarelyLockAsync(It.IsAny <CancellationToken>())).ReturnsAsync(() =>
                {
                    currentStates[iCopy].ShouldBe(0);
                    ++currentStates[iCopy];
                    return(iCopy.ToString());
                });
                object valueToken;
                l.Setup(x => x.BarelyTryLock(out valueToken)).Returns(new TryLockDelegate((out object v) =>
                {
                    if (currentStates[iCopy] > 0)
                    {
                        // unlock "externally"
                        --currentStates[iCopy];
                        var next = remainingStates.FirstOrDefault();
                        if (next != null)
                        {
                            remainingStates.RemoveAt(0);
                            for (int s = 0; s < count; ++s)
                            {
                                currentStates[s] += next[s];
                            }
                        }
                        v = null;
                        return(false);
                    }
                    ++currentStates[iCopy];
                    v = iCopy.ToString();
                    return(true);
                }));
                l.Setup(x => x.BarelyUnlock()).Callback(() => -- currentStates[iCopy]);
                locks.Add(l.Object);
            }

            // act
            var guard = await MultiSync.AllAsync(locks);

            // assert
            currentStates.ShouldBe(Enumerable.Repeat(1, count));
            guard.Value.ShouldBe(Enumerable.Range(0, count).Select(x => x.ToString()));
        }
Esempio n. 5
0
        public void AllBareLock_ExceptionInAcquireAndRelease_ThrowsUnlockException()
        {
            // setup
            var locks = new List <IBareLock <string> >();
            {
                var l = new Mock <IBareLock <string> >(MockBehavior.Strict);
                l.As <IBareLock>().Setup(x => x.BarelyLock()).Returns(() =>
                {
                    return("0");
                });
                l.Setup(x => x.BarelyUnlock()).Throws(new SynchronizationLockException());
                locks.Add(l.Object);
            }
            {
                var l = new Mock <IBareLock <string> >(MockBehavior.Strict);
                l.As <IBareLock>().Setup(x => x.BarelyLock()).Returns(() =>
                {
                    return("1");
                });
                object valueToken;
                l.As <IBareLock>().Setup(x => x.BarelyTryLock(out valueToken)).Returns(new TryLockDelegate((out object v) =>
                {
                    v = "1";
                    return(true);
                }));
                l.Setup(x => x.BarelyUnlock());
                locks.Add(l.Object);
            }
            var guard = MultiSync.All(locks);

            // act and assert
            var exception = Should.Throw <UnlockException>(() => guard.Dispose());

            exception.PriorException.ShouldBeNull();
            exception.InnerExceptions
            .ToDictionary(kv => kv.Key, kv => kv.Value.GetType())
            .ShouldBe(new Dictionary <int, Type>
            {
                [0] = typeof(SynchronizationLockException)
            });
        }
Esempio n. 6
0
        public async Task AllBareLock_Release()
        {
            // setup
            var locks         = new List <IBareAsyncLock>();
            var currentStates = new List <int> {
                0, 0, 0
            };
            int count = currentStates.Count;

            for (int i = 0; i < count; ++i)
            {
                int iCopy = i;
                var l     = new Mock <IBareAsyncLock>(MockBehavior.Strict);
                l.Setup(x => x.BarelyLockAsync(It.IsAny <CancellationToken>())).ReturnsAsync(() =>
                {
                    currentStates[iCopy].ShouldBe(0);
                    ++currentStates[iCopy];
                    return(iCopy.ToString());
                });
                object valueToken;
                l.Setup(x => x.BarelyTryLock(out valueToken)).Returns(new TryLockDelegate((out object v) =>
                {
                    ++currentStates[iCopy];
                    v = iCopy.ToString();
                    return(true);
                }));
                l.Setup(x => x.BarelyUnlock()).Callback(() => -- currentStates[iCopy]);
                locks.Add(l.Object);
            }
            var guard = await MultiSync.AllAsync(locks);

            // act
            guard.Dispose();

            // assert
            currentStates.ShouldBe(Enumerable.Repeat(0, count));
        }
Esempio n. 7
0
        private async Task DiningAsync()
        {
            for (var method = (Method)0; method < Method.Count; ++method)
            {
                for (var nt = 2; nt <= 32; ++nt)
                {
                    ForceGC();
                    var table      = new List <IBareAsyncLock>();
                    var lockOrders = new Dictionary <IBareAsyncLock, int>();
                    for (var i = 0; i < nt; ++i)
                    {
                        table.Add(AsyncSynchronized.Create(new object()));
                        lockOrders[table[i]] = i;
                    }

                    var diners = new List <AsyncPhilosopher>();
                    for (var i = 0; i < nt; ++i)
                    {
                        int j = i;
                        int k = j < nt - 1 ? j + 1 : 0;
                        Func <IReadOnlyList <IBareAsyncLock>, Action, Task> lockToEat = null;
                        switch (method)
                        {
                        case Method.Ordered:
                            lockToEat = async(locks, eat) =>
                            {
                                locks = locks.OrderBy(x => lockOrders[x]).ToList();
                                foreach (var l in locks)
                                {
                                    await l.BarelyLockAsync().ConfigureAwait(false);
                                }
                                eat();
                                foreach (var l in locks)
                                {
                                    l.BarelyUnlock();
                                }
                            };
                            break;

                        case Method.SmartAndPolite:
                            lockToEat = async(locks, eat) =>
                            {
                                using (await MultiSync.AllAsync(locks).ConfigureAwait(false))
                                {
                                    eat();
                                }
                            };
                            break;
                        }
                        diners.Add(new AsyncPhilosopher(new[] { table[j], table[k] }, lockToEat));
                    }
                    var stopwatch = new Stopwatch();
                    var tasks     = new List <Task>();
                    stopwatch.Start();
                    for (var i = 0; i < nt; ++i)
                    {
                        tasks.Add(Task.Run(diners[i].DineAsync));
                    }
                    await Task.WhenAll(tasks).ConfigureAwait(false);

                    stopwatch.Stop();
                    Console.WriteLine($"{method},{nt},{stopwatch.Elapsed.TotalSeconds}");
                }
            }
        }
Esempio n. 8
0
        private void Dining()
        {
            for (var method = (Method)0; method < Method.Count; ++method)
            {
                for (var nt = 2; nt <= 32; ++nt)
                {
                    ForceGC();
                    var table      = new List <IBareLock>();
                    var lockOrders = new Dictionary <IBareLock, int>();
                    for (var i = 0; i < nt; ++i)
                    {
                        table.Add(Synchronized.Create(new object()));
                        lockOrders[table[i]] = i;
                    }

                    var diners = new List <Philosopher>();
                    for (var i = 0; i < nt; ++i)
                    {
                        int j = i;
                        int k = j < nt - 1 ? j + 1 : 0;
                        Action <IReadOnlyList <IBareLock>, Action> lockToEat = null;
                        switch (method)
                        {
                        case Method.Ordered:
                            lockToEat = (locks, eat) =>
                            {
                                locks = locks.OrderBy(x => lockOrders[x]).ToList();
                                foreach (var l in locks)
                                {
                                    l.BarelyLock();
                                }
                                eat();
                                foreach (var l in locks)
                                {
                                    l.BarelyUnlock();
                                }
                            };
                            break;

                        case Method.SmartAndPolite:
                            lockToEat = (locks, eat) =>
                            {
                                using (MultiSync.All(locks))
                                {
                                    eat();
                                }
                            };
                            break;
                        }
                        diners.Add(new Philosopher(new[] { table[j], table[k] }, lockToEat));
                    }
                    var threads   = new List <Thread>();
                    var stopwatch = new Stopwatch();
                    for (var i = 0; i < nt; ++i)
                    {
                        threads.Add(new Thread(diners[i].Dine));
                    }
                    stopwatch.Start();
                    for (var i = 0; i < nt; ++i)
                    {
                        threads[i].Start();
                    }
                    foreach (var t in threads)
                    {
                        t.Join();
                    }
                    stopwatch.Stop();
                    Console.WriteLine($"{method},{nt},{stopwatch.Elapsed.TotalSeconds}");
                }
            }
        }
Esempio n. 9
0
        private async Task TestSynchronizeMultipleAsync(int repeat, bool output)
        {
            var watch = new Stopwatch();

            var x1   = new X();
            var x2   = new X();
            var sqrt = (int)Math.Sqrt(1);

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                lock (x1)
                {
                    lock (x2)
                    {
                        x1.Value += sqrt;
                        x2.Value += sqrt;
                    }
                }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"lock,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            var syncMonitor1 = Synchronized.Create(x1);
            var syncMonitor2 = Synchronized.Create(x2);

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                using (var v1 = syncMonitor1.Lock())
                    using (var v2 = syncMonitor2.Lock())
                    {
                        v1.Value.Value += sqrt;
                        v2.Value.Value += sqrt;
                    }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"Synchronized.Lock,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                using (var guard = MultiSync.All(new[] { syncMonitor1, syncMonitor2 }))
                {
                    guard.Value[0].Value += sqrt;
                    guard.Value[1].Value += sqrt;
                }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"MultiSync.All Monitor,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            var syncMonitors = new[] { syncMonitor1, syncMonitor2 };

            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                using (var guard = MultiSync.All(syncMonitors))
                {
                    guard.Value[0].Value += sqrt;
                    guard.Value[1].Value += sqrt;
                }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"MultiSync.All Monitor reusing array,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            watch.Restart();
            var semaphore1 = new SemaphoreSlim(1);
            var semaphore2 = new SemaphoreSlim(1);

            for (int i = 0; i < repeat; ++i)
            {
                await semaphore1.WaitAsync().ConfigureAwait(false);

                await semaphore2.WaitAsync().ConfigureAwait(false);

                x1.Value += sqrt;
                x2.Value += sqrt;
                semaphore2.Release();
                semaphore1.Release();
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"SemaphoreSlim.WaitAsync,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }

            ForceGC();
            var syncSemaphore1 = AsyncSynchronized.Create(x1);
            var syncSemaphore2 = AsyncSynchronized.Create(x2);

            watch.Restart();
            for (int i = 0; i < repeat; ++i)
            {
                using (var guard = await MultiSync.AllAsync(new[] { syncSemaphore1, syncSemaphore2 }).ConfigureAwait(false))
                {
                    guard.Value[0].Value += sqrt;
                    guard.Value[1].Value += sqrt;
                }
            }
            watch.Stop();
            if (output)
            {
                Console.WriteLine($"MultiSync.AllAsync SemaphoreSlim,{((double)watch.ElapsedTicks * 100 / repeat)}");
            }
        }
Esempio n. 10
0
 public void AllBareLockTimeout_InfiniteTimeout_Acquire(TimingMethod timingMethod, int[][] lockStates)
 {
     AllBareLock_Acquire(lockStates, locks => MultiSync.All(locks, -1, timingMethod));
 }
Esempio n. 11
0
 public void AllBareLock_Acquire(int[][] lockStates)
 {
     AllBareLock_Acquire(lockStates, locks => MultiSync.All(locks));
 }
Esempio n. 12
0
 public void AllBareLockTimeout_MaxTimeout_Acquire(int timeoutMs, TimingMethod timingMethod)
 {
     AllBareLock_Acquire(new[] { new[] { 0, 0, 0 } }, locks => MultiSync.All(locks, timeoutMs, timingMethod));
 }