Package org.apache.excalibur.mpool.test

Source Code of org.apache.excalibur.mpool.test.MultiThreadedPoolComparisonProfile$PoolRunner

/*
* Copyright 1999-2004 The Apache Software Foundation
* Licensed  under the  Apache License,  Version 2.0  (the "License");
* you may not use  this file  except in  compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed  under the  License is distributed on an "AS IS" BASIS,
* WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
* implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.excalibur.mpool.test;

import org.apache.avalon.excalibur.pool.Poolable;
import org.apache.avalon.excalibur.testcase.CascadingAssertionFailedError;
import org.apache.avalon.excalibur.testcase.LatchedThreadGroup;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.logger.Logger;
import org.apache.excalibur.mpool.Pool;

/**
* This is used to profile and compare various pool implementations
*  given a single access thread.
*
* @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
* @version $Id: MultiThreadedPoolComparisonProfile.java,v 1.4 2004/02/28 11:47:32 cziegeler Exp $
*/
public class MultiThreadedPoolComparisonProfile
    extends PoolComparisonProfileAbstract
{
    protected static final int THREADS = 100;

    private int m_getCount;
    private Throwable m_throwable;

    /*---------------------------------------------------------------
     * Constructors
     *-------------------------------------------------------------*/
    public MultiThreadedPoolComparisonProfile( String name )
    {
        super( name );
    }

    /*---------------------------------------------------------------
     * PoolComparisonProfileAbstract Methods
     *-------------------------------------------------------------*/
    protected long getPoolRunTime( final Pool pool, final int gets )
        throws Exception
    {
        if( gets % THREADS != 0 )
        {
            m_logger.info( "Invalid: " + gets % THREADS + " gets(" + gets + ") threads(" + THREADS + ")" );
            fail( "gets must be evenly divisible by THREADS" );
        }

        m_getCount = 0;
        m_throwable = null;

        // Create the runnable
        MPoolRunner runnable = new MPoolRunner( pool, gets, m_logger );

        LatchedThreadGroup group = new LatchedThreadGroup( runnable, THREADS );
        group.enableLogging( m_logger );

        long duration;
        try
        {
            duration = group.go();
        }
        catch( Throwable t )
        {
            // Throwable could have been thrown by one of the tests.
            if( m_throwable == null )
            {
                m_throwable = t;
            }
            duration = 0;
        }

        if( m_throwable != null )
        {
            throw new CascadingAssertionFailedError( "Exception in test thread.", m_throwable );
        }

        assertTrue( "m_getCount == 0 (" + m_getCount + ")", m_getCount == 0 );

        // Dispose if necessary
        if( pool instanceof Disposable )
        {
            ( (Disposable)pool ).dispose();
        }

        return duration;
    }

    /*---------------------------------------------------------------
     * PoolComparisonProfileAbstract Methods
     *-------------------------------------------------------------*/
    protected long getPoolRunTime( final org.apache.avalon.excalibur.pool.Pool pool, final int gets )
        throws Exception
    {
        if( gets % THREADS != 0 )
        {
            m_logger.info( "Invalid: " + gets % THREADS + " gets(" + gets + ") threads(" + THREADS + ")" );
            fail( "gets must be evenly divisible by THREADS" );
        }

        m_getCount = 0;
        m_throwable = null;

        // Create the runnable
        PoolRunner runnable = new PoolRunner( pool, gets, m_logger );

        LatchedThreadGroup group = new LatchedThreadGroup( runnable, THREADS );
        group.enableLogging( m_logger );

        long duration;
        try
        {
            duration = group.go();
        }
        catch( Throwable t )
        {
            // Throwable could have been thrown by one of the tests.
            if( m_throwable == null )
            {
                m_throwable = t;
            }
            duration = 0;
        }

        if( m_throwable != null )
        {
            throw new CascadingAssertionFailedError( "Exception in test thread.", m_throwable );
        }

        assertTrue( "m_getCount == 0 (" + m_getCount + ")", m_getCount == 0 );

        // Dispose if necessary
        if( pool instanceof Disposable )
        {
            ( (Disposable)pool ).dispose();
        }

        return duration;
    }

    private static class PoolRunner implements Runnable
    {
        private Logger m_logger;
        private org.apache.avalon.excalibur.pool.Pool m_pool;
        private int m_getCount = 0;
        private Throwable m_throwable = null;
        private int m_gets;

        public PoolRunner( org.apache.avalon.excalibur.pool.Pool pool, int gets, Logger logger )
        {
            m_pool = pool;
            m_logger = logger;
            m_gets = gets;
        }

        public int getCount()
        {
            return m_getCount;
        }

        public Throwable getThrowable()
        {
            return m_throwable;
        }

        public void run()
        {
            // Perform this threads part of the test.
            final int cnt = m_gets / THREADS;
            final Poolable[] poolTmp = new Poolable[ cnt ];
            final int loops = ( TEST_SIZE / THREADS ) / cnt;
            for( int i = 0; i < loops; i++ )
            {
                // Get some Poolables
                for( int j = 0; j < cnt; j++ )
                {
                    try
                    {
                        poolTmp[ j ] = m_pool.get();
                        m_getCount++;
                    }
                    catch( Throwable t )
                    {
                        m_logger.error( "Unexpected error", t );

                        if( m_throwable == null )
                        {
                            m_throwable = t;
                        }

                        return;
                    }
                }

                // Make the loops hold the poolables longer than they are released, but only slightly.
                Thread.yield();

                // Put the Poolables back
                for( int j = 0; j < cnt; j++ )
                {
                    m_pool.put( poolTmp[ j ] );
                    m_getCount--;
                    poolTmp[ j ] = null;
                }
            }
        }
    }

    private static class MPoolRunner implements Runnable
    {
        private Logger m_logger;
        private Pool m_pool;
        private int m_getCount = 0;
        private Throwable m_throwable = null;
        private final int m_gets;

        public MPoolRunner( Pool pool, int gets, Logger logger )
        {
            m_pool = pool;
            m_logger = logger;
            m_gets = gets;
        }

        public int getCount()
        {
            return m_getCount;
        }

        public Throwable getThrowable()
        {
            return m_throwable;
        }

        public void run()
        {
            // Perform this threads part of the test.
            final int cnt = m_gets / THREADS;
            final Object[] poolTmp = new Poolable[ cnt ];
            final int loops = ( TEST_SIZE / THREADS ) / cnt;
            for( int i = 0; i < loops; i++ )
            {
                // Get some Poolables
                for( int j = 0; j < cnt; j++ )
                {
                    try
                    {
                        poolTmp[ j ] = m_pool.acquire();
                        m_getCount++;
                    }
                    catch( Throwable t )
                    {
                        m_logger.error( "Unexpected error after " + m_getCount +
                                        " items retrieved and " + m_gets + " requested", t );

                        if( m_throwable == null )
                        {
                            m_throwable = t;
                        }
                        return;
                    }
                }

                // Make the loops hold the poolables longer than they are released, but only slightly.
                Thread.yield();

                // Put the Poolables back
                for( int j = 0; j < cnt; j++ )
                {
                    m_pool.release( poolTmp[ j ] );
                    m_getCount--;
                    poolTmp[ j ] = null;
                }
            }
        }
    }
}
TOP

Related Classes of org.apache.excalibur.mpool.test.MultiThreadedPoolComparisonProfile$PoolRunner

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.