QtCore: use C++11 thread_local instead of QThreadStorage
It's more efficient than our QThreadStorage and definitely much better than the Q_GLOBAL_STATIC+QThreadStorage solution. We can do this because the last compiler not to have thread_local support was MSVC 2013, which is no longer supported since Qt 5.11. QThreadStorage also managed the lifetimes of pointers for us, so the equivalent thread_local requires std::unique_ptr. Change-Id: Id59bdd8f1a804b809e22fffd15405f1b394c48d8 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
parent
de6ced6692
commit
4a93285b16
@ -149,7 +149,6 @@
|
|||||||
#include "qabstractanimation_p.h"
|
#include "qabstractanimation_p.h"
|
||||||
|
|
||||||
#include <QtCore/qmath.h>
|
#include <QtCore/qmath.h>
|
||||||
#include <QtCore/qthreadstorage.h>
|
|
||||||
#include <QtCore/qcoreevent.h>
|
#include <QtCore/qcoreevent.h>
|
||||||
#include <QtCore/qpointer.h>
|
#include <QtCore/qpointer.h>
|
||||||
#include <QtCore/qscopedvaluerollback.h>
|
#include <QtCore/qscopedvaluerollback.h>
|
||||||
@ -214,8 +213,6 @@ typedef QList<QAbstractAnimation*>::ConstIterator AnimationListConstIt;
|
|||||||
QUnifiedTimer drives animations indirectly, via QAbstractAnimationTimer.
|
QUnifiedTimer drives animations indirectly, via QAbstractAnimationTimer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(QThreadStorage<QUnifiedTimer *>, unifiedTimer)
|
|
||||||
|
|
||||||
QUnifiedTimer::QUnifiedTimer() :
|
QUnifiedTimer::QUnifiedTimer() :
|
||||||
QObject(), defaultDriver(this), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL),
|
QObject(), defaultDriver(this), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL),
|
||||||
currentAnimationIdx(0), insideTick(false), insideRestart(false), consistentTiming(false), slowMode(false),
|
currentAnimationIdx(0), insideTick(false), insideRestart(false), consistentTiming(false), slowMode(false),
|
||||||
@ -233,11 +230,12 @@ QUnifiedTimer::~QUnifiedTimer()
|
|||||||
QUnifiedTimer *QUnifiedTimer::instance(bool create)
|
QUnifiedTimer *QUnifiedTimer::instance(bool create)
|
||||||
{
|
{
|
||||||
QUnifiedTimer *inst;
|
QUnifiedTimer *inst;
|
||||||
if (create && !unifiedTimer()->hasLocalData()) {
|
static thread_local std::unique_ptr<QUnifiedTimer> unifiedTimer;
|
||||||
|
if (create && !unifiedTimer) {
|
||||||
inst = new QUnifiedTimer;
|
inst = new QUnifiedTimer;
|
||||||
unifiedTimer()->setLocalData(inst);
|
unifiedTimer.reset(inst);
|
||||||
} else {
|
} else {
|
||||||
inst = unifiedTimer() ? unifiedTimer()->localData() : nullptr;
|
inst = unifiedTimer.get();
|
||||||
}
|
}
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
@ -550,10 +548,6 @@ bool QUnifiedTimer::canUninstallAnimationDriver(QAnimationDriver *d)
|
|||||||
return d == driver && driver != &defaultDriver;
|
return d == driver && driver != &defaultDriver;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(thread)
|
|
||||||
Q_GLOBAL_STATIC(QThreadStorage<QAnimationTimer *>, animationTimer)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QAnimationTimer::QAnimationTimer() :
|
QAnimationTimer::QAnimationTimer() :
|
||||||
QAbstractAnimationTimer(), lastTick(0),
|
QAbstractAnimationTimer(), lastTick(0),
|
||||||
currentAnimationIdx(0), insideTick(false),
|
currentAnimationIdx(0), insideTick(false),
|
||||||
@ -569,11 +563,12 @@ QAnimationTimer *QAnimationTimer::instance(bool create)
|
|||||||
{
|
{
|
||||||
QAnimationTimer *inst;
|
QAnimationTimer *inst;
|
||||||
#if QT_CONFIG(thread)
|
#if QT_CONFIG(thread)
|
||||||
if (create && !animationTimer()->hasLocalData()) {
|
static thread_local std::unique_ptr<QAnimationTimer> animationTimer;
|
||||||
|
if (create && !animationTimer) {
|
||||||
inst = new QAnimationTimer;
|
inst = new QAnimationTimer;
|
||||||
animationTimer()->setLocalData(inst);
|
animationTimer.reset(inst);
|
||||||
} else {
|
} else {
|
||||||
inst = animationTimer() ? animationTimer()->localData() : nullptr;
|
inst = animationTimer.get();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Q_UNUSED(create);
|
Q_UNUSED(create);
|
||||||
|
@ -46,7 +46,6 @@
|
|||||||
#include <qendian.h>
|
#include <qendian.h>
|
||||||
#include <qmutex.h>
|
#include <qmutex.h>
|
||||||
#include <qobjectdefs.h>
|
#include <qobjectdefs.h>
|
||||||
#include <qthreadstorage.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
@ -47,7 +47,6 @@
|
|||||||
#include <QtCore/qmutex.h>
|
#include <QtCore/qmutex.h>
|
||||||
#include <QtCore/qstringlist.h>
|
#include <QtCore/qstringlist.h>
|
||||||
#include <QtCore/qdebug.h>
|
#include <QtCore/qdebug.h>
|
||||||
#include <QtCore/qthreadstorage.h>
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include <QtCore/qatomic.h>
|
#include <QtCore/qatomic.h>
|
||||||
#include <QtCore/qdatastream.h>
|
#include <QtCore/qdatastream.h>
|
||||||
@ -962,43 +961,24 @@ void QRegularExpressionPrivate::getPatternInfo()
|
|||||||
Simple "smartpointer" wrapper around a pcre2_jit_stack_16, to be used with
|
Simple "smartpointer" wrapper around a pcre2_jit_stack_16, to be used with
|
||||||
QThreadStorage.
|
QThreadStorage.
|
||||||
*/
|
*/
|
||||||
class QPcreJitStackPointer
|
namespace {
|
||||||
|
struct PcreJitStackFree
|
||||||
{
|
{
|
||||||
Q_DISABLE_COPY(QPcreJitStackPointer)
|
void operator()(pcre2_jit_stack_16 *stack)
|
||||||
|
|
||||||
public:
|
|
||||||
/*!
|
|
||||||
\internal
|
|
||||||
*/
|
|
||||||
QPcreJitStackPointer()
|
|
||||||
{
|
|
||||||
// The default JIT stack size in PCRE is 32K,
|
|
||||||
// we allocate from 32K up to 512K.
|
|
||||||
stack = pcre2_jit_stack_create_16(32 * 1024, 512 * 1024, nullptr);
|
|
||||||
}
|
|
||||||
/*!
|
|
||||||
\internal
|
|
||||||
*/
|
|
||||||
~QPcreJitStackPointer()
|
|
||||||
{
|
{
|
||||||
if (stack)
|
if (stack)
|
||||||
pcre2_jit_stack_free_16(stack);
|
pcre2_jit_stack_free_16(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
pcre2_jit_stack_16 *stack;
|
|
||||||
};
|
};
|
||||||
|
static thread_local std::unique_ptr<pcre2_jit_stack_16, PcreJitStackFree> jitStacks;
|
||||||
Q_GLOBAL_STATIC(QThreadStorage<QPcreJitStackPointer *>, jitStacks)
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
static pcre2_jit_stack_16 *qtPcreCallback(void *)
|
static pcre2_jit_stack_16 *qtPcreCallback(void *)
|
||||||
{
|
{
|
||||||
if (jitStacks()->hasLocalData())
|
return jitStacks.get();
|
||||||
return jitStacks()->localData()->stack;
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1094,9 +1074,10 @@ static int safe_pcre2_match_16(const pcre2_code_16 *code,
|
|||||||
int result = pcre2_match_16(code, subject, length,
|
int result = pcre2_match_16(code, subject, length,
|
||||||
startOffset, options, matchData, matchContext);
|
startOffset, options, matchData, matchContext);
|
||||||
|
|
||||||
if (result == PCRE2_ERROR_JIT_STACKLIMIT && !jitStacks()->hasLocalData()) {
|
if (result == PCRE2_ERROR_JIT_STACKLIMIT && !jitStacks) {
|
||||||
QPcreJitStackPointer *p = new QPcreJitStackPointer;
|
// The default JIT stack size in PCRE is 32K,
|
||||||
jitStacks()->setLocalData(p);
|
// we allocate from 32K up to 512K.
|
||||||
|
jitStacks.reset(pcre2_jit_stack_create_16(32 * 1024, 512 * 1024, NULL));
|
||||||
|
|
||||||
result = pcre2_match_16(code, subject, length,
|
result = pcre2_match_16(code, subject, length,
|
||||||
startOffset, options, matchData, matchContext);
|
startOffset, options, matchData, matchContext);
|
||||||
|
Loading…
Reference in New Issue
Block a user