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 10 namespace 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 /*! intializes 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: BarrierActiveBarrierActive41 BarrierActive () 42 : cntr(0) {} 43 resetBarrierActive44 void reset() { 45 cntr.store(0); 46 } 47 waitBarrierActive48 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: BarrierActiveAutoResetBarrierActiveAutoReset63 BarrierActiveAutoReset () 64 : cntr0(0), cntr1(0) {} 65 waitBarrierActiveAutoReset66 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 /*! intializes 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