1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 18:53:28 +01:00

id_manager: embedded RTTI

This commit is contained in:
Nekotekina 2016-08-01 02:26:55 +03:00
parent e585939ac2
commit e6bd91ada0
9 changed files with 93 additions and 77 deletions

View File

@ -558,9 +558,9 @@ s32 cellAdecOpen(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResource> res, vm::
return CELL_ADEC_ERROR_ARG;
}
auto&& adec = std::make_shared<AudioDecoder>(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg);
auto&& adec = idm::make_ptr<ppu_thread, AudioDecoder>(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg);
*handle = idm::import_existing<ppu_thread>(adec);
*handle = adec->id;
adec->run();
@ -576,9 +576,9 @@ s32 cellAdecOpenEx(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResourceEx> res,
return CELL_ADEC_ERROR_ARG;
}
auto&& adec = std::make_shared<AudioDecoder>(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg);
auto&& adec = idm::make_ptr<ppu_thread, AudioDecoder>(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg);
*handle = idm::import_existing<ppu_thread>(adec);
*handle = adec->id;
adec->run();

View File

@ -976,9 +976,9 @@ s32 cellDmuxOpen(vm::cptr<CellDmuxType> type, vm::cptr<CellDmuxResource> res, vm
}
// TODO: check demuxerResource and demuxerCb arguments
auto&& dmux = std::make_shared<Demuxer>(res->memAddr, res->memSize, cb->cbMsgFunc, cb->cbArg);
auto&& dmux = idm::make_ptr<ppu_thread, Demuxer>(res->memAddr, res->memSize, cb->cbMsgFunc, cb->cbArg);
*handle = idm::import_existing<ppu_thread>(dmux);
*handle = dmux->id;
dmux->run();
@ -995,9 +995,9 @@ s32 cellDmuxOpenEx(vm::cptr<CellDmuxType> type, vm::cptr<CellDmuxResourceEx> res
}
// TODO: check demuxerResourceEx and demuxerCb arguments
auto&& dmux = std::make_shared<Demuxer>(resEx->memAddr, resEx->memSize, cb->cbMsgFunc, cb->cbArg);
auto&& dmux = idm::make_ptr<ppu_thread, Demuxer>(resEx->memAddr, resEx->memSize, cb->cbMsgFunc, cb->cbArg);
*handle = idm::import_existing<ppu_thread>(dmux);
*handle = dmux->id;
dmux->run();
@ -1021,9 +1021,9 @@ s32 cellDmuxOpen2(vm::cptr<CellDmuxType2> type2, vm::cptr<CellDmuxResource2> res
}
// TODO: check demuxerType2, demuxerResource2 and demuxerCb arguments
auto&& dmux = std::make_shared<Demuxer>(res2->memAddr, res2->memSize, cb->cbMsgFunc, cb->cbArg);
auto&& dmux = idm::make_ptr<ppu_thread, Demuxer>(res2->memAddr, res2->memSize, cb->cbMsgFunc, cb->cbArg);
*handle = idm::import_existing<ppu_thread>(dmux);
*handle = dmux->id;
dmux->run();

View File

@ -737,12 +737,12 @@ struct fs_aio_thread : ppu_thread
struct fs_aio_manager
{
std::shared_ptr<fs_aio_thread> t = std::make_shared<fs_aio_thread>("FS AIO Thread", 500);
std::shared_ptr<fs_aio_thread> thread;
fs_aio_manager()
: thread(idm::make_ptr<ppu_thread, fs_aio_thread>("FS AIO Thread", 500))
{
idm::import_existing<ppu_thread>(t);
t->run();
thread->run();
}
};
@ -779,13 +779,13 @@ s32 cellFsAioRead(vm::ptr<CellFsAio> aio, vm::ptr<s32> id, fs_aio_cb_t func)
const auto m = fxm::get_always<fs_aio_manager>();
m->t->cmd_list
m->thread->cmd_list
({
{ 1, xid },
{ aio, func },
});
m->t->lock_notify();
m->thread->lock_notify();
return CELL_OK;
}
@ -800,13 +800,13 @@ s32 cellFsAioWrite(vm::ptr<CellFsAio> aio, vm::ptr<s32> id, fs_aio_cb_t func)
const auto m = fxm::get_always<fs_aio_manager>();
m->t->cmd_list
m->thread->cmd_list
({
{ 2, xid },
{ aio, func },
});
m->t->lock_notify();
m->thread->lock_notify();
return CELL_OK;
}

