v12/src/PerfHarness/src/com/ibm/uk/hursley/perfharness/ControlThread.java
/**
	 * Starts any WorkerThreads in the workers array which are not yet started.
	 * It does this using a startup pool of threads. Start is issued to multiple
	 * threads to fill the pool. As threads start, they get removed from the pool
	 * and the start command can be issued to a new thread.
	 * 
	 * @param newWorkers
	 *            If not null the given workers are started and are added to the
	 *            main list of workers.
	 * @param new_qm signifies it's the new version of this method.
	 * @return boolean True if all workers were started without error.
	 */
Starts any WorkerThreads in the workers array which are not yet started.
It does this using a startup pool of threads. Start is issued to multiple
threads to fill the pool. As threads start, they get removed from the pool
and the start command can be issued to a new thread.

@param newWorkers
If not null the given workers are started and are added to the
main list of workers.
@param new_qm signifies it's the new version of this method.
@return boolean True if all workers were started without error.
Starts any WorkerThreads in the workers array which are not yet started . It does this using a startup pool of threads . Start is issued to multiple threads to fill the pool . As threads start they get removed from the pool and the start command can be issued to a new thread . @param newWorkers If not null the given workers are started and are added to the main list of workers . @param new_qm signifies it ' s the new version of this method . @return boolean True if all workers were started without error .
protected final boolean startWorkers(Collection<WorkerThread> newWorkers, boolean new_qm)
			throws Exception {
		final class StartingWorker implements Comparable<StartingWorker> {
			WorkerThread wt;
			Long started;
			StartingWorker(WorkerThread wt, Long started) {
				this.wt = wt;
				this.started = started;
			}
			public int compareTo(StartingWorker sw) {
				return (started.compareTo(sw.started));
			}
		}
		final long waitPeriod = ((long) Config.parms.getInt("wt")) * 1000;
		final int workerInc = Config.parms.getInt("wi");
		final int poolmax = Config.parms.getInt("wc", 0);
		ArrayList<StartingWorker> startPool = new ArrayList<StartingWorker>(poolmax);
		int status = 0;
		if (newWorkers != null) {
			addWorkers(newWorkers);
		}
		Iterator<WorkerThread> iter = workers.iterator();
		long looptime;
		Long timetostart, fastest = Long.MAX_VALUE, slowest = 0L, sumtostart = 0L;
		Itera: while (!shutdown && iter.hasNext()) {
			WorkerThread worker = (WorkerThread) iter.next();
			if ((worker.getStatus() & WorkerThread.sCREATED) == 0) {
				continue Itera;
			}
			looptime = System.currentTimeMillis();
			worker.start();			
			StartingWorker sw = new StartingWorker(worker, looptime);
			startPool.add(sw);
			/*
			 * if the pool's not full, start more threads
			 */
			if (startPool.size() < poolmax) {
				if (iter.hasNext()) {
					Thread.sleep(workerInc);
					continue Itera;
				}
			}
			/*
			 * If the pool's full, wait until either one has started or the
			 * oldest one times out
			 */
			while (!shutdown && startPool.size() > 0) {
				/*
				 * check if the oldest starting worker has
				 * exceeded the wait time (note: the array is sorted by start time)
				 */
				if ((looptime - startPool.get(0).started) > waitPeriod) {
					Log.logger
							.log(Level.SEVERE,
									"WorkerThread start interval (-wt={0}) exceeded with no response from {1}",
									new Object[] { waitPeriod / 1000,
											startPool.get(0).wt.getName() });
					return false;
				}
				for (int i = 0; i < startPool.size(); i++) {
					if (shutdown)
						break;
					StartingWorker ref_sw = startPool.get(i);
					status = ref_sw.wt.getStatus();
					if ((status & WorkerThread.sERROR) != 0) {
						Log.logger.log(Level.SEVERE,
								"Error starting WorkerThread {0}",
								worker.getName());
						return false;
					}
					if ((status & WorkerThread.sCREATED) == 0) {
						if ((status & WorkerThread.sRUNNING) != 0) {
							runningWorkers++;
							timetostart = looptime - ref_sw.started;
							if (timetostart < fastest) { fastest = timetostart; }
							if (timetostart > slowest) { slowest = timetostart; }
							sumtostart += timetostart;
							startPool.remove(i);
							Collections.sort(startPool);
							if (iter.hasNext()) {
								Thread.sleep(workerInc);
								continue Itera;
							}
						}
					}
				} 
				if (startPool.size() > 0) {
					Thread.sleep(200);
					looptime = System.currentTimeMillis();
				}
			} 
		} 
		String msg = "threads=" + runningWorkers + ",fastest_conn=" + fastest + ",slowest_conn=" + slowest + ",avg_conn=" + ((runningWorkers > 0) ? sumtostart/runningWorkers : 0);
		Log.logger.log(Level.INFO, msg);
		cmd.sendMessage(msg);
		return true;
	}
