diff options
Diffstat (limited to 'runtimes/nn/depend/libutils')
-rw-r--r-- | runtimes/nn/depend/libutils/CMakeLists.txt | 22 | ||||
-rw-r--r-- | runtimes/nn/depend/libutils/RefBase.cpp | 809 | ||||
-rw-r--r-- | runtimes/nn/depend/libutils/StrongPointer.cpp | 29 | ||||
-rw-r--r-- | runtimes/nn/depend/libutils/include/utils/Compat.h | 87 | ||||
-rw-r--r-- | runtimes/nn/depend/libutils/include/utils/Errors.h | 88 | ||||
-rw-r--r-- | runtimes/nn/depend/libutils/include/utils/LightRefBase.h | 72 | ||||
-rw-r--r-- | runtimes/nn/depend/libutils/include/utils/RefBase.h | 690 | ||||
-rw-r--r-- | runtimes/nn/depend/libutils/include/utils/StrongPointer.h | 245 | ||||
-rw-r--r-- | runtimes/nn/depend/libutils/include/utils/TypeHelpers.h | 336 |
9 files changed, 0 insertions, 2378 deletions
diff --git a/runtimes/nn/depend/libutils/CMakeLists.txt b/runtimes/nn/depend/libutils/CMakeLists.txt deleted file mode 100644 index 343389ed7..000000000 --- a/runtimes/nn/depend/libutils/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ - -SET(CUR_INCS - ${CMAKE_CURRENT_SOURCE_DIR}/include -) - - -SET(INC_DIRS - ${INC_DIRS} - ${CUR_INCS} - PARENT_SCOPE -) - -SET(CUR_SRCS - ${CMAKE_CURRENT_SOURCE_DIR}/RefBase.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/StrongPointer.cpp -) - -SET(SRCS - ${SRCS} - ${CUR_SRCS} - PARENT_SCOPE -) diff --git a/runtimes/nn/depend/libutils/RefBase.cpp b/runtimes/nn/depend/libutils/RefBase.cpp deleted file mode 100644 index 7f9c95b31..000000000 --- a/runtimes/nn/depend/libutils/RefBase.cpp +++ /dev/null @@ -1,809 +0,0 @@ -/* - * Copyright (C) 2005 The Android Open Source Project - * - * 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. - */ - -#define LOG_TAG "RefBase" -// #define LOG_NDEBUG 0 - -#include <utils/RefBase.h> - -//#include <utils/CallStack.h> -#if 0 // REF-ANN -#include <log/log.h> -#endif // REF-ANN -#ifndef __unused -#define __unused __attribute__((__unused__)) -#endif - -// compile with refcounting debugging enabled -#define DEBUG_REFS 0 - -// whether ref-tracking is enabled by default, if not, trackMe(true, false) -// needs to be called explicitly -#define DEBUG_REFS_ENABLED_BY_DEFAULT 0 - -// whether callstack are collected (significantly slows things down) -#define DEBUG_REFS_CALLSTACK_ENABLED 1 - -// folder where stack traces are saved when DEBUG_REFS is enabled -// this folder needs to exist and be writable -#define DEBUG_REFS_CALLSTACK_PATH "/data/debug" - -// log all reference counting operations -#define PRINT_REFS 0 - -// --------------------------------------------------------------------------- - -namespace android { - -// Observations, invariants, etc: - -// By default, obects are destroyed when the last strong reference disappears -// or, if the object never had a strong reference, when the last weak reference -// disappears. -// -// OBJECT_LIFETIME_WEAK changes this behavior to retain the object -// unconditionally until the last reference of either kind disappears. The -// client ensures that the extendObjectLifetime call happens before the dec -// call that would otherwise have deallocated the object, or before an -// attemptIncStrong call that might rely on it. We do not worry about -// concurrent changes to the object lifetime. -// -// AttemptIncStrong will succeed if the object has a strong reference, or if it -// has a weak reference and has never had a strong reference. -// AttemptIncWeak really does succeed only if there is already a WEAK -// reference, and thus may fail when attemptIncStrong would succeed. -// -// mStrong is the strong reference count. mWeak is the weak reference count. -// Between calls, and ignoring memory ordering effects, mWeak includes strong -// references, and is thus >= mStrong. -// -// A weakref_impl holds all the information, including both reference counts, -// required to perform wp<> operations. Thus these can continue to be performed -// after the RefBase object has been destroyed. -// -// A weakref_impl is allocated as the value of mRefs in a RefBase object on -// construction. -// In the OBJECT_LIFETIME_STRONG case, it is normally deallocated in decWeak, -// and hence lives as long as the last weak reference. (It can also be -// deallocated in the RefBase destructor iff the strong reference count was -// never incremented and the weak count is zero, e.g. if the RefBase object is -// explicitly destroyed without decrementing the strong count. This should be -// avoided.) In this case, the RefBase destructor should be invoked from -// decStrong. -// In the OBJECT_LIFETIME_WEAK case, the weakref_impl is always deallocated in -// the RefBase destructor, which is always invoked by decWeak. DecStrong -// explicitly avoids the deletion in this case. -// -// Memory ordering: -// The client must ensure that every inc() call, together with all other -// accesses to the object, happens before the corresponding dec() call. -// -// We try to keep memory ordering constraints on atomics as weak as possible, -// since memory fences or ordered memory accesses are likely to be a major -// performance cost for this code. All accesses to mStrong, mWeak, and mFlags -// explicitly relax memory ordering in some way. -// -// The only operations that are not memory_order_relaxed are reference count -// decrements. All reference count decrements are release operations. In -// addition, the final decrement leading the deallocation is followed by an -// acquire fence, which we can view informally as also turning it into an -// acquire operation. (See 29.8p4 [atomics.fences] for details. We could -// alternatively use acq_rel operations for all decrements. This is probably -// slower on most current (2016) hardware, especially on ARMv7, but that may -// not be true indefinitely.) -// -// This convention ensures that the second-to-last decrement synchronizes with -// (in the language of 1.10 in the C++ standard) the final decrement of a -// reference count. Since reference counts are only updated using atomic -// read-modify-write operations, this also extends to any earlier decrements. -// (See "release sequence" in 1.10.) -// -// Since all operations on an object happen before the corresponding reference -// count decrement, and all reference count decrements happen before the final -// one, we are guaranteed that all other object accesses happen before the -// object is destroyed. - - -#define INITIAL_STRONG_VALUE (1<<28) - -#define MAX_COUNT 0xfffff - -// Test whether the argument is a clearly invalid strong reference count. -// Used only for error checking on the value before an atomic decrement. -// Intended to be very cheap. -// Note that we cannot just check for excess decrements by comparing to zero -// since the object would be deallocated before that. -#define BAD_STRONG(c) \ - ((c) == 0 || ((c) & (~(MAX_COUNT | INITIAL_STRONG_VALUE))) != 0) - -// Same for weak counts. -#define BAD_WEAK(c) ((c) == 0 || ((c) & (~MAX_COUNT)) != 0) - -// --------------------------------------------------------------------------- - -class RefBase::weakref_impl : public RefBase::weakref_type -{ -public: - std::atomic<int32_t> mStrong; - std::atomic<int32_t> mWeak; - RefBase* const mBase; - std::atomic<int32_t> mFlags; - -#if !DEBUG_REFS - - explicit weakref_impl(RefBase* base) - : mStrong(INITIAL_STRONG_VALUE) - , mWeak(0) - , mBase(base) - , mFlags(0) - { - } - - void addStrongRef(const void* /*id*/) { } - void removeStrongRef(const void* /*id*/) { } - void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { } - void addWeakRef(const void* /*id*/) { } - void removeWeakRef(const void* /*id*/) { } - void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { } - void printRefs() const { } - void trackMe(bool, bool) { } - -#else - - weakref_impl(RefBase* base) - : mStrong(INITIAL_STRONG_VALUE) - , mWeak(0) - , mBase(base) - , mFlags(0) - , mStrongRefs(NULL) - , mWeakRefs(NULL) - , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT) - , mRetain(false) - { - } - - ~weakref_impl() - { - bool dumpStack = false; - if (!mRetain && mStrongRefs != NULL) { - dumpStack = true; - ALOGE("Strong references remain:"); - ref_entry* refs = mStrongRefs; - while (refs) { - char inc = refs->ref >= 0 ? '+' : '-'; -#if 0 // REF-ANN - ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref); -#endif // REF-ANN - -#if DEBUG_REFS_CALLSTACK_ENABLED - refs->stack.log(LOG_TAG); -#endif - refs = refs->next; - } - } - - if (!mRetain && mWeakRefs != NULL) { - dumpStack = true; -#if 0 // REF-ANN - ALOGE("Weak references remain!"); -#endif // REF-ANN - ref_entry* refs = mWeakRefs; - while (refs) { - char inc = refs->ref >= 0 ? '+' : '-'; -#if 0 // REF-ANN - ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref); -#endif // REF-ANN -#if DEBUG_REFS_CALLSTACK_ENABLED - refs->stack.log(LOG_TAG); -#endif - refs = refs->next; - } - } - if (dumpStack) { -#if 0 // REF-ANN - ALOGE("above errors at:"); -#endif // REF-ANN - //CallStack stack(LOG_TAG); - } - } - - void addStrongRef(const void* id) { - //ALOGD_IF(mTrackEnabled, - // "addStrongRef: RefBase=%p, id=%p", mBase, id); - addRef(&mStrongRefs, id, mStrong.load(std::memory_order_relaxed)); - } - - void removeStrongRef(const void* id) { - //ALOGD_IF(mTrackEnabled, - // "removeStrongRef: RefBase=%p, id=%p", mBase, id); - if (!mRetain) { - removeRef(&mStrongRefs, id); - } else { - addRef(&mStrongRefs, id, -mStrong.load(std::memory_order_relaxed)); - } - } - - void renameStrongRefId(const void* old_id, const void* new_id) { - //ALOGD_IF(mTrackEnabled, - // "renameStrongRefId: RefBase=%p, oid=%p, nid=%p", - // mBase, old_id, new_id); - renameRefsId(mStrongRefs, old_id, new_id); - } - - void addWeakRef(const void* id) { - addRef(&mWeakRefs, id, mWeak.load(std::memory_order_relaxed)); - } - - void removeWeakRef(const void* id) { - if (!mRetain) { - removeRef(&mWeakRefs, id); - } else { - addRef(&mWeakRefs, id, -mWeak.load(std::memory_order_relaxed)); - } - } - - void renameWeakRefId(const void* old_id, const void* new_id) { - renameRefsId(mWeakRefs, old_id, new_id); - } - - void trackMe(bool track, bool retain) - { - mTrackEnabled = track; - mRetain = retain; - } - - void printRefs() const - { - String8 text; - - { - Mutex::Autolock _l(mMutex); - char buf[128]; - snprintf(buf, sizeof(buf), - "Strong references on RefBase %p (weakref_type %p):\n", - mBase, this); - text.append(buf); - printRefsLocked(&text, mStrongRefs); - snprintf(buf, sizeof(buf), - "Weak references on RefBase %p (weakref_type %p):\n", - mBase, this); - text.append(buf); - printRefsLocked(&text, mWeakRefs); - } - - { - char name[100]; - snprintf(name, sizeof(name), DEBUG_REFS_CALLSTACK_PATH "/%p.stack", - this); - int rc = open(name, O_RDWR | O_CREAT | O_APPEND, 644); - if (rc >= 0) { - write(rc, text.string(), text.length()); - close(rc); -#if 0 // REF-ANN - ALOGD("STACK TRACE for %p saved in %s", this, name); -#endif // REF-ANN - } -#if 0 // REF-ANN - else ALOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this, - name, strerror(errno)); -#endif // REF-ANN - } - } - -private: - struct ref_entry - { - ref_entry* next; - const void* id; -#if DEBUG_REFS_CALLSTACK_ENABLED - CallStack stack; -#endif - int32_t ref; - }; - - void addRef(ref_entry** refs, const void* id, int32_t mRef) - { - if (mTrackEnabled) { - AutoMutex _l(mMutex); - - ref_entry* ref = new ref_entry; - // Reference count at the time of the snapshot, but before the - // update. Positive value means we increment, negative--we - // decrement the reference count. - ref->ref = mRef; - ref->id = id; -#if DEBUG_REFS_CALLSTACK_ENABLED - ref->stack.update(2); -#endif - ref->next = *refs; - *refs = ref; - } - } - - void removeRef(ref_entry** refs, const void* id) - { - if (mTrackEnabled) { - AutoMutex _l(mMutex); - - ref_entry* const head = *refs; - ref_entry* ref = head; - while (ref != NULL) { - if (ref->id == id) { - *refs = ref->next; - delete ref; - return; - } - refs = &ref->next; - ref = *refs; - } - -#if 0 // REF-ANN - ALOGE("RefBase: removing id %p on RefBase %p" - "(weakref_type %p) that doesn't exist!", - id, mBase, this); -#endif // REF-ANN - - ref = head; - while (ref) { - char inc = ref->ref >= 0 ? '+' : '-'; -#if 0 // REF-ANN - ALOGD("\t%c ID %p (ref %d):", inc, ref->id, ref->ref); -#endif // REF-ANN - ref = ref->next; - } - - //CallStack stack(LOG_TAG); - } - } - - void renameRefsId(ref_entry* r, const void* old_id, const void* new_id) - { - if (mTrackEnabled) { - AutoMutex _l(mMutex); - ref_entry* ref = r; - while (ref != NULL) { - if (ref->id == old_id) { - ref->id = new_id; - } - ref = ref->next; - } - } - } - - void printRefsLocked(String8* out, const ref_entry* refs) const - { - char buf[128]; - while (refs) { - char inc = refs->ref >= 0 ? '+' : '-'; - snprintf(buf, sizeof(buf), "\t%c ID %p (ref %d):\n", - inc, refs->id, refs->ref); - out->append(buf); -#if DEBUG_REFS_CALLSTACK_ENABLED - out->append(refs->stack.toString("\t\t")); -#else - out->append("\t\t(call stacks disabled)"); -#endif - refs = refs->next; - } - } - - mutable Mutex mMutex; - ref_entry* mStrongRefs; - ref_entry* mWeakRefs; - - bool mTrackEnabled; - // Collect stack traces on addref and removeref, instead of deleting the stack references - // on removeref that match the address ones. - bool mRetain; - -#endif -}; - -// --------------------------------------------------------------------------- - -void RefBase::incStrong(const void* id) const -{ - weakref_impl* const refs = mRefs; - refs->incWeak(id); - - refs->addStrongRef(id); - const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed); -#if 0 // REF-ANN - ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); -#endif // REF-ANN -#if PRINT_REFS -#if 0 // REF-ANN - ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c); -#endif // REF-ANN -#endif - if (c != INITIAL_STRONG_VALUE) { - return; - } - - int32_t old = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE, - std::memory_order_relaxed); - // A decStrong() must still happen after us. -#if 0 // REF-ANN - ALOG_ASSERT(old > INITIAL_STRONG_VALUE, "0x%x too small", old); -#endif // REF-ANN - refs->mBase->onFirstRef(); -} - -void RefBase::decStrong(const void* id) const -{ - weakref_impl* const refs = mRefs; - refs->removeStrongRef(id); - const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release); -#if PRINT_REFS -#if 0 // REF-ANN - ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c); -#endif // REF-ANN -#endif -#if 0 // REF-ANN - LOG_ALWAYS_FATAL_IF(BAD_STRONG(c), "decStrong() called on %p too many times", - refs); -#endif // REF-ANN - if (c == 1) { - std::atomic_thread_fence(std::memory_order_acquire); - refs->mBase->onLastStrongRef(id); - int32_t flags = refs->mFlags.load(std::memory_order_relaxed); - if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { - delete this; - // The destructor does not delete refs in this case. - } - } - // Note that even with only strong reference operations, the thread - // deallocating this may not be the same as the thread deallocating refs. - // That's OK: all accesses to this happen before its deletion here, - // and all accesses to refs happen before its deletion in the final decWeak. - // The destructor can safely access mRefs because either it's deleting - // mRefs itself, or it's running entirely before the final mWeak decrement. - refs->decWeak(id); -} - -void RefBase::forceIncStrong(const void* id) const -{ - // Allows initial mStrong of 0 in addition to INITIAL_STRONG_VALUE. - // TODO: Better document assumptions. - weakref_impl* const refs = mRefs; - refs->incWeak(id); - - refs->addStrongRef(id); - const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed); -#if 0 // REF-ANN - ALOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow", - refs); -#endif // REF-ANN -#if PRINT_REFS -#if 0 // REF-ANN - ALOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c); -#endif // REF-ANN -#endif - - switch (c) { - case INITIAL_STRONG_VALUE: - refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE, - std::memory_order_relaxed); - // fall through... - case 0: - refs->mBase->onFirstRef(); - } -} - -int32_t RefBase::getStrongCount() const -{ - // Debugging only; No memory ordering guarantees. - return mRefs->mStrong.load(std::memory_order_relaxed); -} - -RefBase* RefBase::weakref_type::refBase() const -{ - return static_cast<const weakref_impl*>(this)->mBase; -} - -void RefBase::weakref_type::incWeak(const void* id) -{ - weakref_impl* const impl = static_cast<weakref_impl*>(this); - impl->addWeakRef(id); - const int32_t c __unused = impl->mWeak.fetch_add(1, - std::memory_order_relaxed); -#if 0 // REF-ANN - ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this); -#endif // REF-ANN -} - - -void RefBase::weakref_type::decWeak(const void* id) -{ - weakref_impl* const impl = static_cast<weakref_impl*>(this); - impl->removeWeakRef(id); - const int32_t c = impl->mWeak.fetch_sub(1, std::memory_order_release); -#if 0 // REF-ANN - LOG_ALWAYS_FATAL_IF(BAD_WEAK(c), "decWeak called on %p too many times", - this); -#endif // REF-ANN - if (c != 1) return; - atomic_thread_fence(std::memory_order_acquire); - - int32_t flags = impl->mFlags.load(std::memory_order_relaxed); - if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { - // This is the regular lifetime case. The object is destroyed - // when the last strong reference goes away. Since weakref_impl - // outlives the object, it is not destroyed in the dtor, and - // we'll have to do it here. - if (impl->mStrong.load(std::memory_order_relaxed) - == INITIAL_STRONG_VALUE) { - // Decrementing a weak count to zero when object never had a strong - // reference. We assume it acquired a weak reference early, e.g. - // in the constructor, and will eventually be properly destroyed, - // usually via incrementing and decrementing the strong count. - // Thus we no longer do anything here. We log this case, since it - // seems to be extremely rare, and should not normally occur. We - // used to deallocate mBase here, so this may now indicate a leak. -#if 0 // REF-ANN - ALOGW("RefBase: Object at %p lost last weak reference " - "before it had a strong reference", impl->mBase); -#endif // REF-ANN - } else { - // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase); - delete impl; - } - } else { - // This is the OBJECT_LIFETIME_WEAK case. The last weak-reference - // is gone, we can destroy the object. - impl->mBase->onLastWeakRef(id); - delete impl->mBase; - } -} - -bool RefBase::weakref_type::attemptIncStrong(const void* id) -{ - incWeak(id); - - weakref_impl* const impl = static_cast<weakref_impl*>(this); - int32_t curCount = impl->mStrong.load(std::memory_order_relaxed); - -#if 0 // REF-ANN - ALOG_ASSERT(curCount >= 0, - "attemptIncStrong called on %p after underflow", this); -#endif // REF-ANN - while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) { - // we're in the easy/common case of promoting a weak-reference - // from an existing strong reference. - if (impl->mStrong.compare_exchange_weak(curCount, curCount+1, - std::memory_order_relaxed)) { - break; - } - // the strong count has changed on us, we need to re-assert our - // situation. curCount was updated by compare_exchange_weak. - } - - if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) { - // we're now in the harder case of either: - // - there never was a strong reference on us - // - or, all strong references have been released - int32_t flags = impl->mFlags.load(std::memory_order_relaxed); - if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { - // this object has a "normal" life-time, i.e.: it gets destroyed - // when the last strong reference goes away - if (curCount <= 0) { - // the last strong-reference got released, the object cannot - // be revived. - decWeak(id); - return false; - } - - // here, curCount == INITIAL_STRONG_VALUE, which means - // there never was a strong-reference, so we can try to - // promote this object; we need to do that atomically. - while (curCount > 0) { - if (impl->mStrong.compare_exchange_weak(curCount, curCount+1, - std::memory_order_relaxed)) { - break; - } - // the strong count has changed on us, we need to re-assert our - // situation (e.g.: another thread has inc/decStrong'ed us) - // curCount has been updated. - } - - if (curCount <= 0) { - // promote() failed, some other thread destroyed us in the - // meantime (i.e.: strong count reached zero). - decWeak(id); - return false; - } - } else { - // this object has an "extended" life-time, i.e.: it can be - // revived from a weak-reference only. - // Ask the object's implementation if it agrees to be revived - if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) { - // it didn't so give-up. - decWeak(id); - return false; - } - // grab a strong-reference, which is always safe due to the - // extended life-time. - curCount = impl->mStrong.fetch_add(1, std::memory_order_relaxed); - // If the strong reference count has already been incremented by - // someone else, the implementor of onIncStrongAttempted() is holding - // an unneeded reference. So call onLastStrongRef() here to remove it. - // (No, this is not pretty.) Note that we MUST NOT do this if we - // are in fact acquiring the first reference. - if (curCount != 0 && curCount != INITIAL_STRONG_VALUE) { - impl->mBase->onLastStrongRef(id); - } - } - } - - impl->addStrongRef(id); - -#if PRINT_REFS -#if 0 // REF-ANN - ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount); -#endif // REF-ANN -#endif - - // curCount is the value of mStrong before we incremented it. - // Now we need to fix-up the count if it was INITIAL_STRONG_VALUE. - // This must be done safely, i.e.: handle the case where several threads - // were here in attemptIncStrong(). - // curCount > INITIAL_STRONG_VALUE is OK, and can happen if we're doing - // this in the middle of another incStrong. The subtraction is handled - // by the thread that started with INITIAL_STRONG_VALUE. - if (curCount == INITIAL_STRONG_VALUE) { - impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE, - std::memory_order_relaxed); - } - - return true; -} - -bool RefBase::weakref_type::attemptIncWeak(const void* id) -{ - weakref_impl* const impl = static_cast<weakref_impl*>(this); - - int32_t curCount = impl->mWeak.load(std::memory_order_relaxed); -#if 0 // REF-ANN - ALOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow", - this); -#endif // REF-ANN - while (curCount > 0) { - if (impl->mWeak.compare_exchange_weak(curCount, curCount+1, - std::memory_order_relaxed)) { - break; - } - // curCount has been updated. - } - - if (curCount > 0) { - impl->addWeakRef(id); - } - - return curCount > 0; -} - -int32_t RefBase::weakref_type::getWeakCount() const -{ - // Debug only! - return static_cast<const weakref_impl*>(this)->mWeak - .load(std::memory_order_relaxed); -} - -void RefBase::weakref_type::printRefs() const -{ - static_cast<const weakref_impl*>(this)->printRefs(); -} - -void RefBase::weakref_type::trackMe(bool enable, bool retain) -{ - static_cast<weakref_impl*>(this)->trackMe(enable, retain); -} - -RefBase::weakref_type* RefBase::createWeak(const void* id) const -{ - mRefs->incWeak(id); - return mRefs; -} - -RefBase::weakref_type* RefBase::getWeakRefs() const -{ - return mRefs; -} - -RefBase::RefBase() - : mRefs(new weakref_impl(this)) -{ -} - -RefBase::~RefBase() -{ - int32_t flags = mRefs->mFlags.load(std::memory_order_relaxed); - // Life-time of this object is extended to WEAK, in - // which case weakref_impl doesn't out-live the object and we - // can free it now. - if ((flags & OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) { - // It's possible that the weak count is not 0 if the object - // re-acquired a weak reference in its destructor - if (mRefs->mWeak.load(std::memory_order_relaxed) == 0) { - delete mRefs; - } - } else if (mRefs->mStrong.load(std::memory_order_relaxed) - == INITIAL_STRONG_VALUE) { - // We never acquired a strong reference on this object. -#if 0 // REF-ANN - LOG_ALWAYS_FATAL_IF(mRefs->mWeak.load() != 0, - "RefBase: Explicit destruction with non-zero weak " - "reference count"); -#endif // REF-ANN - // TODO: Always report if we get here. Currently MediaMetadataRetriever - // C++ objects are inconsistently managed and sometimes get here. - // There may be other cases, but we believe they should all be fixed. - delete mRefs; - } - // For debugging purposes, clear mRefs. Ineffective against outstanding wp's. - const_cast<weakref_impl*&>(mRefs) = NULL; -} - -void RefBase::extendObjectLifetime(int32_t mode) -{ - // Must be happens-before ordered with respect to construction or any - // operation that could destroy the object. - mRefs->mFlags.fetch_or(mode, std::memory_order_relaxed); -} - -void RefBase::onFirstRef() -{ -} - -void RefBase::onLastStrongRef(const void* /*id*/) -{ -} - -bool RefBase::onIncStrongAttempted(uint32_t flags, const void* /*id*/) -{ - return (flags&FIRST_INC_STRONG) ? true : false; -} - -void RefBase::onLastWeakRef(const void* /*id*/) -{ -} - -// --------------------------------------------------------------------------- - -#if DEBUG_REFS -void RefBase::renameRefs(size_t n, const ReferenceRenamer& renamer) { - for (size_t i=0 ; i<n ; i++) { - renamer(i); - } -} -#else -void RefBase::renameRefs(size_t /*n*/, const ReferenceRenamer& /*renamer*/) { } -#endif - -void RefBase::renameRefId(weakref_type* ref, - const void* old_id, const void* new_id) { - weakref_impl* const impl = static_cast<weakref_impl*>(ref); - impl->renameStrongRefId(old_id, new_id); - impl->renameWeakRefId(old_id, new_id); -} - -void RefBase::renameRefId(RefBase* ref, - const void* old_id, const void* new_id) { - ref->mRefs->renameStrongRefId(old_id, new_id); - ref->mRefs->renameWeakRefId(old_id, new_id); -} - -}; // namespace android diff --git a/runtimes/nn/depend/libutils/StrongPointer.cpp b/runtimes/nn/depend/libutils/StrongPointer.cpp deleted file mode 100644 index 619a81c86..000000000 --- a/runtimes/nn/depend/libutils/StrongPointer.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * 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. - */ - -#if 0 // REF-ANN -#define LOG_TAG "sp" - -#include <log/log.h> -#endif // REF-ANN - -namespace android { - -void sp_report_race() { } -#if 0 // REF-ANN -void sp_report_race() { LOG_ALWAYS_FATAL("sp<> assignment detected data race"); } -#endif // REF-ANN -} diff --git a/runtimes/nn/depend/libutils/include/utils/Compat.h b/runtimes/nn/depend/libutils/include/utils/Compat.h deleted file mode 100644 index dee577e36..000000000 --- a/runtimes/nn/depend/libutils/include/utils/Compat.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * 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. - */ - -#ifndef __LIB_UTILS_COMPAT_H -#define __LIB_UTILS_COMPAT_H - -#include <unistd.h> - -#if defined(__APPLE__) - -/* Mac OS has always had a 64-bit off_t, so it doesn't have off64_t. */ - -typedef off_t off64_t; - -static inline off64_t lseek64(int fd, off64_t offset, int whence) { - return lseek(fd, offset, whence); -} - -static inline ssize_t pread64(int fd, void* buf, size_t nbytes, off64_t offset) { - return pread(fd, buf, nbytes, offset); -} - -static inline ssize_t pwrite64(int fd, const void* buf, size_t nbytes, off64_t offset) { - return pwrite(fd, buf, nbytes, offset); -} - -static inline int ftruncate64(int fd, off64_t length) { - return ftruncate(fd, length); -} - -#endif /* __APPLE__ */ - -#if defined(_WIN32) -#define O_CLOEXEC O_NOINHERIT -#define O_NOFOLLOW 0 -#define DEFFILEMODE 0666 -#endif /* _WIN32 */ - -#define ZD "%zd" -#define ZD_TYPE ssize_t - -/* - * Needed for cases where something should be constexpr if possible, but not - * being constexpr is fine if in pre-C++11 code (such as a const static float - * member variable). - */ -#if __cplusplus >= 201103L -#define CONSTEXPR constexpr -#else -#define CONSTEXPR -#endif - -/* - * TEMP_FAILURE_RETRY is defined by some, but not all, versions of - * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's - * not already defined, then define it here. - */ -#ifndef TEMP_FAILURE_RETRY -/* Used to retry syscalls that can return EINTR. */ -#define TEMP_FAILURE_RETRY(exp) ({ \ - typeof (exp) _rc; \ - do { \ - _rc = (exp); \ - } while (_rc == -1 && errno == EINTR); \ - _rc; }) -#endif - -#if defined(_WIN32) -#define OS_PATH_SEPARATOR '\\' -#else -#define OS_PATH_SEPARATOR '/' -#endif - -#endif /* __LIB_UTILS_COMPAT_H */ diff --git a/runtimes/nn/depend/libutils/include/utils/Errors.h b/runtimes/nn/depend/libutils/include/utils/Errors.h deleted file mode 100644 index 16e1fa2c2..000000000 --- a/runtimes/nn/depend/libutils/include/utils/Errors.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * 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. - */ - -#ifndef ANDROID_ERRORS_H -#define ANDROID_ERRORS_H - -#include <sys/types.h> -#include <errno.h> - -namespace android { - -// use this type to return error codes -#ifdef _WIN32 -typedef int status_t; -#else -typedef int32_t status_t; -#endif - -/* the MS C runtime lacks a few error codes */ - -/* - * Error codes. - * All error codes are negative values. - */ - -// Win32 #defines NO_ERROR as well. It has the same value, so there's no -// real conflict, though it's a bit awkward. -#ifdef _WIN32 -# undef NO_ERROR -#endif - -enum { - OK = 0, // Everything's swell. - NO_ERROR = 0, // No errors. - - UNKNOWN_ERROR = (-2147483647-1), // INT32_MIN value - - NO_MEMORY = -ENOMEM, - INVALID_OPERATION = -ENOSYS, - BAD_VALUE = -EINVAL, - BAD_TYPE = (UNKNOWN_ERROR + 1), - NAME_NOT_FOUND = -ENOENT, - PERMISSION_DENIED = -EPERM, - NO_INIT = -ENODEV, - ALREADY_EXISTS = -EEXIST, - DEAD_OBJECT = -EPIPE, - FAILED_TRANSACTION = (UNKNOWN_ERROR + 2), -#if !defined(_WIN32) - BAD_INDEX = -EOVERFLOW, - NOT_ENOUGH_DATA = -ENODATA, - WOULD_BLOCK = -EWOULDBLOCK, - TIMED_OUT = -ETIMEDOUT, - UNKNOWN_TRANSACTION = -EBADMSG, -#else - BAD_INDEX = -E2BIG, - NOT_ENOUGH_DATA = (UNKNOWN_ERROR + 3), - WOULD_BLOCK = (UNKNOWN_ERROR + 4), - TIMED_OUT = (UNKNOWN_ERROR + 5), - UNKNOWN_TRANSACTION = (UNKNOWN_ERROR + 6), -#endif - FDS_NOT_ALLOWED = (UNKNOWN_ERROR + 7), - UNEXPECTED_NULL = (UNKNOWN_ERROR + 8), -}; - -// Restore define; enumeration is in "android" namespace, so the value defined -// there won't work for Win32 code in a different namespace. -#ifdef _WIN32 -# define NO_ERROR 0L -#endif - -}; // namespace android - -// --------------------------------------------------------------------------- - -#endif // ANDROID_ERRORS_H diff --git a/runtimes/nn/depend/libutils/include/utils/LightRefBase.h b/runtimes/nn/depend/libutils/include/utils/LightRefBase.h deleted file mode 100644 index 65257edb9..000000000 --- a/runtimes/nn/depend/libutils/include/utils/LightRefBase.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * 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. - */ - -#pragma once - -/* - * See documentation in RefBase.h - */ - -#include <atomic> - -#include <sys/types.h> - -namespace android { - -class ReferenceRenamer; - -template <class T> -class LightRefBase -{ -public: - inline LightRefBase() : mCount(0) { } - inline void incStrong(__attribute__((unused)) const void* id) const { - mCount.fetch_add(1, std::memory_order_relaxed); - } - inline void decStrong(__attribute__((unused)) const void* id) const { - if (mCount.fetch_sub(1, std::memory_order_release) == 1) { - std::atomic_thread_fence(std::memory_order_acquire); - delete static_cast<const T*>(this); - } - } - //! DEBUGGING ONLY: Get current strong ref count. - inline int32_t getStrongCount() const { - return mCount.load(std::memory_order_relaxed); - } - - typedef LightRefBase<T> basetype; - -protected: - inline ~LightRefBase() { } - -private: - friend class ReferenceMover; - inline static void renameRefs(size_t /*n*/, const ReferenceRenamer& /*renamer*/) { } - inline static void renameRefId(T* /*ref*/, const void* /*old_id*/ , const void* /*new_id*/) { } - -private: - mutable std::atomic<int32_t> mCount; -}; - - -// This is a wrapper around LightRefBase that simply enforces a virtual -// destructor to eliminate the template requirement of LightRefBase -class VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> { -public: - virtual ~VirtualLightRefBase() = default; -}; - -}; // namespace android diff --git a/runtimes/nn/depend/libutils/include/utils/RefBase.h b/runtimes/nn/depend/libutils/include/utils/RefBase.h deleted file mode 100644 index 223b6669d..000000000 --- a/runtimes/nn/depend/libutils/include/utils/RefBase.h +++ /dev/null @@ -1,690 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * 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. - */ - - -// SOME COMMENTS ABOUT USAGE: - -// This provides primarily wp<> weak pointer types and RefBase, which work -// together with sp<> from <StrongPointer.h>. - -// sp<> (and wp<>) are a type of smart pointer that use a well defined protocol -// to operate. As long as the object they are templated with implements that -// protocol, these smart pointers work. In several places the platform -// instantiates sp<> with non-RefBase objects; the two are not tied to each -// other. - -// RefBase is such an implementation and it supports strong pointers, weak -// pointers and some magic features for the binder. - -// So, when using RefBase objects, you have the ability to use strong and weak -// pointers through sp<> and wp<>. - -// Normally, when the last strong pointer goes away, the object is destroyed, -// i.e. it's destructor is called. HOWEVER, parts of its associated memory is not -// freed until the last weak pointer is released. - -// Weak pointers are essentially "safe" pointers. They are always safe to -// access through promote(). They may return nullptr if the object was -// destroyed because it ran out of strong pointers. This makes them good candidates -// for keys in a cache for instance. - -// Weak pointers remain valid for comparison purposes even after the underlying -// object has been destroyed. Even if object A is destroyed and its memory reused -// for B, A remaining weak pointer to A will not compare equal to one to B. -// This again makes them attractive for use as keys. - -// How is this supposed / intended to be used? - -// Our recommendation is to use strong references (sp<>) when there is an -// ownership relation. e.g. when an object "owns" another one, use a strong -// ref. And of course use strong refs as arguments of functions (it's extremely -// rare that a function will take a wp<>). - -// Typically a newly allocated object will immediately be used to initialize -// a strong pointer, which may then be used to construct or assign to other -// strong and weak pointers. - -// Use weak references when there are no ownership relation. e.g. the keys in a -// cache (you cannot use plain pointers because there is no safe way to acquire -// a strong reference from a vanilla pointer). - -// This implies that two objects should never (or very rarely) have sp<> on -// each other, because they can't both own each other. - - -// Caveats with reference counting - -// Obviously, circular strong references are a big problem; this creates leaks -// and it's hard to debug -- except it's in fact really easy because RefBase has -// tons of debugging code for that. It can basically tell you exactly where the -// leak is. - -// Another problem has to do with destructors with side effects. You must -// assume that the destructor of reference counted objects can be called AT ANY -// TIME. For instance code as simple as this: - -// void setStuff(const sp<Stuff>& stuff) { -// std::lock_guard<std::mutex> lock(mMutex); -// mStuff = stuff; -// } - -// is very dangerous. This code WILL deadlock one day or another. - -// What isn't obvious is that ~Stuff() can be called as a result of the -// assignment. And it gets called with the lock held. First of all, the lock is -// protecting mStuff, not ~Stuff(). Secondly, if ~Stuff() uses its own internal -// mutex, now you have mutex ordering issues. Even worse, if ~Stuff() is -// virtual, now you're calling into "user" code (potentially), by that, I mean, -// code you didn't even write. - -// A correct way to write this code is something like: - -// void setStuff(const sp<Stuff>& stuff) { -// std::unique_lock<std::mutex> lock(mMutex); -// sp<Stuff> hold = mStuff; -// mStuff = stuff; -// lock.unlock(); -// } - -// More importantly, reference counted objects should do as little work as -// possible in their destructor, or at least be mindful that their destructor -// could be called from very weird and unintended places. - -// Other more specific restrictions for wp<> and sp<>: - -// Do not construct a strong pointer to "this" in an object's constructor. -// The onFirstRef() callback would be made on an incompletely constructed -// object. -// Construction of a weak pointer to "this" in an object's constructor is also -// discouraged. But the implementation was recently changed so that, in the -// absence of extendObjectLifetime() calls, weak pointers no longer impact -// object lifetime, and hence this no longer risks premature deallocation, -// and hence usually works correctly. - -// Such strong or weak pointers can be safely created in the RefBase onFirstRef() -// callback. - -// Use of wp::unsafe_get() for any purpose other than debugging is almost -// always wrong. Unless you somehow know that there is a longer-lived sp<> to -// the same object, it may well return a pointer to a deallocated object that -// has since been reallocated for a different purpose. (And if you know there -// is a longer-lived sp<>, why not use an sp<> directly?) A wp<> should only be -// dereferenced by using promote(). - -// Any object inheriting from RefBase should always be destroyed as the result -// of a reference count decrement, not via any other means. Such objects -// should never be stack allocated, or appear directly as data members in other -// objects. Objects inheriting from RefBase should have their strong reference -// count incremented as soon as possible after construction. Usually this -// will be done via construction of an sp<> to the object, but may instead -// involve other means of calling RefBase::incStrong(). -// Explicitly deleting or otherwise destroying a RefBase object with outstanding -// wp<> or sp<> pointers to it will result in an abort or heap corruption. - -// It is particularly important not to mix sp<> and direct storage management -// since the sp from raw pointer constructor is implicit. Thus if a RefBase- -// -derived object of type T is managed without ever incrementing its strong -// count, and accidentally passed to f(sp<T>), a strong pointer to the object -// will be temporarily constructed and destroyed, prematurely deallocating the -// object, and resulting in heap corruption. None of this would be easily -// visible in the source. - -// Extra Features: - -// RefBase::extendObjectLifetime() can be used to prevent destruction of the -// object while there are still weak references. This is really special purpose -// functionality to support Binder. - -// Wp::promote(), implemented via the attemptIncStrong() member function, is -// used to try to convert a weak pointer back to a strong pointer. It's the -// normal way to try to access the fields of an object referenced only through -// a wp<>. Binder code also sometimes uses attemptIncStrong() directly. - -// RefBase provides a number of additional callbacks for certain reference count -// events, as well as some debugging facilities. - -// Debugging support can be enabled by turning on DEBUG_REFS in RefBase.cpp. -// Otherwise little checking is provided. - -// Thread safety: - -// Like std::shared_ptr, sp<> and wp<> allow concurrent accesses to DIFFERENT -// sp<> and wp<> instances that happen to refer to the same underlying object. -// They do NOT support concurrent access (where at least one access is a write) -// to THE SAME sp<> or wp<>. In effect, their thread-safety properties are -// exactly like those of T*, NOT atomic<T*>. - -#ifndef ANDROID_REF_BASE_H -#define ANDROID_REF_BASE_H - -#include <atomic> - -#include <stdint.h> -#include <sys/types.h> -#include <stdlib.h> -#include <string.h> - -// LightRefBase used to be declared in this header, so we have to include it -#include <utils/LightRefBase.h> - -#include <utils/StrongPointer.h> -#include <utils/TypeHelpers.h> - -// --------------------------------------------------------------------------- -namespace android { - -class TextOutput; -TextOutput& printWeakPointer(TextOutput& to, const void* val); - -// --------------------------------------------------------------------------- - -#define COMPARE_WEAK(_op_) \ -inline bool operator _op_ (const sp<T>& o) const { \ - return m_ptr _op_ o.m_ptr; \ -} \ -inline bool operator _op_ (const T* o) const { \ - return m_ptr _op_ o; \ -} \ -template<typename U> \ -inline bool operator _op_ (const sp<U>& o) const { \ - return m_ptr _op_ o.m_ptr; \ -} \ -template<typename U> \ -inline bool operator _op_ (const U* o) const { \ - return m_ptr _op_ o; \ -} - -// --------------------------------------------------------------------------- - -// RefererenceRenamer is pure abstract, there is no virtual method -// implementation to put in a translation unit in order to silence the -// weak vtables warning. -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wweak-vtables" -#endif - -class ReferenceRenamer { -protected: - // destructor is purposely not virtual so we avoid code overhead from - // subclasses; we have to make it protected to guarantee that it - // cannot be called from this base class (and to make strict compilers - // happy). - ~ReferenceRenamer() { } -public: - virtual void operator()(size_t i) const = 0; -}; - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - -// --------------------------------------------------------------------------- - -class RefBase -{ -public: - void incStrong(const void* id) const; - void decStrong(const void* id) const; - - void forceIncStrong(const void* id) const; - - //! DEBUGGING ONLY: Get current strong ref count. - int32_t getStrongCount() const; - - class weakref_type - { - public: - RefBase* refBase() const; - - void incWeak(const void* id); - void decWeak(const void* id); - - // acquires a strong reference if there is already one. - bool attemptIncStrong(const void* id); - - // acquires a weak reference if there is already one. - // This is not always safe. see ProcessState.cpp and BpBinder.cpp - // for proper use. - bool attemptIncWeak(const void* id); - - //! DEBUGGING ONLY: Get current weak ref count. - int32_t getWeakCount() const; - - //! DEBUGGING ONLY: Print references held on object. - void printRefs() const; - - //! DEBUGGING ONLY: Enable tracking for this object. - // enable -- enable/disable tracking - // retain -- when tracking is enable, if true, then we save a stack trace - // for each reference and dereference; when retain == false, we - // match up references and dereferences and keep only the - // outstanding ones. - - void trackMe(bool enable, bool retain); - }; - - weakref_type* createWeak(const void* id) const; - - weakref_type* getWeakRefs() const; - - //! DEBUGGING ONLY: Print references held on object. - inline void printRefs() const { getWeakRefs()->printRefs(); } - - //! DEBUGGING ONLY: Enable tracking of object. - inline void trackMe(bool enable, bool retain) - { - getWeakRefs()->trackMe(enable, retain); - } - - typedef RefBase basetype; - -protected: - RefBase(); - virtual ~RefBase(); - - //! Flags for extendObjectLifetime() - enum { - OBJECT_LIFETIME_STRONG = 0x0000, - OBJECT_LIFETIME_WEAK = 0x0001, - OBJECT_LIFETIME_MASK = 0x0001 - }; - - void extendObjectLifetime(int32_t mode); - - //! Flags for onIncStrongAttempted() - enum { - FIRST_INC_STRONG = 0x0001 - }; - - // Invoked after creation of initial strong pointer/reference. - virtual void onFirstRef(); - // Invoked when either the last strong reference goes away, or we need to undo - // the effect of an unnecessary onIncStrongAttempted. - virtual void onLastStrongRef(const void* id); - // Only called in OBJECT_LIFETIME_WEAK case. Returns true if OK to promote to - // strong reference. May have side effects if it returns true. - // The first flags argument is always FIRST_INC_STRONG. - // TODO: Remove initial flag argument. - virtual bool onIncStrongAttempted(uint32_t flags, const void* id); - // Invoked in the OBJECT_LIFETIME_WEAK case when the last reference of either - // kind goes away. Unused. - // TODO: Remove. - virtual void onLastWeakRef(const void* id); - -private: - friend class weakref_type; - class weakref_impl; - - RefBase(const RefBase& o); - RefBase& operator=(const RefBase& o); - -private: - friend class ReferenceMover; - - static void renameRefs(size_t n, const ReferenceRenamer& renamer); - - static void renameRefId(weakref_type* ref, - const void* old_id, const void* new_id); - - static void renameRefId(RefBase* ref, - const void* old_id, const void* new_id); - - weakref_impl* const mRefs; -}; - -// --------------------------------------------------------------------------- - -template <typename T> -class wp -{ -public: - typedef typename RefBase::weakref_type weakref_type; - - inline wp() : m_ptr(0) { } - - wp(T* other); // NOLINT(implicit) - wp(const wp<T>& other); - explicit wp(const sp<T>& other); - template<typename U> wp(U* other); // NOLINT(implicit) - template<typename U> wp(const sp<U>& other); // NOLINT(implicit) - template<typename U> wp(const wp<U>& other); // NOLINT(implicit) - - ~wp(); - - // Assignment - - wp& operator = (T* other); - wp& operator = (const wp<T>& other); - wp& operator = (const sp<T>& other); - - template<typename U> wp& operator = (U* other); - template<typename U> wp& operator = (const wp<U>& other); - template<typename U> wp& operator = (const sp<U>& other); - - void set_object_and_refs(T* other, weakref_type* refs); - - // promotion to sp - - sp<T> promote() const; - - // Reset - - void clear(); - - // Accessors - - inline weakref_type* get_refs() const { return m_refs; } - - inline T* unsafe_get() const { return m_ptr; } - - // Operators - - COMPARE_WEAK(==) - COMPARE_WEAK(!=) - COMPARE_WEAK(>) - COMPARE_WEAK(<) - COMPARE_WEAK(<=) - COMPARE_WEAK(>=) - - inline bool operator == (const wp<T>& o) const { - return (m_ptr == o.m_ptr) && (m_refs == o.m_refs); - } - template<typename U> - inline bool operator == (const wp<U>& o) const { - return m_ptr == o.m_ptr; - } - - inline bool operator > (const wp<T>& o) const { - return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); - } - template<typename U> - inline bool operator > (const wp<U>& o) const { - return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); - } - - inline bool operator < (const wp<T>& o) const { - return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); - } - template<typename U> - inline bool operator < (const wp<U>& o) const { - return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); - } - inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; } - template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); } - inline bool operator <= (const wp<T>& o) const { return !operator > (o); } - template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); } - inline bool operator >= (const wp<T>& o) const { return !operator < (o); } - template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); } - -private: - template<typename Y> friend class sp; - template<typename Y> friend class wp; - - T* m_ptr; - weakref_type* m_refs; -}; - -template <typename T> -TextOutput& operator<<(TextOutput& to, const wp<T>& val); - -#undef COMPARE_WEAK - -// --------------------------------------------------------------------------- -// No user serviceable parts below here. - -template<typename T> -wp<T>::wp(T* other) - : m_ptr(other) -{ - if (other) m_refs = other->createWeak(this); -} - -template<typename T> -wp<T>::wp(const wp<T>& other) - : m_ptr(other.m_ptr), m_refs(other.m_refs) -{ - if (m_ptr) m_refs->incWeak(this); -} - -template<typename T> -wp<T>::wp(const sp<T>& other) - : m_ptr(other.m_ptr) -{ - if (m_ptr) { - m_refs = m_ptr->createWeak(this); - } -} - -template<typename T> template<typename U> -wp<T>::wp(U* other) - : m_ptr(other) -{ - if (other) m_refs = other->createWeak(this); -} - -template<typename T> template<typename U> -wp<T>::wp(const wp<U>& other) - : m_ptr(other.m_ptr) -{ - if (m_ptr) { - m_refs = other.m_refs; - m_refs->incWeak(this); - } -} - -template<typename T> template<typename U> -wp<T>::wp(const sp<U>& other) - : m_ptr(other.m_ptr) -{ - if (m_ptr) { - m_refs = m_ptr->createWeak(this); - } -} - -template<typename T> -wp<T>::~wp() -{ - if (m_ptr) m_refs->decWeak(this); -} - -template<typename T> -wp<T>& wp<T>::operator = (T* other) -{ - weakref_type* newRefs = - other ? other->createWeak(this) : 0; - if (m_ptr) m_refs->decWeak(this); - m_ptr = other; - m_refs = newRefs; - return *this; -} - -template<typename T> -wp<T>& wp<T>::operator = (const wp<T>& other) -{ - weakref_type* otherRefs(other.m_refs); - T* otherPtr(other.m_ptr); - if (otherPtr) otherRefs->incWeak(this); - if (m_ptr) m_refs->decWeak(this); - m_ptr = otherPtr; - m_refs = otherRefs; - return *this; -} - -template<typename T> -wp<T>& wp<T>::operator = (const sp<T>& other) -{ - weakref_type* newRefs = - other != NULL ? other->createWeak(this) : 0; - T* otherPtr(other.m_ptr); - if (m_ptr) m_refs->decWeak(this); - m_ptr = otherPtr; - m_refs = newRefs; - return *this; -} - -template<typename T> template<typename U> -wp<T>& wp<T>::operator = (U* other) -{ - weakref_type* newRefs = - other ? other->createWeak(this) : 0; - if (m_ptr) m_refs->decWeak(this); - m_ptr = other; - m_refs = newRefs; - return *this; -} - -template<typename T> template<typename U> -wp<T>& wp<T>::operator = (const wp<U>& other) -{ - weakref_type* otherRefs(other.m_refs); - U* otherPtr(other.m_ptr); - if (otherPtr) otherRefs->incWeak(this); - if (m_ptr) m_refs->decWeak(this); - m_ptr = otherPtr; - m_refs = otherRefs; - return *this; -} - -template<typename T> template<typename U> -wp<T>& wp<T>::operator = (const sp<U>& other) -{ - weakref_type* newRefs = - other != NULL ? other->createWeak(this) : 0; - U* otherPtr(other.m_ptr); - if (m_ptr) m_refs->decWeak(this); - m_ptr = otherPtr; - m_refs = newRefs; - return *this; -} - -template<typename T> -void wp<T>::set_object_and_refs(T* other, weakref_type* refs) -{ - if (other) refs->incWeak(this); - if (m_ptr) m_refs->decWeak(this); - m_ptr = other; - m_refs = refs; -} - -template<typename T> -sp<T> wp<T>::promote() const -{ - sp<T> result; - if (m_ptr && m_refs->attemptIncStrong(&result)) { - result.set_pointer(m_ptr); - } - return result; -} - -template<typename T> -void wp<T>::clear() -{ - if (m_ptr) { - m_refs->decWeak(this); - m_ptr = 0; - } -} - -template <typename T> -inline TextOutput& operator<<(TextOutput& to, const wp<T>& val) -{ - return printWeakPointer(to, val.unsafe_get()); -} - -// --------------------------------------------------------------------------- - -// this class just serves as a namespace so TYPE::moveReferences can stay -// private. -class ReferenceMover { -public: - // it would be nice if we could make sure no extra code is generated - // for sp<TYPE> or wp<TYPE> when TYPE is a descendant of RefBase: - // Using a sp<RefBase> override doesn't work; it's a bit like we wanted - // a template<typename TYPE inherits RefBase> template... - - template<typename TYPE> static inline - void move_references(sp<TYPE>* dest, sp<TYPE> const* src, size_t n) { - - class Renamer : public ReferenceRenamer { - sp<TYPE>* d_; - sp<TYPE> const* s_; - virtual void operator()(size_t i) const { - // The id are known to be the sp<>'s this pointer - TYPE::renameRefId(d_[i].get(), &s_[i], &d_[i]); - } - public: - Renamer(sp<TYPE>* d, sp<TYPE> const* s) : d_(d), s_(s) { } - virtual ~Renamer() { } - }; - - memmove(dest, src, n*sizeof(sp<TYPE>)); - TYPE::renameRefs(n, Renamer(dest, src)); - } - - - template<typename TYPE> static inline - void move_references(wp<TYPE>* dest, wp<TYPE> const* src, size_t n) { - - class Renamer : public ReferenceRenamer { - wp<TYPE>* d_; - wp<TYPE> const* s_; - virtual void operator()(size_t i) const { - // The id are known to be the wp<>'s this pointer - TYPE::renameRefId(d_[i].get_refs(), &s_[i], &d_[i]); - } - public: - Renamer(wp<TYPE>* rd, wp<TYPE> const* rs) : d_(rd), s_(rs) { } - virtual ~Renamer() { } - }; - - memmove(dest, src, n*sizeof(wp<TYPE>)); - TYPE::renameRefs(n, Renamer(dest, src)); - } -}; - -// specialization for moving sp<> and wp<> types. -// these are used by the [Sorted|Keyed]Vector<> implementations -// sp<> and wp<> need to be handled specially, because they do not -// have trivial copy operation in the general case (see RefBase.cpp -// when DEBUG ops are enabled), but can be implemented very -// efficiently in most cases. - -template<typename TYPE> inline -void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { - ReferenceMover::move_references(d, s, n); -} - -template<typename TYPE> inline -void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { - ReferenceMover::move_references(d, s, n); -} - -template<typename TYPE> inline -void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { - ReferenceMover::move_references(d, s, n); -} - -template<typename TYPE> inline -void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { - ReferenceMover::move_references(d, s, n); -} - -}; // namespace android - -// --------------------------------------------------------------------------- - -#endif // ANDROID_REF_BASE_H diff --git a/runtimes/nn/depend/libutils/include/utils/StrongPointer.h b/runtimes/nn/depend/libutils/include/utils/StrongPointer.h deleted file mode 100644 index 0c2060791..000000000 --- a/runtimes/nn/depend/libutils/include/utils/StrongPointer.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2005 The Android Open Source Project - * - * 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. - */ - -#ifndef ANDROID_STRONG_POINTER_H -#define ANDROID_STRONG_POINTER_H - -// --------------------------------------------------------------------------- -namespace android { - -template<typename T> class wp; - -// --------------------------------------------------------------------------- - -#define COMPARE(_op_) \ -inline bool operator _op_ (const sp<T>& o) const { \ - return m_ptr _op_ o.m_ptr; \ -} \ -inline bool operator _op_ (const T* o) const { \ - return m_ptr _op_ o; \ -} \ -template<typename U> \ -inline bool operator _op_ (const sp<U>& o) const { \ - return m_ptr _op_ o.m_ptr; \ -} \ -template<typename U> \ -inline bool operator _op_ (const U* o) const { \ - return m_ptr _op_ o; \ -} \ -inline bool operator _op_ (const wp<T>& o) const { \ - return m_ptr _op_ o.m_ptr; \ -} \ -template<typename U> \ -inline bool operator _op_ (const wp<U>& o) const { \ - return m_ptr _op_ o.m_ptr; \ -} - -// --------------------------------------------------------------------------- - -template<typename T> -class sp { -public: - inline sp() : m_ptr(0) { } - - sp(T* other); // NOLINT(implicit) - sp(const sp<T>& other); - sp(sp<T>&& other); - template<typename U> sp(U* other); // NOLINT(implicit) - template<typename U> sp(const sp<U>& other); // NOLINT(implicit) - template<typename U> sp(sp<U>&& other); // NOLINT(implicit) - - ~sp(); - - // Assignment - - sp& operator = (T* other); - sp& operator = (const sp<T>& other); - sp& operator = (sp<T>&& other); - - template<typename U> sp& operator = (const sp<U>& other); - template<typename U> sp& operator = (sp<U>&& other); - template<typename U> sp& operator = (U* other); - - //! Special optimization for use by ProcessState (and nobody else). - void force_set(T* other); - - // Reset - - void clear(); - - // Accessors - - inline T& operator* () const { return *m_ptr; } - inline T* operator-> () const { return m_ptr; } - inline T* get() const { return m_ptr; } - - // Operators - - COMPARE(==) - COMPARE(!=) - COMPARE(>) - COMPARE(<) - COMPARE(<=) - COMPARE(>=) - -private: - template<typename Y> friend class sp; - template<typename Y> friend class wp; - void set_pointer(T* ptr); - T* m_ptr; -}; - -// For code size reasons, we do not want this inlined or templated. -void sp_report_race(); - -#undef COMPARE - -// --------------------------------------------------------------------------- -// No user serviceable parts below here. - -template<typename T> -sp<T>::sp(T* other) - : m_ptr(other) { - if (other) - other->incStrong(this); -} - -template<typename T> -sp<T>::sp(const sp<T>& other) - : m_ptr(other.m_ptr) { - if (m_ptr) - m_ptr->incStrong(this); -} - -template<typename T> -sp<T>::sp(sp<T>&& other) - : m_ptr(other.m_ptr) { - other.m_ptr = nullptr; -} - -template<typename T> template<typename U> -sp<T>::sp(U* other) - : m_ptr(other) { - if (other) - (static_cast<T*>(other))->incStrong(this); -} - -template<typename T> template<typename U> -sp<T>::sp(const sp<U>& other) - : m_ptr(other.m_ptr) { - if (m_ptr) - m_ptr->incStrong(this); -} - -template<typename T> template<typename U> -sp<T>::sp(sp<U>&& other) - : m_ptr(other.m_ptr) { - other.m_ptr = nullptr; -} - -template<typename T> -sp<T>::~sp() { - if (m_ptr) - m_ptr->decStrong(this); -} - -template<typename T> -sp<T>& sp<T>::operator =(const sp<T>& other) { - // Force m_ptr to be read twice, to heuristically check for data races. - T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); - T* otherPtr(other.m_ptr); - if (otherPtr) otherPtr->incStrong(this); - if (oldPtr) oldPtr->decStrong(this); - if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); - m_ptr = otherPtr; - return *this; -} - -template<typename T> -sp<T>& sp<T>::operator =(sp<T>&& other) { - T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); - if (oldPtr) oldPtr->decStrong(this); - if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); - m_ptr = other.m_ptr; - other.m_ptr = nullptr; - return *this; -} - -template<typename T> -sp<T>& sp<T>::operator =(T* other) { - T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); - if (other) other->incStrong(this); - if (oldPtr) oldPtr->decStrong(this); - if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); - m_ptr = other; - return *this; -} - -template<typename T> template<typename U> -sp<T>& sp<T>::operator =(const sp<U>& other) { - T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); - T* otherPtr(other.m_ptr); - if (otherPtr) otherPtr->incStrong(this); - if (oldPtr) oldPtr->decStrong(this); - if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); - m_ptr = otherPtr; - return *this; -} - -template<typename T> template<typename U> -sp<T>& sp<T>::operator =(sp<U>&& other) { - T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); - if (m_ptr) m_ptr->decStrong(this); - if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); - m_ptr = other.m_ptr; - other.m_ptr = nullptr; - return *this; -} - -template<typename T> template<typename U> -sp<T>& sp<T>::operator =(U* other) { - T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); - if (other) (static_cast<T*>(other))->incStrong(this); - if (oldPtr) oldPtr->decStrong(this); - if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); - m_ptr = other; - return *this; -} - -template<typename T> -void sp<T>::force_set(T* other) { - other->forceIncStrong(this); - m_ptr = other; -} - -template<typename T> -void sp<T>::clear() { - if (m_ptr) { - m_ptr->decStrong(this); - m_ptr = 0; - } -} - -template<typename T> -void sp<T>::set_pointer(T* ptr) { - m_ptr = ptr; -} - -}; // namespace android - -// --------------------------------------------------------------------------- - -#endif // ANDROID_STRONG_POINTER_H diff --git a/runtimes/nn/depend/libutils/include/utils/TypeHelpers.h b/runtimes/nn/depend/libutils/include/utils/TypeHelpers.h deleted file mode 100644 index 28fbca508..000000000 --- a/runtimes/nn/depend/libutils/include/utils/TypeHelpers.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 2005 The Android Open Source Project - * - * 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. - */ - -#ifndef ANDROID_TYPE_HELPERS_H -#define ANDROID_TYPE_HELPERS_H - -#include <new> -#include <type_traits> - -#include <stdint.h> -#include <string.h> -#include <sys/types.h> - -// --------------------------------------------------------------------------- - -namespace android { - -/* - * Types traits - */ - -template <typename T> struct trait_trivial_ctor { enum { value = false }; }; -template <typename T> struct trait_trivial_dtor { enum { value = false }; }; -template <typename T> struct trait_trivial_copy { enum { value = false }; }; -template <typename T> struct trait_trivial_move { enum { value = false }; }; -template <typename T> struct trait_pointer { enum { value = false }; }; -template <typename T> struct trait_pointer<T*> { enum { value = true }; }; - -template <typename TYPE> -struct traits { - enum { - // whether this type is a pointer - is_pointer = trait_pointer<TYPE>::value, - // whether this type's constructor is a no-op - has_trivial_ctor = is_pointer || trait_trivial_ctor<TYPE>::value, - // whether this type's destructor is a no-op - has_trivial_dtor = is_pointer || trait_trivial_dtor<TYPE>::value, - // whether this type type can be copy-constructed with memcpy - has_trivial_copy = is_pointer || trait_trivial_copy<TYPE>::value, - // whether this type can be moved with memmove - has_trivial_move = is_pointer || trait_trivial_move<TYPE>::value - }; -}; - -template <typename T, typename U> -struct aggregate_traits { - enum { - is_pointer = false, - has_trivial_ctor = - traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor, - has_trivial_dtor = - traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor, - has_trivial_copy = - traits<T>::has_trivial_copy && traits<U>::has_trivial_copy, - has_trivial_move = - traits<T>::has_trivial_move && traits<U>::has_trivial_move - }; -}; - -#define ANDROID_TRIVIAL_CTOR_TRAIT( T ) \ - template<> struct trait_trivial_ctor< T > { enum { value = true }; }; - -#define ANDROID_TRIVIAL_DTOR_TRAIT( T ) \ - template<> struct trait_trivial_dtor< T > { enum { value = true }; }; - -#define ANDROID_TRIVIAL_COPY_TRAIT( T ) \ - template<> struct trait_trivial_copy< T > { enum { value = true }; }; - -#define ANDROID_TRIVIAL_MOVE_TRAIT( T ) \ - template<> struct trait_trivial_move< T > { enum { value = true }; }; - -#define ANDROID_BASIC_TYPES_TRAITS( T ) \ - ANDROID_TRIVIAL_CTOR_TRAIT( T ) \ - ANDROID_TRIVIAL_DTOR_TRAIT( T ) \ - ANDROID_TRIVIAL_COPY_TRAIT( T ) \ - ANDROID_TRIVIAL_MOVE_TRAIT( T ) - -// --------------------------------------------------------------------------- - -/* - * basic types traits - */ - -ANDROID_BASIC_TYPES_TRAITS( void ) -ANDROID_BASIC_TYPES_TRAITS( bool ) -ANDROID_BASIC_TYPES_TRAITS( char ) -ANDROID_BASIC_TYPES_TRAITS( unsigned char ) -ANDROID_BASIC_TYPES_TRAITS( short ) -ANDROID_BASIC_TYPES_TRAITS( unsigned short ) -ANDROID_BASIC_TYPES_TRAITS( int ) -ANDROID_BASIC_TYPES_TRAITS( unsigned int ) -ANDROID_BASIC_TYPES_TRAITS( long ) -ANDROID_BASIC_TYPES_TRAITS( unsigned long ) -ANDROID_BASIC_TYPES_TRAITS( long long ) -ANDROID_BASIC_TYPES_TRAITS( unsigned long long ) -ANDROID_BASIC_TYPES_TRAITS( float ) -ANDROID_BASIC_TYPES_TRAITS( double ) - -// --------------------------------------------------------------------------- - - -/* - * compare and order types - */ - -template<typename TYPE> inline -int strictly_order_type(const TYPE& lhs, const TYPE& rhs) { - return (lhs < rhs) ? 1 : 0; -} - -template<typename TYPE> inline -int compare_type(const TYPE& lhs, const TYPE& rhs) { - return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs); -} - -/* - * create, destroy, copy and move types... - */ - -template<typename TYPE> inline -void construct_type(TYPE* p, size_t n) { - if (!traits<TYPE>::has_trivial_ctor) { - while (n > 0) { - n--; - new(p++) TYPE; - } - } -} - -template<typename TYPE> inline -void destroy_type(TYPE* p, size_t n) { - if (!traits<TYPE>::has_trivial_dtor) { - while (n > 0) { - n--; - p->~TYPE(); - p++; - } - } -} - -template<typename TYPE> -typename std::enable_if<traits<TYPE>::has_trivial_copy>::type -inline -copy_type(TYPE* d, const TYPE* s, size_t n) { - memcpy(d,s,n*sizeof(TYPE)); -} - -template<typename TYPE> -typename std::enable_if<!traits<TYPE>::has_trivial_copy>::type -inline -copy_type(TYPE* d, const TYPE* s, size_t n) { - while (n > 0) { - n--; - new(d) TYPE(*s); - d++, s++; - } -} - -template<typename TYPE> inline -void splat_type(TYPE* where, const TYPE* what, size_t n) { - if (!traits<TYPE>::has_trivial_copy) { - while (n > 0) { - n--; - new(where) TYPE(*what); - where++; - } - } else { - while (n > 0) { - n--; - *where++ = *what; - } - } -} - -template<typename TYPE> -struct use_trivial_move : public std::integral_constant<bool, - (traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) - || traits<TYPE>::has_trivial_move -> {}; - -template<typename TYPE> -typename std::enable_if<use_trivial_move<TYPE>::value>::type -inline -move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { - memmove(d, s, n*sizeof(TYPE)); -} - -template<typename TYPE> -typename std::enable_if<!use_trivial_move<TYPE>::value>::type -inline -move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { - d += n; - s += n; - while (n > 0) { - n--; - --d, --s; - if (!traits<TYPE>::has_trivial_copy) { - new(d) TYPE(*s); - } else { - *d = *s; - } - if (!traits<TYPE>::has_trivial_dtor) { - s->~TYPE(); - } - } -} - -template<typename TYPE> -typename std::enable_if<use_trivial_move<TYPE>::value>::type -inline -move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { - memmove(d, s, n*sizeof(TYPE)); -} - -template<typename TYPE> -typename std::enable_if<!use_trivial_move<TYPE>::value>::type -inline -move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { - while (n > 0) { - n--; - if (!traits<TYPE>::has_trivial_copy) { - new(d) TYPE(*s); - } else { - *d = *s; - } - if (!traits<TYPE>::has_trivial_dtor) { - s->~TYPE(); - } - d++, s++; - } -} - -// --------------------------------------------------------------------------- - -/* - * a key/value pair - */ - -template <typename KEY, typename VALUE> -struct key_value_pair_t { - typedef KEY key_t; - typedef VALUE value_t; - - KEY key; - VALUE value; - key_value_pair_t() { } - key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { } - key_value_pair_t& operator=(const key_value_pair_t& o) { - key = o.key; - value = o.value; - return *this; - } - key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v) { } - explicit key_value_pair_t(const KEY& k) : key(k) { } - inline bool operator < (const key_value_pair_t& o) const { - return strictly_order_type(key, o.key); - } - inline const KEY& getKey() const { - return key; - } - inline const VALUE& getValue() const { - return value; - } -}; - -template <typename K, typename V> -struct trait_trivial_ctor< key_value_pair_t<K, V> > -{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; }; -template <typename K, typename V> -struct trait_trivial_dtor< key_value_pair_t<K, V> > -{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; }; -template <typename K, typename V> -struct trait_trivial_copy< key_value_pair_t<K, V> > -{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; }; -template <typename K, typename V> -struct trait_trivial_move< key_value_pair_t<K, V> > -{ enum { value = aggregate_traits<K,V>::has_trivial_move }; }; - -// --------------------------------------------------------------------------- - -/* - * Hash codes. - */ -typedef uint32_t hash_t; - -template <typename TKey> -hash_t hash_type(const TKey& key); - -/* Built-in hash code specializations */ -#define ANDROID_INT32_HASH(T) \ - template <> inline hash_t hash_type(const T& value) { return hash_t(value); } -#define ANDROID_INT64_HASH(T) \ - template <> inline hash_t hash_type(const T& value) { \ - return hash_t((value >> 32) ^ value); } -#define ANDROID_REINTERPRET_HASH(T, R) \ - template <> inline hash_t hash_type(const T& value) { \ - R newValue; \ - static_assert(sizeof(newValue) == sizeof(value), "size mismatch"); \ - memcpy(&newValue, &value, sizeof(newValue)); \ - return hash_type(newValue); \ - } - -ANDROID_INT32_HASH(bool) -ANDROID_INT32_HASH(int8_t) -ANDROID_INT32_HASH(uint8_t) -ANDROID_INT32_HASH(int16_t) -ANDROID_INT32_HASH(uint16_t) -ANDROID_INT32_HASH(int32_t) -ANDROID_INT32_HASH(uint32_t) -ANDROID_INT64_HASH(int64_t) -ANDROID_INT64_HASH(uint64_t) -ANDROID_REINTERPRET_HASH(float, uint32_t) -ANDROID_REINTERPRET_HASH(double, uint64_t) - -template <typename T> inline hash_t hash_type(T* const & value) { - return hash_type(uintptr_t(value)); -} - -}; // namespace android - -// --------------------------------------------------------------------------- - -#endif // ANDROID_TYPE_HELPERS_H |