mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-20 22:05:12 +00:00
Postpone thread launching on g_fxo->init
This commit is contained in:
parent
a4bcba8971
commit
0c410f8a14
11 changed files with 112 additions and 44 deletions
|
|
@ -15,6 +15,8 @@ extern thread_local std::string_view g_tls_serialize_name;
|
|||
|
||||
namespace stx
|
||||
{
|
||||
struct launch_retainer{};
|
||||
|
||||
// Simplified typemap with exactly one object of each used type, non-moveable. Initialized on init(). Destroyed on clear().
|
||||
template <typename Tag /*Tag should be unique*/, u32 Size = 0, u32 Align = (Size ? 64 : __STDCPP_DEFAULT_NEW_ALIGNMENT__)>
|
||||
class alignas(Align) manual_typemap
|
||||
|
|
@ -62,7 +64,7 @@ namespace stx
|
|||
struct typeinfo
|
||||
{
|
||||
bool(*create)(uchar* ptr, manual_typemap&, utils::serial*, std::string_view) noexcept = nullptr;
|
||||
void(*stop)(void* ptr, thread_state) noexcept = nullptr;
|
||||
void(*thread_op)(void* ptr, thread_state) noexcept = nullptr;
|
||||
void(*save)(void* ptr, utils::serial&) noexcept = nullptr;
|
||||
void(*destroy)(void* ptr) noexcept = nullptr;
|
||||
std::string_view name;
|
||||
|
|
@ -72,13 +74,19 @@ namespace stx
|
|||
{
|
||||
if (ar)
|
||||
{
|
||||
if constexpr (std::is_constructible_v<T, manual_typemap&, exact_t<utils::serial&>>)
|
||||
if constexpr (std::is_constructible_v<T, exact_t<manual_typemap&>, exact_t<utils::serial&>>)
|
||||
{
|
||||
g_tls_serialize_name = name;
|
||||
new (ptr) T(_this, exact_t<utils::serial&>(*ar));
|
||||
return true;
|
||||
}
|
||||
|
||||
if constexpr (std::is_constructible_v<T, exact_t<const launch_retainer&>, exact_t<utils::serial&>>)
|
||||
{
|
||||
new (ptr) T(exact_t<const launch_retainer&>(launch_retainer{}), exact_t<utils::serial&>(*ar));
|
||||
return true;
|
||||
}
|
||||
|
||||
if constexpr (std::is_constructible_v<T, exact_t<utils::serial&>>)
|
||||
{
|
||||
g_tls_serialize_name = name;
|
||||
|
|
@ -88,12 +96,18 @@ namespace stx
|
|||
}
|
||||
|
||||
// Allow passing reference to "this"
|
||||
if constexpr (std::is_constructible_v<T, manual_typemap&>)
|
||||
if constexpr (std::is_constructible_v<T, exact_t<manual_typemap&>>)
|
||||
{
|
||||
new (ptr) T(_this);
|
||||
return true;
|
||||
}
|
||||
|
||||
if constexpr (std::is_constructible_v<T, exact_t<const launch_retainer&>>)
|
||||
{
|
||||
new (ptr) T(exact_t<const launch_retainer&>(launch_retainer{}));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Call default constructor only if available
|
||||
if constexpr (std::is_default_constructible_v<T>)
|
||||
{
|
||||
|
|
@ -111,7 +125,7 @@ namespace stx
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
static void call_stop(void* ptr, thread_state state) noexcept
|
||||
static void call_thread_op(void* ptr, thread_state state) noexcept
|
||||
{
|
||||
// Abort and/or join (expected thread_state::aborting or thread_state::finished)
|
||||
*std::launder(static_cast<T*>(ptr)) = state;
|
||||
|
|
@ -134,7 +148,7 @@ namespace stx
|
|||
|
||||
if constexpr (std::is_assignable_v<T&, thread_state>)
|
||||
{
|
||||
r.stop = &call_stop<T>;
|
||||
r.thread_op = &call_thread_op<T>;
|
||||
}
|
||||
|
||||
if constexpr (!!(requires (T& a) { a.save(std::declval<stx::exact_t<utils::serial&>>()); }))
|
||||
|
|
@ -233,6 +247,8 @@ namespace stx
|
|||
return a.first < b.first;
|
||||
});
|
||||
|
||||
const auto info_before = m_info;
|
||||
|
||||
for (pos = 0; pos < stx::typelist<typeinfo>().count(); pos++)
|
||||
{
|
||||
const auto& type = *order[pos].second;
|
||||
|
|
@ -260,6 +276,15 @@ namespace stx
|
|||
}
|
||||
}
|
||||
|
||||
// Launch threads
|
||||
for (auto it = m_info; it != info_before; it--)
|
||||
{
|
||||
if (auto op = (*std::prev(it))->thread_op)
|
||||
{
|
||||
op(*std::prev(m_order, m_info - it + 1), thread_state{});
|
||||
}
|
||||
}
|
||||
|
||||
g_tls_serialize_name = {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1174,13 +1174,21 @@ namespace stx
|
|||
template <typename T>
|
||||
struct exact_t
|
||||
{
|
||||
static_assert(std::is_reference_v<T> || std::is_convertible_v<T, const T&>);
|
||||
|
||||
T obj;
|
||||
|
||||
exact_t(T&& _obj) : obj(std::forward<T>(_obj)) {}
|
||||
explicit exact_t(T&& _obj) : obj(std::forward<T>(_obj)) {}
|
||||
exact_t& operator=(const exact_t&) = delete;
|
||||
|
||||
// TODO: More conversions
|
||||
template <typename U> requires (std::is_same_v<U&, T>)
|
||||
operator U&() const { return obj; };
|
||||
operator U&() const noexcept { return obj; };
|
||||
|
||||
template <typename U> requires (std::is_same_v<const U&, T>)
|
||||
operator const U&() const noexcept { return obj; };
|
||||
|
||||
template <typename U> requires (std::is_same_v<U, T> && std::is_copy_constructible_v<T>)
|
||||
operator U() const noexcept { return obj; };
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue