1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Copyright (C) 2012 Olivier Goffart <ogoffart@woboq.com>
6 ** Contact: https://www.qt.io/licensing/
7 **
8 ** This file is part of the QtCore module of the Qt Toolkit.
9 **
10 ** $QT_BEGIN_LICENSE:LGPL$
11 ** Commercial License Usage
12 ** Licensees holding valid commercial Qt licenses may use this file in
13 ** accordance with the commercial license agreement provided with the
14 ** Software or, alternatively, in accordance with the terms contained in
15 ** a written agreement between you and The Qt Company. For licensing terms
16 ** and conditions see https://www.qt.io/terms-conditions. For further
17 ** information use the contact form at https://www.qt.io/contact-us.
18 **
19 ** GNU Lesser General Public License Usage
20 ** Alternatively, this file may be used under the terms of the GNU Lesser
21 ** General Public License version 3 as published by the Free Software
22 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
23 ** packaging of this file. Please review the following information to
24 ** ensure the GNU Lesser General Public License version 3 requirements
25 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
26 **
27 ** GNU General Public License Usage
28 ** Alternatively, this file may be used under the terms of the GNU
29 ** General Public License version 2.0 or (at your option) the GNU General
30 ** Public license version 3 or any later version approved by the KDE Free
31 ** Qt Foundation. The licenses are as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
33 ** included in the packaging of this file. Please review the following
34 ** information to ensure the GNU General Public License requirements will
35 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
36 ** https://www.gnu.org/licenses/gpl-3.0.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qplatformdefs.h"
43 #include "qmutex.h"
44 #include <qdebug.h>
45 #include "qatomic.h"
46 #include "qelapsedtimer.h"
47 #include "qthread.h"
48 #include "qmutex_p.h"
49 
50 #ifndef QT_LINUX_FUTEX
51 #include "private/qfreelist_p.h"
52 #endif
53 
54 QT_BEGIN_NAMESPACE
55 
isRecursive(QMutexData * d)56 static inline bool isRecursive(QMutexData *d)
57 {
58     quintptr u = quintptr(d);
59     if (Q_LIKELY(u <= 0x3))
60         return false;
61 #ifdef QT_LINUX_FUTEX
62     Q_ASSERT(d->recursive);
63     return true;
64 #else
65     return d->recursive;
66 #endif
67 }
68 
69 class QRecursiveMutexPrivate : public QMutexData
70 {
71 public:
QRecursiveMutexPrivate()72     QRecursiveMutexPrivate()
73         : QMutexData(QMutex::Recursive), owner(nullptr), count(0) {}
74 
75     // written to by the thread that first owns 'mutex';
76     // read during attempts to acquire ownership of 'mutex' from any other thread:
77     QAtomicPointer<std::remove_pointer<Qt::HANDLE>::type> owner;
78 
79     // only ever accessed from the thread that owns 'mutex':
80     uint count;
81 
82     QMutex mutex;
83 
84     bool lock(int timeout) QT_MUTEX_LOCK_NOEXCEPT;
85     void unlock() noexcept;
86 };
87 
88 /*
89     \class QBasicMutex
90     \inmodule QtCore
91     \brief QMutex POD
92     \internal
93 
94     \ingroup thread
95 
96     - Can be used as global static object.
97     - Always non-recursive
98     - Do not use tryLock with timeout > 0, else you can have a leak (see the ~QMutex destructor)
99 */
100 
101 /*!
102     \class QMutex
103     \inmodule QtCore
104     \brief The QMutex class provides access serialization between threads.
105 
106     \threadsafe
107 
108     \ingroup thread
109 
110     The purpose of a QMutex is to protect an object, data structure or
111     section of code so that only one thread can access it at a time
112     (this is similar to the Java \c synchronized keyword). It is
113     usually best to use a mutex with a QMutexLocker since this makes
114     it easy to ensure that locking and unlocking are performed
115     consistently.
116 
117     For example, say there is a method that prints a message to the
118     user on two lines:
119 
120     \snippet code/src_corelib_thread_qmutex.cpp 0
121 
122     If these two methods are called in succession, the following happens:
123 
124     \snippet code/src_corelib_thread_qmutex.cpp 1
125 
126     If these two methods are called simultaneously from two threads then the
127     following sequence could result:
128 
129     \snippet code/src_corelib_thread_qmutex.cpp 2
130 
131     If we add a mutex, we should get the result we want:
132 
133     \snippet code/src_corelib_thread_qmutex.cpp 3
134 
135     Then only one thread can modify \c number at any given time and
136     the result is correct. This is a trivial example, of course, but
137     applies to any other case where things need to happen in a
138     particular sequence.
139 
140     When you call lock() in a thread, other threads that try to call
141     lock() in the same place will block until the thread that got the
142     lock calls unlock(). A non-blocking alternative to lock() is
143     tryLock().
144 
145     QMutex is optimized to be fast in the non-contended case. A non-recursive
146     QMutex will not allocate memory if there is no contention on that mutex.
147     It is constructed and destroyed with almost no overhead,
148     which means it is fine to have many mutexes as part of other classes.
149 
150     \sa QRecursiveMutex, QMutexLocker, QReadWriteLock, QSemaphore, QWaitCondition
151 */
152 
153 /*!
154     \enum QMutex::RecursionMode
155     \obsolete Use QRecursiveMutex to create a recursive mutex.
156 
157     \value Recursive  In this mode, a thread can lock the same mutex
158                       multiple times and the mutex won't be unlocked
159                       until a corresponding number of unlock() calls
160                       have been made. You should use QRecursiveMutex
161                       for this use-case.
162 
163     \value NonRecursive  In this mode, a thread may only lock a mutex
164                          once.
165 
166     \sa QMutex(), QRecursiveMutex
167 */
168 
169 /*!
170     \fn QMutex::QMutex()
171 
172     Constructs a new mutex. The mutex is created in an unlocked state.
173 */
174 
175 /*!
176     Constructs a new mutex. The mutex is created in an unlocked state.
177     \obsolete Use QRecursiveMutex to create a recursive mutex.
178 
179     If \a mode is QMutex::Recursive, a thread can lock the same mutex
180     multiple times and the mutex won't be unlocked until a
181     corresponding number of unlock() calls have been made. Otherwise
182     a thread may only lock a mutex once. The default is
183     QMutex::NonRecursive.
184 
185     Recursive mutexes are slower and take more memory than non-recursive ones.
186 
187     \sa lock(), unlock()
188 */
QMutex(RecursionMode mode)189 QMutex::QMutex(RecursionMode mode)
190 {
191     d_ptr.storeRelaxed(mode == Recursive ? new QRecursiveMutexPrivate : nullptr);
192 }
193 
194 /*!
195     Destroys the mutex.
196 
197     \warning Destroying a locked mutex may result in undefined behavior.
198 */
~QMutex()199 QMutex::~QMutex()
200 {
201     QMutexData *d = d_ptr.loadRelaxed();
202     if (QBasicMutex::isRecursive()) {
203         delete static_cast<QRecursiveMutexPrivate *>(d);
204     } else if (d) {
205 #ifndef QT_LINUX_FUTEX
206         if (d != dummyLocked() && static_cast<QMutexPrivate *>(d)->possiblyUnlocked.loadRelaxed()
207             && tryLock()) {
208             unlock();
209             return;
210         }
211 #endif
212         qWarning("QMutex: destroying locked mutex");
213     }
214 }
215 
216 /*! \fn void QMutex::lock()
217 
218     Locks the mutex. If another thread has locked the mutex then this
219     call will block until that thread has unlocked it.
220 
221     Calling this function multiple times on the same mutex from the
222     same thread is allowed if this mutex is a
223     \l{QRecursiveMutex}{recursive mutex}. If this mutex is a
224     \l{QMutex}{non-recursive mutex}, this function will
225     \e dead-lock when the mutex is locked recursively.
226 
227     \sa unlock()
228 */
lock()229 void QMutex::lock() QT_MUTEX_LOCK_NOEXCEPT
230 {
231     QMutexData *current;
232     if (fastTryLock(current))
233         return;
234     if (QT_PREPEND_NAMESPACE(isRecursive)(current))
235         static_cast<QRecursiveMutexPrivate *>(current)->lock(-1);
236     else
237         lockInternal();
238 }
239 
240 /*! \fn bool QMutex::tryLock(int timeout)
241 
242     Attempts to lock the mutex. This function returns \c true if the lock
243     was obtained; otherwise it returns \c false. If another thread has
244     locked the mutex, this function will wait for at most \a timeout
245     milliseconds for the mutex to become available.
246 
247     Note: Passing a negative number as the \a timeout is equivalent to
248     calling lock(), i.e. this function will wait forever until mutex
249     can be locked if \a timeout is negative.
250 
251     If the lock was obtained, the mutex must be unlocked with unlock()
252     before another thread can successfully lock it.
253 
254     Calling this function multiple times on the same mutex from the
255     same thread is allowed if this mutex is a
256     \l{QRecursiveMutex}{recursive mutex}. If this mutex is a
257     \l{QMutex}{non-recursive mutex}, this function will
258     \e always return false when attempting to lock the mutex
259     recursively.
260 
261     \sa lock(), unlock()
262 */
tryLock(int timeout)263 bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
264 {
265     QMutexData *current;
266     if (fastTryLock(current))
267         return true;
268     if (QT_PREPEND_NAMESPACE(isRecursive)(current))
269         return static_cast<QRecursiveMutexPrivate *>(current)->lock(timeout);
270     else
271         return lockInternal(timeout);
272 }
273 
274 /*! \fn bool QMutex::try_lock()
275     \since 5.8
276 
277     Attempts to lock the mutex. This function returns \c true if the lock
278     was obtained; otherwise it returns \c false.
279 
280     This function is provided for compatibility with the Standard Library
281     concept \c Lockable. It is equivalent to tryLock().
282 
283     The function returns \c true if the lock was obtained; otherwise it
284     returns \c false
285 */
286 
287 /*! \fn template <class Rep, class Period> bool QMutex::try_lock_for(std::chrono::duration<Rep, Period> duration)
288     \since 5.8
289 
290     Attempts to lock the mutex. This function returns \c true if the lock
291     was obtained; otherwise it returns \c false. If another thread has
292     locked the mutex, this function will wait for at least \a duration
293     for the mutex to become available.
294 
295     Note: Passing a negative duration as the \a duration is equivalent to
296     calling try_lock(). This behavior differs from tryLock().
297 
298     If the lock was obtained, the mutex must be unlocked with unlock()
299     before another thread can successfully lock it.
300 
301     Calling this function multiple times on the same mutex from the
302     same thread is allowed if this mutex is a
303     \l{QRecursiveMutex}{recursive mutex}. If this mutex is a
304     \l{QMutex}{non-recursive mutex}, this function will
305     \e always return false when attempting to lock the mutex
306     recursively.
307 
308     \sa lock(), unlock()
309 */
310 
311 /*! \fn template<class Clock, class Duration> bool QMutex::try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
312     \since 5.8
313 
314     Attempts to lock the mutex. This function returns \c true if the lock
315     was obtained; otherwise it returns \c false. If another thread has
316     locked the mutex, this function will wait at least until \a timePoint
317     for the mutex to become available.
318 
319     Note: Passing a \a timePoint which has already passed is equivalent
320     to calling try_lock(). This behavior differs from tryLock().
321 
322     If the lock was obtained, the mutex must be unlocked with unlock()
323     before another thread can successfully lock it.
324 
325     Calling this function multiple times on the same mutex from the
326     same thread is allowed if this mutex is a
327     \l{QRecursiveMutex}{recursive mutex}. If this mutex is a
328     \l{QMutex}{non-recursive mutex}, this function will
329     \e always return false when attempting to lock the mutex
330     recursively.
331 
332     \sa lock(), unlock()
333 */
334 
335 /*! \fn void QMutex::unlock()
336 
337     Unlocks the mutex. Attempting to unlock a mutex in a different
338     thread to the one that locked it results in an error. Unlocking a
339     mutex that is not locked results in undefined behavior.
340 
341     \sa lock()
342 */
unlock()343 void QMutex::unlock() noexcept
344 {
345     QMutexData *current;
346     if (fastTryUnlock(current))
347         return;
348     if (QT_PREPEND_NAMESPACE(isRecursive)(current))
349         static_cast<QRecursiveMutexPrivate *>(current)->unlock();
350     else
351         unlockInternal();
352 }
353 
354 
355 /*!
356     \fn bool QMutex::isRecursive() const
357     \since 5.7
358 
359     Returns \c true if the mutex is recursive.
360 */
361 
isRecursive()362 bool QBasicMutex::isRecursive() noexcept
363 {
364     return QT_PREPEND_NAMESPACE(isRecursive)(d_ptr.loadAcquire());
365 }
366 
367 /*!
368     \since 5.7
369 
370     Returns \c true if the mutex is recursive.
371 */
isRecursive() const372 bool QBasicMutex::isRecursive() const noexcept
373 {
374     return QT_PREPEND_NAMESPACE(isRecursive)(d_ptr.loadAcquire());
375 }
376 
377 /*!
378     \class QRecursiveMutex
379     \inmodule QtCore
380     \since 5.14
381     \brief The QRecursiveMutex class provides access serialization between threads.
382 
383     \threadsafe
384 
385     \ingroup thread
386 
387     The QRecursiveMutex class is a mutex, like QMutex, with which it is
388     API-compatible. It differs from QMutex by accepting lock() calls from
389     the same thread any number of times. QMutex would deadlock in this situation.
390 
391     QRecursiveMutex is much more expensive to construct and operate on, so
392     use a plain QMutex whenever you can. Sometimes, one public function,
393     however, calls another public function, and they both need to lock the
394     same mutex. In this case, you have two options:
395 
396     \list
397     \li Factor the code that needs mutex protection into private functions,
398     which assume that the mutex is held when they are called, and lock a
399     plain QMutex in the public functions before you call the private
400     implementation ones.
401     \li Or use a recursive mutex, so it doesn't matter that the first public
402     function has already locked the mutex when the second one wishes to do so.
403     \endlist
404 
405     \sa QMutex, QMutexLocker, QReadWriteLock, QSemaphore, QWaitCondition
406 */
407 
408 /*!
409     Constructs a new recursive mutex. The mutex is created in an unlocked state.
410 
411     \sa lock(), unlock()
412 */
QRecursiveMutex()413 QRecursiveMutex::QRecursiveMutex()
414     : QMutex()
415 {
416     d_ptr.storeRelaxed(new QRecursiveMutexPrivate);
417 }
418 
419 /*!
420     Destroys the mutex.
421 
422     \warning Destroying a locked mutex may result in undefined behavior.
423 */
~QRecursiveMutex()424 QRecursiveMutex::~QRecursiveMutex()
425 {
426     delete static_cast<QRecursiveMutexPrivate*>(d_ptr.fetchAndStoreAcquire(nullptr));
427 }
428 
429 /*!
430     \class QMutexLocker
431     \inmodule QtCore
432     \brief The QMutexLocker class is a convenience class that simplifies
433     locking and unlocking mutexes.
434 
435     \threadsafe
436 
437     \ingroup thread
438 
439     Locking and unlocking a QMutex in complex functions and
440     statements or in exception handling code is error-prone and
441     difficult to debug. QMutexLocker can be used in such situations
442     to ensure that the state of the mutex is always well-defined.
443 
444     QMutexLocker should be created within a function where a
445     QMutex needs to be locked. The mutex is locked when QMutexLocker
446     is created. You can unlock and relock the mutex with \c unlock()
447     and \c relock(). If locked, the mutex will be unlocked when the
448     QMutexLocker is destroyed.
449 
450     For example, this complex function locks a QMutex upon entering
451     the function and unlocks the mutex at all the exit points:
452 
453     \snippet code/src_corelib_thread_qmutex.cpp 4
454 
455     This example function will get more complicated as it is
456     developed, which increases the likelihood that errors will occur.
457 
458     Using QMutexLocker greatly simplifies the code, and makes it more
459     readable:
460 
461     \snippet code/src_corelib_thread_qmutex.cpp 5
462 
463     Now, the mutex will always be unlocked when the QMutexLocker
464     object is destroyed (when the function returns since \c locker is
465     an auto variable).
466 
467     The same principle applies to code that throws and catches
468     exceptions. An exception that is not caught in the function that
469     has locked the mutex has no way of unlocking the mutex before the
470     exception is passed up the stack to the calling function.
471 
472     QMutexLocker also provides a \c mutex() member function that returns
473     the mutex on which the QMutexLocker is operating. This is useful
474     for code that needs access to the mutex, such as
475     QWaitCondition::wait(). For example:
476 
477     \snippet code/src_corelib_thread_qmutex.cpp 6
478 
479     \sa QReadLocker, QWriteLocker, QMutex
480 */
481 
482 /*!
483     \fn QMutexLocker::QMutexLocker(QMutex *mutex)
484 
485     Constructs a QMutexLocker and locks \a mutex. The mutex will be
486     unlocked when the QMutexLocker is destroyed. If \a mutex is \nullptr,
487     QMutexLocker does nothing.
488 
489     \sa QMutex::lock()
490 */
491 
492 /*!
493     \fn QMutexLocker::QMutexLocker(QRecursiveMutex *mutex)
494     \since 5.14
495 
496     Constructs a QMutexLocker and locks \a mutex. The mutex will be
497     unlocked (unlock() called) when the QMutexLocker is destroyed.
498     If \a mutex is \nullptr, QMutexLocker does nothing.
499 
500     \sa QMutex::lock()
501 */
502 
503 /*!
504     \fn QMutexLocker::~QMutexLocker()
505 
506     Destroys the QMutexLocker and unlocks the mutex that was locked
507     in the constructor.
508 
509     \sa QMutex::unlock()
510 */
511 
512 /*!
513     \fn void QMutexLocker::unlock()
514 
515     Unlocks this mutex locker. You can use \c relock() to lock
516     it again. It does not need to be locked when destroyed.
517 
518     \sa relock()
519 */
520 
521 /*!
522     \fn void QMutexLocker::relock()
523 
524     Relocks an unlocked mutex locker.
525 
526     \sa unlock()
527 */
528 
529 /*!
530     \fn QMutex *QMutexLocker::mutex() const
531 
532     Returns the mutex on which the QMutexLocker is operating.
533 
534 */
535 
536 #ifndef QT_LINUX_FUTEX //linux implementation is in qmutex_linux.cpp
537 
538 /*
539   For a rough introduction on how this works, refer to
540   http://woboq.com/blog/internals-of-qmutex-in-qt5.html
541   which explains a slightly simplified version of it.
542   The differences are that here we try to work with timeout (requires the
543   possiblyUnlocked flag) and that we only wake one thread when unlocking
544   (requires maintaining the waiters count)
545   We also support recursive mutexes which always have a valid d_ptr.
546 
547   The waiters flag represents the number of threads that are waiting or about
548   to wait on the mutex. There are two tricks to keep in mind:
549   We don't want to increment waiters after we checked no threads are waiting
550   (waiters == 0). That's why we atomically set the BigNumber flag on waiters when
551   we check waiters. Similarly, if waiters is decremented right after we checked,
552   the mutex would be unlocked (d->wakeUp() has (or will) be called), but there is
553   no thread waiting. This is only happening if there was a timeout in tryLock at the
554   same time as the mutex is unlocked. So when there was a timeout, we set the
555   possiblyUnlocked flag.
556 */
557 
558 /*!
559     \internal helper for lock()
560  */
lockInternal()561 void QBasicMutex::lockInternal() QT_MUTEX_LOCK_NOEXCEPT
562 {
563     lockInternal(-1);
564 }
565 
566 /*!
567     \internal helper for lock(int)
568  */
lockInternal(int timeout)569 bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
570 {
571     Q_ASSERT(!isRecursive());
572 
573     while (!fastTryLock()) {
574         QMutexData *copy = d_ptr.loadAcquire();
575         if (!copy) // if d is 0, the mutex is unlocked
576             continue;
577 
578         if (copy == dummyLocked()) {
579             if (timeout == 0)
580                 return false;
581             // The mutex is locked but does not have a QMutexPrivate yet.
582             // we need to allocate a QMutexPrivate
583             QMutexPrivate *newD = QMutexPrivate::allocate();
584             if (!d_ptr.testAndSetOrdered(dummyLocked(), newD)) {
585                 //Either the mutex is already unlocked, or another thread already set it.
586                 newD->deref();
587                 continue;
588             }
589             copy = newD;
590             //the d->refCount is already 1 the deref will occurs when we unlock
591         }
592 
593         QMutexPrivate *d = static_cast<QMutexPrivate *>(copy);
594         if (timeout == 0 && !d->possiblyUnlocked.loadRelaxed())
595             return false;
596 
597         // At this point we have a pointer to a QMutexPrivate. But the other thread
598         // may unlock the mutex at any moment and release the QMutexPrivate to the pool.
599         // We will try to reference it to avoid unlock to release it to the pool to make
600         // sure it won't be released. But if the refcount is already 0 it has been released.
601         if (!d->ref())
602             continue; //that QMutexData was already released
603 
604         // We now hold a reference to the QMutexPrivate. It won't be released and re-used.
605         // But it is still possible that it was already re-used by another QMutex right before
606         // we did the ref(). So check if we still hold a pointer to the right mutex.
607         if (d != d_ptr.loadAcquire()) {
608             //Either the mutex is already unlocked, or relocked with another mutex
609             d->deref();
610             continue;
611         }
612 
613         // In this part, we will try to increment the waiters count.
614         // We just need to take care of the case in which the old_waiters
615         // is set to the BigNumber magic value set in unlockInternal()
616         int old_waiters;
617         do {
618             old_waiters = d->waiters.loadAcquire();
619             if (old_waiters == -QMutexPrivate::BigNumber) {
620                 // we are unlocking, and the thread that unlocks is about to change d to 0
621                 // we try to acquire the mutex by changing to dummyLocked()
622                 if (d_ptr.testAndSetAcquire(d, dummyLocked())) {
623                     // Mutex acquired
624                     d->deref();
625                     return true;
626                 } else {
627                     Q_ASSERT(d != d_ptr.loadRelaxed()); //else testAndSetAcquire should have succeeded
628                     // Mutex is likely to bo 0, we should continue the outer-loop,
629                     //  set old_waiters to the magic value of BigNumber
630                     old_waiters = QMutexPrivate::BigNumber;
631                     break;
632                 }
633             }
634         } while (!d->waiters.testAndSetRelaxed(old_waiters, old_waiters + 1));
635 
636         if (d != d_ptr.loadAcquire()) {
637             // The mutex was unlocked before we incremented waiters.
638             if (old_waiters != QMutexPrivate::BigNumber) {
639                 //we did not break the previous loop
640                 Q_ASSERT(d->waiters.loadRelaxed() >= 1);
641                 d->waiters.deref();
642             }
643             d->deref();
644             continue;
645         }
646 
647         if (d->wait(timeout)) {
648             // reset the possiblyUnlocked flag if needed (and deref its corresponding reference)
649             if (d->possiblyUnlocked.loadRelaxed() && d->possiblyUnlocked.testAndSetRelaxed(true, false))
650                 d->deref();
651             d->derefWaiters(1);
652             //we got the lock. (do not deref)
653             Q_ASSERT(d == d_ptr.loadRelaxed());
654             return true;
655         } else {
656             Q_ASSERT(timeout >= 0);
657             //timeout
658             d->derefWaiters(1);
659             //There may be a race in which the mutex is unlocked right after we timed out,
660             // and before we deref the waiters, so maybe the mutex is actually unlocked.
661             // Set the possiblyUnlocked flag to indicate this possibility.
662             if (!d->possiblyUnlocked.testAndSetRelaxed(false, true)) {
663                 // We keep a reference when possiblyUnlocked is true.
664                 // but if possiblyUnlocked was already true, we don't need to keep the reference.
665                 d->deref();
666             }
667             return false;
668         }
669     }
670     Q_ASSERT(d_ptr.loadRelaxed() != 0);
671     return true;
672 }
673 
674 /*!
675     \internal
676 */
unlockInternal()677 void QBasicMutex::unlockInternal() noexcept
678 {
679     QMutexData *copy = d_ptr.loadAcquire();
680     Q_ASSERT(copy); //we must be locked
681     Q_ASSERT(copy != dummyLocked()); // testAndSetRelease(dummyLocked(), 0) failed
682     Q_ASSERT(!isRecursive());
683 
684     QMutexPrivate *d = reinterpret_cast<QMutexPrivate *>(copy);
685 
686     // If no one is waiting for the lock anymore, we should reset d to 0x0.
687     // Using fetchAndAdd, we atomically check that waiters was equal to 0, and add a flag
688     // to the waiters variable (BigNumber). That way, we avoid the race in which waiters is
689     // incremented right after we checked, because we won't increment waiters if is
690     // equal to -BigNumber
691     if (d->waiters.fetchAndAddRelease(-QMutexPrivate::BigNumber) == 0) {
692         //there is no one waiting on this mutex anymore, set the mutex as unlocked (d = 0)
693         if (d_ptr.testAndSetRelease(d, 0)) {
694             // reset the possiblyUnlocked flag if needed (and deref its corresponding reference)
695             if (d->possiblyUnlocked.loadRelaxed() && d->possiblyUnlocked.testAndSetRelaxed(true, false))
696                 d->deref();
697         }
698         d->derefWaiters(0);
699     } else {
700         d->derefWaiters(0);
701         //there are thread waiting, transfer the lock.
702         d->wakeUp();
703     }
704     d->deref();
705 }
706 
707 //The freelist management
708 namespace {
709 struct FreeListConstants : QFreeListDefaultConstants {
710     enum { BlockCount = 4, MaxIndex=0xffff };
711     static const int Sizes[BlockCount];
712 };
713 const int FreeListConstants::Sizes[FreeListConstants::BlockCount] = {
714     16,
715     128,
716     1024,
717     FreeListConstants::MaxIndex - (16 + 128 + 1024)
718 };
719 
720 typedef QFreeList<QMutexPrivate, FreeListConstants> FreeList;
721 // We cannot use Q_GLOBAL_STATIC because it uses QMutex
722 static FreeList freeList_;
freelist()723 FreeList *freelist()
724 {
725     return &freeList_;
726 }
727 }
728 
allocate()729 QMutexPrivate *QMutexPrivate::allocate()
730 {
731     int i = freelist()->next();
732     QMutexPrivate *d = &(*freelist())[i];
733     d->id = i;
734     Q_ASSERT(d->refCount.loadRelaxed() == 0);
735     Q_ASSERT(!d->recursive);
736     Q_ASSERT(!d->possiblyUnlocked.loadRelaxed());
737     Q_ASSERT(d->waiters.loadRelaxed() == 0);
738     d->refCount.storeRelaxed(1);
739     return d;
740 }
741 
release()742 void QMutexPrivate::release()
743 {
744     Q_ASSERT(!recursive);
745     Q_ASSERT(refCount.loadRelaxed() == 0);
746     Q_ASSERT(!possiblyUnlocked.loadRelaxed());
747     Q_ASSERT(waiters.loadRelaxed() == 0);
748     freelist()->release(id);
749 }
750 
751 // atomically subtract "value" to the waiters, and remove the QMutexPrivate::BigNumber flag
derefWaiters(int value)752 void QMutexPrivate::derefWaiters(int value) noexcept
753 {
754     int old_waiters;
755     int new_waiters;
756     do {
757         old_waiters = waiters.loadRelaxed();
758         new_waiters = old_waiters;
759         if (new_waiters < 0) {
760             new_waiters += QMutexPrivate::BigNumber;
761         }
762         new_waiters -= value;
763     } while (!waiters.testAndSetRelaxed(old_waiters, new_waiters));
764 }
765 #endif
766 
767 /*!
768    \internal
769  */
lock(int timeout)770 inline bool QRecursiveMutexPrivate::lock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
771 {
772     Qt::HANDLE self = QThread::currentThreadId();
773     if (owner.loadRelaxed() == self) {
774         ++count;
775         Q_ASSERT_X(count != 0, "QMutex::lock", "Overflow in recursion counter");
776         return true;
777     }
778     bool success = true;
779     if (timeout == -1) {
780         mutex.QBasicMutex::lock();
781     } else {
782         success = mutex.tryLock(timeout);
783     }
784 
785     if (success)
786         owner.storeRelaxed(self);
787     return success;
788 }
789 
790 /*!
791    \internal
792  */
unlock()793 inline void QRecursiveMutexPrivate::unlock() noexcept
794 {
795     if (count > 0) {
796         count--;
797     } else {
798         owner.storeRelaxed(nullptr);
799         mutex.QBasicMutex::unlock();
800     }
801 }
802 
803 QT_END_NAMESPACE
804 
805 #ifdef QT_LINUX_FUTEX
806 #  include "qmutex_linux.cpp"
807 #elif defined(Q_OS_MAC)
808 #  include "qmutex_mac.cpp"
809 #elif defined(Q_OS_WIN)
810 #  include "qmutex_win.cpp"
811 #else
812 #  include "qmutex_unix.cpp"
813 #endif
814