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:
parent
f04bd57f83
commit
d4c2ce5e98
6 changed files with 83 additions and 93 deletions
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue