Line data Source code
1 : /////////////////////////////////////////////////////////////////////////// 2 : // Spetabaru - Berenger Bramas MPCDF - 2017 3 : // Under LGPL Licence, please you must read the LICENCE file. 4 : /////////////////////////////////////////////////////////////////////////// 5 : #ifndef SPHEAPBUFFER_HPP 6 : #define SPHEAPBUFFER_HPP 7 : 8 : #include <atomic> 9 : #include <mutex> 10 : #include <limits> 11 : 12 : #include "SpAbstractBufferManager.hpp" 13 : #include "SpBufferDataView.hpp" 14 : #include "Utils/small_vector.hpp" 15 : 16 : template <class TargetType> 17 : class SpHeapBuffer : public SpAbstractBufferManager<TargetType> { 18 : const long int softLimiteOfNbBuffers; 19 : small_vector<TargetType*> availableBuffers; 20 : std::mutex availableBuffersMutex; 21 : std::atomic<long int> nbBuffersUnderUse; 22 : 23 : public: 24 2 : explicit SpHeapBuffer(const long int inSoftLimuiteOfNbBuffers = std::numeric_limits<long int>::max()) 25 2 : : softLimiteOfNbBuffers(inSoftLimuiteOfNbBuffers), nbBuffersUnderUse(0){ 26 2 : } 27 : 28 : SpHeapBuffer(const SpHeapBuffer&) = delete; 29 : SpHeapBuffer(SpHeapBuffer&& other) = delete; 30 : SpHeapBuffer& operator=(const SpHeapBuffer&) = delete; 31 : SpHeapBuffer& operator=(SpHeapBuffer&&) = delete; 32 : 33 2 : ~SpHeapBuffer(){ 34 2 : assert(nbBuffersUnderUse == 0); 35 4 : while(availableBuffers.size()){ 36 2 : delete availableBuffers.back(); 37 2 : availableBuffers.pop_back(); 38 : } 39 4 : } 40 : 41 102 : SpBufferDataView<TargetType> getNewBuffer(){ 42 102 : return SpBufferDataView<TargetType>(this); 43 : } 44 : 45 102 : TargetType* getABuffer() final{ 46 204 : std::unique_lock<std::mutex> lockAll(availableBuffersMutex); 47 102 : nbBuffersUnderUse += 1; 48 102 : if(availableBuffers.size()){ 49 100 : TargetType* bufferToUse = availableBuffers.back(); 50 100 : availableBuffers.pop_back(); 51 100 : return bufferToUse; 52 : } 53 : else{ 54 2 : return new TargetType(); 55 : } 56 : } 57 : 58 102 : void releaseABuffer(TargetType* inBuffer) final{ 59 204 : std::unique_lock<std::mutex> lockAll(availableBuffersMutex); 60 102 : nbBuffersUnderUse -= 1; 61 102 : if(softLimiteOfNbBuffers <= int(availableBuffers.size())){ 62 0 : delete inBuffer; 63 : } 64 : else{ 65 102 : availableBuffers.push_back(inBuffer); 66 : } 67 102 : } 68 : }; 69 : 70 : #endif