1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

bug 259768: "Use optimal jobs number" highly misleading.

Allow Internal builder unlimited jobs
This commit is contained in:
Andrew Gvozdev 2011-11-14 12:34:48 -05:00
parent f04bd57f83
commit d4c2ce5e98
6 changed files with 83 additions and 93 deletions

View file

@ -173,8 +173,7 @@ public class InternalBuildRunner extends AbstractBuildRunner {
break; break;
case IBuildModelBuilder.STATUS_ERROR_LAUNCH: case IBuildModelBuilder.STATUS_ERROR_LAUNCH:
default: default:
buf.append(ManagedMakeMessages buf.append(ManagedMakeMessages.getResourceString(BUILD_FAILED_ERR));
.getResourceString(BUILD_FAILED_ERR));
break; break;
} }
buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ 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.close();
epmOutputStream = null; epmOutputStream = null;
// Generate any error markers that the build has discovered // Generate any error markers that the build has discovered
monitor.subTask(ManagedMakeMessages monitor.subTask(ManagedMakeMessages.getResourceString(MARKERS));
.getResourceString(MARKERS));
bsMngr.setProjectBuildState(project, pBS); bsMngr.setProjectBuildState(project, pBS);
} else { } else {

View file

@ -17,6 +17,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.Vector;
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand; import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand;
import org.eclipse.core.runtime.IPath; 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 * 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 { public class BuildProcessManager {
protected OutputStream out; protected OutputStream out;
protected OutputStream err; protected OutputStream err;
protected boolean show; protected boolean show;
protected ProcessLauncher[] processes; protected Vector<ProcessLauncher> processes;
protected int maxProcesses; protected int maxProcesses;
/** /**
* Initializes process manager * Initializes process manager
@ -47,7 +45,7 @@ public class BuildProcessManager {
err = _err; err = _err;
show = _show; show = _show;
maxProcesses = _procNumber; maxProcesses = _procNumber;
processes = new ProcessLauncher[maxProcesses]; processes = new Vector<ProcessLauncher>(Math.min(10, maxProcesses), 10);
} }
/** /**
@ -67,18 +65,19 @@ public class BuildProcessManager {
* @param monitor Progress monitor for this task * @param monitor Progress monitor for this task
*/ */
public ProcessLauncher launchProcess(IBuildCommand cmd, IPath cwd, IProgressMonitor monitor) { public ProcessLauncher launchProcess(IBuildCommand cmd, IPath cwd, IProgressMonitor monitor) {
if (hasEmpty()) { for (int i = 0; i < maxProcesses; i++) {
int i = 0; if (i >= processes.size()) {
for (; i < maxProcesses; i++) { ProcessLauncher process = new ProcessLauncher(cmd.getCommand(), cmd.getArgs(), mapToStringArray(cmd.getEnvironment()), cwd, out, err, monitor, show);
if (processes[i] == null || processes[i].queryState() == ProcessLauncher.STATE_DONE) { processes.add(process);
break; process.launch();
} return process;
} }
if (processes.get(i).queryState() == ProcessLauncher.STATE_DONE) {
if (i < maxProcesses) { ProcessLauncher process = new ProcessLauncher(cmd.getCommand(), cmd.getArgs(), mapToStringArray(cmd.getEnvironment()), cwd, out, err, monitor, show);
processes[i] = new ProcessLauncher(cmd.getCommand(), cmd.getArgs(), mapToStringArray(cmd.getEnvironment()), cwd, out, err, monitor, show); processes.set(i, process);
processes[i].launch(); process.launch();
return processes[i]; return process;
} }
} }
return null; return null;
@ -90,36 +89,37 @@ public class BuildProcessManager {
* returned as a result. Otherwise this method returns null. * returned as a result. Otherwise this method returns null.
*/ */
public ProcessLauncher queryStates() { public ProcessLauncher queryStates() {
ProcessLauncher result = null; for (ProcessLauncher process : processes) {
int state = process.queryState();
for (int i = 0; i < maxProcesses; i++) { if (state != ProcessLauncher.STATE_RUNNING && state != ProcessLauncher.STATE_DONE)
if (processes[i] != null) { return process;
int state = processes[i].queryState();
if (state != ProcessLauncher.STATE_RUNNING) {
if (state != ProcessLauncher.STATE_DONE && result == null)
result = processes[i];
}
}
} }
return result; return null;
} }
/** /**
* Checks states of all currently running processes. * Checks states of all currently running processes.
*/ */
public boolean hasEmpty() { public boolean hasEmpty() {
for (int i = 0; i < maxProcesses; i++) { if (processes.size() < maxProcesses)
if (processes[i] == null) return true;
for (ProcessLauncher process : processes) {
if (process.queryState() != ProcessLauncher.STATE_RUNNING)
return true; return true;
else {
if (processes[i].queryState() != ProcessLauncher.STATE_RUNNING)
return true;
}
} }
return false; return false;
} }
/**
* Returns maximum threads used up to that point
*/
public int getThreadsUsed() {
return processes.size();
}
/** /**
* Converts map to strings array * Converts map to strings array

View file

@ -17,6 +17,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Vector;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand; import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand;
@ -212,9 +213,10 @@ public class ParallelBuilder {
builder.enqueueAll(des); builder.enqueueAll(des);
builder.sortQueue(); builder.sortQueue();
monitor.beginTask("", builder.queue.size()); //$NON-NLS-1$ 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(); monitor.done();
lastThreadsUsed = threads;
return IBuildModelBuilder.STATUS_OK; return IBuildModelBuilder.STATUS_OK;
} }
@ -293,10 +295,8 @@ public class ParallelBuilder {
* Dispatches the build queue and returns build status * Dispatches the build queue and returns build status
*/ */
protected int dispatch(BuildProcessManager mgr) { protected int dispatch(BuildProcessManager mgr) {
ActiveBuildStep[] active = new ActiveBuildStep[mgr.getMaxProcesses()]; int maxProcesses = mgr.getMaxProcesses();
for (int i = 0; i < active.length; i++) { Vector<ActiveBuildStep> active = new Vector<ActiveBuildStep>(Math.min(maxProcesses, 10), 10);
active[i] = null; // new ActiveBuildStep();
}
int activeCount = 0; int activeCount = 0;
int maxLevel = 0; int maxLevel = 0;
@ -330,9 +330,8 @@ public class ParallelBuilder {
proceed = false; proceed = false;
} else { } else {
// Check "active steps" list for completed ones // Check "active steps" list for completed ones
for (int i = 0; i < active.length; i++) { for (ActiveBuildStep buildStep : active) {
if (active[i] == null) continue; ProcessLauncher pl = buildStep.getLauncher();
ProcessLauncher pl = active[i].getLauncher();
if (pl == null) continue; if (pl == null) continue;
if (pl.queryState() == ProcessLauncher.STATE_DONE) { if (pl.queryState() == ProcessLauncher.STATE_DONE) {
// If process has terminated with error, break loop // If process has terminated with error, break loop
@ -343,8 +342,8 @@ public class ParallelBuilder {
break main_loop; break main_loop;
} }
// Try to launch next command for the current active step // Try to launch next command for the current active step
if (active[i].isDone()) continue; if (buildStep.isDone()) continue;
if (active[i].launchNextCmd(mgr)) { if (buildStep.launchNextCmd(mgr)) {
// Command has been launched. Check if process pool is not maximized yet // Command has been launched. Check if process pool is not maximized yet
if (!mgr.hasEmpty()) { if (!mgr.hasEmpty()) {
proceed = false; proceed = false;
@ -352,7 +351,7 @@ public class ParallelBuilder {
} }
} else { } else {
// Command has not been launched: step complete // Command has not been launched: step complete
refreshOutputs(active[i].getStep()); refreshOutputs(buildStep.getStep());
activeCount--; activeCount--;
monitor.worked(1); monitor.worked(1);
} }
@ -371,7 +370,7 @@ public class ParallelBuilder {
} }
// Check if we need to schedule another process // 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 // Need to schedule another process
Iterator<BuildQueueElement> iter = queue.iterator(); Iterator<BuildQueueElement> iter = queue.iterator();
@ -379,8 +378,8 @@ public class ParallelBuilder {
while (iter.hasNext()) { while (iter.hasNext()) {
BuildQueueElement elem = iter.next(); BuildQueueElement elem = iter.next();
// If "active steps" list is full, then break loop // If "active steps" list reaches maximum, then break loop
if (activeCount == active.length) if (activeCount == maxProcesses)
break; break;
// If current element's level exceeds maximum level of currently built // If current element's level exceeds maximum level of currently built
@ -389,14 +388,13 @@ public class ParallelBuilder {
break; break;
//Check if all prerequisites are built //Check if all prerequisites are built
IBuildResource[] res = elem.getStep().getInputResources();
boolean prereqBuilt = true; boolean prereqBuilt = true;
for (int j = 0; j < res.length; j++) { for (IBuildResource bldRes : elem.getStep().getInputResources()) {
IBuildStep stp = res[j].getProducerStep(); // step which produces input for curr IBuildStep step = bldRes.getProducerStep(); // step which produces input for curr
boolean built = true; boolean built = true;
if (stp != stp.getBuildDescription().getInputStep()) { if (step != step.getBuildDescription().getInputStep()) {
for (int k = 0; k < active.length; k++) { for (ActiveBuildStep buildStep : active) {
if (active[k] != null && active[k].getStep().equals(stp) && !active[k].isDone()) { if (buildStep != null && buildStep.getStep().equals(step) && !buildStep.isDone()) {
built = false; built = false;
break; break;
} }
@ -415,10 +413,21 @@ public class ParallelBuilder {
// Remove element from the build queue and add it to the // Remove element from the build queue and add it to the
// "active steps" list. // "active steps" list.
iter.remove(); iter.remove();
for (int i = 0; i < active.length; i++) { for (int i = 0; i < maxProcesses; i++) {
if (active[i] == null || active[i].isDone()) { if (i >= active.size()) {
active[i] = new ActiveBuildStep(step); // add new item
if (active[i].launchNextCmd(mgr)) activeCount++; 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; break;
} }
} }

View file

@ -64,7 +64,6 @@ import org.eclipse.cdt.managedbuilder.macros.IReservedMacroNameSupplier;
import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator;
import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator2; import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator2;
import org.eclipse.cdt.managedbuilder.makegen.gnu.GnuMakefileGenerator; 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.IProject;
import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.Assert;
@ -81,6 +80,7 @@ import org.eclipse.core.variables.VariablesPlugin;
import org.osgi.framework.Version; import org.osgi.framework.Version;
public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider<Builder>, IRealBuildObjectAssociation { public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider<Builder>, IRealBuildObjectAssociation {
public static final int UNLIMITED_JOBS = Integer.MAX_VALUE;
private static final String EMPTY_STRING = ""; //$NON-NLS-1$ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
// Superclass // Superclass
@ -624,7 +624,7 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
if (jobsNumber <= 0) if (jobsNumber <= 0)
return VALUE_OPTIMAL; return VALUE_OPTIMAL;
if (jobsNumber.equals(Integer.MAX_VALUE)) if (jobsNumber.equals(UNLIMITED_JOBS))
return VALUE_UNLIMITED; return VALUE_UNLIMITED;
return jobsNumber.toString(); return jobsNumber.toString();
@ -634,12 +634,7 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
if (VALUE_OPTIMAL.equals(value)) { if (VALUE_OPTIMAL.equals(value)) {
parallelNumberAttribute = -getOptimalParallelJobNum(); parallelNumberAttribute = -getOptimalParallelJobNum();
} else if (VALUE_UNLIMITED.equals(value)) { } else if (VALUE_UNLIMITED.equals(value)) {
if (!isInternalBuilder()) { parallelNumberAttribute = UNLIMITED_JOBS;
parallelNumberAttribute = Integer.MAX_VALUE;
} else {
ManagedBuilderCorePlugin.error("'unlimited' number of jobs is not allowed for Internal Builder, switching to 'optimal'");
parallelNumberAttribute = -getOptimalParallelJobNum();
}
} else { } else {
try { try {
parallelNumberAttribute = Integer.decode(value); parallelNumberAttribute = Integer.decode(value);
@ -654,7 +649,7 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
parallelNumberAttribute = -getOptimalParallelJobNum(); parallelNumberAttribute = -getOptimalParallelJobNum();
} else { } else {
// unlimited for External Builder // 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 // "unlimited" number of jobs results in not adding the number to parallelization cmd
// that behavior corresponds that of "make" flag "-j". // 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
* <pre> * <pre>
* Status Returns * Status Returns
* No parallel 1 * No parallel 1
* Optimal -CPU# (negative number of processors) * Optimal -CPU# (negative number of processors)
* Specific >0 (positive number) * Specific >0 (positive number)
* Unlimited Integer.MAX (N/A for Internal Builder) * Unlimited Builder.UNLIMITED_JOBS
* </pre> * </pre>
*/ */
public int getParallelizationNumAttribute() { public int getParallelizationNumAttribute() {
@ -2570,10 +2565,6 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
setArgumentsAttribute(updatedArgs); setArgumentsAttribute(updatedArgs);
} }
if (jobs == Integer.MAX_VALUE && isInternalBuilder()) {
// Internal Builder does not support "unlimited" jobs, switching to "optimal"
jobs = -1;
}
if (jobs > 0) { if (jobs > 0) {
parallelNumberAttribute = jobs; parallelNumberAttribute = jobs;
} else { } else {

View file

@ -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.BuildMacroException;
import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider;
import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier; 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.IFile;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDelta;

View file

@ -172,7 +172,7 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
public void widgetSelected(SelectionEvent event) { public void widgetSelected(SelectionEvent event) {
if (b_parallelUnlimited.getSelection()) { if (b_parallelUnlimited.getSelection()) {
setParallelDef(true); setParallelDef(true);
setParallelNumber(Integer.MAX_VALUE); setParallelNumber(Builder.UNLIMITED_JOBS);
updateButtons(); updateButtons();
} }
}}); }});
@ -347,9 +347,6 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
private void updateParallelBlock() { private void updateParallelBlock() {
// note: for multi-config selection bldr is from Active cfg // note: for multi-config selection bldr is from Active cfg
boolean isAnyInternalBuilder = bldr.isInternalBuilder();
boolean isAnyExternalBuilder = ! bldr.isInternalBuilder();
boolean isParallelSupported = bldr.supportsParallelBuild(); boolean isParallelSupported = bldr.supportsParallelBuild();
boolean isParallelOn = bldr.isParallelBuildOn(); boolean isParallelOn = bldr.isParallelBuildOn();
int triSelection = isParallelOn ? TRI_YES : TRI_NO; int triSelection = isParallelOn ? TRI_YES : TRI_NO;
@ -357,7 +354,6 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
int parallelizationNumInternal = bldr.getParallelizationNumAttribute(); int parallelizationNumInternal = bldr.getParallelizationNumAttribute();
int optimalParallelNumber = bldr.getOptimalParallelJobNum(); int optimalParallelNumber = bldr.getOptimalParallelJobNum();
int parallelNumber = bldr.getParallelizationNum(); int parallelNumber = bldr.getParallelizationNum();
boolean isUnlimited = parallelizationNumInternal == Integer.MAX_VALUE;
if (icfg instanceof ICMultiItemsHolder) { if (icfg instanceof ICMultiItemsHolder) {
IConfiguration[] cfgs = (IConfiguration[])((ICMultiItemsHolder)icfg).getItems(); IConfiguration[] cfgs = (IConfiguration[])((ICMultiItemsHolder)icfg).getItems();
@ -372,19 +368,15 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
isAnyParallelOn = isAnyParallelOn || builder.isParallelBuildOn(); isAnyParallelOn = isAnyParallelOn || builder.isParallelBuildOn();
isAnyParallelSupported = isAnyParallelSupported || builder.supportsParallelBuild(); isAnyParallelSupported = isAnyParallelSupported || builder.supportsParallelBuild();
isAnyInternalBuilder = isAnyInternalBuilder || builder.isInternalBuilder();
isAnyExternalBuilder = isAnyExternalBuilder || !builder.isInternalBuilder();
} }
// reset initial display to "optimal" to enhance user experience: // reset initial display to "optimal" to enhance user experience:
if ((!isParallelSupported && isAnyParallelSupported) // parallel is supported by other than Active cfg if ((!isParallelSupported && isAnyParallelSupported) // parallel is supported by other than Active cfg
|| (!isParallelOn && isAnyParallelOn) // prevent showing the 1 job as parallel in the spinner || (!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
) { ) {
isParallelSupported = true; isParallelSupported = true;
parallelizationNumInternal = -optimalParallelNumber; parallelizationNumInternal = -optimalParallelNumber;
parallelNumber = optimalParallelNumber; parallelNumber = optimalParallelNumber;
isUnlimited = false;
} }
if (isParallelSupported && isParallelDiffers) { if (isParallelSupported && isParallelDiffers) {
triSelection = TRI_UNKNOWN; triSelection = TRI_UNKNOWN;
@ -394,7 +386,7 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
b_parallel.setVisible(isParallelSupported); b_parallel.setVisible(isParallelSupported);
b_parallelOptimal.setVisible(isParallelSupported); b_parallelOptimal.setVisible(isParallelSupported);
b_parallelSpecific.setVisible(isParallelSupported); b_parallelSpecific.setVisible(isParallelSupported);
b_parallelUnlimited.setVisible(isParallelSupported && isAnyExternalBuilder); b_parallelUnlimited.setVisible(isParallelSupported);
s_parallelNumber.setVisible(isParallelSupported); s_parallelNumber.setVisible(isParallelSupported);
if (isParallelSupported) { if (isParallelSupported) {
@ -404,10 +396,11 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
b_parallelOptimal.setText(MessageFormat.format(Messages.BuilderSettingsTab_UseOptimalJobs, optimalParallelNumber)); b_parallelOptimal.setText(MessageFormat.format(Messages.BuilderSettingsTab_UseOptimalJobs, optimalParallelNumber));
b_parallelOptimal.setEnabled(isParallelSelected); b_parallelOptimal.setEnabled(isParallelSelected);
b_parallelSpecific.setEnabled(isParallelSelected); b_parallelSpecific.setEnabled(isParallelSelected);
b_parallelUnlimited.setEnabled(isParallelSelected && !isAnyInternalBuilder); b_parallelUnlimited.setEnabled(isParallelSelected);
if (isParallelSelected) { if (isParallelSelected) {
boolean isOptimal = parallelizationNumInternal <= 0; boolean isOptimal = parallelizationNumInternal <= 0;
boolean isUnlimited = parallelizationNumInternal == Builder.UNLIMITED_JOBS;
b_parallelOptimal.setSelection(isOptimal); b_parallelOptimal.setSelection(isOptimal);
b_parallelSpecific.setSelection(!isOptimal && !isUnlimited); b_parallelSpecific.setSelection(!isOptimal && !isUnlimited);