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 22 // https://github.com/max0x7ba/atomic_queue/blob/master/include/atomic_queue/defs.h 23 // Copyright (c) 2019 Maxim Egorushkin. MIT License. 24 25 #if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ 26 defined(_M_IX86) 27 #if STDEXEC_MSVC_HEADERS() 28 #include <intrin.h> 29 #endif 30 namespace stdexec 31 { 32 STDEXEC_ATTRIBUTE((always_inline)) __spin_loop_pause()33static void __spin_loop_pause() noexcept 34 { 35 #if STDEXEC_MSVC_HEADERS() 36 _mm_pause(); 37 #else 38 __builtin_ia32_pause(); 39 #endif 40 } 41 } // namespace stdexec 42 #elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM64) 43 namespace stdexec 44 { 45 STDEXEC_ATTRIBUTE((always_inline)) __spin_loop_pause()46static void __spin_loop_pause() noexcept 47 { 48 #if (defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \ 49 defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) || \ 50 defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \ 51 defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || \ 52 defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_8A__) || \ 53 defined(__aarch64__)) 54 asm volatile("yield" ::: "memory"); 55 #elif defined(_M_ARM64) 56 __yield(); 57 #else 58 asm volatile("nop" ::: "memory"); 59 #endif 60 } 61 } // namespace stdexec 62 #else 63 namespace stdexec 64 { 65 STDEXEC_ATTRIBUTE((always_inline)) __spin_loop_pause()66static void __spin_loop_pause() noexcept {} 67 } // namespace stdexec 68 #endif 69