xref: /openbmc/sdbusplus/include/sdbusplus/async/stdexec/__detail/__spin_loop_pause.hpp (revision 10d0b4b7d1498cfd5c3d37edea271a54d1984e41)
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