mirror of
https://github.com/Takiiiiiiii/strato.git
synced 2025-07-17 08:46:39 +00:00
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:
@ -275,32 +275,15 @@ namespace skyline::gpu {
|
||||
}
|
||||
|
||||
void Buffer::BufferDelegate::lock() {
|
||||
auto lBuffer{std::atomic_load(&buffer)};
|
||||
while (true) {
|
||||
lBuffer->lock();
|
||||
|
||||
auto latestBacking{std::atomic_load(&buffer)};
|
||||
if (lBuffer == latestBacking)
|
||||
return;
|
||||
|
||||
lBuffer->unlock();
|
||||
lBuffer = latestBacking;
|
||||
}
|
||||
buffer.Lock();
|
||||
}
|
||||
|
||||
bool Buffer::BufferDelegate::LockWithTag(ContextTag pTag) {
|
||||
auto lBuffer{std::atomic_load(&buffer)};
|
||||
while (true) {
|
||||
bool didLock{lBuffer->LockWithTag(pTag)};
|
||||
|
||||
auto latestBacking{std::atomic_load(&buffer)};
|
||||
if (lBuffer == latestBacking)
|
||||
return didLock;
|
||||
|
||||
if (didLock)
|
||||
lBuffer->unlock();
|
||||
lBuffer = latestBacking;
|
||||
}
|
||||
bool result{};
|
||||
buffer.Lock([pTag, &result](Buffer* pBuffer) {
|
||||
result = pBuffer->LockWithTag(pTag);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
void Buffer::BufferDelegate::unlock() {
|
||||
@ -308,20 +291,7 @@ namespace skyline::gpu {
|
||||
}
|
||||
|
||||
bool Buffer::BufferDelegate::try_lock() {
|
||||
auto lBuffer{std::atomic_load(&buffer)};
|
||||
while (true) {
|
||||
bool success{lBuffer->try_lock()};
|
||||
|
||||
auto latestBuffer{std::atomic_load(&buffer)};
|
||||
if (lBuffer == latestBuffer)
|
||||
// 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
|
||||
lBuffer->unlock();
|
||||
lBuffer = latestBuffer;
|
||||
}
|
||||
return buffer.TryLock();
|
||||
}
|
||||
|
||||
BufferView::BufferView(std::shared_ptr<Buffer> buffer, const Buffer::BufferViewStorage *view) : bufferDelegate(std::make_shared<Buffer::BufferDelegate>(std::move(buffer), view)) {}
|
||||
|
Reference in New Issue
Block a user