Skip to content

Commit 90852c6

Browse files
committed
Revert "Fix case 1044454: Stopwatch does not track time when an app is in the background or the device is asleep."
This reverts commit d496518.
1 parent ef2b8b2 commit 90852c6

File tree

1 file changed

+18
-77
lines changed

1 file changed

+18
-77
lines changed

mono/utils/mono-time.c

+18-77
Original file line numberDiff line numberDiff line change
@@ -94,77 +94,6 @@ mono_100ns_datetime (void)
9494
/* a made up uptime of 300 seconds */
9595
#define MADEUP_BOOT_TIME (300 * MTICKS_PER_SEC)
9696

97-
#if defined(ANDROID)
98-
#include <math.h>
99-
/* CLOCK_MONOTONIC is the most reliable clock type on Android. However, it
100-
does not tick when the device is sleeping (case 867885, case 1037712).
101-
CLOCK_BOOTTIME includes that time, but is very unreliable. Some older
102-
103-
devices had this time ticking back or jumping back and forth (case 970945)
104-
To fix this issue we combine both clocks to produce a CLOCK_MONOTONIC-based
105-
clock that ticks even when the device is disabled.
106-
*/
107-
gint64 android_get_time_since_startup(double current_monotonic_time, double current_boottime_time)
108-
{
109-
static double monotonic_start_time = -HUGE_VAL;
110-
static double boottime_start_time = -HUGE_VAL;
111-
static double boottime_adjustment = 0;
112-
static int broken_boottime = 0;
113-
static double broken_boottime_detection_hysteresis = 0.001;
114-
static double adjustment_hysteresis_when_bootime_good = 0.001;
115-
static double adjustment_hysteresis_when_bootime_broken = 8;
116-
117-
if (monotonic_start_time == -HUGE_VAL)
118-
monotonic_start_time = current_monotonic_time;
119-
if (boottime_start_time == -HUGE_VAL)
120-
boottime_start_time = current_boottime_time;
121-
double monotonicSinceStart = current_monotonic_time - monotonic_start_time;
122-
double boottimeSinceStart = current_boottime_time - boottime_start_time;
123-
/* In theory, boottime can only go faster than monotonic, so whenever we detect
124-
this condition we assume that device was asleep and we must adjust the returned
125-
time by the amount of time that the boottime jumped forwards.
126-
In the real world, boottime can go slower than monotonic or even backwards.
127-
We work around this by only taking into account the total difference between
128-
boottime and monotonic times and only adjusting monotonic time when this difference
129-
increases.
130-
There's also a problem that on some devices the boottime continuously jumps
131-
forwards and backwards by ~4 seconds. This means that a naive implementation would
132-
often do more than one time jump after device sleeps, depending on which part
133-
of the jump "cycle" we landed. We work around this by introducing hysteresis of
134-
hysteresisSeconds seconds and adjusting monotonic time only when this adjustment
135-
changes by more than hysteresisSeconds amount, but only on broken devices.
136-
On devices with broken CLOCK_BOOTTIME behaviour this would ignore device sleeps of
137-
hysteresisSeconds or less, which is small compromise to make.
138-
*/
139-
if (boottimeSinceStart - monotonicSinceStart < -broken_boottime_detection_hysteresis)
140-
broken_boottime = 1;
141-
double hysteresisSeconds = broken_boottime ? adjustment_hysteresis_when_bootime_broken : adjustment_hysteresis_when_bootime_good;
142-
if (boottimeSinceStart - monotonicSinceStart > boottime_adjustment + hysteresisSeconds)
143-
boottime_adjustment = boottimeSinceStart - monotonicSinceStart;
144-
return (gint64)(monotonicSinceStart + boottime_adjustment);
145-
}
146-
#endif
147-
148-
#if defined(CLOCK_MONOTONIC)
149-
static gint64
150-
get_posix_time_for_class(int clock_class)
151-
{
152-
struct timespec tspec;
153-
static struct timespec tspec_freq = {0};
154-
static int can_use_clock = 0;
155-
if (!tspec_freq.tv_nsec) {
156-
can_use_clock = clock_getres (clock_class, &tspec_freq) == 0;
157-
/*printf ("resolution: %lu.%lu\n", tspec_freq.tv_sec, tspec_freq.tv_nsec);*/
158-
}
159-
if (can_use_clock) {
160-
if (clock_gettime (clock_class, &tspec) == 0) {
161-
/*printf ("time: %lu.%lu\n", tspec.tv_sec, tspec.tv_nsec); */
162-
return ((gint64)tspec.tv_sec * MTICKS_PER_SEC + tspec.tv_nsec / 100);
163-
}
164-
}
165-
}
166-
#endif
167-
16897
static gint64
16998
get_boot_time (void)
17099
{
@@ -203,7 +132,11 @@ gint64
203132
mono_msec_boottime (void)
204133
{
205134
#if defined(ANDROID)
206-
return get_posix_time_for_class(CLOCK_BOOTTIME);
135+
struct timespec ts;
136+
if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
137+
return (gint64)MADEUP_BOOT_TIME;
138+
}
139+
return (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
207140
#else
208141
static gint64 boot_time = 0;
209142
gint64 now;
@@ -230,11 +163,19 @@ mono_100ns_ticks (void)
230163
}
231164
return now * timebase.numer / timebase.denom;
232165
#elif defined(CLOCK_MONOTONIC)
233-
#if defined(ANDROID)
234-
return android_get_time_since_startup(get_posix_time_for_class(CLOCK_BOOTTIME), get_posix_time_for_class(CLOCK_MONOTONIC));
235-
#else
236-
return get_posix_time_for_class(CLOCK_MONOTONIC);
237-
#endif
166+
struct timespec tspec;
167+
static struct timespec tspec_freq = {0};
168+
static int can_use_clock = 0;
169+
if (!tspec_freq.tv_nsec) {
170+
can_use_clock = clock_getres (CLOCK_MONOTONIC, &tspec_freq) == 0;
171+
/*printf ("resolution: %lu.%lu\n", tspec_freq.tv_sec, tspec_freq.tv_nsec);*/
172+
}
173+
if (can_use_clock) {
174+
if (clock_gettime (CLOCK_MONOTONIC, &tspec) == 0) {
175+
/*printf ("time: %lu.%lu\n", tspec.tv_sec, tspec.tv_nsec); */
176+
return ((gint64)tspec.tv_sec * MTICKS_PER_SEC + tspec.tv_nsec / 100);
177+
}
178+
}
238179
#endif
239180
if (gettimeofday (&tv, NULL) == 0)
240181
return ((gint64)tv.tv_sec * 1000000 + tv.tv_usec) * 10;

0 commit comments

Comments
 (0)