Skip to content

Commit 1091376

Browse files
andy31415pull[bot]
authored andcommitted
Revert "Remove Microseconds from System::Clock (#11450)" (#11481)
This reverts commit 11c32e8.
1 parent 84fc407 commit 1091376

10 files changed

+147
-17
lines changed

src/lib/dnssd/minimal_mdns/tests/TestActiveResolveAttempts.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ using chip::System::Clock::Timeout;
2929
class MockClock : public System::Clock::ClockBase
3030
{
3131
public:
32+
System::Clock::Microseconds64 GetMonotonicMicroseconds64() override { return mMsec; }
3233
System::Clock::Milliseconds64 GetMonotonicMilliseconds64() override { return mMsec; }
3334

3435
void Advance(System::Clock::Milliseconds32 ms) { mMsec += ms; }

src/platform/ESP32/SystemTimeSupport.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,14 @@ namespace Internal {
3838
ClockImpl gClockImpl;
3939
} // namespace Internal
4040

41+
Microseconds64 ClockImpl::GetMonotonicMicroseconds64(void)
42+
{
43+
return Clock::Microseconds64(::esp_timer_get_time());
44+
}
45+
4146
Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void)
4247
{
43-
return std::chrono::duration_cast<Milliseconds64>(std::chrono::duration<uint64_t, std::micro>(::esp_timer_get_time()));
48+
return std::chrono::duration_cast<Milliseconds64>(GetMonotonicMicroseconds64());
4449
}
4550

4651
} // namespace Clock

src/platform/FreeRTOS/SystemTimeSupport.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ uint64_t FreeRTOSTicksSinceBoot(void)
9090
return static_cast<uint64_t>(timeOut.xTimeOnEntering) + (static_cast<uint64_t>(timeOut.xOverflowCount) << kTicksOverflowShift);
9191
}
9292

93+
Clock::Microseconds64 ClockImpl::GetMonotonicMicroseconds64(void)
94+
{
95+
return Clock::Microseconds64((FreeRTOSTicksSinceBoot() * kMicrosecondsPerSecond) / configTICK_RATE_HZ);
96+
}
97+
9398
Clock::Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void)
9499
{
95100
return Clock::Milliseconds64((FreeRTOSTicksSinceBoot() * kMillisecondsPerSecond) / configTICK_RATE_HZ);

src/platform/Linux/SystemTimeSupport.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ namespace Internal {
4040
ClockImpl gClockImpl;
4141
} // namespace Internal
4242

43+
Microseconds64 ClockImpl::GetMonotonicMicroseconds64()
44+
{
45+
return std::chrono::duration_cast<Microseconds64>(std::chrono::steady_clock::now().time_since_epoch());
46+
}
47+
4348
Milliseconds64 ClockImpl::GetMonotonicMilliseconds64()
4449
{
4550
return std::chrono::duration_cast<Milliseconds64>(std::chrono::steady_clock::now().time_since_epoch());

src/platform/Zephyr/SystemTimeSupport.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ namespace Internal {
3838
ClockImpl gClockImpl;
3939
} // namespace Internal
4040

41+
Microseconds64 ClockImpl::GetMonotonicMicroseconds64(void)
42+
{
43+
return Microseconds64(k_ticks_to_us_floor64(k_uptime_ticks()));
44+
}
45+
4146
Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void)
4247
{
4348
return Milliseconds64(k_uptime_get());

src/platform/mbed/SystemTimeSupport.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,23 @@ mbed::LowPowerTimer timer()
5252
}
5353
} // namespace
5454

55-
// Returns count of microseconds
5655
extern "C" uint64_t get_clock_monotonic()
5756
{
5857
return timer().elapsed_time().count();
5958
}
6059

60+
// Platform-specific function for getting monotonic system time in microseconds.
61+
// Returns elapsed time in microseconds since an arbitrary, platform-defined epoch.
62+
Microseconds64 ClockImpl::GetMonotonicMicroseconds64()
63+
{
64+
return Microseconds64(get_clock_monotonic());
65+
}
66+
6167
// Platform-specific function for getting monotonic system time in milliseconds.
6268
// Return elapsed time in milliseconds since an arbitrary, platform-defined epoch.
6369
Milliseconds64 ClockImpl::GetMonotonicMilliseconds64()
6470
{
65-
return std::chrono::duration_cast<Milliseconds64>(std::chrono::duration<uint64_t, std::micro>(get_clock_monotonic()));
71+
return std::chrono::duration_cast<Milliseconds64>(GetMonotonicMicroseconds64());
6672
}
6773

6874
} // namespace Clock

src/platform/tests/TestPlatformTime.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,43 @@ using namespace chip::System;
4242
using namespace chip::System::Clock::Literals;
4343

4444
constexpr Clock::Milliseconds64 kTestTimeMarginMs = 2_ms64;
45+
constexpr Clock::Microseconds64 kTestTimeMarginUs = 500_us64;
4546

4647
// =================================
4748
// Unit tests
4849
// =================================
4950

