Exemple #1
0
            public void Write <T>(T[] instances, Action <T> write)
            {
                RMonitor.Enter(_writersMutex);
                try
                {
                    var index     = RInterlocked.Read(ref _index);
                    var nextIndex = Toggle(index);
                    if (WaitOnFirstWrite)
                    {
                        WaitWhileOccupied(_readIndicator[nextIndex]); // Now we're subject to starvation by (new) readers.
                    }                                                 // And mutual exclusion may still be violated.
                    _snoop.BeginWrite(nextIndex);
                    write(instances[nextIndex]);
                    _snoop.EndWrite(nextIndex);

                    // Move subsequent readers to 'next' instance
                    RInterlocked.Exchange(ref _index, nextIndex);

                    // Wait for all readers to finish reading the instance we want to write next
                    WaitWhileOccupied(_readIndicator[index]);
                    // At this point there may be readers, but they must be on nextReadIndex, we can
                    // safely write.
                    _snoop.BeginWrite(index);
                    write(instances[index]);
                    _snoop.EndWrite(index);
                }
                finally
                {
                    RMonitor.Exit(_writersMutex);
                }
            }
Exemple #2
0
 private void PulsingThread(int numPulses)
 {
     for (int i = 0; i < numPulses; ++i)
     {
         RMonitor.Enter(_lockObject);
         RMonitor.Pulse(_lockObject);
         RMonitor.Exit(_lockObject);
     }
 }
Exemple #3
0
        private void LockingThread(int idx)
        {
            var myLock   = ActiveConfig.LockObjects[idx];
            var nextLock = ActiveConfig.LockObjects[(idx + 1) % ActiveConfig.NumThreads];

            RMonitor.Enter(myLock);
            RMonitor.Enter(nextLock);
            RMonitor.Exit(nextLock);
            RMonitor.Exit(myLock);
        }
Exemple #4
0
 private void EnterSlow()
 {
     RMonitor.Enter(_lockObj);
     RUnordered.Write(ref _holdingThreadId, Environment.CurrentManagedThreadId);
     RInterlocked.MemoryBarrierProcessWide();
     while (RUnordered.Read(ref _isHeld) == 1)
     {
         RE.Yield();
     }
     RUnordered.Write(ref _isHeld, 1);
     RMonitor.Exit(_lockObj);
     return;
 }
Exemple #5
0
            internal void EnterReadLock()
            {
                var idx = GetReaderIndex();

                RUnordered.Write(ref _readIndicator[idx], 1);
                if (RUnordered.Read(ref _writerActive) == 1)
                {
                    RUnordered.Write(ref _readIndicator[idx], 0);
                    RMonitor.Enter(_lockObj);
                    RUnordered.Write(ref _readIndicator[idx], 1);
                    RMonitor.Exit(_lockObj);
                }
                _snoop.BeginRead();
            }
Exemple #6
0
            private LockCookie EnterSlow()
            {
                RMonitor.Enter(_lockObj);
                var oldEntry = RUnordered.Read(ref _current);

                RUnordered.Write(ref _current, new LockCookie(Environment.CurrentManagedThreadId));
                RInterlocked.MemoryBarrierProcessWide();
                while (oldEntry != null && RUnordered.Read(ref oldEntry.Taken) == 1)
                {
                    RE.Yield();
                }
                var current = RUnordered.Read(ref _current);

                RUnordered.Write(ref current.Taken, 1);
                RMonitor.Exit(_lockObj);
                return(current);
            }
Exemple #7
0
            public void Write <T>(T[] instances, Action <T> write)
            {
                RMonitor.Enter(_writersMutex);
                try
                {
//                    var readIndex = RUnordered.Read(ref _readIndex);
                    var readIndex     = RInterlocked.Read(ref _readIndex);
                    var nextReadIndex = Toggle(readIndex);
                    _snoop.BeginWrite(nextReadIndex);
                    write(instances[nextReadIndex]);
                    _snoop.EndWrite(nextReadIndex);

                    // Move subsequent readers to 'next' instance
                    RInterlocked.Exchange(ref _readIndex, nextReadIndex);
                    // Wait for all readers marked in the 'next' read indicator,
                    // these readers could be reading the 'readIndex' instance
                    // we want to write next
                    var versionIndex = RInterlocked.Read(ref _versionIndex);
                    //var versionIndex = RUnordered.Read(ref _versionIndex);
                    var nextVersionIndex = Toggle(versionIndex);

                    WaitWhileOccupied(_readIndicator[nextVersionIndex]);
                    // Move subsequent readers to the 'next' read indicator

                    RInterlocked.Exchange(ref _versionIndex, nextVersionIndex);
//                    RUnordered.Write(ref _versionIndex, nextVersionIndex);
                    // At this point all subsequent readers will read the 'next' instance
                    // and mark the 'nextVersionIndex' read indicator, so the only remaining potential
                    // readers are the ones on the 'versionIndex' read indicator, so wait for them to finish
                    WaitWhileOccupied(_readIndicator[versionIndex]);
                    // At this point there may be readers, but they must be on nextReadIndex, we can
                    // safely write.
                    _snoop.BeginWrite(readIndex);
                    write(instances[readIndex]);
                    _snoop.EndWrite(readIndex);
                }
                finally
                {
                    RMonitor.Exit(_writersMutex);
                }
            }
 public void Write <T>(T[] instances, Action <T> write)
 {
     RMonitor.Enter(_writersMutex);
     try
     {
         var readIndex     = RInterlocked.Read(ref _readIndex);
         var nextReadIndex = Toggle(readIndex);
         _snoop.BeginWrite(nextReadIndex);
         write(instances[nextReadIndex]);
         _snoop.EndWrite(nextReadIndex);
         RInterlocked.Exchange(ref _readIndex, nextReadIndex);
         WaitWhileOccupied(_readIndicator);
         _snoop.BeginWrite(readIndex);
         write(instances[readIndex]);
         _snoop.EndWrite(readIndex);
     }
     finally
     {
         RMonitor.Exit(_writersMutex);
     }
 }
Exemple #9
0
 internal void ExitWriteLock()
 {
     RUnordered.Write(ref _writerActive, 0);
     _snoop.EndWrite();
     RMonitor.Exit(_lockObj);
 }
Exemple #10
0
 public void WaitingThread()
 {
     RMonitor.Enter(_lockObject);
     RMonitor.Wait(_lockObject);
     RMonitor.Exit(_lockObject);
 }