From: dahyeong.kim Date: Mon, 27 May 2013 08:20:01 +0000 (+0900) Subject: Use atomic operation for Reference counting X-Git-Tag: accepted/tizen/20130912.081851^2~291^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=81cb37643704dafd441119799598ea7e4936fabb;p=platform%2Fframework%2Fnative%2Fappfw.git Use atomic operation for Reference counting Change-Id: Icc9d415736013d641028696bbc840cdeca7c15f7 Signed-off-by: dahyeong.kim --- diff --git a/inc/FBaseString.h b/inc/FBaseString.h index 8cd87f9..f9b6fe0 100644 --- a/inc/FBaseString.h +++ b/inc/FBaseString.h @@ -1097,7 +1097,7 @@ private: int __capacity; int __length; mutable int __hash; - mutable int* __pRefCount; + mutable volatile int* __pRefCount; mutable wchar_t* __pValue; static const float GROWTH_FACTOR; diff --git a/src/base/FBaseString.cpp b/src/base/FBaseString.cpp index 03ce90e..e5ff018 100644 --- a/src/base/FBaseString.cpp +++ b/src/base/FBaseString.cpp @@ -37,6 +37,7 @@ #include #include #include +#include "FBase_String.h" namespace Tizen { namespace Base @@ -158,7 +159,7 @@ String::String(const String& value) { SysTryReturnVoidResult(NID_BASE, value.__length >= 0, E_OUT_OF_RANGE, "The length has to be greater than 0."); - ++(*value.__pRefCount); + _String::AtomicInc(value.__pRefCount); __pRefCount = value.__pRefCount; } @@ -171,7 +172,7 @@ String::~String(void) } else { - (*__pRefCount)--; + _String::AtomicDec(__pRefCount); __pRefCount = null; } } @@ -378,7 +379,7 @@ String::Append(const wchar_t* p) SysTryReturnResult(NID_BASE, pRefCntTemp != null, E_OUT_OF_MEMORY, "Memory allocation failed"); wcsncpy(__pValue, pValue, __length); - (*__pRefCount)--; + _String::AtomicDec(__pRefCount); __pRefCount = pRefCntTemp.release(); } @@ -1044,7 +1045,7 @@ String::SetCapacity(int capacity) { std::unique_ptr pRefCntTemp(new (std::nothrow) int(1)); SysTryReturnResult(NID_BASE, pRefCntTemp != null, E_OUT_OF_MEMORY, "Memory allocation failed"); - (*__pRefCount)--; + _String::AtomicDec(__pRefCount); __pRefCount = pRefCntTemp.release(); } } @@ -1514,7 +1515,7 @@ String::ExpandCapacity(int minCapacity) std::unique_ptr pRefCntTemp(new (std::nothrow) int(1)); SysTryReturn(NID_BASE, pRefCntTemp != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY)); - (*__pRefCount)--; + _String::AtomicDec(__pRefCount); __pRefCount = pRefCntTemp.release(); } } @@ -1546,7 +1547,7 @@ String::CopyOnWrite(int capacity) wcsncpy(__pValue, pValue, __length); __pValue[__length] = '\0'; - --(*__pRefCount); + _String::AtomicDec(__pRefCount); __pRefCount = pRefCntTemp.release(); return E_SUCCESS; } diff --git a/src/base/inc/FBase_String.h b/src/base/inc/FBase_String.h new file mode 100644 index 0000000..530968f --- /dev/null +++ b/src/base/inc/FBase_String.h @@ -0,0 +1,78 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file FBase_String.h + * @brief This is the header file for handling atomic operations. + */ + +#ifndef _FBASE_INTERNAL_STRING_H_ +#define _FBASE_INTERNAL_STRING_H_ + +namespace Tizen { namespace Base +{ +namespace _String +{ + +/** + * Atomically add the value to the variable that pRefCount points to. + * + * @since 2.1 + */ +inline int AtomicAdd(volatile int* pRefCount, int value) +{ +#if defined(__arm__) + register int result; + asm volatile ( + "1: ldrex %0, [%1] \n\t" + "add r1, %0, %2 \n\t" + "strex r2, r1, [%1] \n\t" + "cmp r2, #0 \n\t" + "bne 1b" + : "=&r" (result) + : "r"(pRefCount), "r"(value) + : "r1","r2" + ); + return result; +#else + return __sync_fetch_and_add(pRefCount, value); +#endif +} + +/** + * Atomically increase the variable that pRefCount points to by 1 + * + * @since 2.1 + */ +inline int AtomicInc(volatile int* pRefCount) +{ + return AtomicAdd(pRefCount, 1); +} + +/** + * Atomically decrease the variable that pRefCount points to by 1 + * + * @since 2.1 + */ +inline int AtomicDec(volatile int* pRefCount) +{ + return AtomicAdd(pRefCount, -1); +} + +}// _String +}} // Tizen::Base + +#endif // _FBASE_INTERNAL_STRING_H_ \ No newline at end of file