mirror of https://github.com/RPCS3/rpcs3.git
sys_event: Fix PPU queue forced uproot of waiters (#11147)
This commit is contained in:
parent
05881ffa62
commit
48ad959697
|
@ -133,6 +133,8 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<lv2_event> events;
|
||||||
|
|
||||||
const auto queue = idm::withdraw<lv2_obj, lv2_event_queue>(equeue_id, [&](lv2_event_queue& queue) -> CellError
|
const auto queue = idm::withdraw<lv2_obj, lv2_event_queue>(equeue_id, [&](lv2_event_queue& queue) -> CellError
|
||||||
{
|
{
|
||||||
std::lock_guard lock(queue.mutex);
|
std::lock_guard lock(queue.mutex);
|
||||||
|
@ -142,6 +144,18 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
|
||||||
return CELL_EBUSY;
|
return CELL_EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (queue.sq.empty())
|
||||||
|
{
|
||||||
|
// Optimization
|
||||||
|
mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!queue.events.empty())
|
||||||
|
{
|
||||||
|
// Copy events for logging, does not empty
|
||||||
|
events.insert(events.begin(), queue.events.begin(), queue.events.end());
|
||||||
|
}
|
||||||
|
|
||||||
lv2_obj::on_id_destroy(queue, queue.key);
|
lv2_obj::on_id_destroy(queue, queue.key);
|
||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
|
@ -156,6 +170,8 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
|
||||||
return queue.ret;
|
return queue.ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string lost_data;
|
||||||
|
|
||||||
if (mode == SYS_EVENT_QUEUE_DESTROY_FORCE)
|
if (mode == SYS_EVENT_QUEUE_DESTROY_FORCE)
|
||||||
{
|
{
|
||||||
std::deque<cpu_thread*> sq;
|
std::deque<cpu_thread*> sq;
|
||||||
|
@ -163,7 +179,18 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
|
||||||
std::lock_guard lock(queue->mutex);
|
std::lock_guard lock(queue->mutex);
|
||||||
|
|
||||||
sq = std::move(queue->sq);
|
sq = std::move(queue->sq);
|
||||||
|
|
||||||
|
if (sys_event.warning)
|
||||||
|
{
|
||||||
|
fmt::append(lost_data, "Forcefully awaken waiters (%u):\n", sq.size());
|
||||||
|
|
||||||
|
for (auto cpu : sq)
|
||||||
|
{
|
||||||
|
lost_data += cpu->get_name();
|
||||||
|
lost_data += '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (queue->type == SYS_PPU_QUEUE)
|
if (queue->type == SYS_PPU_QUEUE)
|
||||||
{
|
{
|
||||||
for (auto cpu : sq)
|
for (auto cpu : sq)
|
||||||
|
@ -172,10 +199,7 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
|
||||||
queue->append(cpu);
|
queue->append(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!queue->sq.empty())
|
lv2_obj::awake_all();
|
||||||
{
|
|
||||||
lv2_obj::awake_all();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -187,6 +211,25 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sys_event.warning)
|
||||||
|
{
|
||||||
|
if (!events.empty())
|
||||||
|
{
|
||||||
|
fmt::append(lost_data, "Unread queue events (%u):\n", events.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const lv2_event& evt : events)
|
||||||
|
{
|
||||||
|
fmt::append(lost_data, "data0=0x%x, data1=0x%x, data2=0x%x, data3=0x%x\n"
|
||||||
|
, std::get<0>(evt), std::get<1>(evt), std::get<2>(evt), std::get<3>(evt));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lost_data.empty())
|
||||||
|
{
|
||||||
|
sys_event.warning("sys_event_queue_destroy(): %s", lost_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,6 +253,11 @@ error_code sys_event_queue_tryreceive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sy
|
||||||
|
|
||||||
std::lock_guard lock(queue->mutex);
|
std::lock_guard lock(queue->mutex);
|
||||||
|
|
||||||
|
if (!queue->exists)
|
||||||
|
{
|
||||||
|
return CELL_ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
s32 count = 0;
|
s32 count = 0;
|
||||||
|
|
||||||
while (queue->sq.empty() && count < size && !queue->events.empty())
|
while (queue->sq.empty() && count < size && !queue->events.empty())
|
||||||
|
|
|
@ -49,6 +49,8 @@ namespace logs
|
||||||
return reinterpret_cast<const channel*>(reinterpret_cast<uptr>(this) & -16);
|
return reinterpret_cast<const channel*>(reinterpret_cast<uptr>(this) & -16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline explicit operator bool() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Send log message to global logger instance
|
// Send log message to global logger instance
|
||||||
void broadcast(const char*, const fmt_type_info*, ...) const;
|
void broadcast(const char*, const fmt_type_info*, ...) const;
|
||||||
|
@ -122,10 +124,16 @@ namespace logs
|
||||||
#undef GEN_LOG_METHOD
|
#undef GEN_LOG_METHOD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline logs::message::operator bool() const
|
||||||
|
{
|
||||||
|
// Test if enabled
|
||||||
|
return *this <= (*this)->enabled.observe();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
FORCE_INLINE SAFE_BUFFERS(void) message::operator()(const const_str& fmt, const Args&... args) const
|
FORCE_INLINE SAFE_BUFFERS(void) message::operator()(const const_str& fmt, const Args&... args) const
|
||||||
{
|
{
|
||||||
if (*this <= (*this)->enabled.observe()) [[unlikely]]
|
if (operator bool()) [[unlikely]]
|
||||||
{
|
{
|
||||||
if constexpr (sizeof...(Args) > 0)
|
if constexpr (sizeof...(Args) > 0)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue