Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
447b6153
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
447b6153
编写于
4月 25, 2014
作者:
S
sla
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8040140: System.nanoTime() is slow and non-monotonic on OS X
Reviewed-by: sspitsyn, shade, dholmes, acorn
上级
6c2fbc4e
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
76 addition
and
62 deletion
+76
-62
src/os/bsd/vm/os_bsd.cpp
src/os/bsd/vm/os_bsd.cpp
+39
-3
src/os/bsd/vm/os_bsd.hpp
src/os/bsd/vm/os_bsd.hpp
+10
-4
src/os/solaris/vm/os_solaris.cpp
src/os/solaris/vm/os_solaris.cpp
+24
-55
src/share/vm/runtime/os.hpp
src/share/vm/runtime/os.hpp
+3
-0
未找到文件。
src/os/bsd/vm/os_bsd.cpp
浏览文件 @
447b6153
...
...
@@ -127,8 +127,12 @@
// global variables
julong
os
::
Bsd
::
_physical_memory
=
0
;
#ifdef __APPLE__
mach_timebase_info_data_t
os
::
Bsd
::
_timebase_info
=
{
0
,
0
};
volatile
uint64_t
os
::
Bsd
::
_max_abstime
=
0
;
#else
int
(
*
os
::
Bsd
::
_clock_gettime
)(
clockid_t
,
struct
timespec
*
)
=
NULL
;
#endif
pthread_t
os
::
Bsd
::
_main_thread
;
int
os
::
Bsd
::
_page_size
=
-
1
;
...
...
@@ -986,13 +990,15 @@ jlong os::javaTimeMillis() {
return
jlong
(
time
.
tv_sec
)
*
1000
+
jlong
(
time
.
tv_usec
/
1000
);
}
#ifndef __APPLE__
#ifndef CLOCK_MONOTONIC
#define CLOCK_MONOTONIC (1)
#endif
#endif
#ifdef __APPLE__
void
os
::
Bsd
::
clock_init
()
{
// XXXDARWIN: Investigate replacement monotonic clock
mach_timebase_info
(
&
_timebase_info
);
}
#else
void
os
::
Bsd
::
clock_init
()
{
...
...
@@ -1007,10 +1013,38 @@ void os::Bsd::clock_init() {
#endif
#ifdef __APPLE__
jlong
os
::
javaTimeNanos
()
{
const
uint64_t
tm
=
mach_absolute_time
();
const
uint64_t
now
=
(
tm
*
Bsd
::
_timebase_info
.
numer
)
/
Bsd
::
_timebase_info
.
denom
;
const
uint64_t
prev
=
Bsd
::
_max_abstime
;
if
(
now
<=
prev
)
{
return
prev
;
// same or retrograde time;
}
const
uint64_t
obsv
=
Atomic
::
cmpxchg
(
now
,
(
volatile
jlong
*
)
&
Bsd
::
_max_abstime
,
prev
);
assert
(
obsv
>=
prev
,
"invariant"
);
// Monotonicity
// If the CAS succeeded then we're done and return "now".
// If the CAS failed and the observed value "obsv" is >= now then
// we should return "obsv". If the CAS failed and now > obsv > prv then
// some other thread raced this thread and installed a new value, in which case
// we could either (a) retry the entire operation, (b) retry trying to install now
// or (c) just return obsv. We use (c). No loop is required although in some cases
// we might discard a higher "now" value in deference to a slightly lower but freshly
// installed obsv value. That's entirely benign -- it admits no new orderings compared
// to (a) or (b) -- and greatly reduces coherence traffic.
// We might also condition (c) on the magnitude of the delta between obsv and now.
// Avoiding excessive CAS operations to hot RW locations is critical.
// See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate
return
(
prev
==
obsv
)
?
now
:
obsv
;
}
#else // __APPLE__
jlong
os
::
javaTimeNanos
()
{
if
(
Bsd
::
supports_monotonic_clock
())
{
struct
timespec
tp
;
int
status
=
Bsd
::
clock_gettime
(
CLOCK_MONOTONIC
,
&
tp
);
int
status
=
Bsd
::
_
clock_gettime
(
CLOCK_MONOTONIC
,
&
tp
);
assert
(
status
==
0
,
"gettime error"
);
jlong
result
=
jlong
(
tp
.
tv_sec
)
*
(
1000
*
1000
*
1000
)
+
jlong
(
tp
.
tv_nsec
);
return
result
;
...
...
@@ -1023,6 +1057,8 @@ jlong os::javaTimeNanos() {
}
}
#endif // __APPLE__
void
os
::
javaTimeNanos_info
(
jvmtiTimerInfo
*
info_ptr
)
{
if
(
Bsd
::
supports_monotonic_clock
())
{
info_ptr
->
max_value
=
ALL_64_BITS
;
...
...
src/os/bsd/vm/os_bsd.hpp
浏览文件 @
447b6153
...
...
@@ -58,7 +58,13 @@ class Bsd {
// For signal flags diagnostics
static
int
sigflags
[
MAXSIGNUM
];
#ifdef __APPLE__
// mach_absolute_time
static
mach_timebase_info_data_t
_timebase_info
;
static
volatile
uint64_t
_max_abstime
;
#else
static
int
(
*
_clock_gettime
)(
clockid_t
,
struct
timespec
*
);
#endif
static
GrowableArray
<
int
>*
_cpu_to_node
;
...
...
@@ -135,11 +141,11 @@ class Bsd {
static
void
clock_init
(
void
);
static
inline
bool
supports_monotonic_clock
()
{
#ifdef __APPLE__
return
true
;
#else
return
_clock_gettime
!=
NULL
;
}
static
int
clock_gettime
(
clockid_t
clock_id
,
struct
timespec
*
tp
)
{
return
_clock_gettime
?
_clock_gettime
(
clock_id
,
tp
)
:
-
1
;
#endif
}
// Stack repair handling
...
...
src/os/solaris/vm/os_solaris.cpp
浏览文件 @
447b6153
...
...
@@ -415,11 +415,7 @@ julong os::physical_memory() {
static
hrtime_t
first_hrtime
=
0
;
static
const
hrtime_t
hrtime_hz
=
1000
*
1000
*
1000
;
const
int
LOCK_BUSY
=
1
;
const
int
LOCK_FREE
=
0
;
const
int
LOCK_INVALID
=
-
1
;
static
volatile
hrtime_t
max_hrtime
=
0
;
static
volatile
int
max_hrtime_lock
=
LOCK_FREE
;
// Update counter with LSB as lock-in-progress
void
os
::
Solaris
::
initialize_system_info
()
{
...
...
@@ -1534,58 +1530,31 @@ void* os::thread_local_storage_at(int index) {
}
// gethrtime can move backwards if read from one cpu and then a different cpu
// getTimeNanos is guaranteed to not move backward on Solaris
// local spinloop created as faster for a CAS on an int than
// a CAS on a 64bit jlong. Also Atomic::cmpxchg for jlong is not
// supported on sparc v8 or pre supports_cx8 intel boxes.
// oldgetTimeNanos for systems which do not support CAS on 64bit jlong
// i.e. sparc v8 and pre supports_cx8 (i486) intel boxes
inline
hrtime_t
oldgetTimeNanos
()
{
int
gotlock
=
LOCK_INVALID
;
hrtime_t
newtime
=
gethrtime
();
for
(;;)
{
// grab lock for max_hrtime
int
curlock
=
max_hrtime_lock
;
if
(
curlock
&
LOCK_BUSY
)
continue
;
if
(
gotlock
=
Atomic
::
cmpxchg
(
LOCK_BUSY
,
&
max_hrtime_lock
,
LOCK_FREE
)
!=
LOCK_FREE
)
continue
;
if
(
newtime
>
max_hrtime
)
{
max_hrtime
=
newtime
;
}
else
{
newtime
=
max_hrtime
;
}
// release lock
max_hrtime_lock
=
LOCK_FREE
;
return
newtime
;
}
}
// gethrtime can move backwards if read from one cpu and then a different cpu
// getTimeNanos is guaranteed to not move backward on Solaris
// gethrtime() should be monotonic according to the documentation,
// but some virtualized platforms are known to break this guarantee.
// getTimeNanos() must be guaranteed not to move backwards, so we
// are forced to add a check here.
inline
hrtime_t
getTimeNanos
()
{
if
(
VM_Version
::
supports_cx8
())
{
const
hrtime_t
now
=
gethrtime
();
// Use atomic long load since 32-bit x86 uses 2 registers to keep long.
const
hrtime_t
prev
=
Atomic
::
load
((
volatile
jlong
*
)
&
max_hrtime
);
if
(
now
<=
prev
)
return
prev
;
// same or retrograde time;
const
hrtime_t
obsv
=
Atomic
::
cmpxchg
(
now
,
(
volatile
jlong
*
)
&
max_hrtime
,
prev
);
assert
(
obsv
>=
prev
,
"invariant"
);
// Monotonicity
// If the CAS succeeded then we're done and return "now".
// If the CAS failed and the observed value "obs" is >= now then
// we should return "obs". If the CAS failed and now > obs > prv then
// some other thread raced this thread and installed a new value, in which case
// we could either (a) retry the entire operation, (b) retry trying to install now
// or (c) just return obs. We use (c). No loop is required although in some cases
// we might discard a higher "now" value in deference to a slightly lower but freshly
// installed obs value. That's entirely benign -- it admits no new orderings compared
// to (a) or (b) -- and greatly reduces coherence traffic.
// We might also condition (c) on the magnitude of the delta between obs and now.
// Avoiding excessive CAS operations to hot RW locations is critical.
// See http://blogs.sun.com/dave/entry/cas_and_cache_trivia_invalidate
return
(
prev
==
obsv
)
?
now
:
obsv
;
}
else
{
return
oldgetTimeNanos
();
}
const
hrtime_t
now
=
gethrtime
();
const
hrtime_t
prev
=
max_hrtime
;
if
(
now
<=
prev
)
{
return
prev
;
// same or retrograde time;
}
const
hrtime_t
obsv
=
Atomic
::
cmpxchg
(
now
,
(
volatile
jlong
*
)
&
max_hrtime
,
prev
);
assert
(
obsv
>=
prev
,
"invariant"
);
// Monotonicity
// If the CAS succeeded then we're done and return "now".
// If the CAS failed and the observed value "obsv" is >= now then
// we should return "obsv". If the CAS failed and now > obsv > prv then
// some other thread raced this thread and installed a new value, in which case
// we could either (a) retry the entire operation, (b) retry trying to install now
// or (c) just return obsv. We use (c). No loop is required although in some cases
// we might discard a higher "now" value in deference to a slightly lower but freshly
// installed obsv value. That's entirely benign -- it admits no new orderings compared
// to (a) or (b) -- and greatly reduces coherence traffic.
// We might also condition (c) on the magnitude of the delta between obsv and now.
// Avoiding excessive CAS operations to hot RW locations is critical.
// See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate
return
(
prev
==
obsv
)
?
now
:
obsv
;
}
// Time since start-up in seconds to a fine granularity.
...
...
src/share/vm/runtime/os.hpp
浏览文件 @
447b6153
...
...
@@ -48,6 +48,9 @@
#ifdef TARGET_OS_FAMILY_bsd
# include "jvm_bsd.h"
# include <setjmp.h>
# ifdef __APPLE__
# include <mach/mach_time.h>
# endif
#endif
class
AgentLibrary
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录