• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef COMMON_INTERFACES_OBJECTS_REF_FIELD_H
17 #define COMMON_INTERFACES_OBJECTS_REF_FIELD_H
18 
19 #include <atomic>
20 #include <functional>
21 #include "objects/base_state_word.h"
22 
23 namespace common {
24 class BaseObject;
25 
26 template <bool isAtomic = false>
27 class RefField {
28 public:
29     static constexpr uint64_t TAG_WEAK = 0x01ULL;
30     static constexpr MAddress REF_UNDEFINED = 0x02ULL;
31     // size in bytes
GetSize()32     static constexpr size_t GetSize()
33     {
34         return sizeof(fieldVal);
35     }
36 
37     BaseObject *GetTargetObject(std::memory_order order = std::memory_order_relaxed) const
38     {
39         if (isAtomic) {
40             MAddress value = __atomic_load_n(&fieldVal, order);
41             return reinterpret_cast<BaseObject *>(RefField<>(value).GetAddress() & (~TAG_WEAK));
42         } else {
43             return reinterpret_cast<BaseObject *>(this->GetAddress() & (~TAG_WEAK));
44         }
45     }
46 
47     MAddress GetFieldValue(std::memory_order order = std::memory_order_relaxed) const
48     {
49         if (isAtomic) {
50             MAddress value = __atomic_load_n(&fieldVal, order);
51             return value;
52         } else {
53             return fieldVal;
54         }
55     }
56 
57     void SetTargetObject(const BaseObject *obj, std::memory_order order = std::memory_order_relaxed)
58     {
59         RefField<> newField(obj);
60         MAddress newVal = newField.GetFieldValue();
61         RefFieldValue oldVal = fieldVal;
62         (void)oldVal;
63 
64         if (isAtomic) {
65             __atomic_store_n(&fieldVal, static_cast<RefFieldValue>(newVal), order);
66         } else {
67             fieldVal = static_cast<RefFieldValue>(newVal);
68         }
69     }
70 
71     void SetFieldValue(MAddress newVal, std::memory_order order = std::memory_order_relaxed)
72     {
73         RefFieldValue oldVal = fieldVal;
74         (void)oldVal;
75 
76         if (isAtomic) {
77             __atomic_store_n(&fieldVal, static_cast<RefFieldValue>(newVal), order);
78         } else {
79             fieldVal = static_cast<RefFieldValue>(newVal);
80         }
81     }
82 
ClearRef(MAddress expectedValue)83     bool ClearRef(MAddress expectedValue)
84     {
85         return CompareExchange(expectedValue, REF_UNDEFINED);
86     }
87 
88     bool CompareExchange(MAddress expectedValue, MAddress newValue,
89                          std::memory_order succOrder = std::memory_order_relaxed,
90                          std::memory_order failOrder = std::memory_order_relaxed)
91     {
92         return __atomic_compare_exchange(&fieldVal, &expectedValue, &newValue, false, succOrder, failOrder);
93     }
94 
95     bool CompareExchange(const BaseObject *expectedObj, const BaseObject *newObj,
96                          std::memory_order succOrder = std::memory_order_relaxed,
97                          std::memory_order failOrder = std::memory_order_relaxed)
98     {
99         return CompareExchange(reinterpret_cast<MAddress>(expectedObj), reinterpret_cast<MAddress>(newObj), succOrder,
100                                failOrder);
101     }
102 
103     MAddress Exchange(MAddress newRef, std::memory_order order = std::memory_order_relaxed)
104     {
105         MAddress ret = 0;
106         __atomic_exchange(&fieldVal, &newRef, &ret, order);
107         return static_cast<MAddress>(ret);
108     }
109 
110     MAddress Exchange(const BaseObject *obj, std::memory_order order = std::memory_order_relaxed)
111     {
112         return Exchange(reinterpret_cast<MAddress>(obj), order);
113     }
114 
GetAddress()115     MAddress GetAddress() const
116     {
117         return address;
118     }
119 
IsWeak()120     bool IsWeak() const
121     {
122         return (address & TAG_WEAK);
123     }
124 
125     // bool IsTagged() const { return isTagged == 1; }
IsTagged()126     bool IsTagged() const
127     {
128         return false;
129     }
GetTagID()130     uint16_t GetTagID() const
131     {
132         return tagID;
133     }
134 
135     ~RefField() = default;
RefField(MAddress val)136     explicit RefField(MAddress val) : fieldVal(val) {}
RefField(const RefField & ref)137     RefField(const RefField &ref) : fieldVal(ref.fieldVal) {}
RefField(const BaseObject * obj)138     explicit RefField(const BaseObject *obj) : fieldVal(0)
139     {
140         address = reinterpret_cast<MAddress>(obj);
141     }
RefField(const BaseObject * obj,bool forWeak)142     RefField(const BaseObject* obj, bool forWeak) : fieldVal(0)
143     {
144         MAddress tag = forWeak ? TAG_WEAK : 0;
145         address = reinterpret_cast<MAddress>(obj) | tag;
146     }
RefField(const BaseObject * obj,uint16_t tagged,uint16_t tagid)147     RefField(const BaseObject *obj, uint16_t tagged, uint16_t tagid)
148         : address(reinterpret_cast<MAddress>(obj)), isTagged(tagged), tagID(tagid), padding(0)
149     {
150     }
151 
RefField(RefField && ref)152     RefField(RefField &&ref) : fieldVal(ref.fieldVal) {}
153     RefField() = delete;
154     RefField &operator=(const RefField &) = delete;
155     RefField &operator=(const RefField &&) = delete;
156 
157 private:
158     using RefFieldValue = MAddress;
159 
160     union {
161         struct {
162             MAddress address : 48;
163             MAddress isTagged : 1;
164             MAddress tagID : 1;
165             MAddress padding : 14;
166         };
167         RefFieldValue fieldVal;
168     };
169 };
170 }  // namespace common
171 #endif  // COMMON_INTERFACES_OBJECTS_REF_FIELD_H
172