added support for removing events from queue outside simulation thread
This commit is contained in:
parent
e9fa905ff1
commit
0f0aab0005
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: EventQueue.java,v 1.3 2008/12/08 13:07:32 fros4943 Exp $
|
* $Id: EventQueue.java,v 1.4 2009/01/08 15:42:25 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja;
|
package se.sics.cooja;
|
||||||
|
@ -39,42 +39,61 @@ import java.util.ArrayList;
|
||||||
public class EventQueue {
|
public class EventQueue {
|
||||||
|
|
||||||
private TimeEvent first;
|
private TimeEvent first;
|
||||||
private long nextTime;
|
|
||||||
private int eventCount = 0;
|
private int eventCount = 0;
|
||||||
|
|
||||||
private ArrayList<TimeEvent> pendingEvents = new ArrayList<TimeEvent>();
|
/* For scheduling events from outside simulation thread effectively */
|
||||||
private boolean hasPendingEvents = false;
|
private boolean hasUnsortedEvents = false;
|
||||||
|
private ArrayList<TimeEvent> unsortedEvents = new ArrayList<TimeEvent>();
|
||||||
|
|
||||||
public EventQueue() {
|
public EventQueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void addPendingEvent(TimeEvent event, long time) {
|
private synchronized void sortEvents() {
|
||||||
event.time = time;
|
hasUnsortedEvents = false;
|
||||||
pendingEvents.add(event);
|
|
||||||
hasPendingEvents = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void handlePendingEvents() {
|
for (TimeEvent e: unsortedEvents) {
|
||||||
if (!hasPendingEvents) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (TimeEvent e: pendingEvents) {
|
|
||||||
addEvent(e);
|
addEvent(e);
|
||||||
}
|
}
|
||||||
pendingEvents.clear();
|
unsortedEvents.clear();
|
||||||
hasPendingEvents = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* May be called from outside simulation thread.
|
||||||
|
*
|
||||||
|
* @param event Event
|
||||||
|
* @param time Time
|
||||||
|
*/
|
||||||
|
public synchronized void addEventUnsorted(TimeEvent event, long time) {
|
||||||
|
/* Make sure this event is not executed before being resorted (readded) */
|
||||||
|
if (event.queue != null) {
|
||||||
|
event.remove();
|
||||||
|
}
|
||||||
|
event.time = time;
|
||||||
|
unsortedEvents.add(event);
|
||||||
|
hasUnsortedEvents = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should only be called from simulation thread!
|
||||||
|
*
|
||||||
|
* @param event Event
|
||||||
|
* @param time Time
|
||||||
|
*/
|
||||||
public void addEvent(TimeEvent event, long time) {
|
public void addEvent(TimeEvent event, long time) {
|
||||||
event.time = time;
|
event.time = time;
|
||||||
addEvent(event);
|
addEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should only be called from simulation thread!
|
||||||
|
*
|
||||||
|
* @param event Event
|
||||||
|
*/
|
||||||
public void addEvent(TimeEvent event) {
|
public void addEvent(TimeEvent event) {
|
||||||
if (event.scheduledIn != null) {
|
if (event.queue != null) {
|
||||||
event.remove();
|
removeFromQueue(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first == null) {
|
if (first == null) {
|
||||||
first = event;
|
first = event;
|
||||||
} else {
|
} else {
|
||||||
|
@ -95,21 +114,21 @@ public class EventQueue {
|
||||||
lastPos.nextEvent = event;
|
lastPos.nextEvent = event;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (first != null) {
|
event.removed = false;
|
||||||
nextTime = first.time;
|
event.queue = this;
|
||||||
} else {
|
|
||||||
nextTime = 0;
|
|
||||||
}
|
|
||||||
event.scheduledIn = this;
|
|
||||||
eventCount++;
|
eventCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not yet impl.
|
/**
|
||||||
public boolean removeEvent(TimeEvent event) {
|
* Should only be called from simulation thread!
|
||||||
|
*
|
||||||
|
* @param event Event
|
||||||
|
* @return True if event was removed
|
||||||
|
*/
|
||||||
|
private boolean removeFromQueue(TimeEvent event) {
|
||||||
TimeEvent pos = first;
|
TimeEvent pos = first;
|
||||||
TimeEvent lastPos = first;
|
TimeEvent lastPos = first;
|
||||||
// System.out.println("Removing: " + event.getShort() + " Before remove: ");
|
|
||||||
// print();
|
|
||||||
while (pos != null && pos != event) {
|
while (pos != null && pos != event) {
|
||||||
lastPos = pos;
|
lastPos = pos;
|
||||||
pos = pos.nextEvent;
|
pos = pos.nextEvent;
|
||||||
|
@ -128,21 +147,26 @@ public class EventQueue {
|
||||||
// unlink
|
// unlink
|
||||||
pos.nextEvent = null;
|
pos.nextEvent = null;
|
||||||
|
|
||||||
if (first != null) {
|
event.queue = null;
|
||||||
nextTime = first.time;
|
|
||||||
} else {
|
|
||||||
nextTime = 0;
|
|
||||||
}
|
|
||||||
// System.out.println("Removed =>");
|
|
||||||
// print();
|
|
||||||
event.scheduledIn = null;
|
|
||||||
eventCount--;
|
eventCount--;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeAll() {
|
||||||
|
TimeEvent event = popFirst();
|
||||||
|
while (event != null) {
|
||||||
|
event = popFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should only be called from simulation thread!
|
||||||
|
*
|
||||||
|
* @return Event
|
||||||
|
*/
|
||||||
public TimeEvent popFirst() {
|
public TimeEvent popFirst() {
|
||||||
if (hasPendingEvents) {
|
if (hasUnsortedEvents) {
|
||||||
handlePendingEvents();
|
sortEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeEvent tmp = first;
|
TimeEvent tmp = first;
|
||||||
|
@ -154,31 +178,18 @@ public class EventQueue {
|
||||||
// Unlink.
|
// Unlink.
|
||||||
tmp.nextEvent = null;
|
tmp.nextEvent = null;
|
||||||
|
|
||||||
if (first != null) {
|
|
||||||
nextTime = first.time;
|
|
||||||
} else {
|
|
||||||
nextTime = 0;
|
|
||||||
}
|
|
||||||
// No longer scheduled!
|
// No longer scheduled!
|
||||||
tmp.scheduledIn = null;
|
tmp.queue = null;
|
||||||
eventCount--;
|
eventCount--;
|
||||||
|
|
||||||
|
if (tmp.removed) {
|
||||||
|
/* pop and return another event instead */
|
||||||
|
return popFirst();
|
||||||
|
}
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAll() {
|
|
||||||
TimeEvent t = first;
|
|
||||||
while(t != null) {
|
|
||||||
TimeEvent clr = t;
|
|
||||||
t = t.nextEvent;
|
|
||||||
clr.nextEvent = null;
|
|
||||||
clr.time = 0;
|
|
||||||
clr.scheduledIn = null;
|
|
||||||
}
|
|
||||||
first = null;
|
|
||||||
eventCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "EventQueue (" + eventCount + " events)";
|
return "EventQueue with " + (eventCount+unsortedEvents.size()) + " events";
|
||||||
}
|
}
|
||||||
} // LLEventQueue
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: Simulation.java,v 1.36 2008/12/08 13:07:06 fros4943 Exp $
|
* $Id: Simulation.java,v 1.37 2009/01/08 15:42:38 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja;
|
package se.sics.cooja;
|
||||||
|
@ -126,7 +126,7 @@ public class Simulation extends Observable implements Runnable {
|
||||||
if (Thread.currentThread() == simulationThread) {
|
if (Thread.currentThread() == simulationThread) {
|
||||||
eventQueue.addEvent(e, time);
|
eventQueue.addEvent(e, time);
|
||||||
} else {
|
} else {
|
||||||
eventQueue.addPendingEvent(e, time);
|
eventQueue.addEventUnsorted(e, time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: TimeEvent.java,v 1.2 2008/12/04 14:03:42 joxe Exp $
|
* $Id: TimeEvent.java,v 1.3 2009/01/08 15:42:25 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja;
|
package se.sics.cooja;
|
||||||
|
@ -35,18 +35,18 @@ package se.sics.cooja;
|
||||||
* @author Joakim Eriksson (ported to COOJA by Fredrik Österlind)
|
* @author Joakim Eriksson (ported to COOJA by Fredrik Österlind)
|
||||||
*/
|
*/
|
||||||
public abstract class TimeEvent {
|
public abstract class TimeEvent {
|
||||||
// For linking events...
|
|
||||||
TimeEvent nextEvent;
|
TimeEvent nextEvent;
|
||||||
TimeEvent prevEvent;
|
TimeEvent prevEvent;
|
||||||
|
|
||||||
// Keeps track of where this is scheduled
|
EventQueue queue = null;
|
||||||
EventQueue scheduledIn = null;
|
|
||||||
String name;
|
String name;
|
||||||
|
|
||||||
protected long time;
|
protected long time;
|
||||||
|
|
||||||
|
boolean removed = false;
|
||||||
|
|
||||||
public TimeEvent(long time) {
|
public TimeEvent(long time) {
|
||||||
this.time = time;
|
this(time, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimeEvent(long time, String name) {
|
public TimeEvent(long time, String name) {
|
||||||
|
@ -59,13 +59,11 @@ public abstract class TimeEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isScheduled() {
|
public boolean isScheduled() {
|
||||||
return scheduledIn != null;
|
return queue != null && !removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean remove() {
|
public boolean remove() {
|
||||||
if (scheduledIn != null) {
|
removed = true;
|
||||||
return scheduledIn.removeEvent(this);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,4 +73,4 @@ public abstract class TimeEvent {
|
||||||
return "" + time + (name != null ? ": " + name : "");
|
return "" + time + (name != null ? ": " + name : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // TimeEvent
|
}
|
||||||
|
|
Loading…
Reference in a new issue