XSemaphore Save/Restore
This commit is contained in:
parent
afb514528e
commit
d0284e943d
|
@ -143,7 +143,7 @@ object_ref<XObject> XObject::Restore(KernelState* kernel_state, Type type,
|
|||
case kTypeNotifyListener:
|
||||
return NotifyListener::Restore(kernel_state, stream);
|
||||
case kTypeSemaphore:
|
||||
break;
|
||||
return XSemaphore::Restore(kernel_state, stream);
|
||||
case kTypeSession:
|
||||
break;
|
||||
case kTypeSocket:
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
|
||||
#include "xenia/kernel/xsemaphore.h"
|
||||
|
||||
#include "xenia/base/byte_stream.h"
|
||||
#include "xenia/base/logging.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
@ -22,6 +25,7 @@ void XSemaphore::Initialize(int32_t initial_count, int32_t maximum_count) {
|
|||
|
||||
CreateNative(sizeof(X_KSEMAPHORE));
|
||||
|
||||
maximum_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_);
|
||||
|
||||
auto semaphore = reinterpret_cast<X_KSEMAPHORE*>(native_ptr);
|
||||
maximum_count_ = semaphore->limit;
|
||||
semaphore_ = xe::threading::Semaphore::Create(semaphore->header.signal_state,
|
||||
semaphore->limit);
|
||||
}
|
||||
|
@ -39,5 +44,50 @@ int32_t XSemaphore::ReleaseSemaphore(int32_t release_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 xe
|
||||
|
|
|
@ -38,8 +38,13 @@ class XSemaphore : public XObject {
|
|||
return semaphore_.get();
|
||||
}
|
||||
|
||||
bool Save(ByteStream* stream) override;
|
||||
static object_ref<XSemaphore> Restore(KernelState* kernel_state,
|
||||
ByteStream* stream);
|
||||
|
||||
private:
|
||||
std::unique_ptr<xe::threading::Semaphore> semaphore_;
|
||||
uint32_t maximum_count_ = 0;
|
||||
};
|
||||
|
||||
} // namespace kernel
|
||||
|
|
Loading…
Reference in New Issue