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 */