diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index e969fe402..496ffac17 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -29,21 +29,20 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::backend::x64; -using namespace alloy::hir; -using namespace alloy::runtime; +namespace alloy { +namespace backend { +namespace x64 { using namespace Xbyak; +// TODO(benvanik): direct usings. +using namespace alloy::hir; +using namespace alloy::runtime; + // Utilities/types used only in this file: #include -namespace { -static std::unordered_multimap sequence_table; -} // namespace - +std::unordered_multimap sequence_table; // Selects the right byte/word/etc from a vector. We need to flip logical // indices (0,1,2,3,4,5,6,7,...) = (3,2,1,0,7,6,5,4,...) @@ -5121,3 +5120,7 @@ bool alloy::backend::x64::SelectSequence(X64Emitter& e, const Instr* i, const In XELOGE("No sequence match for variant %s", i->opcode->name); return false; } + +} // namespace x64 +} // namespace backend +} // namespace alloy diff --git a/src/alloy/runtime/entry_table.cc b/src/alloy/runtime/entry_table.cc index 4d2bef52a..0277be312 100644 --- a/src/alloy/runtime/entry_table.cc +++ b/src/alloy/runtime/entry_table.cc @@ -48,7 +48,7 @@ Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) { do { lock_.unlock(); // TODO(benvanik): sleep for less time? - Sleep(0); + poly::threading::Sleep(std::chrono::microseconds(100)); lock_.lock(); } while (entry->status == Entry::STATUS_COMPILING); } diff --git a/src/alloy/runtime/module.cc b/src/alloy/runtime/module.cc index f144de2e3..24e27f00c 100644 --- a/src/alloy/runtime/module.cc +++ b/src/alloy/runtime/module.cc @@ -42,7 +42,7 @@ SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) { do { lock_.unlock(); // TODO(benvanik): sleep for less time? - Sleep(0); + poly::threading::Sleep(std::chrono::microseconds(100)); lock_.lock(); } while (symbol_info->status() == SymbolInfo::STATUS_DECLARING); } else { @@ -75,7 +75,7 @@ SymbolInfo::Status Module::DeclareSymbol(SymbolInfo::Type type, do { lock_.unlock(); // TODO(benvanik): sleep for less time? - Sleep(0); + poly::threading::Sleep(std::chrono::microseconds(100)); lock_.lock(); } while (symbol_info->status() == SymbolInfo::STATUS_DECLARING); } @@ -135,7 +135,7 @@ SymbolInfo::Status Module::DefineSymbol(SymbolInfo* symbol_info) { do { lock_.unlock(); // TODO(benvanik): sleep for less time? - Sleep(0); + poly::threading::Sleep(std::chrono::microseconds(100)); lock_.lock(); } while (symbol_info->status() == SymbolInfo::STATUS_DEFINING); status = symbol_info->status(); diff --git a/src/alloy/runtime/thread_state.cc b/src/alloy/runtime/thread_state.cc index cfe153bd6..549d7d2d3 100644 --- a/src/alloy/runtime/thread_state.cc +++ b/src/alloy/runtime/thread_state.cc @@ -26,7 +26,7 @@ ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id) if (thread_id_ == UINT_MAX) { // System thread. Assign the system thread ID with a high bit // set so people know what's up. - uint32_t system_thread_handle = GetCurrentThreadId(); + uint32_t system_thread_handle = poly::threading::current_thread_id(); thread_id_ = 0x80000000 | system_thread_handle; } backend_data_ = runtime->backend()->AllocThreadData(); diff --git a/src/poly/poly.h b/src/poly/poly.h index e9b10a17b..aab80b5e1 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -12,6 +12,7 @@ #include #include +#include namespace poly {} // namespace poly diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index d19d26fdd..2a6f55017 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -6,6 +6,7 @@ 'poly-private.h', 'poly.cc', 'poly.h', + 'threading.h', ], 'conditions': [ @@ -19,10 +20,12 @@ }], ['OS == "mac"', { 'sources': [ + 'threading_mac.cc', ], }], ['OS == "win"', { 'sources': [ + 'threading_win.cc', ], }], ], diff --git a/src/poly/threading.h b/src/poly/threading.h new file mode 100644 index 000000000..06e21c9c8 --- /dev/null +++ b/src/poly/threading.h @@ -0,0 +1,36 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_THREADING_H_ +#define POLY_THREADING_H_ + +#include +#include + +namespace poly { +namespace threading { + +// Gets a stable thread-specific ID, but may not be. Use for informative +// purposes only. +uint32_t current_thread_id(); + +// Yields the current thread to the scheduler. Maybe. +void Yield(); + +// Sleeps the current thread for at least as long as the given duration. +void Sleep(std::chrono::microseconds duration); +template +void Sleep(std::chrono::duration duration) { + Sleep(std::chrono::duration_cast(duration)); +} + +} // namespace threading +} // namespace poly + +#endif // POLY_THREADING_H_ diff --git a/src/poly/threading_mac.cc b/src/poly/threading_mac.cc new file mode 100644 index 000000000..55b508f35 --- /dev/null +++ b/src/poly/threading_mac.cc @@ -0,0 +1,32 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include + +namespace poly { +namespace threading { + +uint32_t current_thread_id() { + mach_port_t tid = pthread_mach_thread_np(pthread_self()); + return static_cast(tid); +} + +void Yield() { pthread_yield_np(); } + +void Sleep(std::chrono::microseconds duration) { + timespec rqtp = {duration.count() / 1000000, duration.count() % 1000}; + nanosleep(&rqtp, nullptr); + // TODO(benvanik): spin while rmtp >0? +} + +} // namespace threading +} // namespace poly diff --git a/src/poly/threading_win.cc b/src/poly/threading_win.cc new file mode 100644 index 000000000..7b2b8be3d --- /dev/null +++ b/src/poly/threading_win.cc @@ -0,0 +1,30 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace poly { +namespace threading { + +uint32_t current_thread_id() { + return static_cast(GetCurrentThreadId()); +} + +void Yield() { SwitchToThread(); } + +void Sleep(std::chrono::microseconds duration) { + if (duration.count() < 100) { + SwitchToThread(); + } else { + Sleep(duration.count() / 1000); + } +} + +} // namespace threading +} // namespace poly