Browse Source

Tidied up ReadWriteLock a bit, and optimised Array to reduce allocation frequency when working with small numbers of items.

tags/2021-05-28
jules 13 years ago
parent
commit
40929e5db9
3 changed files with 52 additions and 61 deletions
  1. +22
    -29
      modules/juce_core/containers/juce_Array.h
  2. +22
    -31
      modules/juce_core/threads/juce_ReadWriteLock.cpp
  3. +8
    -1
      modules/juce_core/threads/juce_ReadWriteLock.h

+ 22
- 29
modules/juce_core/containers/juce_Array.h View File

@@ -679,30 +679,23 @@ public:
// avoids getting warning messages about the parameter being unused
const ScopedLockType lock (getLock());
int start = 0;
int end_ = numUsed;
for (;;)
for (int s = 0, e = numUsed;;)
{
if (start >= end_)
{
if (s >= e)
return -1;
}
else if (comparator.compareElements (elementToLookFor, data.elements [start]) == 0)
{
return start;
}
else
{
const int halfway = (start + end_) >> 1;
if (halfway == start)
return -1;
else if (comparator.compareElements (elementToLookFor, data.elements [halfway]) >= 0)
start = halfway;
else
end_ = halfway;
}
if (comparator.compareElements (elementToLookFor, data.elements [s]) == 0)
return s;
const int halfway = (s + e) / 2;
if (halfway == s)
return -1;
if (comparator.compareElements (elementToLookFor, data.elements [halfway]) >= 0)
s = halfway;
else
e = halfway;
}
}
@@ -733,9 +726,7 @@ public:
if (numberToShift > 0)
memmove (e, e + 1, ((size_t) numberToShift) * sizeof (ElementType));
if ((numUsed << 1) < data.numAllocated)
minimiseStorageOverheads();
minimiseStorageAfterRemoval();
return removed;
}
else
@@ -798,9 +789,7 @@ public:
memmove (e, e + numberToRemove, ((size_t) numToShift) * sizeof (ElementType));
numUsed -= numberToRemove;
if ((numUsed << 1) < data.numAllocated)
minimiseStorageOverheads();
minimiseStorageAfterRemoval();
}
}
@@ -820,9 +809,7 @@ public:
data.elements [numUsed - i].~ElementType();
numUsed -= howManyToRemove;
if ((numUsed << 1) < data.numAllocated)
minimiseStorageOverheads();
minimiseStorageAfterRemoval();
}
/** Removes any elements which are also in another array.
@@ -1029,6 +1016,12 @@ private:
for (int i = 0; i < numUsed; ++i)
data.elements[i].~ElementType();
}
void minimiseStorageAfterRemoval()
{
if (data.numAllocated > numUsed * 2)
data.shrinkToNoMoreThan (jmax (numUsed, 64 / (int) sizeof (ElementType)));
}
};


+ 22
- 31
modules/juce_core/threads/juce_ReadWriteLock.cpp View File

@@ -45,27 +45,22 @@ void ReadWriteLock::enterRead() const noexcept
for (;;)
{
jassert (readerThreads.size() % 2 == 0);
int i;
for (i = 0; i < readerThreads.size(); i += 2)
if (readerThreads.getUnchecked(i) == threadId)
break;
if (i < readerThreads.size()
|| numWriters + numWaitingWriters == 0
|| (threadId == writerThreadId && numWriters > 0))
for (int i = 0; i < readerThreads.size(); ++i)
{
if (i < readerThreads.size())
{
readerThreads.set (i + 1, (Thread::ThreadID) (1 + (pointer_sized_int) readerThreads.getUnchecked (i + 1)));
}
else
ThreadRecursionCount& trc = readerThreads.getReference(i);
if (trc.threadID == threadId)
{
readerThreads.add (threadId);
readerThreads.add ((Thread::ThreadID) 1);
trc.count++;
return;
}
}
if (numWriters + numWaitingWriters == 0
|| (threadId == writerThreadId && numWriters > 0))
{
ThreadRecursionCount trc = { threadId, 1 };
readerThreads.add (trc);
return;
}
@@ -79,21 +74,17 @@ void ReadWriteLock::exitRead() const noexcept
const Thread::ThreadID threadId = Thread::getCurrentThreadId();
const SpinLock::ScopedLockType sl (accessLock);
for (int i = 0; i < readerThreads.size(); i += 2)
for (int i = 0; i < readerThreads.size(); ++i)
{
if (readerThreads.getUnchecked(i) == threadId)
{
const pointer_sized_int newCount = ((pointer_sized_int) readerThreads.getUnchecked (i + 1)) - 1;
ThreadRecursionCount& trc = readerThreads.getReference(i);
if (newCount == 0)
if (trc.threadID == threadId)
{
if (--(trc.count) == 0)
{
readerThreads.removeRange (i, 2);
readerThreads.remove (i);
waitEvent.signal();
}
else
{
readerThreads.set (i + 1, (Thread::ThreadID) newCount);
}
return;
}
@@ -112,8 +103,8 @@ void ReadWriteLock::enterWrite() const noexcept
{
if (readerThreads.size() + numWriters == 0
|| threadId == writerThreadId
|| (readerThreads.size() == 2
&& readerThreads.getUnchecked(0) == threadId))
|| (readerThreads.size() == 1
&& readerThreads.getReference(0).threadID == threadId))
{
writerThreadId = threadId;
++numWriters;
@@ -135,8 +126,8 @@ bool ReadWriteLock::tryEnterWrite() const noexcept
if (readerThreads.size() + numWriters == 0
|| threadId == writerThreadId
|| (readerThreads.size() == 2
&& readerThreads.getUnchecked(0) == threadId))
|| (readerThreads.size() == 1
&& readerThreads.getReference(0).threadID == threadId))
{
writerThreadId = threadId;
++numWriters;


+ 8
- 1
modules/juce_core/threads/juce_ReadWriteLock.h View File

@@ -129,7 +129,14 @@ private:
WaitableEvent waitEvent;
mutable int numWaitingWriters, numWriters;
mutable Thread::ThreadID writerThreadId;
mutable Array <Thread::ThreadID> readerThreads;
struct ThreadRecursionCount
{
Thread::ThreadID threadID;
int count;
};
mutable Array <ThreadRecursionCount> readerThreads;
JUCE_DECLARE_NON_COPYABLE (ReadWriteLock);
};


Loading…
Cancel
Save