Mutants.
This commit is contained in:
parent
40ca0bcb76
commit
5019f350f8
|
@ -7,6 +7,8 @@
|
|||
'xfile.h',
|
||||
'xmodule.cc',
|
||||
'xmodule.h',
|
||||
'xmutant.cc',
|
||||
'xmutant.h',
|
||||
'xnotify_listener.cc',
|
||||
'xnotify_listener.h',
|
||||
'xsemaphore.cc',
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/kernel/objects/xmutant.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
XMutant::XMutant(KernelState* kernel_state) :
|
||||
XObject(kernel_state, kTypeMutant),
|
||||
handle_(NULL) {
|
||||
}
|
||||
|
||||
XMutant::~XMutant() {
|
||||
if (handle_) {
|
||||
CloseHandle(handle_);
|
||||
}
|
||||
}
|
||||
|
||||
void XMutant::Initialize(bool initial_owner) {
|
||||
XEASSERTNULL(handle_);
|
||||
|
||||
handle_ = CreateMutex(NULL, initial_owner ? TRUE : FALSE, NULL);
|
||||
}
|
||||
|
||||
void XMutant::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) {
|
||||
XEASSERTNULL(handle_);
|
||||
|
||||
// Haven't seen this yet, but it's possible.
|
||||
XEASSERTALWAYS();
|
||||
}
|
||||
|
||||
X_STATUS XMutant::ReleaseMutant(
|
||||
uint32_t priority_increment, bool abandon, bool wait) {
|
||||
// TODO(benvanik): abandoning.
|
||||
XEASSERTFALSE(abandon);
|
||||
BOOL result = ReleaseMutex(handle_);
|
||||
if (result) {
|
||||
return X_STATUS_SUCCESS;
|
||||
} else {
|
||||
return X_STATUS_MUTANT_NOT_OWNED;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_KERNEL_XBOXKRNL_XMUTANT_H_
|
||||
#define XENIA_KERNEL_XBOXKRNL_XMUTANT_H_
|
||||
|
||||
#include <xenia/kernel/xobject.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
|
||||
|
||||
class XMutant : public XObject {
|
||||
public:
|
||||
XMutant(KernelState* kernel_state);
|
||||
virtual ~XMutant();
|
||||
|
||||
void Initialize(bool initial_owner);
|
||||
void InitializeNative(void* native_ptr, DISPATCH_HEADER& header);
|
||||
|
||||
X_STATUS ReleaseMutant(uint32_t priority_increment, bool abandon, bool wait);
|
||||
|
||||
virtual void* GetWaitHandle() { return handle_; }
|
||||
|
||||
private:
|
||||
HANDLE handle_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_XBOXKRNL_XMUTANT_H_
|
|
@ -12,6 +12,7 @@
|
|||
#include <xenia/kernel/kernel_state.h>
|
||||
#include <xenia/kernel/xboxkrnl_private.h>
|
||||
#include <xenia/kernel/objects/xevent.h>
|
||||
#include <xenia/kernel/objects/xmutant.h>
|
||||
#include <xenia/kernel/objects/xsemaphore.h>
|
||||
#include <xenia/kernel/objects/xthread.h>
|
||||
#include <xenia/kernel/util/shim_utils.h>
|
||||
|
@ -885,6 +886,65 @@ SHIM_CALL NtReleaseSemaphore_shim(
|
|||
}
|
||||
|
||||
|
||||
SHIM_CALL NtCreateMutant_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t handle_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t obj_attributes_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t initial_owner = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD(
|
||||
"NtCreateMutant(%.8X, %.8X, %.1X)",
|
||||
handle_ptr, obj_attributes_ptr, initial_owner);
|
||||
|
||||
XMutant* mutant = new XMutant(state);
|
||||
mutant->Initialize(initial_owner ? true : false);
|
||||
|
||||
// obj_attributes may have a name inside of it, if != NULL.
|
||||
if (obj_attributes_ptr) {
|
||||
//mutant->SetName(...);
|
||||
}
|
||||
|
||||
if (handle_ptr) {
|
||||
SHIM_SET_MEM_32(handle_ptr, mutant->handle());
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN(X_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
SHIM_CALL NtReleaseMutant_shim(
|
||||
PPCContext* ppc_state, KernelState* state) {
|
||||
uint32_t mutant_handle = SHIM_GET_ARG_32(0);
|
||||
int32_t unknown = SHIM_GET_ARG_32(1);
|
||||
// This doesn't seem to be supported.
|
||||
//int32_t previous_count_ptr = SHIM_GET_ARG_32(2);
|
||||
|
||||
// Whatever arg 1 is all games seem to set it to 0, so whether it's
|
||||
// abandon or wait we just say false. Which is good, cause they are
|
||||
// both ignored.
|
||||
XEASSERTZERO(unknown);
|
||||
uint32_t priority_increment = 0;
|
||||
bool abandon = false;
|
||||
bool wait = false;
|
||||
|
||||
XELOGD(
|
||||
"NtReleaseMutant(%.8X, %8.X)",
|
||||
mutant_handle, unknown);
|
||||
|
||||
X_STATUS result = X_STATUS_SUCCESS;
|
||||
|
||||
XMutant* mutant = NULL;
|
||||
result = state->object_table()->GetObject(
|
||||
mutant_handle, (XObject**)&mutant);
|
||||
if (XSUCCEEDED(result)) {
|
||||
result = mutant->ReleaseMutant(priority_increment, abandon, wait);
|
||||
mutant->Release();
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN(result);
|
||||
}
|
||||
|
||||
|
||||
X_STATUS xeKeWaitForSingleObject(
|
||||
void* object_ptr, uint32_t wait_reason, uint32_t processor_mode,
|
||||
uint32_t alertable, uint64_t* opt_timeout) {
|
||||
|
@ -1145,6 +1205,9 @@ void xe::kernel::xboxkrnl::RegisterThreadingExports(
|
|||
SHIM_SET_MAPPING("xboxkrnl.exe", KeReleaseSemaphore, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtReleaseSemaphore, state);
|
||||
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtCreateMutant, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtReleaseMutant, state);
|
||||
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeWaitForSingleObject, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtWaitForSingleObjectEx, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeWaitForMultipleObjects, state);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <xenia/kernel/xboxkrnl_private.h>
|
||||
#include <xenia/kernel/objects/xevent.h>
|
||||
#include <xenia/kernel/objects/xmutant.h>
|
||||
#include <xenia/kernel/objects/xsemaphore.h>
|
||||
|
||||
|
||||
|
@ -225,6 +226,13 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
|||
object = ev;
|
||||
}
|
||||
break;
|
||||
case 2: // MutantObjectt
|
||||
{
|
||||
XMutant* mutant = new XMutant(kernel_state);
|
||||
mutant->InitializeNative(native_ptr, header);
|
||||
object = mutant;
|
||||
}
|
||||
break;
|
||||
case 5: // SemaphoreObject
|
||||
{
|
||||
XSemaphore* sem = new XSemaphore(kernel_state);
|
||||
|
@ -232,7 +240,6 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
|||
object = sem;
|
||||
}
|
||||
break;
|
||||
case 2: // MutantObject
|
||||
case 3: // ProcessObject
|
||||
case 4: // QueueObject
|
||||
case 6: // ThreadObject
|
||||
|
|
|
@ -37,6 +37,7 @@ public:
|
|||
kTypeFile,
|
||||
kTypeSemaphore,
|
||||
kTypeNotifyListener,
|
||||
kTypeMutant,
|
||||
};
|
||||
|
||||
XObject(KernelState* kernel_state, Type type);
|
||||
|
|
|
@ -45,6 +45,7 @@ typedef uint32_t X_STATUS;
|
|||
#define X_STATUS_BUFFER_TOO_SMALL ((uint32_t)0xC0000023L)
|
||||
#define X_STATUS_OBJECT_TYPE_MISMATCH ((uint32_t)0xC0000024L)
|
||||
#define X_STATUS_INVALID_PAGE_PROTECTION ((uint32_t)0xC0000045L)
|
||||
#define X_STATUS_MUTANT_NOT_OWNED ((uint32_t)0xC0000046L)
|
||||
#define X_STATUS_MEMORY_NOT_ALLOCATED ((uint32_t)0xC00000A0L)
|
||||
#define X_STATUS_INVALID_PARAMETER_1 ((uint32_t)0xC00000EFL)
|
||||
#define X_STATUS_INVALID_PARAMETER_2 ((uint32_t)0xC00000F0L)
|
||||
|
|
Loading…
Reference in New Issue