51+
static void TestDevice_GetMonotonicMicroseconds(nlTestSuite * inSuite, void * inContext)
52+
{
53+
static const Clock::Microseconds64 kTestVectorSystemTimeUs[] = {
54+
600_us64,
55+
900_us64,
56+
1500_us64,
57+
};
58+
int numOfTestsRan = 0;
59+
constexpr Clock::Microseconds64 margin = kTestTimeMarginUs;
60+
61+
for (const Clock::Microseconds64 & Tdelay : kTestVectorSystemTimeUs)
62+
{
63+
const Clock::Microseconds64 Tstart = System::SystemClock().GetMonotonicMicroseconds64();
64+
65+
chip::test_utils::SleepMicros(Tdelay.count());
66+
67+
const Clock::Microseconds64 Tend = System::SystemClock().GetMonotonicMicroseconds64();
68+
const Clock::Microseconds64 Tdelta = Tend - Tstart;
69+
70+
ChipLogProgress(DeviceLayer, "Start=%" PRIu64 " End=%" PRIu64 " Delta=%" PRIu64 " Expected=%" PRIu64, Tstart.count(),
71+
Tend.count(), Tdelta.count(), Tdelay.count());
72+
73+
// verify that timers don't fire early
74+
NL_TEST_ASSERT(inSuite, Tdelta > (Tdelay - margin));
75+
// verify they're not too late
76+
// NL_TEST_ASSERT(inSuite, Tdelta < (Tdelay + margin));
77+
numOfTestsRan++;
78+
}
79+
NL_TEST_ASSERT(inSuite, numOfTestsRan > 0);
80+
}
81+
5082
static void TestDevice_GetMonotonicMilliseconds(nlTestSuite * inSuite, void * inContext)
5183
{
5284
static const System::Clock::Milliseconds64 kTestVectorSystemTimeMs[] = {
@@ -83,6 +115,7 @@ static void TestDevice_GetMonotonicMilliseconds(nlTestSuite * inSuite, void * in
83115
*/
84116
static const nlTest sTests[] = {
85117

118+
NL_TEST_DEF("Test DeviceLayer::GetMonotonicMicroseconds", TestDevice_GetMonotonicMicroseconds),
86119
NL_TEST_DEF("Test DeviceLayer::GetMonotonicMilliseconds", TestDevice_GetMonotonicMilliseconds),
87120

88121
NL_TEST_SENTINEL()

src/system/SystemClock.cpp

+27-8
Original file line numberDiff line numberDiff line change
@@ -82,25 +82,35 @@ ClockBase * gClockBase = &gClockImpl;
8282
#define MONOTONIC_CLOCK_ID CLOCK_MONOTONIC
8383
#endif
8484

85-
Milliseconds64 ClockImpl::GetMonotonicMilliseconds64()
85+
Microseconds64 ClockImpl::GetMonotonicMicroseconds64()
8686
{
8787
struct timespec ts;
8888
int res = clock_gettime(MONOTONIC_CLOCK_ID, &ts);
8989
VerifyOrDie(res == 0);
9090
return Seconds64(ts.tv_sec) +
91-
std::chrono::duration_cast<Milliseconds64>(std::chrono::duration<uint64_t, std::nano>(ts.tv_nsec));
91+
std::chrono::duration_cast<Microseconds64>(std::chrono::duration<uint64_t, std::nano>(ts.tv_nsec));
92+
}
93+
94+
Milliseconds64 ClockImpl::GetMonotonicMilliseconds64()
95+
{
96+
return std::chrono::duration_cast<Milliseconds64>(GetMonotonicMicroseconds64());
9297
}
9398

9499
#endif // HAVE_CLOCK_GETTIME
95100

96101
#if HAVE_GETTIMEOFDAY
97102

98-
Milliseconds64 ClockImpl::GetMonotonicMilliseconds64()
103+
Microseconds64 ClockImpl::GetMonotonicMicroseconds64()
99104
{
100105
struct timeval tv;
101106
int res = gettimeofday(&tv, NULL);
102107
VerifyOrDie(res == 0);
103-
return TimevalToMilliseconds(tv);
108+
return TimevalToMicroseconds(tv);
109+
}
110+
111+
Milliseconds64 ClockImpl::GetMonotonicMilliseconds64()
112+
{
113+
return std::chrono::duration_cast<Milliseconds64>(GetMonotonicMicroseconds64());
104114
}
105115

106116
#endif // HAVE_GETTIMEOFDAY
@@ -111,6 +121,11 @@ Milliseconds64 ClockImpl::GetMonotonicMilliseconds64()
111121

112122
// -------------------- Default Get/SetClock Functions for LwIP Systems --------------------
113123

124+
Microseconds64 ClockImpl::GetMonotonicMicroseconds64(void)
125+
{
126+
return GetMonotonicMilliseconds64();
127+
}
128+
114129
Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void)
115130
{
116131
static volatile uint64_t overflow = 0;
@@ -157,27 +172,31 @@ Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void)
157172

158173
#if CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS || CHIP_SYSTEM_CONFIG_USE_SOCKETS
159174

160-
Milliseconds64 TimevalToMilliseconds(const timeval & tv)
175+
Microseconds64 TimevalToMicroseconds(const timeval & tv)
161176
{
162-
return Seconds64(tv.tv_sec) + Milliseconds64(tv.tv_usec);
177+
return Seconds64(tv.tv_sec) + Microseconds64(tv.tv_usec);
163178
}
164179

165-
void ToTimeval(Milliseconds64 in, timeval & out)
180+
void ToTimeval(Microseconds64 in, timeval & out)
166181
{
167182
Seconds32 seconds = std::chrono::duration_cast<Seconds32>(in);
168183
in -= seconds;
169184
out.tv_sec = static_cast<time_t>(seconds.count());
170-
out.tv_usec = static_cast<suseconds_t>(1000 * in.count());
185+
out.tv_usec = static_cast<suseconds_t>(in.count());
171186
}
172187

173188
#endif // CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS || CHIP_SYSTEM_CONFIG_USE_SOCKETS
174189

190+
static_assert(std::numeric_limits<Microseconds64::rep>::is_integer, "Microseconds64 must be an integer type");
191+
static_assert(std::numeric_limits<Microseconds32::rep>::is_integer, "Microseconds32 must be an integer type");
175192
static_assert(std::numeric_limits<Milliseconds64::rep>::is_integer, "Milliseconds64 must be an integer type");
176193
static_assert(std::numeric_limits<Milliseconds32::rep>::is_integer, "Milliseconds32 must be an integer type");
177194
static_assert(std::numeric_limits<Seconds64::rep>::is_integer, "Seconds64 must be an integer type");
178195
static_assert(std::numeric_limits<Seconds32::rep>::is_integer, "Seconds32 must be an integer type");
179196
static_assert(std::numeric_limits<Seconds16::rep>::is_integer, "Seconds16 must be an integer type");
180197

198+
static_assert(std::numeric_limits<Microseconds64::rep>::digits >= 64, "Microseconds64 must be at least 64 bits");
199+
static_assert(std::numeric_limits<Microseconds32::rep>::digits >= 32, "Microseconds32 must be at least 32 bits");
181200
static_assert(std::numeric_limits<Milliseconds64::rep>::digits >= 64, "Milliseconds64 must be at least 64 bits");
182201
static_assert(std::numeric_limits<Milliseconds32::rep>::digits >= 32, "Milliseconds32 must be at least 32 bits");
183202
static_assert(std::numeric_limits<Seconds64::rep>::digits >= 64, "Seconds64 must be at least 64 bits");

src/system/SystemClock.h

+45-4
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ namespace Clock {
5353
* `std::chrono::duration_cast<>()`.
5454
*/
5555

56+
using Microseconds64 = std::chrono::duration<uint64_t, std::micro>;
57+
using Microseconds32 = std::chrono::duration<uint32_t, std::micro>;
58+
5659
using Milliseconds64 = std::chrono::duration<uint64_t, std::milli>;
5760
using Milliseconds32 = std::chrono::duration<uint32_t, std::milli>;
5861

@@ -64,6 +67,19 @@ constexpr Seconds16 kZero{ 0 };
6467

6568
namespace Literals {
6669

70+
constexpr Microseconds64 operator""_us(unsigned long long int us)
71+
{
72+
return Microseconds64(us);
73+
}
74+
constexpr Microseconds64 operator""_us64(unsigned long long int us)
75+
{
76+
return Microseconds64(us);
77+
}
78+
constexpr Microseconds32 operator""_us32(unsigned long long int us)
79+
{
80+
return Microseconds32(us);
81+
}
82+
6783
constexpr Milliseconds64 operator""_ms(unsigned long long int ms)
6884
{
6985
return Milliseconds64(ms);
@@ -127,6 +143,29 @@ class ClockBase
127143
*/
128144
Timestamp GetMonotonicTimestamp() { return GetMonotonicMilliseconds64(); }
129145

146+
/**
147+
* Returns a monotonic system time in units of microseconds.
148+
*
149+
* This function returns an elapsed time in microseconds since an arbitrary, platform-defined epoch.
150+
* The value returned is guaranteed to be ever-increasing (i.e. never wrapping or decreasing) between
151+
* reboots of the system. Additionally, the underlying time source is guaranteed to tick
152+
* continuously during any system sleep modes that do not entail a restart upon wake.
153+
*
154+
* Although some platforms may choose to return a value that measures the time since boot for the
155+
* system, applications must *not* rely on this.
156+
*
157+
* Applications must not rely on the time returned by GetMonotonicMicroseconds64() actually having
158+
* granularity finer than milliseconds.
159+
*
160+
* Platform implementations *must* use the same epoch for GetMonotonicMicroseconds64() and GetMonotonicMilliseconds64().
161+
*
162+
* Platforms *must* use an epoch such that the upper bit of a value returned by GetMonotonicMicroseconds64() is zero
163+
* for the expected operational life of the system.
164+
*
165+
* @returns Elapsed time in microseconds since an arbitrary, platform-defined epoch.
166+
*/
167+
virtual Microseconds64 GetMonotonicMicroseconds64() = 0;
168+
130169
/**
131170
* Returns a monotonic system time in units of milliseconds.
132171
*
@@ -138,8 +177,9 @@ class ClockBase
138177
* Although some platforms may choose to return a value that measures the time since boot for the
139178
* system, applications must *not* rely on this.
140179
*
141-
* Platforms *must* use an epoch such that the upper bit of a value returned by GetMonotonicMilliseconds64() is zero
142-
* for the expected operational life of the system.
180+
* Platform implementations *must* use the same epoch for GetMonotonicMicroseconds64() and GetMonotonicMilliseconds64().
181+
* (As a consequence of this, and the requirement for GetMonotonicMicroseconds64() to return high bit zero, values
182+
* returned by GetMonotonicMilliseconds64() will have the high ten bits zero.)
143183
*
144184
* @returns Elapsed time in milliseconds since an arbitrary, platform-defined epoch.
145185
*/
@@ -151,6 +191,7 @@ class ClockImpl : public ClockBase
151191
{
152192
public:
153193
~ClockImpl() = default;
194+
Microseconds64 GetMonotonicMicroseconds64() override;
154195
Milliseconds64 GetMonotonicMilliseconds64() override;
155196
};
156197

@@ -167,8 +208,8 @@ inline void SetSystemClockForTesting(Clock::ClockBase * clock)
167208
} // namespace Internal
168209

169210
#if CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS || CHIP_SYSTEM_CONFIG_USE_SOCKETS
170-
Milliseconds64 TimevalToMilliseconds(const timeval & in);
171-
void ToTimeval(Milliseconds64 in, timeval & out);
211+
Microseconds64 TimevalToMicroseconds(const timeval & in);
212+
void ToTimeval(Microseconds64 in, timeval & out);
172213
#endif // CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS || CHIP_SYSTEM_CONFIG_USE_SOCKETS
173214

174215
} // namespace Clock

src/system/tests/TestSystemClock.cpp

+12-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,12 @@ void TestRealClock(nlTestSuite * inSuite, void * inContext)
5151
Clock::Milliseconds64 newMilli = SystemClock().GetMonotonicMilliseconds64();
5252
NL_TEST_ASSERT(inSuite, newMilli >= oldMilli);
5353

54-
Clock::Milliseconds64::rep milliseconds = newMilli.count();
55-
NL_TEST_ASSERT(inSuite, (milliseconds & 0x8000'0000'0000'0000) == 0);
54+
Clock::Microseconds64 oldMicro = SystemClock().GetMonotonicMicroseconds64();
55+
Clock::Microseconds64 newMicro = SystemClock().GetMonotonicMicroseconds64();
56+
NL_TEST_ASSERT(inSuite, newMicro >= oldMicro);
57+
58+
Clock::Microseconds64::rep microseconds = newMicro.count();
59+
NL_TEST_ASSERT(inSuite, (microseconds & 0x8000'0000'0000'0000) == 0);
5660

5761
#if !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME && \
5862
(CHIP_SYSTEM_CONFIG_USE_LWIP_MONOTONIC_TIME || CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS)
@@ -72,6 +76,9 @@ void TestRealClock(nlTestSuite * inSuite, void * inContext)
7276
newMilli = SystemClock().GetMonotonicMilliseconds64();
7377
NL_TEST_ASSERT(inSuite, newMilli > oldMilli);
7478

79+
newMicro = SystemClock().GetMonotonicMicroseconds64();
80+
NL_TEST_ASSERT(inSuite, newMicro > oldMicro);
81+
7582
#endif // !CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME && (CHIP_SYSTEM_CONFIG_USE_LWIP_MONOTONIC_TIME ||
7683
// CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS)
7784
}
@@ -81,6 +88,7 @@ void TestMockClock(nlTestSuite * inSuite, void * inContext)
8188
class MockClock : public Clock::ClockBase
8289
{
8390
public:
91+
Clock::Microseconds64 GetMonotonicMicroseconds64() override { return mTime; }
8492
Clock::Milliseconds64 GetMonotonicMilliseconds64() override { return mTime; }
8593
Clock::Milliseconds64 mTime = Clock::kZero;
8694
};
@@ -90,10 +98,12 @@ void TestMockClock(nlTestSuite * inSuite, void * inContext)
9098
Clock::Internal::SetSystemClockForTesting(&clock);
9199

92100
NL_TEST_ASSERT(inSuite, SystemClock().GetMonotonicMilliseconds64() == Clock::kZero);
101+
NL_TEST_ASSERT(inSuite, SystemClock().GetMonotonicMicroseconds64() == Clock::kZero);
93102

94103
constexpr Clock::Milliseconds64 k1234 = Clock::Milliseconds64(1234);
95104
clock.mTime = k1234;
96105
NL_TEST_ASSERT(inSuite, SystemClock().GetMonotonicMilliseconds64() == k1234);
106+
NL_TEST_ASSERT(inSuite, SystemClock().GetMonotonicMicroseconds64() == k1234);
97107

98108
Clock::Internal::SetSystemClockForTesting(savedRealClock);
99109
}

0 commit comments

Comments
 (0)