public void CreateRWLSContext()
 {
     _rwls            = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
     _rwlsVal         = new Val64(-1L);
     _rwlsBarrier     = new ManualResetEvent(false);
     _rwlsThreads     = new List <Thread>();
     _rwlsSyncBarrier = new Barrier(NumThreads);
     BenchmarkUtils.PrepareThreads(NumThreads, _rwlsBarrier, WithRWLS_Entry, _rwlsThreads);
 }
 public void CreateLessGranularLockContext()
 {
     _lessGranularLock            = new object();
     _lessGranularLockVal         = new Val64(-1L);
     _lessGranularLockBarrier     = new ManualResetEvent(false);
     _lessGranularLockThreads     = new List <Thread>();
     _lessGranularLockSyncBarrier = new Barrier(NumThreads);
     BenchmarkUtils.PrepareThreads(NumThreads, _lessGranularLockBarrier, WithLessGranularLock_Entry, _lessGranularLockThreads);
 }
        void WithRWLS_Entry()
        {
            var result = 0L;

            for (var i = 0; i < NumIterations; i++)
            {
                _rwls.EnterReadLock();
                if (_rwlsVal.A < i)
                {
                    result += _rwlsVal.A;
                }
                else
                {
                    result -= _rwlsVal.A;
                }
                _rwls.ExitReadLock();

                BenchmarkUtils.SimulateContention(ContentionLevel);

                _rwls.EnterReadLock();
                var curVal = _rwlsVal;
                _rwls.ExitReadLock();

                BenchmarkUtils.SimulateContention(ContentionLevel);

                _rwls.EnterReadLock();
                if (curVal.A >= _rwlsVal.A)
                {
                    if (_rwlsVal.B > _rwlsVal.C)
                    {
                        result += _rwlsVal.C;
                    }
                    else
                    {
                        result += _rwlsVal.B;
                    }
                }
                else
                {
                    if (_rwlsVal.B > _rwlsVal.C)
                    {
                        result += _rwlsVal.B;
                    }
                    else
                    {
                        result += _rwlsVal.C;
                    }
                }

                if (_rwlsVal.A < i)
                {
                    result += _rwlsVal.A;
                }
                else
                {
                    result -= _rwlsVal.A;
                }

                curVal = _rwlsVal;

                if (curVal.A >= _rwlsVal.A)
                {
                    if (_rwlsVal.B > _rwlsVal.C)
                    {
                        result += _rwlsVal.C;
                    }
                    else
                    {
                        result += _rwlsVal.B;
                    }
                }
                else
                {
                    if (_rwlsVal.B > _rwlsVal.C)
                    {
                        result += _rwlsVal.B;
                    }
                    else
                    {
                        result += _rwlsVal.C;
                    }
                }
                _rwls.ExitReadLock();

                BenchmarkUtils.SimulateContention(ContentionLevel);

                if (i % IterationsPerBarrier == 0)
                {
                    _rwls.EnterWriteLock();
                    if (_rwlsVal.B < curVal.A)
                    {
                        if (_rwlsVal == curVal)
                        {
                            _rwlsVal = new Val64(curVal.A - 1L);
                        }
                        result += _rwlsVal.A;
                    }
                    else
                    {
                        if (_rwlsVal == curVal)
                        {
                            _rwlsVal = new Val64(curVal.A + 1L);
                        }
                        result += _rwlsVal.A;
                    }
                    _rwls.ExitWriteLock();

                    _rwlsSyncBarrier.SignalAndWait();
                }

                BenchmarkUtils.SimulateContention(ContentionLevel);
            }

            if (result == 0L)
            {
                Console.Beep(1000, 100);
            }
        }
        void WithLessGranularLock_Entry()
        {
            var result = 0L;

            for (var i = 0; i < NumIterations; i++)
            {
                Val64 curVal;

                lock (_lessGranularLock) {
                    if (_lessGranularLockVal.A < i)
                    {
                        result += _lessGranularLockVal.A;
                    }
                    else
                    {
                        result -= _lessGranularLockVal.A;
                    }

                    BenchmarkUtils.SimulateContention(ContentionLevel);

                    curVal = _lessGranularLockVal;

                    BenchmarkUtils.SimulateContention(ContentionLevel);

                    if (curVal.A >= _lessGranularLockVal.A)
                    {
                        if (_lessGranularLockVal.B > _lessGranularLockVal.C)
                        {
                            result += _lessGranularLockVal.C;
                        }
                        else
                        {
                            result += _lessGranularLockVal.B;
                        }
                    }
                    else
                    {
                        if (_lessGranularLockVal.B > _lessGranularLockVal.C)
                        {
                            result += _lessGranularLockVal.B;
                        }
                        else
                        {
                            result += _lessGranularLockVal.C;
                        }
                    }

                    if (_lessGranularLockVal.A < i)
                    {
                        result += _lessGranularLockVal.A;
                    }
                    else
                    {
                        result -= _lessGranularLockVal.A;
                    }

                    curVal = _lessGranularLockVal;

                    if (curVal.A >= _lessGranularLockVal.A)
                    {
                        if (_lessGranularLockVal.B > _lessGranularLockVal.C)
                        {
                            result += _lessGranularLockVal.C;
                        }
                        else
                        {
                            result += _lessGranularLockVal.B;
                        }
                    }
                    else
                    {
                        if (_lessGranularLockVal.B > _lessGranularLockVal.C)
                        {
                            result += _lessGranularLockVal.B;
                        }
                        else
                        {
                            result += _lessGranularLockVal.C;
                        }
                    }
                }

                BenchmarkUtils.SimulateContention(ContentionLevel);

                if (i % IterationsPerBarrier == 0)
                {
                    lock (_lessGranularLock) {
                        if (_lessGranularLockVal.B < curVal.A)
                        {
                            if (_lessGranularLockVal == curVal)
                            {
                                _lessGranularLockVal = new Val64(curVal.A - 1L);
                            }
                            result += _lessGranularLockVal.A;
                        }
                        else
                        {
                            if (_lessGranularLockVal == curVal)
                            {
                                _lessGranularLockVal = new Val64(curVal.A + 1L);
                            }
                            result += _lessGranularLockVal.A;
                        }
                    }

                    _lessGranularLockSyncBarrier.SignalAndWait();
                }

                BenchmarkUtils.SimulateContention(ContentionLevel);
            }

            if (result == 0L)
            {
                Console.Beep(1000, 100);
            }
        }