Block-Structured AMR Software Framework
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
AMReX_BlockMutex.H
Go to the documentation of this file.
1#ifndef AMREX_BLOCK_MUTEX_H_
2#define AMREX_BLOCK_MUTEX_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_Gpu.H>
6
7namespace amrex {
8
9#ifdef AMREX_USE_GPU
10
12{
13 union state_t
14 {
15 struct II { int blockid; int count; } data;
16 unsigned long long ull;
17 };
18
20 static constexpr state_t FreeState () noexcept {
21 return state_t{{-1,0}};
22 }
23
24 static void init_states (state_t* state, int N) noexcept;
25
26 explicit BlockMutex (int N) noexcept;
27
28 ~BlockMutex ();
29
30 void operator= (BlockMutex const&) = delete;
31
33 void lock (int i) noexcept {
34#ifdef AMREX_USE_SYCL
35// xxxxx SYCL todo
37#else
38 int blockid = blockIdx.z*blockDim.x*blockDim.y + blockIdx.y*blockDim.x + blockIdx.x;
39 state_t old = m_state[i];
40 state_t assumed;
41 do {
42 assumed = old;
43 state_t val;
44 val.data.blockid = blockid;
45 if (assumed.data.blockid == blockid) {
46 // Already locked by another thread in this block. Need to ++count.
47 val.data.count = assumed.data.count + 1;
48 } else {
49 // Currently unlocked or locked by another block. Need to lock.
50 val.data.count = 1;
51 assumed = FreeState();
52 }
53 old.ull = atomicCAS((unsigned long long*)(m_state+i), assumed.ull, val.ull);
54 } while (assumed.ull != old.ull);
55#endif
56 }
57
59 void unlock (int i) noexcept {
60#ifdef AMREX_USE_SYCL
61// xxxxx SYCL todo
63#else
64 state_t old = m_state[i];
65 state_t assumed;
66 do {
67 assumed = old;
68 state_t val;
69 if (assumed.data.count == 1) {
70 // Need to unlock
71 val = FreeState();
72 } else {
73 // --count, but do NOT unlock
74 val = assumed;
75 --val.data.count;
76 }
77 old.ull = atomicCAS((unsigned long long*)(m_state+i), assumed.ull, val.ull);
78 } while (assumed.ull != old.ull);
79#endif
80 }
81
82private:
83
86};
87#endif
88}
89#endif
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
Definition AMReX_Amr.cpp:49
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition AMReX.H:127
Definition AMReX_BlockMutex.H:15
int blockid
Definition AMReX_BlockMutex.H:15
int count
Definition AMReX_BlockMutex.H:15
Definition AMReX_BlockMutex.H:12
~BlockMutex()
Definition AMReX_BlockMutex.cpp:34
void operator=(BlockMutex const &)=delete
int m_nstates
Definition AMReX_BlockMutex.H:84
state_t * m_state
Definition AMReX_BlockMutex.H:85
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void unlock(int i) noexcept
Definition AMReX_BlockMutex.H:59
static AMREX_GPU_HOST_DEVICE constexpr state_t FreeState() noexcept
Definition AMReX_BlockMutex.H:20
AMREX_GPU_DEVICE AMREX_FORCE_INLINE void lock(int i) noexcept
Definition AMReX_BlockMutex.H:33
static void init_states(state_t *state, int N) noexcept
Definition AMReX_BlockMutex.cpp:7
Definition AMReX_BlockMutex.H:14
struct amrex::BlockMutex::state_t::II data
unsigned long long ull
Definition AMReX_BlockMutex.H:16