RetroArch
barrier.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015-2017 ARM Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SPIRV_CROSS_BARRIER_HPP
18 #define SPIRV_CROSS_BARRIER_HPP
19 
20 #include <atomic>
21 #include <thread>
22 
23 namespace spirv_cross
24 {
25 class Barrier
26 {
27 public:
29  {
30  count.store(0);
31  iteration.store(0);
32  }
33 
35  {
36  this->divisor = divisor;
37  }
38 
39  static inline void memoryBarrier()
40  {
41  std::atomic_thread_fence(std::memory_order_seq_cst);
42  }
43 
45  {
46  count.store(0);
47  iteration.store(0);
48  }
49 
50  void wait()
51  {
52  unsigned target_iteration = iteration.load(std::memory_order_relaxed) + 1;
53  // Overflows cleanly.
54  unsigned target_count = divisor * target_iteration;
55 
56  // Barriers don't enforce memory ordering.
57  // Be as relaxed about the barrier as we possibly can!
58  unsigned c = count.fetch_add(1u, std::memory_order_relaxed);
59 
60  if (c + 1 == target_count)
61  {
62  iteration.store(target_iteration, std::memory_order_relaxed);
63  }
64  else
65  {
66  // If we have more threads than the CPU, don't hog the CPU for very long periods of time.
67  while (iteration.load(std::memory_order_relaxed) != target_iteration)
68  std::this_thread::yield();
69  }
70  }
71 
72 private:
73  unsigned divisor = 1;
74  std::atomic<unsigned> count;
75  std::atomic<unsigned> iteration;
76 };
77 }
78 
79 #endif
GLuint divisor
Definition: glext.h:6953
std::atomic< unsigned > iteration
Definition: barrier.hpp:75
std::atomic< unsigned > count
Definition: barrier.hpp:74
void wait()
Definition: barrier.hpp:50
const GLubyte * c
Definition: glext.h:9812
GLuint GLuint GLsizei count
Definition: glext.h:6292
Barrier()
Definition: barrier.hpp:28
Definition: barrier.hpp:23
void reset_counter()
Definition: barrier.hpp:44
Definition: barrier.hpp:25
unsigned divisor
Definition: barrier.hpp:73
void set_release_divisor(unsigned divisor)
Definition: barrier.hpp:34
static void memoryBarrier()
Definition: barrier.hpp:39