SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
spin_delay.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <thread>
13
15
17#ifndef SEQAN3_HAS_MM_PAUSE
18# if defined(__SSE2__) && __has_include(<xmmintrin.h>)
19# include <xmmintrin.h> // _mm_pause()
20# define SEQAN3_HAS_MM_PAUSE 1
21# else
22# define SEQAN3_HAS_MM_PAUSE 0
23# endif // defined(__SSE2__) && __has_include(<xmmintrin.h>)
24#endif // SEQAN3_HAS_MM_PAUSE
26
27namespace seqan3::detail
28{
41{
42public:
46 constexpr spin_delay() noexcept = default;
47 constexpr spin_delay(spin_delay const &) noexcept = default;
48 constexpr spin_delay(spin_delay &&) noexcept = default;
49 constexpr spin_delay & operator=(spin_delay const &) noexcept = default;
50 constexpr spin_delay & operator=(spin_delay &&) noexcept = default;
51 ~spin_delay() noexcept = default;
52
54
62 void wait()
63 {
64 if (current <= max_repetitions) // Start active spinning phase
65 {
66 for (int_fast32_t i = 0; i < current; ++i)
68 current <<= 1; // double the amount of active CPU waiting cycles.
69 }
70 else // Start passive spinning phase
71 {
73 }
74 }
75
76private:
79 {
80#if SEQAN3_HAS_MM_PAUSE // AMD and Intel
81 _mm_pause();
82#elif defined(__armel__) || defined(__ARMEL__) // ARM, but broken? repeat of default case as ARMEL also defines __arm__
83 asm volatile("nop" ::: "memory"); // default operation - does nothing => Might lead to passive spinning.
84#elif defined(__arm__) || defined(__aarch64__) // ARM big endian / ARM64
85 __asm__ __volatile__("yield" ::: "memory");
86#elif defined(__ia64__) // IA64
87 __asm__ __volatile__("hint @pause");
88#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(__ppc64__) // PowerPC
89# if defined(__APPLE__)
90 __asm__ volatile("or r27,r27,r27" ::: "memory");
91# else
92 __asm__ __volatile__("or 27,27,27" ::: "memory");
93# endif
94#else // everything else
95 asm volatile("nop" ::: "memory"); // default operation - does nothing => Might lead to passive spinning.
96#endif
97 }
98
100 static constexpr int_fast32_t max_repetitions{16};
102 int_fast32_t current{1};
103};
104
105} // namespace seqan3::detail
A delay for threads waiting for a shared resource.
Definition spin_delay.hpp:41
void pause_processor()
Efficient instruction to pause the CPU.
Definition spin_delay.hpp:78
void wait()
Delays the calling thread by either using active spinning or passive spinning.
Definition spin_delay.hpp:62
constexpr spin_delay() noexcept=default
Defaulted.
static constexpr int_fast32_t max_repetitions
The maximal number of repetitions until the thread yields.
Definition spin_delay.hpp:100
int_fast32_t current
The current waiting phase.
Definition spin_delay.hpp:102
The internal SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
Provides platform and dependency checks.
T yield(T... args)
Hide me