1 //===- Synchronization.h - OpenMP synchronization utilities ------- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // 10 //===----------------------------------------------------------------------===// 11 12 #ifndef OMPTARGET_DEVICERTL_SYNCHRONIZATION_H 13 #define OMPTARGET_DEVICERTL_SYNCHRONIZATION_H 14 15 #include "Types.h" 16 17 namespace _OMP { 18 19 namespace synchronize { 20 21 /// Initialize the synchronization machinery. Must be called by all threads. 22 void init(bool IsSPMD); 23 24 /// Synchronize all threads in a warp identified by \p Mask. 25 void warp(LaneMaskTy Mask); 26 27 /// Synchronize all threads in a block. 28 void threads(); 29 30 /// Synchronizing threads is allowed even if they all hit different instances of 31 /// `synchronize::threads()`. However, `synchronize::threadsAligned()` is more 32 /// restrictive in that it requires all threads to hit the same instance. The 33 /// noinline is removed by the openmp-opt pass and helps to preserve the 34 /// information till then. 35 ///{ 36 #pragma omp begin assumes ext_aligned_barrier 37 38 /// Synchronize all threads in a block, they are are reaching the same 39 /// instruction (hence all threads in the block are "aligned"). 40 __attribute__((noinline)) void threadsAligned(); 41 42 #pragma omp end assumes 43 ///} 44 45 } // namespace synchronize 46 47 namespace fence { 48 49 /// Memory fence with \p Ordering semantics for the team. 50 void team(int Ordering); 51 52 /// Memory fence with \p Ordering semantics for the contention group. 53 void kernel(int Ordering); 54 55 /// Memory fence with \p Ordering semantics for the system. 56 void system(int Ordering); 57 58 } // namespace fence 59 60 namespace atomic { 61 62 /// Atomically load \p Addr with \p Ordering semantics. 63 uint32_t load(uint32_t *Addr, int Ordering); 64 65 /// Atomically store \p V to \p Addr with \p Ordering semantics. 66 void store(uint32_t *Addr, uint32_t V, int Ordering); 67 68 /// Atomically increment \p *Addr and wrap at \p V with \p Ordering semantics. 69 uint32_t inc(uint32_t *Addr, uint32_t V, int Ordering); 70 71 /// Atomically add \p V to \p *Addr with \p Ordering semantics. 72 uint32_t add(uint32_t *Addr, uint32_t V, int Ordering); 73 74 /// Atomically add \p V to \p *Addr with \p Ordering semantics. 75 uint64_t add(uint64_t *Addr, uint64_t V, int Ordering); 76 77 } // namespace atomic 78 79 } // namespace _OMP 80 81 #endif 82