From a6f2f21257118dc5bcae6954de255cb79c06e7fa Mon Sep 17 00:00:00 2001 From: GH <781213930@qq.com> Date: Fri, 17 Jul 2026 02:36:42 +0800 Subject: [PATCH 1/4] build: support LoongArch host toolchains --- 3rdparty/CMakeLists.txt | 62 +++++++++++++++++----------- CMakeLists.txt | 15 ++++++- preempt/src/sched/executor.cpp | 3 +- sched/src/scheduler/local.cpp | 6 ++- utils/include/xsched/utils/common.h | 5 +++ utils/include/xsched/utils/lock.h | 4 +- utils/include/xsched/utils/region.h | 3 +- utils/src/lock.cpp | 64 ++++++++++++++++++----------- 8 files changed, 107 insertions(+), 55 deletions(-) diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index b4cc587c..9d401d9a 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -1,33 +1,47 @@ -set(CLI11_PRECOMPILED OFF CACHE BOOL "do not precompile CLI11") +if(BUILD_SERVICE) + set(CLI11_PRECOMPILED OFF CACHE BOOL "do not precompile CLI11") add_subdirectory(CLI11 EXCLUDE_FROM_ALL) -unset(CLI11_PRECOMPILED CACHE) + unset(CLI11_PRECOMPILED CACHE) -set(HTTPLIB_INSTALL OFF CACHE BOOL "do not install cpp-httplib") -set(HTTPLIB_USE_OPENSSL_IF_AVAILABLE OFF CACHE BOOL "disable openssl for cpp-httplib") -set(HTTPLIB_USE_ZLIB_IF_AVAILABLE OFF CACHE BOOL "disable zlib for cpp-httplib") -set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF CACHE BOOL "disable brotli for cpp-httplib") + set(HTTPLIB_INSTALL OFF CACHE BOOL "do not install cpp-httplib") + set(HTTPLIB_USE_OPENSSL_IF_AVAILABLE OFF CACHE BOOL "disable openssl for cpp-httplib") + set(HTTPLIB_USE_ZLIB_IF_AVAILABLE OFF CACHE BOOL "disable zlib for cpp-httplib") + set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF CACHE BOOL "disable brotli for cpp-httplib") add_subdirectory(cpp-httplib EXCLUDE_FROM_ALL) -unset(HTTPLIB_USE_OPENSSL_IF_AVAILABLE CACHE) -unset(HTTPLIB_USE_ZLIB_IF_AVAILABLE CACHE) -unset(HTTPLIB_USE_BROTLI_IF_AVAILABLE CACHE) -unset(HTTPLIB_INSTALL CACHE) + unset(HTTPLIB_USE_OPENSSL_IF_AVAILABLE CACHE) + unset(HTTPLIB_USE_ZLIB_IF_AVAILABLE CACHE) + unset(HTTPLIB_USE_BROTLI_IF_AVAILABLE CACHE) + unset(HTTPLIB_INSTALL CACHE) +endif() +# Bundled googletest requires CMake 3.16. Keep XSched's platform tests +# buildable with older toolchains without enabling libipc's own tests. +set(XSCHED_BUILD_TEST_SAVED "${BUILD_TEST}") +if(CMAKE_VERSION VERSION_LESS 3.16) + set(BUILD_TEST OFF) +endif() add_subdirectory(ipc EXCLUDE_FROM_ALL) +set(BUILD_TEST "${XSCHED_BUILD_TEST_SAVED}") +unset(XSCHED_BUILD_TEST_SAVED) -add_subdirectory(cuxtra EXCLUDE_FROM_ALL) +if(PLATFORM_CUDA) + add_subdirectory(cuxtra EXCLUDE_FROM_ALL) +endif() -set(JSONCPP_WITH_TESTS OFF CACHE BOOL "do not build jsoncpp tests") -set(JSONCPP_WITH_POST_BUILD_UNITTEST OFF CACHE BOOL "disable jsoncpp post build unit test") -set(JSONCPP_WITH_PKGCONFIG_SUPPORT OFF CACHE BOOL "disable jsoncpp pkgconfig support") -set(JSONCPP_WITH_CMAKE_PACKAGE OFF CACHE BOOL "disable jsoncpp cmake package") -set(BUILD_SHARED_LIBS OFF CACHE BOOL "do not build jsoncpp shared library") -set(BUILD_OBJECT_LIBS OFF CACHE BOOL "do not build jsoncpp object library") +if(BUILD_SERVICE) + set(JSONCPP_WITH_TESTS OFF CACHE BOOL "do not build jsoncpp tests") + set(JSONCPP_WITH_POST_BUILD_UNITTEST OFF CACHE BOOL "disable jsoncpp post build unit test") + set(JSONCPP_WITH_PKGCONFIG_SUPPORT OFF CACHE BOOL "disable jsoncpp pkgconfig support") + set(JSONCPP_WITH_CMAKE_PACKAGE OFF CACHE BOOL "disable jsoncpp cmake package") + set(BUILD_SHARED_LIBS OFF CACHE BOOL "do not build jsoncpp shared library") + set(BUILD_OBJECT_LIBS OFF CACHE BOOL "do not build jsoncpp object library") add_subdirectory(jsoncpp EXCLUDE_FROM_ALL) -unset(JSONCPP_WITH_TESTS CACHE) -unset(JSONCPP_WITH_POST_BUILD_UNITTEST CACHE) -unset(JSONCPP_WITH_PKGCONFIG_SUPPORT CACHE) -unset(JSONCPP_WITH_CMAKE_PACKAGE CACHE) -unset(BUILD_SHARED_LIBS CACHE) -unset(BUILD_OBJECT_LIBS CACHE) + unset(JSONCPP_WITH_TESTS CACHE) + unset(JSONCPP_WITH_POST_BUILD_UNITTEST CACHE) + unset(JSONCPP_WITH_PKGCONFIG_SUPPORT CACHE) + unset(JSONCPP_WITH_CMAKE_PACKAGE CACHE) + unset(BUILD_SHARED_LIBS CACHE) + unset(BUILD_OBJECT_LIBS CACHE) -add_subdirectory(ftxui EXCLUDE_FROM_ALL) + add_subdirectory(ftxui EXCLUDE_FROM_ALL) +endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index e482a121..f4f20dd6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,18 @@ -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.13) project(XSched VERSION 1.2.0) option(SHIM_SOFTLINK "Create softlink for shim library." OFF) option(BUILD_TEST "Build test cases." OFF) +option(BUILD_SERVICE "Build scheduler service and CLI tools." ON) + +if(BUILD_SERVICE AND CMAKE_VERSION VERSION_LESS 3.14) + message(FATAL_ERROR "BUILD_SERVICE requires CMake 3.14 or newer") +endif() + +if(BUILD_TEST) + enable_testing() +endif() set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_EXTENSIONS OFF) @@ -22,7 +31,9 @@ add_subdirectory(utils) add_subdirectory(protocol) add_subdirectory(sched) add_subdirectory(preempt) -add_subdirectory(service) +if(BUILD_SERVICE) + add_subdirectory(service) +endif() add_subdirectory(platforms) include(CMakePackageConfigHelpers) diff --git a/preempt/src/sched/executor.cpp b/preempt/src/sched/executor.cpp index 3c12c1e0..86b9056d 100644 --- a/preempt/src/sched/executor.cpp +++ b/preempt/src/sched/executor.cpp @@ -27,7 +27,8 @@ void SchedExecutor::Execute(std::shared_ptr op) { OperationType type = op->Type(); XASSERT(op->Pid() == GetProcessId(), - "operation %ld sent to the wrong process, target: %d, receiver %d", + "operation " FMT_64U " sent to the wrong process, target: " + FMT_PID ", receiver " FMT_PID, op->Id(), op->Pid(), GetProcessId()); if (!executing_.load()) type = kOperationNone; diff --git a/sched/src/scheduler/local.cpp b/sched/src/scheduler/local.cpp index 47ff2a25..9028451e 100644 --- a/sched/src/scheduler/local.cpp +++ b/sched/src/scheduler/local.cpp @@ -74,10 +74,12 @@ void LocalScheduler::RecvEvent(std::shared_ptr event) std::unique_lock lock(op_mtx_); auto it = ops_.find(pid); if (it == ops_.end()) { - XWARN("operation %ld completed of unknown process %d", op_id, pid); + XWARN("operation " FMT_64U " completed of unknown process " + FMT_PID, op_id, pid); return; } - XASSERT(op_id <= it->second.issued_id, "unknown operation %ld completed", op_id); + XASSERT(op_id <= it->second.issued_id, + "unknown operation " FMT_64U " completed", op_id); it->second.completed_id = std::max(it->second.completed_id, op_id); lock.unlock(); op_cv_.notify_all(); diff --git a/utils/include/xsched/utils/common.h b/utils/include/xsched/utils/common.h index c02346c4..05f93311 100644 --- a/utils/include/xsched/utils/common.h +++ b/utils/include/xsched/utils/common.h @@ -87,6 +87,11 @@ #elif defined(__aarch64__) || defined(_M_ARM64) #define ARCH_AARCH64 #define ARCH_STR "aarch64" +#elif defined(__loongarch__) + #define ARCH_LOONGARCH64 + #define ARCH_STR "loongarch64" +#else + #error unsupported architecture #endif // operating system detection diff --git a/utils/include/xsched/utils/lock.h b/utils/include/xsched/utils/lock.h index 73da960c..fa137f3b 100644 --- a/utils/include/xsched/utils/lock.h +++ b/utils/include/xsched/utils/lock.h @@ -78,8 +78,8 @@ class MCSLock : public MutexLock struct alignas(64) MCSNode { - volatile LockStatus flag; - volatile MCSNode *next; + std::atomic flag { kLockWaiting }; + std::atomic next { nullptr }; }; static thread_local MCSNode me; diff --git a/utils/include/xsched/utils/region.h b/utils/include/xsched/utils/region.h index 9014c45e..975f3c36 100644 --- a/utils/include/xsched/utils/region.h +++ b/utils/include/xsched/utils/region.h @@ -141,7 +141,8 @@ class Region uint64_t intersect_begin = std::max(begin, cur_begin); uint64_t intersect_end = std::min(end, cur_end); XASSERT(intersect_begin < intersect_end, - "[%lu, %lu] must intersect with [%lu, %lu]", + "[" FMT_64U ", " FMT_64U "] must intersect with [" + FMT_64U ", " FMT_64U "]", begin, end, cur_begin, cur_end); result[intersect_end] = intersect_begin; diff --git a/utils/src/lock.cpp b/utils/src/lock.cpp index 0c39eab6..90da4f3f 100644 --- a/utils/src/lock.cpp +++ b/utils/src/lock.cpp @@ -1,45 +1,63 @@ #include "xsched/utils/lock.h" #include "xsched/utils/common.h" -#if defined(__linux__) - #if defined(ARCH_X86_64) - #define memory_barrier() asm volatile("pause" ::: "memory") - #elif defined(ARCH_AARCH64) - #define memory_barrier() asm volatile("yield" ::: "memory") - #endif -#elif defined(_WIN32) +#if defined(_WIN32) #include - #define memory_barrier() _mm_pause() #endif using namespace xsched::utils; +namespace +{ + +inline void CpuRelax() +{ +#if defined(_WIN32) + _mm_pause(); +#elif defined(ARCH_X86) || defined(ARCH_X86_64) + asm volatile("pause" ::: "memory"); +#elif defined(ARCH_ARM) || defined(ARCH_AARCH64) + asm volatile("yield" ::: "memory"); +#else + // LoongArch has no userspace pause/yield instruction. The Linux kernel's + // cpu_relax() is a compiler barrier on this architecture as well. + std::atomic_signal_fence(std::memory_order_seq_cst); +#endif +} + +} // namespace + thread_local MCSLock::MCSNode MCSLock::me; void MCSLock::lock() { - MCSNode *tail = nullptr; - me.flag = kLockWaiting; - me.next = nullptr; - tail = tail_.exchange(&me); - if (tail) { - tail->next = &me; - while (me.flag != kLockGranted) { - memory_barrier(); + me.flag.store(kLockWaiting, std::memory_order_relaxed); + me.next.store(nullptr, std::memory_order_relaxed); + + MCSNode *predecessor = tail_.exchange(&me, std::memory_order_acq_rel); + if (predecessor != nullptr) { + predecessor->next.store(&me, std::memory_order_release); + while (me.flag.load(std::memory_order_acquire) != kLockGranted) { + CpuRelax(); } } } void MCSLock::unlock() { - if (!me.next) { - MCSNode *me_ptr = &me; - if (tail_.compare_exchange_strong(me_ptr, nullptr)) { + MCSNode *successor = me.next.load(std::memory_order_acquire); + if (successor == nullptr) { + MCSNode *expected = &me; + if (tail_.compare_exchange_strong(expected, nullptr, + std::memory_order_release, + std::memory_order_relaxed)) { return; } - while (!me.next) { - memory_barrier(); - } + do { + CpuRelax(); + successor = me.next.load(std::memory_order_acquire); + } while (successor == nullptr); } - me.next->flag = kLockGranted; + + successor->flag.store(kLockGranted, std::memory_order_release); } From 5e5d7e5beb444bf422dc93591189e6598582e087 Mon Sep 17 00:00:00 2001 From: WeihangShen Date: Fri, 24 Jul 2026 16:56:15 +0800 Subject: [PATCH 2/4] [improve]: cmake --- 3rdparty/CMakeLists.txt | 34 ++++++++++++++++++---------------- CMakeLists.txt | 4 ---- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index 9d401d9a..d296d93d 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -1,4 +1,22 @@ +# Bundled googletest requires CMake 3.16. Keep XSched's platform tests +# buildable with older toolchains without enabling libipc's own tests. +set(XSCHED_BUILD_TEST_TMP "${BUILD_TEST}") +if(CMAKE_VERSION VERSION_LESS 3.16) + set(BUILD_TEST OFF) +endif() +add_subdirectory(ipc EXCLUDE_FROM_ALL) +set(BUILD_TEST "${XSCHED_BUILD_TEST_TMP}") +unset(XSCHED_BUILD_TEST_TMP) + +if(PLATFORM_CUDA) + add_subdirectory(cuxtra EXCLUDE_FROM_ALL) +endif() + if(BUILD_SERVICE) + if(CMAKE_VERSION VERSION_LESS 3.14) + message(FATAL_ERROR "BUILD_SERVICE requires CMake 3.14 or newer") + endif() + set(CLI11_PRECOMPILED OFF CACHE BOOL "do not precompile CLI11") add_subdirectory(CLI11 EXCLUDE_FROM_ALL) unset(CLI11_PRECOMPILED CACHE) @@ -12,23 +30,7 @@ if(BUILD_SERVICE) unset(HTTPLIB_USE_ZLIB_IF_AVAILABLE CACHE) unset(HTTPLIB_USE_BROTLI_IF_AVAILABLE CACHE) unset(HTTPLIB_INSTALL CACHE) -endif() -# Bundled googletest requires CMake 3.16. Keep XSched's platform tests -# buildable with older toolchains without enabling libipc's own tests. -set(XSCHED_BUILD_TEST_SAVED "${BUILD_TEST}") -if(CMAKE_VERSION VERSION_LESS 3.16) - set(BUILD_TEST OFF) -endif() -add_subdirectory(ipc EXCLUDE_FROM_ALL) -set(BUILD_TEST "${XSCHED_BUILD_TEST_SAVED}") -unset(XSCHED_BUILD_TEST_SAVED) - -if(PLATFORM_CUDA) - add_subdirectory(cuxtra EXCLUDE_FROM_ALL) -endif() - -if(BUILD_SERVICE) set(JSONCPP_WITH_TESTS OFF CACHE BOOL "do not build jsoncpp tests") set(JSONCPP_WITH_POST_BUILD_UNITTEST OFF CACHE BOOL "disable jsoncpp post build unit test") set(JSONCPP_WITH_PKGCONFIG_SUPPORT OFF CACHE BOOL "disable jsoncpp pkgconfig support") diff --git a/CMakeLists.txt b/CMakeLists.txt index f4f20dd6..3374c23c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,10 +6,6 @@ option(SHIM_SOFTLINK "Create softlink for shim library." OFF) option(BUILD_TEST "Build test cases." OFF) option(BUILD_SERVICE "Build scheduler service and CLI tools." ON) -if(BUILD_SERVICE AND CMAKE_VERSION VERSION_LESS 3.14) - message(FATAL_ERROR "BUILD_SERVICE requires CMake 3.14 or newer") -endif() - if(BUILD_TEST) enable_testing() endif() From ba95f33c7b193cd46daae50bed423dae037bfaa1 Mon Sep 17 00:00:00 2001 From: WeihangShen Date: Fri, 24 Jul 2026 17:13:16 +0800 Subject: [PATCH 3/4] [fix]: CMAKE_INSTALL_INCLUDEDIR --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3374c23c..d8396bbf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ if(BUILD_SERVICE) endif() add_subdirectory(platforms) +include(GNUInstallDirs) include(CMakePackageConfigHelpers) configure_package_config_file( From 6b24d5d015192718ea0d2254a50ba311e56ec874 Mon Sep 17 00:00:00 2001 From: WeihangShen Date: Fri, 24 Jul 2026 17:15:12 +0800 Subject: [PATCH 4/4] [improve]: add lock fixme --- utils/include/xsched/utils/lock.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/include/xsched/utils/lock.h b/utils/include/xsched/utils/lock.h index fa137f3b..bfddc26e 100644 --- a/utils/include/xsched/utils/lock.h +++ b/utils/include/xsched/utils/lock.h @@ -82,6 +82,8 @@ class MCSLock : public MutexLock std::atomic next { nullptr }; }; + /// @FIXME: current implementation is one node per-thread, + /// should be one node per-thread per-lock. static thread_local MCSNode me; std::atomic tail_{nullptr}; };