2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/public-api/object/ref-object.h>
22 #include <dali/public-api/common/dali-common.h>
30 RefObject::RefObject()
35 RefObject::RefObject(const RefObject&)
36 : mCount(0) // Do not copy the reference count
40 RefObject::~RefObject()
45 DALI_LOG_ERROR("mCount should be zero, deleting referenced object!");
47 #endif // ENABLE_DEBUG
50 RefObject& RefObject::operator=(const RefObject&)
52 // Do not copy the reference count
56 void RefObject::Reference()
58 // The inline assembly below was tested on an ARMv8 64 bit platform on
59 // 2015-02-06 and found to run in 11.8 nanoseconds, whereas
60 // __sync_add_and_fetch( address, 1 ) required 18.8 nanoseconds.
61 // Including the assembly here produced one fewer assembly instruction than if
62 // it was wrapped in a function and inlined here by the compiler.
63 #if defined __aarch64__
66 "1:\tldxr w1, %[address] \n\t"
67 "add w1, w1, %[one] \n\t"
68 "stxr w2, w1, %[address] \n\t"
71 : // Q = A memory address with no offset
72 // ( https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints )
73 [address] "+Q" (mCount)
76 // Clobbers: (explicitly clobber w1 register to hold the loaded value and
77 // register w2 to hold success/fail):
81 // 32 bit ARMv7 version of above:
82 // Better than the code emitted by GCC for __sync_add_and_fetch(), as that
83 // includes two dmb memory barrier instructions: one before and one after the
88 "1:\tldrex r1, %[address] \n\t"
89 "add r1, r1, %[one] \n\t"
90 "strex r2, r1, %[address] \n\t"
91 "teq r2, %[zero] \n\t"
94 : [address] "+Q" (mCount)
98 // Clobbers: (modified registers):
104 // gcc > 4.1 builtin atomic add and fetch:
105 __sync_add_and_fetch( &mCount, 1 );
110 void RefObject::Unreference()
112 // The output register:
115 #if defined __aarch64__
118 "1:\tldxr %w[newValue], %[address] \n\t"
119 "sub %w[newValue], %w[newValue], %[one] \n\t"
120 "stxr w2, %w[newValue], %[address] \n\t"
123 : [newValue] "=&r" (newValue),
124 // Q = A memory address with no offset
125 // ( https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints )
126 [address] "+Q" (mCount)
129 // Clobbered: I.e., stuff that is modified.
133 #elif defined __arm__
136 "1:\tldrex %[newValue], %[address] \n\t"
137 "sub %[newValue], %[newValue], %[one] \n\t"
138 "strex r2, %[newValue], %[address] \n\t"
139 "teq r2, %[zero] \n\t"
142 : [newValue] "=&r" (newValue),
143 [address] "+Q" (mCount)
153 // gcc > 4.1 builtin atomic subtract and fetch (--mCount; return mCount)
154 newValue = __sync_sub_and_fetch( &mCount, 1 );
164 int RefObject::ReferenceCount()