xref: /openbmc/sdbusplus/include/sdbusplus/async/stdexec/__detail/__spin_loop_pause.hpp (revision f083bc1a64e1f94c99fc270b7c0856810f4be638)
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()33 static 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()46 static 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()66 static void __spin_loop_pause() noexcept {}
67 } // namespace stdexec
68 #endif
69