XMutant Save/Restore

This commit is contained in:
Dr. Chat 2015-12-16 17:27:25 -06:00 committed by Ben Vanik
parent 5aff9d12ee
commit ab9fac9a98
3 changed files with 57 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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: