Finally adding thread wait so we kill the spin loop.
This commit is contained in:
parent
d16ab71252
commit
b0481472f2
|
@ -36,10 +36,7 @@ KernelState::KernelState(Runtime* runtime) :
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelState::~KernelState() {
|
KernelState::~KernelState() {
|
||||||
if (executable_module_) {
|
SetExecutableModule(NULL);
|
||||||
executable_module_->Release();
|
|
||||||
executable_module_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete all objects.
|
// Delete all objects.
|
||||||
xe_mutex_free(object_mutex_);
|
xe_mutex_free(object_mutex_);
|
||||||
|
|
|
@ -33,6 +33,7 @@ ObjectTable::~ObjectTable() {
|
||||||
ObjectTableEntry& entry = table_[n];
|
ObjectTableEntry& entry = table_[n];
|
||||||
if (entry.object) {
|
if (entry.object) {
|
||||||
entry.object->ReleaseHandle();
|
entry.object->ReleaseHandle();
|
||||||
|
entry.object->Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,13 @@ XEvent::XEvent(KernelState* kernel_state) :
|
||||||
XEvent::~XEvent() {
|
XEvent::~XEvent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XEvent::Initialize(void* native_ptr, DISPATCH_HEADER& header) {
|
void XEvent::Initialize(bool manual_reset, bool initial_state) {
|
||||||
|
XEASSERTNULL(handle_);
|
||||||
|
|
||||||
|
handle_ = CreateEvent(NULL, manual_reset, initial_state, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XEvent::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) {
|
||||||
XEASSERTNULL(handle_);
|
XEASSERTNULL(handle_);
|
||||||
|
|
||||||
bool manual_reset;
|
bool manual_reset;
|
||||||
|
|
|
@ -25,7 +25,8 @@ public:
|
||||||
XEvent(KernelState* kernel_state);
|
XEvent(KernelState* kernel_state);
|
||||||
virtual ~XEvent();
|
virtual ~XEvent();
|
||||||
|
|
||||||
void Initialize(void* native_ptr, DISPATCH_HEADER& header);
|
void Initialize(bool manual_reset, bool initial_state);
|
||||||
|
void InitializeNative(void* native_ptr, DISPATCH_HEADER& header);
|
||||||
|
|
||||||
int32_t Set(uint32_t priority_increment, bool wait);
|
int32_t Set(uint32_t priority_increment, bool wait);
|
||||||
int32_t Reset();
|
int32_t Reset();
|
||||||
|
|
|
@ -142,16 +142,7 @@ X_STATUS XModule::Launch(uint32_t flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until thread completes.
|
// Wait until thread completes.
|
||||||
// XLARGE_INTEGER timeout = XINFINITE;
|
thread->Wait(0, 0, 0, NULL);
|
||||||
// xekNtWaitForSingleObjectEx(thread_handle, TRUE, &timeout);
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
#if XE_PLATFORM(WIN32)
|
|
||||||
Sleep(1000);
|
|
||||||
#else
|
|
||||||
sleep(1);
|
|
||||||
#endif // WIN32
|
|
||||||
}
|
|
||||||
|
|
||||||
kernel_state()->SetExecutableModule(NULL);
|
kernel_state()->SetExecutableModule(NULL);
|
||||||
thread->Release();
|
thread->Release();
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <xenia/kernel/modules/xboxkrnl/objects/xthread.h>
|
#include <xenia/kernel/modules/xboxkrnl/objects/xthread.h>
|
||||||
|
|
||||||
|
#include <xenia/kernel/modules/xboxkrnl/objects/xevent.h>
|
||||||
#include <xenia/kernel/modules/xboxkrnl/objects/xmodule.h>
|
#include <xenia/kernel/modules/xboxkrnl/objects/xmodule.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,7 +32,8 @@ XThread::XThread(KernelState* kernel_state,
|
||||||
thread_id_(++next_xthread_id),
|
thread_id_(++next_xthread_id),
|
||||||
thread_handle_(0),
|
thread_handle_(0),
|
||||||
thread_state_address_(0),
|
thread_state_address_(0),
|
||||||
thread_state_(0) {
|
thread_state_(0),
|
||||||
|
event_(NULL) {
|
||||||
creation_params_.stack_size = stack_size;
|
creation_params_.stack_size = stack_size;
|
||||||
creation_params_.xapi_thread_startup = xapi_thread_startup;
|
creation_params_.xapi_thread_startup = xapi_thread_startup;
|
||||||
creation_params_.start_address = start_address;
|
creation_params_.start_address = start_address;
|
||||||
|
@ -42,9 +44,14 @@ XThread::XThread(KernelState* kernel_state,
|
||||||
if (creation_params_.stack_size < 16 * 1024 * 1024) {
|
if (creation_params_.stack_size < 16 * 1024 * 1024) {
|
||||||
creation_params_.stack_size = 16 * 1024 * 1024;
|
creation_params_.stack_size = 16 * 1024 * 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event_ = new XEvent(kernel_state);
|
||||||
|
event_->Initialize(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
XThread::~XThread() {
|
XThread::~XThread() {
|
||||||
|
event_->Release();
|
||||||
|
|
||||||
PlatformDestroy();
|
PlatformDestroy();
|
||||||
|
|
||||||
if (thread_state_) {
|
if (thread_state_) {
|
||||||
|
@ -100,13 +107,15 @@ X_STATUS XThread::Create() {
|
||||||
return X_STATUS_NO_MEMORY;
|
return X_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate TLS block.
|
|
||||||
XModule* module = kernel_state()->GetExecutableModule();
|
XModule* module = kernel_state()->GetExecutableModule();
|
||||||
|
|
||||||
|
// Allocate TLS block.
|
||||||
const xe_xex2_header_t* header = module->xex_header();
|
const xe_xex2_header_t* header = module->xex_header();
|
||||||
uint32_t tls_size = header->tls_info.slot_count * header->tls_info.data_size;
|
uint32_t tls_size = header->tls_info.slot_count * header->tls_info.data_size;
|
||||||
tls_address_ = xe_memory_heap_alloc(memory(), 0, tls_size, 0);
|
tls_address_ = xe_memory_heap_alloc(memory(), 0, tls_size, 0);
|
||||||
if (!tls_address_) {
|
if (!tls_address_) {
|
||||||
XELOGW("Unable to allocate thread local storage block");
|
XELOGW("Unable to allocate thread local storage block");
|
||||||
|
module->Release();
|
||||||
return X_STATUS_NO_MEMORY;
|
return X_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,21 +138,26 @@ X_STATUS XThread::Create() {
|
||||||
creation_params_.stack_size, thread_state_address_, thread_id_);
|
creation_params_.stack_size, thread_state_address_, thread_id_);
|
||||||
if (!thread_state_) {
|
if (!thread_state_) {
|
||||||
XELOGW("Unable to allocate processor thread state");
|
XELOGW("Unable to allocate processor thread state");
|
||||||
|
module->Release();
|
||||||
return X_STATUS_NO_MEMORY;
|
return X_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS return_code = PlatformCreate();
|
X_STATUS return_code = PlatformCreate();
|
||||||
if (XFAILED(return_code)) {
|
if (XFAILED(return_code)) {
|
||||||
XELOGW("Unable to create platform thread (%.8X)", return_code);
|
XELOGW("Unable to create platform thread (%.8X)", return_code);
|
||||||
|
module->Release();
|
||||||
return return_code;
|
return return_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module->Release();
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS XThread::Exit(int exit_code) {
|
X_STATUS XThread::Exit(int exit_code) {
|
||||||
// TODO(benvanik): set exit code in thread state block
|
// TODO(benvanik): set exit code in thread state block
|
||||||
|
|
||||||
// TODO(benvanik); dispatch events? waiters? etc?
|
// TODO(benvanik); dispatch events? waiters? etc?
|
||||||
|
event_->Set(0, false);
|
||||||
|
|
||||||
// NOTE: unless PlatformExit fails, expect it to never return!
|
// NOTE: unless PlatformExit fails, expect it to never return!
|
||||||
X_STATUS return_code = PlatformExit(exit_code);
|
X_STATUS return_code = PlatformExit(exit_code);
|
||||||
|
@ -271,3 +285,8 @@ void XThread::Execute() {
|
||||||
Exit(exit_code);
|
Exit(exit_code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
X_STATUS XThread::Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||||
|
uint32_t alertable, uint64_t* opt_timeout) {
|
||||||
|
return event_->Wait(wait_reason, processor_mode, alertable, opt_timeout);
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@ namespace kernel {
|
||||||
namespace xboxkrnl {
|
namespace xboxkrnl {
|
||||||
|
|
||||||
|
|
||||||
|
class XEvent;
|
||||||
|
|
||||||
|
|
||||||
class XThread : public XObject {
|
class XThread : public XObject {
|
||||||
public:
|
public:
|
||||||
XThread(KernelState* kernel_state,
|
XThread(KernelState* kernel_state,
|
||||||
|
@ -40,6 +43,9 @@ public:
|
||||||
|
|
||||||
void Execute();
|
void Execute();
|
||||||
|
|
||||||
|
virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||||
|
uint32_t alertable, uint64_t* opt_timeout);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
X_STATUS PlatformCreate();
|
X_STATUS PlatformCreate();
|
||||||
void PlatformDestroy();
|
void PlatformDestroy();
|
||||||
|
@ -58,6 +64,8 @@ private:
|
||||||
uint32_t tls_address_;
|
uint32_t tls_address_;
|
||||||
uint32_t thread_state_address_;
|
uint32_t thread_state_address_;
|
||||||
cpu::ThreadState* thread_state_;
|
cpu::ThreadState* thread_state_;
|
||||||
|
|
||||||
|
XEvent* event_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -590,10 +590,12 @@ uint32_t xeRtlImageXexHeaderField(uint32_t xex_header_base_ptr,
|
||||||
const xe_xex2_header_t* xex_header = module->xex_header();
|
const xe_xex2_header_t* xex_header = module->xex_header();
|
||||||
for (size_t n = 0; n < xex_header->header_count; n++) {
|
for (size_t n = 0; n < xex_header->header_count; n++) {
|
||||||
if (xex_header->headers[n].key == image_field) {
|
if (xex_header->headers[n].key == image_field) {
|
||||||
|
module->Release();
|
||||||
return xex_header->headers[n].value;
|
return xex_header->headers[n].value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module->Release();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ using namespace xe::kernel::xboxkrnl;
|
||||||
XObject::XObject(KernelState* kernel_state, Type type) :
|
XObject::XObject(KernelState* kernel_state, Type type) :
|
||||||
kernel_state_(kernel_state),
|
kernel_state_(kernel_state),
|
||||||
handle_ref_count_(0),
|
handle_ref_count_(0),
|
||||||
pointer_ref_count_(0),
|
pointer_ref_count_(1),
|
||||||
type_(type), handle_(X_INVALID_HANDLE_VALUE) {
|
type_(type), handle_(X_INVALID_HANDLE_VALUE) {
|
||||||
kernel_state->object_table()->AddHandle(this, &handle_);
|
kernel_state->object_table()->AddHandle(this, &handle_);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr) {
|
||||||
case 1: // EventSynchronizationObject
|
case 1: // EventSynchronizationObject
|
||||||
{
|
{
|
||||||
XEvent* ev = new XEvent(kernel_state);
|
XEvent* ev = new XEvent(kernel_state);
|
||||||
ev->Initialize(native_ptr, header);
|
ev->InitializeNative(native_ptr, header);
|
||||||
object = ev;
|
object = ev;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue