diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/InternalBuildRunner.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/InternalBuildRunner.java index 8c2cf096a4f..f50ce9993aa 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/InternalBuildRunner.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/InternalBuildRunner.java @@ -173,8 +173,7 @@ public class InternalBuildRunner extends AbstractBuildRunner { break; case IBuildModelBuilder.STATUS_ERROR_LAUNCH: default: - buf.append(ManagedMakeMessages - .getResourceString(BUILD_FAILED_ERR)); + buf.append(ManagedMakeMessages.getResourceString(BUILD_FAILED_ERR)); break; } buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ @@ -194,8 +193,7 @@ public class InternalBuildRunner extends AbstractBuildRunner { epmOutputStream.close(); epmOutputStream = null; // Generate any error markers that the build has discovered - monitor.subTask(ManagedMakeMessages - .getResourceString(MARKERS)); + monitor.subTask(ManagedMakeMessages.getResourceString(MARKERS)); bsMngr.setProjectBuildState(project, pBS); } else { diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/BuildProcessManager.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/BuildProcessManager.java index ac5dfc450de..5525b20774b 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/BuildProcessManager.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/BuildProcessManager.java @@ -17,6 +17,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.Vector; import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand; import org.eclipse.core.runtime.IPath; @@ -24,16 +25,13 @@ import org.eclipse.core.runtime.IProgressMonitor; /** * This class implements process pool management for internal builder - * - * NOTE: This class is subject to change and discuss, - * and is currently available in experimental mode only */ public class BuildProcessManager { protected OutputStream out; protected OutputStream err; protected boolean show; - protected ProcessLauncher[] processes; - protected int maxProcesses; + protected Vector processes; + protected int maxProcesses; /** * Initializes process manager @@ -47,7 +45,7 @@ public class BuildProcessManager { err = _err; show = _show; maxProcesses = _procNumber; - processes = new ProcessLauncher[maxProcesses]; + processes = new Vector(Math.min(10, maxProcesses), 10); } /** @@ -67,18 +65,19 @@ public class BuildProcessManager { * @param monitor Progress monitor for this task */ public ProcessLauncher launchProcess(IBuildCommand cmd, IPath cwd, IProgressMonitor monitor) { - if (hasEmpty()) { - int i = 0; - for (; i < maxProcesses; i++) { - if (processes[i] == null || processes[i].queryState() == ProcessLauncher.STATE_DONE) { - break; - } + for (int i = 0; i < maxProcesses; i++) { + if (i >= processes.size()) { + ProcessLauncher process = new ProcessLauncher(cmd.getCommand(), cmd.getArgs(), mapToStringArray(cmd.getEnvironment()), cwd, out, err, monitor, show); + processes.add(process); + process.launch(); + return process; + } - - if (i < maxProcesses) { - processes[i] = new ProcessLauncher(cmd.getCommand(), cmd.getArgs(), mapToStringArray(cmd.getEnvironment()), cwd, out, err, monitor, show); - processes[i].launch(); - return processes[i]; + if (processes.get(i).queryState() == ProcessLauncher.STATE_DONE) { + ProcessLauncher process = new ProcessLauncher(cmd.getCommand(), cmd.getArgs(), mapToStringArray(cmd.getEnvironment()), cwd, out, err, monitor, show); + processes.set(i, process); + process.launch(); + return process; } } return null; @@ -90,36 +89,37 @@ public class BuildProcessManager { * returned as a result. Otherwise this method returns null. */ public ProcessLauncher queryStates() { - ProcessLauncher result = null; - - for (int i = 0; i < maxProcesses; i++) { - if (processes[i] != null) { - int state = processes[i].queryState(); - if (state != ProcessLauncher.STATE_RUNNING) { - if (state != ProcessLauncher.STATE_DONE && result == null) - result = processes[i]; - } - } + for (ProcessLauncher process : processes) { + int state = process.queryState(); + if (state != ProcessLauncher.STATE_RUNNING && state != ProcessLauncher.STATE_DONE) + return process; } - return result; + return null; } /** * Checks states of all currently running processes. */ public boolean hasEmpty() { - for (int i = 0; i < maxProcesses; i++) { - if (processes[i] == null) + if (processes.size() < maxProcesses) + return true; + + for (ProcessLauncher process : processes) { + if (process.queryState() != ProcessLauncher.STATE_RUNNING) return true; - else { - if (processes[i].queryState() != ProcessLauncher.STATE_RUNNING) - return true; - } } return false; } + /** + * Returns maximum threads used up to that point + */ + public int getThreadsUsed() { + return processes.size(); + } + + /** * Converts map to strings array diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/ParallelBuilder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/ParallelBuilder.java index 814e0310bf8..b6e41fd3345 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/ParallelBuilder.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/ParallelBuilder.java @@ -17,6 +17,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; +import java.util.Vector; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand; @@ -212,9 +213,10 @@ public class ParallelBuilder { builder.enqueueAll(des); builder.sortQueue(); monitor.beginTask("", builder.queue.size()); //$NON-NLS-1$ - builder.dispatch(new BuildProcessManager(out, err, true, threads)); + BuildProcessManager buildProcessManager = new BuildProcessManager(out, err, true, threads); + builder.dispatch(buildProcessManager); + lastThreadsUsed = buildProcessManager.getThreadsUsed(); monitor.done(); - lastThreadsUsed = threads; return IBuildModelBuilder.STATUS_OK; } @@ -293,10 +295,8 @@ public class ParallelBuilder { * Dispatches the build queue and returns build status */ protected int dispatch(BuildProcessManager mgr) { - ActiveBuildStep[] active = new ActiveBuildStep[mgr.getMaxProcesses()]; - for (int i = 0; i < active.length; i++) { - active[i] = null; // new ActiveBuildStep(); - } + int maxProcesses = mgr.getMaxProcesses(); + Vector active = new Vector(Math.min(maxProcesses, 10), 10); int activeCount = 0; int maxLevel = 0; @@ -330,9 +330,8 @@ public class ParallelBuilder { proceed = false; } else { // Check "active steps" list for completed ones - for (int i = 0; i < active.length; i++) { - if (active[i] == null) continue; - ProcessLauncher pl = active[i].getLauncher(); + for (ActiveBuildStep buildStep : active) { + ProcessLauncher pl = buildStep.getLauncher(); if (pl == null) continue; if (pl.queryState() == ProcessLauncher.STATE_DONE) { // If process has terminated with error, break loop @@ -343,8 +342,8 @@ public class ParallelBuilder { break main_loop; } // Try to launch next command for the current active step - if (active[i].isDone()) continue; - if (active[i].launchNextCmd(mgr)) { + if (buildStep.isDone()) continue; + if (buildStep.launchNextCmd(mgr)) { // Command has been launched. Check if process pool is not maximized yet if (!mgr.hasEmpty()) { proceed = false; @@ -352,7 +351,7 @@ public class ParallelBuilder { } } else { // Command has not been launched: step complete - refreshOutputs(active[i].getStep()); + refreshOutputs(buildStep.getStep()); activeCount--; monitor.worked(1); } @@ -371,7 +370,7 @@ public class ParallelBuilder { } // Check if we need to schedule another process - if (queue.size() != 0 && activeCount < active.length) { + if (queue.size() != 0 && activeCount < maxProcesses) { // Need to schedule another process Iterator iter = queue.iterator(); @@ -379,8 +378,8 @@ public class ParallelBuilder { while (iter.hasNext()) { BuildQueueElement elem = iter.next(); - // If "active steps" list is full, then break loop - if (activeCount == active.length) + // If "active steps" list reaches maximum, then break loop + if (activeCount == maxProcesses) break; // If current element's level exceeds maximum level of currently built @@ -389,14 +388,13 @@ public class ParallelBuilder { break; //Check if all prerequisites are built - IBuildResource[] res = elem.getStep().getInputResources(); boolean prereqBuilt = true; - for (int j = 0; j < res.length; j++) { - IBuildStep stp = res[j].getProducerStep(); // step which produces input for curr + for (IBuildResource bldRes : elem.getStep().getInputResources()) { + IBuildStep step = bldRes.getProducerStep(); // step which produces input for curr boolean built = true; - if (stp != stp.getBuildDescription().getInputStep()) { - for (int k = 0; k < active.length; k++) { - if (active[k] != null && active[k].getStep().equals(stp) && !active[k].isDone()) { + if (step != step.getBuildDescription().getInputStep()) { + for (ActiveBuildStep buildStep : active) { + if (buildStep != null && buildStep.getStep().equals(step) && !buildStep.isDone()) { built = false; break; } @@ -415,10 +413,21 @@ public class ParallelBuilder { // Remove element from the build queue and add it to the // "active steps" list. iter.remove(); - for (int i = 0; i < active.length; i++) { - if (active[i] == null || active[i].isDone()) { - active[i] = new ActiveBuildStep(step); - if (active[i].launchNextCmd(mgr)) activeCount++; + for (int i = 0; i < maxProcesses; i++) { + if (i >= active.size()) { + // add new item + ActiveBuildStep buildStep = new ActiveBuildStep(step); + active.add(buildStep); + if (buildStep.launchNextCmd(mgr)) + activeCount++; + break; + } + if (active.get(i).isDone()) { + // replace old item + ActiveBuildStep buildStep = new ActiveBuildStep(step); + active.set(i, buildStep); + if (buildStep.launchNextCmd(mgr)) + activeCount++; break; } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java index b9e27e02f97..e5e7d187eb0 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java @@ -64,7 +64,6 @@ import org.eclipse.cdt.managedbuilder.macros.IReservedMacroNameSupplier; import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator2; import org.eclipse.cdt.managedbuilder.makegen.gnu.GnuMakefileGenerator; -import org.eclipse.cdt.newmake.core.IMakeCommonBuildInfo; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.Assert; @@ -81,6 +80,7 @@ import org.eclipse.core.variables.VariablesPlugin; import org.osgi.framework.Version; public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider, IRealBuildObjectAssociation { + public static final int UNLIMITED_JOBS = Integer.MAX_VALUE; private static final String EMPTY_STRING = ""; //$NON-NLS-1$ // Superclass @@ -624,7 +624,7 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider if (jobsNumber <= 0) return VALUE_OPTIMAL; - if (jobsNumber.equals(Integer.MAX_VALUE)) + if (jobsNumber.equals(UNLIMITED_JOBS)) return VALUE_UNLIMITED; return jobsNumber.toString(); @@ -634,12 +634,7 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider if (VALUE_OPTIMAL.equals(value)) { parallelNumberAttribute = -getOptimalParallelJobNum(); } else if (VALUE_UNLIMITED.equals(value)) { - if (!isInternalBuilder()) { - parallelNumberAttribute = Integer.MAX_VALUE; - } else { - ManagedBuilderCorePlugin.error("'unlimited' number of jobs is not allowed for Internal Builder, switching to 'optimal'"); - parallelNumberAttribute = -getOptimalParallelJobNum(); - } + parallelNumberAttribute = UNLIMITED_JOBS; } else { try { parallelNumberAttribute = Integer.decode(value); @@ -654,7 +649,7 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider parallelNumberAttribute = -getOptimalParallelJobNum(); } else { // unlimited for External Builder - parallelNumberAttribute = Integer.MAX_VALUE; + parallelNumberAttribute = UNLIMITED_JOBS; } } } @@ -1176,7 +1171,7 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider } // "unlimited" number of jobs results in not adding the number to parallelization cmd // that behavior corresponds that of "make" flag "-j". - return processParallelPattern(pattern, num == Integer.MAX_VALUE, num); + return processParallelPattern(pattern, num == UNLIMITED_JOBS, num); } /** @@ -2537,9 +2532,9 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider *
 	 *  Status       Returns
 	 * No parallel      1       
-	 * Optimal       -CPU#       (negative number of processors) 
-	 * Specific        >0        (positive number)
-	 * Unlimited    Integer.MAX  (N/A for Internal Builder)
+	 * Optimal       -CPU# (negative number of processors) 
+	 * Specific        >0  (positive number)
+	 * Unlimited    Builder.UNLIMITED_JOBS
 	 * 
*/ public int getParallelizationNumAttribute() { @@ -2570,10 +2565,6 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider setArgumentsAttribute(updatedArgs); } - if (jobs == Integer.MAX_VALUE && isInternalBuilder()) { - // Internal Builder does not support "unlimited" jobs, switching to "optimal" - jobs = -1; - } if (jobs > 0) { parallelNumberAttribute = jobs; } else { diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java index 5d552fc9594..4ac53e132a9 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java @@ -81,7 +81,6 @@ import org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData; import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier; -import org.eclipse.cdt.newmake.core.IMakeCommonBuildInfo; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildBehaviourTab.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildBehaviourTab.java index 543259ae733..02b45c20994 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildBehaviourTab.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildBehaviourTab.java @@ -172,7 +172,7 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab { public void widgetSelected(SelectionEvent event) { if (b_parallelUnlimited.getSelection()) { setParallelDef(true); - setParallelNumber(Integer.MAX_VALUE); + setParallelNumber(Builder.UNLIMITED_JOBS); updateButtons(); } }}); @@ -347,9 +347,6 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab { private void updateParallelBlock() { // note: for multi-config selection bldr is from Active cfg - boolean isAnyInternalBuilder = bldr.isInternalBuilder(); - boolean isAnyExternalBuilder = ! bldr.isInternalBuilder(); - boolean isParallelSupported = bldr.supportsParallelBuild(); boolean isParallelOn = bldr.isParallelBuildOn(); int triSelection = isParallelOn ? TRI_YES : TRI_NO; @@ -357,7 +354,6 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab { int parallelizationNumInternal = bldr.getParallelizationNumAttribute(); int optimalParallelNumber = bldr.getOptimalParallelJobNum(); int parallelNumber = bldr.getParallelizationNum(); - boolean isUnlimited = parallelizationNumInternal == Integer.MAX_VALUE; if (icfg instanceof ICMultiItemsHolder) { IConfiguration[] cfgs = (IConfiguration[])((ICMultiItemsHolder)icfg).getItems(); @@ -372,19 +368,15 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab { isAnyParallelOn = isAnyParallelOn || builder.isParallelBuildOn(); isAnyParallelSupported = isAnyParallelSupported || builder.supportsParallelBuild(); - isAnyInternalBuilder = isAnyInternalBuilder || builder.isInternalBuilder(); - isAnyExternalBuilder = isAnyExternalBuilder || !builder.isInternalBuilder(); } // reset initial display to "optimal" to enhance user experience: if ((!isParallelSupported && isAnyParallelSupported) // parallel is supported by other than Active cfg - || (!isParallelOn && isAnyParallelOn) // prevent showing the 1 job as parallel in the spinner - || (isUnlimited && isAnyInternalBuilder) // can't show "unlimited" as it won't be selectable if Internal Builder present + || (!isParallelOn && isAnyParallelOn) // prevent showing the 1 job as parallel in the spinner ) { isParallelSupported = true; parallelizationNumInternal = -optimalParallelNumber; parallelNumber = optimalParallelNumber; - isUnlimited = false; } if (isParallelSupported && isParallelDiffers) { triSelection = TRI_UNKNOWN; @@ -394,7 +386,7 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab { b_parallel.setVisible(isParallelSupported); b_parallelOptimal.setVisible(isParallelSupported); b_parallelSpecific.setVisible(isParallelSupported); - b_parallelUnlimited.setVisible(isParallelSupported && isAnyExternalBuilder); + b_parallelUnlimited.setVisible(isParallelSupported); s_parallelNumber.setVisible(isParallelSupported); if (isParallelSupported) { @@ -404,10 +396,11 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab { b_parallelOptimal.setText(MessageFormat.format(Messages.BuilderSettingsTab_UseOptimalJobs, optimalParallelNumber)); b_parallelOptimal.setEnabled(isParallelSelected); b_parallelSpecific.setEnabled(isParallelSelected); - b_parallelUnlimited.setEnabled(isParallelSelected && !isAnyInternalBuilder); + b_parallelUnlimited.setEnabled(isParallelSelected); if (isParallelSelected) { boolean isOptimal = parallelizationNumInternal <= 0; + boolean isUnlimited = parallelizationNumInternal == Builder.UNLIMITED_JOBS; b_parallelOptimal.setSelection(isOptimal); b_parallelSpecific.setSelection(!isOptimal && !isUnlimited);