XThread acquire mutants on restore
This commit is contained in:
parent
5c94062110
commit
bca5fb5382
|
@ -54,12 +54,14 @@ X_STATUS XMutant::ReleaseMutant(uint32_t priority_increment, bool abandon,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XMutant::Save(ByteStream* stream) {
|
bool XMutant::Save(ByteStream* stream) {
|
||||||
XELOGD("XMutant %.8X", handle());
|
|
||||||
if (!SaveObject(stream)) {
|
if (!SaveObject(stream)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->Write(owning_thread_->handle());
|
uint32_t owning_thread_handle = owning_thread_ ? owning_thread_->handle() : 0;
|
||||||
|
stream->Write<uint32_t>(owning_thread_handle);
|
||||||
|
XELOGD("XMutant %.8X (owner: %.8X)", handle(), owning_thread_handle);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,11 +77,13 @@ object_ref<XMutant> XMutant::Restore(KernelState* kernel_state,
|
||||||
|
|
||||||
mutant->Initialize(false);
|
mutant->Initialize(false);
|
||||||
|
|
||||||
// TODO: Make the thread acquire this mutex... Somehow.
|
|
||||||
auto owning_thread_handle = stream->Read<uint32_t>();
|
auto owning_thread_handle = stream->Read<uint32_t>();
|
||||||
mutant->owning_thread_ = kernel_state->object_table()
|
if (owning_thread_handle) {
|
||||||
->LookupObject<XThread>(owning_thread_handle)
|
mutant->owning_thread_ = kernel_state->object_table()
|
||||||
.get();
|
->LookupObject<XThread>(owning_thread_handle)
|
||||||
|
.get();
|
||||||
|
mutant->owning_thread_->AcquireMutantOnStartup(retain_object(mutant));
|
||||||
|
}
|
||||||
|
|
||||||
return object_ref<XMutant>(mutant);
|
return object_ref<XMutant>(mutant);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
#include "xenia/kernel/user_module.h"
|
#include "xenia/kernel/user_module.h"
|
||||||
#include "xenia/kernel/xevent.h"
|
#include "xenia/kernel/xevent.h"
|
||||||
|
#include "xenia/kernel/xmutant.h"
|
||||||
|
|
||||||
DEFINE_bool(ignore_thread_priorities, true,
|
DEFINE_bool(ignore_thread_priorities, true,
|
||||||
"Ignores game-specified thread priorities.");
|
"Ignores game-specified thread priorities.");
|
||||||
|
@ -1218,13 +1219,21 @@ object_ref<XThread> XThread::Restore(KernelState* kernel_state,
|
||||||
Clock::SetGuestTickCount(state.tick_count_);
|
Clock::SetGuestTickCount(state.tick_count_);
|
||||||
Clock::SetGuestSystemTime(state.system_time_);
|
Clock::SetGuestSystemTime(state.system_time_);
|
||||||
|
|
||||||
// Execute user code.
|
|
||||||
thread->running_ = true;
|
|
||||||
current_thread_tls_ = thread;
|
current_thread_tls_ = thread;
|
||||||
|
|
||||||
|
// Acquire any mutants
|
||||||
|
for (auto mutant : thread->pending_mutant_acquires_) {
|
||||||
|
uint64_t timeout = 0;
|
||||||
|
auto status = mutant->Wait(0, 0, 0, &timeout);
|
||||||
|
assert_true(status == X_STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
thread->pending_mutant_acquires_.clear();
|
||||||
|
|
||||||
|
// Execute user code.
|
||||||
|
thread->running_ = true;
|
||||||
|
|
||||||
uint32_t pc = state.context.pc;
|
uint32_t pc = state.context.pc;
|
||||||
thread->kernel_state()->processor()->ExecuteRaw(thread->thread_state_,
|
thread->kernel_state_->processor()->ExecuteRaw(thread->thread_state_, pc);
|
||||||
pc);
|
|
||||||
|
|
||||||
current_thread_tls_ = nullptr;
|
current_thread_tls_ = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "xenia/cpu/thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
#include "xenia/kernel/util/native_list.h"
|
#include "xenia/kernel/util/native_list.h"
|
||||||
#include "xenia/kernel/xobject.h"
|
#include "xenia/kernel/xobject.h"
|
||||||
|
#include "xenia/kernel/xmutant.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
@ -190,6 +191,11 @@ class XThread : public XObject {
|
||||||
static object_ref<XThread> Restore(KernelState* kernel_state,
|
static object_ref<XThread> Restore(KernelState* kernel_state,
|
||||||
ByteStream* stream);
|
ByteStream* stream);
|
||||||
|
|
||||||
|
// Internal - do not use.
|
||||||
|
void AcquireMutantOnStartup(object_ref<XMutant> mutant) {
|
||||||
|
pending_mutant_acquires_.push_back(mutant);
|
||||||
|
}
|
||||||
|
|
||||||
// Steps the thread to a point where it's safe to terminate or read its
|
// Steps the thread to a point where it's safe to terminate or read its
|
||||||
// context. Returns the PC after we've finished stepping.
|
// context. Returns the PC after we've finished stepping.
|
||||||
// Pass true for ignore_host if you've stopped the thread yourself
|
// Pass true for ignore_host if you've stopped the thread yourself
|
||||||
|
@ -210,6 +216,8 @@ class XThread : public XObject {
|
||||||
|
|
||||||
CreationParams creation_params_ = {0};
|
CreationParams creation_params_ = {0};
|
||||||
|
|
||||||
|
std::vector<object_ref<XMutant>> pending_mutant_acquires_;
|
||||||
|
|
||||||
uint32_t thread_id_ = 0;
|
uint32_t thread_id_ = 0;
|
||||||
std::unique_ptr<xe::threading::Thread> thread_;
|
std::unique_ptr<xe::threading::Thread> thread_;
|
||||||
uint32_t scratch_address_ = 0;
|
uint32_t scratch_address_ = 0;
|
||||||
|
|
Loading…
Reference in New Issue