Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
bingbingbingbing
mono
提交
cbd6944e
M
mono
项目概览
bingbingbingbing
/
mono
与 Fork 源项目一致
从无法访问的项目Fork
通知
35
Star
0
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
mono
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
cbd6944e
编写于
10月 28, 2019
作者:
J
Jonathan Chambers
提交者:
GitHub
10月 28, 2019
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1236 from Unity-Technologies/android-stopwatch-fix
Fix case 1044454. Stopwatch on Android does not update.
上级
07057aa8
d4965180
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
77 addition
and
18 deletion
+77
-18
mono/utils/mono-time.c
mono/utils/mono-time.c
+77
-18
未找到文件。
mono/utils/mono-time.c
浏览文件 @
cbd6944e
...
...
@@ -94,6 +94,77 @@ mono_100ns_datetime (void)
/* a made up uptime of 300 seconds */
#define MADEUP_BOOT_TIME (300 * MTICKS_PER_SEC)
#if defined(ANDROID)
#include <math.h>
/* CLOCK_MONOTONIC is the most reliable clock type on Android. However, it
does not tick when the device is sleeping (case 867885, case 1037712).
CLOCK_BOOTTIME includes that time, but is very unreliable. Some older
devices had this time ticking back or jumping back and forth (case 970945)
To fix this issue we combine both clocks to produce a CLOCK_MONOTONIC-based
clock that ticks even when the device is disabled.
*/
gint64
android_get_time_since_startup
(
double
current_monotonic_time
,
double
current_boottime_time
)
{
static
double
monotonic_start_time
=
-
HUGE_VAL
;
static
double
boottime_start_time
=
-
HUGE_VAL
;
static
double
boottime_adjustment
=
0
;
static
int
broken_boottime
=
0
;
static
double
broken_boottime_detection_hysteresis
=
0
.
001
;
static
double
adjustment_hysteresis_when_bootime_good
=
0
.
001
;
static
double
adjustment_hysteresis_when_bootime_broken
=
8
;
if
(
monotonic_start_time
==
-
HUGE_VAL
)
monotonic_start_time
=
current_monotonic_time
;
if
(
boottime_start_time
==
-
HUGE_VAL
)
boottime_start_time
=
current_boottime_time
;
double
monotonicSinceStart
=
current_monotonic_time
-
monotonic_start_time
;
double
boottimeSinceStart
=
current_boottime_time
-
boottime_start_time
;
/* In theory, boottime can only go faster than monotonic, so whenever we detect
this condition we assume that device was asleep and we must adjust the returned
time by the amount of time that the boottime jumped forwards.
In the real world, boottime can go slower than monotonic or even backwards.
We work around this by only taking into account the total difference between
boottime and monotonic times and only adjusting monotonic time when this difference
increases.
There's also a problem that on some devices the boottime continuously jumps
forwards and backwards by ~4 seconds. This means that a naive implementation would
often do more than one time jump after device sleeps, depending on which part
of the jump "cycle" we landed. We work around this by introducing hysteresis of
hysteresisSeconds seconds and adjusting monotonic time only when this adjustment
changes by more than hysteresisSeconds amount, but only on broken devices.
On devices with broken CLOCK_BOOTTIME behaviour this would ignore device sleeps of
hysteresisSeconds or less, which is small compromise to make.
*/
if
(
boottimeSinceStart
-
monotonicSinceStart
<
-
broken_boottime_detection_hysteresis
)
broken_boottime
=
1
;
double
hysteresisSeconds
=
broken_boottime
?
adjustment_hysteresis_when_bootime_broken
:
adjustment_hysteresis_when_bootime_good
;
if
(
boottimeSinceStart
-
monotonicSinceStart
>
boottime_adjustment
+
hysteresisSeconds
)
boottime_adjustment
=
boottimeSinceStart
-
monotonicSinceStart
;
return
(
gint64
)(
monotonicSinceStart
+
boottime_adjustment
);
}
#endif
#if defined(CLOCK_MONOTONIC)
static
gint64
get_posix_time_for_class
(
int
clock_class
)
{
struct
timespec
tspec
;
static
struct
timespec
tspec_freq
=
{
0
};
static
int
can_use_clock
=
0
;
if
(
!
tspec_freq
.
tv_nsec
)
{
can_use_clock
=
clock_getres
(
clock_class
,
&
tspec_freq
)
==
0
;
/*printf ("resolution: %lu.%lu\n", tspec_freq.tv_sec, tspec_freq.tv_nsec);*/
}
if
(
can_use_clock
)
{
if
(
clock_gettime
(
clock_class
,
&
tspec
)
==
0
)
{
/*printf ("time: %lu.%lu\n", tspec.tv_sec, tspec.tv_nsec); */
return
((
gint64
)
tspec
.
tv_sec
*
MTICKS_PER_SEC
+
tspec
.
tv_nsec
/
100
);
}
}
}
#endif
static
gint64
get_boot_time
(
void
)
{
...
...
@@ -132,11 +203,7 @@ gint64
mono_msec_boottime
(
void
)
{
#if defined(ANDROID)
struct
timespec
ts
;
if
(
clock_gettime
(
CLOCK_MONOTONIC
,
&
ts
)
!=
0
)
{
return
(
gint64
)
MADEUP_BOOT_TIME
;
}
return
(
ts
.
tv_sec
*
1000
)
+
(
ts
.
tv_nsec
/
1000000
);
return
get_posix_time_for_class
(
CLOCK_BOOTTIME
);
#else
static
gint64
boot_time
=
0
;
gint64
now
;
...
...
@@ -163,19 +230,11 @@ mono_100ns_ticks (void)
}
return
now
*
timebase
.
numer
/
timebase
.
denom
;
#elif defined(CLOCK_MONOTONIC)
struct
timespec
tspec
;
static
struct
timespec
tspec_freq
=
{
0
};
static
int
can_use_clock
=
0
;
if
(
!
tspec_freq
.
tv_nsec
)
{
can_use_clock
=
clock_getres
(
CLOCK_MONOTONIC
,
&
tspec_freq
)
==
0
;
/*printf ("resolution: %lu.%lu\n", tspec_freq.tv_sec, tspec_freq.tv_nsec);*/
}
if
(
can_use_clock
)
{
if
(
clock_gettime
(
CLOCK_MONOTONIC
,
&
tspec
)
==
0
)
{
/*printf ("time: %lu.%lu\n", tspec.tv_sec, tspec.tv_nsec); */
return
((
gint64
)
tspec
.
tv_sec
*
MTICKS_PER_SEC
+
tspec
.
tv_nsec
/
100
);
}
}
#if defined(ANDROID)
return
android_get_time_since_startup
(
get_posix_time_for_class
(
CLOCK_BOOTTIME
),
get_posix_time_for_class
(
CLOCK_MONOTONIC
));
#else
return
get_posix_time_for_class
(
CLOCK_MONOTONIC
);
#endif
#endif
if
(
gettimeofday
(
&
tv
,
NULL
)
==
0
)
return
((
gint64
)
tv
.
tv_sec
*
1000000
+
tv
.
tv_usec
)
*
10
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录