Warning, file /graphics/krita/libs/image/3rdparty/lock_free_map/simple_job_coordinator.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*------------------------------------------------------------------------
0002   Junction: Concurrent data structures in C++
0003   Copyright (c) 2016 Jeff Preshing
0004   Distributed under the Simplified BSD License.
0005   Original location: https://github.com/preshing/junction
0006   This software is distributed WITHOUT ANY WARRANTY; without even the
0007   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
0008   See the LICENSE file for more information.
0009 ------------------------------------------------------------------------*/
0010 
0011 #ifndef SIMPLEJOBCOORDINATOR_H
0012 #define SIMPLEJOBCOORDINATOR_H
0013 
0014 #include <QMutex>
0015 #include <QWaitCondition>
0016 #include <QMutexLocker>
0017 
0018 #include "kis_assert.h"
0019 #include "atomic.h"
0020 
0021 #define SANITY_CHECK
0022 
0023 class SimpleJobCoordinator
0024 {
0025 public:
0026     struct Job {
0027         virtual ~Job()
0028         {
0029         }
0030 
0031         virtual void run() = 0;
0032     };
0033 
0034 private:
0035     Atomic<quint64> m_job;
0036     QMutex mutex;
0037     QWaitCondition condVar;
0038 
0039 public:
0040     SimpleJobCoordinator() : m_job(quint64(NULL))
0041     {
0042     }
0043 
0044     Job* loadConsume() const
0045     {
0046         return (Job*) m_job.load(Consume);
0047     }
0048 
0049     void storeRelease(Job* job)
0050     {
0051         {
0052             QMutexLocker guard(&mutex);
0053             m_job.store(quint64(job), Release);
0054         }
0055 
0056         condVar.wakeAll();
0057     }
0058 
0059     void participate()
0060     {
0061         quint64 prevJob = quint64(NULL);
0062 
0063         for (;;) {
0064             quint64 job = m_job.load(Consume);
0065             if (job == prevJob) {
0066                 QMutexLocker guard(&mutex);
0067 
0068                 for (;;) {
0069                     job = m_job.loadNonatomic(); // No concurrent writes inside lock
0070                     if (job != prevJob) {
0071                         break;
0072                     }
0073 
0074                     condVar.wait(&mutex);
0075                 }
0076             }
0077 
0078             if (job == 1) {
0079                 return;
0080             }
0081 
0082             reinterpret_cast<Job*>(job)->run();
0083             prevJob = job;
0084         }
0085     }
0086 
0087     void runOne(Job* job)
0088     {
0089 #ifdef SANITY_CHECK
0090         KIS_ASSERT_RECOVER_NOOP(job != (Job*) m_job.load(Relaxed));
0091 #endif // SANITY_CHECK
0092         storeRelease(job);
0093         job->run();
0094     }
0095 
0096     void end()
0097     {
0098         {
0099             QMutexLocker guard(&mutex);
0100             m_job.store(1, Release);
0101         }
0102 
0103         condVar.wakeAll();
0104     }
0105 };
0106 
0107 #endif // SIMPLEJOBCOORDINATOR_H