1 17 package org.apache.excalibur.mpool.test; 18 19 import org.apache.avalon.excalibur.pool.Poolable; 20 import org.apache.avalon.excalibur.testcase.CascadingAssertionFailedError; 21 import org.apache.avalon.excalibur.testcase.LatchedThreadGroup; 22 import org.apache.avalon.framework.activity.Disposable; 23 import org.apache.avalon.framework.logger.Logger; 24 import org.apache.excalibur.mpool.Pool; 25 26 33 public class MultiThreadedPoolComparisonProfile 34 extends PoolComparisonProfileAbstract 35 { 36 protected static final int THREADS = 100; 37 38 private int m_getCount; 39 private Throwable m_throwable; 40 41 44 public MultiThreadedPoolComparisonProfile( String name ) 45 { 46 super( name ); 47 } 48 49 52 protected long getPoolRunTime( final Pool pool, final int gets ) 53 throws Exception 54 { 55 if( gets % THREADS != 0 ) 56 { 57 m_logger.info( "Invalid: " + gets % THREADS + " gets(" + gets + ") threads(" + THREADS + ")" ); 58 fail( "gets must be evenly divisible by THREADS" ); 59 } 60 61 m_getCount = 0; 62 m_throwable = null; 63 64 MPoolRunner runnable = new MPoolRunner( pool, gets, m_logger ); 66 67 LatchedThreadGroup group = new LatchedThreadGroup( runnable, THREADS ); 68 group.enableLogging( m_logger ); 69 70 long duration; 71 try 72 { 73 duration = group.go(); 74 } 75 catch( Throwable t ) 76 { 77 if( m_throwable == null ) 79 { 80 m_throwable = t; 81 } 82 duration = 0; 83 } 84 85 if( m_throwable != null ) 86 { 87 throw new CascadingAssertionFailedError( "Exception in test thread.", m_throwable ); 88 } 89 90 assertTrue( "m_getCount == 0 (" + m_getCount + ")", m_getCount == 0 ); 91 92 if( pool instanceof Disposable ) 94 { 95 ( (Disposable)pool ).dispose(); 96 } 97 98 return duration; 99 } 100 101 104 protected long getPoolRunTime( final org.apache.avalon.excalibur.pool.Pool pool, final int gets ) 105 throws Exception 106 { 107 if( gets % THREADS != 0 ) 108 { 109 m_logger.info( "Invalid: " + gets % THREADS + " gets(" + gets + ") threads(" + THREADS + ")" ); 110 fail( "gets must be evenly divisible by THREADS" ); 111 } 112 113 m_getCount = 0; 114 m_throwable = null; 115 116 PoolRunner runnable = new PoolRunner( pool, gets, m_logger ); 118 119 LatchedThreadGroup group = new LatchedThreadGroup( runnable, THREADS ); 120 group.enableLogging( m_logger ); 121 122 long duration; 123 try 124 { 125 duration = group.go(); 126 } 127 catch( Throwable t ) 128 { 129 if( m_throwable == null ) 131 { 132 m_throwable = t; 133 } 134 duration = 0; 135 } 136 137 if( m_throwable != null ) 138 { 139 throw new CascadingAssertionFailedError( "Exception in test thread.", m_throwable ); 140 } 141 142 assertTrue( "m_getCount == 0 (" + m_getCount + ")", m_getCount == 0 ); 143 144 if( pool instanceof Disposable ) 146 { 147 ( (Disposable)pool ).dispose(); 148 } 149 150 return duration; 151 } 152 153 private static class PoolRunner implements Runnable 154 { 155 private Logger m_logger; 156 private org.apache.avalon.excalibur.pool.Pool m_pool; 157 private int m_getCount = 0; 158 private Throwable m_throwable = null; 159 private int m_gets; 160 161 public PoolRunner( org.apache.avalon.excalibur.pool.Pool pool, int gets, Logger logger ) 162 { 163 m_pool = pool; 164 m_logger = logger; 165 m_gets = gets; 166 } 167 168 public int getCount() 169 { 170 return m_getCount; 171 } 172 173 public Throwable getThrowable() 174 { 175 return m_throwable; 176 } 177 178 public void run() 179 { 180 final int cnt = m_gets / THREADS; 182 final Poolable[] poolTmp = new Poolable[ cnt ]; 183 final int loops = ( TEST_SIZE / THREADS ) / cnt; 184 for( int i = 0; i < loops; i++ ) 185 { 186 for( int j = 0; j < cnt; j++ ) 188 { 189 try 190 { 191 poolTmp[ j ] = m_pool.get(); 192 m_getCount++; 193 } 194 catch( Throwable t ) 195 { 196 m_logger.error( "Unexpected error", t ); 197 198 if( m_throwable == null ) 199 { 200 m_throwable = t; 201 } 202 203 return; 204 } 205 } 206 207 Thread.yield(); 209 210 for( int j = 0; j < cnt; j++ ) 212 { 213 m_pool.put( poolTmp[ j ] ); 214 m_getCount--; 215 poolTmp[ j ] = null; 216 } 217 } 218 } 219 } 220 221 private static class MPoolRunner implements Runnable 222 { 223 private Logger m_logger; 224 private Pool m_pool; 225 private int m_getCount = 0; 226 private Throwable m_throwable = null; 227 private final int m_gets; 228 229 public MPoolRunner( Pool pool, int gets, Logger logger ) 230 { 231 m_pool = pool; 232 m_logger = logger; 233 m_gets = gets; 234 } 235 236 public int getCount() 237 { 238 return m_getCount; 239 } 240 241 public Throwable getThrowable() 242 { 243 return m_throwable; 244 } 245 246 public void run() 247 { 248 final int cnt = m_gets / THREADS; 250 final Object [] poolTmp = new Poolable[ cnt ]; 251 final int loops = ( TEST_SIZE / THREADS ) / cnt; 252 for( int i = 0; i < loops; i++ ) 253 { 254 for( int j = 0; j < cnt; j++ ) 256 { 257 try 258 { 259 poolTmp[ j ] = m_pool.acquire(); 260 m_getCount++; 261 } 262 catch( Throwable t ) 263 { 264 m_logger.error( "Unexpected error after " + m_getCount + 265 " items retrieved and " + m_gets + " requested", t ); 266 267 if( m_throwable == null ) 268 { 269 m_throwable = t; 270 } 271 return; 272 } 273 } 274 275 Thread.yield(); 277 278 for( int j = 0; j < cnt; j++ ) 280 { 281 m_pool.release( poolTmp[ j ] ); 282 m_getCount--; 283 poolTmp[ j ] = null; 284 } 285 } 286 } 287 } 288 } 289 | Popular Tags |