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;
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 {

View file

@ -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,15 +25,12 @@ 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 Vector<ProcessLauncher> processes;
protected int maxProcesses;
/**
@ -47,7 +45,7 @@ public class BuildProcessManager {
err = _err;
show = _show;
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
*/
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

View file

@ -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<ActiveBuildStep> active = new Vector<ActiveBuildStep>(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<BuildQueueElement> 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;
}
}

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.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<Builder>, 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
* <pre>
* 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
* </pre>
*/
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 {

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.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;

View file

@ -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);