protected final boolean startWorkers ( Collection < WorkerThread > newWorkers , boolean new_qm ) throws Exception { final class StartingWorker implements Comparable < StartingWorker > { WorkerThread wt ; Long started ; StartingWorker ( WorkerThread wt , Long started ) { this . wt = wt ; this . started = started ; } public int compareTo ( StartingWorker sw ) { return ( started . compareTo ( sw . started ) ) ; } } final long waitPeriod = ( ( long ) Config . parms . getInt ( "wt" ) ) * 1000 ; final int workerInc = Config . parms . getInt ( "wi" ) ; final int poolmax = Config . parms . getInt ( "wc" , 0 ) ; ArrayList < StartingWorker > startPool = new ArrayList < StartingWorker > ( poolmax ) ; int status = 0 ; if ( newWorkers != null ) { addWorkers ( newWorkers ) ; } Iterator < WorkerThread > iter = workers . iterator ( ) ; long looptime ; Long timetostart , fastest = Long . MAX_VALUE , slowest = 0L , sumtostart = 0L ; Itera : while ( ! shutdown && iter . hasNext ( ) ) { WorkerThread worker = ( WorkerThread ) iter . next ( ) ; if ( ( worker . getStatus ( ) & WorkerThread . sCREATED ) == 0 ) { continue Itera ; } looptime = System . currentTimeMillis ( ) ; worker . start ( ) ; StartingWorker sw = new StartingWorker ( worker , looptime ) ; startPool . add ( sw ) ; /*
			 * if the pool's not full, start more threads
			 */ if ( startPool . size ( ) < poolmax ) { if ( iter . hasNext ( ) ) { Thread . sleep ( workerInc ) ; continue Itera ; } } /*
			 * If the pool's full, wait until either one has started or the
			 * oldest one times out
			 */ while ( ! shutdown && startPool . size ( ) > 0 ) { /*
				 * check if the oldest starting worker has
				 * exceeded the wait time (note: the array is sorted by start time)
				 */ if ( ( looptime - startPool . get ( 0 ) . started ) > waitPeriod ) { Log . logger . log ( Level . SEVERE , "WorkerThread start interval (-wt={0}) exceeded with no response from {1}" , new Object [ ] { waitPeriod / 1000 , startPool . get ( 0 ) . wt . getName ( ) } ) ; return false ; } for ( int i = 0 ; i < startPool . size ( ) ; i ++ ) { if ( shutdown ) break ; StartingWorker ref_sw = startPool . get ( i ) ; status = ref_sw . wt . getStatus ( ) ; if ( ( status & WorkerThread . sERROR ) != 0 ) { Log . logger . log ( Level . SEVERE , "Error starting WorkerThread {0}" , worker . getName ( ) ) ; return false ; } if ( ( status & WorkerThread . sCREATED ) == 0 ) { if ( ( status & WorkerThread . sRUNNING ) != 0 ) { runningWorkers ++ ; timetostart = looptime - ref_sw . started ; if ( timetostart < fastest ) { fastest = timetostart ; } if ( timetostart > slowest ) { slowest = timetostart ; } sumtostart += timetostart ; startPool . remove ( i ) ; Collections . sort ( startPool ) ; if ( iter . hasNext ( ) ) { Thread . sleep ( workerInc ) ; continue Itera ; } } } } if ( startPool . size ( ) > 0 ) { Thread . sleep ( 200 ) ; looptime = System . currentTimeMillis ( ) ; } } } String msg = "threads=" + runningWorkers + ",fastest_conn=" + fastest + ",slowest_conn=" + slowest + ",avg_conn=" + ( ( runningWorkers > 0 ) ? sumtostart / runningWorkers : 0 ) ; Log . logger . log ( Level . INFO , msg ) ; cmd . sendMessage ( msg ) ; return true ; }
Starts any WorkerThreads in the workers array which are not yet started.
Starts any WorkerThreads in the workers array which are not yet started .
// this now becomes the pause between adding new workers to the pool // for some stats // Skip any already running threads // Note: thread may start later and threads=n output will not be // updated // It failed ... // if it's up and running, either ....  // i. remove from the list & go to the top to start another // or ii. remove from the list & continue looping until all have started  // Note, sCONNECTING is ignored (we wait until it is running) // re-sort the list. This should be fast as it // should be nearly sorted before we start // end for(... // Either the pool is still full or we're waiting for the last threads to start // If we get here, startup is SLOW... expect long connect times // end while pool.size() > 0 // end while iter