1 //===---------- target_impl.cu - NVPTX OpenMP GPU options ------- CUDA -*-===//
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 // Definitions of target specific functions
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "target_impl.h"
14 #include "common/debug.h"
15 #include "common/target_atomic.h"
16 
17 #define __OMP_SPIN 1000
18 #define UNSET 0u
19 #define SET 1u
20 
__kmpc_impl_init_lock(omp_lock_t * lock)21 EXTERN void __kmpc_impl_init_lock(omp_lock_t *lock) {
22   __kmpc_impl_unset_lock(lock);
23 }
24 
__kmpc_impl_destroy_lock(omp_lock_t * lock)25 EXTERN void __kmpc_impl_destroy_lock(omp_lock_t *lock) {
26   __kmpc_impl_unset_lock(lock);
27 }
28 
__kmpc_impl_set_lock(omp_lock_t * lock)29 EXTERN void __kmpc_impl_set_lock(omp_lock_t *lock) {
30   // TODO: not sure spinning is a good idea here..
31   while (__kmpc_atomic_cas(lock, UNSET, SET) != UNSET) {
32     clock_t start = clock();
33     clock_t now;
34     for (;;) {
35       now = clock();
36       clock_t cycles = now > start ? now - start : now + (0xffffffff - start);
37       if (cycles >= __OMP_SPIN * GetBlockIdInKernel()) {
38         break;
39       }
40     }
41   } // wait for 0 to be the read value
42 }
43 
__kmpc_impl_unset_lock(omp_lock_t * lock)44 EXTERN void __kmpc_impl_unset_lock(omp_lock_t *lock) {
45   (void)__kmpc_atomic_exchange(lock, UNSET);
46 }
47 
__kmpc_impl_test_lock(omp_lock_t * lock)48 EXTERN int __kmpc_impl_test_lock(omp_lock_t *lock) {
49   return __kmpc_atomic_add(lock, 0u);
50 }
51