diff options
Diffstat (limited to 'src/corelib/kernel/qabstracteventdispatcher.cpp')
-rw-r--r-- | src/corelib/kernel/qabstracteventdispatcher.cpp | 67 |
1 files changed, 51 insertions, 16 deletions
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index e79f87a2fa..2949cd0d3a 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -49,22 +49,51 @@ QT_BEGIN_NAMESPACE // we allow for 2^24 = 8^8 = 16777216 simultaneously running timers -enum { NumberOfBuckets = 8, FirstBucketSize = 8 }; - -static const int BucketSize[NumberOfBuckets] = - { 8, 64, 512, 4096, 32768, 262144, 2097152, 16777216 - 2396744 }; -static const int BucketOffset[NumberOfBuckets] = - { 0, 8, 72, 584, 4680, 37448, 299592, 2396744 }; - -static int FirstBucket[FirstBucketSize] = { 1, 2, 3, 4, 5, 6, 7, 8 }; -static QBasicAtomicPointer<int> timerIds[NumberOfBuckets] = +static const int TimerIdMask = 0x00ffffff; +static const int TimerSerialMask = ~TimerIdMask & ~0x80000000; +static const int TimerSerialCounter = TimerIdMask + 1; +static const int MaxTimerId = TimerIdMask; + +static int FirstBucket[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 +}; + +enum { + FirstBucketOffset = 0, + SecondBucketOffset = sizeof(FirstBucket) / sizeof(FirstBucket[0]), + ThirdBucketOffset = 0x100, + FourthBucketOffset = 0x1000, + FifthBucketOffset = 0x10000, + SixthBucketOffset = 0x100000 +}; + +enum { + FirstBucketSize = SecondBucketOffset, + SecondBucketSize = ThirdBucketOffset - SecondBucketOffset, + ThirdBucketSize = FourthBucketOffset - ThirdBucketOffset, + FourthBucketSize = FifthBucketOffset - FourthBucketOffset, + FifthBucketSize = SixthBucketOffset - FifthBucketOffset, + SixthBucketSize = MaxTimerId - SixthBucketOffset +}; + +static const int BucketSize[] = { + FirstBucketSize, SecondBucketSize, ThirdBucketSize, + FourthBucketSize, FifthBucketSize, SixthBucketSize +}; +enum { NumberOfBuckets = sizeof(BucketSize) / sizeof(BucketSize[0]) }; + +static const int BucketOffset[] = { + FirstBucketOffset, SecondBucketOffset, ThirdBucketOffset, + FourthBucketOffset, FifthBucketOffset, SixthBucketOffset +}; + +static QBasicAtomicPointer<int> timerIds[] = { Q_BASIC_ATOMIC_INITIALIZER(FirstBucket), Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0), - Q_BASIC_ATOMIC_INITIALIZER(0), - Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0) }; static void timerIdsDestructorFunction() @@ -77,18 +106,23 @@ Q_DESTRUCTOR_FUNCTION(timerIdsDestructorFunction) static QBasicAtomicInt nextFreeTimerId = Q_BASIC_ATOMIC_INITIALIZER(1); -static const int TimerIdMask = 0x00ffffff; -static const int TimerSerialMask = ~TimerIdMask & ~0x80000000; -static const int TimerSerialCounter = TimerIdMask + 1; - // avoid the ABA-problem by using 7 of the top 8 bits of the timerId as a serial number static inline int prepareNewValueWithSerialNumber(int oldId, int newId) { return (newId & TimerIdMask) | ((oldId + TimerSerialCounter) & TimerSerialMask); } +namespace { + template<bool> struct QStaticAssertType; + template<> struct QStaticAssertType<true> { enum { Value = 1 }; }; +} +#define q_static_assert(expr) (void)QStaticAssertType<expr>::Value + static inline int bucketOffset(int timerId) { + q_static_assert(sizeof BucketSize == sizeof BucketOffset); + q_static_assert(sizeof(timerIds) / sizeof(timerIds[0]) == NumberOfBuckets); + for (int i = 0; i < NumberOfBuckets; ++i) { if (timerId < BucketSize[i]) return i; @@ -187,7 +221,8 @@ void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) int at = bucketIndex(bucket, which); int *b = timerIds[bucket]; - Q_ASSERT(b[at] == -timerId); + Q_ASSERT_X(timerId == -b[at], "QAbstractEventDispatcher::releaseTimerId", + "Internal error: timer ID not found"); int freeId, newTimerId; do { |