[Build] Generalize POSIX platform guards

Most non-Windows code paths use standard POSIX APIs (sockets, signals,
dlopen, threading) that work on any POSIX platform. Change Linux-specific
guards to !WIN32 or #else where the code is portable. Linux-specific
APIs (SIGRTMIN, Vulkan/X11, fontconfig/GTK) remain Linux-guarded.
This commit is contained in:
Herman S.
2026-03-26 22:07:28 +09:00
parent 6c20f64e0d
commit cb12f7fa1e
10 changed files with 39 additions and 48 deletions

View File

@@ -23,10 +23,11 @@
// NOTE: must be included last as it expects windows.h to already be included.
#define _WINSOCK_DEPRECATED_NO_WARNINGS // inet_addr
#include <winsock2.h> // NOLINT(build/include_order)
#elif XE_PLATFORM_LINUX
#else
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/select.h>
#include <sys/socket.h>
#endif

View File

@@ -244,7 +244,7 @@ dword_result_t NtSuspendThread_entry(dword_t handle,
} else {
return X_STATUS_THREAD_IS_TERMINATING;
}
#elif XE_PLATFORM_LINUX
#else
// Handle self-suspension specially to avoid deadlock.
if (!thread->guest_object<X_KTHREAD>()->terminated) {
bool is_self_suspend =
@@ -261,8 +261,6 @@ dword_result_t NtSuspendThread_entry(dword_t handle,
} else {
return X_STATUS_THREAD_IS_TERMINATING;
}
#else
#error "Unsupported platform"
#endif
} else {
return X_STATUS_OBJECT_TYPE_MISMATCH;

View File

@@ -86,7 +86,7 @@ X_STATUS XSocket::Initialize(AddressFamily af, Type type, Protocol proto) {
X_STATUS XSocket::Close() {
#if XE_PLATFORM_WIN32
int ret = closesocket(native_handle_);
#elif XE_PLATFORM_LINUX
#else
int ret = close(native_handle_);
#endif
@@ -166,7 +166,7 @@ X_STATUS XSocket::IOControl(uint32_t cmd, uint8_t* arg_ptr) {
return X_STATUS_UNSUCCESSFUL;
}
return X_STATUS_SUCCESS;
#elif XE_PLATFORM_LINUX
#else
int native_cmd = cmd;
assert_false(!supported_controls.contains(cmd));

View File

@@ -9,7 +9,7 @@
#include "xenia/kernel/xthread.h"
#if XE_PLATFORM_LINUX
#if !XE_PLATFORM_WIN32
#include <signal.h>
#endif
@@ -556,17 +556,19 @@ void XThread::Execute() {
// On Windows, setjmp/longjmp is used because MSVC's longjmp performs SEH
// stack unwinding which already calls destructors.
uint32_t next_address;
#if XE_PLATFORM_LINUX
#if !XE_PLATFORM_WIN32
try {
exit_code = static_cast<int>(kernel_state()->processor()->Execute(
thread_state_, address, args.data(), args.size()));
next_address = 0;
} catch (const FiberReentryException& e) {
#if XE_PLATFORM_LINUX
// Ensure SIGRTMIN (used for thread suspend) is not left blocked.
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGRTMIN);
pthread_sigmask(SIG_UNBLOCK, &set, nullptr);
#endif
next_address = e.address;
}
@@ -578,10 +580,12 @@ void XThread::Execute() {
exit_code = static_cast<int>(thread_state_->context()->r[3]);
}
} catch (const FiberReentryException& e) {
#if XE_PLATFORM_LINUX
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGRTMIN);
pthread_sigmask(SIG_UNBLOCK, &set, nullptr);
#endif
next_address = e.address;
}
}
@@ -616,7 +620,7 @@ void XThread::Reenter(uint32_t address) {
// Called when the game switches fiber stacks (e.g., via
// KeSetCurrentStackPointers in games like Forza Horizon 2).
// Must unwind through all frames between here and Execute().
#if XE_PLATFORM_LINUX
#if !XE_PLATFORM_WIN32
// Throw a C++ exception that unwinds through JIT frames (using DWARF
// .eh_frame info) and host frames (using compiler-generated DWARF),
// calling destructors properly along the way.
@@ -767,7 +771,7 @@ X_STATUS XThread::Resume(uint32_t* out_suspend_count) {
} else {
return X_STATUS_UNSUCCESSFUL;
}
#elif XE_PLATFORM_LINUX
#else
// Use mutex to protect suspend_count access and coordinate with SelfSuspend.
bool should_resume_host = false;
{
@@ -788,8 +792,6 @@ X_STATUS XThread::Resume(uint32_t* out_suspend_count) {
thread_->Resume(&unused_host_suspend_count);
}
return X_STATUS_SUCCESS;
#else
#error "Unsupported platform"
#endif
}
@@ -821,7 +823,7 @@ X_STATUS XThread::Suspend(uint32_t* out_suspend_count) {
}
}
#if XE_PLATFORM_LINUX
#if !XE_PLATFORM_WIN32
uint32_t XThread::SelfSuspend() {
auto guest_thread = guest_object<X_KTHREAD>();
std::unique_lock<std::mutex> lock(suspend_mutex_);
@@ -831,7 +833,7 @@ uint32_t XThread::SelfSuspend() {
lock, [guest_thread]() { return guest_thread->suspend_count == 0; });
return previous;
}
#endif
#endif // !XE_PLATFORM_WIN32
X_STATUS XThread::Delay(uint32_t processor_mode, uint32_t alertable,
uint64_t interval) {

View File

@@ -14,7 +14,7 @@
#include <string>
#include "xenia/base/mutex.h"
#if XE_PLATFORM_LINUX
#if !XE_PLATFORM_WIN32
#include <condition_variable>
#include <csignal>
#include <mutex>
@@ -343,7 +343,7 @@ struct X_KTHREAD {
};
static_assert_size(X_KTHREAD, 0xAB0);
#if XE_PLATFORM_LINUX
#if !XE_PLATFORM_WIN32
// Exception thrown by XThread::Reenter() to unwind through JIT frames.
// C++ exception unwinding uses DWARF .eh_frame info registered for JIT code,
// ensuring destructors and RAII guards in host C++ frames are properly called.
@@ -442,7 +442,7 @@ class XThread : public XObject, public cpu::Thread {
X_STATUS Delay(uint32_t processor_mode, uint32_t alertable,
uint64_t interval);
#if XE_PLATFORM_LINUX
#if !XE_PLATFORM_WIN32
// Performs self-suspension: increments suspend_count and blocks until
// another thread calls Resume() and suspend_count reaches 0.
// Returns the previous suspend_count value.
@@ -490,7 +490,7 @@ class XThread : public XObject, public cpu::Thread {
int32_t priority_ = 0;
#if XE_PLATFORM_LINUX
#if !XE_PLATFORM_WIN32
// Condition variable for thread self-suspension.
std::mutex suspend_mutex_;
std::condition_variable suspend_cv_;