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:
return NotifyListener::Restore(kernel_state, stream);
case kTypeSemaphore:
break;
return XSemaphore::Restore(kernel_state, stream);
case kTypeSession:
break;
case kTypeSocket:

View File

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

View File

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