diff --git a/platform/cooja-ip64/contiki-cooja-ip64-main.c b/platform/cooja-ip64/contiki-cooja-ip64-main.c index 02576a3be..d2d42ae9f 100644 --- a/platform/cooja-ip64/contiki-cooja-ip64-main.c +++ b/platform/cooja-ip64/contiki-cooja-ip64-main.c @@ -376,9 +376,6 @@ Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory(JNIEnv *env, jobject obj, JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj) { - clock_time_t nextEtimer; - rtimer_clock_t nextRtimer; - simProcessRunValue = 0; /* Let all simulation interfaces act first */ @@ -403,21 +400,11 @@ Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj) doActionsAfterTick(); /* Do we have any pending timers */ - simEtimerPending = etimer_pending() || rtimer_arch_pending(); - if(!simEtimerPending) { - return; - } + simEtimerPending = etimer_pending(); /* Save nearest expiration time */ - nextEtimer = etimer_next_expiration_time() - (clock_time_t) simCurrentTime; - nextRtimer = rtimer_arch_next() - (rtimer_clock_t) simCurrentTime; - if(etimer_pending() && rtimer_arch_pending()) { - simNextExpirationTime = MIN(nextEtimer, nextRtimer); - } else if(etimer_pending()) { - simNextExpirationTime = nextEtimer; - } else if(rtimer_arch_pending()) { - simNextExpirationTime = nextRtimer; - } + simEtimerNextExpirationTime = etimer_next_expiration_time(); + } /*---------------------------------------------------------------------------*/ /** diff --git a/platform/cooja/contiki-conf.h b/platform/cooja/contiki-conf.h index 7d107a0b1..430f27a69 100644 --- a/platform/cooja/contiki-conf.h +++ b/platform/cooja/contiki-conf.h @@ -200,8 +200,8 @@ typedef unsigned short uip_stats_t; #define CLOCK_CONF_SECOND 1000L typedef unsigned long clock_time_t; -typedef unsigned long rtimer_clock_t; -#define RTIMER_CLOCK_DIFF(a,b) ((signed long)((a)-(b))) +typedef uint64_t rtimer_clock_t; +#define RTIMER_CLOCK_DIFF(a,b) ((int64_t)((a)-(b))) #define RADIO_DELAY_BEFORE_TX 0 #define RADIO_DELAY_BEFORE_RX 0 diff --git a/platform/cooja/contiki-cooja-main.c b/platform/cooja/contiki-cooja-main.c index 40dd49d1c..9a1e60e4c 100644 --- a/platform/cooja/contiki-cooja-main.c +++ b/platform/cooja/contiki-cooja-main.c @@ -452,9 +452,6 @@ Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory(JNIEnv *env, jobject obj, JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj) { - clock_time_t nextEtimer; - rtimer_clock_t nextRtimer; - simProcessRunValue = 0; /* Let all simulation interfaces act first */ @@ -479,21 +476,11 @@ Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj) doActionsAfterTick(); /* Do we have any pending timers */ - simEtimerPending = etimer_pending() || rtimer_arch_pending(); - if(!simEtimerPending) { - return; - } + simEtimerPending = etimer_pending(); /* Save nearest expiration time */ - nextEtimer = etimer_next_expiration_time() - (clock_time_t) simCurrentTime; - nextRtimer = rtimer_arch_next() - (rtimer_clock_t) simCurrentTime; - if(etimer_pending() && rtimer_arch_pending()) { - simNextExpirationTime = MIN(nextEtimer, nextRtimer); - } else if(etimer_pending()) { - simNextExpirationTime = nextEtimer; - } else if(rtimer_arch_pending()) { - simNextExpirationTime = nextRtimer; - } + simEtimerNextExpirationTime = etimer_next_expiration_time(); + } /*---------------------------------------------------------------------------*/ /** diff --git a/platform/cooja/lib/simEnvChange.c b/platform/cooja/lib/simEnvChange.c index c9fbd438f..f6060b449 100644 --- a/platform/cooja/lib/simEnvChange.c +++ b/platform/cooja/lib/simEnvChange.c @@ -40,7 +40,7 @@ char simDontFallAsleep = 0; int simProcessRunValue; int simEtimerPending; -clock_time_t simNextExpirationTime; +clock_time_t simEtimerNextExpirationTime; void doActionsBeforeTick() { // Poll all interfaces to do their thing before the tick diff --git a/platform/cooja/lib/simEnvChange.h b/platform/cooja/lib/simEnvChange.h index 35189a42d..7723eb16f 100644 --- a/platform/cooja/lib/simEnvChange.h +++ b/platform/cooja/lib/simEnvChange.h @@ -42,7 +42,7 @@ struct simInterface { // Variable for keeping the last process_run() return value extern int simProcessRunValue; extern int simEtimerPending; -extern clock_time_t simNextExpirationTime; +extern clock_time_t simEtimerNextExpirationTime; extern clock_time_t simCurrentTime; // Variable that when set to != 0, stops the mote from falling asleep next tick diff --git a/platform/cooja/rtimer-arch.c b/platform/cooja/rtimer-arch.c index dff66fdc7..9d4f77646 100644 --- a/platform/cooja/rtimer-arch.c +++ b/platform/cooja/rtimer-arch.c @@ -48,46 +48,44 @@ #define PRINTF(...) #endif -extern clock_time_t simCurrentTime; - -static int pending_rtimer = 0; -static rtimer_clock_t next_rtimer = 0; -static clock_time_t last_rtimer_now = 0; +/* COOJA */ +int simRtimerPending; +rtimer_clock_t simRtimerNextExpirationTime; +rtimer_clock_t simRtimerCurrentTicks; /*---------------------------------------------------------------------------*/ void rtimer_arch_init(void) { - next_rtimer = 0; - last_rtimer_now = 0; - pending_rtimer = 0; + simRtimerNextExpirationTime = 0; + simRtimerPending = 0; } /*---------------------------------------------------------------------------*/ void rtimer_arch_schedule(rtimer_clock_t t) { - next_rtimer = t; - pending_rtimer = 1; + simRtimerNextExpirationTime = t; + simRtimerPending = 1; } /*---------------------------------------------------------------------------*/ rtimer_clock_t rtimer_arch_next(void) { - return next_rtimer; + return simRtimerNextExpirationTime; } /*---------------------------------------------------------------------------*/ int rtimer_arch_pending(void) { - return pending_rtimer; + return simRtimerPending; } /*---------------------------------------------------------------------------*/ int rtimer_arch_check(void) { - if (simCurrentTime == next_rtimer) { + if (simRtimerCurrentTicks == simRtimerNextExpirationTime) { /* Execute rtimer */ - pending_rtimer = 0; + simRtimerPending = 0; rtimer_run_next(); return 1; } @@ -97,14 +95,7 @@ rtimer_arch_check(void) rtimer_clock_t rtimer_arch_now(void) { - if(last_rtimer_now == simCurrentTime) { - /* Yield to COOJA, to allow time to change */ - simProcessRunValue = 1; - simNextExpirationTime = simCurrentTime + 1; - cooja_mt_yield(); - } - last_rtimer_now = simCurrentTime; - return simCurrentTime; + return simRtimerCurrentTicks; } /*---------------------------------------------------------------------------*/ diff --git a/platform/cooja/rtimer-arch.h b/platform/cooja/rtimer-arch.h index 616ad4185..390e1ac56 100644 --- a/platform/cooja/rtimer-arch.h +++ b/platform/cooja/rtimer-arch.h @@ -36,7 +36,10 @@ #include "contiki-conf.h" #include "sys/clock.h" -#define RTIMER_ARCH_SECOND CLOCK_CONF_SECOND +#define RTIMER_ARCH_SECOND UINT64_C(1000000) + +#define US_TO_RTIMERTICKS(US) (US) +#define RTIMERTICKS_TO_US(T) (T) rtimer_clock_t rtimer_arch_now(void); int rtimer_arch_check(void); diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiClock.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiClock.java index b033ef06d..97cbc61c3 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiClock.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiClock.java @@ -52,8 +52,11 @@ import org.contikios.cooja.mote.memory.VarMemory; * Contiki variables: * * @@ -125,16 +128,24 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB public void doActionsBeforeTick() { /* Update time */ - setTime(mote.getSimulation().getSimulationTime() + timeDrift); + long currentSimulationTime = simulation.getSimulationTime(); + setTime(currentSimulationTime + timeDrift); + moteMem.setInt64ValueOf("simRtimerCurrentTicks", currentSimulationTime); } public void doActionsAfterTick() { + long currentSimulationTime = mote.getSimulation().getSimulationTime(); + + /* Always schedule for Rtimer if anything pending */ + if (moteMem.getIntValueOf("simRtimerPending") != 0) { + mote.scheduleNextWakeup(moteMem.getInt64ValueOf("simRtimerNextExpirationTime")); + } /* Request next tick for remaining events / timers */ int processRunValue = moteMem.getIntValueOf("simProcessRunValue"); if (processRunValue != 0) { /* Handle next Contiki event in one millisecond */ - mote.scheduleNextWakeup(simulation.getSimulationTime() + Simulation.MILLISECOND); + mote.scheduleNextWakeup(currentSimulationTime + Simulation.MILLISECOND); return; } @@ -144,15 +155,20 @@ public class ContikiClock extends Clock implements ContikiMoteInterface, PolledB return; } - /* Request tick next wakeup time */ - int nextExpirationTime = moteMem.getIntValueOf("simNextExpirationTime"); - if (nextExpirationTime <= 0) { - /*logger.warn("Event timer already expired, but has been delayed: " + nextExpirationTime);*/ - mote.scheduleNextWakeup(simulation.getSimulationTime() + Simulation.MILLISECOND); - return; + /* Request tick next wakeup time for Etimer */ + long etimerNextExpirationTime = (long)moteMem.getInt32ValueOf("simEtimerNextExpirationTime") * Simulation.MILLISECOND; + long etimerTimeToNextExpiration = etimerNextExpirationTime - moteTime; + if (etimerTimeToNextExpiration <= 0) { + /* logger.warn(mote.getID() + ": Event timer already expired, but has been delayed: " + etimerTimeToNextExpiration); */ + /* Wake up in one millisecond to handle a missed Etimer task + * which may be blocked by busy waiting such as one in + * radio_send(). Scheduling it in a shorter time than one + * millisecond, e.g., one microsecond, seems to be worthless and + * it would cause unnecessary CPU usage. */ + mote.scheduleNextWakeup(currentSimulationTime + Simulation.MILLISECOND); + } else { + mote.scheduleNextWakeup(currentSimulationTime + etimerTimeToNextExpiration); } - - mote.scheduleNextWakeup(simulation.getSimulationTime() + Simulation.MILLISECOND*nextExpirationTime); }