Browse Source

Fixed data races in the Atomic and AbstractFifo classes

tags/2021-05-28
Tom Poole 8 years ago
parent
commit
170cc39858
2 changed files with 15 additions and 13 deletions
  1. +7
    -5
      modules/juce_core/containers/juce_AbstractFifo.cpp
  2. +8
    -8
      modules/juce_core/memory/juce_Atomic.h

+ 7
- 5
modules/juce_core/containers/juce_AbstractFifo.cpp View File

@@ -58,7 +58,7 @@ void AbstractFifo::setTotalSize (int newSize) noexcept
void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept
{ {
const int vs = validStart.get(); const int vs = validStart.get();
const int ve = validEnd.value;
const int ve = validEnd.get();
const int freeSpace = ve >= vs ? (bufferSize - (ve - vs)) : (vs - ve); const int freeSpace = ve >= vs ? (bufferSize - (ve - vs)) : (vs - ve);
numToWrite = jmin (numToWrite, freeSpace - 1); numToWrite = jmin (numToWrite, freeSpace - 1);
@@ -83,7 +83,9 @@ void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockS
void AbstractFifo::finishedWrite (int numWritten) noexcept void AbstractFifo::finishedWrite (int numWritten) noexcept
{ {
jassert (numWritten >= 0 && numWritten < bufferSize); jassert (numWritten >= 0 && numWritten < bufferSize);
int newEnd = validEnd.value + numWritten;
int newEnd = validEnd.get() + numWritten;
if (newEnd >= bufferSize) if (newEnd >= bufferSize)
newEnd -= bufferSize; newEnd -= bufferSize;
@@ -92,7 +94,7 @@ void AbstractFifo::finishedWrite (int numWritten) noexcept
void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const noexcept
{ {
const int vs = validStart.value;
const int vs = validStart.get();
const int ve = validEnd.get(); const int ve = validEnd.get();
const int numReady = ve >= vs ? (ve - vs) : (bufferSize - (vs - ve)); const int numReady = ve >= vs ? (ve - vs) : (bufferSize - (vs - ve));
@@ -119,14 +121,14 @@ void AbstractFifo::finishedRead (int numRead) noexcept
{ {
jassert (numRead >= 0 && numRead <= bufferSize); jassert (numRead >= 0 && numRead <= bufferSize);
int newStart = validStart.value + numRead;
int newStart = validStart.get() + numRead;
if (newStart >= bufferSize) if (newStart >= bufferSize)
newStart -= bufferSize; newStart -= bufferSize;
validStart = newStart; validStart = newStart;
} }
//==============================================================================
//============================================================================== //==============================================================================
#if JUCE_UNIT_TESTS #if JUCE_UNIT_TESTS


+ 8
- 8
modules/juce_core/memory/juce_Atomic.h View File

@@ -346,14 +346,14 @@ namespace juce
{ {
static inline Type inc (AtomicBase<Type>& a) noexcept static inline Type inc (AtomicBase<Type>& a) noexcept
{ {
return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (& (a.value), (Type) 1)
: (Type) __sync_add_and_fetch ((int64_t*) & (a.value), 1);
return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (& (a.value), (Type) 1)
: (Type) __sync_add_and_fetch ((int64_t*) & (a.value), 1);
} }
static inline Type dec (AtomicBase<Type>& a) noexcept static inline Type dec (AtomicBase<Type>& a) noexcept
{ {
return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (& (a.value), (Type) -1)
: (Type) __sync_add_and_fetch ((int64_t*) & (a.value), -1);
return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (& (a.value), (Type) -1)
: (Type) __sync_add_and_fetch ((int64_t*) & (a.value), -1);
} }
}; };
@@ -368,15 +368,15 @@ namespace juce
template <typename Type> template <typename Type>
inline Type AtomicBase<Type>::get() const noexcept inline Type AtomicBase<Type>::get() const noexcept
{ {
return sizeof (Type) == 4 ? castFrom32Bit ((int32) __sync_add_and_fetch ((volatile int32*) &value, 0))
: castFrom64Bit ((int64) __sync_add_and_fetch ((volatile int64*) &value, 0));
return sizeof (Type) == 4 ? castFrom32Bit ((int32) __sync_add_and_fetch ((volatile int32*) &value, 0))
: castFrom64Bit ((int64) __sync_add_and_fetch ((volatile int64*) &value, 0));
} }
template <typename Type> template <typename Type>
inline Type AtomicBase<Type>::exchange (const Type newValue) noexcept inline Type AtomicBase<Type>::exchange (const Type newValue) noexcept
{ {
Type currentVal = value;
while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; }
Type currentVal = get();
while (! compareAndSetBool (newValue, currentVal)) { currentVal = get(); }
return currentVal; return currentVal;
} }


Loading…
Cancel
Save