[Kernel] Improvements to host and guest objects handling

This commit is contained in:
Gliniak 2023-01-05 22:51:18 +01:00 committed by Radosław Gliński
parent 5b0fe5aada
commit 40f6b5b3ac
4 changed files with 23 additions and 18 deletions

View File

@ -132,7 +132,13 @@ X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) {
entry.object = object;
entry.handle_ref_count = 1;
handle = slot << 2;
if (!host_object) handle += XObject::kHandleBase;
if (!host_object) {
if (object->type() != XObject::Type::Socket) {
handle += XObject::kHandleBase;
}
} else {
handle += XObject::kHandleHostBase;
}
object->handles().push_back(handle);
// Retain so long as the object is in the table.
@ -286,10 +292,9 @@ ObjectTable::ObjectTableEntry* ObjectTable::LookupTableInLock(X_HANDLE handle) {
return nullptr;
}
// Lower 2 bits are ignored.
bool host = (handle < XObject::kHandleBase);
uint32_t slot = GetHandleSlot(handle, host);
if (host) {
const bool is_host_object = XObject::is_handle_host_object(handle);
uint32_t slot = GetHandleSlot(handle, is_host_object);
if (is_host_object) {
if (slot <= host_table_capacity_) {
return &host_table_[slot];
}
@ -320,12 +325,11 @@ XObject* ObjectTable::LookupObject(X_HANDLE handle, bool already_locked) {
global_critical_region_.mutex().lock();
}
// Lower 2 bits are ignored.
bool host = (handle < XObject::kHandleBase);
uint32_t slot = GetHandleSlot(handle, host);
const bool is_host_object = XObject::is_handle_host_object(handle);
uint32_t slot = GetHandleSlot(handle, is_host_object);
// Verify slot.
if (host) {
if (is_host_object) {
if (slot < host_table_capacity_) {
ObjectTableEntry& entry = host_table_[slot];
if (entry.object) {
@ -461,13 +465,13 @@ bool ObjectTable::Restore(ByteStream* stream) {
}
X_STATUS ObjectTable::RestoreHandle(X_HANDLE handle, XObject* object) {
bool host = (handle < XObject::kHandleBase);
uint32_t slot = GetHandleSlot(handle, host);
uint32_t capacity = host ? host_table_capacity_ : table_capacity_;
const bool is_host_object = XObject::is_handle_host_object(handle);
uint32_t slot = GetHandleSlot(handle, is_host_object);
uint32_t capacity = is_host_object ? host_table_capacity_ : table_capacity_;
assert_true(capacity >= slot);
if (capacity >= slot) {
auto& entry = host ? host_table_[slot] : table_[slot];
auto& entry = is_host_object ? host_table_[slot] : table_[slot];
entry.object = object;
object->Retain();
}

View File

@ -49,9 +49,6 @@ class ObjectTable {
X_STATUS RestoreHandle(X_HANDLE handle, XObject* object);
template <typename T>
object_ref<T> LookupObject(X_HANDLE handle, bool already_locked = false) {
if (T::kObjectType == XObject::Type::Socket) {
handle |= XObject::kHandleBase;
}
auto object = LookupObject(handle, already_locked);
if (object) {
assert_true(object->type() == T::kObjectType);
@ -96,7 +93,7 @@ class ObjectTable {
X_HANDLE TranslateHandle(X_HANDLE handle);
static constexpr uint32_t GetHandleSlot(X_HANDLE handle, bool host) {
if (!host) handle -= XObject::kHandleBase;
handle &= host ? ~XObject::kHandleHostBase : ~XObject::kHandleBase;
return handle >> 2;
}
X_STATUS FindFreeSlot(uint32_t* out_slot, bool host);

View File

@ -639,7 +639,7 @@ dword_result_t NetDll_socket_entry(dword_t caller, dword_t af, dword_t type,
return -1;
}
return (socket->handle() & 0x00FFFFFF);
return socket->handle();
}
DECLARE_XAM_EXPORT1(NetDll_socket, kNetworking, kImplemented);

View File

@ -117,6 +117,7 @@ class XObject {
// Instead of receiving address that starts with 0x82... we're receiving
// one with 0x8A... which causes crash
static constexpr uint32_t kHandleBase = 0xF8000000;
static constexpr uint32_t kHandleHostBase = 0x01000000;
enum class Type : uint32_t {
Undefined,
@ -175,6 +176,9 @@ class XObject {
static object_ref<XObject> Restore(KernelState* kernel_state, Type type,
ByteStream* stream);
static constexpr bool is_handle_host_object(X_HANDLE handle) {
return handle > XObject::kHandleHostBase && handle < XObject::kHandleBase;
};
// Reference()
// Dereference()