LV2: Fixup for IPC

* Fix typo in lv2_obj::create.
* Always save ipc_key as 0 for non-shared object creations, regardless of thbe value set by creation attribute.
* Show IPC key of shared memory (sys_mmapper) memory objects in kernel explorer.
This commit is contained in:
Eladash 2021-05-07 13:08:16 +03:00 committed by Ivan
parent 900ebf6583
commit 64997662d2
15 changed files with 63 additions and 42 deletions

View file

@ -24,11 +24,12 @@ error_code sys_cond_create(ppu_thread& ppu, vm::ptr<u32> cond_id, u32 mutex_id,
const auto _attr = *attr;
if (const auto error = lv2_obj::create<lv2_cond>(_attr.pshared, _attr.ipc_key, _attr.flags, [&]
const u64 ipc_key = lv2_obj::get_key(_attr);
if (const auto error = lv2_obj::create<lv2_cond>(_attr.pshared, ipc_key, _attr.flags, [&]
{
return std::make_shared<lv2_cond>(
_attr.pshared,
_attr.ipc_key,
ipc_key,
_attr.name_u64,
mutex_id,
std::move(mutex));
@ -57,7 +58,7 @@ error_code sys_cond_destroy(ppu_thread& ppu, u32 cond_id)
}
cond.mutex->cond_count--;
lv2_obj::on_id_destroy(cond, cond.shared, cond.key);
lv2_obj::on_id_destroy(cond, cond.key);
return {};
});

View file

@ -22,7 +22,6 @@ struct lv2_cond final : lv2_obj
{
static const u32 id_base = 0x86000000;
const u32 shared;
const u64 key;
const u64 name;
const u32 mtx_id;
@ -31,9 +30,8 @@ struct lv2_cond final : lv2_obj
atomic_t<u32> waiters{0};
std::deque<cpu_thread*> sq;
lv2_cond(u32 shared, u64 key, u64 name, u32 mtx_id, std::shared_ptr<lv2_mutex> mutex)
: shared(shared)
, key(key)
lv2_cond(u64 key, u64 name, u32 mtx_id, std::shared_ptr<lv2_mutex> mutex)
: key(key)
, name(name)
, mtx_id(mtx_id)
, mutex(std::move(mutex))

View file

@ -147,7 +147,7 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
return CELL_EBUSY;
}
lv2_obj::on_id_destroy(queue, queue.key == SYS_EVENT_QUEUE_LOCAL ? SYS_SYNC_NOT_PROCESS_SHARED : SYS_SYNC_PROCESS_SHARED, queue.key);
lv2_obj::on_id_destroy(queue, queue.key);
return {};
});

View file

@ -40,12 +40,13 @@ error_code sys_event_flag_create(ppu_thread& ppu, vm::ptr<u32> id, vm::ptr<sys_e
return CELL_EINVAL;
}
if (const auto error = lv2_obj::create<lv2_event_flag>(_attr.pshared, _attr.ipc_key, _attr.flags, [&]
const u64 ipc_key = lv2_obj::get_key(_attr);
if (const auto error = lv2_obj::create<lv2_event_flag>(_attr.pshared, ipc_key, _attr.flags, [&]
{
return std::make_shared<lv2_event_flag>(
_attr.protocol,
_attr.pshared,
_attr.ipc_key,
ipc_key,
_attr.type,
_attr.name_u64,
init);
@ -71,7 +72,7 @@ error_code sys_event_flag_destroy(ppu_thread& ppu, u32 id)
return CELL_EBUSY;
}
lv2_obj::on_id_destroy(flag, flag.shared, flag.key);
lv2_obj::on_id_destroy(flag, flag.key);
return {};
});

View file

@ -36,7 +36,6 @@ struct lv2_event_flag final : lv2_obj
static const u32 id_base = 0x98000000;
const lv2_protocol protocol;
const u32 shared;
const u64 key;
const s32 type;
const u64 name;
@ -46,9 +45,8 @@ struct lv2_event_flag final : lv2_obj
atomic_t<u64> pattern;
std::deque<cpu_thread*> sq;
lv2_event_flag(u32 protocol, u32 shared, u64 key, s32 type, u64 name, u64 pattern)
lv2_event_flag(u32 protocol, u64 key, s32 type, u64 name, u64 pattern)
: protocol{protocol}
, shared(shared)
, key(key)
, type(type)
, name(name)

View file

@ -12,7 +12,7 @@
LOG_CHANNEL(sys_mmapper);
lv2_memory::lv2_memory(u32 size, u32 align, u64 flags, u64 key, u32 pshared, lv2_memory_container* ct)
lv2_memory::lv2_memory(u32 size, u32 align, u64 flags, u64 key, bool pshared, lv2_memory_container* ct)
: size(size)
, align(align)
, flags(flags)
@ -31,6 +31,12 @@ template <bool exclusive = false>
error_code create_lv2_shm(bool pshared, u64 ipc_key, u64 size, u32 align, u64 flags, lv2_memory_container* ct)
{
const u32 _pshared = pshared ? SYS_SYNC_PROCESS_SHARED : SYS_SYNC_NOT_PROCESS_SHARED;
if (!pshared)
{
ipc_key = 0;
}
if (auto error = lv2_obj::create<lv2_memory>(_pshared, ipc_key, exclusive ? SYS_SYNC_NEWLY_CREATED : SYS_SYNC_NOT_CARE, [&]()
{
return std::make_shared<lv2_memory>(
@ -38,7 +44,7 @@ error_code create_lv2_shm(bool pshared, u64 ipc_key, u64 size, u32 align, u64 fl
align,
flags,
ipc_key,
_pshared,
pshared,
ct);
}, false))
{
@ -528,7 +534,7 @@ error_code sys_mmapper_free_shared_memory(ppu_thread& ppu, u32 mem_id)
return CELL_EBUSY;
}
lv2_obj::on_id_destroy(mem, mem.pshared, mem.key);
lv2_obj::on_id_destroy(mem, mem.key, +mem.pshared);
return {};
});

View file

@ -22,13 +22,13 @@ struct lv2_memory : lv2_obj
const u32 align; // Alignment required
const u64 flags;
const u64 key; // IPC key
const u32 pshared;
const bool pshared; // Process shared flag
lv2_memory_container* const ct; // Associated memory container
const std::shared_ptr<utils::shm> shm;
atomic_t<u32> counter{0};
lv2_memory(u32 size, u32 align, u64 flags, u64 key, u32 pshared, lv2_memory_container* ct);
lv2_memory(u32 size, u32 align, u64 flags, u64 key, bool pshared, lv2_memory_container* ct);
};
enum : u64

View file

@ -57,7 +57,6 @@ error_code sys_mutex_create(ppu_thread& ppu, vm::ptr<u32> mutex_id, vm::ptr<sys_
return std::make_shared<lv2_mutex>(
_attr.protocol,
_attr.recursive,
_attr.pshared,
_attr.adaptive,
_attr.ipc_key,
_attr.name_u64);
@ -90,7 +89,7 @@ error_code sys_mutex_destroy(ppu_thread& ppu, u32 mutex_id)
return CELL_EPERM;
}
lv2_obj::on_id_destroy(mutex, mutex.shared, mutex.key);
lv2_obj::on_id_destroy(mutex, mutex.key);
return {};
});

