(Vita/PS4) Publish read_pos after the device has taken the window

The worker advanced read_pos and released it before handing the same
window to sceAudioOutOutput, so the period the device was reading was
already the writer's to fill. A write landing in it while the call
was in flight put the writer's samples into audio being played.

The output call returns once the device has taken the window, which
is where the period becomes free: move the release store there, and
the notify with it. PSP1 does not have this - it outputs the window
after read_pos, which is still-unread data, and frees a window only
on the iteration after it played.
This commit is contained in:
LibretroAdmin authored and libretroadmin committed 2026-09-20 15:54:42 +02:00
1 parent 0127835abb
commit ba5339c419
2 files changed
+16 -12

No files matched your search

+8 -6
View File
@@ -124,21 +124,23 @@ static void ps4_audio_mainloop(void *data)
{
read_pos += AUDIO_OUT_COUNT;
read_pos &= AUDIO_BUFFER_SIZE_MASK;
/* Release: the period is free for the writer only after
* this store; the syscall below reads the old window, which
* the writer cannot touch until it sees the new index. */
retro_atomic_store_release_int(&ps4->read_pos, read_pos);
}
else
retro_atomic_fetch_add_size(&ps4->underruns, 1);
retro_eventcount_notify(&ps4->park);
sceAudioOutOutput(ps4->port,
ps4->buffer_u32
+ (cond ? AUDIO_SILENCE_OFFSET : read_pos_2));
retro_atomic_fetch_add_size(&ps4->consumed, AUDIO_OUT_COUNT);
/* Release only now: the call returns once the device has
* taken the window, so the period is the writer's from
* here and not before. */
if (!cond)
retro_atomic_store_release_int(&ps4->read_pos, read_pos);
retro_eventcount_notify(&ps4->park);
}
return;
+8 -6
View File
@@ -126,21 +126,23 @@ static void psp2_audio_mainloop(void *data)
{
read_pos += AUDIO_OUT_COUNT;
read_pos &= AUDIO_BUFFER_SIZE_MASK;
/* Release: the period is free for the writer only after
* this store; the syscall below reads the old window, which
* the writer cannot touch until it sees the new index. */
retro_atomic_store_release_int(&psp->read_pos, read_pos);
}
else
retro_atomic_fetch_add_size(&psp->underruns, 1);
retro_eventcount_notify(&psp->park);
sceAudioOutOutput(psp->port,
psp->buffer_u32
+ (cond ? AUDIO_SILENCE_OFFSET : read_pos_2));
retro_atomic_fetch_add_size(&psp->consumed, AUDIO_OUT_COUNT);
/* Release only now: the call returns once the device has
* taken the window, so the period is the writer's from
* here and not before. */
if (!cond)
retro_atomic_store_release_int(&psp->read_pos, read_pos);
retro_eventcount_notify(&psp->park);
}
return;