Shuffling kernel util types to util/.
This commit is contained in:
parent
068b2056ca
commit
8588fbc6cf
|
@ -61,8 +61,6 @@ KernelState::KernelState(Emulator* emulator)
|
||||||
content_root = xe::to_absolute_path(content_root);
|
content_root = xe::to_absolute_path(content_root);
|
||||||
content_manager_ = std::make_unique<ContentManager>(this, content_root);
|
content_manager_ = std::make_unique<ContentManager>(this, content_root);
|
||||||
|
|
||||||
object_table_ = new ObjectTable();
|
|
||||||
|
|
||||||
assert_null(shared_kernel_state_);
|
assert_null(shared_kernel_state_);
|
||||||
shared_kernel_state_ = this;
|
shared_kernel_state_ = this;
|
||||||
|
|
||||||
|
@ -98,7 +96,7 @@ KernelState::~KernelState() {
|
||||||
kernel_modules_.clear();
|
kernel_modules_.clear();
|
||||||
|
|
||||||
// Delete all objects.
|
// Delete all objects.
|
||||||
delete object_table_;
|
object_table_.Reset();
|
||||||
|
|
||||||
// Shutdown apps.
|
// Shutdown apps.
|
||||||
app_manager_.reset();
|
app_manager_.reset();
|
||||||
|
@ -372,7 +370,7 @@ void KernelState::TerminateTitle(bool from_guest_thread) {
|
||||||
X_STATUS status = user_modules_[i]->Unload();
|
X_STATUS status = user_modules_[i]->Unload();
|
||||||
assert_true(XSUCCEEDED(status));
|
assert_true(XSUCCEEDED(status));
|
||||||
|
|
||||||
object_table_->RemoveHandle(user_modules_[i]->handle());
|
object_table_.RemoveHandle(user_modules_[i]->handle());
|
||||||
}
|
}
|
||||||
user_modules_.clear();
|
user_modules_.clear();
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
#include "xenia/cpu/export_resolver.h"
|
#include "xenia/cpu/export_resolver.h"
|
||||||
#include "xenia/kernel/app.h"
|
#include "xenia/kernel/app.h"
|
||||||
#include "xenia/kernel/content_manager.h"
|
#include "xenia/kernel/content_manager.h"
|
||||||
#include "xenia/kernel/native_list.h"
|
|
||||||
#include "xenia/kernel/object_table.h"
|
|
||||||
#include "xenia/kernel/user_profile.h"
|
#include "xenia/kernel/user_profile.h"
|
||||||
|
#include "xenia/kernel/util/native_list.h"
|
||||||
|
#include "xenia/kernel/util/object_table.h"
|
||||||
#include "xenia/memory.h"
|
#include "xenia/memory.h"
|
||||||
#include "xenia/vfs/virtual_file_system.h"
|
#include "xenia/vfs/virtual_file_system.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
@ -104,7 +104,7 @@ class KernelState {
|
||||||
ContentManager* content_manager() const { return content_manager_.get(); }
|
ContentManager* content_manager() const { return content_manager_.get(); }
|
||||||
|
|
||||||
// Access must be guarded by the global critical region.
|
// Access must be guarded by the global critical region.
|
||||||
ObjectTable* object_table() const { return object_table_; }
|
util::ObjectTable* object_table() { return &object_table_; }
|
||||||
|
|
||||||
uint32_t process_type() const;
|
uint32_t process_type() const;
|
||||||
void set_process_type(uint32_t value);
|
void set_process_type(uint32_t value);
|
||||||
|
@ -150,7 +150,7 @@ class KernelState {
|
||||||
void UnregisterNotifyListener(XNotifyListener* listener);
|
void UnregisterNotifyListener(XNotifyListener* listener);
|
||||||
void BroadcastNotification(XNotificationID id, uint32_t data);
|
void BroadcastNotification(XNotificationID id, uint32_t data);
|
||||||
|
|
||||||
NativeList* dpc_list() { return &dpc_list_; }
|
util::NativeList* dpc_list() { return &dpc_list_; }
|
||||||
|
|
||||||
void CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result);
|
void CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result);
|
||||||
void CompleteOverlappedEx(uint32_t overlapped_ptr, X_RESULT result,
|
void CompleteOverlappedEx(uint32_t overlapped_ptr, X_RESULT result,
|
||||||
|
@ -179,7 +179,7 @@ class KernelState {
|
||||||
xe::global_critical_region global_critical_region_;
|
xe::global_critical_region global_critical_region_;
|
||||||
|
|
||||||
// Must be guarded by the global critical region.
|
// Must be guarded by the global critical region.
|
||||||
ObjectTable* object_table_ = nullptr;
|
util::ObjectTable object_table_;
|
||||||
std::unordered_map<uint32_t, XThread*> threads_by_id_;
|
std::unordered_map<uint32_t, XThread*> threads_by_id_;
|
||||||
std::vector<object_ref<XNotifyListener>> notify_listeners_;
|
std::vector<object_ref<XNotifyListener>> notify_listeners_;
|
||||||
bool has_notified_startup_ = false;
|
bool has_notified_startup_ = false;
|
||||||
|
@ -195,7 +195,7 @@ class KernelState {
|
||||||
std::atomic<bool> dispatch_thread_running_;
|
std::atomic<bool> dispatch_thread_running_;
|
||||||
object_ref<XHostThread> dispatch_thread_;
|
object_ref<XHostThread> dispatch_thread_;
|
||||||
// Must be guarded by the global critical region.
|
// Must be guarded by the global critical region.
|
||||||
NativeList dpc_list_;
|
util::NativeList dpc_list_;
|
||||||
std::condition_variable_any dispatch_cond_;
|
std::condition_variable_any dispatch_cond_;
|
||||||
std::list<std::function<void()>> dispatch_queue_;
|
std::list<std::function<void()>> dispatch_queue_;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
#include "xenia/kernel/native_list.h"
|
|
||||||
#include "xenia/kernel/objects/xevent.h"
|
#include "xenia/kernel/objects/xevent.h"
|
||||||
#include "xenia/kernel/objects/xuser_module.h"
|
#include "xenia/kernel/objects/xuser_module.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
@ -42,7 +41,8 @@ XThread::XThread(KernelState* kernel_state, uint32_t stack_size,
|
||||||
bool guest_thread)
|
bool guest_thread)
|
||||||
: XObject(kernel_state, kTypeThread),
|
: XObject(kernel_state, kTypeThread),
|
||||||
thread_id_(++next_xthread_id_),
|
thread_id_(++next_xthread_id_),
|
||||||
guest_thread_(guest_thread) {
|
guest_thread_(guest_thread),
|
||||||
|
apc_list_(kernel_state->memory()) {
|
||||||
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;
|
||||||
|
@ -57,8 +57,6 @@ XThread::XThread(KernelState* kernel_state, uint32_t stack_size,
|
||||||
creation_params_.stack_size = 16 * 1024;
|
creation_params_.stack_size = 16 * 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
apc_list_ = new NativeList(kernel_state->memory());
|
|
||||||
|
|
||||||
// The kernel does not take a reference. We must unregister in the dtor.
|
// The kernel does not take a reference. We must unregister in the dtor.
|
||||||
kernel_state_->RegisterThread(this);
|
kernel_state_->RegisterThread(this);
|
||||||
}
|
}
|
||||||
|
@ -71,8 +69,6 @@ XThread::~XThread() {
|
||||||
emulator()->debugger()->OnThreadDestroyed(this);
|
emulator()->debugger()->OnThreadDestroyed(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete apc_list_;
|
|
||||||
|
|
||||||
thread_.reset();
|
thread_.reset();
|
||||||
|
|
||||||
if (thread_state_) {
|
if (thread_state_) {
|
||||||
|
@ -460,7 +456,7 @@ void XThread::CheckApcs() { DeliverAPCs(); }
|
||||||
void XThread::LockApc() { EnterCriticalRegion(); }
|
void XThread::LockApc() { EnterCriticalRegion(); }
|
||||||
|
|
||||||
void XThread::UnlockApc(bool queue_delivery) {
|
void XThread::UnlockApc(bool queue_delivery) {
|
||||||
bool needs_apc = apc_list_->HasPending();
|
bool needs_apc = apc_list_.HasPending();
|
||||||
LeaveCriticalRegion();
|
LeaveCriticalRegion();
|
||||||
if (needs_apc && queue_delivery) {
|
if (needs_apc && queue_delivery) {
|
||||||
thread_->QueueUserCallback([this]() { DeliverAPCs(); });
|
thread_->QueueUserCallback([this]() { DeliverAPCs(); });
|
||||||
|
@ -486,7 +482,7 @@ void XThread::EnqueueApc(uint32_t normal_routine, uint32_t normal_context,
|
||||||
apc->enqueued = 1;
|
apc->enqueued = 1;
|
||||||
|
|
||||||
uint32_t list_entry_ptr = apc_ptr + 8;
|
uint32_t list_entry_ptr = apc_ptr + 8;
|
||||||
apc_list_->Insert(list_entry_ptr);
|
apc_list_.Insert(list_entry_ptr);
|
||||||
|
|
||||||
UnlockApc(true);
|
UnlockApc(true);
|
||||||
}
|
}
|
||||||
|
@ -496,10 +492,10 @@ void XThread::DeliverAPCs() {
|
||||||
// http://www.drdobbs.com/inside-nts-asynchronous-procedure-call/184416590?pgno=7
|
// http://www.drdobbs.com/inside-nts-asynchronous-procedure-call/184416590?pgno=7
|
||||||
auto processor = kernel_state()->processor();
|
auto processor = kernel_state()->processor();
|
||||||
LockApc();
|
LockApc();
|
||||||
while (apc_list_->HasPending()) {
|
while (apc_list_.HasPending()) {
|
||||||
// Get APC entry (offset for LIST_ENTRY offset) and cache what we need.
|
// Get APC entry (offset for LIST_ENTRY offset) and cache what we need.
|
||||||
// Calling the routine may delete the memory/overwrite it.
|
// Calling the routine may delete the memory/overwrite it.
|
||||||
uint32_t apc_ptr = apc_list_->Shift() - 8;
|
uint32_t apc_ptr = apc_list_.Shift() - 8;
|
||||||
auto apc = reinterpret_cast<XAPC*>(memory()->TranslateVirtual(apc_ptr));
|
auto apc = reinterpret_cast<XAPC*>(memory()->TranslateVirtual(apc_ptr));
|
||||||
bool needs_freeing = apc->kernel_routine == XAPC::kDummyKernelRoutine;
|
bool needs_freeing = apc->kernel_routine == XAPC::kDummyKernelRoutine;
|
||||||
|
|
||||||
|
@ -560,10 +556,10 @@ void XThread::DeliverAPCs() {
|
||||||
void XThread::RundownAPCs() {
|
void XThread::RundownAPCs() {
|
||||||
assert_true(XThread::GetCurrentThread() == this);
|
assert_true(XThread::GetCurrentThread() == this);
|
||||||
LockApc();
|
LockApc();
|
||||||
while (apc_list_->HasPending()) {
|
while (apc_list_.HasPending()) {
|
||||||
// Get APC entry (offset for LIST_ENTRY offset) and cache what we need.
|
// Get APC entry (offset for LIST_ENTRY offset) and cache what we need.
|
||||||
// Calling the routine may delete the memory/overwrite it.
|
// Calling the routine may delete the memory/overwrite it.
|
||||||
uint32_t apc_ptr = apc_list_->Shift() - 8;
|
uint32_t apc_ptr = apc_list_.Shift() - 8;
|
||||||
auto apc = reinterpret_cast<XAPC*>(memory()->TranslateVirtual(apc_ptr));
|
auto apc = reinterpret_cast<XAPC*>(memory()->TranslateVirtual(apc_ptr));
|
||||||
bool needs_freeing = apc->kernel_routine == XAPC::kDummyKernelRoutine;
|
bool needs_freeing = apc->kernel_routine == XAPC::kDummyKernelRoutine;
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,13 @@
|
||||||
#include "xenia/base/mutex.h"
|
#include "xenia/base/mutex.h"
|
||||||
#include "xenia/base/threading.h"
|
#include "xenia/base/threading.h"
|
||||||
#include "xenia/cpu/thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
|
#include "xenia/kernel/util/native_list.h"
|
||||||
#include "xenia/kernel/xobject.h"
|
#include "xenia/kernel/xobject.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|
||||||
class NativeList;
|
|
||||||
class XEvent;
|
class XEvent;
|
||||||
|
|
||||||
constexpr uint32_t X_CREATE_SUSPENDED = 0x00000001;
|
constexpr uint32_t X_CREATE_SUSPENDED = 0x00000001;
|
||||||
|
@ -114,7 +114,7 @@ class XThread : public XObject {
|
||||||
XThread(KernelState* kernel_state, uint32_t stack_size,
|
XThread(KernelState* kernel_state, uint32_t stack_size,
|
||||||
uint32_t xapi_thread_startup, uint32_t start_address,
|
uint32_t xapi_thread_startup, uint32_t start_address,
|
||||||
uint32_t start_context, uint32_t creation_flags, bool guest_thread);
|
uint32_t start_context, uint32_t creation_flags, bool guest_thread);
|
||||||
virtual ~XThread();
|
~XThread() override;
|
||||||
|
|
||||||
static bool IsInThread(XThread* other);
|
static bool IsInThread(XThread* other);
|
||||||
static bool IsInThread();
|
static bool IsInThread();
|
||||||
|
@ -149,7 +149,7 @@ class XThread : public XObject {
|
||||||
void CheckApcs();
|
void CheckApcs();
|
||||||
void LockApc();
|
void LockApc();
|
||||||
void UnlockApc(bool queue_delivery);
|
void UnlockApc(bool queue_delivery);
|
||||||
NativeList* apc_list() const { return apc_list_; }
|
util::NativeList* apc_list() { return &apc_list_; }
|
||||||
void EnqueueApc(uint32_t normal_routine, uint32_t normal_context,
|
void EnqueueApc(uint32_t normal_routine, uint32_t normal_context,
|
||||||
uint32_t arg1, uint32_t arg2);
|
uint32_t arg1, uint32_t arg2);
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ class XThread : public XObject {
|
||||||
|
|
||||||
xe::global_critical_region global_critical_region_;
|
xe::global_critical_region global_critical_region_;
|
||||||
std::atomic<uint32_t> irql_ = {0};
|
std::atomic<uint32_t> irql_ = {0};
|
||||||
NativeList* apc_list_ = nullptr;
|
util::NativeList apc_list_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class XHostThread : public XThread {
|
class XHostThread : public XThread {
|
||||||
|
|
|
@ -7,10 +7,11 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/kernel/native_list.h"
|
#include "xenia/kernel/util/native_list.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
namespace util {
|
||||||
|
|
||||||
NativeList::NativeList(Memory* memory)
|
NativeList::NativeList(Memory* memory)
|
||||||
: memory_(memory), head_(kInvalidPointer) {}
|
: memory_(memory), head_(kInvalidPointer) {}
|
||||||
|
@ -66,5 +67,6 @@ uint32_t NativeList::Shift() {
|
||||||
|
|
||||||
bool NativeList::HasPending() { return head_ != kInvalidPointer; }
|
bool NativeList::HasPending() { return head_ != kInvalidPointer; }
|
||||||
|
|
||||||
|
} // namespace util
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
|
@ -7,14 +7,15 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_KERNEL_NATIVE_LIST_H_
|
#ifndef XENIA_KERNEL_UTIL_NATIVE_LIST_H_
|
||||||
#define XENIA_KERNEL_NATIVE_LIST_H_
|
#define XENIA_KERNEL_UTIL_NATIVE_LIST_H_
|
||||||
|
|
||||||
#include "xenia/memory.h"
|
#include "xenia/memory.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
namespace util {
|
||||||
|
|
||||||
// List is designed for storing pointers to objects in the guest heap.
|
// List is designed for storing pointers to objects in the guest heap.
|
||||||
// All values in the list should be assumed to be in big endian.
|
// All values in the list should be assumed to be in big endian.
|
||||||
|
@ -44,7 +45,8 @@ class NativeList {
|
||||||
uint32_t head_;
|
uint32_t head_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace util
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_KERNEL_NATIVE_LIST_H_
|
#endif // XENIA_KERNEL_UTIL_NATIVE_LIST_H_
|
|
@ -7,7 +7,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/kernel/object_table.h"
|
#include "xenia/kernel/util/object_table.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -17,11 +17,13 @@
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
namespace util {
|
||||||
|
|
||||||
ObjectTable::ObjectTable()
|
ObjectTable::ObjectTable() {}
|
||||||
: table_capacity_(0), table_(nullptr), last_free_entry_(0) {}
|
|
||||||
|
|
||||||
ObjectTable::~ObjectTable() {
|
ObjectTable::~ObjectTable() { Reset(); }
|
||||||
|
|
||||||
|
void ObjectTable::Reset() {
|
||||||
auto global_lock = global_critical_region_.Acquire();
|
auto global_lock = global_critical_region_.Acquire();
|
||||||
|
|
||||||
// Release all objects.
|
// Release all objects.
|
||||||
|
@ -313,5 +315,6 @@ X_STATUS ObjectTable::GetObjectByName(const std::string& name,
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace util
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
|
@ -7,8 +7,8 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_KERNEL_OBJECT_TABLE_H_
|
#ifndef XENIA_KERNEL_UTIL_OBJECT_TABLE_H_
|
||||||
#define XENIA_KERNEL_OBJECT_TABLE_H_
|
#define XENIA_KERNEL_UTIL_OBJECT_TABLE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -20,12 +20,15 @@
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
namespace util {
|
||||||
|
|
||||||
class ObjectTable {
|
class ObjectTable {
|
||||||
public:
|
public:
|
||||||
ObjectTable();
|
ObjectTable();
|
||||||
~ObjectTable();
|
~ObjectTable();
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
X_STATUS AddHandle(XObject* object, X_HANDLE* out_handle);
|
X_STATUS AddHandle(XObject* object, X_HANDLE* out_handle);
|
||||||
X_STATUS DuplicateHandle(X_HANDLE orig, X_HANDLE* out_handle);
|
X_STATUS DuplicateHandle(X_HANDLE orig, X_HANDLE* out_handle);
|
||||||
X_STATUS RetainHandle(X_HANDLE handle);
|
X_STATUS RetainHandle(X_HANDLE handle);
|
||||||
|
@ -65,13 +68,14 @@ class ObjectTable {
|
||||||
X_STATUS FindFreeSlot(uint32_t* out_slot);
|
X_STATUS FindFreeSlot(uint32_t* out_slot);
|
||||||
|
|
||||||
xe::global_critical_region global_critical_region_;
|
xe::global_critical_region global_critical_region_;
|
||||||
uint32_t table_capacity_;
|
uint32_t table_capacity_ = 0;
|
||||||
ObjectTableEntry* table_;
|
ObjectTableEntry* table_ = nullptr;
|
||||||
uint32_t last_free_entry_;
|
uint32_t last_free_entry_ = 0;
|
||||||
std::unordered_map<std::string, X_HANDLE> name_table_;
|
std::unordered_map<std::string, X_HANDLE> name_table_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace util
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_KERNEL_OBJECT_TABLE_H_
|
#endif // XENIA_KERNEL_UTIL_OBJECT_TABLE_H_
|
|
@ -13,7 +13,6 @@
|
||||||
#include "xenia/base/mutex.h"
|
#include "xenia/base/mutex.h"
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
#include "xenia/kernel/native_list.h"
|
|
||||||
#include "xenia/kernel/objects/xevent.h"
|
#include "xenia/kernel/objects/xevent.h"
|
||||||
#include "xenia/kernel/objects/xmutant.h"
|
#include "xenia/kernel/objects/xmutant.h"
|
||||||
#include "xenia/kernel/objects/xsemaphore.h"
|
#include "xenia/kernel/objects/xsemaphore.h"
|
||||||
|
|
Loading…
Reference in New Issue