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) {
|
||||
XELOGD("XMutant %.8X", handle());
|
||||
if (!SaveObject(stream)) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -75,11 +77,13 @@ object_ref<XMutant> XMutant::Restore(KernelState* kernel_state,
|
|||
|
||||
mutant->Initialize(false);
|
||||
|
||||
// TODO: Make the thread acquire this mutex... Somehow.
|
||||
auto owning_thread_handle = stream->Read<uint32_t>();
|
||||
mutant->owning_thread_ = kernel_state->object_table()
|
||||
->LookupObject<XThread>(owning_thread_handle)
|
||||
.get();
|
||||
if (owning_thread_handle) {
|
||||
mutant->owning_thread_ = kernel_state->object_table()
|
||||
->LookupObject<XThread>(owning_thread_handle)
|
||||
.get();
|
||||
mutant->owning_thread_->AcquireMutantOnStartup(retain_object(mutant));
|
||||
}
|
||||
|
||||
return object_ref<XMutant>(mutant);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "xenia/kernel/kernel_state.h"
|
||||
#include "xenia/kernel/user_module.h"
|
||||
#include "xenia/kernel/xevent.h"
|
||||
#include "xenia/kernel/xmutant.h"
|
||||
|
||||
DEFINE_bool(ignore_thread_priorities, true,
|
||||
"Ignores game-specified thread priorities.");
|
||||
|
@ -1218,13 +1219,21 @@ object_ref<XThread> XThread::Restore(KernelState* kernel_state,
|
|||
Clock::SetGuestTickCount(state.tick_count_);
|
||||
Clock::SetGuestSystemTime(state.system_time_);
|
||||
|
||||
// Execute user code.
|
||||
thread->running_ = true;
|
||||
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;
|
||||
thread->kernel_state()->processor()->ExecuteRaw(thread->thread_state_,
|
||||
pc);
|
||||
thread->kernel_state_->processor()->ExecuteRaw(thread->thread_state_, pc);
|
||||
|
||||
current_thread_tls_ = nullptr;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "xenia/cpu/thread_state.h"
|
||||
#include "xenia/kernel/util/native_list.h"
|
||||
#include "xenia/kernel/xobject.h"
|
||||
#include "xenia/kernel/xmutant.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
namespace xe {
|
||||
|
@ -190,6 +191,11 @@ class XThread : public XObject {
|
|||
static object_ref<XThread> Restore(KernelState* kernel_state,
|
||||
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
|
||||
// context. Returns the PC after we've finished stepping.
|
||||
// Pass true for ignore_host if you've stopped the thread yourself
|
||||
|
@ -210,6 +216,8 @@ class XThread : public XObject {
|
|||
|
||||
CreationParams creation_params_ = {0};
|
||||
|
||||
std::vector<object_ref<XMutant>> pending_mutant_acquires_;
|
||||
|
||||
uint32_t thread_id_ = 0;
|
||||
std::unique_ptr<xe::threading::Thread> thread_;
|
||||
uint32_t scratch_address_ = 0;
|
||||
|
|
Loading…
Reference in New Issue