View file

@ -27,7 +27,6 @@ struct lv2_mutex final : lv2_obj
const lv2_protocol protocol;
const u32 recursive;
const u32 shared;
const u32 adaptive;
const u64 key;
const u64 name;
@ -38,10 +37,9 @@ 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 shared, u32 adaptive, u64 key, u64 name)
lv2_mutex(u32 protocol, u32 recursive,u32 adaptive, u64 key, u64 name)
: protocol{protocol}
, recursive(recursive)
, shared(shared)
, adaptive(adaptive)
, key(key)
, name(name)

View file

@ -30,9 +30,11 @@ error_code sys_rwlock_create(ppu_thread& ppu, vm::ptr<u32> rw_lock_id, vm::ptr<s
return CELL_EINVAL;
}
if (auto error = lv2_obj::create<lv2_rwlock>(_attr.pshared, _attr.ipc_key, _attr.flags, [&]
const u64 ipc_key = lv2_obj::get_key(_attr);
if (auto error = lv2_obj::create<lv2_rwlock>(_attr.pshared, ipc_key, _attr.flags, [&]
{
return std::make_shared<lv2_rwlock>(protocol, _attr.pshared, _attr.ipc_key, _attr.name_u64);
return std::make_shared<lv2_rwlock>(protocol, ipc_key, _attr.name_u64);
}))
{
return error;
@ -55,7 +57,7 @@ error_code sys_rwlock_destroy(ppu_thread& ppu, u32 rw_lock_id)
return CELL_EBUSY;
}
lv2_obj::on_id_destroy(rw, rw.shared, rw.key);
lv2_obj::on_id_destroy(rw, rw.key);
return {};
});

View file

