SeqAn3  3.2.0
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 
26 #include <seqan3/core/platform.hpp>
27 
28 namespace seqan3::detail
29 {
41 class spin_delay
42 {
43 public:
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)
68  pause_processor();
69  current <<= 1; // double the amount of active CPU waiting cycles.
70  }
71  else // Start passive spinning phase
72  {
74  }
75  }
76 
77 private:
79  void pause_processor()
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
Provides platform and dependency checks.
T yield(T... args)