Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2019-06-06 18:11:38 +0000
committerThomas Watson2019-06-10 13:42:42 +0000
commitea9b6a9a5eb69d9428a5cf9ea337541a009f4751 (patch)
treed99d9dfaf49409add7e9f172afa53dbf120c55a9 /bundles/org.eclipse.osgi
parent7e858cf2d9b52934e943b584b0975eeda8e27fb3 (diff)
downloadrt.equinox.framework-ea9b6a9a5eb69d9428a5cf9ea337541a009f4751.tar.gz
rt.equinox.framework-ea9b6a9a5eb69d9428a5cf9ea337541a009f4751.tar.xz
rt.equinox.framework-ea9b6a9a5eb69d9428a5cf9ea337541a009f4751.zip
Bug 548075 - Ability to control if bundles are activated in parallelI20190610-1800
Add a new option equinox.start.level.restrict.parallel which is false by default. Setting this value to true requires that the method Module.setParallelActivation must be called with true to enable parallel activation for the Module. The parallel activation setting is persistent across restarts. Tests have been added to test for persistence of the setting and that the setting is applied correctly when activating bundles from the start-level implementation. Change-Id: I20ea5807edfd10762fc5758317d946946299d5a7 Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
Diffstat (limited to 'bundles/org.eclipse.osgi')
-rw-r--r--bundles/org.eclipse.osgi/META-INF/MANIFEST.MF4
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java35
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java48
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java2
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java1
-rw-r--r--bundles/org.eclipse.osgi/pom.xml2
6 files changed, 74 insertions, 18 deletions
diff --git a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
index fc081bfdb..768511155 100644
--- a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2
Export-Package: org.eclipse.core.runtime.adaptor;x-friends:="org.eclipse.core.runtime",
org.eclipse.core.runtime.internal.adaptor;x-internal:=true,
org.eclipse.equinox.log;version="1.1";uses:="org.osgi.framework,org.osgi.service.log",
- org.eclipse.osgi.container;version="1.4";
+ org.eclipse.osgi.container;version="1.5";
uses:="org.eclipse.osgi.report.resolution,
org.osgi.framework.wiring,
org.osgi.framework.startlevel,
@@ -101,7 +101,7 @@ Bundle-Activator: org.eclipse.osgi.internal.framework.SystemBundleActivator
Bundle-Description: %systemBundle
Bundle-Copyright: %copyright
Bundle-Vendor: %eclipse.org
-Bundle-Version: 3.14.100.qualifier
+Bundle-Version: 3.15.0.qualifier
Bundle-Localization: systembundle
Bundle-DocUrl: http://www.eclipse.org
Eclipse-ExtensibleAPI: true
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java
index 3d6cfbf5b..4a8d7e723 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java
@@ -151,7 +151,12 @@ public abstract class Module implements BundleReference, BundleStartLevel, Compa
/**
* The module has been set to use its activation policy.
*/
- USE_ACTIVATION_POLICY
+ USE_ACTIVATION_POLICY,
+ /**
+ * The module has been set for parallel activation from start-level
+ * @since 3.15
+ */
+ PARALLEL_ACTIVATION
}
/**
@@ -693,11 +698,37 @@ public abstract class Module implements BundleReference, BundleStartLevel, Compa
private void persistStopOptions(StopOptions... options) {
if (StopOptions.TRANSIENT.isContained(options))
return;
- settings.clear();
+ settings.remove(Settings.USE_ACTIVATION_POLICY);
+ settings.remove(Settings.AUTO_START);
+ revisions.getContainer().moduleDatabase.persistSettings(settings, this);
+ }
+
+ /**
+ * Set if this module should be activated in parallel with other modules that have
+ * the same {@link #getStartLevel() start level}.
+ * @param parallelActivation true if the module should be started in parallel; false otherwise
+ * @since 3.15
+ */
+ public void setParallelActivation(boolean parallelActivation) {
+ if (parallelActivation) {
+ settings.add(Settings.PARALLEL_ACTIVATION);
+ } else {
+ settings.remove(Settings.PARALLEL_ACTIVATION);
+ }
revisions.getContainer().moduleDatabase.persistSettings(settings, this);
}
/**
+ * Returns if this module should be activated in parallel with other modules that have
+ * the same {@link #getStartLevel() start level}.
+ * @return true if the module should be started in parallel; false otherwise
+ * @since 3.15
+ */
+ public boolean isParallelActivated() {
+ return settings.contains(Settings.PARALLEL_ACTIVATION);
+ }
+
+ /**
* The container is done with the revision and it has been completely removed.
* This method allows the resources behind the revision to be cleaned up.
* @param revision the revision to clean up
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java
index 319b21f5d..c248ff4e2 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java
@@ -131,6 +131,8 @@ public final class ModuleContainer implements DebugOptionsListener {
private final boolean autoStartOnResolve;
+ final boolean restrictParallelStart;
+
boolean DEBUG_MONITOR_LAZY = false;
boolean DEBUG_BUNDLE_START_TIME = false;
@@ -169,6 +171,7 @@ public final class ModuleContainer implements DebugOptionsListener {
autoStartOnResolveProp = Boolean.toString(true);
}
this.autoStartOnResolve = Boolean.parseBoolean(autoStartOnResolveProp);
+ this.restrictParallelStart = Boolean.parseBoolean(adaptor.getProperty(EquinoxConfiguration.PROP_EQUINOX_START_LEVEL_RESTRICT_PARALLEL));
}
/**
@@ -1713,7 +1716,9 @@ public final class ModuleContainer implements DebugOptionsListener {
long currentTimestamp = Long.MIN_VALUE;
if (newStartLevel > currentSL) {
List<Module> lazyStart = null;
+ List<Module> lazyStartParallel = null;
List<Module> eagerStart = null;
+ List<Module> eagerStartParallel = null;
for (int i = currentSL; i < newStartLevel; i++) {
int toStartLevel = i + 1;
activeStartLevel.set(toStartLevel);
@@ -1725,14 +1730,16 @@ public final class ModuleContainer implements DebugOptionsListener {
try {
sorted = moduleDatabase.getSortedModules(Sort.BY_START_LEVEL);
lazyStart = new ArrayList<>(sorted.size());
+ lazyStartParallel = new ArrayList<>(sorted.size());
eagerStart = new ArrayList<>(sorted.size());
- separateModulesByActivationPolicy(sorted, lazyStart, eagerStart);
+ eagerStartParallel = new ArrayList<>(sorted.size());
+ separateModulesByActivationPolicy(sorted, lazyStart, lazyStartParallel, eagerStart, eagerStartParallel);
currentTimestamp = moduleDatabase.getTimestamp();
} finally {
moduleDatabase.readUnlock();
}
}
- incStartLevel(toStartLevel, lazyStart, eagerStart);
+ incStartLevel(toStartLevel, lazyStart, lazyStartParallel, eagerStart, eagerStartParallel);
}
} else {
for (int i = currentSL; i > newStartLevel; i--) {
@@ -1765,26 +1772,38 @@ public final class ModuleContainer implements DebugOptionsListener {
}
}
- private void incStartLevel(int toStartLevel, List<Module> lazyStart, List<Module> eagerStart) {
- incStartLevel(toStartLevel, lazyStart);
- incStartLevel(toStartLevel, eagerStart);
+ private void incStartLevel(int toStartLevel, List<Module> lazyStart, List<Module> lazyStartParallel, List<Module> eagerStart, List<Module> eagerStartParallel) {
+ // start lazy activated first
+ // start parallel bundles first
+ incStartLevel(toStartLevel, lazyStartParallel, true);
+ incStartLevel(toStartLevel, lazyStart, false);
+ incStartLevel(toStartLevel, eagerStartParallel, true);
+ incStartLevel(toStartLevel, eagerStart, false);
}
- private void separateModulesByActivationPolicy(List<Module> sortedModules, List<Module> lazyStart, List<Module> eagerStart) {
+ private void separateModulesByActivationPolicy(List<Module> sortedModules, List<Module> lazyStart, List<Module> lazyStartParallel, List<Module> eagerStart, List<Module> eagerStartParallel) {
for (Module module : sortedModules) {
- if (module.isLazyActivate()) {
- lazyStart.add(module);
+ if (!restrictParallelStart || module.isParallelActivated()) {
+ if (module.isLazyActivate()) {
+ lazyStartParallel.add(module);
+ } else {
+ eagerStartParallel.add(module);
+ }
} else {
- eagerStart.add(module);
+ if (module.isLazyActivate()) {
+ lazyStart.add(module);
+ } else {
+ eagerStart.add(module);
+ }
}
}
}
- private void incStartLevel(final int toStartLevel, List<Module> candidatesToStart) {
+ private void incStartLevel(final int toStartLevel, List<Module> candidatesToStart, boolean inParallel) {
if (candidatesToStart.isEmpty()) {
return;
}
- List<Module> toStart = new ArrayList<>();
+ final List<Module> toStart = new ArrayList<>();
for (final Module module : candidatesToStart) {
if (isRefreshingSystemModule()) {
return;
@@ -1807,7 +1826,12 @@ public final class ModuleContainer implements DebugOptionsListener {
if (toStart.isEmpty()) {
return;
}
- final Executor executor = adaptor.getStartLevelExecutor();
+ final Executor executor = inParallel ? adaptor.getStartLevelExecutor() : new Executor() {
+ @Override
+ public void execute(Runnable command) {
+ command.run();
+ }
+ };
final CountDownLatch done = new CountDownLatch(toStart.size());
for (final Module module : toStart) {
executor.execute(new Runnable() {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java
index 6d7cfc4f5..a25ed24f1 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java
@@ -957,7 +957,7 @@ public class ModuleDatabase {
}
private static class Persistence {
- private static final int VERSION = 2;
+ private static final int VERSION = 3;
private static final byte NULL = 0;
private static final byte OBJECT = 1;
private static final byte INDEX = 2;
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java
index cdf363c88..a6f8da3a6 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java
@@ -227,6 +227,7 @@ public class EquinoxConfiguration implements EnvironmentInfo {
public static final String PROP_RESOLVER_THREAD_COUNT = "equinox.resolver.thead.count"; //$NON-NLS-1$
public static final String PROP_EQUINOX_RESOLVER_THREAD_COUNT = "equinox.resolver.thread.count"; //$NON-NLS-1$
public static final String PROP_EQUINOX_START_LEVEL_THREAD_COUNT = "equinox.start.level.thread.count"; //$NON-NLS-1$
+ public static final String PROP_EQUINOX_START_LEVEL_RESTRICT_PARALLEL = "equinox.start.level.restrict.parallel"; //$NON-NLS-1$
public static final String PROP_RESOLVER_REVISION_BATCH_SIZE = "equinox.resolver.revision.batch.size"; //$NON-NLS-1$
public static final String PROP_RESOLVER_BATCH_TIMEOUT = "equinox.resolver.batch.timeout"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.osgi/pom.xml b/bundles/org.eclipse.osgi/pom.xml
index 9ae03a65b..dffff72d5 100644
--- a/bundles/org.eclipse.osgi/pom.xml
+++ b/bundles/org.eclipse.osgi/pom.xml
@@ -19,7 +19,7 @@
</parent>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId>
- <version>3.14.100-SNAPSHOT</version>
+ <version>3.15.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>

Back to the top