提交 606b421c 编写于 作者: K kvn

6863420: os::javaTimeNanos() go backward on Solaris x86

Summary: Use new atomic long load method Atomic::load() to load max_hrtime.
Reviewed-by: never, ysr, johnc, phh, dcubed, acorn
上级 acedc402
...@@ -1643,7 +1643,8 @@ inline hrtime_t oldgetTimeNanos() { ...@@ -1643,7 +1643,8 @@ inline hrtime_t oldgetTimeNanos() {
inline hrtime_t getTimeNanos() { inline hrtime_t getTimeNanos() {
if (VM_Version::supports_cx8()) { if (VM_Version::supports_cx8()) {
const hrtime_t now = gethrtime(); const hrtime_t now = gethrtime();
const hrtime_t prev = max_hrtime; // 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; if (now <= prev) return prev; // same or retrograde time;
const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev); const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev);
assert(obsv >= prev, "invariant"); // Monotonicity assert(obsv >= prev, "invariant"); // Monotonicity
......
...@@ -46,6 +46,8 @@ inline void Atomic::dec (volatile jint* dest) { (void)add (-1, dest); ...@@ -46,6 +46,8 @@ inline void Atomic::dec (volatile jint* dest) { (void)add (-1, dest);
inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); } inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); }
inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); } inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); }
inline jlong Atomic::load(volatile jlong* src) { return *src; }
#ifdef _GNU_SOURCE #ifdef _GNU_SOURCE
inline jint Atomic::add (jint add_value, volatile jint* dest) { inline jint Atomic::add (jint add_value, volatile jint* dest) {
......
...@@ -99,6 +99,8 @@ inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* ...@@ -99,6 +99,8 @@ inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void*
return (void*)_Atomic_cmpxchg_long((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, (int) os::is_MP()); return (void*)_Atomic_cmpxchg_long((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, (int) os::is_MP());
} }
inline jlong Atomic::load(volatile jlong* src) { return *src; }
#else // !AMD64 #else // !AMD64
inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
...@@ -131,6 +133,15 @@ inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* ...@@ -131,6 +133,15 @@ inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t*
inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) { inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) {
return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value); return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value);
} }
extern "C" void _Atomic_load_long(volatile jlong* src, volatile jlong* dst);
inline jlong Atomic::load(volatile jlong* src) {
volatile jlong dest;
_Atomic_load_long(src, &dest);
return dest;
}
#endif // AMD64 #endif // AMD64
#ifdef _GNU_SOURCE #ifdef _GNU_SOURCE
......
...@@ -97,6 +97,15 @@ ...@@ -97,6 +97,15 @@
popl %ebx popl %ebx
.end .end
// Support for void Atomic::load(volatile jlong* src, volatile jlong* dest).
.inline _Atomic_load_long,2
movl 0(%esp), %eax // src
fildll (%eax)
movl 4(%esp), %eax // dest
fistpll (%eax)
.end
// Support for OrderAccess::acquire() // Support for OrderAccess::acquire()
.inline _OrderAccess_acquire,0 .inline _OrderAccess_acquire,0
movl 0(%esp), %eax movl 0(%esp), %eax
......
...@@ -39,6 +39,8 @@ class Atomic : AllStatic { ...@@ -39,6 +39,8 @@ class Atomic : AllStatic {
static void store_ptr(intptr_t store_value, volatile intptr_t* dest); static void store_ptr(intptr_t store_value, volatile intptr_t* dest);
static void store_ptr(void* store_value, volatile void* dest); static void store_ptr(void* store_value, volatile void* dest);
static jlong load(volatile jlong* src);
// Atomically add to a location, return updated value // Atomically add to a location, return updated value
static jint add (jint add_value, volatile jint* dest); static jint add (jint add_value, volatile jint* dest);
static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest); static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest);
......
/*
* Copyright 2009 D.E. Shaw. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
/**
* @test
* @bug 6863420
* @summary os::javaTimeNanos() go backward on Solaris x86
*
* @run main/othervm Test
*/
public class Test {
static long value = 0;
static boolean got_backward_time = false;
public static void main(String args[]) {
final int count = 100000;
for (int numThreads = 1; numThreads <= 32; numThreads++) {
final int numRuns = 1;
for (int t=1; t <= numRuns; t++) {
final int curRun = t;
System.out.println("Spawning " + numThreads + " threads");
final Thread threads[] = new Thread[numThreads];
for (int i = 0; i < threads.length; i++) {
Runnable thread =
new Runnable() {
public void run() {
for (long l = 0; l < 100000; l++) {
final long start = System.nanoTime();
if (value == 12345678) {
System.out.println("Wow!");
}
final long end = System.nanoTime();
final long time = end - start;
value += time;
if (time < 0) {
System.out.println(
"Backwards: " +
"start=" + start + " " +
"end=" + end + " " +
"time= " + time
);
got_backward_time = true;
}
}
}
};
threads[i] = new Thread(thread, "Thread" + i);
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
for (int i = 0; i < threads.length; i++) {
try {
threads[i].join();
}
catch (InterruptedException e) {
continue;
}
}
}
}
if (got_backward_time) {
System.exit(97);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册