1 /* 2 * Copyright (c) 2023 Maikel Nadolski 3 * Copyright (c) 2023 NVIDIA Corporation 4 * 5 * Licensed under the Apache License Version 2.0 with LLVM Exceptions 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * https://llvm.org/LICENSE.txt 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 #pragma once 18 19 #include "../../stdexec/__detail/__config.hpp" 20 21 // The below code for spin_loop_pause is taken from https://github.com/max0x7ba/atomic_queue/blob/master/include/atomic_queue/defs.h 22 // Copyright (c) 2019 Maxim Egorushkin. MIT License. 23 24 #if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) 25 # if STDEXEC_MSVC_HEADERS() 26 # include <intrin.h> 27 # endif 28 namespace stdexec { STDEXEC_ATTRIBUTE(always_inline)29 STDEXEC_ATTRIBUTE(always_inline) static void __spin_loop_pause() noexcept { 30 # if STDEXEC_MSVC_HEADERS() 31 _mm_pause(); 32 # else 33 __builtin_ia32_pause(); 34 # endif 35 } 36 } // namespace stdexec 37 #elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM64) 38 namespace stdexec { STDEXEC_ATTRIBUTE(always_inline)39 STDEXEC_ATTRIBUTE(always_inline) static void __spin_loop_pause() noexcept { 40 # if ( \ 41 defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \ 42 || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ 43 || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) \ 44 || defined(__ARM_ARCH_8A__) || defined(__aarch64__)) 45 asm volatile("yield" ::: "memory"); 46 # elif defined(_M_ARM64) 47 __yield(); 48 # else 49 asm volatile("nop" ::: "memory"); 50 # endif 51 } 52 } // namespace stdexec 53 #else 54 namespace stdexec { STDEXEC_ATTRIBUTE(always_inline)55 STDEXEC_ATTRIBUTE(always_inline) static void __spin_loop_pause() noexcept { 56 } 57 } // namespace stdexec 58 #endif