From e6cb997b2baadec318357d48ee8fb3e2835ce437 Mon Sep 17 00:00:00 2001
From: Jaroslav Keznikl
Date: Thu, 6 Feb 2014 14:54:21 +0100
Subject: [PATCH] support for non-periodic events & property-based jdeeco setup
in the sim
---
.../cuni/mff/d3s/deeco/DeecoProperties.java | 13 ++
.../deeco/model/runtime/api/TimeTrigger.java | 78 +++++++
.../model/runtime/impl/TimeTriggerImpl.java | 217 ++++++++++++++++++
.../mff/d3s/deeco/network/PublisherTask.java | 4 +-
.../scheduler/SingleThreadedScheduler.java | 14 --
.../d3s/jdeeco/simulation/demo/Leader.java | 1 -
.../mff/d3s/jdeeco/simulation/demo/Main.java | 12 +-
.../demo/MemberDataAggregation.java | 3 -
.../d3s/jdeeco/simulation/jni/JNITest.java | 8 +-
.../cuni/mff/d3s/deeco/simulation/Host.java | 9 +-
.../mff/d3s/deeco/simulation/Simulation.java | 6 +-
.../simulation/SimulationRuntimeBuilder.java | 18 +-
.../scheduler/SimulationScheduler.java | 46 ++--
13 files changed, 370 insertions(+), 59 deletions(-)
create mode 100644 jdeeco-core/src/cz/cuni/mff/d3s/deeco/DeecoProperties.java
create mode 100644 jdeeco-core/src/cz/cuni/mff/d3s/deeco/model/runtime/api/TimeTrigger.java
create mode 100644 jdeeco-core/src/cz/cuni/mff/d3s/deeco/model/runtime/impl/TimeTriggerImpl.java
diff --git a/jdeeco-core/src/cz/cuni/mff/d3s/deeco/DeecoProperties.java b/jdeeco-core/src/cz/cuni/mff/d3s/deeco/DeecoProperties.java
new file mode 100644
index 000000000..10521cb35
--- /dev/null
+++ b/jdeeco-core/src/cz/cuni/mff/d3s/deeco/DeecoProperties.java
@@ -0,0 +1,13 @@
+package cz.cuni.mff.d3s.deeco;
+
+public final class DeecoProperties {
+ public static final String PACKET_SIZE = "deeco.publish.packetsize";
+ public static final String PUBLISHING_PERIOD = "deeco.publish.period";
+ public static final String USE_INDIVIDUAL_KNOWLEDGE_PUBLISHING = "deeco.publish.individual";
+ public static final String DISABLE_BOUNDARY_CONDITIONS = "deeco.boundary.disable";
+ public static final String DISABLE_GOSSIP_CONDITION = "deeco.gossipcnd.disable";
+ public static final String GOSSIP_CONDITION_RSSI = "deeco.gossipcnd.rssi";
+ public static final String MESSAGE_CACHE_DEADLINE = "deeco.receive.cache.deadline";
+ public static final String MESSAGE_CACHE_WIPE_PERIOD = "deeco.receive.cache.period";
+
+}
diff --git a/jdeeco-core/src/cz/cuni/mff/d3s/deeco/model/runtime/api/TimeTrigger.java b/jdeeco-core/src/cz/cuni/mff/d3s/deeco/model/runtime/api/TimeTrigger.java
new file mode 100644
index 000000000..869af8b6d
--- /dev/null
+++ b/jdeeco-core/src/cz/cuni/mff/d3s/deeco/model/runtime/api/TimeTrigger.java
@@ -0,0 +1,78 @@
+/**
+ */
+package cz.cuni.mff.d3s.deeco.model.runtime.api;
+
+
+/**
+ *
+ * A representation of the model object 'Time Trigger'.
+ *
+ *
+ *
+ * The following features are supported:
+ *
+ * - {@link cz.cuni.mff.d3s.deeco.model.runtime.api.TimeTrigger#getPeriod Period}
+ * - {@link cz.cuni.mff.d3s.deeco.model.runtime.api.TimeTrigger#getOffset Offset}
+ *
+ *
+ *
+ * @see cz.cuni.mff.d3s.deeco.model.runtime.meta.RuntimeMetadataPackage#getTimeTrigger()
+ * @model
+ * @generated
+ */
+public interface TimeTrigger extends Trigger {
+ /**
+ * Returns the value of the 'Period' attribute.
+ * The default value is "0"
.
+ *
+ *
+ * If the meaning of the 'Period' attribute isn't clear,
+ * there really should be more of a description here...
+ *
+ *
+ * @return the value of the 'Period' attribute.
+ * @see #setPeriod(long)
+ * @see cz.cuni.mff.d3s.deeco.model.runtime.meta.RuntimeMetadataPackage#getTimeTrigger_Period()
+ * @model default="0" required="true"
+ * @generated
+ */
+ long getPeriod();
+
+ /**
+ * Sets the value of the '{@link cz.cuni.mff.d3s.deeco.model.runtime.api.TimeTrigger#getPeriod Period}' attribute.
+ *
+ *
+ * @param value the new value of the 'Period' attribute.
+ * @see #getPeriod()
+ * @generated
+ */
+ void setPeriod(long value);
+
+ /**
+ * Returns the value of the 'Offset' attribute.
+ * The default value is "0"
.
+ *
+ *
+ * If the meaning of the 'Offset' attribute isn't clear,
+ * there really should be more of a description here...
+ *
+ *
+ * @return the value of the 'Offset' attribute.
+ * @see #setOffset(long)
+ * @see cz.cuni.mff.d3s.deeco.model.runtime.meta.RuntimeMetadataPackage#getTimeTrigger_Offset()
+ * @model default="0" required="true"
+ * @generated
+ */
+ long getOffset();
+
+ /**
+ * Sets the value of the '{@link cz.cuni.mff.d3s.deeco.model.runtime.api.TimeTrigger#getOffset Offset}' attribute.
+ *
+ *
+ * @param value the new value of the 'Offset' attribute.
+ * @see #getOffset()
+ * @generated
+ */
+ void setOffset(long value);
+
+} // TimeTrigger
diff --git a/jdeeco-core/src/cz/cuni/mff/d3s/deeco/model/runtime/impl/TimeTriggerImpl.java b/jdeeco-core/src/cz/cuni/mff/d3s/deeco/model/runtime/impl/TimeTriggerImpl.java
new file mode 100644
index 000000000..aa1ed3813
--- /dev/null
+++ b/jdeeco-core/src/cz/cuni/mff/d3s/deeco/model/runtime/impl/TimeTriggerImpl.java
@@ -0,0 +1,217 @@
+/**
+ */
+package cz.cuni.mff.d3s.deeco.model.runtime.impl;
+
+import cz.cuni.mff.d3s.deeco.model.runtime.api.TimeTrigger;
+
+import cz.cuni.mff.d3s.deeco.model.runtime.meta.RuntimeMetadataPackage;
+
+import org.eclipse.emf.common.notify.Notification;
+
+import org.eclipse.emf.ecore.EClass;
+
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+
+/**
+ *
+ * An implementation of the model object 'Time Trigger'.
+ *
+ *
+ * The following features are implemented:
+ *
+ * - {@link cz.cuni.mff.d3s.deeco.model.runtime.impl.TimeTriggerImpl#getPeriod Period}
+ * - {@link cz.cuni.mff.d3s.deeco.model.runtime.impl.TimeTriggerImpl#getOffset Offset}
+ *
+ *
+ *
+ * @generated
+ */
+public class TimeTriggerImpl extends TriggerImpl implements TimeTrigger {
+ /**
+ * The default value of the '{@link #getPeriod() Period}' attribute.
+ *
+ *
+ * @see #getPeriod()
+ * @generated
+ * @ordered
+ */
+ protected static final long PERIOD_EDEFAULT = 0L;
+
+ /**
+ * The cached value of the '{@link #getPeriod() Period}' attribute.
+ *
+ *
+ * @see #getPeriod()
+ * @generated
+ * @ordered
+ */
+ protected long period = PERIOD_EDEFAULT;
+
+ /**
+ * The default value of the '{@link #getOffset() Offset}' attribute.
+ *
+ *
+ * @see #getOffset()
+ * @generated
+ * @ordered
+ */
+ protected static final long OFFSET_EDEFAULT = 0L;
+
+ /**
+ * The cached value of the '{@link #getOffset() Offset}' attribute.
+ *
+ *
+ * @see #getOffset()
+ * @generated
+ * @ordered
+ */
+ protected long offset = OFFSET_EDEFAULT;
+
+ /**
+ *
+ *
+ * @generated
+ */
+ protected TimeTriggerImpl() {
+ super();
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ protected EClass eStaticClass() {
+ return RuntimeMetadataPackage.Literals.TIME_TRIGGER;
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ public long getPeriod() {
+ return period;
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ public void setPeriod(long newPeriod) {
+ long oldPeriod = period;
+ period = newPeriod;
+ if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, RuntimeMetadataPackage.TIME_TRIGGER__PERIOD, oldPeriod, period));
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ public long getOffset() {
+ return offset;
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ public void setOffset(long newOffset) {
+ long oldOffset = offset;
+ offset = newOffset;
+ if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, RuntimeMetadataPackage.TIME_TRIGGER__OFFSET, oldOffset, offset));
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public Object eGet(int featureID, boolean resolve, boolean coreType) {
+ switch (featureID) {
+ case RuntimeMetadataPackage.TIME_TRIGGER__PERIOD:
+ return getPeriod();
+ case RuntimeMetadataPackage.TIME_TRIGGER__OFFSET:
+ return getOffset();
+ }
+ return super.eGet(featureID, resolve, coreType);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public void eSet(int featureID, Object newValue) {
+ switch (featureID) {
+ case RuntimeMetadataPackage.TIME_TRIGGER__PERIOD:
+ setPeriod((Long)newValue);
+ return;
+ case RuntimeMetadataPackage.TIME_TRIGGER__OFFSET:
+ setOffset((Long)newValue);
+ return;
+ }
+ super.eSet(featureID, newValue);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public void eUnset(int featureID) {
+ switch (featureID) {
+ case RuntimeMetadataPackage.TIME_TRIGGER__PERIOD:
+ setPeriod(PERIOD_EDEFAULT);
+ return;
+ case RuntimeMetadataPackage.TIME_TRIGGER__OFFSET:
+ setOffset(OFFSET_EDEFAULT);
+ return;
+ }
+ super.eUnset(featureID);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public boolean eIsSet(int featureID) {
+ switch (featureID) {
+ case RuntimeMetadataPackage.TIME_TRIGGER__PERIOD:
+ return period != PERIOD_EDEFAULT;
+ case RuntimeMetadataPackage.TIME_TRIGGER__OFFSET:
+ return offset != OFFSET_EDEFAULT;
+ }
+ return super.eIsSet(featureID);
+ }
+
+ /**
+ *
+ *
+ * @generated
+ */
+ @Override
+ public String toString() {
+ if (eIsProxy()) return super.toString();
+
+ StringBuffer result = new StringBuffer(super.toString());
+ result.append(" (period: ");
+ result.append(period);
+ result.append(", offset: ");
+ result.append(offset);
+ result.append(')');
+ return result.toString();
+ }
+
+} //TimeTriggerImpl
diff --git a/jdeeco-core/src/cz/cuni/mff/d3s/deeco/network/PublisherTask.java b/jdeeco-core/src/cz/cuni/mff/d3s/deeco/network/PublisherTask.java
index 15fb71472..eb2aca6d9 100644
--- a/jdeeco-core/src/cz/cuni/mff/d3s/deeco/network/PublisherTask.java
+++ b/jdeeco-core/src/cz/cuni/mff/d3s/deeco/network/PublisherTask.java
@@ -43,8 +43,10 @@ private static class PublisherTrigger extends TimeTriggerExt {
public PublisherTrigger(long period, long seed) {
super();
setPeriod(period);
- setOffset(0);
random = new Random(seed);
+ // for experiments, publisher task has a random start offset up to its period
+ setOffset(random.nextInt((int) period));
+
}
@Override
diff --git a/jdeeco-core/src/cz/cuni/mff/d3s/deeco/scheduler/SingleThreadedScheduler.java b/jdeeco-core/src/cz/cuni/mff/d3s/deeco/scheduler/SingleThreadedScheduler.java
index fb9c507bf..435f888e0 100644
--- a/jdeeco-core/src/cz/cuni/mff/d3s/deeco/scheduler/SingleThreadedScheduler.java
+++ b/jdeeco-core/src/cz/cuni/mff/d3s/deeco/scheduler/SingleThreadedScheduler.java
@@ -233,20 +233,6 @@ void scheduleAfter(SchedulerEvent event, long delay) {
queue.notify();
}
-//
-// /**
-// * Note that this method has to be explicitly protected by queue's monitor!
-// */
-// void scheduleNow(SchedulerEvent event, long period) {
-// event.nextExecutionTime = System.currentTimeMillis(); // start immediately
-// event.period = period;
-// event.state = SchedulerEvent.SCHEDULED;
-//
-// queue.add(event);
-// if (queue.getMin() == event)
-// queue.notify();
-// }
-
@Override
public void removeTask(Task task) {
diff --git a/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/demo/Leader.java b/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/demo/Leader.java
index f46cd96c9..395db02fd 100644
--- a/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/demo/Leader.java
+++ b/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/demo/Leader.java
@@ -22,7 +22,6 @@
import cz.cuni.mff.d3s.deeco.annotations.In;
import cz.cuni.mff.d3s.deeco.annotations.InOut;
-import cz.cuni.mff.d3s.deeco.annotations.Out;
import cz.cuni.mff.d3s.deeco.annotations.PeriodicScheduling;
import cz.cuni.mff.d3s.deeco.annotations.Process;
import cz.cuni.mff.d3s.deeco.annotations.TriggerOnChange;
diff --git a/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/demo/Main.java b/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/demo/Main.java
index 83a65d645..50f214a20 100644
--- a/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/demo/Main.java
+++ b/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/demo/Main.java
@@ -28,10 +28,6 @@
*/
public class Main {
- static double POSITION_FACTOR = 1;
- static int PACKET_SIZE = 2000;
- static int PUBLISHING_PERIOD = 1000;
-
static String OMNET_CONFIG_TEMPLATE = "omnetpp.ini.templ";
static String OMNET_CONFIG_PATH = "omnetpp.ini";
@@ -80,22 +76,22 @@ public static void main(String[] args) throws AnnotationProcessorException, IOEx
omnetConfig.append(String.format(
"**.node[%s].mobility.initialX = %dm\n",
- i, (int) (component.position.x * POSITION_FACTOR)));
+ i, (int) (component.position.x)));
omnetConfig.append(String.format(
"**.node[%s].mobility.initialY = %dm\n",
- i, (int) (component.position.y * POSITION_FACTOR)));
+ i, (int) (component.position.y)));
omnetConfig.append(String.format(
"**.node[%s].mobility.initialZ = 0m\n", i));
omnetConfig.append(String.format(
"**.node[%s].appl.id = \"%s\"\n\n", i, component.id));
- Host host = sim.getHost(component.id, PACKET_SIZE);
+ Host host = sim.getHost(component.id);
hosts.add(host);
// there is only one component instance
model.getComponentInstances().get(0).getInternalData().put(PositionAwareComponent.HOST_REFERENCE, host);
- RuntimeFramework runtime = builder.build(host, model, PUBLISHING_PERIOD);
+ RuntimeFramework runtime = builder.build(host, model);
runtimes.add(runtime);
runtime.start();
i++;
diff --git a/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/demo/MemberDataAggregation.java b/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/demo/MemberDataAggregation.java
index 9f18a78e5..f1da0fd72 100644
--- a/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/demo/MemberDataAggregation.java
+++ b/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/demo/MemberDataAggregation.java
@@ -41,8 +41,6 @@
@PeriodicScheduling(1000)
public class MemberDataAggregation {
- private static final long serialVersionUID = 5991804902054860542L;
-
@Membership
public static boolean membership(
@In("member.teamId") String mteamId,
@@ -70,7 +68,6 @@ public static void map(@In("member.id") String mId,
@CommunicationBoundary
public static boolean boundary(KnowledgeData data, ReadOnlyKnowledgeManager sender) throws KnowledgeNotFoundException {
-// return true;
KnowledgePath kpPosition = KnowledgePathBuilder.buildSimplePath("position");
KnowledgePath kpTeam = KnowledgePathBuilder.buildSimplePath("teamId");
//Position ownerPos = (Position) data.getKnowledge().getValue(kpPosition);
diff --git a/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/jni/JNITest.java b/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/jni/JNITest.java
index ca7f202b0..ad5f3b977 100644
--- a/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/jni/JNITest.java
+++ b/jdeeco-simulation-demo/src/cz/cuni/mff/d3s/jdeeco/simulation/jni/JNITest.java
@@ -12,17 +12,17 @@ public static void main(String[] args) throws Exception {
simulation.initialize(); //loads Library
- Host h0 = simulation.getHost("0", 1000);
+ Host h0 = simulation.getHost("0");
KnowledgeDataManager kr = new KnowledgeDataManager(h0);
kr.sendDummyData();
- Host h1 = simulation.getHost("1", 1000);
+ Host h1 = simulation.getHost("1");
kr = new KnowledgeDataManager(h1);
- Host h2 = simulation.getHost("2", 1000);
+ Host h2 = simulation.getHost("2");
kr = new KnowledgeDataManager(h2);
- Host h3 = simulation.getHost("3", 1000);
+ Host h3 = simulation.getHost("3");
kr = new KnowledgeDataManager(h3);
simulation.run("Cmdenv", "omnetpp-jni.ini");
diff --git a/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/Host.java b/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/Host.java
index 1992d0d95..ec3a0e6e1 100644
--- a/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/Host.java
+++ b/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/Host.java
@@ -13,6 +13,7 @@
*
*/
public class Host extends PacketSender implements CurrentTimeProvider {
+
private SimulationTimeEventListener timeEventListener = null;
@@ -20,14 +21,16 @@ public class Host extends PacketSender implements CurrentTimeProvider {
private final Simulation simulation;
private final String id;
- protected Host(Simulation simulation, String id, int packetSize) {
- super(id, packetSize);
+ protected Host(Simulation simulation, String id) {
+ super(id);
this.simulation = simulation;
this.id = id;
- this.packetReceiver = new PacketReceiver(id, packetSize);
+ this.packetReceiver = new PacketReceiver(id);
this.packetReceiver.setCurrentTimeProvider(this);
simulation.register(this, id);
}
+
+
public PacketReceiver getPacketReceiver() {
return packetReceiver;
diff --git a/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/Simulation.java b/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/Simulation.java
index cd3d03b73..582d9ef22 100644
--- a/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/Simulation.java
+++ b/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/Simulation.java
@@ -62,13 +62,15 @@ public void initialize() {
System.loadLibrary("libintegration");
}
+
+
/**
* Creates new instance of the {@link Host}.
*
* @return new host instance
*/
- public Host getHost(String id, int packetSize) {
- return new Host(this, id, packetSize);
+ public Host getHost(String id) {
+ return new Host(this, id);
}
// Wrapper methods we may need them.
diff --git a/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/SimulationRuntimeBuilder.java b/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/SimulationRuntimeBuilder.java
index 234194815..1c29d85e3 100644
--- a/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/SimulationRuntimeBuilder.java
+++ b/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/SimulationRuntimeBuilder.java
@@ -3,9 +3,7 @@
import cz.cuni.mff.d3s.deeco.executor.Executor;
import cz.cuni.mff.d3s.deeco.executor.SameThreadExecutor;
import cz.cuni.mff.d3s.deeco.knowledge.KnowledgeManagerContainer;
-import cz.cuni.mff.d3s.deeco.model.runtime.api.PeriodicTrigger;
import cz.cuni.mff.d3s.deeco.model.runtime.api.RuntimeMetadata;
-import cz.cuni.mff.d3s.deeco.model.runtime.meta.RuntimeMetadataFactory;
import cz.cuni.mff.d3s.deeco.network.KnowledgeDataManager;
import cz.cuni.mff.d3s.deeco.network.PublisherTask;
import cz.cuni.mff.d3s.deeco.runtime.RuntimeFramework;
@@ -15,8 +13,7 @@
public class SimulationRuntimeBuilder {
- public RuntimeFramework build(Host host, RuntimeMetadata model,
- long publishingPeriod) {
+ public RuntimeFramework build(Host host, RuntimeMetadata model) {
if (model == null) {
throw new IllegalArgumentException("Model must not be null");
}
@@ -31,13 +28,22 @@ public RuntimeFramework build(Host host, RuntimeMetadata model,
// Set up the host container
KnowledgeManagerContainer container = new KnowledgeManagerContainer();
- KnowledgeDataManager kdManager = new KnowledgeDataManager(container, host, model.getEnsembleDefinitions(), host.getId(), scheduler);
+ KnowledgeDataManager kdManager = new KnowledgeDataManager(
+ container,
+ host,
+ model.getEnsembleDefinitions(),
+ host.getId(),
+ scheduler);
// Bind KnowledgeDataReceiver with PacketDataReceiver
host.getPacketReceiver().setKnowledgeDataReceiver(kdManager);
// Set up the publisher task
- PublisherTask publisherTask = new PublisherTask(scheduler, kdManager, publishingPeriod, host.getId());
+ PublisherTask publisherTask = new PublisherTask(
+ scheduler,
+ kdManager,
+ host.getId());
+
// Add publisher task to the scheduler
scheduler.addTask(publisherTask);
diff --git a/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/scheduler/SimulationScheduler.java b/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/scheduler/SimulationScheduler.java
index cd3da56e4..62981fbf4 100644
--- a/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/scheduler/SimulationScheduler.java
+++ b/jdeeco-simulation/src/cz/cuni/mff/d3s/deeco/simulation/scheduler/SimulationScheduler.java
@@ -74,16 +74,12 @@ public void addTask(Task task) {
throw new IllegalArgumentException("The task cannot be null");
if (allTasks.contains(task))
return;
- if (task.getPeriodicTrigger() != null) {
+ if (task.getTimeTrigger() != null) {
SchedulerEvent event = new SchedulerEvent(task,
- task.getPeriodicTrigger());
-
- // TODO: for experiments, every periodic task has a random start delay up to its period
- long lastProcessExecutionTimeBackup = lastProcessExecutionTime;
- lastProcessExecutionTime = rnd.nextInt((int) task.getPeriodicTrigger().getPeriod());
- scheduleNow(event, task.getPeriodicTrigger().getPeriod());
- lastProcessExecutionTime = lastProcessExecutionTimeBackup;
+ task.getTimeTrigger());
+ scheduleAfter(event, task.getTimeTrigger().getOffset());
+
periodicEvents.put(task, event);
}
task.setTriggerListener(new TaskTriggerListener() {
@@ -96,7 +92,9 @@ public void triggered(Task task, Trigger trigger) {
}
if (isScheduled) {
measureExecutionTime();
- scheduleNow(new SchedulerEvent(task, trigger), 0);
+ // schedule immediately, regardless the actual runtime of
+ // the process that triggered this trigger
+ scheduleAfter(new SchedulerEvent(task, trigger), 0);
}
}
});
@@ -130,8 +128,12 @@ public void executionFailed(Task task, Exception e) {
@Override
public void executionCompleted(Task task) {
measureExecutionTime();
- if (task.getPeriodicTrigger() != null && lastProcessExecutionTime > task.getPeriodicTrigger().getPeriod()) {
- Log.e("Task " + task.toString() + " has greater actual execution time than its period (" + task.getPeriodicTrigger().getPeriod() + ")");
+ if ((task.getTimeTrigger() != null)
+ && (task.getTimeTrigger().getPeriod() > 0)
+ && (lastProcessExecutionTime > task.getTimeTrigger().getPeriod())) {
+ Log.e("Periodic task " + task.toString()
+ + " has greater actual execution time than its period ("
+ + task.getTimeTrigger().getPeriod() + ")");
}
registerNextExecution();
}
@@ -153,17 +155,18 @@ public void at(long time) {
//System.out.println("Scheduler " +host.getId()+" at: "+time+" called with queue: " + Arrays.toString(queue.toArray()));
SchedulerEvent event;
while ((event = queue.first()) != null) {
- // if notified too early
+ // if notified too early (or already processed all events scheduled
+ // for the current time)
if (event.nextExecutionTime > time)
break;
// The time is right to execute the next task
pop();
- if (event.period != 0) {
+ if (event.periodic) {
// schedule for the next period (the period might be variable,
// that's we query the trigger)
event.nextExecutionTime = event.nextExecutionTime
- + event.executable.getPeriodicTrigger().getPeriod();
+ + event.executable.getTimeTrigger().getPeriod();
push(event);
}
if (executor != null) {
@@ -185,10 +188,19 @@ public long getCurrentTime() {
// ------Private methods--------
- private void scheduleNow(SchedulerEvent event, long period) {
- event.period = period;
- event.nextExecutionTime = host.getCurrentTime() + lastProcessExecutionTime;
+// private void scheduleNow(SchedulerEvent event, long period) {
+// event.period = period;
+// event.nextExecutionTime = host.getCurrentTime() + lastProcessExecutionTime;
+// push(event);
+// }
+
+ /**
+ * Note that this method has to be explicitly protected by queue's monitor!
+ */
+ void scheduleAfter(SchedulerEvent event, long delay) {
+ event.nextExecutionTime = host.getCurrentTime() + delay;
push(event);
+
}
private void registerNextExecution() {