File indexing completed on 2024-05-12 15:58:26
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef __KIS_LOCK_FREE_LOD_COUNTER_H 0008 #define __KIS_LOCK_FREE_LOD_COUNTER_H 0009 0010 #include <QAtomicInt> 0011 0012 0013 class KisLockFreeLodCounter 0014 { 0015 public: 0016 void addLod(int newLod) { 0017 int oldValue = 0; 0018 int newValue = 0; 0019 0020 do { 0021 oldValue = m_num; 0022 0023 int counter; 0024 int lod; 0025 unpackLod(oldValue, &counter, &lod); 0026 0027 if (!counter) { 0028 lod = newLod; 0029 } else { 0030 Q_ASSERT(lod == newLod); 0031 } 0032 0033 counter++; 0034 newValue = packLod(counter, lod); 0035 } while(!m_num.testAndSetOrdered(oldValue, newValue)); 0036 } 0037 0038 void removeLod() { 0039 int oldValue = 0; 0040 int newValue = 0; 0041 0042 do { 0043 oldValue = m_num; 0044 0045 int counter; 0046 int lod; 0047 unpackLod(oldValue, &counter, &lod); 0048 0049 Q_ASSERT(counter > 0); 0050 0051 counter--; 0052 newValue = packLod(counter, lod); 0053 } while(!m_num.testAndSetOrdered(oldValue, newValue)); 0054 } 0055 0056 int readLod() const { 0057 int value = m_num; 0058 0059 int counter; 0060 int lod; 0061 unpackLod(value, &counter, &lod); 0062 0063 return counter ? lod : -1; 0064 } 0065 0066 void testingClear() { 0067 m_num = 0; 0068 } 0069 0070 private: 0071 static inline int packLod(int counter, int lod) { 0072 return (counter << 8) | (lod & 0xFF); 0073 } 0074 0075 static inline void unpackLod(int value, int *counter, int *lod) { 0076 *lod = value & 0xFF; 0077 *counter = value >> 8; 0078 } 0079 0080 private: 0081 QAtomicInt m_num; 0082 }; 0083 0084 #endif /* __KIS_LOCK_FREE_LOD_COUNTER_H */