new event scheduling api

This commit is contained in:
fros4943 2009-10-27 10:11:17 +00:00
parent a81f216acb
commit ed8867bcb5
12 changed files with 157 additions and 99 deletions

View file

@ -26,20 +26,22 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: MspClock.java,v 1.9 2009/05/26 14:31:07 fros4943 Exp $
* $Id: MspClock.java,v 1.10 2009/10/27 10:14:35 fros4943 Exp $
*/
package se.sics.cooja.mspmote.interfaces;
import java.util.Collection;
import javax.swing.JPanel;
import org.apache.log4j.Logger;
import org.jdom.Element;
import se.sics.cooja.*;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.Mote;
import se.sics.cooja.Simulation;
import se.sics.cooja.interfaces.Clock;
import se.sics.cooja.mspmote.MspMote;
import se.sics.mspsim.core.MSP430;
/**
* @author Fredrik Osterlind
@ -48,12 +50,12 @@ import se.sics.mspsim.core.MSP430;
public class MspClock extends Clock {
private static Logger logger = Logger.getLogger(MspClock.class);
private MspMote myMote;
private MSP430 cpu;
private Simulation simulation;
private long timeDrift; /* Microseconds */
public MspClock(Mote mote) {
myMote = (MspMote) mote;
cpu = myMote.getCPU();
simulation = mote.getSimulation();
}
public void setTime(long newTime) {
@ -61,19 +63,19 @@ public class MspClock extends Clock {
}
public long getTime() {
long time = (long) ((double)cpu.cycles * Simulation.MILLISECOND / MspMote.NR_CYCLES_PER_MSEC);
return time > 0 ? time : 0;
return simulation.getSimulationTime() + timeDrift;
}
public void setDrift(long drift) {
myMote.usDrift = drift;
timeDrift = drift;
}
public long getDrift() {
return myMote.usDrift;
return timeDrift;
}
public JPanel getInterfaceVisualizer() {
/* TODO Show current CPU speed */
return null;
}

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: SkyByteRadio.java,v 1.12 2009/05/26 14:33:30 fros4943 Exp $
* $Id: SkyByteRadio.java,v 1.13 2009/10/27 10:14:35 fros4943 Exp $
*/
package se.sics.cooja.mspmote.interfaces;
@ -173,6 +173,7 @@ public class SkyByteRadio extends Radio implements CustomDataRadio {
for (byte b: crossBufferedData) {
cc2420.receivedByte(b);
}
mote.requestImmediateWakeup();
crossBufferedData = null;
}
};
@ -217,6 +218,7 @@ public class SkyByteRadio extends Radio implements CustomDataRadio {
for (byte b: packetData) {
cc2420.receivedByte(b);
}
mote.requestImmediateWakeup();
}
/* Custom data radio support */
@ -232,6 +234,7 @@ public class SkyByteRadio extends Radio implements CustomDataRadio {
if (data instanceof CC2420RadioByte) {
lastIncomingByte = (CC2420RadioByte) data;
cc2420.receivedByte(lastIncomingByte.getPacketData()[0]);
mote.requestImmediateWakeup();
}
}

View file

