3#ifndef USE_NATIVE_64BIT_TIME
8#ifdef ESPHOME_DEBUG_SCHEDULER
12#ifdef ESPHOME_THREAD_MULTI_ATOMICS
19#ifdef ESPHOME_DEBUG_SCHEDULER
20static const char *
const TAG =
"time_64";
23#ifdef ESPHOME_THREAD_SINGLE
25uint32_t Millis64Impl::last_millis_{0};
26uint16_t Millis64Impl::millis_major_{0};
29uint64_t Millis64Impl::compute(
uint32_t now) {
31 static constexpr uint32_t HALF_MAX_UINT32 = std::numeric_limits<uint32_t>::max() / 2;
34#ifdef ESPHOME_THREAD_MULTI_ATOMICS
46 static std::atomic<uint32_t> last_millis{0};
52 static std::atomic<uint16_t> millis_major{0};
56 static uint16_t millis_major{0};
71#if defined(ESPHOME_THREAD_MULTI_NO_ATOMICS)
77 uint16_t major = millis_major;
82 static constexpr uint32_t ROLLOVER_WINDOW = 10000;
85 bool near_rollover = (last > (std::numeric_limits<uint32_t>::max() - ROLLOVER_WINDOW)) || (now < ROLLOVER_WINDOW);
87 if (near_rollover || (now < last && (last - now) > HALF_MAX_UINT32)) {
89 LockGuard guard{lock};
93 if (now < last && (last - now) > HALF_MAX_UINT32) {
97#ifdef ESPHOME_DEBUG_SCHEDULER
98 ESP_LOGD(TAG,
"Detected true 32-bit rollover at %" PRIu32
"ms (was %" PRIu32
")", now, last);
103 }
else if (now > last) {
116 return now + (
static_cast<uint64_t
>(major) << 32);
118#elif defined(ESPHOME_THREAD_MULTI_ATOMICS)
127 uint16_t major = millis_major.load(std::memory_order_acquire);
135 uint32_t last = last_millis.load(std::memory_order_acquire);
139 if (now < last && (last - now) > HALF_MAX_UINT32) {
141 LockGuard guard{lock};
143 last = last_millis.load(std::memory_order_relaxed);
145 if (now < last && (last - now) > HALF_MAX_UINT32) {
147 millis_major.fetch_add(1, std::memory_order_relaxed);
149#ifdef ESPHOME_DEBUG_SCHEDULER
150 ESP_LOGD(TAG,
"Detected true 32-bit rollover at %" PRIu32
"ms (was %" PRIu32
")", now, last);
158 last_millis.store(now, std::memory_order_release);
162 while (now > last && (now - last) < HALF_MAX_UINT32) {
163 if (last_millis.compare_exchange_weak(last, now,
164 std::memory_order_release,
165 std::memory_order_relaxed)) {
172 uint16_t major_end = millis_major.load(std::memory_order_relaxed);
173 if (major_end == major)
174 return now + (
static_cast<uint64_t
>(major) << 32);
177 __builtin_unreachable();
181 "No platform threading model defined. One of ESPHOME_THREAD_SINGLE, ESPHOME_THREAD_MULTI_NO_ATOMICS, or ESPHOME_THREAD_MULTI_ATOMICS must be defined."
Providing packet encoding functions for exchanging data with a remote host.