2018-09-25 22:34:45 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "vm.h"
|
|
|
|
|
#include "Utilities/cond.h"
|
2019-07-27 00:34:10 +02:00
|
|
|
#include "util/atomic.hpp"
|
2018-09-29 00:12:00 +02:00
|
|
|
|
2018-09-25 22:34:45 +02:00
|
|
|
namespace vm
|
|
|
|
|
{
|
|
|
|
|
// Get reservation status for further atomic update: last update timestamp
|
|
|
|
|
inline atomic_t<u64>& reservation_acquire(u32 addr, u32 size)
|
|
|
|
|
{
|
|
|
|
|
// Access reservation info: stamp and the lock bit
|
|
|
|
|
return reinterpret_cast<atomic_t<u64>*>(g_reservations)[addr / 128];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update reservation status
|
|
|
|
|
inline void reservation_update(u32 addr, u32 size, bool lsb = false)
|
|
|
|
|
{
|
|
|
|
|
// Update reservation info with new timestamp
|
|
|
|
|
reservation_acquire(addr, size) += 128;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get reservation sync variable
|
2019-09-19 01:57:08 +02:00
|
|
|
inline atomic_t<u64>& reservation_notifier(u32 addr, u32 size)
|
2018-09-25 22:34:45 +02:00
|
|
|
{
|
2019-09-19 01:57:08 +02:00
|
|
|
return reinterpret_cast<atomic_t<u64>*>(g_reservations)[addr / 128];
|
2018-09-25 22:34:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void reservation_lock_internal(atomic_t<u64>&);
|
|
|
|
|
|
|
|
|
|
inline atomic_t<u64>& reservation_lock(u32 addr, u32 size)
|
|
|
|
|
{
|
|
|
|
|
auto& res = vm::reservation_acquire(addr, size);
|
|
|
|
|
|
2020-02-05 08:00:08 +01:00
|
|
|
if (res.bts(0)) [[unlikely]]
|
2018-09-25 22:34:45 +02:00
|
|
|
{
|
|
|
|
|
reservation_lock_internal(res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace vm
|