File indexing completed on 2024-06-23 04:22:04

0001 /*
0002  *  SPDX-FileCopyrightText: 2009 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #ifndef KIS_TILE_DATA_POOLER_H_
0007 #define KIS_TILE_DATA_POOLER_H_
0008 
0009 #include <QObject>
0010 #include <QThread>
0011 #include <QSemaphore>
0012 
0013 #include "kritaimage_export.h"
0014 
0015 class KisTileDataStore;
0016 class KisTileData;
0017 
0018 
0019 class KRITAIMAGE_EXPORT KisTileDataPooler : public QThread
0020 {
0021     Q_OBJECT
0022 
0023 public:
0024 
0025     KisTileDataPooler(KisTileDataStore *store, qint32 memoryLimit = -1);
0026     ~KisTileDataPooler() override;
0027 
0028     void kick();
0029     void terminatePooler();
0030 
0031     void testingRereadConfig();
0032 
0033     qint64 lastPoolMemoryMetric() const;
0034     qint64 lastRealMemoryMetric() const;
0035     qint64 lastHistoricalMemoryMetric() const;
0036 
0037 
0038     /**
0039      * Is case the pooler thread is not running, the user might force
0040      * recalculation of the memory statistics explicitly.
0041      */
0042     void forceUpdateMemoryStats();
0043 
0044 protected:
0045     static const qint32 MAX_NUM_CLONES;
0046     static const qint32 MAX_TIMEOUT;
0047     static const qint32 MIN_TIMEOUT;
0048     static const qint32 TIMEOUT_FACTOR;
0049 
0050     void waitForWork();
0051     qint32 numClonesNeeded(KisTileData *td) const;
0052     void cloneTileData(KisTileData *td, qint32 numClones) const;
0053     void run() override;
0054 
0055     inline int clonesMetric(KisTileData *td, int numClones);
0056     inline int clonesMetric(KisTileData *td);
0057 
0058     inline void tryFreeOrphanedClones(KisTileData *td);
0059     inline qint32 needMemory(KisTileData *td);
0060     inline qint32 canDonorMemory(KisTileData *td);
0061     qint32 tryGetMemory(QList<KisTileData*> &donors, qint32 memoryMetric);
0062 
0063     template<class Iter>
0064         void getLists(Iter *iter, QList<KisTileData*> &beggars,
0065                       QList<KisTileData*> &donors,
0066                       qint32 &memoryOccupied,
0067                       qint32 &statRealMemory,
0068                       qint32 &statHistoricalMemory);
0069 
0070     bool processLists(QList<KisTileData*> &beggars,
0071                       QList<KisTileData*> &donors,
0072                       qint32 &memoryOccupied);
0073 
0074 private:
0075     void debugTileStatistics();
0076 protected:
0077     QSemaphore m_semaphore;
0078     QAtomicInt m_shouldExitFlag;
0079     KisTileDataStore *m_store;
0080     qint32 m_timeout;
0081     bool m_lastCycleHadWork;
0082     qint32 m_memoryLimit;
0083     qint32 m_lastPoolMemoryMetric;
0084     qint32 m_lastRealMemoryMetric;
0085     qint32 m_lastHistoricalMemoryMetric;
0086 };
0087 
0088 
0089 
0090 #endif /* KIS_TILE_DATA_POOLER_H_ */
0091