From 2461d94e51ac6ce793825eacbf8a57b21861bd0d Mon Sep 17 00:00:00 2001 From: aleck099 Date: Sun, 20 Apr 2025 21:46:07 +0800 Subject: [PATCH] Move inlined vfork syscall to all system_call()s attribute __gnu__::__always_inline__ is required Signed-off-by: aleck099 --- .../fast_io_hosted/platforms/linux/aarch64.h | 40 ++++++++++++++++++ .../fast_io_hosted/platforms/linux/amd64.h | 41 ++++++++++++++++++- .../fast_io_hosted/platforms/linux/generic.h | 10 +++++ .../platforms/linux/loongarch64.h | 40 ++++++++++++++++++ .../fast_io_hosted/platforms/linux/riscv64.h | 40 ++++++++++++++++++ .../fast_io_hosted/process/process/posix.h | 7 +--- 6 files changed, 171 insertions(+), 7 deletions(-) diff --git a/include/fast_io_hosted/platforms/linux/aarch64.h b/include/fast_io_hosted/platforms/linux/aarch64.h index 134f65ba9..25e8d11ac 100644 --- a/include/fast_io_hosted/platforms/linux/aarch64.h +++ b/include/fast_io_hosted/platforms/linux/aarch64.h @@ -5,6 +5,11 @@ namespace fast_io template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call() noexcept { register ::std::uint_least64_t x8 __asm__("x8") = syscall_number; @@ -15,6 +20,11 @@ inline return_value_type system_call() noexcept template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1) noexcept { register ::std::uint_least64_t x8 __asm__("x8") = syscall_number; @@ -24,6 +34,11 @@ inline return_value_type system_call(auto p1) noexcept } template <::std::size_t syscall_number> +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline void system_call_no_return(auto p1) noexcept { register ::std::uint_least64_t x8 __asm__("x8") = syscall_number; @@ -34,6 +49,11 @@ inline void system_call_no_return(auto p1) noexcept template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2) noexcept { register ::std::uint_least64_t x8 __asm__("x8") = syscall_number; @@ -45,6 +65,11 @@ inline return_value_type system_call(auto p1, auto p2) noexcept template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept { register ::std::uint_least64_t x8 __asm__("x8") = syscall_number; @@ -57,6 +82,11 @@ inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4) noexcept { register ::std::uint_least64_t x8 __asm__("x8") = syscall_number; @@ -70,6 +100,11 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4) noexcep template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5) noexcept { register ::std::uint_least64_t x8 __asm__("x8") = syscall_number; @@ -84,6 +119,11 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5 template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5, auto p6) noexcept { register ::std::uint_least64_t x8 __asm__("x8") = syscall_number; diff --git a/include/fast_io_hosted/platforms/linux/amd64.h b/include/fast_io_hosted/platforms/linux/amd64.h index 469d04c06..34129306f 100644 --- a/include/fast_io_hosted/platforms/linux/amd64.h +++ b/include/fast_io_hosted/platforms/linux/amd64.h @@ -3,9 +3,13 @@ namespace fast_io { - template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call() noexcept { return_value_type ret; @@ -19,6 +23,11 @@ inline return_value_type system_call() noexcept template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1) noexcept { return_value_type ret; @@ -31,6 +40,11 @@ inline return_value_type system_call(auto p1) noexcept } template <::std::size_t syscall_number> +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline void system_call_no_return(auto p1) noexcept { ::std::size_t ret; @@ -44,6 +58,11 @@ inline void system_call_no_return(auto p1) noexcept template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2) noexcept { return_value_type ret; @@ -57,6 +76,11 @@ inline return_value_type system_call(auto p1, auto p2) noexcept template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept { return_value_type ret; @@ -70,6 +94,11 @@ inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4) noexcept { return_value_type ret; @@ -84,6 +113,11 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4) noexcep template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5) noexcept { return_value_type ret; @@ -99,6 +133,11 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5 template <::std::size_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5, auto p6) noexcept { return_value_type ret; diff --git a/include/fast_io_hosted/platforms/linux/generic.h b/include/fast_io_hosted/platforms/linux/generic.h index 74decedeb..2f5fb961c 100644 --- a/include/fast_io_hosted/platforms/linux/generic.h +++ b/include/fast_io_hosted/platforms/linux/generic.h @@ -7,6 +7,11 @@ namespace fast_io template <::std::size_t syscall_number, ::std::signed_integral return_value_type, typename... Args> requires(::std::is_trivially_copyable_v && ...) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(Args... args) noexcept { long ret{::syscall(syscall_number, args...)}; @@ -18,6 +23,11 @@ inline return_value_type system_call(Args... args) noexcept } template <::std::size_t syscall_number> +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline void system_call_no_return(auto p1) noexcept { ::syscall(syscall_number, p1); diff --git a/include/fast_io_hosted/platforms/linux/loongarch64.h b/include/fast_io_hosted/platforms/linux/loongarch64.h index d3dbe4868..f523111f3 100644 --- a/include/fast_io_hosted/platforms/linux/loongarch64.h +++ b/include/fast_io_hosted/platforms/linux/loongarch64.h @@ -10,6 +10,11 @@ namespace fast_io template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call() noexcept { register ::std::uint_least64_t a7 __asm__("$a7") = syscall_number; @@ -21,6 +26,11 @@ inline return_value_type system_call() noexcept template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1) noexcept { register ::std::uint_least64_t a7 __asm__("$a7") = syscall_number; @@ -31,6 +41,11 @@ inline return_value_type system_call(auto p1) noexcept } template <::std::uint_least64_t syscall_number> +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline void system_call_no_return(auto p1) noexcept { register ::std::uint_least64_t a7 __asm__("$a7") = syscall_number; @@ -42,6 +57,11 @@ inline void system_call_no_return(auto p1) noexcept template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2) noexcept { register ::std::uint_least64_t a7 __asm__("$a7") = syscall_number; @@ -54,6 +74,11 @@ inline return_value_type system_call(auto p1, auto p2) noexcept template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept { register ::std::uint_least64_t a7 __asm__("$a7") = syscall_number; @@ -67,6 +92,11 @@ inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4) noexcept { register ::std::uint_least64_t a7 __asm__("$a7") = syscall_number; @@ -81,6 +111,11 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4) noexcep template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5) noexcept { register ::std::uint_least64_t a7 __asm__("$a7") = syscall_number; @@ -96,6 +131,11 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5 template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5, auto p6) noexcept { register ::std::uint_least64_t a7 __asm__("$a7") = syscall_number; diff --git a/include/fast_io_hosted/platforms/linux/riscv64.h b/include/fast_io_hosted/platforms/linux/riscv64.h index bdc1786d9..bfeee54c9 100644 --- a/include/fast_io_hosted/platforms/linux/riscv64.h +++ b/include/fast_io_hosted/platforms/linux/riscv64.h @@ -10,6 +10,11 @@ namespace fast_io template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call() noexcept { register ::std::uint_least64_t a7 __asm__("a7") = syscall_number; @@ -20,6 +25,11 @@ inline return_value_type system_call() noexcept template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1) noexcept { register ::std::uint_least64_t a7 __asm__("a7") = syscall_number; @@ -29,6 +39,11 @@ inline return_value_type system_call(auto p1) noexcept } template <::std::uint_least64_t syscall_number> +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline void system_call_no_return(auto p1) noexcept { register ::std::uint_least64_t a7 __asm__("a7") = syscall_number; @@ -39,6 +54,11 @@ inline void system_call_no_return(auto p1) noexcept template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2) noexcept { register ::std::uint_least64_t a7 __asm__("a7") = syscall_number; @@ -50,6 +70,11 @@ inline return_value_type system_call(auto p1, auto p2) noexcept template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept { register ::std::uint_least64_t a7 __asm__("a7") = syscall_number; @@ -62,6 +87,11 @@ inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4) noexcept { register ::std::uint_least64_t a7 __asm__("a7") = syscall_number; @@ -75,6 +105,11 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4) noexcep template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5) noexcept { register ::std::uint_least64_t a7 __asm__("a7") = syscall_number; @@ -89,6 +124,11 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5 template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) +#if __has_cpp_attribute(__gnu__::__always_inline__) +[[__gnu__::__always_inline__]] +#else +#error "system_call must be inlined" +#endif inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5, auto p6) noexcept { register ::std::uint_least64_t a7 __asm__("a7") = syscall_number; diff --git a/include/fast_io_hosted/process/process/posix.h b/include/fast_io_hosted/process/process/posix.h index 93a62a897..a2d1dffff 100644 --- a/include/fast_io_hosted/process/process/posix.h +++ b/include/fast_io_hosted/process/process/posix.h @@ -472,12 +472,7 @@ struct fd_remapper inline void vfork_and_execveat(pid_t &pid, int dirfd, char const *cstr, char const *const *args, char const *const *envp, int volatile &t_errno, process_mode mode) noexcept { #if defined(__linux__) && defined(__NR_vfork) - // NOTE: vfork and exec must be in the same function!!! - // system_call can't be used here - __asm__ __volatile__("syscall" - : "=a"(pid) - : "0"(__NR_vfork) - : "memory", "cc", "r11", "cx"); + pid = system_call<__NR_vfork, pid_t>(); system_call_throw_error(pid); #else pid = ::fast_io::posix::libc_vfork();