SeqAn3 3.3.0-rc.1
The Modern C++ library for sequence analysis.
spin_delay.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, Knut Reinert & MPI für molekulare Genetik
4// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6// -----------------------------------------------------------------------------------------------------
7
13#pragma once
14
15#include <thread>
16
18#ifndef SEQAN3_HAS_MM_PAUSE
19# if defined(__SSE2__) && __has_include(<xmmintrin.h>)
20# include <xmmintrin.h> // _mm_pause()
21# define SEQAN3_HAS_MM_PAUSE 1
22# endif // defined(__SSE2__) && __has_include(<xmmintrin.h>)
23#endif // SEQAN3_HAS_MM_PAUSE
25
27
28namespace seqan3::detail
29{
42{
43public:
47 constexpr spin_delay() noexcept = default;
48 constexpr spin_delay(spin_delay const &) noexcept = default;
49 constexpr spin_delay(spin_delay &&) noexcept = default;
50 constexpr spin_delay & operator=(spin_delay const &) noexcept = default;
51 constexpr spin_delay & operator=(spin_delay &&) noexcept = default;
52 ~spin_delay() noexcept = default;
53
55
63 void wait()
64 {
65 if (current <= max_repetitions) // Start active spinning phase
66 {
67 for (int_fast32_t i = 0; i < current; ++i)
69 current <<= 1; // double the amount of active CPU waiting cycles.
70 }
71 else // Start passive spinning phase
72 {
74 }
75 }
76
77private:
80 {
81#if SEQAN3_HAS_MM_PAUSE // AMD and Intel
82 _mm_pause();
83#elif defined(__armel__) \
84 || defined(__ARMEL__) // arm, but broken? ; repeat of default case as armel also defines __arm__
85 asm volatile("nop" ::: "memory"); // default operation - does nothing => Might lead to passive spinning.
86#elif defined(__arm__) || defined(__aarch64__) // arm big endian / arm64
87 __asm__ __volatile__("yield" ::: "memory");
88#elif defined(__ia64__) // IA64
89 __asm__ __volatile__("hint @pause");
90#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) // PowerPC
91 __asm__ __volatile__("or 27,27,27" ::: "memory");
92#else // everything else.
93 asm volatile("nop" ::: "memory"); // default operation - does nothing => Might lead to passive spinning.
94#endif
95 }
96
98 static constexpr int_fast32_t max_repetitions{16};
100 int_fast32_t current{1};
101};
102
103} // namespace seqan3::detail
A delay for threads waiting for a shared resource.
Definition: spin_delay.hpp:42
void pause_processor()
Efficient instruction to pause the CPU.
Definition: spin_delay.hpp:79
void wait()
Delays the calling thread by either using active spinning or passive spinning.
Definition: spin_delay.hpp:63
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:98
int_fast32_t current
The current waiting phase.
Definition: spin_delay.hpp:100
The internal SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
Provides platform and dependency checks.
T yield(T... args)