Skip to content
Snippets Groups Projects
Select Git revision
  • master
  • develop protected
  • feature/up-conv-test
  • jst
  • fabian
  • ITAConvolution_v2024a
  • VA_v2023b
  • VA_v2023a
  • VA_v2022a
  • before_cmake_rework
  • v2021.a
  • v2020.a
  • v2019.a
  • v2018.b
  • v2018.a
  • v2017.c
  • v2017.d
  • v2017.b
  • v2017.a
  • v2016.a
20 results

ITAUPFilterPool.cpp

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ITAUPFilterPool.cpp 6.60 KiB
    #include <ITAFunctors.h>
    #include <ITAUPFilter.h>
    #include <ITAUPFilterPool.h>
    #include <algorithm>
    #include <cassert>
    #include <cstdio>
    
    
    // Debug-Meldung ausgeben
    #define VERBOSE 0
    
    ITAUPFilterPool::ITAUPFilterPool( const int iBlocklength, const int iMaxFilterLength, const int iInitialSize )
        : m_iBlocklength( iBlocklength )
        , m_iMaxFilterLength( iMaxFilterLength )
    {
    	for( int i = 0; i < iInitialSize; i++ )
    	{
    		ITAUPFilter* pFilter = new ITAUPFilter( m_iBlocklength, m_iMaxFilterLength );
    		pFilter->m_pParent   = this;
    		m_lpFreeFilters.push_back( pFilter );
    	}
    }
    
    ITAUPFilterPool::~ITAUPFilterPool( )
    {
    	m_csFilters.enter( );
    
    	std::for_each( m_lpFreeFilters.begin( ), m_lpFreeFilters.end( ), deleteFunctor<ITAUPFilter> );
    	std::for_each( m_lpUsedFilters.begin( ), m_lpUsedFilters.end( ), deleteFunctor<ITAUPFilter> );
    	std::for_each( m_lpAutoFilters.begin( ), m_lpAutoFilters.end( ), deleteFunctor<ITAUPFilter> );
    
    	m_csFilters.leave( );
    }
    
    int ITAUPFilterPool::GetBlocklength( ) const
    {
    	return m_iBlocklength;
    }
    
    int ITAUPFilterPool::GetMaxFilterlength( ) const
    {
    	return m_iMaxFilterLength;
    }
    
    int ITAUPFilterPool::GetNumFreeFilters( ) const
    {
    	m_csFilters.enter( );
    	int iResult = (int)m_lpFreeFilters.size( );
    	m_csFilters.leave( );
    	return iResult;
    }
    
    int ITAUPFilterPool::GetNumUsedFilters( ) const
    {
    	m_csFilters.enter( );
    	int iResult = (int)m_lpUsedFilters.size( ) + (int)m_lpAutoFilters.size( );
    	m_csFilters.leave( );
    	return iResult;
    }
    
    int ITAUPFilterPool::GetNumTotalFilters( ) const
    {
    	m_csFilters.enter( );
    	int iResult = (int)m_lpFreeFilters.size( ) + (int)m_lpUsedFilters.size( ) + (int)m_lpAutoFilters.size( );
    	m_csFilters.leave( );
    	return iResult;
    }
    
    ITAUPFilter* ITAUPFilterPool::RequestFilter( )
    {
    	m_csFilters.enter( );
    
    	ITAUPFilter* pFilter = nullptr;
    
    	if( m_lpFreeFilters.empty( ) )
    	{
    		// Fall: Keine Filter in der Frei-Liste -> Zunchst schauen ob freie Filter in der Auto-Liste
    		if( !m_lpAutoFilters.empty( ) )
    		{
    			for( std::list<ITAUPFilter*>::iterator it = m_lpAutoFilters.begin( ); it != m_lpAutoFilters.end( ); ++it )
    			{
    				/*
    				 *  Wichtig: Wenn der Filter bereits in der Auto-Liste ist,
    				 *           hat der Benutzer fr dieses Filter release() aufgerufen.
    				 *           Er braucht den Filter also nicht mehr und darf den
    				 *           ihm zuvor genannten Zeiger nicht mehr weiterbenutzen.
    				 *           Deshalb kann auch den Filter auch nicht zwischenzeitlich
    				 *           in einen anderen Falter einsetzen.
    				 *
    				 *           Fazit: Es ist sicher hier nur-lesend zu testen!
    				 */
    
    				assert( ( *it ) != 0 );
    
    				if( !( *it )->IsInUse( ) )
    				{
    					pFilter = ( *it );
    
    					// Filter wieder vergeben
    					m_lpAutoFilters.erase( it );
    #if VERBOSE == 1
    					{
    						DEBUG_PRINTF( "[DSMBCFilterPool] Reusing auto filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n", pFilter, m_lpUsedFilters.size( ),
    						              m_lpAutoFilters.size( ), m_lpFreeFilters.size( ), GetNumTotalFilters( ) );
    					}
    #endif
    					break;
    				}
    				//				} else {
    				//					// Nur Meldung machen
    				//					DSMBCFilter::State::StateStruct ss;
    				//					ss.iPrepRefCount = 0;
    				//					ss.iUseRefCount = 0;
    				//					if (pFilter) atomic_read32( &pFilter->m_oState.m_oState, &ss );
    				//#if VERBOSE==1
    				//					DEBUG_PRINTF("[DSMBCFilterPool] Cannot reusing auto filter 0x%08Xh (preps=%d, uses=%d) [Used %d, Auto %d, Free %d, Total %d]\n",
    				//						pFilter, ss.iPrepRefCount, ss.iUseRefCount, m_lpUsedFilters.size(), m_lpAutoFilters.size(), m_lpFreeFilters.size(),
    				//getNumTotalFilters()); #endif
    				//				}
    			}
    		}
    
    		if( pFilter == nullptr )
    		{
    			// Fall: Auch kein freies Filter in der Auto-Liste -> Neues Filter erzeugen
    			pFilter            = new ITAUPFilter( m_iBlocklength, m_iMaxFilterLength );
    			pFilter->m_pParent = this;
    
    #if VERBOSE == 1
    			DEBUG_PRINTF( "[DSMBCFilterPool] Created new filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n", pFilter, m_lpUsedFilters.size( ),
    			              m_lpAutoFilters.size( ), m_lpFreeFilters.size( ), GetNumTotalFilters( ) );
    #endif
    		}
    
    		m_lpUsedFilters.push_back( pFilter );
    	}
    	else
    	{
    		// Fall: Freie Filter verfgbar
    		pFilter = m_lpFreeFilters.back( );
    		m_lpFreeFilters.pop_back( );
    		m_lpUsedFilters.push_back( pFilter );
    
    		//#if VERBOSE==1
    		//		{
    		//			// Nur Meldung machen
    		//			DSMBCFilter::State::StateStruct ss;
    		//			ss.iPrepRefCount = 0;
    		//			ss.iUseRefCount = 0;
    		//			if (pFilter) atomic_read32( &pFilter->m_oState.m_oState, &ss );
    		//		DEBUG_PRINTF("[DSMBCFilterPool] Freed filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n",
    		//			   pFilter, m_lpUsedFilters.size(), m_lpAutoFilters.size(), m_lpFreeFilters.size(), getNumTotalFilters());
    		//		}
    		//#endif
    	}
    
    	m_csFilters.leave( );
    
    
    #if VERBOSE == 1
    	DEBUG_PRINTF( "[DSMBCFilterPool] Request returns filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n", pFilter, m_lpUsedFilters.size( ), m_lpAutoFilters.size( ),
    	              m_lpFreeFilters.size( ), GetNumTotalFilters( ) );
    #endif
    
    	return pFilter;
    }
    
    void ITAUPFilterPool::ReleaseFilter( ITAUPFilter* pFilter )
    {
    	m_csFilters.enter( );
    
    	// Nonsens einfach ignoieren
    	if( !pFilter )
    	{
    		m_csFilters.leave( );
    		return;
    	}
    
    #if VERBOSE == 1
    	DEBUG_PRINTF( "[DSMBCFilterPool] Release filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n", pFilter, m_lpUsedFilters.size( ), m_lpAutoFilters.size( ),
    	              m_lpFreeFilters.size( ), GetNumTotalFilters( ) );
    #endif
    
    	// Zunchst die eigene Zust?ndigkeit sicherstellen
    	std::list<ITAUPFilter*>::iterator it = std::find( m_lpUsedFilters.begin( ), m_lpUsedFilters.end( ), pFilter );
    	if( it == m_lpUsedFilters.end( ) )
    	{
    		// Filter garnicht aus diesem Pool. Ignorieren ...
    		m_csFilters.leave( );
    		return;
    	}
    
    	/*
    	// Schneller und einfacher Test auf Zustndigkeit
    	if (pFilter->m_pParent != this) {
    	m_csFilters.leave();
    	return;
    	}
    	*/
    
    	if( pFilter->IsInUse( ) )
    	{
    		// Ist der Filter noch in Faltern in Benutzung -> Zur Freigabe vormerken (Auto-Liste)
    		m_lpUsedFilters.erase( it );
    		m_lpAutoFilters.push_back( pFilter );
    		m_csFilters.leave( );
    
    #if VERBOSE == 1
    		DEBUG_PRINTF( "[DSMBCFilterPool] Auto-release filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n", pFilter, m_lpUsedFilters.size( ), m_lpAutoFilters.size( ),
    		              m_lpFreeFilters.size( ), GetNumTotalFilters( ) );
    #endif
    		return;
    	}
    
    	// Filter wieder in die Frei-Liste
    	m_lpUsedFilters.erase( it );
    	m_lpFreeFilters.push_back( pFilter );
    
    #if VERBOSE == 1
    	DEBUG_PRINTF( "[DSMBCFilterPool] Instant-release filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n", pFilter, m_lpUsedFilters.size( ), m_lpAutoFilters.size( ),
    	              m_lpFreeFilters.size( ), GetNumTotalFilters( ) );
    #endif
    
    	m_csFilters.leave( );
    }