native_clock: Use writeback from CAS to avoid double-loading
This commit is contained in:
parent
084bd225dc
commit
979e53b87b
|
@ -55,8 +55,9 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen
|
||||||
u64 NativeClock::GetRTSC() {
|
u64 NativeClock::GetRTSC() {
|
||||||
TimePoint new_time_point{};
|
TimePoint new_time_point{};
|
||||||
TimePoint current_time_point{};
|
TimePoint current_time_point{};
|
||||||
do {
|
|
||||||
current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
|
current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
|
||||||
|
do {
|
||||||
_mm_mfence();
|
_mm_mfence();
|
||||||
const u64 current_measure = __rdtsc();
|
const u64 current_measure = __rdtsc();
|
||||||
u64 diff = current_measure - current_time_point.inner.last_measure;
|
u64 diff = current_measure - current_time_point.inner.last_measure;
|
||||||
|
@ -66,7 +67,7 @@ u64 NativeClock::GetRTSC() {
|
||||||
: current_time_point.inner.last_measure;
|
: current_time_point.inner.last_measure;
|
||||||
new_time_point.inner.accumulated_ticks = current_time_point.inner.accumulated_ticks + diff;
|
new_time_point.inner.accumulated_ticks = current_time_point.inner.accumulated_ticks + diff;
|
||||||
} while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack,
|
} while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack,
|
||||||
current_time_point.pack));
|
current_time_point.pack, current_time_point.pack));
|
||||||
/// The clock cannot be more precise than the guest timer, remove the lower bits
|
/// The clock cannot be more precise than the guest timer, remove the lower bits
|
||||||
return new_time_point.inner.accumulated_ticks & inaccuracy_mask;
|
return new_time_point.inner.accumulated_ticks & inaccuracy_mask;
|
||||||
}
|
}
|
||||||
|
@ -75,13 +76,14 @@ void NativeClock::Pause(bool is_paused) {
|
||||||
if (!is_paused) {
|
if (!is_paused) {
|
||||||
TimePoint current_time_point{};
|
TimePoint current_time_point{};
|
||||||
TimePoint new_time_point{};
|
TimePoint new_time_point{};
|
||||||
do {
|
|
||||||
current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
|
current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
|
||||||
|
do {
|
||||||
new_time_point.pack = current_time_point.pack;
|
new_time_point.pack = current_time_point.pack;
|
||||||
_mm_mfence();
|
_mm_mfence();
|
||||||
new_time_point.inner.last_measure = __rdtsc();
|
new_time_point.inner.last_measure = __rdtsc();
|
||||||
} while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack,
|
} while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack,
|
||||||
current_time_point.pack));
|
current_time_point.pack, current_time_point.pack));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue