QMutexPool: avoid QVarLengthArray of QAtomicPointers

QAtomicPointer is CopyConstructible, but std::atomic<T*> is not,
for a reason. So avoid putting them in a QVarLengthArray, using
a dynamic heap allocation instead. This sounds wasteful until
you realize that virtually all users of QMutexPool (and we know
them all) use the global instance(), and that each QMutex (131,
by default) is heap-allocated, too.

Change-Id: Ie9c95671ec42a1f51919c18631b623aad2c0d6ba
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2016-04-24 12:00:25 +02:00
parent 8586cccc07
commit 4579d966af
2 changed files with 8 additions and 8 deletions

View File

@ -92,11 +92,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (QMutex::Recursive))
QMutexPool is destructed.
*/
QMutexPool::QMutexPool(QMutex::RecursionMode recursionMode, int size)
: mutexes(size), recursionMode(recursionMode)
: count(size),
mutexes(new QAtomicPointer<QMutex>[size]()), // (): zero-initialize
recursionMode(recursionMode)
{
for (int index = 0; index < mutexes.count(); ++index) {
mutexes[index].store(0);
}
}
/*!
@ -105,8 +104,8 @@ QMutexPool::QMutexPool(QMutex::RecursionMode recursionMode, int size)
*/
QMutexPool::~QMutexPool()
{
for (int index = 0; index < mutexes.count(); ++index)
delete mutexes[index].load();
qDeleteAll(mutexes, mutexes + count);
delete[] mutexes;
}
/*!

View File

@ -66,7 +66,7 @@ public:
~QMutexPool();
inline QMutex *get(const void *address) {
int index = uint(quintptr(address)) % mutexes.count();
int index = uint(quintptr(address)) % count;
QMutex *m = mutexes[index].load();
if (m)
return m;
@ -78,7 +78,8 @@ public:
private:
QMutex *createMutex(int index);
QVarLengthArray<QAtomicPointer<QMutex>, 131> mutexes;
int count;
QAtomicPointer<QMutex> *mutexes;
QMutex::RecursionMode recursionMode;
};