Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 43 additions & 27 deletions 3rdparty/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,33 +1,49 @@
set(CLI11_PRECOMPILED OFF CACHE BOOL "do not precompile CLI11")
add_subdirectory(CLI11 EXCLUDE_FROM_ALL)
unset(CLI11_PRECOMPILED CACHE)
# 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)

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)
if(PLATFORM_CUDA)
add_subdirectory(cuxtra EXCLUDE_FROM_ALL)
endif()

add_subdirectory(ipc EXCLUDE_FROM_ALL)
if(BUILD_SERVICE)
if(CMAKE_VERSION VERSION_LESS 3.14)
message(FATAL_ERROR "BUILD_SERVICE requires CMake 3.14 or newer")
endif()

add_subdirectory(cuxtra EXCLUDE_FROM_ALL)
set(CLI11_PRECOMPILED OFF CACHE BOOL "do not precompile CLI11")
add_subdirectory(CLI11 EXCLUDE_FROM_ALL)
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")
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)

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")
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()
12 changes: 10 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
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_TEST)
enable_testing()
endif()

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_EXTENSIONS OFF)
Expand All @@ -22,9 +27,12 @@ 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(GNUInstallDirs)
include(CMakePackageConfigHelpers)

configure_package_config_file(
Expand Down
3 changes: 2 additions & 1 deletion preempt/src/sched/executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ void SchedExecutor::Execute(std::shared_ptr<const sched::Operation> 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());
Comment thread
guohuan78 marked this conversation as resolved.
if (!executing_.load()) type = kOperationNone;

Expand Down
6 changes: 4 additions & 2 deletions sched/src/scheduler/local.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,12 @@ void LocalScheduler::RecvEvent(std::shared_ptr<const Event> event)
std::unique_lock<std::mutex> 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();
Expand Down
5 changes: 5 additions & 0 deletions utils/include/xsched/utils/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions utils/include/xsched/utils/lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@ class MCSLock : public MutexLock

struct alignas(64) MCSNode
{
volatile LockStatus flag;
volatile MCSNode *next;
std::atomic<LockStatus> flag { kLockWaiting };
std::atomic<MCSNode *> 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<MCSNode *> tail_{nullptr};
};
Expand Down
3 changes: 2 additions & 1 deletion utils/include/xsched/utils/region.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
64 changes: 41 additions & 23 deletions utils/src/lock.cpp
Original file line number Diff line number Diff line change
@@ -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 <intrin.h>
#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);
}