SeqAn3  3.0.3
The Modern C++ library for sequence analysis.
spin_delay.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2021, 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 
17 #if defined(__SSE2__) // AMD and Intel
18 #include <xmmintrin.h> // _mm_pause()
19 #endif
20 
21 #include <seqan3/core/platform.hpp>
22 
23 namespace seqan3::detail
24 {
36 class spin_delay
37 {
38 public:
42  constexpr spin_delay() noexcept = default;
43  constexpr spin_delay(spin_delay const &) noexcept = default;
44  constexpr spin_delay(spin_delay &&) noexcept = default;
45  constexpr spin_delay & operator=(spin_delay const &) noexcept = default;
46  constexpr spin_delay & operator=(spin_delay &&) noexcept = default;
47  ~spin_delay() noexcept = default;
48 
50 
58  void wait()
59  {
60  if (current <= max_repetitions) // Start active spinning phase
61  {
62  for (int_fast32_t i = 0; i < current; ++i)
63  pause_processor();
64  current <<= 1; // double the amount of active CPU waiting cycles.
65  }
66  else // Start passive spinning phase
67  {
69  }
70  }
71 
72 private:
73 
75  void pause_processor()
76  {
77  #if defined(__SSE2__) // AMD and Intel
78  _mm_pause();
79  #elif defined(__armel__) || defined(__ARMEL__) // arm, but broken? ; repeat of default case as armel also defines __arm__
80  asm volatile ("nop" ::: "memory"); // default operation - does nothing => Might lead to passive spinning.
81  #elif defined(__arm__) || defined(__aarch64__) // arm big endian / arm64
82  __asm__ __volatile__ ("yield" ::: "memory");
83  #elif defined(__ia64__) // IA64
84  __asm__ __volatile__ ("hint @pause");
85  #elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) // PowerPC
86  __asm__ __volatile__ ("or 27,27,27" ::: "memory");
87  #else // everything else.
88  asm volatile ("nop" ::: "memory"); // default operation - does nothing => Might lead to passive spinning.
89  #endif
90  }
91 
93  static constexpr int_fast32_t max_repetitions{16};
95  int_fast32_t current{1};
96 };
97 
98 } // namespace seqan3::detail
Provides platform and dependency checks.
T yield(T... args)