View File

@ -607,9 +607,9 @@ s32 _spurs::create_handler(vm::ptr<CellSpurs> spurs, u32 ppuPriority)
}
};
auto&& eht = std::make_shared<handler_thread>(std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr0", ppuPriority, 0x4000);
auto&& eht = idm::make_ptr<ppu_thread, handler_thread>(std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr0", ppuPriority, 0x4000);
spurs->ppu0 = idm::import_existing<ppu_thread>(eht);
spurs->ppu0 = eht->id;
eht->gpr[3] = spurs.addr();
eht->run();
@ -804,11 +804,9 @@ s32 _spurs::create_event_helper(ppu_thread& ppu, vm::ptr<CellSpurs> spurs, u32 p
}
};
auto&& eht = std::make_shared<event_helper_thread>(std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr1", ppuPriority, 0x8000);
auto&& eht = idm::make_ptr<ppu_thread, event_helper_thread>(std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr1", ppuPriority, 0x8000);
const u32 tid = idm::import_existing<ppu_thread>(eht);
if (tid == 0)
if (!eht)
{
sys_event_port_disconnect(spurs->eventPort);
sys_event_port_destroy(spurs->eventPort);
@ -825,7 +823,7 @@ s32 _spurs::create_event_helper(ppu_thread& ppu, vm::ptr<CellSpurs> spurs, u32 p
eht->gpr[3] = spurs.addr();
eht->run();
spurs->ppu1 = tid;
spurs->ppu1 = eht->id;
return CELL_OK;
}

View File

@ -399,10 +399,10 @@ s32 cellVdecOpen(vm::cptr<CellVdecType> type, vm::cptr<CellVdecResource> res, vm
cellVdec.warning("cellVdecOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
// Create decoder thread
auto&& vdec = std::make_shared<vdec_thread>(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg);
auto&& vdec = idm::make_ptr<ppu_thread, vdec_thread>(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg);
// Hack: store thread id (normally it should be pointer)
*handle = idm::import_existing<ppu_thread>(vdec);
*handle = vdec->id;
vdec->run();
@ -414,10 +414,10 @@ s32 cellVdecOpenEx(vm::cptr<CellVdecTypeEx> type, vm::cptr<CellVdecResourceEx> r
cellVdec.warning("cellVdecOpenEx(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
// Create decoder thread
auto&& vdec = std::make_shared<vdec_thread>(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg);
auto&& vdec = idm::make_ptr<ppu_thread, vdec_thread>(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg);
// Hack: store thread id (normally it should be pointer)
*handle = idm::import_existing<ppu_thread>(vdec);
*handle = vdec->id;
vdec->run();
@ -428,7 +428,7 @@ s32 cellVdecClose(u32 handle)
{
cellVdec.warning("cellVdecClose(handle=0x%x)", handle);
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
if (!vdec)
{
@ -446,7 +446,7 @@ s32 cellVdecStartSeq(u32 handle)
{
cellVdec.trace("cellVdecStartSeq(handle=0x%x)", handle);
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
if (!vdec)
{
@ -462,7 +462,7 @@ s32 cellVdecEndSeq(u32 handle)
{
cellVdec.warning("cellVdecEndSeq(handle=0x%x)", handle);
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
if (!vdec)
{
@ -478,7 +478,7 @@ s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr<CellVdecAuInf
{
cellVdec.trace("cellVdecDecodeAu(handle=0x%x, mode=%d, auInfo=*0x%x)", handle, mode, auInfo);
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
if (mode > CELL_VDEC_DEC_MODE_PB_SKIP || !vdec)
{
@ -509,7 +509,7 @@ s32 cellVdecGetPicture(u32 handle, vm::cptr<CellVdecPicFormat> format, vm::ptr<u
{
cellVdec.trace("cellVdecGetPicture(handle=0x%x, format=*0x%x, outBuff=*0x%x)", handle, format, outBuff);
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
if (!format || !vdec)
{
@ -629,7 +629,7 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem)
{
cellVdec.trace("cellVdecGetPicItem(handle=0x%x, picItem=**0x%x)", handle, picItem);
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
if (!vdec)
{
@ -824,7 +824,7 @@ s32 cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frc)
{
cellVdec.trace("cellVdecSetFrameRate(handle=0x%x, frc=0x%x)", handle, frc);
const auto vdec = std::dynamic_pointer_cast<vdec_thread>(idm::get<ppu_thread>(handle)); // TODO: avoid RTTI
const auto vdec = idm::get<ppu_thread, vdec_thread>(handle);
if (!vdec)
{

View File

@ -489,9 +489,7 @@ s32 cellSurMixerCreate(vm::cptr<CellSurMixerConfig> config)
libmixer.warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)", config->chStrips1, config->chStrips2, config->chStrips6, config->chStrips8);
auto&& thread = std::make_shared<surmixer_thread>("Surmixer Thread");
idm::import_existing<ppu_thread>(thread);
auto&& thread = idm::make_ptr<ppu_thread, surmixer_thread>("Surmixer Thread");
thread->run();

View File

@ -80,6 +80,7 @@ std::string ppu_thread::dump() const
{
std::string ret;
ret += fmt::format("Type: %s\n", typeid(*this).name());
ret += fmt::format("State: 0x%08x\n", state.load());
ret += fmt::format("Priority: %d\n", prio);

View File

@ -24,7 +24,7 @@ u32 id_manager::typeinfo::add_type()
return ::size32(list) - 1;
}
id_manager::id_map::pointer idm::allocate_id(u32 tag, u32 min, u32 max)
id_manager::id_map::pointer idm::allocate_id(u32 tag, u32 type, u32 min, u32 max)
{
// Check all IDs starting from "next id"
for (u32 i = 0; i <= max - min; i++)
@ -33,7 +33,7 @@ id_manager::id_map::pointer idm::allocate_id(u32 tag, u32 min, u32 max)
if (g_id[tag] < min || g_id[tag] > max) g_id[tag] = min;
// Get ID
const auto r = g_map[tag].emplace(g_id[tag]++, nullptr);
const auto r = g_map[tag].emplace(id_manager::id_key{g_id[tag]++, type}, nullptr);
if (r.second)
{
@ -58,19 +58,23 @@ std::shared_ptr<void> idm::deallocate_id(u32 tag, u32 id)
return ptr;
}
id_manager::id_map::pointer idm::find_id(u32 type, u32 id)
id_manager::id_map::pointer idm::find_id(u32 type, u32 true_type, u32 id)
{
const auto found = g_map[type].find(id);
if (found == g_map[type].end()) return nullptr;
if (true_type != get_type<void>() && found->first.type() != true_type) return nullptr;
return &*found;
}
std::shared_ptr<void> idm::delete_id(u32 type, u32 tag, u32 id)
std::shared_ptr<void> idm::delete_id(u32 type, u32 true_type, u32 tag, u32 id)
{
writer_lock lock(g_mutex);
if (!find_id(type, true_type, id)) return nullptr; // ???
auto&& ptr = deallocate_id(tag, id);
g_map[type].erase(id);

View File

@ -228,13 +228,13 @@ class idm
};
// Prepares new ID, returns nullptr if out of resources
static id_manager::id_map::pointer allocate_id(u32 tag, u32 min, u32 max);
static id_manager::id_map::pointer allocate_id(u32 tag, u32 type, u32 min, u32 max);
// Deallocate ID, returns object
static std::shared_ptr<void> deallocate_id(u32 tag, u32 id);
// Allocate new ID and construct it from the provider()
template<typename T, typename F>
template<typename T, typename Set, typename F>
static id_manager::id_map::pointer create_id(F&& provider)
{
id_manager::typeinfo::update<T>();
@ -242,7 +242,7 @@ class idm
writer_lock lock(g_mutex);
if (auto place = allocate_id(get_tag<T>(), id_manager::id_traits<T>::min, id_manager::id_traits<T>::max))
if (auto place = allocate_id(get_tag<T>(), get_type<Set>(), id_manager::id_traits<T>::min, id_manager::id_traits<T>::max))
{
try
{
@ -265,10 +265,10 @@ class idm
}
// Get ID (internal)
static id_manager::id_map::pointer find_id(u32 type, u32 id);
static id_manager::id_map::pointer find_id(u32 type, u32 true_type, u32 id);
// Remove ID and return object
static std::shared_ptr<void> delete_id(u32 type, u32 tag, u32 id);
static std::shared_ptr<void> delete_id(u32 type, u32 true_type, u32 tag, u32 id);
public:
// Initialize object manager
@ -279,13 +279,13 @@ public:
// Add a new ID of specified type with specified constructor arguments (returns object or nullptr)
template<typename T, typename Make = T, typename... Args>
static inline std::enable_if_t<std::is_constructible<Make, Args...>::value, std::shared_ptr<T>> make_ptr(Args&&... args)
static inline std::enable_if_t<std::is_constructible<Make, Args...>::value, std::shared_ptr<Make>> make_ptr(Args&&... args)
{
if (auto pair = create_id<T>(WRAP_EXPR(std::make_shared<Make>(std::forward<Args>(args)...))))
if (auto pair = create_id<T, Make>(WRAP_EXPR(std::make_shared<Make>(std::forward<Args>(args)...))))
{
id_manager::on_init<T>::func(static_cast<T*>(pair->second.get()), pair->second);
id_manager::on_stop<T>::func(nullptr);
return{ pair->second, static_cast<T*>(pair->second.get()) };
return{ pair->second, static_cast<Make*>(pair->second.get()) };
}
return nullptr;
@ -295,7 +295,7 @@ public:
template<typename T, typename Make = T, typename... Args>
static inline std::enable_if_t<std::is_constructible<Make, Args...>::value, u32> make(Args&&... args)
{
if (auto pair = create_id<T>(WRAP_EXPR(std::make_shared<Make>(std::forward<Args>(args)...))))
if (auto pair = create_id<T, Make>(WRAP_EXPR(std::make_shared<Make>(std::forward<Args>(args)...))))
{
id_manager::on_init<T>::func(static_cast<T*>(pair->second.get()), pair->second);
id_manager::on_stop<T>::func(nullptr);
@ -306,10 +306,10 @@ public:
}
// Add a new ID for an existing object provided (returns new id)
template<typename T>
template<typename T, typename Made = T>
static inline u32 import_existing(const std::shared_ptr<T>& ptr)
{
if (auto pair = create_id<T>(WRAP_EXPR(ptr)))
if (auto pair = create_id<T, Made>(WRAP_EXPR(ptr)))
{
id_manager::on_init<T>::func(static_cast<T*>(pair->second.get()), pair->second);
id_manager::on_stop<T>::func(nullptr);
@ -320,53 +320,53 @@ public:
}
// Add a new ID for an object returned by provider()
template<typename T, typename F, typename = std::result_of_t<F()>>
static inline std::shared_ptr<T> import(F&& provider)
template<typename T, typename Made = T, typename F, typename = std::result_of_t<F()>>
static inline std::shared_ptr<Made> import(F&& provider)
{
if (auto pair = create_id<T>(std::forward<F>(provider)))
if (auto pair = create_id<T, Made>(std::forward<F>(provider)))
{
id_manager::on_init<T>::func(static_cast<T*>(pair->second.get()), pair->second);
id_manager::on_stop<T>::func(nullptr);
return { pair->second, static_cast<T*>(pair->second.get()) };
return { pair->second, static_cast<Made*>(pair->second.get()) };
}
return nullptr;
}
// Check whether the ID exists
template<typename T>
template<typename T, typename Get = void>
static inline bool check(u32 id)
{
reader_lock lock(g_mutex);
return find_id(get_type<T>(), id) != nullptr;
return find_id(get_type<T>(), get_type<Get>(), id) != nullptr;
}
// Get the ID
template<typename T>
static inline std::shared_ptr<T> get(u32 id)
template<typename T, typename Get = void, typename Made = std::conditional_t<std::is_void<Get>::value, T, Get>>
static inline std::shared_ptr<Made> get(u32 id)
{
reader_lock lock(g_mutex);
const auto found = find_id(get_type<T>(), id);
const auto found = find_id(get_type<T>(), get_type<Get>(), id);
if (UNLIKELY(found == nullptr))
{
return nullptr;
}
return{ found->second, static_cast<T*>(found->second.get()) };
return{ found->second, static_cast<Made*>(found->second.get()) };
}
// Conditionally get the ID, almost similar to select() but for the single object only.
template<typename T, typename F, typename FT = decltype(&F::operator()), typename A2 = typename function_traits<FT>::second_type>
template<typename T, typename Get = void, typename F, typename FT = decltype(&F::operator()), typename A2 = typename function_traits<FT>::second_type>
static inline auto get(u32 id, F&& pred)
{
using result_type = std::conditional_t<std::is_void<typename function_traits<FT>::return_type>::value, void, std::shared_ptr<A2>>;
reader_lock lock(g_mutex);
const auto found = find_id(get_type<T>(), id);
const auto found = find_id(get_type<T>(), get_type<Get>(), id);
if (UNLIKELY(found == nullptr))
{
@ -404,19 +404,34 @@ public:
}
// Get count of objects
template<typename T>
template<typename T, typename Get = void>
static inline u32 get_count()
{
reader_lock lock(g_mutex);
return ::size32(g_map[get_type<T>()]);
if (std::is_void<Get>::value)
{
return ::size32(g_map[get_type<T>()]);
}
u32 result = 0;
for (auto& id : g_map[get_type<T>()])
{
if (id.first.type() == get_type<Get>())
{
result++;
}
}
return result;
}
// Remove the ID
template<typename T>
template<typename T, typename Get = void>
static inline bool remove(u32 id)
{
auto&& ptr = delete_id(get_type<T>(), get_tag<T>(), id);
auto&& ptr = delete_id(get_type<T>(), get_type<Get>(), get_tag<T>(), id);
if (LIKELY(ptr))
{
@ -427,28 +442,28 @@ public:
}
// Remove the ID and return it
template<typename T>
static inline std::shared_ptr<T> withdraw(u32 id)
template<typename T, typename Get = void, typename Made = std::conditional_t<std::is_void<Get>::value, T, Get>>
static inline std::shared_ptr<Made> withdraw(u32 id)
{
auto&& ptr = delete_id(get_type<T>(), get_tag<T>(), id);
auto&& ptr = delete_id(get_type<T>(), get_type<Get>(), get_tag<T>(), id);
if (LIKELY(ptr))
{
id_manager::on_stop<T>::func(static_cast<T*>(ptr.get()));
}
return{ ptr, static_cast<T*>(ptr.get()) };
return{ ptr, static_cast<Made*>(ptr.get()) };
}
// Conditionally remove the ID and return it.
template<typename T, typename F>
static inline std::shared_ptr<T> withdraw(u32 id, F&& pred)
template<typename T, typename Get = void, typename Made = std::conditional_t<std::is_void<Get>::value, T, Get>, typename F>
static inline std::shared_ptr<Made> withdraw(u32 id, F&& pred)
{
std::shared_ptr<void> ptr;
{
writer_lock lock(g_mutex);
const auto found = find_id(get_type<T>(), id);
const auto found = find_id(get_type<T>(), get_type<Get>(), id);
if (UNLIKELY(found == nullptr || !pred(id, *static_cast<T*>(found->second.get()))))
{
@ -462,7 +477,7 @@ public:
id_manager::on_stop<T>::func(static_cast<T*>(ptr.get()));
return{ ptr, static_cast<T*>(ptr.get()) };
return{ ptr, static_cast<Made*>(ptr.get()) };
}
};