1// Copyright 2009-2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include "intrinsics.h"
7#include "sysinfo.h"
8#include "atomic.h"
9
10namespace embree
11{
12 /*! system barrier using operating system */
13 class BarrierSys
14 {
15 public:
16
17 /*! construction / destruction */
18 BarrierSys (size_t N = 0);
19 ~BarrierSys ();
20
21 private:
22 /*! class in non-copyable */
23 BarrierSys (const BarrierSys& other) DELETED; // do not implement
24 BarrierSys& operator= (const BarrierSys& other) DELETED; // do not implement
25
26 public:
27 /*! initializes the barrier with some number of threads */
28 void init(size_t count);
29
30 /*! lets calling thread wait in barrier */
31 void wait();
32
33 private:
34 void* opaque;
35 };
36
37 /*! fast active barrier using atomitc counter */
38 struct BarrierActive
39 {
40 public:
41 BarrierActive ()
42 : cntr(0) {}
43
44 void reset() {
45 cntr.store(0);
46 }
47
48 void wait (size_t numThreads)
49 {
50 cntr++;
51 while (cntr.load() != numThreads)
52 pause_cpu();
53 }
54
55 private:
56 std::atomic<size_t> cntr;
57 };
58
59 /*! fast active barrier that does not require initialization to some number of threads */
60 struct BarrierActiveAutoReset
61 {
62 public:
63 BarrierActiveAutoReset ()
64 : cntr0(0), cntr1(0) {}
65
66 void wait (size_t threadCount)
67 {
68 cntr0.fetch_add(1);
69 while (cntr0 != threadCount) pause_cpu();
70 cntr1.fetch_add(1);
71 while (cntr1 != threadCount) pause_cpu();
72 cntr0.fetch_add(-1);
73 while (cntr0 != 0) pause_cpu();
74 cntr1.fetch_add(-1);
75 while (cntr1 != 0) pause_cpu();
76 }
77
78 private:
79 std::atomic<size_t> cntr0;
80 std::atomic<size_t> cntr1;
81 };
82
83 class LinearBarrierActive
84 {
85 public:
86
87 /*! construction and destruction */
88 LinearBarrierActive (size_t threadCount = 0);
89 ~LinearBarrierActive();
90
91 private:
92 /*! class in non-copyable */
93 LinearBarrierActive (const LinearBarrierActive& other) DELETED; // do not implement
94 LinearBarrierActive& operator= (const LinearBarrierActive& other) DELETED; // do not implement
95
96 public:
97 /*! initializes the barrier with some number of threads */
98 void init(size_t threadCount);
99
100 /*! thread with threadIndex waits in the barrier */
101 void wait (const size_t threadIndex);
102
103 private:
104 volatile unsigned char* count0;
105 volatile unsigned char* count1;
106 volatile unsigned int mode;
107 volatile unsigned int flag0;
108 volatile unsigned int flag1;
109 volatile size_t threadCount;
110 };
111}
112
113