mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 22:05:38 +00:00
CDROM: Fix async readahead causing lockups in some games
This commit is contained in:
parent
ab9109f3b1
commit
c2c204c845
|
@ -101,9 +101,28 @@ void CDROMAsyncReader::QueueReadSector(CDImage::LBA lba)
|
||||||
|
|
||||||
bool CDROMAsyncReader::ReadSectorUncached(CDImage::LBA lba, CDImage::SubChannelQ* subq, SectorBuffer* data)
|
bool CDROMAsyncReader::ReadSectorUncached(CDImage::LBA lba, CDImage::SubChannelQ* subq, SectorBuffer* data)
|
||||||
{
|
{
|
||||||
if (IsUsingThread())
|
if (!IsUsingThread())
|
||||||
CancelReadahead();
|
return InternalReadSectorUncached(lba, subq, data);
|
||||||
|
|
||||||
|
std::unique_lock lock(m_mutex);
|
||||||
|
|
||||||
|
// wait until the read thread is idle
|
||||||
|
m_notify_read_complete_cv.wait(lock, [this]() { return !m_is_reading.load(); });
|
||||||
|
|
||||||
|
// read while the lock is held so it has to wait
|
||||||
|
const CDImage::LBA prev_lba = m_media->GetPositionOnDisc();
|
||||||
|
const bool result = InternalReadSectorUncached(lba, subq, data);
|
||||||
|
if (!m_media->Seek(prev_lba))
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("Failed to re-seek to cached position %u", prev_lba);
|
||||||
|
m_can_readahead.store(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROMAsyncReader::InternalReadSectorUncached(CDImage::LBA lba, CDImage::SubChannelQ* subq, SectorBuffer* data)
|
||||||
|
{
|
||||||
if (m_media->GetPositionOnDisc() != lba && !m_media->Seek(lba))
|
if (m_media->GetPositionOnDisc() != lba && !m_media->Seek(lba))
|
||||||
{
|
{
|
||||||
Log_WarningPrintf("Seek to LBA %u failed", lba);
|
Log_WarningPrintf("Seek to LBA %u failed", lba);
|
||||||
|
|
|
@ -52,6 +52,7 @@ private:
|
||||||
void EmptyBuffers();
|
void EmptyBuffers();
|
||||||
bool ReadSectorIntoBuffer(std::unique_lock<std::mutex>& lock);
|
bool ReadSectorIntoBuffer(std::unique_lock<std::mutex>& lock);
|
||||||
void ReadSectorNonThreaded(CDImage::LBA lba);
|
void ReadSectorNonThreaded(CDImage::LBA lba);
|
||||||
|
bool InternalReadSectorUncached(CDImage::LBA lba, CDImage::SubChannelQ* subq, SectorBuffer* data);
|
||||||
void CancelReadahead();
|
void CancelReadahead();
|
||||||
|
|
||||||
void WorkerThreadEntryPoint();
|
void WorkerThreadEntryPoint();
|
||||||
|
@ -67,12 +68,12 @@ private:
|
||||||
std::atomic_bool m_next_position_set{false};
|
std::atomic_bool m_next_position_set{false};
|
||||||
std::atomic_bool m_shutdown_flag{true};
|
std::atomic_bool m_shutdown_flag{true};
|
||||||
|
|
||||||
std::atomic_bool m_is_reading{ false };
|
std::atomic_bool m_is_reading{false};
|
||||||
std::atomic_bool m_can_readahead{ false };
|
std::atomic_bool m_can_readahead{false};
|
||||||
std::atomic_bool m_seek_error{ false };
|
std::atomic_bool m_seek_error{false};
|
||||||
|
|
||||||
std::vector<BufferSlot> m_buffers;
|
std::vector<BufferSlot> m_buffers;
|
||||||
std::atomic<u32> m_buffer_front{ 0 };
|
std::atomic<u32> m_buffer_front{0};
|
||||||
std::atomic<u32> m_buffer_back{ 0 };
|
std::atomic<u32> m_buffer_back{0};
|
||||||
std::atomic<u32> m_buffer_count{ 0 };
|
std::atomic<u32> m_buffer_count{0};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue