mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-14 10:48:36 +12:00
idm::check extended
idm::check_unlocked idm::find_unlocked idm::get_unlocked
This commit is contained in:
parent
a809f33418
commit
0674a58502
4 changed files with 72 additions and 37 deletions
|
@ -102,9 +102,9 @@ error_code sys_memory_allocate_from_container(u32 size, u32 cid, u64 flags, vm::
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ct.value)
|
if (ct.ret)
|
||||||
{
|
{
|
||||||
return ct.value;
|
return ct.ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate memory, write back the start address of the allocated area, use cid as the supplementary info
|
// Allocate memory, write back the start address of the allocated area, use cid as the supplementary info
|
||||||
|
@ -219,9 +219,9 @@ error_code sys_memory_container_destroy(u32 cid)
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ct.value)
|
if (ct.ret)
|
||||||
{
|
{
|
||||||
return ct.value;
|
return ct.ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return "physical memory" to the default container
|
// Return "physical memory" to the default container
|
||||||
|
|
|
@ -157,9 +157,9 @@ error_code sys_mmapper_allocate_shared_memory_from_container(u64 unk, u32 size,
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ct.value)
|
if (ct.ret)
|
||||||
{
|
{
|
||||||
return ct.value;
|
return ct.ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a new mem ID
|
// Generate a new mem ID
|
||||||
|
@ -215,9 +215,9 @@ error_code sys_mmapper_free_shared_memory(u32 mem_id)
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mem.value)
|
if (mem.ret)
|
||||||
{
|
{
|
||||||
return mem.value;
|
return mem.ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return "physical memory" to the memory container
|
// Return "physical memory" to the memory container
|
||||||
|
|
|
@ -70,9 +70,9 @@ error_code sys_semaphore_destroy(u32 sem_id)
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sem.value)
|
if (sem.ret)
|
||||||
{
|
{
|
||||||
return sem.value;
|
return sem.ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
@ -112,7 +112,7 @@ error_code sys_semaphore_wait(ppu_thread& ppu, u32 sem_id, u64 timeout)
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sem.value)
|
if (sem.ret)
|
||||||
{
|
{
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ error_code sys_semaphore_trywait(u32 sem_id)
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sem.value)
|
if (!sem.ret)
|
||||||
{
|
{
|
||||||
return not_an_error(CELL_EBUSY);
|
return not_an_error(CELL_EBUSY);
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ error_code sys_semaphore_post(u32 sem_id, s32 count)
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sem.value)
|
if (sem.ret)
|
||||||
{
|
{
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,33 +227,39 @@ class idm
|
||||||
using void_type = void;
|
using void_type = void;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper
|
// Helper type: pointer + return value propagated
|
||||||
template <typename T, typename RT>
|
template <typename T, typename RT>
|
||||||
struct return_pair
|
struct return_pair
|
||||||
{
|
{
|
||||||
std::shared_ptr<T> ptr;
|
std::shared_ptr<T> ptr;
|
||||||
RT value;
|
RT ret;
|
||||||
|
|
||||||
explicit operator bool() const
|
explicit operator bool() const
|
||||||
{
|
{
|
||||||
return ptr.operator bool();
|
return ptr.operator bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator->() const
|
T* operator->() const
|
||||||
{
|
{
|
||||||
return ptr.get();
|
return ptr.get();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename RT>
|
// Unsafe specialization (not refcounted)
|
||||||
struct return_pair<bool, RT>
|
template <typename T, typename RT>
|
||||||
|
struct return_pair<T*, RT>
|
||||||
{
|
{
|
||||||
bool result;
|
T* ptr;
|
||||||
RT value;
|
RT ret;
|
||||||
|
|
||||||
explicit operator bool() const
|
explicit operator bool() const
|
||||||
{
|
{
|
||||||
return result;
|
return ptr != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* operator->() const
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -382,46 +388,75 @@ public:
|
||||||
return id_manager::id_traits<Made>::invalid;
|
return id_manager::id_traits<Made>::invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Access the ID record without locking (unsafe)
|
||||||
|
template <typename T, typename Get = T>
|
||||||
|
static inline id_manager::id_map::pointer find_unlocked(u32 id)
|
||||||
|
{
|
||||||
|
return find_id<T, Get>(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the ID without locking (can be called from other method)
|
||||||
|
template <typename T, typename Get = T>
|
||||||
|
static inline Get* check_unlocked(u32 id)
|
||||||
|
{
|
||||||
|
if (const auto found = find_id<T, Get>(id))
|
||||||
|
{
|
||||||
|
return static_cast<Get*>(found->second.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Check the ID
|
// Check the ID
|
||||||
template <typename T, typename Get = T>
|
template <typename T, typename Get = T>
|
||||||
static inline explicit_bool_t check(u32 id)
|
static inline Get* check(u32 id)
|
||||||
{
|
{
|
||||||
reader_lock lock(id_manager::g_mutex);
|
reader_lock lock(id_manager::g_mutex);
|
||||||
|
|
||||||
return find_id<T, Get>(id) != nullptr;
|
return check_unlocked<T, Get>(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the ID, access object under shared lock
|
// Check the ID, access object under shared lock
|
||||||
template <typename T, typename Get = T, typename F, typename FRT = std::result_of_t<F(Get&)>, typename = std::enable_if_t<std::is_void<FRT>::value>>
|
template <typename T, typename Get = T, typename F, typename FRT = std::result_of_t<F(Get&)>, typename = std::enable_if_t<std::is_void<FRT>::value>>
|
||||||
static inline explicit_bool_t check(u32 id, F&& func, int = 0)
|
static inline Get* check(u32 id, F&& func, int = 0)
|
||||||
{
|
{
|
||||||
reader_lock lock(id_manager::g_mutex);
|
reader_lock lock(id_manager::g_mutex);
|
||||||
|
|
||||||
const auto found = find_id<T, Get>(id);
|
if (const auto ptr = check_unlocked<T, Get>(id))
|
||||||
|
|
||||||
if (UNLIKELY(found == nullptr))
|
|
||||||
{
|
{
|
||||||
return false;
|
func(*ptr);
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
func(*static_cast<Get*>(found->second.get()));
|
return nullptr;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the ID, access object under reader lock, propagate return value
|
// Check the ID, access object under reader lock, propagate return value
|
||||||
template <typename T, typename Get = T, typename F, typename FRT = std::result_of_t<F(Get&)>, typename = std::enable_if_t<!std::is_void<FRT>::value>>
|
template <typename T, typename Get = T, typename F, typename FRT = std::result_of_t<F(Get&)>, typename = std::enable_if_t<!std::is_void<FRT>::value>>
|
||||||
static inline return_pair<bool, FRT> check(u32 id, F&& func)
|
static inline return_pair<Get*, FRT> check(u32 id, F&& func)
|
||||||
{
|
{
|
||||||
reader_lock lock(id_manager::g_mutex);
|
reader_lock lock(id_manager::g_mutex);
|
||||||
|
|
||||||
|
if (const auto ptr = check_unlocked<T, Get>(id))
|
||||||
|
{
|
||||||
|
return {ptr, func(*ptr)};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {nullptr};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the object without locking (can be called from other method)
|
||||||
|
template <typename T, typename Get = T>
|
||||||
|
static inline std::shared_ptr<Get> get_unlocked(u32 id)
|
||||||
|
{
|
||||||
const auto found = find_id<T, Get>(id);
|
const auto found = find_id<T, Get>(id);
|
||||||
|
|
||||||
if (UNLIKELY(found == nullptr))
|
if (UNLIKELY(found == nullptr))
|
||||||
{
|
{
|
||||||
return {false};
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {true, func(*static_cast<Get*>(found->second.get()))};
|
return {found->second, static_cast<Get*>(found->second.get())};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the object
|
// Get the object
|
||||||
|
@ -807,12 +842,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the object exists
|
// Check whether the object exists
|
||||||
template <typename T, typename Get = T>
|
template <typename T>
|
||||||
static inline explicit_bool_t check()
|
static inline T* check()
|
||||||
{
|
{
|
||||||
reader_lock lock(id_manager::g_mutex);
|
reader_lock lock(id_manager::g_mutex);
|
||||||
|
|
||||||
return g_vec[get_type<T>()].second != nullptr;
|
return static_cast<T*>(g_vec[get_type<T>()].second.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the object (returns nullptr if it doesn't exist)
|
// Get the object (returns nullptr if it doesn't exist)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue