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