XSemaphore Save/Restore

This commit is contained in:
Dr. Chat 2015-12-11 19:51:47 -06:00 committed by Ben Vanik
parent afb514528e
commit d0284e943d
3 changed files with 56 additions and 1 deletions

View File

@ -143,7 +143,7 @@ object_ref<XObject> XObject::Restore(KernelState* kernel_state, Type type,
case kTypeNotifyListener: case kTypeNotifyListener:
return NotifyListener::Restore(kernel_state, stream); return NotifyListener::Restore(kernel_state, stream);
case kTypeSemaphore: case kTypeSemaphore:
break; return XSemaphore::Restore(kernel_state, stream);
case kTypeSession: case kTypeSession:
break; break;
case kTypeSocket: case kTypeSocket:

View File

@ -9,6 +9,9 @@
#include "xenia/kernel/xsemaphore.h" #include "xenia/kernel/xsemaphore.h"
#include "xenia/base/byte_stream.h"
#include "xenia/base/logging.h"
namespace xe { namespace xe {
namespace kernel { namespace kernel {
@ -22,6 +25,7 @@ void XSemaphore::Initialize(int32_t initial_count, int32_t maximum_count) {
CreateNative(sizeof(X_KSEMAPHORE)); CreateNative(sizeof(X_KSEMAPHORE));
maximum_count_ = maximum_count;
semaphore_ = xe::threading::Semaphore::Create(initial_count, maximum_count); semaphore_ = xe::threading::Semaphore::Create(initial_count, maximum_count);
} }
@ -29,6 +33,7 @@ void XSemaphore::InitializeNative(void* native_ptr, X_DISPATCH_HEADER* header) {
assert_false(semaphore_); assert_false(semaphore_);
auto semaphore = reinterpret_cast<X_KSEMAPHORE*>(native_ptr); auto semaphore = reinterpret_cast<X_KSEMAPHORE*>(native_ptr);
maximum_count_ = semaphore->limit;
semaphore_ = xe::threading::Semaphore::Create(semaphore->header.signal_state, semaphore_ = xe::threading::Semaphore::Create(semaphore->header.signal_state,
semaphore->limit); semaphore->limit);
} }
@ -39,5 +44,50 @@ int32_t XSemaphore::ReleaseSemaphore(int32_t release_count) {
return previous_count; return previous_count;
} }
bool XSemaphore::Save(ByteStream* stream) {
if (!SaveObject(stream)) {
return false;
}
// Get the free number of slots from the semaphore.
uint32_t free_count = 0;
while (
threading::Wait(semaphore_.get(), false, std::chrono::milliseconds(0)) ==
threading::WaitResult::kSuccess) {
free_count++;
}
uint32_t used_count = maximum_count_ - free_count;
XELOGD("XSemaphore %.8X (count %d/%d)", handle(), used_count, maximum_count_);
// Restore the semaphore back to its previous count.
semaphore_->Release(free_count, nullptr);
stream->Write(maximum_count_);
stream->Write(used_count);
return true;
}
object_ref<XSemaphore> XSemaphore::Restore(KernelState* kernel_state,
ByteStream* stream) {
auto sem = new XSemaphore(nullptr);
sem->kernel_state_ = kernel_state;
if (!sem->RestoreObject(stream)) {
return nullptr;
}
sem->maximum_count_ = stream->Read<uint32_t>();
auto initial_count = stream->Read<uint32_t>();
XELOGD("XSemaphore %.8X (count %d/%d)", sem->handle(), initial_count,
sem->maximum_count_);
sem->semaphore_ =
threading::Semaphore::Create(initial_count, sem->maximum_count_);
return object_ref<XSemaphore>(sem);
}
} // namespace kernel } // namespace kernel
} // namespace xe } // namespace xe

View File

@ -38,8 +38,13 @@ class XSemaphore : public XObject {
return semaphore_.get(); return semaphore_.get();
} }
bool Save(ByteStream* stream) override;
static object_ref<XSemaphore> Restore(KernelState* kernel_state,
ByteStream* stream);
private: private:
std::unique_ptr<xe::threading::Semaphore> semaphore_; std::unique_ptr<xe::threading::Semaphore> semaphore_;
uint32_t maximum_count_ = 0;
}; };
} // namespace kernel } // namespace kernel