@ -24,7 +24,6 @@ struct lv2_rwlock final : lv2_obj
static const u32 id_base = 0x88000000;
const lv2_protocol protocol;
const u32 shared;
const u64 key;
const u64 name;
@ -33,9 +32,8 @@ struct lv2_rwlock final : lv2_obj
std::deque<cpu_thread*> rq;
std::deque<cpu_thread*> wq;
lv2_rwlock(u32 protocol, u32 shared, u64 key, u64 name)
lv2_rwlock(u32 protocol, u64 key, u64 name)
: protocol{protocol}
, shared(shared)
, key(key)
, name(name)
{

View file

@ -36,9 +36,11 @@ error_code sys_semaphore_create(ppu_thread& ppu, vm::ptr<u32> sem_id, vm::ptr<sy
return CELL_EINVAL;
}
if (auto error = lv2_obj::create<lv2_sema>(_attr.pshared, _attr.ipc_key, _attr.flags, [&]
const u64 ipc_key = lv2_obj::get_key(_attr);
if (auto error = lv2_obj::create<lv2_sema>(_attr.pshared, ipc_key, _attr.flags, [&]
{
return std::make_shared<lv2_sema>(protocol, _attr.pshared, _attr.ipc_key, _attr.name_u64, max_val, initial_val);
return std::make_shared<lv2_sema>(protocol, ipc_key, _attr.name_u64, max_val, initial_val);
}))
{
return error;
@ -66,7 +68,7 @@ error_code sys_semaphore_destroy(ppu_thread& ppu, u32 sem_id)
return CELL_EBUSY;
}
lv2_obj::on_id_destroy(sema, sema.shared, sema.key);
lv2_obj::on_id_destroy(sema, sema.key);
return {};
});

View file

@ -24,7 +24,6 @@ struct lv2_sema final : lv2_obj
static const u32 id_base = 0x96000000;
const lv2_protocol protocol;
const u32 shared;
const u64 key;
const u64 name;
const s32 max;
@ -33,9 +32,8 @@ struct lv2_sema final : lv2_obj
atomic_t<s32> val;
std::deque<cpu_thread*> sq;
lv2_sema(u32 protocol, u32 shared, u64 key, u64 name, s32 max, s32 value)
lv2_sema(u32 protocol, u64 key, u64 name, s32 max, s32 value)
: protocol{protocol}
, shared(shared)
, key(key)
, name(name)
, max(max)

View file

@ -186,6 +186,12 @@ public:
static void cleanup();
template <typename T>
static inline u64 get_key(const T& attr)
{
return (attr.pshared != SYS_SYNC_PROCESS_SHARED ? +attr.ipc_key : 0);
}
template <typename T, typename F>
static error_code create(u32 pshared, u64 ipc_key, s32 flags, F&& make, bool key_not_zero = true)
{
@ -235,7 +241,7 @@ public:
return std::move(result);
};
if (flags != SYS_SYNC_PROCESS_SHARED)
if (pshared != SYS_SYNC_PROCESS_SHARED)
{
// Creation of unique (non-shared) object handle
return finalize_construct();
@ -286,9 +292,15 @@ public:
}
template <typename T>
static void on_id_destroy(T& obj, u32 pshared, u64 ipc_key)
static void on_id_destroy(T& obj, u64 ipc_key, u64 pshared = -1)
{
if (obj.exists-- == 1u && pshared == SYS_SYNC_PROCESS_SHARED)
if (pshared == umax)
{
// Default is to check key
pshared = ipc_key != 0;
}
if (obj.exists-- == 1u && pshared)
{
g_fxo->get<ipc_manager<T, u64>>().remove(ipc_key);
}

View file

@ -314,7 +314,15 @@ void kernel_explorer::Update()
case SYS_MEM_OBJECT:
{
auto& mem = static_cast<lv2_memory&>(obj);
add_leaf(node, qstr(fmt::format("Shared Mem 0x%08x: Size: 0x%x (%0.2f MB), Granularity: %s, Mappings: %u", id, mem.size, mem.size * 1. / (1024 * 1024), mem.align == 0x10000u ? "64K" : "1MB", +mem.counter)));
const f64 size_mb = mem.size * 1. / (1024 * 1024);
if (mem.pshared)
{
add_leaf(node, qstr(fmt::format("Shared Mem 0x%08x: Size: 0x%x (%0.2f MB), Granularity: %s, Mappings: %u Key: %#llx", id, mem.size, size_mb, mem.align == 0x10000u ? "64K" : "1MB", +mem.counter, mem.key)));
break;
}
add_leaf(node, qstr(fmt::format("Shared Mem 0x%08x: Size: 0x%x (%0.2f MB), Granularity: %s, Mappings: %u", id, mem.size, size_mb, mem.align == 0x10000u ? "64K" : "1MB", +mem.counter)));
break;
}
case SYS_MUTEX_OBJECT: