mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-15 19:28:43 +12:00
LV2: allocation-free synchronization syscalls
* Show waiters' ID in kernel explorer. * Remove deque dependency from sys_sync.h
This commit is contained in:
parent
c7fbc16357
commit
73aaff1b29
26 changed files with 547 additions and 275 deletions
|
@ -120,7 +120,7 @@ CellError lv2_event_queue::send(lv2_event event, bool notify_later)
|
|||
return CELL_ENOTCONN;
|
||||
}
|
||||
|
||||
if (sq.empty())
|
||||
if (!pq && !sq)
|
||||
{
|
||||
if (events.size() < this->size + 0u)
|
||||
{
|
||||
|
@ -135,7 +135,7 @@ CellError lv2_event_queue::send(lv2_event event, bool notify_later)
|
|||
if (type == SYS_PPU_QUEUE)
|
||||
{
|
||||
// Store event in registers
|
||||
auto& ppu = static_cast<ppu_thread&>(*schedule<ppu_thread>(sq, protocol));
|
||||
auto& ppu = static_cast<ppu_thread&>(*schedule<ppu_thread>(pq, protocol));
|
||||
|
||||
if (ppu.state & cpu_flag::again)
|
||||
{
|
||||
|
@ -241,11 +241,15 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
|
|||
|
||||
std::unique_lock<shared_mutex> qlock;
|
||||
|
||||
cpu_thread* head{};
|
||||
|
||||
const auto queue = idm::withdraw<lv2_obj, lv2_event_queue>(equeue_id, [&](lv2_event_queue& queue) -> CellError
|
||||
{
|
||||
qlock = std::unique_lock{queue.mutex};
|
||||
|
||||
if (!mode && !queue.sq.empty())
|
||||
head = queue.type == SYS_PPU_QUEUE ? static_cast<cpu_thread*>(+queue.pq) : +queue.sq;
|
||||
|
||||
if (!mode && head)
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
@ -258,13 +262,13 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
|
|||
|
||||
lv2_obj::on_id_destroy(queue, queue.key);
|
||||
|
||||
if (queue.sq.empty())
|
||||
if (!head)
|
||||
{
|
||||
qlock.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto cpu : queue.sq)
|
||||
for (auto cpu = head; cpu; cpu = cpu->get_next_cpu())
|
||||
{
|
||||
if (cpu->state & cpu_flag::again)
|
||||
{
|
||||
|
@ -296,15 +300,18 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
|
|||
|
||||
if (qlock.owns_lock())
|
||||
{
|
||||
std::deque<cpu_thread*> sq;
|
||||
|
||||
sq = std::move(queue->sq);
|
||||
|
||||
if (sys_event.warning)
|
||||
{
|
||||
fmt::append(lost_data, "Forcefully awaken waiters (%u):\n", sq.size());
|
||||
u32 size = 0;
|
||||
|
||||
for (auto cpu : sq)
|
||||
for (auto cpu = head; cpu; cpu = cpu->get_next_cpu())
|
||||
{
|
||||
size++;
|
||||
}
|
||||
|
||||
fmt::append(lost_data, "Forcefully awaken waiters (%u):\n", size);
|
||||
|
||||
for (auto cpu = head; cpu; cpu = cpu->get_next_cpu())
|
||||
{
|
||||
lost_data += cpu->get_name();
|
||||
lost_data += '\n';
|
||||
|
@ -313,21 +320,24 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
|
|||
|
||||
if (queue->type == SYS_PPU_QUEUE)
|
||||
{
|
||||
for (auto cpu : sq)
|
||||
for (auto cpu = +queue->pq; cpu; cpu = cpu->next_cpu)
|
||||
{
|
||||
static_cast<ppu_thread&>(*cpu).gpr[3] = CELL_ECANCELED;
|
||||
cpu->gpr[3] = CELL_ECANCELED;
|
||||
queue->append(cpu);
|
||||
}
|
||||
|
||||
atomic_storage<ppu_thread*>::release(queue->pq, nullptr);
|
||||
lv2_obj::awake_all();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto cpu : sq)
|
||||
for (auto cpu = +queue->sq; cpu; cpu = cpu->next_cpu)
|
||||
{
|
||||
static_cast<spu_thread&>(*cpu).ch_in_mbox.set_values(1, CELL_ECANCELED);
|
||||
resume_spu_thread_group_from_waiting(static_cast<spu_thread&>(*cpu));
|
||||
cpu->ch_in_mbox.set_values(1, CELL_ECANCELED);
|
||||
resume_spu_thread_group_from_waiting(*cpu);
|
||||
}
|
||||
|
||||
atomic_storage<spu_thread*>::release(queue->sq, nullptr);
|
||||
}
|
||||
|
||||
qlock.unlock();
|
||||
|
@ -382,7 +392,7 @@ error_code sys_event_queue_tryreceive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sy
|
|||
|
||||
s32 count = 0;
|
||||
|
||||
while (queue->sq.empty() && count < size && !queue->events.empty())
|
||||
while (count < size && !queue->events.empty())
|
||||
{
|
||||
auto& dest = event_array[count++];
|
||||
const auto event = queue->events.front();
|
||||
|
@ -425,8 +435,8 @@ error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_e
|
|||
|
||||
if (queue.events.empty())
|
||||
{
|
||||
queue.sq.emplace_back(&ppu);
|
||||
queue.sleep(ppu, timeout, true);
|
||||
lv2_obj::emplace(queue.pq, &ppu);
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
|
@ -464,13 +474,16 @@ error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_e
|
|||
{
|
||||
std::lock_guard lock_rsx(queue->mutex);
|
||||
|
||||
if (std::find(queue->sq.begin(), queue->sq.end(), &ppu) == queue->sq.end())
|
||||
for (auto cpu = +queue->pq; cpu; cpu = cpu->next_cpu)
|
||||
{
|
||||
break;
|
||||
if (cpu == &ppu)
|
||||
{
|
||||
ppu.state += cpu_flag::again;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
ppu.state += cpu_flag::again;
|
||||
return {};
|
||||
break;
|
||||
}
|
||||
|
||||
for (usz i = 0; cpu_flag::signal - ppu.state && i < 50; i++)
|
||||
|
@ -495,7 +508,7 @@ error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_e
|
|||
|
||||
std::lock_guard lock(queue->mutex);
|
||||
|
||||
if (!queue->unqueue(queue->sq, &ppu))
|
||||
if (!queue->unqueue(queue->pq, &ppu))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue