Switching a few types to their platform-agnostic versions.
This commit is contained in:
parent
91ae97e558
commit
fefaa31cd8
|
@ -106,8 +106,8 @@ void AudioSystem::WorkerThreadMain() {
|
||||||
|
|
||||||
// Main run loop.
|
// Main run loop.
|
||||||
while (worker_running_) {
|
while (worker_running_) {
|
||||||
auto result = xe::threading::WaitAny(
|
auto result =
|
||||||
wait_handles_, DWORD(xe::countof(wait_handles_)), true);
|
xe::threading::WaitAny(wait_handles_, xe::countof(wait_handles_), true);
|
||||||
if (result.first == xe::threading::WaitResult::kFailed ||
|
if (result.first == xe::threading::WaitResult::kFailed ||
|
||||||
(result.first == xe::threading::WaitResult::kSuccess &&
|
(result.first == xe::threading::WaitResult::kSuccess &&
|
||||||
result.second == kMaximumClientCount)) {
|
result.second == kMaximumClientCount)) {
|
||||||
|
|
|
@ -48,6 +48,10 @@ class Fence {
|
||||||
// Returns the total number of logical processors in the host system.
|
// Returns the total number of logical processors in the host system.
|
||||||
uint32_t logical_processor_count();
|
uint32_t logical_processor_count();
|
||||||
|
|
||||||
|
// Enables the current process to set thread affinity.
|
||||||
|
// Must be called at startup before attempting to set thread affinity.
|
||||||
|
void EnableAffinityConfiguration();
|
||||||
|
|
||||||
// Gets a stable thread-specific ID, but may not be. Use for informative
|
// Gets a stable thread-specific ID, but may not be. Use for informative
|
||||||
// purposes only.
|
// purposes only.
|
||||||
uint32_t current_thread_id();
|
uint32_t current_thread_id();
|
||||||
|
|
|
@ -26,6 +26,15 @@ uint32_t logical_processor_count() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnableAffinityConfiguration() {
|
||||||
|
HANDLE process_handle = GetCurrentProcess();
|
||||||
|
DWORD_PTR process_affinity_mask;
|
||||||
|
DWORD_PTR system_affinity_mask;
|
||||||
|
GetProcessAffinityMask(process_handle, &process_affinity_mask,
|
||||||
|
&system_affinity_mask);
|
||||||
|
SetProcessAffinityMask(process_handle, system_affinity_mask);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t current_thread_id() {
|
uint32_t current_thread_id() {
|
||||||
return static_cast<uint32_t>(GetCurrentThreadId());
|
return static_cast<uint32_t>(GetCurrentThreadId());
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,19 +7,22 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <gflags/gflags.h>
|
||||||
|
|
||||||
|
#include "xenia/base/filesystem.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/main.h"
|
#include "xenia/base/main.h"
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
|
#include "xenia/base/platform.h"
|
||||||
#include "xenia/cpu/backend/x64/x64_backend.h"
|
#include "xenia/cpu/backend/x64/x64_backend.h"
|
||||||
#include "xenia/cpu/frontend/ppc_context.h"
|
#include "xenia/cpu/frontend/ppc_context.h"
|
||||||
#include "xenia/cpu/frontend/ppc_frontend.h"
|
#include "xenia/cpu/frontend/ppc_frontend.h"
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
#include "xenia/cpu/raw_module.h"
|
#include "xenia/cpu/raw_module.h"
|
||||||
|
|
||||||
#if !XE_PLATFORM_WIN32
|
#if XE_COMPILER_MSVC
|
||||||
#include <dirent.h>
|
#include "xenia/base/platform_win.h"
|
||||||
#endif // !WIN32
|
#endif // XE_COMPILER_MSVC
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
DEFINE_string(test_path, "src/xenia/cpu/frontend/test/",
|
DEFINE_string(test_path, "src/xenia/cpu/frontend/test/",
|
||||||
"Directory scanned for test files.");
|
"Directory scanned for test files.");
|
||||||
|
@ -331,69 +334,30 @@ class TestRunner {
|
||||||
|
|
||||||
bool DiscoverTests(std::wstring& test_path,
|
bool DiscoverTests(std::wstring& test_path,
|
||||||
std::vector<std::wstring>& test_files) {
|
std::vector<std::wstring>& test_files) {
|
||||||
// TODO(benvanik): use PAL instead of this.
|
auto file_infos = xe::filesystem::ListFiles(test_path);
|
||||||
#if XE_PLATFORM_WIN32
|
for (auto& file_info : file_infos) {
|
||||||
std::wstring search_path = test_path;
|
if (file_info.name.rfind(L".s") == file_info.name.size() - 2) {
|
||||||
search_path.append(L"\\*.s");
|
test_files.push_back(xe::join_paths(test_path, file_info.name));
|
||||||
WIN32_FIND_DATA ffd;
|
|
||||||
HANDLE hFind = FindFirstFile(search_path.c_str(), &ffd);
|
|
||||||
if (hFind == INVALID_HANDLE_VALUE) {
|
|
||||||
XELOGE("Unable to find test path %ls", test_path.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
|
||||||
std::wstring file_name(ffd.cFileName);
|
|
||||||
std::wstring file_path = test_path;
|
|
||||||
if (*(test_path.end() - 1) != '\\') {
|
|
||||||
file_path += '\\';
|
|
||||||
}
|
|
||||||
file_path += file_name;
|
|
||||||
test_files.push_back(file_path);
|
|
||||||
}
|
|
||||||
} while (FindNextFile(hFind, &ffd));
|
|
||||||
FindClose(hFind);
|
|
||||||
#else
|
|
||||||
DIR* d = opendir(test_path.c_str());
|
|
||||||
if (!d) {
|
|
||||||
XELOGE("Unable to find test path %ls", test_path.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
struct dirent* dir;
|
|
||||||
while ((dir = readdir(d))) {
|
|
||||||
if (dir->d_type == DT_REG) {
|
|
||||||
// Only return .s files.
|
|
||||||
string file_name = string(dir->d_name);
|
|
||||||
if (file_name.rfind(".s") != string::npos) {
|
|
||||||
string file_path = test_path;
|
|
||||||
if (*(test_path.end() - 1) != '/') {
|
|
||||||
file_path += "/";
|
|
||||||
}
|
|
||||||
file_path += file_name;
|
|
||||||
test_files.push_back(file_path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(d);
|
|
||||||
#endif // WIN32
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#if XE_COMPILER_MSVC
|
||||||
int filter(unsigned int code) {
|
int filter(unsigned int code) {
|
||||||
if (code == EXCEPTION_ILLEGAL_INSTRUCTION) {
|
if (code == EXCEPTION_ILLEGAL_INSTRUCTION) {
|
||||||
return EXCEPTION_EXECUTE_HANDLER;
|
return EXCEPTION_EXECUTE_HANDLER;
|
||||||
}
|
}
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // XE_COMPILER_MSVC
|
||||||
|
|
||||||
void ProtectedRunTest(TestSuite& test_suite, TestRunner& runner,
|
void ProtectedRunTest(TestSuite& test_suite, TestRunner& runner,
|
||||||
TestCase& test_case, int& failed_count,
|
TestCase& test_case, int& failed_count,
|
||||||
int& passed_count) {
|
int& passed_count) {
|
||||||
#ifdef _MSC_VER
|
#if XE_COMPILER_MSVC
|
||||||
__try {
|
__try {
|
||||||
#endif
|
#endif // XE_COMPILER_MSVC
|
||||||
|
|
||||||
if (!runner.Setup(test_suite)) {
|
if (!runner.Setup(test_suite)) {
|
||||||
XELOGE(" TEST FAILED SETUP");
|
XELOGE(" TEST FAILED SETUP");
|
||||||
|
@ -406,13 +370,13 @@ void ProtectedRunTest(TestSuite& test_suite, TestRunner& runner,
|
||||||
++failed_count;
|
++failed_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#if XE_COMPILER_MSVC
|
||||||
}
|
}
|
||||||
__except(filter(GetExceptionCode())) {
|
__except(filter(GetExceptionCode())) {
|
||||||
XELOGE(" TEST FAILED (UNSUPPORTED INSTRUCTION)");
|
XELOGE(" TEST FAILED (UNSUPPORTED INSTRUCTION)");
|
||||||
++failed_count;
|
++failed_count;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // XE_COMPILER_MSVC
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RunTests(const std::wstring& test_name) {
|
bool RunTests(const std::wstring& test_name) {
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
#include "xenia/debug/debugger.h"
|
#include "xenia/debug/debugger.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
|
|
||||||
|
// TODO(benvanik): generic socket implementation in base/.
|
||||||
|
#include "xenia/base/platform_win.h"
|
||||||
#include <mstcpip.h>
|
#include <mstcpip.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
|
|
@ -84,12 +84,7 @@ X_STATUS Emulator::Setup(ui::Window* display_window) {
|
||||||
|
|
||||||
// Before we can set thread affinity we must enable the process to use all
|
// Before we can set thread affinity we must enable the process to use all
|
||||||
// logical processors.
|
// logical processors.
|
||||||
HANDLE process_handle = GetCurrentProcess();
|
xe::threading::EnableAffinityConfiguration();
|
||||||
DWORD_PTR process_affinity_mask;
|
|
||||||
DWORD_PTR system_affinity_mask;
|
|
||||||
GetProcessAffinityMask(process_handle, &process_affinity_mask,
|
|
||||||
&system_affinity_mask);
|
|
||||||
SetProcessAffinityMask(process_handle, system_affinity_mask);
|
|
||||||
|
|
||||||
// Create memory system first, as it is required for other systems.
|
// Create memory system first, as it is required for other systems.
|
||||||
memory_ = std::make_unique<Memory>();
|
memory_ = std::make_unique<Memory>();
|
||||||
|
|
|
@ -63,7 +63,7 @@ CommandProcessor::CommandProcessor(GL4GraphicsSystem* graphics_system)
|
||||||
read_ptr_index_(0),
|
read_ptr_index_(0),
|
||||||
read_ptr_update_freq_(0),
|
read_ptr_update_freq_(0),
|
||||||
read_ptr_writeback_ptr_(0),
|
read_ptr_writeback_ptr_(0),
|
||||||
write_ptr_index_event_(CreateEvent(NULL, FALSE, FALSE, NULL)),
|
write_ptr_index_event_(xe::threading::Event::CreateAutoResetEvent(false)),
|
||||||
write_ptr_index_(0),
|
write_ptr_index_(0),
|
||||||
bin_select_(0xFFFFFFFFull),
|
bin_select_(0xFFFFFFFFull),
|
||||||
bin_mask_(0xFFFFFFFFull),
|
bin_mask_(0xFFFFFFFFull),
|
||||||
|
@ -78,7 +78,7 @@ CommandProcessor::CommandProcessor(GL4GraphicsSystem* graphics_system)
|
||||||
draw_batcher_(graphics_system_->register_file()),
|
draw_batcher_(graphics_system_->register_file()),
|
||||||
scratch_buffer_(kScratchBufferCapacity, kScratchBufferAlignment) {}
|
scratch_buffer_(kScratchBufferCapacity, kScratchBufferAlignment) {}
|
||||||
|
|
||||||
CommandProcessor::~CommandProcessor() { CloseHandle(write_ptr_index_event_); }
|
CommandProcessor::~CommandProcessor() = default;
|
||||||
|
|
||||||
bool CommandProcessor::Initialize(
|
bool CommandProcessor::Initialize(
|
||||||
std::unique_ptr<xe::ui::GraphicsContext> context) {
|
std::unique_ptr<xe::ui::GraphicsContext> context) {
|
||||||
|
@ -101,7 +101,7 @@ void CommandProcessor::Shutdown() {
|
||||||
EndTracing();
|
EndTracing();
|
||||||
|
|
||||||
worker_running_ = false;
|
worker_running_ = false;
|
||||||
SetEvent(write_ptr_index_event_);
|
write_ptr_index_event_->Set();
|
||||||
worker_thread_->Wait(0, 0, 0, nullptr);
|
worker_thread_->Wait(0, 0, 0, nullptr);
|
||||||
worker_thread_.reset();
|
worker_thread_.reset();
|
||||||
|
|
||||||
|
@ -200,7 +200,8 @@ void CommandProcessor::WorkerThreadMain() {
|
||||||
// TODO(benvanik): if we go longer than Nms, switch to waiting?
|
// TODO(benvanik): if we go longer than Nms, switch to waiting?
|
||||||
// It'll keep us from burning power.
|
// It'll keep us from burning power.
|
||||||
// const int wait_time_ms = 5;
|
// const int wait_time_ms = 5;
|
||||||
// WaitForSingleObject(write_ptr_index_event_, wait_time_ms);
|
// xe::threading::Wait(write_ptr_index_event_.get(), true,
|
||||||
|
// std::chrono::milliseconds(wait_time_ms));
|
||||||
xe::threading::MaybeYield();
|
xe::threading::MaybeYield();
|
||||||
write_ptr_index = write_ptr_index_.load();
|
write_ptr_index = write_ptr_index_.load();
|
||||||
} while (worker_running_ && pending_fns_.empty() &&
|
} while (worker_running_ && pending_fns_.empty() &&
|
||||||
|
@ -488,7 +489,7 @@ void CommandProcessor::EnableReadPointerWriteBack(uint32_t ptr,
|
||||||
|
|
||||||
void CommandProcessor::UpdateWritePointer(uint32_t value) {
|
void CommandProcessor::UpdateWritePointer(uint32_t value) {
|
||||||
write_ptr_index_ = value;
|
write_ptr_index_ = value;
|
||||||
SetEvent(write_ptr_index_event_);
|
write_ptr_index_event_->Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandProcessor::WriteRegister(uint32_t index, uint32_t value) {
|
void CommandProcessor::WriteRegister(uint32_t index, uint32_t value) {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "xenia/base/threading.h"
|
||||||
#include "xenia/gpu/gl4/draw_batcher.h"
|
#include "xenia/gpu/gl4/draw_batcher.h"
|
||||||
#include "xenia/gpu/gl4/gl4_shader.h"
|
#include "xenia/gpu/gl4/gl4_shader.h"
|
||||||
#include "xenia/gpu/gl4/gl4_shader_translator.h"
|
#include "xenia/gpu/gl4/gl4_shader_translator.h"
|
||||||
|
@ -259,7 +260,7 @@ class CommandProcessor {
|
||||||
uint32_t read_ptr_update_freq_;
|
uint32_t read_ptr_update_freq_;
|
||||||
uint32_t read_ptr_writeback_ptr_;
|
uint32_t read_ptr_writeback_ptr_;
|
||||||
|
|
||||||
HANDLE write_ptr_index_event_;
|
std::unique_ptr<xe::threading::Event> write_ptr_index_event_;
|
||||||
std::atomic<uint32_t> write_ptr_index_;
|
std::atomic<uint32_t> write_ptr_index_;
|
||||||
|
|
||||||
uint64_t bin_select_;
|
uint64_t bin_select_;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "xenia/base/main.h"
|
#include "xenia/base/main.h"
|
||||||
#include "xenia/base/mapped_memory.h"
|
#include "xenia/base/mapped_memory.h"
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
|
#include "xenia/base/platform_win.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
#include "xenia/gpu/graphics_system.h"
|
#include "xenia/gpu/graphics_system.h"
|
||||||
#include "xenia/gpu/register_file.h"
|
#include "xenia/gpu/register_file.h"
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
#include "xenia/kernel/xobject.h"
|
#include "xenia/kernel/xobject.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
typedef void* HANDLE;
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
|
#include "xenia/base/platform_win.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
#include "xenia/kernel/util/shim_utils.h"
|
#include "xenia/kernel/util/shim_utils.h"
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
|
#include "xenia/base/platform_win.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
#include "xenia/kernel/xboxkrnl_private.h"
|
#include "xenia/kernel/xboxkrnl_private.h"
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
// All of the exported functions:
|
// All of the exported functions:
|
||||||
#include "xenia/kernel/xboxkrnl_rtl.h"
|
#include "xenia/kernel/xboxkrnl_rtl.h"
|
||||||
|
|
||||||
|
// TODO(benvanik): switch timer.
|
||||||
|
typedef void* HANDLE;
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/mutex.h"
|
#include "xenia/base/mutex.h"
|
||||||
|
#include "xenia/base/platform_win.h"
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
#include "xenia/kernel/dispatcher.h"
|
#include "xenia/kernel/dispatcher.h"
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
|
@ -446,7 +447,7 @@ SHIM_CALL KeTlsSetValue_shim(PPCContext* ppc_context,
|
||||||
|
|
||||||
#if XE_PLATFORM_WIN32
|
#if XE_PLATFORM_WIN32
|
||||||
result = TlsSetValue(
|
result = TlsSetValue(
|
||||||
tls_index, reinterpret_cast<LPVOID>(static_cast<uintptr_t>(tls_value)));
|
tls_index, reinterpret_cast<void*>(static_cast<uintptr_t>(tls_value)));
|
||||||
#else
|
#else
|
||||||
result = pthread_setspecific(tls_index, (void*)tls_value) == 0;
|
result = pthread_setspecific(tls_index, (void*)tls_value) == 0;
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
@ -1031,7 +1032,7 @@ SHIM_CALL KfAcquireSpinLock_shim(PPCContext* ppc_context,
|
||||||
while (!xe::atomic_cas(0, 1, lock)) {
|
while (!xe::atomic_cas(0, 1, lock)) {
|
||||||
// Spin!
|
// Spin!
|
||||||
// TODO(benvanik): error on deadlock?
|
// TODO(benvanik): error on deadlock?
|
||||||
YieldProcessor();
|
xe::threading::MaybeYield();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Raise IRQL to DISPATCH.
|
// Raise IRQL to DISPATCH.
|
||||||
|
|
Loading…
Reference in New Issue