Пример #1
0
        private void RecordStore(T data, MemoryOrder mo, ShadowThread runningThread, bool isReleaseSequence)
        {
            var storeTarget = _history.GetNext();

            storeTarget.RecordStore(runningThread.Id, runningThread.Clock, mo, data);

            bool isAtLeastRelease = mo == MemoryOrder.Release || mo == MemoryOrder.AcquireRelease || mo == MemoryOrder.SequentiallyConsistent;

            // Here 'sourceClock' is the clock that other threads must synchronize with if they read-acquire this data.
            // If this store is a release (or stronger), then those threads must synchronize with the latest clocks that
            // this thread has synchronized with (i.e. the releases it has acquired: runningThread.ReleasesAcquired).
            // Otherwise, if this store is relaxed, then those threads need only synchronize with the latest release fence of this thread
            // (i.e. runningThread.FenceReleasesAcquired)
            var sourceClock = isAtLeastRelease ? runningThread.ReleasesAcquired : runningThread.FenceReleasesAcquired;

            var previous    = _history[_history.CurrentIndex - 1];
            var targetClock = storeTarget.ReleasesToAcquire;

            if (isReleaseSequence)
            {
                targetClock.Assign(previous.ReleasesToAcquire);
                targetClock.Join(sourceClock);
            }
            else
            {
                targetClock.Assign(sourceClock);
            }
        }
Пример #2
0
 public T Load(ShadowThread runningThread, Action <string> failTest)
 {
     if (_storeClock.AnyGreater(runningThread.ReleasesAcquired))
     {
         failTest($"Data race detected in load on thread {runningThread.Id} @ {runningThread.Clock}");
         return(default(T));
     }
     runningThread.IncrementClock();
     _loadClock[runningThread.Id] = runningThread.Clock;
     return(_data);
 }
Пример #3
0
 public void Store(T data, ShadowThread runningThread, Action <string> failTest)
 {
     if (_loadClock.AnyGreater(runningThread.ReleasesAcquired) || _storeClock.AnyGreater(runningThread.ReleasesAcquired))
     {
         failTest($"Data race detected in store on thread {runningThread.Id} @ {runningThread.Clock}");
         return;
     }
     runningThread.IncrementClock();
     _storeClock[runningThread.Id] = runningThread.Clock;
     _data = data;
     return;
 }
Пример #4
0
        private T RecordLoad(MemoryOrder mo, ShadowThread runningThread, AccessData <T> loadData)
        {
            loadData.RecordLoad(runningThread.Id, runningThread.Clock);
            bool isAtLeastAcquire = mo == MemoryOrder.Acquire || mo == MemoryOrder.AcquireRelease || mo == MemoryOrder.SequentiallyConsistent;

            // Here 'destinationClock' is the clock that must synchronize with the last release to this data.
            // If this load is an acquire (or stronger), then this thread's clock must synchronize with the last release
            // (i.e. it should acquire the release to this data so runningThread.ReleasesAcquired must update).
            // Otherwise, if this load is relaxed, then other threads must only synchronize with the last release to this data
            // if an acquire fence is issued. So to allow for updating the releases acquired by this thread in the case of an acquire
            // fence being issued at some point, update runningThread.FenceReleasesToAcquire
            var destinationClock = isAtLeastAcquire ? runningThread.ReleasesAcquired : runningThread.FenceReleasesToAcquire;

            destinationClock.Join(loadData.ReleasesToAcquire);
            return(loadData.Payload);
        }
Пример #5
0
        public T RecordPossibleLoad(MemoryOrder mo, ShadowThread runningThread)
        {
            var loadData = GetPossibleLoad(runningThread.ReleasesAcquired, runningThread.Id, mo);

            return(RecordLoad(mo, runningThread, loadData));
        }
Пример #6
0
        public T RecordRMWLoad(MemoryOrder mo, ShadowThread runningThread)
        {
            var loadData = _history[_history.CurrentIndex];

            return(RecordLoad(mo, runningThread, loadData));
        }
Пример #7
0
        public void RecordStore(T data, MemoryOrder mo, ShadowThread runningThread)
        {
            var previous = _history[_history.CurrentIndex - 1];

            RecordStore(data, mo, runningThread, previous.IsInitialized && previous.LastStoredThreadId == runningThread.Id);
        }
Пример #8
0
 public void RecordRMWStore(T data, MemoryOrder mo, ShadowThread runningThread)
 {
     RecordStore(data, mo, runningThread, true);
 }