XMutant Save/Restore
This commit is contained in:
parent
5aff9d12ee
commit
ab9fac9a98
|
@ -9,9 +9,16 @@
|
||||||
|
|
||||||
#include "xenia/kernel/xmutant.h"
|
#include "xenia/kernel/xmutant.h"
|
||||||
|
|
||||||
|
#include "xenia/base/byte_stream.h"
|
||||||
|
#include "xenia/base/logging.h"
|
||||||
|
#include "xenia/kernel/kernel_state.h"
|
||||||
|
#include "xenia/kernel/xthread.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|
||||||
|
XMutant::XMutant() : XObject(kTypeMutant) {}
|
||||||
|
|
||||||
XMutant::XMutant(KernelState* kernel_state)
|
XMutant::XMutant(KernelState* kernel_state)
|
||||||
: XObject(kernel_state, kTypeMutant) {}
|
: XObject(kernel_state, kTypeMutant) {}
|
||||||
|
|
||||||
|
@ -32,6 +39,11 @@ void XMutant::InitializeNative(void* native_ptr, X_DISPATCH_HEADER* header) {
|
||||||
|
|
||||||
X_STATUS XMutant::ReleaseMutant(uint32_t priority_increment, bool abandon,
|
X_STATUS XMutant::ReleaseMutant(uint32_t priority_increment, bool abandon,
|
||||||
bool wait) {
|
bool wait) {
|
||||||
|
// Call should succeed if we own the mutant, so go ahead and do this.
|
||||||
|
if (owning_thread_ == XThread::GetCurrentThread()) {
|
||||||
|
owning_thread_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(benvanik): abandoning.
|
// TODO(benvanik): abandoning.
|
||||||
assert_false(abandon);
|
assert_false(abandon);
|
||||||
if (mutant_->Release()) {
|
if (mutant_->Release()) {
|
||||||
|
@ -41,5 +53,38 @@ 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());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
object_ref<XMutant> XMutant::Restore(KernelState* kernel_state,
|
||||||
|
ByteStream* stream) {
|
||||||
|
auto mutant = new XMutant();
|
||||||
|
mutant->kernel_state_ = kernel_state;
|
||||||
|
|
||||||
|
if (!mutant->RestoreObject(stream)) {
|
||||||
|
delete mutant;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
return object_ref<XMutant>(mutant);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XMutant::WaitCallback() { owning_thread_ = XThread::GetCurrentThread(); }
|
||||||
|
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
class XThread;
|
||||||
|
|
||||||
class XMutant : public XObject {
|
class XMutant : public XObject {
|
||||||
public:
|
public:
|
||||||
|
@ -31,8 +32,18 @@ class XMutant : public XObject {
|
||||||
|
|
||||||
xe::threading::WaitHandle* GetWaitHandle() override { return mutant_.get(); }
|
xe::threading::WaitHandle* GetWaitHandle() override { return mutant_.get(); }
|
||||||
|
|
||||||
|
bool Save(ByteStream* stream) override;
|
||||||
|
static object_ref<XMutant> Restore(KernelState* kernel_state,
|
||||||
|
ByteStream* stream);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void WaitCallback() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
XMutant();
|
||||||
|
|
||||||
std::unique_ptr<xe::threading::Mutant> mutant_;
|
std::unique_ptr<xe::threading::Mutant> mutant_;
|
||||||
|
XThread* owning_thread_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
|
@ -139,7 +139,7 @@ object_ref<XObject> XObject::Restore(KernelState* kernel_state, Type type,
|
||||||
case kTypeModule:
|
case kTypeModule:
|
||||||
return XModule::Restore(kernel_state, stream);
|
return XModule::Restore(kernel_state, stream);
|
||||||
case kTypeMutant:
|
case kTypeMutant:
|
||||||
break;
|
return XMutant::Restore(kernel_state, stream);
|
||||||
case kTypeNotifyListener:
|
case kTypeNotifyListener:
|
||||||
return NotifyListener::Restore(kernel_state, stream);
|
return NotifyListener::Restore(kernel_state, stream);
|
||||||
case kTypeSemaphore:
|
case kTypeSemaphore:
|
||||||
|
|
Loading…
Reference in New Issue