SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
spin_delay.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, 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 
57  void wait()
58  {
59  if (current <= max_repetitions) // Start active spinning phase
60  {
61  for (int_fast32_t i = 0; i < current; ++i)
62  pause_processor();
63  current <<= 1; // double the amount of active CPU waiting cycles.
64  }
65  else // Start passive spinning phase
66  {
68  }
69  }
70 
71 private:
72 
74  void pause_processor()
75  {
76  #if defined(__SSE2__) // AMD and Intel
77  _mm_pause();
78  #elif defined(__armel__) || defined(__ARMEL__) // arm, but broken? ; repeat of default case as armel also defines __arm__
79  asm volatile ("nop" ::: "memory"); // default operation - does nothing => Might lead to passive spinning.
80  #elif defined(__arm__) || defined(__aarch64__) // arm big endian / arm64
81  __asm__ __volatile__ ("yield" ::: "memory");
82  #elif defined(__ia64__) // IA64
83  __asm__ __volatile__ ("hint @pause");
84  #elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) // PowerPC
85  __asm__ __volatile__ ("or 27,27,27" ::: "memory");
86  #else // everything else.
87  asm volatile ("nop" ::: "memory"); // default operation - does nothing => Might lead to passive spinning.
88  #endif
89  }
90 
92  static constexpr int_fast32_t max_repetitions{16};
94  int_fast32_t current{1};
95 };
96 
97 } // namespace seqan3::detail
thread
platform.hpp
Provides platform and dependency checks.
std::this_thread::yield
T yield(T... args)