@ -26,38 +26,44 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: SkySerial.java,v 1.16 2009/06/02 09:34:59 fros4943 Exp $
* $Id: SkySerial.java,v 1.17 2009/10/27 10:14:35 fros4943 Exp $
*/
package se.sics.cooja.mspmote.interfaces;
import java.util.*;
import java.util.Vector;
import org.apache.log4j.Logger;
import se.sics.cooja.*;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.Mote;
import se.sics.cooja.Simulation;
import se.sics.cooja.TimeEvent;
import se.sics.mspsim.core.*;
import se.sics.cooja.dialogs.SerialUI;
import se.sics.cooja.interfaces.SerialPort;
import se.sics.cooja.mspmote.SkyMote;
import se.sics.mspsim.core.IOUnit;
import se.sics.mspsim.core.USART;
import se.sics.mspsim.core.USARTListener;
/**
* @author Fredrik Osterlind
*/
@ClassDescription("Serial port")
public class SkySerial extends SerialUI implements SerialPort {
private static final long DELAY_INCOMING_DATA = 69; /* Corresponds to 115200 bit/s */
private static final long DELAY_INCOMING_DATA = 69; /* 115200 bit/s */
private static Logger logger = Logger.getLogger(SkySerial.class);
private Simulation simulation;
private SkyMote mote;
private USART usart;
private Vector<Byte> incomingData = new Vector<Byte>();
public SkySerial(Mote mote) {
this.mote = (SkyMote) mote;
this.simulation = mote.getSimulation();
/* Listen to port writes */
IOUnit ioUnit = this.mote.getCPU().getIOUnit("USART 1");
@ -78,7 +84,25 @@ public class SkySerial extends SerialUI implements SerialPort {
public void writeByte(byte b) {
incomingData.add(b);
mote.getSimulation().scheduleEvent(writeDataEvent, mote.getSimulation().getSimulationTime());
if (writeDataEvent.isScheduled()) {
return;
}
/* Simulation thread: schedule immediately */
if (simulation.isSimulationThread()) {
simulation.scheduleEvent(writeDataEvent, simulation.getSimulationTime());
return;
}
/* Non-simulation thread: poll */
simulation.invokeSimulationThread(new Runnable() {
public void run() {
if (writeDataEvent.isScheduled()) {
return;
}
simulation.scheduleEvent(writeDataEvent, simulation.getSimulationTime());
}
});
}
public void writeString(String s) {
@ -109,13 +133,14 @@ public class SkySerial extends SerialUI implements SerialPort {
b = incomingData.remove(0);
}
usart.byteReceived(b);
mote.requestImmediateWakeup();
}
private TimeEvent writeDataEvent = new TimeEvent(0) {
public void execute(long t) {
tryWriteNextByte();
if (!incomingData.isEmpty()) {
mote.getSimulation().scheduleEvent(this, t+DELAY_INCOMING_DATA);
simulation.scheduleEvent(this, t+DELAY_INCOMING_DATA);
}
}
};
@ -123,5 +148,4 @@ public class SkySerial extends SerialUI implements SerialPort {
public Mote getMote() {
return mote;
}
}

View file

@ -26,24 +26,39 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: TR1001Radio.java,v 1.13 2009/05/26 14:33:30 fros4943 Exp $
* $Id: TR1001Radio.java,v 1.14 2009/10/27 10:14:35 fros4943 Exp $
*/
package se.sics.cooja.mspmote.interfaces;
import java.util.*;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.apache.log4j.Logger;
import org.jdom.Element;
import se.sics.mspsim.core.*;
import se.sics.cooja.*;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.Mote;
import se.sics.cooja.RadioPacket;
import se.sics.cooja.Simulation;
import se.sics.cooja.TimeEvent;
import se.sics.cooja.interfaces.*;
import se.sics.cooja.interfaces.CustomDataRadio;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.interfaces.Radio;
import se.sics.cooja.mspmote.ESBMote;
import se.sics.mspsim.core.IOUnit;
import se.sics.mspsim.core.USART;
import se.sics.mspsim.core.USARTListener;
/**
* TR1001 radio interface on ESB platform. Assumes driver specifics such as
@ -133,9 +148,9 @@ public class TR1001Radio extends Radio implements USARTListener,
/* Convert to TR1001 packet data */
TR1001RadioByte[] byteArr = TR1001RadioPacketConverter.fromCoojaToTR1001(packet);
final ArrayList<TR1001RadioByte> byteList = new ArrayList<TR1001RadioByte>();
final ArrayDeque<TR1001RadioByte> byteList = new ArrayDeque<TR1001RadioByte>();
for (TR1001RadioByte b : byteArr) {
byteList.add(b);
byteList.addLast(b);
}
/* Feed incoming bytes to radio "slowly" via time events */
@ -143,10 +158,11 @@ public class TR1001Radio extends Radio implements USARTListener,
public void execute(long t) {
/* Stop receiving data when buffer is empty */
if (byteList.isEmpty() || isInterfered) {
byteList.clear();
return;
}
TR1001RadioByte b = byteList.remove(0);
TR1001RadioByte b = byteList.pop();
radioUSART.byteReceived(b.getByte());
mote.getSimulation().scheduleEvent(this, t + DELAY_BETWEEN_BYTES);
@ -196,9 +212,11 @@ public class TR1001Radio extends Radio implements USARTListener,
// Remember recent radio activity
millisSinceLastSend = 0;
mote.getSimulation().scheduleEvent(
followupTransmissionEvent,
mote.getSimulation().getSimulationTime() + Simulation.MILLISECOND);
if (!followupTransmissionEvent.isScheduled()) {
mote.getSimulation().scheduleEvent(
followupTransmissionEvent,
mote.getSimulation().getSimulationTime() + Simulation.MILLISECOND);
}
if (outgoingDataLength >= outgoingData.length) {
logger.warn("----- TR1001 DROPPING OUTGOING BYTE (buffer overflow) -----");

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ContikiButton.java,v 1.13 2009/05/26 14:24:20 fros4943 Exp $
* $Id: ContikiButton.java,v 1.14 2009/10/27 10:11:17 fros4943 Exp $
*/
package se.sics.cooja.contikimote.interfaces;
@ -127,7 +127,7 @@ public class ContikiButton extends Button implements ContikiMoteInterface {
moteMem.setByteValueOf("simButtonChanged", (byte) 1);
/* If mote is inactive, wake it up */
mote.scheduleImmediateWakeup();
mote.requestImmediateWakeup();
setChanged();
notifyObservers();
@ -141,7 +141,7 @@ public class ContikiButton extends Button implements ContikiMoteInterface {
moteMem.setByteValueOf("simButtonChanged", (byte) 1);
/* If mote is inactive, wake it up */
mote.scheduleImmediateWakeup();
mote.requestImmediateWakeup();
setChanged();
notifyObservers();

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ContikiPIR.java,v 1.7 2009/05/26 14:24:20 fros4943 Exp $
* $Id: ContikiPIR.java,v 1.8 2009/10/27 10:11:17 fros4943 Exp $
*/
package se.sics.cooja.contikimote.interfaces;
@ -119,7 +119,7 @@ public class ContikiPIR extends PIR implements ContikiMoteInterface {
if (moteMem.getByteValueOf("simPirIsActive") == 1) {
moteMem.setByteValueOf("simPirChanged", (byte) 1);
mote.scheduleImmediateWakeup();
mote.requestImmediateWakeup();
}
}

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ContikiRS232.java,v 1.10 2009/06/15 14:40:28 fros4943 Exp $
* $Id: ContikiRS232.java,v 1.11 2009/10/27 10:11:17 fros4943 Exp $
*/
package se.sics.cooja.contikimote.interfaces;
@ -119,8 +119,8 @@ public class ContikiRS232 extends SerialUI implements ContikiMoteInterface, Poll
public void writeString(String message) {
final byte[] dataToAppend = message.getBytes();
TimeEvent writeStringEvent = new MoteTimeEvent(mote, 0) {
public void execute(long t) {
mote.getSimulation().invokeSimulationThread(new Runnable() {
public void run() {
/* Append to existing buffer */
int oldSize = moteMem.getIntValueOf("simSerialReceivingLength");
int newSize = oldSize + dataToAppend.length;
@ -135,13 +135,9 @@ public class ContikiRS232 extends SerialUI implements ContikiMoteInterface, Poll
moteMem.setByteArray("simSerialReceivingData", newData);
moteMem.setByteValueOf("simSerialReceivingFlag", (byte) 1);
mote.scheduleImmediateWakeup();
mote.requestImmediateWakeup();
}
};
mote.getSimulation().scheduleEvent(
writeStringEvent,
mote.getSimulation().getSimulationTime()
);
});
}
public double energyConsumption() {
@ -196,13 +192,17 @@ public class ContikiRS232 extends SerialUI implements ContikiMoteInterface, Poll
/* Reschedule us if more bytes are available */
mote.getSimulation().scheduleEvent(this, t);
mote.scheduleImmediateWakeup();
mote.requestImmediateWakeup();
}
};
mote.getSimulation().scheduleEvent(
pendingBytesEvent,
mote.getSimulation().getSimulationTime()
);
mote.getSimulation().invokeSimulationThread(new Runnable() {
public void run() {
mote.getSimulation().scheduleEvent(
pendingBytesEvent,
mote.getSimulation().getSimulationTime()
);
}
});
}
public void writeByte(final byte b) {
@ -245,13 +245,17 @@ public class ContikiRS232 extends SerialUI implements ContikiMoteInterface, Poll
/* Reschedule us if more bytes are available */
mote.getSimulation().scheduleEvent(this, t);
mote.scheduleImmediateWakeup();
mote.requestImmediateWakeup();
}
};
mote.getSimulation().scheduleEvent(
pendingBytesEvent,
mote.getSimulation().getSimulationTime()
);
mote.getSimulation().invokeSimulationThread(new Runnable() {
public void run() {
mote.getSimulation().scheduleEvent(
pendingBytesEvent,
mote.getSimulation().getSimulationTime()
);
}
});
}
}

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ContikiRadio.java,v 1.29 2009/09/17 11:06:35 fros4943 Exp $
* $Id: ContikiRadio.java,v 1.30 2009/10/27 10:11:17 fros4943 Exp $
*/
package se.sics.cooja.contikimote.interfaces;
@ -223,7 +223,7 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface, PolledA
// Unlock (if locked)
myMoteMemory.setByteValueOf("simReceiving", (byte) 0);
mote.scheduleImmediateWakeup();
mote.requestImmediateWakeup();
lastEventTime = mote.getSimulation().getSimulationTime();
lastEvent = RadioEvent.RECEPTION_FINISHED;
@ -241,7 +241,7 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface, PolledA
lastEventTime = mote.getSimulation().getSimulationTime();
lastEvent = RadioEvent.RECEPTION_FINISHED;
mote.scheduleImmediateWakeup();
mote.requestImmediateWakeup();
this.setChanged();
this.notifyObservers();
}
@ -308,7 +308,7 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface, PolledA
* data to the mote.
*/
private void lockInReceivingMode() {
mote.scheduleImmediateWakeup();
mote.requestImmediateWakeup();
// Lock core radio in receiving loop
myMoteMemory.setByteValueOf("simReceiving", (byte) 1);

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ContikiVib.java,v 1.7 2009/05/26 14:24:20 fros4943 Exp $
* $Id: ContikiVib.java,v 1.8 2009/10/27 10:11:17 fros4943 Exp $
*/
package se.sics.cooja.contikimote.interfaces;
@ -119,7 +119,7 @@ public class ContikiVib extends MoteInterface implements ContikiMoteInterface {
if (moteMem.getByteValueOf("simVibIsActive") == 1) {
moteMem.setByteValueOf("simVibChanged", (byte) 1);
mote.scheduleImmediateWakeup();
mote.requestImmediateWakeup();
}
}

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: Battery.java,v 1.9 2009/09/17 11:08:07 fros4943 Exp $
* $Id: Battery.java,v 1.10 2009/10/27 10:11:17 fros4943 Exp $
*/
package se.sics.cooja.interfaces;
@ -127,7 +127,7 @@ public class Battery extends MoteInterface implements PolledAfterAllTicks {
/* Check if we are out of energy */
if (getEnergyConsumption() > INITIAL_ENERGY) {
mote.scheduleImmediateWakeup();
mote.requestImmediateWakeup();
}
setChanged();

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: LogScriptEngine.java,v 1.19 2009/10/23 11:55:53 fros4943 Exp $
* $Id: LogScriptEngine.java,v 1.20 2009/10/27 10:12:00 fros4943 Exp $
*/
package se.sics.cooja.plugins;
@ -103,11 +103,11 @@ public class LogScriptEngine {
/* Check if test script requested us to stop */
if (stopSimulation) {
stopSimulationEvent.execute(0);
stopSimulationRunnable.run();
stopSimulation = false;
}
if (quitCooja) {
quitEvent.execute(0);
quitRunnable.run();
quitCooja = false;
}
}
@ -173,8 +173,8 @@ public class LogScriptEngine {
* @param mote Mote
*/
public void fakeMoteLogOutput(final String msg, final Mote mote) {
simulation.scheduleEvent(new TimeEvent(0) {
public void execute(long time) {
simulation.invokeSimulationThread(new Runnable() {
public void run() {
handleNewMoteOutput(
mote,
mote.getID(),
@ -182,7 +182,7 @@ public class LogScriptEngine {
msg
);
}
}, simulation.getSimulationTime());
});
}
public void setScriptLogObserver(Observer observer) {
@ -281,17 +281,16 @@ public class LogScriptEngine {
String jsCode = parser.getJSCode();
long timeoutTime = parser.getTimeoutTime();
if (timeoutTime > 0) {
simulation.scheduleEvent(
timeoutEvent,
simulation.getSimulationTime() + timeoutTime);
} else {
logger.info("No timeout defined, using default (us): " +
(simulation.getSimulationTime() + DEFAULT_TIMEOUT));
simulation.scheduleEvent(
timeoutEvent,
(simulation.getSimulationTime() + DEFAULT_TIMEOUT));
if (timeoutTime < 0) {
logger.info("No timeout defined, using default (us): " + DEFAULT_TIMEOUT);
timeoutTime = DEFAULT_TIMEOUT;
}
final long absoluteTimeout = simulation.getSimulationTime() + timeoutTime;
simulation.invokeSimulationThread(new Runnable() {
public void run() {
simulation.scheduleEvent(timeoutEvent, absoluteTimeout);
}
});
engine.eval(jsCode);
@ -375,10 +374,10 @@ public class LogScriptEngine {
if (GUI.isVisualized()) {
log("[if test was run without visualization, COOJA would now have been terminated]\n");
stopSimulation = true;
simulation.scheduleEvent(stopSimulationEvent, simulation.getSimulationTime());
simulation.invokeSimulationThread(stopSimulationRunnable);
} else {
quitCooja = true;
simulation.scheduleEvent(quitEvent, simulation.getSimulationTime());
simulation.invokeSimulationThread(quitRunnable);
}
timeoutEvent.remove();
@ -392,19 +391,19 @@ public class LogScriptEngine {
if (GUI.isVisualized()) {
log("[if test was run without visualization, COOJA would now have been terminated]\n");
stopSimulation = true;
simulation.scheduleEvent(stopSimulationEvent, simulation.getSimulationTime());
simulation.invokeSimulationThread(stopSimulationRunnable);
} else {
quitCooja = true;
simulation.scheduleEvent(quitEvent, simulation.getSimulationTime());
simulation.invokeSimulationThread(quitRunnable);
}
semaphoreSim.release(100);
throw new RuntimeException("test script killed");
}
public void generateMessage(long delay, final String msg) {
public void generateMessage(final long delay, final String msg) {
final Mote currentMote = (Mote) engine.get("mote");
TimeEvent generateEvent = new TimeEvent(0) {
final TimeEvent generateEvent = new TimeEvent(0) {
public void execute(long t) {
if (scriptThread == null ||
!scriptThread.isAlive()) {
@ -422,9 +421,13 @@ public class LogScriptEngine {
stepScript();
}
};
simulation.scheduleEvent(
generateEvent,
simulation.getSimulationTime() + delay*Simulation.MILLISECOND);
simulation.invokeSimulationThread(new Runnable() {
public void run() {
simulation.scheduleEvent(
generateEvent,
simulation.getSimulationTime() + delay*Simulation.MILLISECOND);
}
});
}
});
@ -444,14 +447,14 @@ public class LogScriptEngine {
stepScript();
}
};
private TimeEvent stopSimulationEvent = new TimeEvent(0) {
public void execute(long time) {
private Runnable stopSimulationRunnable = new Runnable() {
public void run() {
simulation.stopSimulation();
timeoutEvent.remove();
}
};
private TimeEvent quitEvent = new TimeEvent(0) {
public void execute(long time) {
private Runnable quitRunnable = new Runnable() {
public void run() {
simulation.stopSimulation();
new Thread() {
public void run() {

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: SimControl.java,v 1.15 2009/07/06 12:29:57 fros4943 Exp $
* $Id: SimControl.java,v 1.16 2009/10/27 10:12:00 fros4943 Exp $
*/
package se.sics.cooja.plugins;
@ -122,7 +122,7 @@ public class SimControl extends VisPlugin {
stopEvent.remove();
}
long t = ((Number)e.getNewValue()).intValue()*Simulation.MILLISECOND;
final long t = ((Number)e.getNewValue()).intValue()*Simulation.MILLISECOND;
if (t <= SimControl.this.simulation.getSimulationTime()) {
/* No simulation stop scheduled */
stopTimeTextField.setBackground(Color.LIGHT_GRAY);
@ -131,7 +131,11 @@ public class SimControl extends VisPlugin {
/* Schedule simulation stop */
stopTimeTextField.setBackground(Color.WHITE);
stopTimeTextField.setToolTipText("Simulation will stop at time (us): " + t);
SimControl.this.simulation.scheduleEvent(stopEvent, t);
SimControl.this.simulation.invokeSimulationThread(new Runnable() {
public void run() {
SimControl.this.simulation.scheduleEvent(stopEvent, t);
}
});
}
}
});