Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sys_event: Save ID of self event queue #10252

Merged
merged 4 commits into from
May 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 12 additions & 3 deletions rpcs3/Emu/Cell/lv2/sys_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@

LOG_CHANNEL(sys_event);

lv2_event_queue::lv2_event_queue(u32 protocol, s32 type, s32 size, u64 name, u64 ipc_key) noexcept
: id(idm::last_id())
, protocol{static_cast<u8>(protocol)}
, type(static_cast<u8>(type))
, size(static_cast<u8>(size))
, name(name)
, key(ipc_key)
{
}

std::shared_ptr<lv2_event_queue> lv2_event_queue::find(u64 ipc_key)
{
if (ipc_key == SYS_EVENT_QUEUE_LOCAL)
Expand Down Expand Up @@ -112,12 +122,12 @@ error_code sys_event_queue_create(cpu_thread& cpu, vm::ptr<u32> equeue_id, vm::p
}

const u32 pshared = ipc_key == SYS_EVENT_QUEUE_LOCAL ? SYS_SYNC_NOT_PROCESS_SHARED : SYS_SYNC_PROCESS_SHARED;
constexpr u32 flags = SYS_SYNC_NEWLY_CREATED; // NOTE: This is inaccurate for multi-process
constexpr u32 flags = SYS_SYNC_NEWLY_CREATED;
const u64 name = attr->name_u64;

if (const auto error = lv2_obj::create<lv2_event_queue>(pshared, ipc_key, flags, [&]()
{
return std::make_shared<lv2_event_queue>(protocol, type, name, ipc_key, size);
return std::make_shared<lv2_event_queue>(protocol, type, size, name, ipc_key);
}))
{
return error;
Expand Down Expand Up @@ -409,7 +419,6 @@ error_code sys_event_port_connect_local(cpu_thread& cpu, u32 eport_id, u32 equeu
}

port->queue = idm::get_unlocked<lv2_obj, lv2_event_queue>(equeue_id);
port->queue_id = equeue_id;

return CELL_OK;
}
Expand Down
15 changes: 4 additions & 11 deletions rpcs3/Emu/Cell/lv2/sys_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,24 +80,18 @@ struct lv2_event_queue final : public lv2_obj
{
static const u32 id_base = 0x8d000000;

const u32 id;
const lv2_protocol protocol;
const s32 type;
const u8 type;
const u8 size;
const u64 name;
const u64 key;
const s32 size;

shared_mutex mutex;
std::deque<lv2_event> events;
std::deque<cpu_thread*> sq;

lv2_event_queue(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size)
: protocol{protocol}
, type(type)
, name(name)
, key(ipc_key)
, size(size)
{
}
lv2_event_queue(u32 protocol, s32 type, s32 size, u64 name, u64 ipc_key) noexcept;

CellError send(lv2_event);

Expand All @@ -120,7 +114,6 @@ struct lv2_event_port final : lv2_obj

const s32 type; // Port type, either IPC or local
const u64 name; // Event source (generated from id and process id if not set)
u32 queue_id = 0; // Event queue ID (if IPC is used this value is meaningless)

std::shared_ptr<lv2_event_queue> queue; // Event queue this port is connected to

Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/lv2/sys_event_flag.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ struct lv2_event_flag final : lv2_obj
atomic_t<u64> pattern;
std::deque<cpu_thread*> sq;

lv2_event_flag(u32 protocol, u64 key, s32 type, u64 name, u64 pattern)
: protocol{protocol}
lv2_event_flag(u32 protocol, u64 key, s32 type, u64 name, u64 pattern) noexcept
: protocol{static_cast<u8>(protocol)}
, key(key)
, type(type)
, name(name)
Expand Down
13 changes: 13 additions & 0 deletions rpcs3/Emu/Cell/lv2/sys_interrupt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@

LOG_CHANNEL(sys_interrupt);

lv2_int_tag::lv2_int_tag() noexcept
: id(idm::last_id())
{
}

lv2_int_serv::lv2_int_serv(const std::shared_ptr<named_thread<ppu_thread>>& thread, u64 arg1, u64 arg2) noexcept
: id(idm::last_id())
, thread(thread)
, arg1(arg1)
, arg2(arg2)
{
}

void lv2_int_serv::exec() const
{
thread->cmd_list
Expand Down
11 changes: 5 additions & 6 deletions rpcs3/Emu/Cell/lv2/sys_interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,22 @@ struct lv2_int_tag final : lv2_obj
{
static const u32 id_base = 0x0a000000;

const u32 id;
std::weak_ptr<struct lv2_int_serv> handler;

lv2_int_tag() noexcept;
};

struct lv2_int_serv final : lv2_obj
{
static const u32 id_base = 0x0b000000;

const u32 id;
const std::shared_ptr<named_thread<ppu_thread>> thread;
const u64 arg1;
const u64 arg2;

lv2_int_serv(const std::shared_ptr<named_thread<ppu_thread>>& thread, u64 arg1, u64 arg2)
: thread(thread)
, arg1(arg1)
, arg2(arg2)
{
}
lv2_int_serv(const std::shared_ptr<named_thread<ppu_thread>>& thread, u64 arg1, u64 arg2) noexcept;

void exec() const;
void join() const;
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/lv2/sys_lwcond.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ struct lv2_lwcond final : lv2_obj
atomic_t<u32> waiters{0};
std::deque<cpu_thread*> sq;

lv2_lwcond(u64 name, u32 lwid, u32 protocol, vm::ptr<sys_lwcond_t> control)
lv2_lwcond(u64 name, u32 lwid, u32 protocol, vm::ptr<sys_lwcond_t> control) noexcept
: name(std::bit_cast<be_t<u64>>(name))
, lwid(lwid)
, protocol{protocol}
, protocol{static_cast<u8>(protocol)}
, control(control)
{
}
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/lv2/sys_lwmutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ struct lv2_lwmutex final : lv2_obj
std::deque<cpu_thread*> sq;
atomic_t<s32> lwcond_waiters{0};

lv2_lwmutex(u32 protocol, vm::ptr<sys_lwmutex_t> control, u64 name)
: protocol{protocol}
lv2_lwmutex(u32 protocol, vm::ptr<sys_lwmutex_t> control, u64 name) noexcept
: protocol{static_cast<u8>(protocol)}
, control(control)
, name(std::bit_cast<be_t<u64>>(name))
{
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/lv2/sys_mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ struct lv2_mutex final : lv2_obj
atomic_t<u32> lock_count{0}; // Recursive Locks
std::deque<cpu_thread*> sq;

lv2_mutex(u32 protocol, u32 recursive,u32 adaptive, u64 key, u64 name)
: protocol{protocol}
lv2_mutex(u32 protocol, u32 recursive,u32 adaptive, u64 key, u64 name) noexcept
: protocol{static_cast<u8>(protocol)}
, recursive(recursive)
, adaptive(adaptive)
, key(key)
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/lv2/sys_rwlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ struct lv2_rwlock final : lv2_obj
std::deque<cpu_thread*> rq;
std::deque<cpu_thread*> wq;

lv2_rwlock(u32 protocol, u64 key, u64 name)
: protocol{protocol}
lv2_rwlock(u32 protocol, u64 key, u64 name) noexcept
: protocol{static_cast<u8>(protocol)}
, key(key)
, name(name)
{
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/lv2/sys_semaphore.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ struct lv2_sema final : lv2_obj
atomic_t<s32> val;
std::deque<cpu_thread*> sq;

lv2_sema(u32 protocol, u64 key, u64 name, s32 max, s32 value)
: protocol{protocol}
lv2_sema(u32 protocol, u64 key, u64 name, s32 max, s32 value) noexcept
: protocol{static_cast<u8>(protocol)}
, key(key)
, name(name)
, max(max)
Expand Down
16 changes: 2 additions & 14 deletions rpcs3/Emu/Cell/lv2/sys_spu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1948,25 +1948,13 @@ error_code raw_spu_destroy(ppu_thread& ppu, u32 id)
// SLEEP
lv2_obj::sleep(ppu);
handler->join();
to_remove.emplace_back(std::move(handler), 0);
to_remove.emplace_back(std::move(handler), +handler->id);
}

to_remove.emplace_back(std::move(tag), 0);
to_remove.emplace_back(std::move(tag), +tag->id);
}
}

// Scan all kernel objects to determine IDs
idm::select<lv2_obj>([&](u32 id, lv2_obj& obj)
{
for (auto& pair : to_remove)
{
if (pair.first.get() == std::addressof(obj))
{
pair.second = id;
}
}
});

// Remove IDs
for (auto&& pair : to_remove)
{
Expand Down
6 changes: 3 additions & 3 deletions rpcs3/Emu/Cell/lv2/sys_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include <thread>

// attr_protocol (waiting scheduling policy)
enum lv2_protocol : u32
enum lv2_protocol : u8
{
SYS_SYNC_FIFO = 0x1, // First In, First Out Order
SYS_SYNC_PRIORITY = 0x2, // Priority Order
Expand Down Expand Up @@ -224,13 +224,13 @@ struct lv2_obj
default: return CELL_EINVAL;
}

std::shared_ptr<T> result = make();

// EAGAIN for IDM IDs shortage
CellError error = CELL_EAGAIN;

if (!idm::import<lv2_obj, T>([&]() -> std::shared_ptr<T>
{
std::shared_ptr<T> result = make();

auto finalize_construct = [&]() -> std::shared_ptr<T>
{
if ((error = result->on_id_create()))
Expand Down
26 changes: 16 additions & 10 deletions rpcs3/rpcs3qt/kernel_explorer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "Emu/Cell/lv2/sys_vm.h"
#include "Emu/Cell/lv2/sys_net.h"
#include "Emu/Cell/lv2/sys_fs.h"
#include "Emu/Cell/lv2/sys_interrupt.h"
#include "Emu/Cell/Modules/cellSpurs.h"

#include "Emu/RSX/RSXThread.h"
Expand Down Expand Up @@ -348,14 +349,22 @@ void kernel_explorer::Update()
}
case SYS_INTR_TAG_OBJECT:
{
// auto& tag = static_cast<lv2_int_tag&>(obj);
add_leaf(node, qstr(fmt::format("Intr Tag 0x%08x", id)));
auto& tag = static_cast<lv2_int_tag&>(obj);
auto handler = tag.handler.lock();

if (handler && handler.get() == idm::check_unlocked<lv2_obj, lv2_int_serv>(handler->id))
{
add_leaf(node, qstr(fmt::format("Intr Tag 0x%08x, Handler: 0x%08x", id, handler->id)));
break;
}

add_leaf(node, qstr(fmt::format("Intr Tag 0x%08x, Handler: Unbound", id)));
break;
}
case SYS_INTR_SERVICE_HANDLE_OBJECT:
{
// auto& serv = static_cast<lv2_int_serv&>(obj);
add_leaf(node, qstr(fmt::format("Intr Svc 0x%08x", id)));
auto& serv = static_cast<lv2_int_serv&>(obj);
add_leaf(node, qstr(fmt::format("Intr Svc 0x%08x, PPU: 0x%07x, arg1: 0x%x, arg2: 0x%x", id, serv.thread->id, serv.arg1, serv.arg2)));
break;
}
case SYS_EVENT_QUEUE_OBJECT:
Expand All @@ -372,18 +381,15 @@ void kernel_explorer::Update()

if (const auto queue = ep.queue.get(); queue && queue->exists)
{
if (queue == idm::check_unlocked<lv2_obj, lv2_event_queue>(ep.queue_id))
if (queue == idm::check_unlocked<lv2_obj, lv2_event_queue>(queue->id))
{
// Type must be LOCAL here, but refer to the note below for why it is showed
add_leaf(node, qstr(fmt::format("Event Port 0x%08x: %s, Name: %#llx, Event Queue (ID): 0x%08x", id, type, ep.name, ep.queue_id)));
add_leaf(node, qstr(fmt::format("Event Port 0x%08x: %s, Name: %#llx, Event Queue (ID): 0x%08x", id, type, ep.name, queue->id)));
break;
}

// This code is unused until multi-process is implemented
if (queue == lv2_event_queue::find(queue->key).get())
{
// There are cases in which the attached queue by ID also has an IPC
// And the ID was destroyed but another was created for that same IPC
// So show event port type as well here because it not guaranteed to be IPC
add_leaf(node, qstr(fmt::format("Event Port 0x%08x: %s, Name: %#llx, Event Queue (IPC): %s", id, type, ep.name, queue->key)));
break;
}
Expand Down