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