KeWaitForMultipleObjects.
This commit is contained in:
parent
372fd97821
commit
bb41ab717b
|
@ -861,6 +861,45 @@ SHIM_CALL NtWaitForSingleObjectEx_shim(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHIM_CALL KeWaitForMultipleObjects_shim(
|
||||||
|
PPCContext* ppc_state, KernelState* state) {
|
||||||
|
uint32_t count = SHIM_GET_ARG_32(0);
|
||||||
|
uint32_t objects_ptr = SHIM_GET_ARG_32(1);
|
||||||
|
uint32_t wait_type = SHIM_GET_ARG_32(2);
|
||||||
|
uint32_t wait_reason = SHIM_GET_ARG_32(3);
|
||||||
|
uint32_t processor_mode = SHIM_GET_ARG_32(4);
|
||||||
|
uint32_t alertable = SHIM_GET_ARG_32(5);
|
||||||
|
uint32_t timeout_ptr = SHIM_GET_ARG_32(6);
|
||||||
|
uint32_t wait_block_array_ptr = SHIM_GET_ARG_32(7);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
"KeWaitForMultipleObjects(%d, %.8X, %.8X, %.8X, %.8X, %.1X, %.8X, %.8X)",
|
||||||
|
count, objects_ptr, wait_type, wait_reason, processor_mode,
|
||||||
|
alertable, timeout_ptr, wait_block_array_ptr);
|
||||||
|
|
||||||
|
X_STATUS result = X_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
XObject** objects = (XObject**)alloca(sizeof(XObject*) * count);
|
||||||
|
for (uint32_t n = 0; n < count; n++) {
|
||||||
|
uint32_t object_ptr_ptr = SHIM_MEM_32(objects_ptr + n * 4);
|
||||||
|
void* object_ptr = SHIM_MEM_ADDR(object_ptr_ptr);
|
||||||
|
objects[n] = XObject::GetObject(state, object_ptr);
|
||||||
|
if (!objects[n]) {
|
||||||
|
SHIM_SET_RETURN(X_STATUS_INVALID_PARAMETER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t timeout = timeout_ptr ? SHIM_MEM_64(timeout_ptr) : 0;
|
||||||
|
result = XObject::WaitMultiple(
|
||||||
|
count, objects,
|
||||||
|
wait_type, wait_reason, processor_mode, alertable,
|
||||||
|
timeout_ptr ? &timeout : NULL);
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t xeKfAcquireSpinLock(void* lock_ptr) {
|
uint32_t xeKfAcquireSpinLock(void* lock_ptr) {
|
||||||
// Lock.
|
// Lock.
|
||||||
while (!xe_atomic_cas_32(0, 1, lock_ptr)) {
|
while (!xe_atomic_cas_32(0, 1, lock_ptr)) {
|
||||||
|
@ -975,6 +1014,7 @@ void xe::kernel::xboxkrnl::RegisterThreadingExports(
|
||||||
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeWaitForSingleObject, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", KeWaitForSingleObject, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtWaitForSingleObjectEx, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", NtWaitForSingleObjectEx, state);
|
||||||
|
SHIM_SET_MAPPING("xboxkrnl.exe", KeWaitForMultipleObjects, state);
|
||||||
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", KfAcquireSpinLock, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", KfAcquireSpinLock, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", KfReleaseSpinLock, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", KfReleaseSpinLock, state);
|
||||||
|
|
|
@ -70,6 +70,22 @@ X_STATUS XObject::Delete() {
|
||||||
return shared_kernel_state_->object_table()->RemoveHandle(handle_);
|
return shared_kernel_state_->object_table()->RemoveHandle(handle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
uint32_t ConvertTimeoutTicks(int64_t timeout_ticks) {
|
||||||
|
if (timeout_ticks > 0) {
|
||||||
|
// Absolute time, based on January 1, 1601.
|
||||||
|
// TODO(benvanik): convert time to relative time.
|
||||||
|
XEASSERTALWAYS();
|
||||||
|
return 0;
|
||||||
|
} else if (timeout_ticks < 0) {
|
||||||
|
// Relative time.
|
||||||
|
return (uint32_t)(-timeout_ticks / 10000); // Ticks -> MS
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode,
|
X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||||
uint32_t alertable, uint64_t* opt_timeout) {
|
uint32_t alertable, uint64_t* opt_timeout) {
|
||||||
void* wait_handle = GetWaitHandle();
|
void* wait_handle = GetWaitHandle();
|
||||||
|
@ -78,23 +94,8 @@ X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD timeout_ms;
|
DWORD timeout_ms = opt_timeout ?
|
||||||
if (opt_timeout) {
|
ConvertTimeoutTicks(*opt_timeout) : INFINITE;
|
||||||
int64_t timeout_ticks = (int64_t)(*opt_timeout);
|
|
||||||
if (timeout_ticks > 0) {
|
|
||||||
// Absolute time, based on January 1, 1601.
|
|
||||||
// TODO(benvanik): convert time to relative time.
|
|
||||||
XEASSERTALWAYS();
|
|
||||||
timeout_ms = 0;
|
|
||||||
} else if (timeout_ticks < 0) {
|
|
||||||
// Relative time.
|
|
||||||
timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS
|
|
||||||
} else {
|
|
||||||
timeout_ms = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
timeout_ms = INFINITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD result = WaitForSingleObjectEx(wait_handle, timeout_ms, alertable);
|
DWORD result = WaitForSingleObjectEx(wait_handle, timeout_ms, alertable);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
|
@ -112,6 +113,26 @@ X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
X_STATUS XObject::WaitMultiple(
|
||||||
|
uint32_t count, XObject** objects,
|
||||||
|
uint32_t wait_type, uint32_t wait_reason, uint32_t processor_mode,
|
||||||
|
uint32_t alertable, uint64_t* opt_timeout) {
|
||||||
|
void** wait_handles = (void**)alloca(sizeof(void*) * count);
|
||||||
|
for (uint32_t n = 0; n < count; n++) {
|
||||||
|
wait_handles[n] = objects[n]->GetWaitHandle();
|
||||||
|
XEASSERTNOTNULL(wait_handles[n]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD timeout_ms = opt_timeout ?
|
||||||
|
ConvertTimeoutTicks(*opt_timeout) : INFINITE;
|
||||||
|
|
||||||
|
DWORD result = WaitForMultipleObjectsEx(
|
||||||
|
count, wait_handles,
|
||||||
|
wait_type ? TRUE : FALSE, timeout_ms, alertable);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void XObject::LockType() {
|
void XObject::LockType() {
|
||||||
xe_mutex_lock(shared_kernel_state_->object_mutex_);
|
xe_mutex_lock(shared_kernel_state_->object_mutex_);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,10 @@ public:
|
||||||
X_STATUS Wait(
|
X_STATUS Wait(
|
||||||
uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable,
|
uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable,
|
||||||
uint64_t* opt_timeout);
|
uint64_t* opt_timeout);
|
||||||
|
static X_STATUS WaitMultiple(
|
||||||
|
uint32_t count, XObject** objects,
|
||||||
|
uint32_t wait_type, uint32_t wait_reason, uint32_t processor_mode,
|
||||||
|
uint32_t alertable, uint64_t* opt_timeout);
|
||||||
|
|
||||||
static void LockType();
|
static void LockType();
|
||||||
static void UnlockType();
|
static void UnlockType();
|
||||||
|
|
Loading…
Reference in New Issue