From 963f8a495d6d2af97fbe060e43e1c261a87b2503 Mon Sep 17 00:00:00 2001
From: Ian Martin <ian@locicontrols.com>
Date: Mon, 18 Apr 2016 12:06:20 -0400
Subject: [PATCH] sys/xtimer: eliminate XTIMER_SHIFT_ON_COMPARE

---
 boards/airfy-beacon/include/board.h          |  1 -
 boards/arduino-mega2560/include/board.h      |  1 -
 boards/chronos/include/board.h               |  1 -
 boards/msb-430-common/include/board_common.h |  1 -
 boards/nrf51dongle/include/board.h           |  1 -
 boards/pca10000/include/board.h              |  1 -
 boards/pca10005/include/board.h              |  1 -
 boards/telosb/include/board.h                |  1 -
 boards/wsn430-common/include/board_common.h  |  1 -
 boards/yunjia-nrf51822/include/board.h       |  1 -
 boards/z1/include/board.h                    |  1 -
 sys/include/xtimer.h                         | 35 ++++++--------------
 12 files changed, 11 insertions(+), 35 deletions(-)

diff --git a/boards/airfy-beacon/include/board.h b/boards/airfy-beacon/include/board.h
index a94b061e8e..49b17c03e7 100644
--- a/boards/airfy-beacon/include/board.h
+++ b/boards/airfy-beacon/include/board.h
@@ -34,7 +34,6 @@
 #define XTIMER                      (0)
 #define XTIMER_CHAN                 (0)
 #define XTIMER_MASK                 (0xff000000)
-#define XTIMER_SHIFT_ON_COMPARE     (2)
 #define XTIMER_BACKOFF              (40)
 /** @} */
 
diff --git a/boards/arduino-mega2560/include/board.h b/boards/arduino-mega2560/include/board.h
index fb5fc9b57a..8bd917f531 100644
--- a/boards/arduino-mega2560/include/board.h
+++ b/boards/arduino-mega2560/include/board.h
@@ -53,7 +53,6 @@ extern "C" {
  */
 #define XTIMER_MASK                 (0xffff0000)
 #define XTIMER_SHIFT                (2)
-#define XTIMER_SHIFT_ON_COMPARE     (8)
 #define XTIMER_BACKOFF              (40)
 /** @} */
 
diff --git a/boards/chronos/include/board.h b/boards/chronos/include/board.h
index 319eb4f817..00dab1df8a 100644
--- a/boards/chronos/include/board.h
+++ b/boards/chronos/include/board.h
@@ -41,7 +41,6 @@ extern "C" {
 #define XTIMER                      (0)
 #define XTIMER_CHAN                 (0)
 #define XTIMER_MASK                 (0xffff0000)
-#define XTIMER_SHIFT_ON_COMPARE     (4)
 /** @} */
 
 /**
diff --git a/boards/msb-430-common/include/board_common.h b/boards/msb-430-common/include/board_common.h
index 24953643ae..72d856dcb7 100644
--- a/boards/msb-430-common/include/board_common.h
+++ b/boards/msb-430-common/include/board_common.h
@@ -40,7 +40,6 @@ extern "C" {
 #define XTIMER                      (0)
 #define XTIMER_CHAN                 (0)
 #define XTIMER_MASK                 (0xffff0000)
-#define XTIMER_SHIFT_ON_COMPARE     (4)
 #define XTIMER_BACKOFF              (40)
 /** @} */
 
diff --git a/boards/nrf51dongle/include/board.h b/boards/nrf51dongle/include/board.h
index 39223c8db0..3e3ee91c66 100644
--- a/boards/nrf51dongle/include/board.h
+++ b/boards/nrf51dongle/include/board.h
@@ -35,7 +35,6 @@ extern "C" {
 #define XTIMER                      (0)
 #define XTIMER_CHAN                 (0)
 #define XTIMER_MASK                 (0xff000000)
-#define XTIMER_SHIFT_ON_COMPARE     (2)
 #define XTIMER_BACKOFF              (40)
 /** @} */
 
diff --git a/boards/pca10000/include/board.h b/boards/pca10000/include/board.h
index 67e31bbbd3..11ee1dcbb3 100644
--- a/boards/pca10000/include/board.h
+++ b/boards/pca10000/include/board.h
@@ -35,7 +35,6 @@ extern "C" {
 #define XTIMER                      (0)
 #define XTIMER_CHAN                 (0)
 #define XTIMER_MASK                 (0xff000000)
-#define XTIMER_SHIFT_ON_COMPARE     (2)
 #define XTIMER_BACKOFF              (40)
 /** @} */
 
diff --git a/boards/pca10005/include/board.h b/boards/pca10005/include/board.h
index a5ce739b6d..ab8a291f77 100644
--- a/boards/pca10005/include/board.h
+++ b/boards/pca10005/include/board.h
@@ -35,7 +35,6 @@ extern "C" {
 #define XTIMER                      (0)
 #define XTIMER_CHAN                 (0)
 #define XTIMER_MASK                 (0xff000000)
-#define XTIMER_SHIFT_ON_COMPARE     (2)
 #define XTIMER_BACKOFF              (40)
 /** @} */
 
diff --git a/boards/telosb/include/board.h b/boards/telosb/include/board.h
index 78c67772f3..a3e36ab473 100644
--- a/boards/telosb/include/board.h
+++ b/boards/telosb/include/board.h
@@ -57,7 +57,6 @@ extern "C" {
 #define XTIMER                      (0)
 #define XTIMER_CHAN                 (0)
 #define XTIMER_MASK                 (0xffff0000)
-#define XTIMER_SHIFT_ON_COMPARE     (4)
 #define XTIMER_BACKOFF              (40)
 /** @} */
 
diff --git a/boards/wsn430-common/include/board_common.h b/boards/wsn430-common/include/board_common.h
index 56a0b6b5c6..1942986328 100644
--- a/boards/wsn430-common/include/board_common.h
+++ b/boards/wsn430-common/include/board_common.h
@@ -40,7 +40,6 @@ extern "C" {
 #define XTIMER                      (0)
 #define XTIMER_CHAN                 (0)
 #define XTIMER_MASK                 (0xffff0000)
-#define XTIMER_SHIFT_ON_COMPARE     (4)
 #define XTIMER_BACKOFF              (40)
 /** @} */
 
diff --git a/boards/yunjia-nrf51822/include/board.h b/boards/yunjia-nrf51822/include/board.h
index 4b5509d560..22f21e9905 100644
--- a/boards/yunjia-nrf51822/include/board.h
+++ b/boards/yunjia-nrf51822/include/board.h
@@ -34,7 +34,6 @@ extern "C" {
 #define XTIMER                      (0)
 #define XTIMER_CHAN                 (0)
 #define XTIMER_MASK                 (0xff000000)
-#define XTIMER_SHIFT_ON_COMPARE     (2)
 #define XTIMER_BACKOFF              (40)
 /** @} */
 
diff --git a/boards/z1/include/board.h b/boards/z1/include/board.h
index 431931cd91..4698181e04 100644
--- a/boards/z1/include/board.h
+++ b/boards/z1/include/board.h
@@ -51,7 +51,6 @@ extern "C" {
 #define XTIMER                      (0)
 #define XTIMER_CHAN                 (0)
 #define XTIMER_MASK                 (0xffff0000)
-#define XTIMER_SHIFT_ON_COMPARE     (4)
 #define XTIMER_BACKOFF              (40)
 /** @} */
 
diff --git a/sys/include/xtimer.h b/sys/include/xtimer.h
index 05c68270b9..a600777c80 100644
--- a/sys/include/xtimer.h
+++ b/sys/include/xtimer.h
@@ -432,25 +432,6 @@ void _xtimer_sleep(uint32_t offset, uint32_t long_offset);
 static inline void xtimer_spin_until(uint32_t value);
 /** @} */
 
-#if XTIMER_MASK
-#ifndef XTIMER_SHIFT_ON_COMPARE
-/**
- * @brief ignore some bits when comparing timer values
- *
- * (only relevant when XTIMER_MASK != 0, e.g., timers < 32bit.)
- *
- * When combining _lltimer_now() and _high_cnt, we have to get the same value in
- * order to work around a race between overflowing _lltimer_now() and OR'ing the
- * resulting values.
- * But some platforms are too slow to get the same timer
- * value twice, so we use this define to ignore some of the bits.
- *
- * Use tests/xtimer_shift_on_compare to find the correct value for your MCU.
- */
-#define XTIMER_SHIFT_ON_COMPARE     (0)
-#endif
-#endif
-
 #ifndef XTIMER_MIN_SPIN
 /**
  * @brief Minimal value xtimer_spin() can spin
@@ -461,12 +442,18 @@ static inline void xtimer_spin_until(uint32_t value);
 static inline uint32_t xtimer_now(void)
 {
 #if XTIMER_MASK
-    uint32_t a, b;
+    uint32_t latched_high_cnt, now;
+
+    /* _high_cnt can change at any time, so check the value before
+     * and after reading the low-level timer. If it hasn't changed,
+     * then it can be safely applied to the timer count. */
+
     do {
-        a = _lltimer_now() | _high_cnt;
-        b = _lltimer_now() | _high_cnt;
-    } while ((a >> XTIMER_SHIFT_ON_COMPARE) != (b >> XTIMER_SHIFT_ON_COMPARE));
-    return b;
+        latched_high_cnt = _high_cnt;
+        now = _lltimer_now();
+    } while (_high_cnt != latched_high_cnt);
+
+    return latched_high_cnt | now;
 #else
     return _lltimer_now();
 #endif
-- 
GitLab