Abstract TextureView/BufferDelegate locking into LockableSharedPtr

An atomic transactional loop was performed on the backing `std::shared_ptr` inside `BufferView`/`TextureView`'s `lock`/`LockWithTag`/`try_lock` functions, these locks utilized `std::atomic_load` for atomically loading the value from the `shared_ptr` recursively till it was the same value pre/post-locking. 

This commit abstracts the locking functionality of `TextureView`/`BufferDelegate` into `LockableSharedPtr` to avoid code duplication and removes the usage of `std::atomic_load` in either case as it is not necessary due to the implicit memory barrier provided by locking a mutex.
This commit is contained in:
PixelyIon
2022-06-27 21:17:49 +05:30
parent 2d08886e4e
commit 217d484cba
6 changed files with 97 additions and 77 deletions

View File

@ -93,32 +93,15 @@ namespace skyline::gpu {
}
void TextureView::lock() {
auto backing{std::atomic_load(&texture)};
while (true) {
backing->lock();
auto latestBacking{std::atomic_load(&texture)};
if (backing == latestBacking)
return;
backing->unlock();
backing = latestBacking;
}
texture.Lock();
}
bool TextureView::LockWithTag(ContextTag tag) {
auto backing{std::atomic_load(&texture)};
while (true) {
bool didLock{backing->LockWithTag(tag)};
auto latestBacking{std::atomic_load(&texture)};
if (backing == latestBacking)
return didLock;
if (didLock)
backing->unlock();
backing = latestBacking;
}
bool result{};
texture.Lock([tag, &result](Texture* pTexture) {
result = pTexture->LockWithTag(tag);
});
return result;
}
void TextureView::unlock() {
@ -126,20 +109,7 @@ namespace skyline::gpu {
}
bool TextureView::try_lock() {
auto backing{std::atomic_load(&texture)};
while (true) {
bool success{backing->try_lock()};
auto latestBacking{std::atomic_load(&texture)};
if (backing == latestBacking)
// We want to ensure that the try_lock() was on the latest backing and not on an outdated one
return success;
if (success)
// We only unlock() if the try_lock() was successful and we acquired the mutex
backing->unlock();
backing = latestBacking;
}
return texture.TryLock();
}
void Texture::SetupGuestMappings() {