@Test public void testMultipleSequentialAfterTailRadioActive() throws Exception { MonotonicRadioMonitor radioMonitor = new MonotonicRadioMonitor(WAKEUP_INTERVAL_S); int firstRadioActiveS = radioMonitor.onRadioActivate(0L, 2000L); assertThat(firstRadioActiveS, is(0)); assertThat(getRadioActiveS(radioMonitor), is(2 + WAKEUP_INTERVAL_S)); assertThat(radioMonitor.mWakeupCounter.get(), is(1)); long delay = TimeUnit.SECONDS.toMillis(WAKEUP_INTERVAL_S); int secondRadioActiveS = radioMonitor.onRadioActivate(2000L + delay, 3000L + delay); assertThat(secondRadioActiveS, is(2 + WAKEUP_INTERVAL_S)); assertThat(getRadioActiveS(radioMonitor), is(3 + 2 * WAKEUP_INTERVAL_S)); assertThat(radioMonitor.mWakeupCounter.get(), is(2)); int thirdRadioActiveS = radioMonitor.onRadioActivate(3000L + 2 * delay, 4000L + 2 * delay); assertThat(thirdRadioActiveS, is(3 + 2 * WAKEUP_INTERVAL_S)); assertThat(getRadioActiveS(radioMonitor), is(4 + 3 * WAKEUP_INTERVAL_S)); assertThat(radioMonitor.mWakeupCounter.get(), is(3)); }
public int onRadioActivate(long transferStartMs, long transferEndMs) { long transferStartS = TimeUnit.MILLISECONDS.toSeconds(transferStartMs); long transferEndS = TimeUnit.MILLISECONDS.toSeconds(transferEndMs); long expectedNextIdleAndTotals; long newNextIdleAndTotals; boolean casSucceeded = false; do { expectedNextIdleAndTotals = mNextIdleTimeActive.get(); newNextIdleAndTotals = adjustTotalsAndNextIdle(transferStartS, transferEndS, expectedNextIdleAndTotals); } while (nextIdle(expectedNextIdleAndTotals) < nextIdle(newNextIdleAndTotals) && !(casSucceeded = mNextIdleTimeActive.compareAndSet(expectedNextIdleAndTotals, newNextIdleAndTotals))); if (casSucceeded) { if (nextIdle(expectedNextIdleAndTotals) <= transferStartS) { mWakeupCounter.getAndIncrement(); } return totalTxS(expectedNextIdleAndTotals) + totalTailS(expectedNextIdleAndTotals); } else { return 0; } }
MonotonicRadioMonitor { public int onRadioActivate(long transferStartMs, long transferEndMs) { long transferStartS = TimeUnit.MILLISECONDS.toSeconds(transferStartMs); long transferEndS = TimeUnit.MILLISECONDS.toSeconds(transferEndMs); long expectedNextIdleAndTotals; long newNextIdleAndTotals; boolean casSucceeded = false; do { expectedNextIdleAndTotals = mNextIdleTimeActive.get(); newNextIdleAndTotals = adjustTotalsAndNextIdle(transferStartS, transferEndS, expectedNextIdleAndTotals); } while (nextIdle(expectedNextIdleAndTotals) < nextIdle(newNextIdleAndTotals) && !(casSucceeded = mNextIdleTimeActive.compareAndSet(expectedNextIdleAndTotals, newNextIdleAndTotals))); if (casSucceeded) { if (nextIdle(expectedNextIdleAndTotals) <= transferStartS) { mWakeupCounter.getAndIncrement(); } return totalTxS(expectedNextIdleAndTotals) + totalTailS(expectedNextIdleAndTotals); } else { return 0; } } }
MonotonicRadioMonitor { public int onRadioActivate(long transferStartMs, long transferEndMs) { long transferStartS = TimeUnit.MILLISECONDS.toSeconds(transferStartMs); long transferEndS = TimeUnit.MILLISECONDS.toSeconds(transferEndMs); long expectedNextIdleAndTotals; long newNextIdleAndTotals; boolean casSucceeded = false; do { expectedNextIdleAndTotals = mNextIdleTimeActive.get(); newNextIdleAndTotals = adjustTotalsAndNextIdle(transferStartS, transferEndS, expectedNextIdleAndTotals); } while (nextIdle(expectedNextIdleAndTotals) < nextIdle(newNextIdleAndTotals) && !(casSucceeded = mNextIdleTimeActive.compareAndSet(expectedNextIdleAndTotals, newNextIdleAndTotals))); if (casSucceeded) { if (nextIdle(expectedNextIdleAndTotals) <= transferStartS) { mWakeupCounter.getAndIncrement(); } return totalTxS(expectedNextIdleAndTotals) + totalTailS(expectedNextIdleAndTotals); } else { return 0; } } MonotonicRadioMonitor(int wakeUpTimeS); }
MonotonicRadioMonitor { public int onRadioActivate(long transferStartMs, long transferEndMs) { long transferStartS = TimeUnit.MILLISECONDS.toSeconds(transferStartMs); long transferEndS = TimeUnit.MILLISECONDS.toSeconds(transferEndMs); long expectedNextIdleAndTotals; long newNextIdleAndTotals; boolean casSucceeded = false; do { expectedNextIdleAndTotals = mNextIdleTimeActive.get(); newNextIdleAndTotals = adjustTotalsAndNextIdle(transferStartS, transferEndS, expectedNextIdleAndTotals); } while (nextIdle(expectedNextIdleAndTotals) < nextIdle(newNextIdleAndTotals) && !(casSucceeded = mNextIdleTimeActive.compareAndSet(expectedNextIdleAndTotals, newNextIdleAndTotals))); if (casSucceeded) { if (nextIdle(expectedNextIdleAndTotals) <= transferStartS) { mWakeupCounter.getAndIncrement(); } return totalTxS(expectedNextIdleAndTotals) + totalTailS(expectedNextIdleAndTotals); } else { return 0; } } MonotonicRadioMonitor(int wakeUpTimeS); int onRadioActivate(long transferStartMs, long transferEndMs); long getTotalTxS(); long getTotalTailS(); long getWakeupCount(); }
MonotonicRadioMonitor { public int onRadioActivate(long transferStartMs, long transferEndMs) { long transferStartS = TimeUnit.MILLISECONDS.toSeconds(transferStartMs); long transferEndS = TimeUnit.MILLISECONDS.toSeconds(transferEndMs); long expectedNextIdleAndTotals; long newNextIdleAndTotals; boolean casSucceeded = false; do { expectedNextIdleAndTotals = mNextIdleTimeActive.get(); newNextIdleAndTotals = adjustTotalsAndNextIdle(transferStartS, transferEndS, expectedNextIdleAndTotals); } while (nextIdle(expectedNextIdleAndTotals) < nextIdle(newNextIdleAndTotals) && !(casSucceeded = mNextIdleTimeActive.compareAndSet(expectedNextIdleAndTotals, newNextIdleAndTotals))); if (casSucceeded) { if (nextIdle(expectedNextIdleAndTotals) <= transferStartS) { mWakeupCounter.getAndIncrement(); } return totalTxS(expectedNextIdleAndTotals) + totalTailS(expectedNextIdleAndTotals); } else { return 0; } } MonotonicRadioMonitor(int wakeUpTimeS); int onRadioActivate(long transferStartMs, long transferEndMs); long getTotalTxS(); long getTotalTailS(); long getWakeupCount();  }