SeqAn3 3.3.0
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
spin_delay.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2023, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2023, 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
20#ifndef SEQAN3_HAS_MM_PAUSE
21# if defined(__SSE2__) && __has_include(<xmmintrin.h>)
22# include <xmmintrin.h> // _mm_pause()
23# define SEQAN3_HAS_MM_PAUSE 1
24# else
25# define SEQAN3_HAS_MM_PAUSE 0
26# endif // defined(__SSE2__) && __has_include(<xmmintrin.h>)
27#endif // SEQAN3_HAS_MM_PAUSE
29
30namespace seqan3::detail
31{
43class spin_delay
44{
45public:
49 constexpr spin_delay() noexcept = default;
50 constexpr spin_delay(spin_delay const &) noexcept = default;
51 constexpr spin_delay(spin_delay &&) noexcept = default;
52 constexpr spin_delay & operator=(spin_delay const &) noexcept = default;
53 constexpr spin_delay & operator=(spin_delay &&) noexcept = default;
54 ~spin_delay() noexcept = default;
55
57
65 void wait()
66 {
67 if (current <= max_repetitions) // Start active spinning phase
68 {
69 for (int_fast32_t i = 0; i < current; ++i)
70 pause_processor();
71 current <<= 1; // double the amount of active CPU waiting cycles.
72 }
73 else // Start passive spinning phase
74 {
76 }
77 }
78
79private:
81 void pause_processor()
82 {
83#if SEQAN3_HAS_MM_PAUSE // AMD and Intel
84 _mm_pause();
85#elif defined(__armel__) || defined(__ARMEL__) // ARM, but broken? repeat of default case as ARMEL also defines __arm__
86 asm volatile("nop" ::: "memory"); // default operation - does nothing => Might lead to passive spinning.
87#elif defined(__arm__) || defined(__aarch64__) // ARM big endian / ARM64
88 __asm__ __volatile__("yield" ::: "memory");
89#elif defined(__ia64__) // IA64
90 __asm__ __volatile__("hint @pause");
91#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(__ppc64__) // PowerPC
92# if defined(__APPLE__)
93 __asm__ volatile("or r27,r27,r27" ::: "memory");
94# else
95 __asm__ __volatile__("or 27,27,27" ::: "memory");
96# endif
97#else // everything else
98 asm volatile("nop" ::: "memory"); // default operation - does nothing => Might lead to passive spinning.
99#endif
100 }
101
103 static constexpr int_fast32_t max_repetitions{16};
105 int_fast32_t current{1};
106};
107
108} // namespace seqan3::detail
Provides platform and dependency checks.
T yield(T... args)