Warning: This file is not a C or C++ file. It does not have highlighting.

1//===---- ExclusiveAccess.h - Helper for exclusive access data structures -===//
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#ifndef OMPTARGET_EXCLUSIVE_ACCESS
12#define OMPTARGET_EXCLUSIVE_ACCESS
13
14#include <cassert>
15#include <cstddef>
16#include <cstdint>
17#include <mutex>
18
19/// Forward declaration.
20template <typename Ty> struct Accessor;
21
22/// A protected object is a simple wrapper to allocate an object of type \p Ty
23/// together with a mutex that guards accesses to the object. The only way to
24/// access the object is through the "exclusive accessor" which will lock the
25/// mutex accordingly.
26template <typename Ty> struct ProtectedObj {
27 using AccessorTy = Accessor<Ty>;
28
29 /// Get an exclusive access Accessor object. \p DoNotGetAccess allows to
30 /// create an accessor that is not owning anything based on a boolean
31 /// condition.
32 AccessorTy getExclusiveAccessor(bool DoNotGetAccess = false);
33
34private:
35 Ty Obj;
36 std::mutex Mtx;
37 friend struct Accessor<Ty>;
38};
39
40/// Helper to provide transparent exclusive access to protected objects.
41template <typename Ty> struct Accessor {
42 /// Default constructor does not own anything and cannot access anything.
43 Accessor() : Ptr(nullptr) {}
44
45 /// Constructor to get exclusive access by locking the mutex protecting the
46 /// underlying object.
47 Accessor(ProtectedObj<Ty> &PO) : Ptr(&PO) { lock(); }
48
49 /// Constructor to get exclusive access by taking it from \p Other.
50 Accessor(Accessor<Ty> &&Other) : Ptr(Other.Ptr) { Other.Ptr = nullptr; }
51
52 Accessor(Accessor &Other) = delete;
53
54 /// If the object is still owned when the lifetime ends we give up access.
55 ~Accessor() { unlock(); }
56
57 /// Give up access to the underlying object, virtually "destroying" the
58 /// accessor even if the object is still life.
59 void destroy() {
60 unlock();
61 Ptr = nullptr;
62 }
63
64 /// Provide transparent access to the underlying object.
65 Ty &operator*() {
66 assert(Ptr && "Trying to access an object through a non-owning (or "
67 "destroyed) accessor!");
68 return Ptr->Obj;
69 }
70 Ty *operator->() {
71 assert(Ptr && "Trying to access an object through a non-owning (or "
72 "destroyed) accessor!");
73 return &Ptr->Obj;
74 }
75
76private:
77 /// Lock the underlying object if there is one.
78 void lock() {
79 if (Ptr)
80 Ptr->Mtx.lock();
81 }
82
83 /// Unlock the underlying object if there is one.
84 void unlock() {
85 if (Ptr)
86 Ptr->Mtx.unlock();
87 }
88
89 /// Pointer to the underlying object or null if the accessor lost access,
90 /// e.g., after a destroy call.
91 ProtectedObj<Ty> *Ptr;
92};
93
94template <typename Ty>
95Accessor<Ty> ProtectedObj<Ty>::getExclusiveAccessor(bool DoNotGetAccess) {
96 if (DoNotGetAccess)
97 return Accessor<Ty>();
98 return Accessor<Ty>(*this);
99}
100
101#endif
102

Warning: This file is not a C or C++ file. It does not have highlighting.

source code of offload/include/ExclusiveAccess.h